def process_command(command): # Ignore blank lines if command == "": return # Speed command if command[0:5].lower() == 'speed': speed_re = re.compile('speed\s+([+|-]*)(\d+)') match = speed_re.search(command) if not match: log("Invalid speed command, usage is: speed <integer>") return speed = int("%s%s" % (match.group(1), match.group(2))) if speed < -16 or speed > 16: log("Invalid speed: must be -16 <= speed <= 16") return robopower.speed(speed) log("Speed set to %d" % speed) return # Stop command if command[0:4].lower() == 'stop': robopower.stop() log("Robot stopped") return # No match - must be an invalid command log("Invalid command: %s" % command)
def mainloop(): log("Starting command server") HOST = get_local_ipv4_address() PORT = roboconfig.command_port command_server = SocketServer.UDPServer((HOST,PORT),MyUDPHandler) command_server.serve_forever()
def process_control_line(line): """Processes a line from the RoboMagellen control file.""" # skip comments and blank lines if line[0] == '#': return None if line == "": return None re_anything = re.compile('\S+') if re_anything.match(line) == None: return None # determine and process line type line = line.rstrip() if line[0:4] == "DRIV": return process_driv_directive(line) elif line[0:4] == "GOTO": return process_goto_directive(line) elif line[0:4] == "CONE": return process_cone_directive(line) elif line[0:4] == "STOP": return process_stop_directive(line) elif line[0:4] == "STER": return process_ster_directive(line) elif line[0:4] == "POWR": return process_powr_directive(line) elif line[0:4] == "WAIT": return process_wait_directive(line) else: log("Undefined directive " + line[0:4] +" in line: " + line) return False
def initialize(): log("Sensor initialization started") compass_thread = CompassThread() compass_thread.start() sensor_thread = SensorThread() sensor_thread.start() log("Sensor initialization completed") return True
def run(self): while self.run_flag == True: global compass_data self.ser.flushInput() # Discard readings buffered during sleep data = self.ser.readline() m = self.compass_re.match(data) if m: compass_data = int(m.group(1)) + 0.1 * int(m.group(2)) else: log("robosensors - recieved invalid compass data: %s" % data) time.sleep(roboconfig.compass_read_delay) log("Compass thread terminated")
def initialize(): try: robocomms.initialize() robopower.initialize() robocamera.initialize() robosensors.initialize() robonavigation.initialize() except RobotError as e: log("RobotException: " + e.value) log("Exception occurred in initialization - ending") robopower.halt() exit(0) return
def process_control_file(filename): """Parses the RoboMagellan control file. Returns a data structure with the route details if sucessful, otherwise NULL if an error is found""" log("Processing control file: " + filename) error_count = 0 control_data = [] # Process the file f = open(filename) while True: line = f.readline() log(">>> " + line.rstrip()) if not line: break result = process_control_line(line) if result == False: error_count = error_count + 1 elif result == None: pass else: control_data.append(result) f.close() # Return the control data or None to the caller if error_count == 1: log("Control file processed, " + str(error_count) + " error.") else: log("Control file processed, " + str(error_count) + " errors.") if error_count == 0: return control_data else: raise RobotError('Control file error')
def initialize(): try: control_data = robocontrol.process_control_file(sys.argv[1]) robocomms.initialize() robopower.initialize() robocamera.initialize() robosensors.initialize() robonavigation.initialize() except RobotError as e: log("RobotException: " + e.value) log("Exception occurred in initialization - ending") robopower.halt() exit(0) return control_data
def run(self): while self.run_flag == True: global ping_data, bumper_status self.ser.flushInput() # Discard readings buffered during sleep self.ser.readline() # Read five lines of data to get complete input for i in range(5): data = self.ser.readline().lower().strip() if data.find('bumper') == 0: if data.find('on') > 0: bumper_status = True elif data.find('off') > 0: bumper_status = False else: log("robosensors - recieved invalid bumper data: %s" % \ data) elif data.find('sensor') == 0: m = self.sensor_re.match(data) if m: ping_data[int(m.group(1))-1] = int(m.group(2)) else: log("robosensors - recieved invalid sensor data: %s" % \ data) else: log("robosensor - received invalid data %s" % data) time.sleep(roboconfig.sensor_read_delay) log("Sensor thread terminated")
def set_speed(self, k): k_val = 17 - abs(k) if k < 0: right_motor = "1,0,1,%s\n" % k_val left_motor = "2,0,0,%s\n" % k_val elif k == 0: right_motor = "1,1,0,0\n" left_motor = "2,1,0,0\n" else: right_motor = "1,0,0,%s\n" % k_val left_motor = "2,0,1,%s\n" % k_val log("Right: %s" % right_motor) log("Left: %s" % left_motor) self.ser.write(right_motor) self.ser.write(left_motor)
def main(): log("RoboMagellan 2012 started") initialize() time.sleep(1) # Allow time for processing threads to start try: mainloop() except: log("*** ERROR *** A fatal error has occured *** ERROR ***") log(str(traceback.format_exc())) else: log("RoboMagellan 2012 ended - Champagne Time!") # Stop the robot robopower.halt() # Terminate running threads for thread in threading.enumerate(): if thread.name != 'MainThread': log("Terminating thread: " + str(thread)) thread.stop()
def run(self): while True: global current_speed, target_speed # If necessary, bring current speed to target if current_speed != target_speed: if current_speed < target_speed: values = range(current_speed+1, target_speed+1) else: values = range(current_speed-1, target_speed-1, -1) for k in values: log("Setting speed to %d" % k) self.set_speed(k) current_speed = k time.sleep(roboconfig.power_delay) if self.run_flag == False: break time.sleep(roboconfig.power_delay) log("Power thread terminated")
def log_robot_status(): ping = robosensors.get_sensors() touch_sensor = robosensors.get_bumper() log(">> Speed=%d" % robopower.get_power()) log(">> Compass=%3.2f" % robosensors.get_compass()) log(">> Touch=%s, Ping1=%d, Ping2=%d, Ping3=%d" % \ (touch_sensor, ping[0], ping[1], ping[2]))
def process_cone_directive(line): # Parse Cone data cone_re = re.compile('CONE\s+(\d\d)(\d\d).(\d+)\s+(\d\d\d)(\d\d).(\d+)') m = cone_re.search(line) if not m: log("Invalid CONE directive in line: " + line) return False # Validate and calculate latitude lat_deg = int(m.group(1)) lat_min = int(m.group(2)) if lat_min > 59: log("Minutes must be less than 60 in latitude specification in line: " + line) return False lat_min = lat_min + int(m.group(3))/1000.0 lat_deg = lat_deg + lat_min/60.0 # Validate and calculate longitude lon_deg = int(m.group(4)) lon_min = int(m.group(5)) if lon_min > 59: log("Minutes must be less than 60 in longitude specification in line: " + line) return False lon_min = lon_min + int(m.group(6))/1000.0 lon_deg = lon_deg + lon_min/60.0 return {'command': "CONE", 'latitude': lat_deg, 'longitude': lon_deg}
def mainloop(control_data): for command in control_data: log("Processing command: " + repr(command)) if command['command'] == 'CONE': navigate_to(command['latitude'], command['longitude'], mode='cone') elif command['command'] == 'GOTO': navigate_to(command['latitude'], command['longitude'], mode='goto') elif command['command'] == 'DRIV': log("DRIV command not yet implemented") elif command['command'] == 'STOP': robopower.stop() return elif command['command'] == 'POWR': robopower.power(command['power']) elif command['command'] == 'STER': robopower.steer(command['steering']) elif command['command'] == 'WAIT': time.sleep(command['sleeptime']) else: # Should never happen: robocontrol should catch, but hey... log("Error in mainloop: invalid command " + command['command']) robopower.halt() raise RobotError
def re_sight_cone(): log("Re-sighting cone...") # Try a few times for i in range(roboconfig.re_sight_attempts): (camera_X, camera_Y, camera_distance) = robocamera.get_data() if camera_distance < roboconfig.max_camera_distance: log("...sucess!") return True else: time.sleep(re_sight_sleep_time) # Couldn't find it - return False log("...failed") return False
def speed(speed_value): assert(-16 <= speed_value <= 16) global target_speed log("Old target speed = %d" % target_speed) target_speed = speed_value log("New target speed = %d" % target_speed)
def stop(self): log("Terminating sensor thread") self.run_flag = False
def stop(self): log("Terminating compass thread") self.run_flag = False
def navigate_to(latitude, longitude, mode='cone'): assert (mode == 'cone') or (mode == 'goto') log("Navigate to lat: " + str(latitude) + ", lon: " + str(longitude)) log("Navigate to mode=" + mode) task_complete = False while task_complete == False: #TODO - probably need to time out # Get camera, compass heading, and GPS data (camera_X, camera_Y, camera_distance) = robocamera.get_data() log("Navigate to: camera_X = %03d, camera_Y = %03d, distance = %1.2f" \ % (camera_X, camera_Y, camera_distance)) current_heading = robosensors.get_compass() log("Navigate to: current heading = %d" % current_heading) (gps_distance, heading_to_target) = \ robonavigation.vector_to_target(latitude, longitude) log("Navigate to: target distance = %2.2f, vector = %d" % \ (gps_distance, heading_to_target)) # Test to see if we are at the GPS waypoint (within the radius of # error). We we are and we're in goto mode, we're done. Otherwise # switch to looking for the cone with the camera. if gps_distance < roboconfig.gps_radius: log("GPS waypoint found") if mode == 'goto': log("Goto mode - task complete") return else: # If we can see the cone at this point, go and locate # it. If we can't, keep going until we can see it. # # Note that locate_cone() may fail if the camera loses # sight of the cone. If that happens, we drop back to # locating the GPS waypoint again if camera_distance < roboconfig.max_camera_distance: if locate_cone() == True: return # Outside of GPS range - set the steer angle and drive/turn # towards the cone steer_angle = \ robonavigation.get_steer_angle(current_heading, heading_to_target) log("Navigate to: steer_angle = " + str(steer_angle)) robopower.speed(5) robopower.steer(steer_angle/180.0) # Slow things down! time.sleep(3)
def initialize(): log("Power initialization started") power_thread = PowerThread() power_thread.start() log("Power initialization completed") return True