UserPreferences

Pyro Devices


Pyro Devices

In the section on Robot Attributes, we learned how the attribute abstractions provide uniform access to all the devices available on a robot. By default, a small subset of the available devices are already activated. For example, the range attribute is activated for all robots, Pioneer robots also have the sonar devices and bumpers already activated.

So far, we have mostly looked at sensory devices, those that provide inputs that can be accessed using the dot-name format. For other devices, you may need actuator control as well as sensory control. For example, if a robot is equipped with a pan-tilt-zoom (PTZ) camera, you need to be able to access the image from the camera (a sensory modality) and also control the directionality of the camera by panning, tilting, or zooming. Similarly, a gripper device can be used to pick up objects (actuator control) and sense if the gripper is actually holding something (sensory). In this section we will learn the Pyro device interface that enables the use of all kinds of devices. Since different robots are expected to have different devices, their attributes etc. will vary.

In order to find out the set of available devices in Pyro, you can ask for the value of the builtinDevices attribute of the robot:

>>>  self.robot.builtinDevices
['bumper', 'truth', 'power', 'gripper', 'position', 'sonar', 'blobfinder', 'ptz']

The robot above has 8 available devices. Typically, as explained earlier, some of these (bumper and sonar) are already activated. You have already seen how to access the attributes of those devices. Let us take a look at the gripper device abstraction.

Pioneer Grippers

By default, the gripper device is not activated. Thus, if you try to access its attributes:

>>>  self.robot.gripper[0]
ERROR: exceptions.AttributeError no such directory item 'gripper'
exceptions.AttributeError: no such directory item 'gripper' in command line
You will get the above message. In order to enable access to a device, you have to start it:
>>>  self.startDevice('gripper')
Loading device 'gripper[0]'...
gripper[0]
If the device is successfully started, you will see the above response. Now, you can examine the gripper as a regular attribute (or click the View on the robot line in the GUI):
>>>  robot.printView()
---------------------------------
robot:
   .brain          = None
   .builtinDevices = ['position', 'sonar', 'gripper', 'simulation']
   .client         = <C playerc_client instance at _38dd9c09_p_playerc_client>
   .devices        = ['position', 'sonar', 'simulation', 'gripper']
   .gripper[0]:
      .active         = 1
      .breakBeamState = None
      .client         = <C playerc_client instance at _38dd9c09_p_playerc_client>
      .data           = None
      .dev            = 0
      .groups         = {}
      .handle         = <C playerc_gripper instance at _08dd9a09_p_playerc_gripper>
      .index          = 0
      .isClosed       = None
      .isLiftMaxed    = None
      .isLiftMoving   = None
      .isMoving       = None
      .name           = 'gripper0'
      .noise          = 0.0
      .number         = 0
      .printFormat    = {'data'}
      .state          = None
      .title          = 'gripper[0]'
      .type           = 'gripper'
      .visible        = 0
      .window         = 0
   .hostname       = 'localhost'
   .last_rotate    = 0.0
   .last_translate = 0.0
   .name           = 'Player6665'
   .port           = 6665
   .position[0]:
      .active         = 1
      .client         = <C playerc_client instance at _38dd9c09_p_playerc_client>
      .data           = None
      .dev            = 0
      .groups         = {}
      .handle         = <C playerc_position instance at _703c9909_p_playerc_position>
      .index          = 0
      .name           = 'position0'
      .noise          = 0.0
      .number         = 0
      .printFormat    = {'data'}
      .state          = 'stopped'
      .title          = 'position[0]'
      .type           = 'position'
      .visible        = 0
      .window         = 0
   .radius         = 0.75
   .range          = <pyrobot.robot.player.PlayerSonarDevice instance at 0xb7b70a2c>
   .simulated      = 1
   .simulation[0]:
      .active         = 1
      .client         = <C playerc_client instance at _f03d9d09_p_playerc_client>
      .data           = None
      .dev            = 0
      .groups         = {}
      .handle         = <C playerc_simulation instance at _f8a19909_p_playerc_simulation>
      .index          = 0
      .name           = 'simulation0'
      .noise          = 0.0
      .number         = 0
      .printFormat    = {'data'}
      .state          = 'stopped'
      .thread         = <PlayerUpdater(PlayerUpdater, started)>
      .title          = 'simulation[0]'
      .type           = 'simulation'
      .visible        = 0
      .window         = 0
   .sonar[0]:
      .active         = 1
      .client         = <C playerc_client instance at _38dd9c09_p_playerc_client>
      .count          = 16
      .data           = None
      .dev            = 0
      .groups         = {'all', 'right', 'right-back', 'front-all', 'back-left', 'left-front', 'back', 'right-front', 'back-all', 'front-left', 'front-right', 'front', 'back-right', 'left-back', 'left'}
      .handle         = <C playerc_sonar instance at _089c9a09_p_playerc_sonar>
      .index          = 0
      .maxvalue       = 10.6666666667
      .maxvalueraw    = 8.0
      .name           = 'sonar0'
      .noise          = 0.05
      .number         = 0
      .printFormat    = {'data'}
      .radius         = 0.75
      .rawunits       = 'METERS'
      .state          = 'stopped'
      .title          = 'sonar[0]'
      .type           = 'sonar'
      .units          = 'ROBOTS'
      .visible        = 0
      .window         = 0
   .stall          = 0
   .subtype        = 0
   .supportedFeatures = ['odometry', 'continuous-movement', 'range-sensor']
   .th             = 0.0
   .thr            = 0.0
   .thread         = <PlayerUpdater(PlayerUpdater, started)>
   .timestamp      = 1120146774.21
   .type           = 'Player'
   .units          = 'METERS'
   .x              = 0.0
   .y              = 0.0
>>> self.robot.gripper[0]
<pyrobot.robot.player.PlayerGripperDevice instance at 0xb7c40a4c>
Two commands were entered above. The first one listed all of a robot's attributes. Notice that after starting a gripper, the gripper appears as an attribute (gripper[0]). The second command shows the type of the gripper. Let us try and access some of the gripper attributes:
>>>  self.robot.gripper[0].name
gripper[0]
>>>  self.robot.gripper[0].type
gripper
>>>  self.robot.gripper[0].isClosed
0
>>>  self.robot.gripper[0].name = 'Jaws'
Ok
>>>  self.robot.gripper[0].name
Jaws
There are several specific values that can be given as various actuator commands for the gripper. These are listed below:
   .open()   - opens the paddles of the gripper.
   .close()  - closes the paddles of the gripper.
   .stop()   - stops the paddles if they are in motion.
   .up()     - raises the paddles up.
   .down()   - lowers the paddles down.
   .store()  - raises and closes the paddles.
   .deploy() - lowers and opens the paddles.
   .halt()   - stops both horizontal and vertical movement of the grippers.
Thus, to lower the gripper onto something, you will position the robot so that the gripper is open and positioned above the object. Then you would lower the gripper, close it, and lift it up:
>>>  self.robot.gripper[0].down()
Ok
>>>  self.robot.gripper[0].close()
Ok
>>>  self.robot.gripper[0].up()
Ok
Or, alternately, you could:
>>>  self.robot.gripper[0].deploy()
Ok
>>>  self.robot.gripper[0].store()
Ok

States of the gripper are accessible through the state and breakBeamState attributes. When queried, you will get a number returned which should be interpreted as shown below:

   Gripper States
      0 if paddles are moving.
      1 if paddles are open.
      2 if paddles are closed.

   Break Beam States - finds out if something is between the gripper paddles.
      0 if neither beam is broken.
      1 if back beam is broken.
      2 if front beam is broken.
      3 if both beams are broken.

Pioneer Pan-Tilt-Zoom Controls

This device is used to control a pan-tilt-zoom camera's actuator modes. To start this device do:

>>>  self.startDevice('ptz')
Loading device 'ptz0'...
<PTZObject>
You can examine the attributes of the device as shown below:
>>>  dir(self.robot.ptz[0])
[... 'command', 'data', 'name', 'pan', 'pose', 'tilt', 'type', 'zoom']
The current state of the ptz device can be obtained by accessing the pose attribute:
>>>  self.robot.ptz[0].getPose()
(0, 0, 60, 0, 0)
The numbers reported are the current values of pan, tilt, and zoom (or field of view) in degrees, followed by the pan and tilt velocities in degrees/second. All of these can be individually set using the set method on the command attribute:
self.robot.ptz[0].COMMAND()
where COMMAND is: setPose, pan, tilt, zoom.

Simulation

The simulation device is, obviously, only defined for simulations, specifically the Player/Stage, Gazebo and Pyrobot simulators. This interface allows you to query the robot to see exactly where it is in the world, and also to pick up the robot and place it any where you wish, even outside the defined world.

The simulation device will start automatically. You can access all its attributes:

>>>  self.robot.simulation[0].    (PRESS TAB)
>>>  self.robot.simulation[0].title
simulation[0]
>>>  self.robot.simulation[0].getPose("Pioneer")
(2000, 1250, -90)

Through the simulation device, you can also set the robot's position and heading:

>>> self.robot.simulation[0].setPose('Pioneer', (2.0, 2.0, 90))
ok

See the Player/Stage or Pyrobot Simulator documentation for more information on this device.

Starting devices on start-up

Some thought must be given to how you start and remove devices. For now, you should know that you can start up a device by selecting it from the Load -> Devices... menu, or listing it on the command line with the -d flag when you start Pyro. We'll also examine methods of loading devices programmatically in the next section.

More: Pyro Devices Advanced Next: Pyro Brains Up: PyroModuleIntroduction