def set_analog_voltage(self, v): """ Sets the robot's analog output voltage. Args: v (float): The output voltage to set. This is limited to the range of 0-10V. """ if self.simulated: raise SoarIOError('Cannot set the analog output of a simulated robot (yet)') # TODO: CMax integration else: # Sent the analog-digital output required to read it later try: self.arcos.send_command(DIGOUT, int(clip(v, 0, 10)*25.5) | 0xff00) except Timeout as e: # Recast arcos errors as Soar errors raise SoarIOError(str(e)) from e
def on_stop(self): if not self.simulated: try: self.arcos.send_command(STOP) # Stop the robot from moving self.arcos.send_command(ENABLE, 0) # Disable the motors after we've stopped except Timeout as e: # Recast arcos errors as Soar errors raise SoarIOError(str(e)) from e
def on_load(self): if self.simulated: self.arcos = None print('Connected to Pioneer p3dx-sh MIT_0042 (12.0 Volts) [Simulated]') print('Your robot\'s name is \'Denny\'') # Hi Denny Freeman! else: try: self.arcos = ARCOSClient() self.arcos.connect(forced_ports=self._serial_ports) self.arcos.send_command(ENABLE, 0) # We disable the motors so that the robot is easily movable # Continuously request IOpacs, and make sure we receive at least one self.arcos.send_command(IOREQUEST, 2) self.arcos.wait_or_timeout(self.arcos.io_event, 1.0, 'Could not access robot IO information') # Request a CONFIGpac and make sure we receive one self.arcos.send_command(CONFIG) self.arcos.wait_or_timeout(self.arcos.config_event, 1.0, 'Could not access robot configuration') config = self.arcos.config serial_num = str(getnode()) battery_volts = self.arcos.standard['BATTERY'] / 10.0 # Set the serial device for viewing self.serial_device = self.arcos.ser.name # Print the standard connection message and warn if the battery is low print('Connected to', ' '.join([config[field] for field in ['ROBOT_TYPE', 'SUBTYPE', 'NAME']]), 'on', self.serial_device, '(%s Volts)' % battery_volts) print('Your robot\'s name is \'%s\'' % name_from_sernum(serial_num)) if battery_volts < self.arcos.config['LOWBATTERY']/10.0: printerr('WARNING: The robot\'s battery is low. Consider recharging or finding a new one.') except ARCOSError as e: # If anything goes wrong, raise a SoarIOError raise SoarIOError(str(e)) from e
def analogs(self): """ Get the robot's 4 analog inputs, so long as it is real and not simulated, as a 4 tuple. """ if self.simulated: raise SoarIOError('Cannot access the inputs of a simulated robot (yet)') # TODO: CMax integration else: # Assume that the io information is relatively current return tuple([round(a*10.0/1023.0, 3) for a in self.arcos.io['ANALOGS'][4:]])
def rv(self, value): self._rv = clip(value, -self.RV_CAP, self.RV_CAP) if not self.simulated: try: self.arcos.send_command(RVEL, int(self._rv * 180 / pi)) # Convert radians/sec to degrees/sec except Timeout as e: # Recast arcos errors as Soar errors raise SoarIOError(str(e)) from e
def fv(self, value): self._fv = clip(value, -self.FV_CAP, self.FV_CAP) if not self.simulated: # For real robots, must send an ARCOS command try: self.arcos.send_command(VEL, int(self._fv*1000)) # Convert m/s to mm/s except Timeout as e: # Recast arcos errors as Soar errors raise SoarIOError(str(e)) from e
def on_start(self): if not self.simulated: for _ in range(5): # Try enabling motors a few times if self.arcos.standard['FLAGS'] & 0x1 != 0x1: # If the motors have not been enabled try: self.arcos.send_command(ENABLE, 1) # Re-enable them except Timeout as e: # Recast arcos errors as Soar errors raise SoarIOError(str(e)) from e sleep(1.0) else: # If they have been, we're all set break if self.arcos.standard['FLAGS'] & 0x1 != 0x1: # If they still aren't enabled, raise an error raise SoarIOError('Unable to enable the robot\'s motors') try: self.arcos.send_command(SETO) except Timeout as e: # Recast arcos errors as Soar errors raise SoarIOError(str(e)) from e
def on_load(self): """ Called when the controller of the robot is loaded. The behavior of this method should differ depending on the value of `simulated`; if it is `False`, this method should be used to connect with the real robot. If a connection error occurs, a :class:`soar.errors.SoarIOError` should be raised to notify the client that the error was not due to other causes. """ if not self.simulated: raise SoarIOError('BaseRobot has no real interface to connect to')