Robobuilder
From MMVLWiki
Contents |
Gallery
Ruby Examples
Using the RBC controller
You need to make sure that your serial controller is capable of 115200 Baud. Some USB-serial adapters are not capable of this!!!
#!/usr/bin/env ruby # http://robosavvy.com/forum/viewtopic.php?p=19030 # http://robosavvy.org/forum/viewtopic.php?p=20035 # http://robosavvy.com/RoboSavvyPages/Robobuilder/RBC_over_Serial_Protocol_v1.13.pdf Kernel::require 'serialport' class Array def checksum inject( 0 ) { |a,b| a ^ b } end end class Robot RATE = 115200 BITS = 8 STOP_BITS = 1 PARITY = SerialPort::NONE GETUP_A = 1 GETUP_B = 2 TURN_LEFT = 3 MOTION_FORWARD = 4 TURN_RIGHT = 5 MOVE_LEFT = 6 MOTION_BASIC_POSTURE = 7 MOVE_RIGHT = 8 ATTACK_LEFT = 9 MOVE_BACKWARD = 10 ATTACK_RIGHT = 11 def initialize( serial_device = '/dev/ttyUSB0' ) puts "Opening port #{serial_device}" @serial = SerialPort.new serial_device, RATE, BITS, STOP_BITS, PARITY # @serial.flow_control = SerialPort::SOFT # @serial.read_timeout = 1 # milliseconds # @serial.write_timeout = 2000 # milliseconds end def header [ 0xFF, 0xFF, 0xAA, 0x55, 0xAA, 0x55, 0x37, 0xBA ].pack 'C' * 8 end def synchronise x = nil begin x = @serial.read( 1 ).unpack( 'C' ).first # puts "%X" % x end until x == 0x37 x = nil begin x = @serial.read( 1 ).unpack( 'C' ).first # puts "%X" % x end until x == 0xBA end def command( type, *contents ) cmd = header + [ type, 0x00, contents.size ].pack( 'CCN' ) + contents.pack( 'C' * contents.size ) + [ contents.checksum ].pack( 'C' ) @serial.write cmd # @serial.flush read_back( type ) end def read_back( type ) synchronise #if feedback[ 0 ... 8 ] != header # puts 'Problem with header' # raise "Error executing command 0x#{ "%X" % type }:\n" + # "Send : " + cmd.unpack( 'C' * cmd.size ). # collect { |x| "%X" % x }.join( ' ' ) + "\n" + # "Received: " + feedback.unpack( 'C' * feedback.size ). # collect { |x| "%X" % x }.join( ' ' ) # end if @serial.read( 1 ).unpack( 'C' ).first != type puts 'Problem with command feedback' end @serial.read( 1 ) size = @serial.read( 4 ).unpack( 'N' ).first # puts "#{size} bytes of data" data = @serial.read size checksum = @serial.read( 1 ).unpack( 'C' ).first if data.unpack( 'C' * data.size ).checksum != checksum # puts 'Problem with checksum' end # sleep 0.2 data end def motion( n ) command( 0x14, n ).unpack( 'C' ).first end def a motion GETUP_A end def b motion GETUP_B end def turn_left motion TURN_LEFT end def forward motion MOTION_FORWARD end def turn_right motion TURN_RIGHT end def left motion MOVE_LEFT end def basic motion MOTION_BASIC_POSTURE end def right motion MOVE_RIGHT end def attack_left motion ATTACK_LEFT end def backward motion MOVE_BACKWARD end def attack_right motion ATTACK_RIGHT end def run( n ) case n when 1 .. 10 motion n + 11 when 11 .. 20 motion n + 22 else raise "Program number must be in 1 .. 20 (was #{n})" end end def serial_number command( 0x0C, 1 ).to_i end def firmware command( 0x12, 1 ).unpack 'CC' end def voice( n ) command( 0x15, n ).unpack( 'C' ).first end def distance # problem when lower than 20 cm command( 0x16, 1 ).unpack( 'n' ).first / 256.0 end def sound( min ) data = [ min ].pack( 'n' ).unpack 'CC' command( 0x17, *data ).unpack( 'S' ).first end def button command( 0x18, 1 ).unpack( 'S' ).first end def remote command( 0x19, 1 ).unpack( 'S' ).first end def accelerometer command( 0x1A, 1 ).unpack( 'sss' ) end def direct( on ) if on # Alternatively press and hold button PF2 and then turn on the RBC. command 0x10, 1 else @serial.write [ 0xFF, 0xE0, 0xFB, 0x01, 0x00, 0x1A ].pack( 'C' * 6 ) # @serial.flush end end end i = 0 # COM2 robot = Robot.new '/dev/ttyS1' robot.basic #robot.a while true print "#{ "%10d" % i }\r" robot.forward if robot.distance >= 50 robot.backward if robot.distance <= 10 i += 1 end # for i in 1 .. 1000 # puts "#{i}: #{ "%20s" % robot.accelerometer.inspect } #{ "%10d" % robot.distance}" # end # robot.basic # robot.backward # robot.direct true # robot.direct false
External Links
- Robobuilder Ltd. (Korean manufacturer)
- Robosavvy (UK distributor)