Reddy Update

From IntRoLab
Revision as of 15:20, 30 November 2009 by Dominic Létourneau (talk | contribs) (Useful Examples Using Direct CAN Commands)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Introduction

Some problems have been experienced with the initial Reddy configuration :

  1. Motors can overheat and "self-destruct"
  2. Motors are noisy because of the switching frequency of the original servo controllers
  3. No position feedback on servo motors is available
  4. No current control on servo motors is available
  5. No Speed profile on servo motors is available
  6. The head will fall when no power is applied (the mechanism may break over time)
  7. Maintaining the head position requires more power than necessary because of the initial mechanism.

This wiki page describes what have been done to minimize those problems. Most of the changes will be invisible to the end user. Changes in the initial serial protocol are adding functionality and can be used if the user requires more control of the motor controllers. Expert users will have the possibility to change the motor controller behavior if required. The only change that will be required in the user code is the range of the variables to control the joints. This is the result of changing the hardware for position acquisition that is now done using 12bits ADC converters. The MLA, MRA and MRN are then modified to fit the new motor controllers and now uses 12 bits position comands instead of a position and the speed. Please see this section for more information on that matter.


Why do we need new motor controllers

It was a mistake to use standard servo motors for Reddy because :

  • The datasheet of the motor is not very clear about the continuous torque they can provide
    • This caused us a lot of problems, because we are using the servo motors with torque they cannot sustain for a long period of time. This causes overheat in the motor winding and can destroy the servo motor.
  • Noise caused by the original switching frequency was neglected. The switching frequency is about 300Hz and is very audible.
  • The real positions of the joints are not available.
    • They can be approximated with the last setpoint, but it is not safe to assume that.

The best solution to fix those problems is to change all the problematic motors (8 motors in fact) with motors (+ gearboxes) with additional torque and adequate motor controllers. This would require a complete change in the mechanical design of the robot. This solution is not a "low cost" option and was not considered.

The best solution we have to compensate for the motor problems is to create a new motor controller that have the following characteristics :

  • Cost < 1000$ for all motors.
  • Can monitor the motor temperature and shutdown if overheating
  • Can provide position feedback
  • Can monitor the motor current and limit the current to avoid breaking the hardware
  • Can provide position control with speed profile to avoid breaking the hardware
    • The result is that the motor position control will be slower, but safer
  • Can be eventually used if motors are replaced with motors with greater torque

We would have liked to place the new motor controllers directly in the servo motor housing, but it was not possible because of space constraints. Also, making the motor controller only work for servo motors would limit the reusaibility of the controller. We have finally come to the following solution  :

  • Place a small PCB into the motor housing that will be used for thermal monitoring and connecting the motor power and potentiometer.
  • Create a master controller installed in Reddy's torso that is easily accessible and programmable.

Schedule

Week 31, July 27 - August 1
  • Ordered new coupling for shoulder
  • Fab. + installation of head mechanism for gravity assist (previous one had interference problems with other head parts)
  • Assembly and installation of 1 motor PCB for neck
  • Assembly and installation of the speaker PCB + support
  • Final tuning of motor controllers
  • Documentation (protocol)
Week 32, August 3 - August 9
  • Final tests & tuning
    • We are still waiting for motor couplings and speaker PCB. This will delay the tests until we receive them.
    • Update1 : We did receive the speaker PCB. Still waiting for the couplings.
    • Update2 : (08/07/2009) Just received the motor couplings.
    • Update3 : (08/14/2009) Couplings are installed
Week 33, August 10 - August 15
  • Install motor couplings
  • Schedule a meeting for robot exchange
    • If speaker PCB & coupling is received.

Team

  • Marc-Antoine Legault
  • Serge Caron
  • Jean-François Duval
  • Alexis Demers
  • Dominic Létourneau
  • François Michaud

Documents

Note : Please read the new updated Reddy documentation. We have found that the initial MELVIN documentation does not fit with your robot.

Reddy Updated Documentation

Other Documents

Arm Improvements

To have better control of the arm (and neck) motors, we did the following :

  • Change the Motor PCB to support
    • Temperature detector. A signal will be sent to the motor controller if the motor temperature is higher than 60 degrees Celsius. Analog temperature value is also available.
    • Potentiometer feedback.
    • Motor power connection.
  • Design a new PCB for motor control with support for 4 motors
  • Communicate with the CAN bus already available on Reddy
  • Allow position feedback from the RS-232 interface
  • Create a tuning GUI for easier setup of the robot controllers

Motor PCB

Modified Servo Motors
ReddyMotorPCB1.jpg ReddyMotorPCB2.jpg ReddyMotorPCB3.jpg
Cable + Servo PCB Servo PCB installed in housing Final servo + cable + connector

Motor Controllers

ReddyMotorControllers.jpg

  • A new motor drive that can control up to 4 motors have been designed.
  • New dsPIC30F code for position control with current limit, trapezoidal speed, temperature limit
  • A new adjustable bracket for fixing the drive to the side of the robot have been designed.
  • We installed two motor controllers (one on each side) to allow the modification of 8 motors. Motors modified are :
    • Arm-Elbow (x2)
    • Arm-Shoulder-Yaw (x2)
    • Arm-Shoulder-Pitch (x2)
    • Neck-Yaw (x1)
    • Neck-Pitch (x1)

Cabling Improvements

ReddyArmCables.jpg

  • Cables are now better organized
  • Added connectors inside the arm to disconnect motors easily for repairs
  • Signals are color coded as follow (Number in brackets is the pin number of the motor side connector)
    • Red = Power 5V [5]
    • Black = Power GND [6]
    • Yellow = Motor A [10]
    • Brown = Motor B [9]
    • Blue = Analog temperature readout (refer to LM20 datasheet) [7]
    • Orange = Over temperature flag (5V if more than 60 degrees) [8]
    • Gray = Potentiometer GND (tied with Power GND) [4]
    • White = Potentiometer 5V (tied with Power 5V) [3]
    • Purple = Potentiometer signal (0-5V analog) [2]

Pitch motor coupling updated

We replaced the motor coupling on both arms with a bigger one that can sustain more torque on the motor shaft.

ReddyArmCoupling.jpg

Head Improvements

We added gravity compensation for the head yaw to minimize power required for motors.

Head modifications
ReddyGravityCompensationEllipse.jpg ReddyHeadModification1.jpg ReddyHeadModification2.jpg
The mechanical part that was modified View of the head with new part added (1) View of the head with new part added (2)

This will also prevent the head from falling when the robot is turned off.


Motor controllers for head movement (Yaw + Pitch)

  • Same motor controllers were used for the neck to add overheating protection and better feedback / control
  • Internal servo potentiometers were used for position control.

Tuning the motor controller

A GUI was created to facilitate motor tuning.

Warning! This GUI is intended for Engineers at IntRoLab and changing control values can lead to indesirable effects. Assistance will be required before changing controller values.

ReddyTuningGUI.jpg

RS-232 protocol enhancements

  • We added a CAN command to the RS-232 robot interface to allow direct communication with the motor controllers. The RS-232 robot interface now acts as a RS-232 to CAN bridge and bidirectional communication is now possible. This will allow feedback from the motor controllers (current, position, speed, etc.)
(RS-232 CAN COMMAND) <------------------------> (MOTOR DRIVE CAN INTERFACE)
* Serial Communication is at 57600 baud, 8 bits, no parity


CAN command format for RS-232 communication

Serial messages containing CAN commands have the following stucture :

RS-232 Data Format (16 bytes total) (part 1)
HEADER CAN_MSG_PRI_MSB_CMD CAN_MSG_TYPE CAN_MSG_BOOT_RTR_LENGTH
(3 bytes) (1 byte) (1 byte) (1 byte)
  • header[0] = 'c'
  • header[1] = 'a'
  • header[2] = 'n'
  • We had to change the standard protocol here to address more than 256 bytes of internal memory of the motor controlers. MSB of the MSG_CMD will be stored here (3 bits max).
  • CAN_TYPE_EMERGENCY=0x01
  • CAN_TYPE_ACTUATOR_HIGH_PRIORITY=0x02
  • CAN_TYPE_SENSOR_HIGH_PRIORITY=0x04
  • CAN_TYPE_ACTUATOR_LOW_PRIORITY=0x08
  • CAN_TYPE_SENSOR_LOW_PRIORITY=0x10
  • CAN_TYPE_REQUEST_DATA=0x20
  • CAN_TYPE_USER2=0x40
  • CAN_TYPE_EVENTS=0x80
  • bit 0-3 = DATA_LENGTH (0-8)
  • bit 4 = RTR
  • bit 5 = Boot (READ=1/WRITE=0)
  • bit 6 = Boot (EEPROM=1/RAM=0)
RS-232 Data Format (16 bytes total) (part 2)
CAN_MSG_CMD CAN_MSG_DEST CAN_MSG_DATA
(1 byte) (1 byte) (8 bytes)

if (MSG_TYPE == REQUEST)

  • CMD = RAM OFFSET FOR READ/WRITE

endif

if (MSG_TYPE == ACTUATOR_HIGH_PRIORITY)

  • CAN_ACTUATOR_CMD_POSITIONS=0x90
  • CAN_ACTUATOR_CMD_SPEEDS=0x91
  • CAN_ACTUATOR_CMD_SETPOINTS=0x92
  • CAN_ACTUATOR_CMD_WRITE_SETPOINT=0x93

endif

  • 0x01 = First controller
  • 0x02 = Second controller
  • Wll depend on commands


To keep things simple, we are using fixed length messages with 16 bytes. In some cases, the bytes contaning the CAN frame data are transmitted but are ignored by the RS-232 Server.

Note: It is not essential to understand the structure of the CAN messages. Souce code will be provided to format the data correctly.

Motor Controller Variables

Motor controller internal variables can be represented like this :

typedef struct _SharedVariables
	{
		union {
			struct {
				unsigned char CtrlMode;
				unsigned char CtrlType;		
				unsigned char SetPointSource;	
				unsigned char PosMesSource;
				unsigned short ErrorCode;
				short SetPoint;
				short SetPointMax; //Maximum SetPoint
				short SetPointMin; //Minimum SetPoint
				short Current;
				short CurrentOffset;
				short ADCValue;
				short ADCOffset;
				short ICValue;
				short ICOffset;
				short ThermalState;	
				//CONTROL VARIABLES
				short Speed;//16 bit speed
				short Position; //16 bits position
				short Acceleration;
				//PID REF AND MES POINT
				short RefPoint; 
				short MesPoint;
				float pid_kp;
				float pid_ki;
				float pid_kd;
				float pid_error;
				float pid_error_accum;
				float pid_error_derivative;
				float pid_error_accum_max; //PID I value max limit (abs)
				short PIDOut;
				short SpeedMax; //for Trapz 
				short AccelerationStep; //for Trapz, Speed
				short InitPoint; //for Trapz
				short DestPoint; //for Trapz
				short NextPoint; //for Trapz
				short CurrentLimit; //unit = mA
				short PWM_CurrentLimit;
				short PWM_CurrentStep; //PWM increment
				unsigned char CurrentLimitActive;
				unsigned char EncoderBias; //Setting this to 1 will invert the encoder sign
				unsigned char MotorBias; //Setting this to 1 will invert motor polarity
				unsigned char padding[3];
			} __attribute__((packed));
			
			unsigned char m_data[];
		};
	} SharedVariables;


typedef struct _GlobalVariables
	{
		union {
			struct {
				
				//All control variables
				SharedVariables m_variables[4];
				
				//additional (global) variables
				unsigned char m_ESTOPEnabled;
				unsigned char m_WriteEEPROM;
				short m_loopTime;
				unsigned char m_padding[4];
				
			} __attribute__((packed));
		
			unsigned char m_data[];
		};//union
	} GlobalVariables;	

Notes :

  • Understanding the structure of the controller is not required for normal operation.
  • The structure GlobalVariables represents the memory organization of the motor controller. You can see that it contains control variables (SharedVariables structure) for 4 motor axis.
  • Using the CAN protocol, we can access each variable and read/write its value.
  • The GUI was designed for easy tuning of those variables by our engineers.


MRA, MLA, MRN Modified Serial Messages

Those commands are still available, but have been modified to fit the new motor controllers :

MRA - Move Right Arm (New version)

Previous serial message format was :

  • Header[0] = 'm'
  • Header[1] = 'r'
  • Header[2] = 'a'
  • Param[0] = Desired right elbow pitch position
  • Param[1] = Desired right elbow pitch speed
  • Param[2] = Desired right shoulder yaw position
  • Param[3] = Desired right shoulder yaw speed
  • Param[4] = Desired right shoulder pitch position
  • Param[5] = Desired right shoulder pitch speed

The new MRA serial message format is :

  • Header[0] = 'm'
  • Header[1] = 'r'
  • Header[2] = 'a'
  • Param[0] = Desired right elbow pitch position LSB
  • Param[1] = Desired right elbow pitch position MSB
  • Param[2] = Desired right shoulder yaw position LSB
  • Param[3] = Desired right shoulder yaw position MSB
  • Param[4] = Desired right shoulder pitch position LSB
  • Param[5] = Desired right shoulder pitch position MSB
Note : Speed was optimized to for fastest (safe) movement possible with a trapezoidal speed profile

MLA - Move Left Arm (New version)

Previous serial message format was :

  • Header[0] = 'm'
  • Header[1] = 'l'
  • Header[2] = 'a'
  • Param[0] = Desired left elbow pitch position
  • Param[1] = Desired left elbow pitch speed
  • Param[2] = Desired left shoulder yaw position
  • Param[3] = Desired left shoulder yaw speed
  • Param[4] = Desired left shoulder pitch position
  • Param[5] = Desired left shoulder pitch speed

The new MLA serial message format is :

  • Header[0] = 'm'
  • Header[1] = 'l'
  • Header[2] = 'a'
  • Param[0] = Desired left elbow pitch position LSB
  • Param[1] = Desired left elbow pitch position MSB
  • Param[2] = Desired left shoulder yaw position LSB
  • Param[3] = Desired left shoulder yaw position MSB
  • Param[4] = Desired left shoulder pitch position LSB
  • Param[5] = Desired left shoulder pitch position MSB
Note : Speed was optimized to for fastest (safe) movement possible with a trapezoidal speed profile

MRN - Move Robot Neck (New version)

Previous serial message format was :

  • Header[0] = 'm'
  • Header[1] = 'r'
  • Header[2] = 'n'
  • Param[0] = Desired neck pitch position
  • Param[1] = Desired neck pitch speed
  • Param[2] = Desired neck yaw position
  • Param[3] = Desired neck yaw speed

The new MRN serial message format is :

  • Header[0] = 'm'
  • Header[1] = 'r'
  • Header[2] = 'n'
  • Param[0] = Desired neck pitch position LSB
  • Param[1] = Desired neck pitch position MSB
  • Param[2] = Desired neck yaw position LSB
  • Param[3] = Desired neck yaw position MSB
Note : Speed was optimized to for fastest (safe) movement possible with a trapezoidal speed profile

New Joints Configuration

Arms Limits (click on the image for full scale)
ReddyUpdateElbow.jpg ReddyUpdateYaw.jpg ReddyUpdatePitch.jpg
Elbows Yaw Pitch



Neck Limits (click for the image for full scale)
ReddyUpdateNeckYaw.jpg ReddyUpdateNeckPitch.jpg
Yaw Pitch


Updated Reddy Joints Configuration
Motor controller id=0x01 Motor controller id=0x02
  • Motor 0 = Left Arm Shoulder Pitch
    • Range:
  • Motor 1 = Left Arm Shoulder Yaw
    • Range:
  • Motor 2 = Left Arm Elbow
    • Range:
  • Motor 3 = Head Yaw ("NO")
    • Range:
  • Motor 0 = Right Arm Shoulder Pitch
    • Range:
  • Motor 1 = Right Arm Should Yaw
    • Range:
  • Motor 2 = Right Arm Elbow
    • Range:
  • Motor 3 = Yead Pitch ("YES")
    • Range:

Useful Examples Using Direct CAN Commands

Emergency STOP for all motor controllers

This will stop all motors with a single CAN command. This will stop controllers and kill power to the motor.

Send Emergency STOP (E-STOP), RS-232 Data Format (16 bytes total) (part 1)
HEADER CAN_MSG_PRI_MSB_CMD CAN_MSG_TYPE CAN_MSG_BOOT_RTR_LENGTH
(3 bytes) (1 byte) (1 byte) (1 byte)
  • header[0] = 'c'
  • header[1] = 'a'
  • header[2] = 'n'
  • CAN_MSG_PRI_MSB_CMD=0
  • CAN_TYPE_EMERGENCY=0x01
  • bit 0-3 = 0 (length = 0)
  • bit 4 = RTR = 0
  • bit 5 =1 (not used)
  • bit 6 =1 (not used)
Send Emergency STOP (E-STOP), RS-232 Data Format (16 bytes total) (part 2)
CAN_MSG_CMD CAN_MSG_DEST CAN_MSG_DATA
(1 byte) (1 byte) (8 bytes)
  • CAN_EMERGENCY_CMD_STOP=0x01
  • 0xFF = Broadcast
  • No data.

Serial Message Sent:

  • serial_message[0] = 'c'
  • serial_message[1] = 'a'
  • serial_message[2] = 'n'
  • serial_message[3] = 0x00
  • serial_message[4] = 0x01
  • serial_message[5] = 0x60
  • serial_message[6] = 0x01
  • serial_message[7] = 0xFF
  • serial_message[8] = (ignored)
  • serial_message[9] = (ignored)
  • serial_message[10] = (ignored)
  • serial_message[11] = (ignored)
  • serial_message[12] = (ignored)
  • serial_message[13] = (ignored)
  • serial_message[14] = (ignored)
  • serial_message[15] = (ignored)

Direct Servo Motor CAN Commands

Be careful not to send out of range motor commands. Servo gearboxes are fragile.

Send direct servo commands to the controller, RS-232 Data Format (16 bytes total) (part 1)
HEADER CAN_MSG_PRI_MSB_CMD CAN_MSG_TYPE CAN_MSG_BOOT_RTR_LENGTH
(3 bytes) (1 byte) (1 byte) (1 byte)
  • header[0] = 'c'
  • header[1] = 'a'
  • header[2] = 'n'
  • CAN_MSG_PRI_MSB_CMD=0
  • CAN_TYPE_ACTUATOR_HIGH_PRIORITY=0x02
  • bit 0-3 = 4
  • bit 4 = RTR = 0
  • bit 5 =1 (not used)
  • bit 6 =1 (not used)
Read all positions from the motor controller RS-232 Data Format (16 bytes total) (part 2)
CAN_MSG_CMD CAN_MSG_DEST CAN_MSG_DATA
(1 byte) (1 byte) (8 bytes)
  • CAN_SERVO_SET_POINT=0x30
  • CAN_SERVO_GET_POINT=0x31
  • 0x27 = Servo controller
  • CAN_MSG_DATA[0] = Servo ID (See list below)
  • CAN_MSG_DATA[1] = SetPoint LSB
  • CAN_MSG_DATA[2] = SetPoint MSB
  • CAN_MSG_DATA[3] = 0


SetPoint Range is [1100, 1900] which corresponds to ms values for servo commands. For testing we recommend starting with a value of 1500, which is the mid range of the servo and should be a safe starting point.

ServoIDs:

  • Eyes
    • LEFT EYE YAW servo=8
    • RIGHT EYE YAW servo=7
    • EYE PITCH servo=9
  • Mouth
    • MOUTH LEFT UPPER servo=11
    • MOUTH LEFT LOWER servo=12
    • MOUTH RIGHT UPPER servo=13
    • MOUTH RIGHT LOWER servo=10
  • Eyebrows
    • EYEBROW LEFT servo=4
    • EYEBROW RIGHT servo=6


Serial Message Sent:

  • serial_message[0] = 'c'
  • serial_message[1] = 'a'
  • serial_message[2] = 'n'
  • serial_message[3] = 0x00
  • serial_message[4] = 0x02
  • serial_message[5] = 0x64
  • serial_message[6] = 0x30
  • serial_message[7] = 0x27
  • serial_message[8] = Servo ID
  • serial_message[9] = SetPoint LSB
  • serial_message[10] = SetPoint MSB
  • serial_message[11] = 0 (Speed Max)
  • serial_message[12] = (ignored)
  • serial_message[13] = (ignored)
  • serial_message[14] = (ignored)
  • serial_message[15] = (ignored)


Those examples will probably contain all you will need to do to operate the robot.

Read all positions from the motor controller

The computer sends this to the RS-232 server (Remote request) :

Read all positions from the motor controller RS-232 Data Format (16 bytes total) (part 1)
HEADER CAN_MSG_PRI_MSB_CMD CAN_MSG_TYPE CAN_MSG_BOOT_RTR_LENGTH
(3 bytes) (1 byte) (1 byte) (1 byte)
  • header[0] = 'c'
  • header[1] = 'a'
  • header[2] = 'n'
  • CAN_MSG_PRI_MSB_CMD=0
  • CAN_TYPE_ACTUATOR_HIGH_PRIORITY=0x02
  • bit 0-3 = 8
  • bit 4 = RTR = 1
  • bit 5 =1 (not used)
  • bit 6 =1 (not used)


Read all positions from the motor controller RS-232 Data Format (16 bytes total) (part 2)
CAN_MSG_CMD CAN_MSG_DEST CAN_MSG_DATA
(1 byte) (1 byte) (8 bytes)
  • CAN_ACTUATOR_CMD_POSITIONS=0x90
  • 0x01 = First controller
  • 0x02 = Second controller
  • CAN_MSG_DATA[0-7] (ignored)

Serial Message Sent:

  • serial_message[0] = 'c'
  • serial_message[1] = 'a'
  • serial_message[2] = 'n'
  • serial_message[3] = 0x00
  • serial_message[4] = 0x02
  • serial_message[5] = 0x78
  • serial_message[6] = 0x90
  • serial_message[7] = 0x01 or 0x02
  • serial_message[8] = (ignored)
  • serial_message[9] = (ignored)
  • serial_message[10] = (ignored)
  • serial_message[11] = (ignored)
  • serial_message[12] = (ignored)
  • serial_message[13] = (ignored)
  • serial_message[14] = (ignored)
  • serial_message[15] = (ignored)

The RS-232 server responds (response to remote request):

Read all positions from the motor controller RS-232 Data Format (16 bytes total) (part 1)
HEADER CAN_MSG_PRI_MSB_CMD CAN_MSG_TYPE CAN_MSG_BOOT_RTR_LENGTH
(3 bytes) (1 byte) (1 byte) (1 byte)
  • header[0] = 'c'
  • header[1] = 'a'
  • header[2] = 'n'
  • CAN_MSG_PRI_MSB_CMD=0
  • CAN_TYPE_ACTUATOR_HIGH_PRIORITY=0x02
  • bit 0-3 = 8
  • bit 4 = RTR = 0
  • bit 5 =1 (not used)
  • bit 6 =1 (not used)


Read all positions from the motor controller RS-232 Data Format (16 bytes total) (part 2)
CAN_MSG_CMD CAN_MSG_DEST CAN_MSG_DATA
(1 byte) (1 byte) (8 bytes)
  • CAN_ACTUATOR_CMD_POSITIONS=0x90
  • 0x01 = First controller
  • 0x02 = Second controller

  • CAN_MSG_DATA[0-1]
    • LSB, MSB Position motor 0
  • CAN_MSG_DATA[2-3]
    • LSB, MSB Position motor 1
  • CAN_MSG_DATA[4-5]
    • LSB, MSB Position motor 2
  • CAN_MSG_DATA[6-7]
    • LSB, MSB Position motor 3

Serial Message Received :

  • serial_message[0] = 'c'
  • serial_message[1] = 'a'
  • serial_message[2] = 'n'
  • serial_message[3] = 0x00
  • serial_message[4] = 0x02
  • serial_message[5] = 0x68
  • serial_message[6] = 0x90
  • serial_message[7] = 0x01 or 0x02
  • serial_message[8] = Motor 0 Position LSB
  • serial_message[9] = Motor 0 Position MSB
  • serial_message[10] = Motor 1 Position LSB
  • serial_message[11] = Motor 1 Position MSB
  • serial_message[12] = Motor 2 Position LSB
  • serial_message[13] = Motor 2 Position MSB
  • serial_message[14] = Motor 3 Position LSB
  • serial_message[15] = Motor 3 Position MSB

Read all speeds from the motor controller

The computer sends this to the RS-232 server (Remote request) :

Read all currents from the motor controller RS-232 Data Format (16 bytes total) (part 1)
HEADER CAN_MSG_PRI_MSB_CMD CAN_MSG_TYPE CAN_MSG_BOOT_RTR_LENGTH
(3 bytes) (1 byte) (1 byte) (1 byte)
  • header[0] = 'c'
  • header[1] = 'a'
  • header[2] = 'n'
  • CAN_MSG_PRI_MSB_CMD=0
  • CAN_TYPE_ACTUATOR_HIGH_PRIORITY=0x02
  • bit 0-3 = 8
  • bit 4 = RTR = 1
  • bit 5 =1 (not used)
  • bit 6 =1 (not used)


Read all currents from the motor controller RS-232 Data Format (16 bytes total) (part 2)
CAN_MSG_CMD CAN_MSG_DEST CAN_MSG_DATA
(1 byte) (1 byte) (8 bytes)
  • CAN_ACTUATOR_CMD_SPEEDS=0x91
  • 0x01 = First controller
  • 0x02 = Second controller
  • CAN_MSG_DATA[0-7] (ignored)

Serial Message Sent:

  • serial_message[0] = 'c'
  • serial_message[1] = 'a'
  • serial_message[2] = 'n'
  • serial_message[3] = 0x00
  • serial_message[4] = 0x02
  • serial_message[5] = 0x78
  • serial_message[6] = 0x91
  • serial_message[7] = 0x01 or 0x02
  • serial_message[8] = (ignored)
  • serial_message[9] = (ignored)
  • serial_message[10] = (ignored)
  • serial_message[11] = (ignored)
  • serial_message[12] = (ignored)
  • serial_message[13] = (ignored)
  • serial_message[14] = (ignored)
  • serial_message[15] = (ignored)

The RS-232 server responds (response to remote request):

Read all currents from the motor controller RS-232 Data Format (16 bytes total) (part 1)
HEADER CAN_MSG_PRI_MSB_CMD CAN_MSG_TYPE CAN_MSG_BOOT_RTR_LENGTH
(3 bytes) (1 byte) (1 byte) (1 byte)
  • header[0] = 'c'
  • header[1] = 'a'
  • header[2] = 'n'
  • CAN_MSG_PRI_MSB_CMD=0
  • CAN_TYPE_ACTUATOR_HIGH_PRIORITY=0x02
  • bit 0-3 = 8
  • bit 4 = RTR = 0
  • bit 5 =1 (not used)
  • bit 6 =1 (not used)


Read all currents from the motor controller RS-232 Data Format (16 bytes total) (part 2)
CAN_MSG_CMD CAN_MSG_DEST CAN_MSG_DATA
(1 byte) (1 byte) (8 bytes)
  • CAN_ACTUATOR_CMD_SPEEDS=0x91
  • 0x01 = First controller
  • 0x02 = Second controller

  • CAN_MSG_DATA[0-1]
    • LSB, MSB Speed motor 0
  • CAN_MSG_DATA[2-3]
    • LSB, MSB Speed motor 1
  • CAN_MSG_DATA[4-5]
    • LSB, MSB Speed motor 2
  • CAN_MSG_DATA[6-7]
    • LSB, MSB Speed motor 3


Serial Message Received :

  • serial_message[0] = 'c'
  • serial_message[1] = 'a'
  • serial_message[2] = 'n'
  • serial_message[3] = 0x00
  • serial_message[4] = 0x02
  • serial_message[5] = 0x68
  • serial_message[6] = 0x91
  • serial_message[7] = 0x01 or 0x02
  • serial_message[8] = Motor 0 Speed LSB
  • serial_message[9] = Motor 0 Speed MSB
  • serial_message[10] = Motor 1 Speed LSB
  • serial_message[11] = Motor 1 Speed MSB
  • serial_message[12] = Motor 2 Speed LSB
  • serial_message[13] = Motor 2 Speed MSB
  • serial_message[14] = Motor 3 Speed LSB
  • serial_message[15] = Motor 3 Speed MSB

Read all SetPoints from the motor controller

The computer sends this to the RS-232 server (Remote request) :

Read all setpoints from the motor controller RS-232 Data Format (16 bytes total) (part 1)
HEADER CAN_MSG_PRI_MSB_CMD CAN_MSG_TYPE CAN_MSG_BOOT_RTR_LENGTH
(3 bytes) (1 byte) (1 byte) (1 byte)
  • header[0] = 'c'
  • header[1] = 'a'
  • header[2] = 'n'
  • CAN_MSG_PRI_MSB_CMD=0
  • CAN_TYPE_ACTUATOR_HIGH_PRIORITY=0x02
  • bit 0-3 = 8
  • bit 4 = RTR = 1
  • bit 5 =1 (not used)
  • bit 6 =1 (not used)


Read all setpoints from the motor controller RS-232 Data Format (16 bytes total) (part 2)
CAN_MSG_CMD CAN_MSG_DEST CAN_MSG_DATA
(1 byte) (1 byte) (8 bytes)
  • CAN_ACTUATOR_CMD_SETPOINTS=0x92
  • 0x01 = First controller
  • 0x02 = Second controller
  • CAN_MSG_DATA[0-7] (ignored)

Serial Message Sent:

  • serial_message[0] = 'c'
  • serial_message[1] = 'a'
  • serial_message[2] = 'n'
  • serial_message[3] = 0x00
  • serial_message[4] = 0x02
  • serial_message[5] = 0x78
  • serial_message[6] = 0x92
  • serial_message[7] = 0x01 or 0x02
  • serial_message[8] = (ignored)
  • serial_message[9] = (ignored)
  • serial_message[10] = (ignored)
  • serial_message[11] = (ignored)
  • serial_message[12] = (ignored)
  • serial_message[13] = (ignored)
  • serial_message[14] = (ignored)
  • serial_message[15] = (ignored)

The RS-232 server responds (response to remote request):

Read all setpoints from the motor controller RS-232 Data Format (16 bytes total) (part 1)
HEADER CAN_MSG_PRI_MSB_CMD CAN_MSG_TYPE CAN_MSG_BOOT_RTR_LENGTH
(3 bytes) (1 byte) (1 byte) (1 byte)
  • header[0] = 'c'
  • header[1] = 'a'
  • header[2] = 'n'
  • CAN_MSG_PRI_MSB_CMD=0
  • CAN_TYPE_ACTUATOR_HIGH_PRIORITY=0x02
  • bit 0-3 = 8
  • bit 4 = RTR = 0
  • bit 5 =1 (not used)
  • bit 6 =1 (not used)


Read all setpoints from the motor controller RS-232 Data Format (16 bytes total) (part 2)
CAN_MSG_CMD CAN_MSG_DEST CAN_MSG_DATA
(1 byte) (1 byte) (8 bytes)
  • CAN_ACTUATOR_CMD_SETPOINTS=0x92
  • 0x01 = First controller
  • 0x02 = Second controller

  • CAN_MSG_DATA[0-1]
    • LSB, MSB SetPoint motor 0
  • CAN_MSG_DATA[2-3]
    • LSB, MSB SetPoint motor 1
  • CAN_MSG_DATA[4-5]
    • LSB, MSB SetPoint motor 2
  • CAN_MSG_DATA[6-7]
    • LSB, MSB SetPoint motor 3

Serial Message Received :

  • serial_message[0] = 'c'
  • serial_message[1] = 'a'
  • serial_message[2] = 'n'
  • serial_message[3] = 0x00
  • serial_message[4] = 0x02
  • serial_message[5] = 0x68
  • serial_message[6] = 0x92
  • serial_message[7] = 0x01 or 0x02
  • serial_message[8] = Motor 0 SetPoint LSB
  • serial_message[9] = Motor 0 SetPoint MSB
  • serial_message[10] = Motor 1 SetPoint LSB
  • serial_message[11] = Motor 1 SetPoint MSB
  • serial_message[12] = Motor 2 SetPoint LSB
  • serial_message[13] = Motor 2 SetPoint MSB
  • serial_message[14] = Motor 3 SetPoint LSB
  • serial_message[15] = Motor 3 SetPoint MSB

Write the SetPoint of motor [0-3]

The computer sends this to the RS-232 server (Remote request) :

Write a SetPoint to the motor controller RS-232 Data Format (16 bytes total) (part 1)
HEADER CAN_MSG_PRI_MSB_CMD CAN_MSG_TYPE CAN_MSG_BOOT_RTR_LENGTH
(3 bytes) (1 byte) (1 byte) (1 byte)
  • header[0] = 'c'
  • header[1] = 'a'
  • header[2] = 'n'
  • CAN_MSG_PRI_MSB_CMD=0
  • CAN_TYPE_ACTUATOR_HIGH_PRIORITY=0x02
  • bit 0-3 = 3
  • bit 4 = RTR = 0
  • bit 5 =1 (not used)
  • bit 6 =1 (not used)


Write a SetPoint to the motor controller RS-232 Data Format (16 bytes total) (part 2)
CAN_MSG_CMD CAN_MSG_DEST CAN_MSG_DATA
(1 byte) (1 byte) (8 bytes)
  • CAN_ACTUATOR_CMD_WRITE_SETPONT=0x93
  • 0x01 = First controller
  • 0x02 = Second controller
  • CAN_MSG_DATA[0] MOTOR_ID (0,1,2,3)
  • CAN_MSG_DATA[1] SetPoint LSB
  • CAN_MSG_DATA[2] SetPoint MSB

Serial Message Sent:

  • serial_message[0] = 'c'
  • serial_message[1] = 'a'
  • serial_message[2] = 'n'
  • serial_message[3] = 0x00
  • serial_message[4] = 0x02
  • serial_message[5] = 0x63
  • serial_message[6] = 0x93
  • serial_message[7] = 0x01 or 0x02
  • serial_message[8] = MOTOR_ID
  • serial_message[9] = SetPoint LSB
  • serial_message[10] = SetPoint MSB
  • serial_message[11] = (ignored)
  • serial_message[12] = (ignored)
  • serial_message[13] = (ignored)
  • serial_message[14] = (ignored)
  • serial_message[15] = (ignored)

No serial message will be received

Additional Notes & Comments

  • Single 12V power supply could be useful for direct connection to Pioneer robots. A 12V-->7.5V DC-DC (75-100W) converter is required for this operation. This item can be ordered at Vicor. 7.5V battery packs would then be useless.
    • Option 1 : VI-200 (full size): VI-20R-EX $112.00, 12V Input, 7.5V Output, 75W
    • Maximum power from the robot is 2Amp * 8 * 7.5V = 120W, this situation will happen only when all motors are blocked. Normal power required is around 30-40W.
    • The vicor product was NOT tested by our team. It is only listed as a potential solution. If we draw too much current, the module may overheat and would necessitate a heat sink.
    • It is not recommended to operate the robot at voltage higher than 7.5V. Otherwise the robot's electronic circuits may overheat.
  • Timing for all motors positions feedback can be obtained with the following calculation :
    • 2 serial messages (CMD_POSITIONS) * (1/57600 second/bits) * 16 bytes * 8 bits / byte) = 4.4 ms
    • Position refresh is then possible at maximum frequency : 225Hz.