RFLEX plugin
As the Institute for Automation got a hand on an iRobot ATRV-Jr robot platform, we needed a plug-in to control the robot. The robot has a fully developed control framework built-in, the rFLEX, that provides odometry and sensors through a RS-232 connection.
iRobot has moved focus towards developing consumer (vacuum) and military robots, so no documentation at all is available for the robot. Fortunately, Carnegie Mellon University (CMU) has drivers for the rFLEX in their Carnegie Mellon Robot Navigation Toolkit (CARMEN). This is actually also the base for the rFLEX drivers in Player/Stage framework. About half of the code is ported from CARMEN - Thank you guys!
The rFLEX system
rFLEX provides a full interface to the robot sensors, and does somewhat of post-processing, such as odometry calculations and ultrasound processing.
The intension of the interface is to create a flexible platform for all iRobot research robots. As we only had the ATRV-Jr robot for testing, the rFLEX plugin is kept as universal as possible, but bumpers and ultrasound sensors are mapped specifically for ATRV-Jr.
Odometry is provided in a translation / rotation axis configuration. The system outputs position, velocity, acceleration and torque in both axes (i.e. forward speed and rotation speed)
XML Configuration
Through the RHD XML configuration, it is possible to define parameters for the plug-in
The default configuration is seen below:
<rflex enable="true" lib="librflex.so.1" critical="true">
<serial port="/dev/ttyUSB0" baudrate="115200" />
<odometry period="100000" />
<translation accel="100000" torque="30000" />
<rotation accel="100000" torque="35000" />
<bumperbrake default="true" />
</rflex>
Configuration include serial port settings and default values for accelleration and torque in both translation and rotation axes.
The odometry period sets, how often a odometry package is sampled to the serial bus. The value is in µs.
The final parameter is the bumperbrake, that is described below.
Plug-in special features
Normally, it is against RHD principles to assign too much robot functionality into the plug-ins. But as a safety feature, a brake feature is coupled to the bumpers of the robot.
If the bumperbrake is enabled, the robot will enable it's brake, when bumpers is touched. The default setting is assigned in the XML configuration, but a write-variable makes it possible to en/disable the feature at runtime. This makes the response-time as short as possible for emergency stop.
Plug-in variables
Most of the plug-in functionality is described by the plug-ins it creates
Direction | Variable name | Array contents | Description |
---|---|---|---|
r | transvel | [vel] | Velocity of translation |
r | transaccl | [accl] | Acceleration of translation |
r | transtorque | [torque] | Torque of translation |
r | transpos | [pos] | Position of translation (distance) |
r | rotvel | [vel] | Velocity of rotation |
r | rotaccl | [accl] | Acceleration of rotation |
r | rottorque | [torque] | Torque of rotation |
r | rotpos | [pos] | Position of rotation (bering) |
r | sonar | [s0]..[s16] | Measurements of sonars (mapped 0-16, as on ATRV-Jr) |
r | bumper | [front][rear] | Status of ARTV-Jr bumpers |
r | brake | [brake] | Status of robot brake (updated at 1Hz) |
r | battvoltage | [batt] | Raw mesurement of battery voltage (needs calibration and updated at 1Hz) |
w | cmdtransvel | [vel] | Desired velocity of translation (command) |
w | cmdtransaccl | [accl] | Max acceleration of translation (XML default used if = 0) |
w | cmdtranstorque | [torque] | Max torque of translation (XML default used if = 0) |
w | cmdrotvel | [vel] | Desired velocity of rotation (command) |
w | cmdrotaccl | [accl] | Max acceleration of rotation (XML default used if = 0) |
w | cmdrottorque | [torque] | Max torque of rotation (XML default used if = 0) |
w | usesonar | [enable] | Enable / disable ultrasound sonars (default off) |
w | cmdbrake | [brake] | Enable / disable robot brake (default off) |
w | bumperbrake | [enable] | Enable / disable bumperbrake (overrides default) |
Using these variables, it is possible to control all functions on the ATRV-Jr robot... Enjoy
rFlex protocold
Before you begin, understand
Packet Header: ---
PKT_STX | 2 bytes | 0x1b 0x02 PORT | 1 byte | 0x01 - System Module 0x02 - Motion 0x03 - Joystick 0x04 - Sonar 0x05 - Digital I/O (Bump panels) 0x06 - IR PACKET_ID | 1 byte | Not used, but packets returned from base have increasing ID's OPCODE | 1 byte | Depends on module and command DATA_LENGTH | 1 byte | Length of following data DATA | n bytes | Actual data CHECKSUM | 1 byte | xor of all bytes from PORT to end of DATA PKT_ETX | 2 bytes | 0x1b 0x03
Byte stuffing
As communication is binary and PKT_STX and PKT_ETX needs to be unique, then if the escape character is in the data, and escape sequence is stuffed, like:
By code inspection in http://wurde.sourceforge.net/doxygen/a00376.html#l00473 it seems like an escape sequence of 0x1b 0x00 should be replaced by just 0x1b, and escape sequence 0x1b 0x01 should just be removed (a bit odd that it is there in the first place).
Testing has shown that "all" packages are now received with no errors, with this interpretation if byte stuffing (jca 16 sep 2013). - change included in mobotware version 3.240.
Opcodes and Packet Descriptions
---
SYS_LCD_DUMP 0 ---
Timestamp | 4 bytes Row | 1 byte Number of bytes | 1 byte LCD Screen contents | Variable
SYS_STATUS 1 ---
Timestamp | 4 bytes Volts | 4 bytes Brake Status | 1 byte
Motion Opcodes
---
Motion Axis: 0 - translation 1 - rotation 2 & 3 - not used
MOT_AXIS_GET_SYSTEM 0 ---
Axis | 1 byte
MOT_AXIS_GET_MODEL 1 ---
Axis | 1 byte
MOT_AXIS_GET_TARGET 2 ---
Axis | 1 byte
MOT_AXIS_SET_DIR 7 ---
Axis | 1 byte Velocity | 4 bytes Acceleration | 4 byte Torque | 4 bytes Direction | 1 byte
MOT_AXIS_SET_POS 8 ---
Axis | 1 byte Velocity | 4 bytes Acceleration | 4 byte Torque | 4 bytes Position | 4 bytes
MOT_AXIS_GET_MODE 9 ---
Axis | 1 byte
MOT_SET_DEFAULTS 10 ---
No Data Segment
MOT_BRAKE_SET 11 ---
No Data Segment
MOT_BRAKE_RELEASE 12 ---
No Data Segment
MOT_SYSTEM_REPORT 33 ---
rv | 4 bytes | Unknown data Timestamp | 4 bytes Axis | 1 byte Position | 4 bytes Velocity | 4 bytes Acceleration | 4 byte Torque | 4 bytes
MOT_SYSTEM_REPORT_REQ 34 ---
Period | 4 bytes | Time between published system reports Mask | 4 bytes | Which axes to publish for.
| Mask |= 1 << axis
Unused Opcodes: ---
MOT_AXIS_SET_LIMITS 3 MOT_AXIS_GET_LIMITS 4 MOT_AXIS_SET_POS_LIMITS 5 MOT_AXIS_GET_POS_LIMITS 6 MOT_GET_NAXES 65 MOT_SET_GEARING 66 MOT_GET_GEARING 67 MOT_MOTOR_SET_MODE 68 MOT_MOTOR_GET_MODE 69 MOT_MOTOR_SET_PARMS 70 MOT_MOTOR_GET_PARMS 71 MOT_MOTOR_SET_LIMITS 72 MOT_MOTOR_GET_LIMITS 73 MOT_MOTOR_GET_DATA 74 MOT_AXIS_SET_PARMS 75 MOT_AXIS_GET_PARMS 76 MOT_AXIS_SET_PWM_LIMIT 77 MOT_AXIS_GET_PWM_LIMIT 78 MOT_AXIS_SET_PWM 79 MOT_AXIS_GET_PWM 80
Motion Opcodes ---
From client to base: JSTK_GET_STATE 0 ---
No Data Segment
From base to client: JSTK_GET_STATE 0 ---
Timestamp | 4 bytes X | 4 bytes Y | 4 bytes Buttons | 1 byte
Sonar Opcodes ---
SONAR_RUN 0 ---
Echo Delay | 4 bytes | Default is 30000 Ping Delay | 4 bytes | Default is 0 Set Delay | 4 bytes | Default is 0 Mode | 1 byte | 0 off 2 on
SONAR_GET_UPDATE 1 ---
Timestamp | 4 bytes
SONAR_REPORT 2 ---
Retval | 4 bytes | Unknown data Timestamp | 4 bytes Sonar ID | 1 byte | There are a variable number of these, given Range | 2 bytes | by (DATA_LENGTH - 8)/2
Digital I/O Opcodes --- DIO_REPORTS_REQ 0 ---
Period | 4 bytes
From base to client: DIO_REPORTS_REQ 0 ---
Retval | 4 bytes | Unknown data Timestamp | 4 bytes
DIO_REPORT 1 ---
Timestamp | 4 bytes Net ID | 1 byte Offset | 1 byte State | 1 byte
From client to base: DIO_GET_UPDATE 2 ---
Timestamp | 4 bytes
From base to client: DIO_GET_UPDATE 2 ---
Retval | 4 bytes | Unknown data Timestamp | 4 bytes Count | 4 bytes | Unknown data
DIO_UPDATE 3 ---
Timestamp | 4 bytes Net ID | 1 byte Offset | 1 byte State | 1 byte
From client to base: DIO_SET 4 ---
Net ID | 1 byte Offset | 1 byte State | 1 byte Mask | 1 byte
From base to client: DIO_SET 4 ---
Retval | 4 bytes | Unknown data Timestamp | 4 bytes
I/R Opcodes ---
There are no used I/R opcodes IR_RUN 0 IR_REPORT 1