Difference between revisions of "API Reference"

Jump to: navigation , search
(Enable Robot)
(Python Code API)
 
(86 intermediate revisions by one other user not shown)
Line 5: Line 5:
  
 
</div>
 
</div>
 +
 +
{{TOClimit|limit=2}}
  
 
<div class="content-block">
 
<div class="content-block">
  
== ROS Topic API Reference ==
+
= ROS Topic API Reference =
  
  
===Python Code API===
+
==Python Code API==
: For the [[Robot Interface|Robot Interface]] Python classes (built on top of the ROS API), please see the [https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/index.html Code API Reference] page.
+
: For the [[Robot Interface|Robot Interface]] Python classes (built on top of the ROS API), please see the [https://rethinkrobotics.github.io/intera_sdk_docs/index.html Code API Reference] page.
 
 
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 26: Line 27:
 
* [[#Robot Description (URDF)|Robot Description (URDF)]]
 
* [[#Robot Description (URDF)|Robot Description (URDF)]]
 
||
 
||
* '''[[#Joints|Joints]]'''
+
* [[#Joints|Joints]]  
 
** [[#Arm Joints|Arm Joints]]
 
** [[#Arm Joints|Arm Joints]]
 
** [[#Head Joints|Head Joints]]
 
** [[#Head Joints|Head Joints]]
 
* [[#Cartesian Endpoint|Cartesian Endpoint]]
 
* [[#Cartesian Endpoint|Cartesian Endpoint]]
 
** [[#Endpoint State|Endpoint State]]
 
** [[#Endpoint State|Endpoint State]]
** [[#Inverse Kinematics Solver Service|IK Solver]]
+
** [[#Kinematics Solver Service|Kinematics Solver Service]]
 
* [[#Gripper (End-Effector)|Gripper (End-Effector)]]
 
* [[#Gripper (End-Effector)|Gripper (End-Effector)]]
 
||
 
||
* '''[[#Sensors|Sensors]]'''
+
* [[#Accelerometer|Accelerometer]]
** [[#Accelerometers|Accelerometers]]
 
** [[#IR Range|IR Range]]
 
** [[#Sonar|Sonar]]
 
 
* [[#Cameras|Cameras]]
 
* [[#Cameras|Cameras]]
 
* [[#Head Display Screen|Head Display Screen]]
 
* [[#Head Display Screen|Head Display Screen]]
Line 44: Line 42:
 
* [[#Cuff Buttons|Cuff Buttons]]
 
* [[#Cuff Buttons|Cuff Buttons]]
 
* [[#Lights|LED Lights]]
 
* [[#Lights|LED Lights]]
* [[#Digital IO|Digital IO]]
 
* [[#Analog IO|Analog IO]]
 
 
|}
 
|}
  
Line 52: Line 48:
 
<div class="content-block">
 
<div class="content-block">
  
== Robot ==
+
= Robot =
  
=== Enable Robot ===
 
Be sure that you 'Enable' the robot before attempting to control any of the motors.  The easiest method for controlling the robot is to use the <code>enable_robot.py</code> ROS executable found in the following example.
 
* [https://github.com/RethinkRobotics/intera_sdk/blob/master/intera_interface/scripts/enable_robot.py Enable Robot Script]
 
* [Key Use Tips in Enable Robot]
 
  
=== Robot Description (URDF) ===
+
== Enable Robot ==
Sawyer automatically builds an appropriate URDF (Unified Robot Description Format) on boot and loads it onto the ROS Parameter Server, under the ROS parameter name <code>/robot_description</code>.  From here, it is accessible by rviz, tf and other ROS utilities that use the URDF. If you want to grab a copy of the actual URDF xml file yourself, see the [[HowTo - Main|How To's]].
+
Be sure that you 'Enable' the robot before attempting to control any of the motors.  The easiest method for controlling the robot is to use the <code>enable_robot.py</code> ROS executable found in the following example:[https://github.com/RethinkRobotics/intera_sdk/blob/master/intera_interface/scripts/enable_robot.py Enable Robot Script]
*  [[Robot Description]]
 
*  [[HowTo - Main|Getting the URDF]]
 
  
</div>
+
=== Robot State ===
 +
<code>/robot/state</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/AssemblyState.html intera_core_msgs/AssemblyState])
 +
Subscribe to the Robot State for the enabled and error state of the robot hardware itself. It also includes information on the EStop.
 +
The robot must be enabled (<code>enabled: true</code>) in order to move the robot. Use the [https://github.com/RethinkRobotics/intera_sdk/blob/master/intera_interface/scripts/enable_robot.py Enable Robot Script], or the "Enable Robot Topic" below, to enable the robot.
 +
It is possible for the robot to have non-fatal errors, so <code>error</code> can be <code>true</code> while <code>enabled</code> is also <code>true</code>.
 +
For more complete information on robot state, see [[E-STOP and Enable Robot]].
  
<div class="content-block">
+
=== Enable Robot ===
 +
<code>/robot/set_super_enable</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/Bool.html std_msgs/Bool]) 
 +
<code>data</code>: <code>true</code> to Enable robot motors; <code>false</code> to disable.
 +
You can check the Robot State Topic to see if the robot enabled properly or if it has an error.
  
== Movement ==
+
=== Reset Robot State ===
=== Joints ===
+
<code>/robot/set_super_reset</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/Empty.html std_msgs/Empty])   
Sawyer has 7 joints (DoF) in arm and one more joint in its head (side-to-side panning).  The control for the head is done separately from the arm; however, you can read the current joint states (position, velocity, and effort) for all the joints on arm and head by subscribing to one topic:
+
Publish an Empty message to reset the state after an error.
<code>/robot/joint_states</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/JointState.html sensor_msgs-JointState])   
+
A reset will clear all pre-existing errors and the state (it will disable).
where the units for the position of a joint are in (rad), the units of velocity are in (rad/s) and the units of effort in each joint is in (Nm).
 
  
The following sections cover the individual joint sensing and control in more detail:
 
* [[#Arm Joints|Arm Joints]]
 
* [[#Head Joints|Head Joints]]
 
  
=== Cartesian Endpoint ===
+
== Robot Description (URDF) ==
Published at 100 Hz, the endpoint state topic provides the current Cartesian Position, Velocity and Effort at the endpoint for either limb.
 
  
The following sections covered the endpoint state and IK Solver in more detail:
+
Sawyer automatically builds an appropriate URDF (Unified Robot Description Format) on boot and loads it onto the ROS Parameter Server, under the ROS parameter name <code>/robot_description</code>.  From here, it is accessible by rviz, tf and other ROS utilities that use the URDF.
* [[#Endpoint State|Endpoint State]]
 
* [[#IK Solver|IK Solver]]
 
  
=== Gripper (End-Effector) ===
+
The [http://wiki.ros.org/urdf Unified Robot Description Format (URDF)] is the standard ROS XML representation of the robot model (kinematics, dynamics, sensors) describing Sawyer.
Before using an End-Effector, or Gripper, you must first send the calibration command. You can check whether the gripper has been calibrated yet by echoing on the gripper state topic for that hand. Once calibrated, gripper can be controlled using the simplified command_grip and command_release topics, or using the more direct command_set topic.
 
For more information on using the gripper, see the [[Gripper_Example | Gripper Example Program]].
 
  
The following sections cover the gripper configuration, gripper state and simple gripper control in more detail:
+
Sawyer generates his URDF dynamically on robot startup. This model is updated when any gripper is attached or detached, an object is 'grasped' or released and its mass is compensated for, and when new urdf segments are provided/commanded to the gripper plugins. As of SDK versions >= 1.0.0 Sawyer's internal robot model, is loaded to the [http://wiki.ros.org/Parameter%20Server parameter server] on the topic <code>/robot_description</code>
* [[#Gripper Configuration|Gripper Configuration]]
 
* [[#Gripper State|Gripper State]]
 
* [[#Simple Gripper Control|Simple Gripper Control]]
 
  
</div>
+
The default URDF for Sawyer is available in the [https://github.com/RethinkRobotics/intera_common intera_common] repository. The package <code> sawyer_description </code> contains the URDF and accompanying meshes.
  
<div class="content-block">
+
=== Getting a Copy of the URDF from the parameter server ===
  
== Arm Joints ==
+
You can now get the current URDF describing '''your''' Sawyer.
  
'''Component IDs:'''<br />
+
From a [[SDK_Shell | properly initialized]] Sawyer environment, export the URDF from the <code>/robot_description</code> parameter on the ROS parameter server where it is stored, to a file of your choice (ex: <code>sawyer_urdf.xml</code>):
<code>right_j0</code>, <code>right_j1</code>, <code>right_j2</code>, <code>right_j3</code>, <code>right_j4</code>, <code>right_j5</code>, <code>right_j6</code> 
 
  
=== Arm Joint States ===
+
<source lang="bash">
 +
$ rosparam get -p /robot_description | tail -n +2 > sawyer_urdf.xml
 +
</source>
  
<code>/robot/joint_states</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/JointState.html sensor_msgs-JointState]) 
+
The <code>-p</code> outputs the parameter using pretty print. The output urdf is piped through the <code>tail</code> command first to remove a dummy first line - an artifact of the pretty print.
* <code>name[i]</code>: '<component_id>' of <code>i</code>-th joint in message value arrays.
 
* <code>position[i]</code>: position of joint <code>i</code> rad
 
* <code>velocity[i]</code>: velocity of joint <code>i</code> in rad/s
 
* <code>effort[i]</code>: effort applied in joint <code>i</code> in Nm
 
  
Joint states are published by the <code>robot_state_publisher</code> and are updated with information from the sensors for every cycle.
+
'''Tip:''' You can check that you now have a proper URDF by running:
 +
<source lang="bash">
 +
$ rosrun urdfdom check_urdf sawyer_urdf.xml
 +
</source>
  
''Set Joint State Publishing Rate''  <br />
+
=== Robot State Publisher ===
<code>/robot/joint_state_publish_rate</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/UInt16.html std_msgs-UInt16]) 
 
* The rate at which the joints are published can be controlled by publishing a frequency on this topic.
 
* Default rate is 100Hz; Maximum is 800Hz.
 
  
=== Arm Joint Control ===
+
The URDF is used by Sawyer's [http://wiki.ros.org/urdf Robot State Publishers] to create a tree of [http://wiki.ros.org/tf transforms (tfs)]. In fact, Sawyer has two of such publishers:
There are currently four modes for controlling the arms: Joint Position Mode, Joint Velocity Mode, and Joint Torque Mode, and Joint Trajectory Mode.
+
'''robot_ref_publisher''': publishes transforms that reflect the commanded robot state.
 +
'''robot_state_publisher''': publishes transforms that reflect the measured state of the robot.
  
For Joint Trajectory Mode, a joint trajectory action server has been created in support of timestamped joint position trajectories using the ROS standard [http://www.ros.org/wiki/joint_trajectory_action joint trajectory action].
+
These robot publishers live internal to Sawyer and are accessible to the RSDK over ROS. The "ref" tfs are used by the robot internals, but you may find them useful to see where the robot will move at the next timestep. Otherwise, be sure to use the non-"ref" transforms if you're only interested in the Sawyer's current state.
  
For more information on joint control, see the following [[Example Programs#movement|movement example programs.]]
+
=== Getting a Copy of the URDF Dynamically ===
 +
Sawyer generates the URDF dynamically on initialization, based on the attached arm.  In some cases, users may want to get the current URDF off the robot. 
 +
From a working Sawyer RSDK environment, export the URDF from the <code>/robot_description</code> parameter on the ROS parameter server where it is stored, to a file of your choice (ex: <code>sawyer_urdf.xml</code>):
  
==== Joint Control Mode ====
+
<source lang="bash">
Each arm can be in independent control modes by publishing the desired control mode to the topic for the appropriate arm.
+
$ rosparam get -p /robot_description | tail -n +2 > sawyer_urdf.xml
 +
</source>
  
==== Position Mode ====
+
The <code>-p</code> outputs the parameter using pretty print.  The output urdf is piped through the <code>tail</code> command first to remove a dummy first line - an artifact of the pretty print.
The first is Position Mode, in which users publish target joint angles for given joints and the internal controller drives the arm to the published angles.
 
  
==== Velocity Mode ====
+
'''Tip:''' You can check that you now have a proper URDF by running:
In Velocity Control Mode, users publish velocities for given joints and the joints will move at the specified velocity.
 
  
==== Torque Mode ====
+
<source lang="bash">
'''''Warning:''' Advanced Control Mode.''  </br>
+
$ rosrun urdf_parser check_urdf sawyer_urdf.xml
In Torque Control Mode, users publish torques for given joints and the joints will move at the specified torque.
+
</source>
 
 
==== Trajectory Mode ====
 
'''''Warning:''' Advanced Control Mode.'' 
 
In Trajectory Control Mode, users publish desired joint positions. Where these commands would typically be modified in traditional 'Position Mode', these commands are passed directly to the Joint Controller Boards (JCBs). The only limitation placed on Trajectory commands is it requires a user-computed Position, Velocity, and Acceleration at each timestamp.
 
 
 
''Switching Modes''  <br />
 
<code>/robot/limb/right/joint_command</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/JointCommand.html intera_core_msgs/JointCommand]) 
 
* Mode is set implicitly by specifying the mode in the command message. Publish a <code>JointCommand</code> message to the <code>joint_command</code> topic for a given arm to set the arm into the desired control mode.
 
* Constants for each mode are defined in the <code>JointCommand</code> message type.
 
 
 
=== Joint Trajectory Action ===
 
The Joint Trajectory Action provides an [http://www.ros.org/wiki/actionlib ROS action interface] for tracking trajectory execution.
 
 
 
The joint trajectory action server provides an action interface for execution of trajectories requested by the client, known as a ''Goal* request.
 
The joint trajectory action server then executes the request trajectory communicating the *Result'' response. The actionlib (action server/client interface) package differs from ROS services, simple request/response interface, in that actions allow mid-execution cancellation, they can also provide feedback during execution as to the progress of the Goal request.
 
 
 
''Joint Trajectory Action Server''  <br />
 
<code>/robot/limb/right/follow_joint_trajectory/cancel</code><br />
 
<code>/robot/limb/right/follow_joint_trajectory/feedback</code><br />
 
<code>/robot/limb/right/follow_joint_trajectory/goal</code><br />
 
<code>/robot/limb/right/follow_joint_trajectory/result</code><br />
 
<code>/robot/limb/right/follow_joint_trajectory/status</code>
 
 
 
=== Usage: ===
 
<syntaxhighlight lang="bash" enclose="div">
 
    # Verify that the robot is enabled:
 
    $ rosrun intera_interface enable_robot.py
 
    # Start the joint trajectory action server:
 
    $ rosrun intera_interface joint_trajectory_action_server.py
 
</syntaxhighlight>
 
 
 
Please see the [[Joint Trajectory Playback Example|joint trajectory playback example]] for examples of creating a client of this action server and requesting a joint trajectory.
 
 
 
=== Parameters: ===
 
The joint trajectory action server provides a number of parameters which describe it's behavior during the trajectory execution. These were largely designed to follow [http://www.ros.org/wiki/joint_trajectory_action#ROS_API these standards.]
 
 
 
'''Note:''' All of these parameters will be initialized on startup of the trajectory_controller.py if they were not previously specified.
 
<code>/rethink_rsdk_joint_trajectory_controller/<joint_name>__kp</code>
 
The proportional gain with which the joint trajectory controller will track the commanded trajectory for the specified joint.
 
 
 
<code>/rethink_rsdk_joint_trajectory_controller/<joint_name>__kd</code>
 
The derivative gain with which the joint trajectory controller will track the commanded trajectory for the specified joint.
 
 
 
<code>/rethink_rsdk_joint_trajectory_controller/<joint_name>__ki</code>
 
The integral gain with which the joint trajectory controller will track the commanded trajectory for the specified joint.
 
 
 
<code>/rethink_rsdk_joint_trajectory_controller/goal_time (double, default: 0.0)</code>
 
The amount of time (in seconds) that the controller is permitted to be late to the goal. If goal_time has passed and the controller still has not reached the final position (within the parameters described by <code>/rethink_rsdk_joint_trajectory_controller/<joint_name>_goal</code>, then the goal is aborted.
 
 
 
<code>/rethink_rsdk_joint_trajectory_controller/<joint>_goal (double, default: -1.0)</code>
 
The maximum final error for <joint> for the trajectory goal to be considered successful. Negative numbers indicate that there is no constraint. Given in units of joint position (radians). If this constraint is violated, the goal is aborted.
 
 
 
<code>/rethink_rsdk_joint_trajectory_controller/trajectory (double, default: -1.0)</code>
 
The maximum error for <joint> at any point during execution for the trajectory goal to be considered successful. Negative numbers indicate that there is no constraint. Given in units of joint position (radians). If this constraint is violated, the goal is aborted.
 
 
 
'''''Dynamic Reconfigure GUI''''' is suggest for use with ROS Distributions >=Indigo for setting these parameters.
 
    # Start the dynamic reconfigure GUI:
 
    $ rosrun rqt_reconfigure rqt_reconfigure
 
Expand the joint trajectory controller's parameters by choosing <code>rethink_rsdk_joint_trajectory_controller</code> from the left menu. Use the sliders/input fields to specify these parameters dynamically.
 
 
 
Alternatively, these parameters can be set  [http://www.ros.org/wiki/rosparam#YAML_Format via a YAML file, command line, or programmatically (rospy, roscpp)].
 
 
 
=== Collision Avoidance ===
 
'''''Warning:''' RETHINK ROBOTICS DISCLAIMS COMPLIANCE BY THE PRODUCTS WITH ANSI, ISO OR OTHER INDUSTRIAL ROBOT SAFETY STANDARDS. RETHINK’S PRODUCTS INCLUDE CERTAIN SAFETY AND/OR COLLISION DETECTION TECHNOLOGY TO PREVENT POSSIBLE INJURY FROM USE OF THE PRODUCTS. THE USER ACKNOWLEDGES THAT HE/SHE HAS THE ABILITY TO DISABLE CERTAIN SAFETY MECHANISMS INCLUDED IN THE PRODUCTS, AND IF DISABLED BY USER, USER ASSUMES ALL RESPONSIBILITY FOR DAMAGE AND/OR HARM CAUSED BY THE PRODUCTS AND AGREES TO INDEMNIFY RETHINK ROBOTICS FROM ALL LIABILITY RELATING TO SUCH DAMAGE OR HARM.'' 
 
 
 
In certain situations, collision avoidance (forces applied to the joints to avoid self collision) are undesirable. 
 
 
 
''Torso Collision Avoidance''  <br />
 
<code>/robot/limb/right/suppress_collision_avoidance</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/Empty.html std_msgs-Empty])
 
* To disable torso self collision avoidance, a std_msgs/Empty message must be published at a rate greater than 5 Hz.
 
 
 
 
 
For additional information on joint control, see the [[Joint Position Example]], [[Head Movement Example]], and [[MoveIt Tutorial|MoveIt! Tutorial]].
 
  
 +
If this doesn't work, you can just remove the tail command and use a text editor to manually remove the first few lines before the actual xml (all the lines before <code><?xml version="1.0" ?></code>).
 +
<source lang="bash">
 +
    $ rosparam get -p /robot_description > sawyer_urdf.xml
 +
    $ head sawyer_urdf.xml
 +
    | 
 +
      <?xml version="1.0" ?> 
 +
      <!-- =================================================================================== --> 
 +
      <!-- |    This document was autogenerated by xacro from sawyerp2.urdf.xacro            | --> 
 +
    ... 
 +
    $ gedit sawyer_urdf.xml &
 +
    $ head sawyer_urdf.xml
 +
      <?xml version="1.0" ?> 
 +
      <!-- =================================================================================== --> 
 +
      <!-- |    This document was autogenerated by xacro from sawyerp2.urdf.xacro            | --> 
 +
    ...
 +
</source>
 
</div>
 
</div>
  
<div class="content-block">
 
 
== Endpoint State ==
 
 
<code>/robot/limb/right/endpoint_state</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/EndpointState.html intera_core_msgs-EndpointState])
 
* The endpoint state message provides the current <code>position/orientation pose</code>, <code>linear/angular velocity</code>, and <code>force/torque effort</code> of the robot end-effector at 100 Hz. Pose is in Meters, Velocity in m/s, Effort in Nm.
 
* The robot's "endpoint" is definied as the <code>right_gripper</code> tf frame. This frame is updated dynamically when gripper is connected to the robot or a [[Gripper Customization]] command is sent.
 
* ''New in v1.0.0:'' The [[URDF]] on the parameter server will now update when the Robot Model is updated by Gripper changes. Check the ROS Parameter for an updated copy of the URDF, especially before using IK or motion planners, such as [[MoveIt_Tutorial|MoveIt!]].
 
 
</div>
 
  
 
<div class="content-block">
 
<div class="content-block">
  
== Inverse Kinematics Solver Service ==
+
= Movement =
The robot software provides a simple Position Inverse Kinematics (IK) Solver as a ROS Service.  Specify a desired Cartesian coordinate and orientation for an Endpoint (in world x,y,z space), and the solver will return a set of joint angles that will get the arm there - or return an Invalid state if the pose is unreachable.  An optional seed to start looking for solutions around can be specified as a joint angle configuration.
 
  
Note that the service takes an '''array''' of requests, and similarly returns an array of results with corresponding indexes. Similarly, optional seeds for each Endpoint request can be provided in a corresponding array of the same size as the requests array. This multiple array structure is a common structure used in ROS and explained in the [http://docs.ros.org/api/sensor_msgs/html/msg/JointState.html sensor_msgs/JointState] message.
 
  
'''SolvePositionIK Service [srv]''' <br />
+
== Joints ==
<code>/ExternalTools/<side>/PositionKinematicsNode/IKService</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/srv/SolvePositionIK.html intera_core_msgs/SolvePositionIK.srv])
+
Sawyer has 7 joints (DoF) in arm and one more joint in its head (side-to-side panning). The control for the head is done separately from the arm; however, you can read the current joint states (position, velocity, and effort) for all the joints on arm and head by subscribing to one topic:
* ''Request''
+
<code>/robot/joint_states</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/JointState.html sensor_msgs-JointState])
** <code>pose_stamp</code> (Required) - an array of geometry_msgs/PoseStamped requests, each defining the Cartesian &lt;x,y,z&gt; Position and Quaternion orientation of the [[#Cartesian Endpoint|Endpoint]] in the <code>/base</code> TF frame.
+
where the units for the position of a joint are in (rad), the units of velocity are in (rad/s) and the units of effort in each joint is in (Nm).
** (Optional) <code>seed_angles</code> - an array of joint configuration seeds to start searching for solutions around, corresponding to each request in <code>pose_stamp</code>, where each individual seed is defined as a JointState message with the joint names and positions filled for all the arm Joints (so <code>seed_angles</code> is an array of arrays).
 
** (Optional) <code>seed_mode</code> - specify the IK solver strategy for what types of seeds to use. By default (<code>SEED_AUTO</code>), the solver will iterate through the different strategies, starting with the user provided seed if it exists, until a solution is found.  However, by explicitly setting the <code>seed_mode</code> to a specific mode, the solver will only return whether it was able to find a solution using that type of seed. The different mode types are defined as constants in the message (default: SEED_AUTO):
 
**: <source lang="bash">    uint8 SEED_AUTO    = 0
 
    uint8 SEED_USER    = 1
 
    uint8 SEED_CURRENT = 2
 
    uint8 SEED_NS_MAP  = 3
 
</source>
 
**:
 
* ''Response''
 
** <code>result_type</code> will be a corresponding array of uint8's, which will be 0 if no valid joint solution was found for the given Endpoint request; otherwise, it will be non-zero and correspond to the type of seed eventually used that gave a valid solution. These values correspond to the constants in the message used to specify <code>seed_mode</code>.
 
** <code>isValid</code> will be a corresponding array of booleans which will be True if a valid joint solution was found for the given Endpoint request.
 
** <code>joints</code> will contain joint solutions corresponding to each Endpoint request. Note that you should '''always''' check the <code>result_type</code> field to see if a valid joint solution was found, as invalid joint solutions can be returned in this array.
 
  
This service allows users to solve for basic IK joint angle solutions or perform workspace validation.  The service will use a number of seeding strategies to find a solution.  These strategies can be specified explicitly or just use the default to find the first solution in the possible methods.  Optionally a Joint configuration can optionally be provided as a seed to the Solver.
+
=== Arm Joints ===
 +
The following sections cover the arm joints sensing and control in more detail: [[Arm Joints]].
  
==== Example: ====
+
=== Head Joints ===
<syntaxhighlight lang="bash" enclose="div">
 
# Seeded request call to the service
 
$ rosservice call /ExternalTools/right/PositionKinematicsNode/IKService "pose_stamp:
 
- header:
 
    seq: 0
 
    stamp: now
 
    frame_id: 'base'
 
  pose:
 
    position:
 
      x: 0.657579481614
 
      y: 0.851981417433
 
      z: 0.0388352386502
 
    orientation:
 
      x: -0.366894936773
 
      y: 0.885980397775
 
      z: 0.108155782462
 
      w: 0.262162481772
 
seed_angles:
 
- header: auto
 
  name: ['right_j0', 'right_j1', 'right_j2', 'right_j3', 'right_j4', 'right_j5', 'right_j6']
 
  position: [0.4371845240478516, 1.8419274289489747, 0.4981602602966309, -1.3483691110107423, -0.11850001572875977, 1.18768462366333, -0.002300971179199219]
 
seed_mode: 0"
 
</syntaxhighlight>
 
<syntaxhighlight lang="bash" enclose="div">
 
# Returns:
 
joints:
 
  -
 
    header:
 
      seq: 0
 
      stamp:
 
        secs: 0
 
        nsecs: 0
 
      frame_id: ''
 
    name: ['right_j0', 'right_j1', 'right_j2', 'right_j3', 'right_j4', 'right_j5', 'right_j6']
 
    position: [0.015646076449046253, -0.5693474841530352, -0.022853580106295266, 1.2930237760722652, 0.05272603583796626, 0.27210782958564905, -0.03912130822108171]
 
    velocity: []
 
    effort: []
 
isValid: [True]
 
result_type: [1]
 
</syntaxhighlight>
 
 
 
</div>
 
 
 
<div class="content-block">
 
 
 
== Head Joints ==
 
 
 
=== Head Position and State ===
 
 
The head state topic will give you the current <code>pan</code> angle (side-to-side) of the head and report boolean status flags if the robot is currently moving its head.   
 
The head state topic will give you the current <code>pan</code> angle (side-to-side) of the head and report boolean status flags if the robot is currently moving its head.   
  
 
'''Note: Flags may not report 'true' values until after the first respective movement command is sent.'''   
 
'''Note: Flags may not report 'true' values until after the first respective movement command is sent.'''   
  
'''Component ID:''' <br /> <code>head_pan</code>  
+
'''Component ID:'''<code>head_pan</code>  
  
 
'''Head State:'''  <br />
 
'''Head State:'''  <br />
<code>/robot/head/head_state</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/HeadState.html intera_core_msgs-HeadState])
+
<code>/robot/head/head_state</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/HeadState.html intera_core_msgs-HeadState]). <code>pan</code> field gives you the current angle (radians) of the head.  0 is forward, <code>-pi/2</code> to Sawyer's right, and <code>+pi/2</code> to Sawyer's left. <code>isPanning</code> is boolean field that will switch to True while the robot is executing a command.   
* <code>pan</code> field gives you the current angle (radians) of the head.  0 is forward, <code>-pi/2</code> to Sawyer's right, and <code>+pi/2</code> to Sawyer's left.
 
* <code>isPanning</code> is boolean field that will switch to True while the robot is executing a command.   
 
  
 
'''Note: The <code>isPanning</code> field is initialized to True upon startup and will update thereafter.'''
 
'''Note: The <code>isPanning</code> field is initialized to True upon startup and will update thereafter.'''
  
 
'''Head (Joint) State:'''  <br />
 
'''Head (Joint) State:'''  <br />
<code>/robot/joint_states</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/JointState.html sensor_msgs-JointState])
+
<code>/robot/joint_states</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/JointState.html sensor_msgs-JointState]).The position of the head may also be determined from the <code>joint_state</code> message.
* The position of the head may also be determined from the <code>joint_state</code> message.
 
  
 
=== Head Movement Control ===
 
=== Head Movement Control ===
 
'''Pan Head:'''  <br />
 
'''Pan Head:'''  <br />
 
<code>/robot/head/command_head_pan</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/HeadPanCommand.html intera_core_msgs-HeadPanCommand])   
 
<code>/robot/head/command_head_pan</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/HeadPanCommand.html intera_core_msgs-HeadPanCommand])   
* <code>target</code> sets the target angle.  0.0 is straight ahead.
+
<code>target</code> sets the target angle.  0.0 is straight ahead.
* <code>speed</code> is an integer from [0-100], 100 = max speed.
+
<code>speed</code> is an integer from [0-100], 100 = max speed.
* Setting an angle in the command_head_pan topic does not gurantee the head will get to that position.  There is a small deband around the reference angle around the order of +/- 0.12 radians.
+
Setting an angle in the command_head_pan topic does not gurantee the head will get to that position.  There is a small deband around the reference angle around the order of +/- 0.12 radians.
+
 
 
=== Example: ===
 
=== Example: ===
<syntaxhighlight lang="bash">
+
<source lang="bash">
 
     # Check head position/state:  
 
     # Check head position/state:  
 
     $ rostopic echo /robot/head/head_state
 
     $ rostopic echo /robot/head/head_state
 
     # Move (pan) head side-to-side:  
 
     # Move (pan) head side-to-side:  
 
     $ rostopic pub /robot/head/command_head_pan intera_core_msgs/HeadPanCommand -- 0.0 100
 
     $ rostopic pub /robot/head/command_head_pan intera_core_msgs/HeadPanCommand -- 0.0 100
</syntaxhighlight>
+
</source>
 +
 
 +
 
 +
 
 +
== Cartesian Endpoint ==
 +
Published at 100 Hz, the endpoint state topic provides the current Cartesian Position, Velocity and Effort at the endpoint for either limb.
 +
 
 +
=== Endpoint State ===
 +
'''Endpoint State''': <code>/robot/limb/right/endpoint_state</code>  [https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/EndpointState.html intera_core_msgs-EndpointState]).
 +
The endpoint state message provides the current <code>position/orientation pose</code>, <code>linear/angular velocity</code>, and <code>force/torque effort</code> of the robot end-effector at 100 Hz. Pose is in Meters, Velocity in m/s, Effort in Nm.
 +
The robot's "endpoint" is definied as the <code>right_gripper</code> tf frame. This frame is updated dynamically when gripper is connected to the robot <!--or a [[Gripper Customization]] command is sent-->.
 +
The [[Robot Description | URDF]] on the parameter server will now update when the Robot Model is updated by Gripper changes. Check the ROS Parameter for an updated copy of the URDF, especially before using IK or motion planners, such as [[MoveIt_Tutorial|MoveIt!]].
 +
 
 +
=== Kinematics Solver Service ===
 +
The following sections cover the Forward Kinematics Solver Service and Inverse Kinematics Solver Service in more detail: [[Kinematics Solvers |Kinematics Solvers]]
  
</div>
 
  
<div class="content-block">
 
  
 
== Gripper (End-Effector) ==
 
== Gripper (End-Effector) ==
Before using an End-Effector, or Gripper, you must first send the calibration command. You can check whether the gripper has been calibrated yet by echoing on the gripper state topic for that hand. Once calibrated, gripper can be controlled using the simplified command_grip and command_release topics, or using the more direct command_set topic.
+
Before using an End-Effector, or Gripper, you must first send the calibration command. You can check whether the gripper has been calibrated yet by echoing on the gripper state topic for that hand. Once calibrated, gripper can be controlled using the simplified command_grip and command_release topics, or using the more direct command_set topic.
 
+
For more information on using the gripper, see the [[Gripper_Example | Gripper Example Program]].
For more information on using the gripper, see the [[Gripper Example|Gripper Example Program]].
 
  
==== Gripper Configuration ====
+
=== Gripper Configuration ===
 
([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/IOComponentCommand.html intera_core_msgs-IOComponentCommand])
 
([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/IOComponentCommand.html intera_core_msgs-IOComponentCommand])
  
''Calibrate Gripper''  <br />
+
'''Calibrate Gripper'''  <br />
<code>/robot/end_effector/right_gripper/command</code> 
+
Publish an IO Command message to calibrate a new gripper by set signal <code>calibrate</code> to <code>True</code>. Gripper should open and close once.
* Publish an End Effector Command message to calibrate a new gripper. Gripper should open and close once.
+
The <code>calibrated</code> field of the gripper state topic will also update to '1' after successful calibration.
* The <code>calibrated</code> field of the gripper state topic will also update to '1' after successful calibration.
+
Once calibrated, the gripper will not calibrate again unless the command reset message is sent, or the robot is restarted.
* Once calibrated, the gripper will not calibrate again unless the command reset message is sent, or the robot is restarted.
 
  
''Reset Gripper''  <br />
+
'''Reset Gripper'''  <br />
<code>/robot/end_effector/<side>_gripper/command</code>
+
Publish an IO Command message to reset the gripper state by set signal <code>reboot</code> to <code>True</code>.
* Publish a End Effector Command message to reset the gripper state.
+
The <code>calibrated</code> field of the gripper state message will reset to '0'.
* The <code>calibrated</code> field of the gripper state message will reset to '0'.
 
  
==== Gripper State ====
+
=== Gripper State ===
''Gripper State''  <br />
+
'''Gripper State'''  <br />
<code>/robot/end_effector/<side>_gripper/state</code>
+
<code>/io/end_effector/state</code>
* The <code>calibrated</code> field must be true (1) before you can control the gripper.  Use the command_calibrate topic to calibrate the gripper.
+
The io signal <code>calibrated</code> field must be true (1) before you can control the gripper.  Use the IO command to calibrate the gripper.
* The gripper state message will also give you the current <code>position</code>, <code>force</code>, and if the gripper is current <code>moving</code>.  Position is from [0.0-100.0] [close-open].
+
The gripper state message will also give you the current <code>position</code>, <code>force</code>, and if the gripper is current <code>moving</code>.  Position is from [0.0-100.0] [close-open].
  
==== Simple Gripper Control ====
+
=== Simple Gripper Control ===
''Simple Gripper Close'' <br />  
+
'''Simple Gripper Close''' <br />  
<code>/robot/end_effector/right_gripper/state</code>
+
<code>/io/end_effector/command</code> the signal <code>'position_m'</code> value to MIN_POSITION: 0.0.
* Publish a End Effector Command message to grip.
+
Publish an IO Command message to grip.
  
''Simple Gripper Open''  <br />
+
'''Simple Gripper Open'''  <br />
<code>/robot/end_effector/right_gripper/state</code>
+
<code>/io/end_effector/command</code> the signal <code>'position_m'</code> value to MAX_POSITION: 0.041667.
* Publish a End Effector Command message to release.
+
Publish an IO Command message to release.
  
 
</div>
 
</div>
 +
  
 
<div class="content-block">
 
<div class="content-block">
  
== Sensors ==
+
= Sensors+ =
  
=== Accelerometers ===
+
== Accelerometer ==
Each hand has a 3-axis accelerometer located inside the cuff, in the same plane as the gripper electrical connection header.  The positive z-axis points back 'up' the arm (towards the previous wrist joint, w0).  The positive x-axis points towards the camera, and the y-axis points towards the cuff buttons, using standard [http://en.wikipedia.org/wiki/Right-hand_rule Right-Hand-Rule] notation.
+
The robot hand has a 3-axis accelerometer located inside the cuff, in the same plane as the gripper electrical connection header.  The positive z-axis points back 'up' the arm (towards the previous wrist joint, j6).  The positive x-axis points towards the direction of gripper, and the y-axis points towards the cuff buttons, using standard [http://en.wikipedia.org/wiki/Right-hand_rule Right-Hand-Rule] notation.
  
 
'''Component IDs:''' <br />
 
'''Component IDs:''' <br />
<code>left_accelerometer</code>, <code>right_accelerometer</code>   
+
<code>right_accelerometer</code>   
  
''Read Linear Acceleration'' <br />
+
'''Accelerometer State:''' <br />
<code>/robot/accelerometer/<component_id>/state</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/Imu.html sensor_msgs-Imu])
+
<code>/robot/accelerometer/<component_id>/state</code>([https://http://docs.ros.org/api/sensor_msgs/html/msg/Imu.html sensor_msgs-ImuMessage])  
* Acceleration values (in m/s^2) are published under <code>linear_acceleration</code> for the x, y, and z axes.  The force of gravity is NOT compensated for.
 
* Note: <code>linear_acceleration</code> is currently the only valid data in the message.  The sensor_msgs/Imu ROS message type is used for the sake of compatibility and standardization.
 
  
=== IR Range ===
+
Acceleration values (in m/s^2) are published under <code>linear_acceleration</code> for the x, y, and z axes.  The force of gravity is NOT compensated for.
There are two IR Range sensors on each hand.  The sensor data is published on the tf frame <code><side>_hand_range</code>, and points down the +x axis, as is convention for [http://ros.org/wiki/rviz/DisplayTypes/Range rviz].
 
  
'''Component IDs:''' <br />
+
<source lang="bash">
<code>left_hand_range</code>, <code>right_hand_range</code>
+
names: ['right_accelerometer']
 +
states:
 +
  -
 +
    header:
 +
      seq: 120921
 +
      stamp:
 +
        secs: 0
 +
        nsecs: 0
 +
      frame_id: ''
 +
    orientation:
 +
      x: 0.0
 +
      y: 0.0
 +
      z: 0.0
 +
      w: 0.0
 +
    orientation_covariance: [-1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
 +
    angular_velocity:
 +
      x: 0.0
 +
      y: 0.0
 +
      z: 0.0
 +
    angular_velocity_covariance: [-1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
 +
    linear_acceleration:
 +
      x: 0.0
 +
      y: 0.0
 +
      z: 0.0
 +
    linear_acceleration_covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
 +
</source>
  
''Read Range Sensor Measurements'' <br />
 
<code>/robot/range/<component_id></code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/Range.html sensor_msgs-Range]) 
 
* Range is published in meters in the <code>range</code> field.
 
* When the sensor goes beyond its max range, the invalid value of 65.5350036621(m) is published instead.  Users should check for valid measurements using the <code>min_range</code> and <code>max_range</code> fields.
 
  
=== Sonar ===
+
== Cameras ==
Mounted in a ring around the head are 12 sonar distance sensorsThere is also a yellow LED around each sensor that, by default, triggers when the corresponding sensor measures a distance below its threshold. For more information on controlling the lights on Baxter's head, see the [[#Lights|Lights]] section.
+
You can access Sawyer's hand camera and the head camera using the standard ROS image types and image_transport mechanism listed belowYou can use the ROS Services to open, close, and configure each of the cameras. See the [[Camera Image Display Example]] for more information on using the cameras. Useful tools for using cameras in ROS include [http://wiki.ros.org/rviz/DisplayTypes/Camera rviz Camera Display].
  
'''Component IDs:''' <br />
+
'''IMPORTANT:''' You can only have one open at a time at standard resolutions, due to bandwidth limitations.
<code>head_sonar</code> 
 
  
==== Read Sonar 3D Distances (Point Cloud) ====
+
'''Component IDs:''' <code>right_hand_camera</code>, <code>head_camera</code>
The sonar range measurements are published as a set of 3D coordinate points in space around Baxter, called a PointCloud.  This gives a "mapping" of detections in the workspace and is well-suited for occupancy-oriented reasoning in the robot's world.
 
  
''Read Sonar Point Cloud'' <br />
+
'''Camera Published Topics'''
<code>/robot/sonar/head_sonar/state</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/PointCloud.html sensor_msgs-PointCloud]) 
 
* The PointCloud message takes all the individual sonar range measurements and instead, uses the known locations of the sonar sensors on the robot, to map the readings into 'points' in 3D space that mark the location of detected objects.
 
* The points for all incoming, valid, current readings are collected each time and published as an array in the PointCloud message.
 
* Note: the result of this is that each published message contains measurements for only a subset of the sensors, not readings for all 12 sensors every time.
 
* There will be a Point for each ''currently active measurement'' - this means a message published at one instant could contain points for only 4 of the sensors, and, also, another instant the published message could contain two points for the same sensor if the sensor had two valid measurements in the last time interval.
 
* The <code>points</code> field contains the array of the actual 3D Points - one for each current measurement - in terms of the (x,y,z) coordinates for each point, relative to Baxter's <code>base</code> tf frame.
 
* The <code>channels</code> field contains arrays with additional information about each point.  The values in each array map 1:1 to the values at the same indices in the <code>points</code> array.
 
* The array with the name <code>SensorId</code> lists which physical sensor each point came from.
 
* The array with the name <code>Distance</code> lists the original range measurement from that sensor.
 
  
=== Cameras ===
+
Raw Image: <code>/internal_camera/<component_id>/image_raw</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/Image.html sensor_msgs-Image]) 
  
You can access Sawyer's hand camera and the head camera using the standard ROS image types and image_transport mechanism listed below.  You can use the ROS Services to open, close, and configure each of the cameras.  See the [[Camera Control Example]] and [[Using the Cameras]] for more information on using the cameras. Useful tools for using cameras in ROS include [[rviz]] and the [[image_view]] program.
+
Camera Intrinsics: <code>/internal_camera/<component_id>/camera_info</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/CameraInfo.html sensor_msgs-CameraInfo])
'''IMPORTANT:''' You can only have one open at a time at standard resolutions, due to bandwidth limitations. The hand camera is opened by default at boot-time,
 
  
'''Component IDs:'''
+
Rectify Color Image: <code>/internal_camera/head_camera/image_rect_color</code> ([http://wiki.ros.org/image_proc image_proc])
<code>right_hand_camera</code>, <code>head_camera</code>
 
  
==== Camera Published Topics ====
+
Rectify Image: <code>/internal_camera/right_hand_camera/image_rect</code> ([http://wiki.ros.org/image_proc image_proc])
''Raw Image'' 
 
<code>/cameras/<component_id>/image</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/Image.html sensor_msgs-Image])
 
  
''Camera Intrinsics'' 
 
<code>/cameras/<component_id>/camera_info</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/CameraInfo.html sensor_msgs-CameraInfo]) 
 
  
''Standardized Camera Intrinsics'' 
+
== Head Display Screen ==
<code>/cameras/<component_id>/camera_info_std</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/CameraInfo.html sensor_msgs-CameraInfo])  
+
Images can be displayed on Sawyer's LCD screen by publishing the image data as a ROS <code>sensor_msgs/Image</code>.   
  
==== Camera Control Services ====
+
'''Display Image'''<code>/robot/head_display</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/Image.html sensor_msgs-Image]).
''List Cameras Service_  '''[ _srv'' ]'''
 
<code>/cameras/list</code> ([http://github.com/RethinkRobotics/intera_common/blob/release-0.7.0/intera_core_msgs/srv/ListCameras.srv intera_core_msgs-ListCameras])
 
* ''Call:'' 
 
    $ rosservice call /cameras/list
 
* ''Returns:'' 
 
    cameras: ['<camera_name-1>', ... '<camera_name-n>']
 
* Returns list of camera names.
 
  
''Close Camera_  '''[ _srv'' ]''' 
+
Publish image data as a [http://ros.org/wiki/sensor_msgs ROS Image message] to update the display.
<code>/cameras/close</code> ([http://github.com/RethinkRobotics/intera_common/blob/release-0.7.0/intera_core_msgs/srv/CloseCamera.srv intera_core_msgs-CloseCamera]
+
The screen resolution is 1024 x 600. Images smaller than this will appear in the top-left corner.
* ''Call:'' 
+
There are dedicated ROS packages for working with and sending ROS Image messages, including [http://ros.org/wiki/image_transport image_transport] and [http://ros.org/wiki/image_pipeline image_pipeline].   
    $ rosservice call /cameras/close <camera_name>
+
Useful tools for working with images in ROS include [http://wiki.ros.org/image_view Image_view] and [http://ros.org/wiki/image_transport#republish republish]. Also see [http://ros.org/wiki/camera_drivers camera_drivers] for assistance working with your own cameras.
* ''Returns:''
 
    err: <error_number> # 0, for success
 
* Call this service with the <code><camera_name></code> argument set to the name of the camera to close (see List Cameras Service above).  
 
* Closes the specified camera.
 
* If successful: Returns '0' in <code>err</code> field.
 
* Else: Returns non-zero, integer error-code in <code>err</code> field.
 
** From the command line, the camera name string can be given as an argument with or without quotes.
 
 
 
''Open Camera_  '''[ _srv'' ]''' 
 
<code>/cameras/open</code> ([http://github.com/RethinkRobotics/intera_common/blob/release-0.7.0/intera_core_msgs/srv/OpenCamera.srv intera_core_msgs-OpenCamera]) 
 
* ''Call:''  
 
    $ rosservice call /cameras/open '{name: <camera_name>, settings: {<optional settings>}}''
 
* ''Returns:''
 
    err: <error_number> # 0, for success
 
* Call this service with at least the <code>name:</code> field set to <code><camera_name></code> (see List Cameras Service above).  
 
* Opens the specified camera, with the optional <code>settings</code> parameters if given (see service type for more info on options).
 
* If successful: Returns '0' in <code>err</code> field.
 
* Else: Returns non-zero, integer error-code in <code>err</code> field.
 
** From the command line, the camera name string can be given as an argument with or without quotes.
 
* Currently available resolutions are: MODES = [(1280, 800); (960, 600); (640, 400); (480, 300); (384, 240); (320, 200)] 
 
 
 
===== Example: =====
 
    # List available cameras
 
    $ rosservice call /cameras/list
 
    cameras: ['head_camera', 'left_hand_camera', 'right_hand_camera']
 
    # Close open camera
 
    $ rosservice call /cameras/close left_hand_camera
 
    err: 0
 
    # Open head camera with optional resolution
 
    $ rosservice call /cameras/open '{name: right_hand_camera, settings: {width: 960, height: 600 }}'
 
    err: 0
 
    # View now open camera topics
 
    $ rostopic list /cameras
 
    /cameras/head_camera/camera_info
 
    /cameras/head_camera/camera_info_std
 
    /cameras/head_camera/image
 
    /cameras/right_hand_camera/camera_info
 
    /cameras/right_hand_camera/camera_info_std
 
    /cameras/right_hand_camera/image
 
  
 +
For more information on displaying images to Sawyer's LCD screen, see the [[Head Display Image Example]].
 
</div>
 
</div>
  
 
<div class="content-block">
 
<div class="content-block">
  
== Inputs and Outputs ==
+
= Inputs and Outputs =
 
 
=== Navigators ===
 
There are four Navigators on Baxter's body: two on each side of the torso and one on each arm.  Each Navigator is comprised of three push buttons, one of which is also an indexing scroll wheel, and two sets of blue LED lights.
 
 
 
'''Component IDs:'''<br />
 
<code>left_itb</code>, <code>right_itb</code>, <code>torso_left_itb</code>, <code>torso_right_itb</code>
 
 
 
==== Navigator Input Buttons ====
 
''Read Button States''  <br />
 
<code>/robot/itb/<component_id>/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/ITBState.msg baxter_core_msgs-ITBState]) 
 
* The states of the three push buttons are the first three values in the boolean <code>buttons[]</code> array.  A value of 'True' indicates the button is currently pushed down. The order is as follows:
 
*  OK_BUTTON (<code>buttons[0]</code>):  The circular button in the middle of the Navigator.
 
*  CANCEL_BUTTON (<code>buttons[1]</code>):  The button 'above' the OK_BUTTON, typically with a 'Back' arrow symbol.
 
*  SHOW_BUTTON (<code>buttons[2]</code>):  The SHOW_BUTTON, or "Rethink Button", is 'below' the OK_BUTTON, and typically is labeled with the Rethink logo.
 
 
 
''Read Wheel Index''  <br />
 
<code>/robot/itb/<component_id>/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/ITBState.msg baxter_core_msgs-ITBState]) 
 
* The <code>wheel</code> field returns an integer between [0-255].  Each physical 'click' of the wheel corresponds to a +/-1 increment.  The value will loop when it goes above or below the bounds. 
 
 
 
==== Control Navigator Lights ====
 
There are two sets of lights on each Navigator: the 'inner' light ring around the circular OK Button, and the 'outer' oval light ring around the entire Navigator.  Each light is identified by the 'Component ID' of its Navigator followed by <code>_light_inner</code> or <code>_light_outer</code>.
 
 
 
'''Component IDs:'''  <br />
 
Inner Lights: <code>left_itb_light_inner</code>, <code>right_itb_light_inner</code>, <code>torso_left_itb_light_inner</code>, <code>torso_right_itb_light_inner</code>  <br />
 
Outer Lights: <code>left_itb_light_outer</code>, <code>right_itb_light_outer</code>, <code>torso_left_itb_light_outer</code>, <code>torso_right_itb_light_outer</code> 
 
 
 
''Turn LEDs On/Off''  <br />
 
<code>/robot/digital_io/command</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalOutputCommand.msg baxter_core_msgs-DigitalOutputCommand])
 
* name: <code><navigator_component_id>_light_inner</code>, <code><navigator_component_id>_light_outer</code> 
 
* value: {True, False} 
 
   
 
* Publish a DigitalOutputCommand message with the component id of the light as the <code>name</code> and a <code>value</code> of <code>True</code> or <code>False</code> to turn the LEDs On or Off, respectively.
 
 
 
''Check State of LEDs''  <br />
 
<code>/robot/digital_io/<light_component_id>/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg//DigitalIOState.msg baxter_core_msgs-DigitalIOState]) 
 
* The <code>state</code> field will give you the current setting of the LED, ON(1) or OFF(0).
 
 
 
=== Shoulder Buttons ===
 
There are two shoulder buttons on the back of the torso, one on each side.  The state of each button is published in a DigitalIOState message under its own topic (DigitalIOState constants: PRESSED==1, UNPRESSED==0).
 
 
 
'''Component IDs:'''<br />
 
<code>left_shoulder_button</code>, <code>right_shoulder_button</code>
 
 
 
''Read Button Pressed''  <br />
 
<code>/robot/digital_io/<side>_shoulder_button/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalIOState.msg baxter_core_msgs-DigitalIOState]) 
 
* The integer field <code>state</code> will read PRESSED (1) when the button is pressed down, and UNPRESSED (0) otherwise.
 
  
=== Cuff Buttons ===
 
There are two buttons and one touch sensor in the cuff of each hand.  The state of each button is published in a DigitalIOState message under its own topic (DigitalIOState constants: PRESSED==1, UNPRESSED==0).
 
  
==== Cuff (Squeeze) Sensor ====
+
== Navigators ==
'''Component IDs:''' <Br />
+
There are two Navigators on Sawyer's body: one on side of the body and one on the arm.  Each Navigator is comprised of three push buttons, one of which is also an indexing scroll wheel, and one set of white LED light.
<code>left_lower_cuff</code>, <code>right_lower_cuff</code> 
 
  
''Read Cuff Squeezed'' <br />
+
'''Component IDs''': <code>right, head</code>
<code>/robot/digital_io/<side>_lower_cuff/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalIOState.msg baxter_core_msgs-DigitalIOState]) 
 
* Integer <code>state</code> will read PRESSED (1) when the cuff sensor is squeezed, and UNPRESSED (0) otherwise.
 
  
==== Cuff OK Button ====
+
'''Read Button States:'''<code>/io/robot/navigator/state</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/IODeviceStatus.html intera_core_msgs-IODeviceStatus])
This is the circular button on the cuff.  <br />
 
'''Component IDs:'''<br />
 
<code>left_lower_button</code>, <code>right_lower_button</code>
 
  
''Read OK Button Pressed''<br  /> 
+
'''Wheel State:'''<code>/io/robot/navigator/state</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/IODeviceStatus.html intera_core_msgs-IODeviceStatus])
<code>/robot/digital_io/<side>_lower_button/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalIOState.msg baxter_core_msgs-DigitalIOState])
 
* Integer <code>state</code> will read PRESSED (1) when the button is pressed, and UNPRESSED (0) otherwise.
 
  
==== Cuff Grasp Button ====
+
'''Command Buttons:'''<code>/io/robot/navigator/command</code>([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/IOComponentCommand.html intera_core_msga-IOComponentCommand])
This is the long, thin button on the cuff. 
 
'''Component IDs:'''<br />
 
<code>left_upper_button</code>, <code>right_upper_button</code>
 
  
''Read Grasp Button Pressed''<br />
+
The states of the push buttons are the values type in integer at <code>data</code> area. For the wheel on navigator, the <code>data</code> field returns an integer between [0-255]. Each physical 'click' of the wheel corresponds to a +/-1 increment. The value will loop when it goes above or below the bounds.   
<code>/robot/digital_io/<side>_upper_button/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalIOState.msg baxter_core_msgs-DigitalIOState])  
+
The values have corresponding meaning: <code>0:'OFF', 1:'CLICK', 2:'LONG_PRESS', 3:'DOUBLE_CLICK'</code>
* Integer <code>state</code> will read PRESSED (1) when the button is pressed, and UNPRESSED (0) otherwise.
 
  
=== Lights  ===
 
  
* LEDs <span id="LEDs">&nbsp;</span>
+
*   '''<Component ID>_button_ok:'''  The circular button in the middle of the navigator.
** [[#Halo LEDs|Head Halo (Red, Green)]]
+
*  '''<Component ID>_button_back:'''  The button above the OK button, typically with a 'Back' arrow symbol.
** [[#Sonar LED Indicators|Sonar Rings (Yellow)]]
+
*   '''<Component ID>_button_show:'''  The "Rethink Button", is above the OK button, next to back button and typically is labeled with the Rethink logo.
** [[#Navigator Lights|Navigator LEDs (inner, outer)]]
+
*   '''<Component ID>_button_triangle(the 'X' button):'''  The button below circle button and square button.
 +
*   '''<Component ID>_button_circle:'''  The button labeled with a circle, next to the square button.
 +
*   '''<Component ID>_button_square:'''  The button labeled with a square, next to the circle button.
 +
*  '''<Component ID>_wheel:''' The wheel of circular button in the middle of the navigator.
  
=== (Head) Halo LEDs ===
 
The 'Halo' light is the red/green light at the top of Baxter's head.  The Halo is actually two separate lights - one for the red, one for the green - whose intensity levels can be independently controlled and mixed to produce a range of colors.
 
  
''Control Light Brightness'' <br />
+
== Cuff Buttons ==
<code>/robot/sonar/lights/set_red_level</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/Float32.html std_msgs-Float32]) <br />
+
There are two buttons and one touch sensor in the cuff of the hand: cuff button, OK button and cuff grasp button.  The state of each button is published in a DigitalIOState message under its own topic (DigitalIOState constants: PRESSED==1, UNPRESSED==0). Integer <code>data</code> will read PRESSED (1) when the cuff sensor is squeezed, and UNPRESSED (0) otherwise.
<code>/robot/sonar/lights/set_green_level</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/Float32.html std_msgs-Float32])
 
* Set the brightness level of the red or green light using a value between 0.0 (full off) and 100.0 (full on).
 
  
''Read Current Light Levels'' <br />
+
'''Component IDs:''' <code>right_cuff, right_button_lower, right_button_upper</code>.  
<code>/robot/sonar/head_sonar/lights/red_level</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/Float32.html std_msgs-Float32]) <br />
 
<code>/robot/sonar/head_sonar/lights/green_level</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/Float32.html std_msgs-Float32]) 
 
* Brightness ranges from 0.0 (full off) to 100.0 (full on).
 
  
=== Sonar LED Indicators ===
+
'''Read Button Squeezed:''' <code>/io/robot/cuff/state</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/IODeviceStatus.html intera_core_msgs-IODeviceStatus])
  
The yellow LEDs surrounding each sonar sensor on the head default to automatically being turned on or off when something enters/leaves the respective sensor's range.  This behavior can be overridden by publishing on the control topic below.  The published value should be the bit-wise OR of the desired mode and state for the 12 individual LEDs.  The two modes are Normal (sensor-based) operation, and Manual Override.  See the definitions below.  '''Note:''' Make sure you constantly publish the values at rate of at least 100Hz or the LEDs will timeout and revert to Normal operation.
+
'''Command Cuff:'''<code>/io/robot/cuff/command</code>([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/IOComponentCommand.html intera_core_msga-IOComponentCommand])
  
To set the LEDs, pick one of the 'Mode's and OR it with any of the individual LED States desired:
 
<code>
 
    # Mode
 
    DEFAULT_BEHAVIOR = 0x0000;
 
    OVERRIDE_ENABLE  = 0x8000;
 
    # States
 
    ALL_LIGHTS_OFF  = 0x8000;
 
    ALL_LIGHTS_ON    = 0x0fff;
 
    LED_0_ON    0x0001
 
    LED_1_ON    0x0002
 
    LED_2_ON    0x0004
 
    LED_3_ON    0x0008
 
    LED_4_ON    0x0010
 
    LED_5_ON    0x0020
 
    LED_6_ON    0x0040
 
    LED_7_ON    0x0080
 
    LED_8_ON    0x0100
 
    LED_9_ON    0x0200
 
    LED_10_ON    0x0400
 
    LED_11_ON    0x0800
 
    LED_ALL_ON  0x8FFF
 
    LED_ALL_OFF  0x8000
 
</code>
 
  
''Control Lights''  
+
== Lights  ==
<code>/robot/sonar/head_sonar/lights/set_lights</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/UInt16.html std_msgs-UInt16]) 
+
The head LEDs at the top of Sawyer's head, and navigator LEDs are inside of navigator.
* If bit 15 is zero, LEDs are controlled locally by Sonar.
 
* Set bit 15 to enable overrides, bits 0-11 to control individual channel LEDs.
 
* To use these flags, OR the OVERRIDE_ENABLE flag with the desired x_ON flags.
 
  
''State of Lights'' 
+
To get state or set command to HALO and Navigator LEDS, we are using <code>IODeviceInterface</code> to config, status and command topics. The data are type in bool in <code>data</code> area.
<code>/robot/sonar/head_sonar/lights/state</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/UInt16.html std_msgs-UInt16])
 
  
=== Navigator LEDs ===
+
'''Lights Component IDs:'''<br />
''(See: [[#Navigator Lights|Navigator Lights]])''
+
<code>head_red_light</code>, <code>head_blue_light</code>, <code>head_green_light</code>, <code>right_hand_blue_light</code>, <code>right_hand_green_light</code>,  <code>right_hand_red_light</code>
  
=== Digital IO ===
+
'''LEDs State:''' <code>/io/robot/robot/state</code> ([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/IODeviceStatus.html intera_core_msgs-IODeviceStatus])
  
''Read Digital Input State''  <br />
+
'''Command Light:'''<code>/io/robot/robot/command</code>([https://rethinkrobotics.github.io/intera_sdk_docs/5.0.4/intera_core_msgs/html/msg/IOComponentCommand.html intera_core_msga-IOComponentCommand])
<code>/robot/digital_io/<component_id>/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalIOState.msg baxter_core_msgs-DigitalIOState]) 
 
* <code>state</code>: field will be 0 (for True, Pressed, On) or 1 (for False, Released, Off).  If the component is an output, then the <code>state</code> field will be the current setting of the output.
 
* <code>isInputOnly</code>: field tells you if the component is an input (sensor) only, and cannot output (not a light, actuator, nor indicator).
 
 
 
''Control Digital Output'' 
 
<code>/robot/digital_io/command</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalOutputCommand.msg baxter_core_msgs-DigitalOutputCommand]) 
 
* name: <code><component_id></code>
 
* value: {True, False}
 
   
 
* Publish a DigitalOutputCommand message with the component id of the Output as the <code>name</code> and a <code>value</code> of <code>True</code> or <code>False</code> to turn the Output On or Off, respectively.
 
 
 
 
 
 
 
{| class="wikitable"
 
!colspan="3"|All Digital Component IDs:
 
|-
 
!colspan="3" style="text-align:left;"|Outputs
 
|-
 
|style="width:3em;"| <!-- spacer cell for columns; need once in table -->
 
|Nav Inner Lights: || <code>left_itb_light_inner</code>, <code>right_itb_light_inner</code>, <code>torso_left_itb_light_inner</code>, <code>torso_right_itb_light_inner</code>
 
|-
 
| ||Nav Outer Lights || <code>left_itb_light_outer</code>, <code>right_itb_light_outer</code>, <code>torso_left_itb_light_outer</code>, <code>torso_right_itb_light_outer</code>
 
|-
 
| ||Configure Valves: || <code>left_blow</code>, <code>right_blow</code>, <code>left_suck</code>, <code>right_suck</code>
 
|-
 
| ||Actuate Pneumatics:|| <code>left_pneumatic</code>, <code>right_pneumatic</code>
 
|-
 
| ||Camera Power: || <code>left_hand_camera_power</code>, <code>right_hand_camera_power</code>, <code>torso_camera_power</code>
 
|-
 
!colspan="3" style="text-align:left;"|Inputs
 
|-
 
| ||(Analog) Raw IR Range Values: || <code>left_hand_range</code>, <code>right_hand_range</code>
 
|-
 
| ||Back Shoulder Buttons: || <code>left_shoulder_button</code>, <code>right_shoulder_button</code>
 
|-
 
| ||Cuff (Squeeze) Sensor: || <code>left_lower_cuff</code>, <code>right_lower_cuff</code>
 
|-
 
| ||Cuff OK Button: || <code>left_lower_button</code>, <code>right_lower_button</code>
 
|-
 
| ||Cuff Grasp Button: || <code>left_upper_button</code>, <code>right_upper_button</code>
 
|-
 
| ||Safety Mat 'is attached': || <code>torso_process_sense0</code>
 
|-
 
| ||Safety Mat 'is NOT actuated': || <code>torso_safety_stop</code>
 
|}
 
 
 
=== Pneumatics ===
 
Baxter is equipped with a pneumatic valve system that can be controlled independently on the left and right sides and fed to proper grippers for suction-based picking.
 
&nbsp;&nbsp;
 
 
 
==== Configure Valves ====
 
''Blow'' 
 
'''Component IDs:'''
 
<code>left_blow</code>, <code>right_blow</code> 
 
<code>/robot/digital_io/<side>_blow/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalIOState.msg baxter_core_msgs-DigitalIOState]) 
 
* Use to switch on/off the suck ''valve'' -- (does not activate suction).
 
* Use this setting to grip objects in most cases.
 
 
 
''Suck'' 
 
'''Component IDs:'''
 
<code>left_suck</code>, <code>right_suck</code> 
 
<code>/robot/digital_io/<side>_suck/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalIOState.msg baxter_core_msgs-DigitalIOState]) 
 
* Use to switch off the blow ''valve'' -- (does not activate suction).
 
* Use this setting to release objects in most cases.
 
 
 
==== Actuate Pneumatics ====
 
''Turn On/Off Pneumatic Pressure/Airflow'' 
 
'''Component IDs:'''
 
<code>left_pneumatic</code>, <code>right_pneumatic</code> 
 
<code>/robot/digital_io/<side>_pneumatic/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalIOState.msg baxter_core_msgs-DigitalIOState]) 
 
*  This is how to use the pneumatic message.
 
 
 
==== Camera Power ====
 
'''Component IDs:'''
 
<code>left_hand_camera_power</code>, <code>right_hand_camera_power</code>, <code>torso_camera_power</code> 
 
<code>/robot/digital_io/<location>_camera_power/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/DigitalIOState.msg baxter_core_msgs-DigitalIOState])
 
 
 
=== Analog IO ===
 
 
 
''(Analog) Input State'' 
 
<code>/robot/analog_io/<component_id>/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/AnalogIOState.msg baxter_core_msgs-AnalogIOState]) 
 
* <code>value</code>: is an integer often either rounded up from the hundreds decimal place or going from [0-100] 
 
 
 
''(Analog) Output Control'' 
 
<code>/robot/analog_io/command</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/AnalogOutputCommand.msgbaxter_core_msgs-AnalogOutputCommand]) 
 
* name: <code><component_id></code>
 
* value: [0-65535] - (uint16)
 
   
 
* Publish a AnalogOutputCommand message with the component id of the Output as the <code>name</code> and a uint16 <code>value</code> from [0-65535].
 
 
 
 
 
{| class="wikitable"
 
!colspan="3"|All Analog Component IDs
 
|-
 
!colspan="3" style="text-align:left;"|Outputs
 
|-
 
|style="width:3em;"| <!-- spacer cell for columns; need once in table -->
 
|Workspace Lights: || <code>torso_lighting</code>
 
|-
 
| ||Torso Fan: || <code>torso_fan</code>
 
|-
 
!colspan="3" style="text-align:left;"|Inputs
 
|-
 
| ||(Analog) Raw IR Range Values: || <code>left_hand_range</code>, <code>right_hand_range</code>
 
|-
 
| ||Vacuum Sensor: || <code>left_vacuum_sensor_analog</code>, <code>right_vacuum_sensor_analog</code>
 
|}
 
 
 
==== Torso Fan ====
 
'''Component IDs:'''
 
<code>torso_fan</code> 
 
''Control Fan Speed'' 
 
<code>/robot/analog_io/command</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/AnalogOutputCommand.msg baxter_core_msgs-AnalogOutputCommand]) 
 
* value: [0-100] power to the fan:
 
* (0 = Auto, 1 = Off, 100 = Full-on)
 
* Auto: Automatic control by hardware, based on torso board heatsink. 
 
 
 
''Fan State'' 
 
<code>/robot/analog_io/torso_fan/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/AnalogIOState.msg baxter_core_msgs-AnalogIOState]) 
 
* <code>value</code>: Current fan setting [0.0-100.0]
 
 
 
==== (Analog) Raw IR Range Values ====
 
Values are shifted by 3 decimal points (essentially in mm). 
 
'''Component IDs:'''
 
<code>left_hand_range</code>, <code>right_hand_range</code> 
 
 
 
''Standard Integer Value'' 
 
<code>/robot/analog_io/<side>_hand_range/value_uint32</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/UInt32.html std_msgs-UInt32])  <br />
 
''Analog Stamped State'' 
 
<code>/robot/analog_io/<side>_hand_range/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/AnalogIOState.msg baxter_core_msgs-AnalogIOState]) 
 
 
 
==== Vacuum Sensor ====
 
'''Component IDs:'''
 
<code>left_vacuum_sensor_analog</code>, <code>right_vacuum_sensor_analog</code>  <br />
 
''Standard Integer Value'' 
 
<code>/robot/analog_io/<side>_vacuum_sensor_analog/value_uint32</code> ([http://www.ros.org/doc/api/std_msgs/html/msg/UInt32.html std_msgs-UInt32])  <br />
 
''Analog Stamped State'' 
 
<code>/robot/analog_io/<side>_vacuum_sensor_analog/state</code> ([http://github.com/RethinkRobotics/baxter_common/blob/release-0.7.0/baxter_core_msgs/msg/AnalogIOState.msg baxter_core_msgs-AnalogIOState])
 
  
 
</div>
 
</div>
 
<div class="content-block">
 
 
== Head Display Screen ==
 
Images can be displayed on Sawyer's LCD screen by publishing the image data as a ROS <code>sensor_msgs/Image</code>. 
 
 
''Display Image'' 
 
<code>/robot/head_display</code> ([http://www.ros.org/doc/api/sensor_msgs/html/msg/Image.html sensor_msgs-Image]) 
 
* Publish image data as a [http://ros.org/wiki/sensor_msgs ROS Image message] to update the display.
 
* The screen resolution is 1024 x 600.  Images smaller than this will appear in the top-left corner. 
 
* There are dedicated ROS packages for working with and sending ROS Image messages, including [http://ros.org/wiki/image_transport image_transport] and [http://ros.org/wiki/image_pipeline image_pipeline]. 
 
* Useful tools for working with images in ROS include [http://wiki.ros.org/image_view Image_view] and [http://ros.org/wiki/image_transport#republish republish]. Also see [http://ros.org/wiki/camera_drivers camera_drivers] for assistance working with your own cameras.
 
 
For more information on displaying images to Sawyer's LCD screen, see the [[Head Display Image Example]] , [[Camera Image Display Example]].
 

Latest revision as of 14:04, 15 September 2017

This page serves as a lookup reference for all the hardware and functionality for the SDK. The main interface of the SDK is via ROS Topics and Services, which you will find listed and described below along with other core information needed to interface with the robot.

Robot

Enable Robot

Be sure that you 'Enable' the robot before attempting to control any of the motors. The easiest method for controlling the robot is to use the enable_robot.py ROS executable found in the following example:Enable Robot Script

Robot State

/robot/state (intera_core_msgs/AssemblyState) Subscribe to the Robot State for the enabled and error state of the robot hardware itself. It also includes information on the EStop. The robot must be enabled (enabled: true) in order to move the robot. Use the Enable Robot Script, or the "Enable Robot Topic" below, to enable the robot. It is possible for the robot to have non-fatal errors, so error can be true while enabled is also true. For more complete information on robot state, see E-STOP and Enable Robot.

Enable Robot

/robot/set_super_enable (std_msgs/Bool) data: true to Enable robot motors; false to disable. You can check the Robot State Topic to see if the robot enabled properly or if it has an error.

Reset Robot State

/robot/set_super_reset (std_msgs/Empty) Publish an Empty message to reset the state after an error. A reset will clear all pre-existing errors and the state (it will disable).


Robot Description (URDF)

Sawyer automatically builds an appropriate URDF (Unified Robot Description Format) on boot and loads it onto the ROS Parameter Server, under the ROS parameter name /robot_description. From here, it is accessible by rviz, tf and other ROS utilities that use the URDF.

The Unified Robot Description Format (URDF) is the standard ROS XML representation of the robot model (kinematics, dynamics, sensors) describing Sawyer.

Sawyer generates his URDF dynamically on robot startup. This model is updated when any gripper is attached or detached, an object is 'grasped' or released and its mass is compensated for, and when new urdf segments are provided/commanded to the gripper plugins. As of SDK versions >= 1.0.0 Sawyer's internal robot model, is loaded to the parameter server on the topic /robot_description

The default URDF for Sawyer is available in the intera_common repository. The package sawyer_description contains the URDF and accompanying meshes.

Getting a Copy of the URDF from the parameter server

You can now get the current URDF describing your Sawyer.

From a properly initialized Sawyer environment, export the URDF from the /robot_description parameter on the ROS parameter server where it is stored, to a file of your choice (ex: sawyer_urdf.xml):

$ rosparam get -p /robot_description | tail -n +2 > sawyer_urdf.xml

The -p outputs the parameter using pretty print. The output urdf is piped through the tail command first to remove a dummy first line - an artifact of the pretty print.

Tip: You can check that you now have a proper URDF by running:

$ rosrun urdfdom check_urdf sawyer_urdf.xml

Robot State Publisher

The URDF is used by Sawyer's Robot State Publishers to create a tree of transforms (tfs). In fact, Sawyer has two of such publishers: robot_ref_publisher: publishes transforms that reflect the commanded robot state. robot_state_publisher: publishes transforms that reflect the measured state of the robot.

These robot publishers live internal to Sawyer and are accessible to the RSDK over ROS. The "ref" tfs are used by the robot internals, but you may find them useful to see where the robot will move at the next timestep. Otherwise, be sure to use the non-"ref" transforms if you're only interested in the Sawyer's current state.

Getting a Copy of the URDF Dynamically

Sawyer generates the URDF dynamically on initialization, based on the attached arm. In some cases, users may want to get the current URDF off the robot. From a working Sawyer RSDK environment, export the URDF from the /robot_description parameter on the ROS parameter server where it is stored, to a file of your choice (ex: sawyer_urdf.xml):

$ rosparam get -p /robot_description | tail -n +2 > sawyer_urdf.xml

The -p outputs the parameter using pretty print. The output urdf is piped through the tail command first to remove a dummy first line - an artifact of the pretty print.

Tip: You can check that you now have a proper URDF by running:

$ rosrun urdf_parser check_urdf sawyer_urdf.xml

If this doesn't work, you can just remove the tail command and use a text editor to manually remove the first few lines before the actual xml (all the lines before <?xml version="1.0" ?>).

    $ rosparam get -p /robot_description > sawyer_urdf.xml
    $ head sawyer_urdf.xml
    |  
      <?xml version="1.0" ?>  
      <!-- =================================================================================== -->  
      <!-- |    This document was autogenerated by xacro from sawyerp2.urdf.xacro            | -->  
    ...  
    $ gedit sawyer_urdf.xml &
    $ head sawyer_urdf.xml
      <?xml version="1.0" ?>  
      <!-- =================================================================================== -->  
      <!-- |    This document was autogenerated by xacro from sawyerp2.urdf.xacro            | -->  
    ...


Movement

Joints

Sawyer has 7 joints (DoF) in arm and one more joint in its head (side-to-side panning). The control for the head is done separately from the arm; however, you can read the current joint states (position, velocity, and effort) for all the joints on arm and head by subscribing to one topic: /robot/joint_states (sensor_msgs-JointState) where the units for the position of a joint are in (rad), the units of velocity are in (rad/s) and the units of effort in each joint is in (Nm).

Arm Joints

The following sections cover the arm joints sensing and control in more detail: Arm Joints.

Head Joints

The head state topic will give you the current pan angle (side-to-side) of the head and report boolean status flags if the robot is currently moving its head.

Note: Flags may not report 'true' values until after the first respective movement command is sent.

Component ID:head_pan

Head State:
/robot/head/head_state (intera_core_msgs-HeadState). pan field gives you the current angle (radians) of the head. 0 is forward, -pi/2 to Sawyer's right, and +pi/2 to Sawyer's left. isPanning is boolean field that will switch to True while the robot is executing a command.

Note: The isPanning field is initialized to True upon startup and will update thereafter.

Head (Joint) State:
/robot/joint_states (sensor_msgs-JointState).The position of the head may also be determined from the joint_state message.

Head Movement Control

Pan Head:
/robot/head/command_head_pan (intera_core_msgs-HeadPanCommand) target sets the target angle. 0.0 is straight ahead. speed is an integer from [0-100], 100 = max speed. Setting an angle in the command_head_pan topic does not gurantee the head will get to that position. There is a small deband around the reference angle around the order of +/- 0.12 radians.

Example:

    # Check head position/state: 
    $ rostopic echo /robot/head/head_state
    # Move (pan) head side-to-side: 
    $ rostopic pub /robot/head/command_head_pan intera_core_msgs/HeadPanCommand -- 0.0 100


Cartesian Endpoint

Published at 100 Hz, the endpoint state topic provides the current Cartesian Position, Velocity and Effort at the endpoint for either limb.

Endpoint State

Endpoint State: /robot/limb/right/endpoint_state intera_core_msgs-EndpointState). The endpoint state message provides the current position/orientation pose, linear/angular velocity, and force/torque effort of the robot end-effector at 100 Hz. Pose is in Meters, Velocity in m/s, Effort in Nm. The robot's "endpoint" is definied as the right_gripper tf frame. This frame is updated dynamically when gripper is connected to the robot . The URDF on the parameter server will now update when the Robot Model is updated by Gripper changes. Check the ROS Parameter for an updated copy of the URDF, especially before using IK or motion planners, such as MoveIt!.

Kinematics Solver Service

The following sections cover the Forward Kinematics Solver Service and Inverse Kinematics Solver Service in more detail: Kinematics Solvers


Gripper (End-Effector)

Before using an End-Effector, or Gripper, you must first send the calibration command. You can check whether the gripper has been calibrated yet by echoing on the gripper state topic for that hand. Once calibrated, gripper can be controlled using the simplified command_grip and command_release topics, or using the more direct command_set topic. For more information on using the gripper, see the Gripper Example Program.

Gripper Configuration

(intera_core_msgs-IOComponentCommand)

Calibrate Gripper
Publish an IO Command message to calibrate a new gripper by set signal calibrate to True. Gripper should open and close once. The calibrated field of the gripper state topic will also update to '1' after successful calibration. Once calibrated, the gripper will not calibrate again unless the command reset message is sent, or the robot is restarted.

Reset Gripper
Publish an IO Command message to reset the gripper state by set signal reboot to True. The calibrated field of the gripper state message will reset to '0'.

Gripper State

Gripper State
/io/end_effector/state The io signal calibrated field must be true (1) before you can control the gripper. Use the IO command to calibrate the gripper. The gripper state message will also give you the current position, force, and if the gripper is current moving. Position is from [0.0-100.0] [close-open].

Simple Gripper Control

Simple Gripper Close
/io/end_effector/command the signal 'position_m' value to MIN_POSITION: 0.0. Publish an IO Command message to grip.

Simple Gripper Open
/io/end_effector/command the signal 'position_m' value to MAX_POSITION: 0.041667. Publish an IO Command message to release.


Sensors+

Accelerometer

The robot hand has a 3-axis accelerometer located inside the cuff, in the same plane as the gripper electrical connection header. The positive z-axis points back 'up' the arm (towards the previous wrist joint, j6). The positive x-axis points towards the direction of gripper, and the y-axis points towards the cuff buttons, using standard Right-Hand-Rule notation.

Component IDs:
right_accelerometer

Accelerometer State:
/robot/accelerometer/<component_id>/state(sensor_msgs-ImuMessage)

Acceleration values (in m/s^2) are published under linear_acceleration for the x, y, and z axes. The force of gravity is NOT compensated for.

names: ['right_accelerometer']
states: 
  - 
    header: 
      seq: 120921
      stamp: 
        secs: 0
        nsecs: 0
      frame_id: ''
    orientation: 
      x: 0.0
      y: 0.0
      z: 0.0
      w: 0.0
    orientation_covariance: [-1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    angular_velocity: 
      x: 0.0
      y: 0.0
      z: 0.0
    angular_velocity_covariance: [-1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    linear_acceleration: 
      x: 0.0
      y: 0.0
      z: 0.0
    linear_acceleration_covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]


Cameras

You can access Sawyer's hand camera and the head camera using the standard ROS image types and image_transport mechanism listed below. You can use the ROS Services to open, close, and configure each of the cameras. See the Camera Image Display Example for more information on using the cameras. Useful tools for using cameras in ROS include rviz Camera Display.

IMPORTANT: You can only have one open at a time at standard resolutions, due to bandwidth limitations.

Component IDs: right_hand_camera, head_camera

Camera Published Topics

Raw Image: /internal_camera/<component_id>/image_raw (sensor_msgs-Image)

Camera Intrinsics: /internal_camera/<component_id>/camera_info (sensor_msgs-CameraInfo)

Rectify Color Image: /internal_camera/head_camera/image_rect_color (image_proc)

Rectify Image: /internal_camera/right_hand_camera/image_rect (image_proc)


Head Display Screen

Images can be displayed on Sawyer's LCD screen by publishing the image data as a ROS sensor_msgs/Image.

Display Image/robot/head_display (sensor_msgs-Image).

Publish image data as a ROS Image message to update the display. The screen resolution is 1024 x 600. Images smaller than this will appear in the top-left corner. There are dedicated ROS packages for working with and sending ROS Image messages, including image_transport and image_pipeline. Useful tools for working with images in ROS include Image_view and republish. Also see camera_drivers for assistance working with your own cameras.

For more information on displaying images to Sawyer's LCD screen, see the Head Display Image Example.

Inputs and Outputs

Navigators

There are two Navigators on Sawyer's body: one on side of the body and one on the arm. Each Navigator is comprised of three push buttons, one of which is also an indexing scroll wheel, and one set of white LED light.

Component IDs: right, head

Read Button States:/io/robot/navigator/state (intera_core_msgs-IODeviceStatus)

Wheel State:/io/robot/navigator/state (intera_core_msgs-IODeviceStatus)

Command Buttons:/io/robot/navigator/command(intera_core_msga-IOComponentCommand)

The states of the push buttons are the values type in integer at data area. For the wheel on navigator, the data field returns an integer between [0-255]. Each physical 'click' of the wheel corresponds to a +/-1 increment. The value will loop when it goes above or below the bounds. The values have corresponding meaning: 0:'OFF', 1:'CLICK', 2:'LONG_PRESS', 3:'DOUBLE_CLICK'


  • <Component ID>_button_ok: The circular button in the middle of the navigator.
  • <Component ID>_button_back: The button above the OK button, typically with a 'Back' arrow symbol.
  • <Component ID>_button_show: The "Rethink Button", is above the OK button, next to back button and typically is labeled with the Rethink logo.
  • <Component ID>_button_triangle(the 'X' button): The button below circle button and square button.
  • <Component ID>_button_circle: The button labeled with a circle, next to the square button.
  • <Component ID>_button_square: The button labeled with a square, next to the circle button.
  • <Component ID>_wheel: The wheel of circular button in the middle of the navigator.


Cuff Buttons

There are two buttons and one touch sensor in the cuff of the hand: cuff button, OK button and cuff grasp button. The state of each button is published in a DigitalIOState message under its own topic (DigitalIOState constants: PRESSED==1, UNPRESSED==0). Integer data will read PRESSED (1) when the cuff sensor is squeezed, and UNPRESSED (0) otherwise.

Component IDs: right_cuff, right_button_lower, right_button_upper.

Read Button Squeezed: /io/robot/cuff/state (intera_core_msgs-IODeviceStatus)

Command Cuff:/io/robot/cuff/command(intera_core_msga-IOComponentCommand)


Lights

The head LEDs at the top of Sawyer's head, and navigator LEDs are inside of navigator.

To get state or set command to HALO and Navigator LEDS, we are using IODeviceInterface to config, status and command topics. The data are type in bool in data area.

Lights Component IDs:
head_red_light, head_blue_light, head_green_light, right_hand_blue_light, right_hand_green_light, right_hand_red_light

LEDs State: /io/robot/robot/state (intera_core_msgs-IODeviceStatus)

Command Light:/io/robot/robot/command(intera_core_msga-IOComponentCommand)