PDA

View Full Version : [Question(s)] dynamixel set to wheel_mode in ros



rossi
04-03-2013, 07:05 AM
hello everybody,
i am new in ros and need to controll 2 dynamixels (mx28r and mx106r).
in the standart_mode the actuators rotate 360°. i read that in the wheel_mode its posible to use the dynamixels as normal motors.
i already install the rospakage, but i cant find any information about it.
do anybody know how i can swich the cases.
thanks for the help.

tician
04-03-2013, 05:26 PM
While it is possible to use dynamixel servos in 'wheel' or 'continuous rotation' mode, I am unaware of any ROS programs that use that mode by default. They tend to be put into arms and pinchers much more frequently than in winches or wheels. The robotis e-support site should have everything you need to change the servos to 'wheel' mode, but it will likely require some effort to make a ros node that can use it.

zhenli
05-29-2013, 12:30 PM
Can you tell me how to change the dynamixel servo to wheel mode. In fact, I want to use this wheel mode to realize velocity control. I have to know the method to set AX-12+,MX-64,MX-28 in wheel mode.

jwatte
05-29-2013, 01:52 PM
Can you tell me how to change the dynamixel servo to wheel mode

1) Connect servo to USB2Dynamixel adapter and proper power voltage.
2) Start up Dynamixel Wizard (typically from the RoboPlus control panel)
3) Find the servo ID / baud rate.
4) Change the register for drive mode to "wheel mode."

Note that the register in option 4 is volatile, so it has to be done each time battery power is lost to the servo. Typically, you'll have your microcontroller or other program that generates Dynamixel control packets generate the appropriate register write command to turn on wheel mode as part of initialization.

tician
05-29-2013, 02:42 PM
Setting servos to wheel mode is as simple as changing both the CW angle limit and CCW angle limit to zero using RoboPlus' Dynamixel Wizard. There will be no position control in any of the servos, and the AX-12 has somewhat limited speed control (only 300 degrees of useable sensing range in the potentiometer). This change to wheel mode will remain in effect until either of the angle limits are changed from zero.

jwatte
05-29-2013, 03:35 PM
You're right! I was thinking of Torque Control Mode (register 70) which behaves like I suggeted above, and can also be used as wheel control with controlled torque. This register is not available in the AX12, though.

zhenli
05-30-2013, 06:14 AM
Please tell me why the following code only make AX-12+ move in clock wise direction? In fact I want to change it direction with diferent seting for Goal speed setting bit 10


//################################################## ########
//## R O B O T I S ##
//## ReadWrite Example code for Dynamixel. ##
//## 2009.11.10 ##
//################################################## ########
#include <stdio.h>
#include <termio.h>
#include <unistd.h>
#include <dynamixel.h>

// Control table address
#define CW_Angle_L 6
#define CW_Angle_H 7
#define CCW_Angle_L 8
#define CCW_Angle_H 9

#define P_GOAL_POSITION_L 30
#define P_GOAL_POSITION_H 31
#define P_GOAL_SPEED_L 32
#define P_GOAL_SPEED_H 33
#define P_PRESENT_POSITION_L 36
#define P_PRESENT_POSITION_H 37
#define P_PRESENT_SPEED_L 38
#define P_PRESENT_SPEED_H 39
#define P_MOVING 46

// Defulat setting
#define DEFAULT_BAUDNUM 1 // 1Mbps
#define DEFAULT_ID 3 //ID motor

void PrintCommStatus(int CommStatus);
void PrintErrorCode(void);

int main()
{
int baudnum = 1;
int GoalPos[2] = {0, 1023};
//int GoalPos[2] = {0, 4095}; // for Ex series
int index = 0;
int deviceIndex = 0;
int Moving, PresentPos;
int CommStatus;

printf( "\n\nRead/Write example for Linux\n\n" );
///////// Open USB2Dynamixel ////////////
if( dxl_initialize(deviceIndex, baudnum) == 0 )
{
printf( "Failed to open USB2Dynamixel!\n" );
printf( "Press Enter key to terminate...\n" );
getchar();
return 0;
}
else
printf( "Succeed to open USB2Dynamixel!\n" );

while(1)
{


printf( "Press Enter key to continue!(press ESC and Enter to quit)\n" );
if(getchar() == 0x1b)
break;
dxl_write_word( DEFAULT_ID, CW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, P_GOAL_SPEED_L, 1023 ); //0-1023
dxl_write_word( DEFAULT_ID, P_GOAL_SPEED_H, 0 ); // 00000000 clock wise


printf( "Press Enter key to continue!(press ESC and Enter to quit)\n" );


if(getchar() == 0x1b)
break;

dxl_write_word( DEFAULT_ID, CW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, P_GOAL_SPEED_L, 1023 );
dxl_write_word( DEFAULT_ID, P_GOAL_SPEED_H, 4 ); // 00000100 anticlock wise


}

// Close device
dxl_terminate();
printf( "Press Enter key to terminate...\n" );
getchar();
return 0;
}
// Print communication result
void PrintCommStatus(int CommStatus)
{
switch(CommStatus)
{
case COMM_TXFAIL:
printf("COMM_TXFAIL: Failed transmit instruction packet!\n");
break;

case COMM_TXERROR:
printf("COMM_TXERROR: Incorrect instruction packet!\n");
break;

case COMM_RXFAIL:
printf("COMM_RXFAIL: Failed get status packet from device!\n");
break;

case COMM_RXWAITING:
printf("COMM_RXWAITING: Now recieving status packet!\n");
break;

case COMM_RXTIMEOUT:
printf("COMM_RXTIMEOUT: There is no status packet!\n");
break;

case COMM_RXCORRUPT:
printf("COMM_RXCORRUPT: Incorrect status packet!\n");
break;

default:
printf("This is unknown error code!\n");
break;
}
}

// Print error bit of status packet
void PrintErrorCode()
{
if(dxl_get_rxpacket_error(ERRBIT_VOLTAGE) == 1)
printf("Input voltage error!\n");

if(dxl_get_rxpacket_error(ERRBIT_ANGLE) == 1)
printf("Angle limit error!\n");

if(dxl_get_rxpacket_error(ERRBIT_OVERHEAT) == 1)
printf("Overheat error!\n");

if(dxl_get_rxpacket_error(ERRBIT_RANGE) == 1)
printf("Out of range error!\n");

if(dxl_get_rxpacket_error(ERRBIT_CHECKSUM) == 1)
printf("Checksum error!\n");

if(dxl_get_rxpacket_error(ERRBIT_OVERLOAD) == 1)
printf("Overload error!\n");

if(dxl_get_rxpacket_error(ERRBIT_INSTRUCTION) == 1)
printf("Instruction code error!\n");
}

zhenli
05-30-2013, 06:17 AM
Besides, when we set

dxl_write_word( DEFAULT_ID, CW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_H, 0 );

What is the default value for joint mode to realize position control.Since I find out we must reset them before we use it back to position mode

zhenli
05-30-2013, 06:18 AM
Please tell me why the following code only make AX-12+ move in clock wise direction? In fact I want to change it direction with diferent seting for Goal speed setting bit 10


//################################################## ########
//## R O B O T I S ##
//## ReadWrite Example code for Dynamixel. ##
//## 2009.11.10 ##
//################################################## ########
#include <stdio.h>
#include <termio.h>
#include <unistd.h>
#include <dynamixel.h>

// Control table address
#define CW_Angle_L 6
#define CW_Angle_H 7
#define CCW_Angle_L 8
#define CCW_Angle_H 9

#define P_GOAL_POSITION_L 30
#define P_GOAL_POSITION_H 31
#define P_GOAL_SPEED_L 32
#define P_GOAL_SPEED_H 33
#define P_PRESENT_POSITION_L 36
#define P_PRESENT_POSITION_H 37
#define P_PRESENT_SPEED_L 38
#define P_PRESENT_SPEED_H 39
#define P_MOVING 46

// Defulat setting
#define DEFAULT_BAUDNUM 1 // 1Mbps
#define DEFAULT_ID 3 //ID motor

void PrintCommStatus(int CommStatus);
void PrintErrorCode(void);

int main()
{
int baudnum = 1;
int GoalPos[2] = {0, 1023};
//int GoalPos[2] = {0, 4095}; // for Ex series
int index = 0;
int deviceIndex = 0;
int Moving, PresentPos;
int CommStatus;

printf( "\n\nRead/Write example for Linux\n\n" );
///////// Open USB2Dynamixel ////////////
if( dxl_initialize(deviceIndex, baudnum) == 0 )
{
printf( "Failed to open USB2Dynamixel!\n" );
printf( "Press Enter key to terminate...\n" );
getchar();
return 0;
}
else
printf( "Succeed to open USB2Dynamixel!\n" );

while(1)
{


printf( "Press Enter key to continue!(press ESC and Enter to quit)\n" );
if(getchar() == 0x1b)
break;
dxl_write_word( DEFAULT_ID, CW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, P_GOAL_SPEED_L, 1023 ); //0-1023
dxl_write_word( DEFAULT_ID, P_GOAL_SPEED_H, 0 ); // 00000000 clock wise


printf( "Press Enter key to continue!(press ESC and Enter to quit)\n" );


if(getchar() == 0x1b)
break;

dxl_write_word( DEFAULT_ID, CW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, P_GOAL_SPEED_L, 1023 );
dxl_write_word( DEFAULT_ID, P_GOAL_SPEED_H, 4 ); // 00000100 anticlock wise


}

// Close device
dxl_terminate();
printf( "Press Enter key to terminate...\n" );
getchar();
return 0;
}
// Print communication result
void PrintCommStatus(int CommStatus)
{
switch(CommStatus)
{
case COMM_TXFAIL:
printf("COMM_TXFAIL: Failed transmit instruction packet!\n");
break;

case COMM_TXERROR:
printf("COMM_TXERROR: Incorrect instruction packet!\n");
break;

case COMM_RXFAIL:
printf("COMM_RXFAIL: Failed get status packet from device!\n");
break;

case COMM_RXWAITING:
printf("COMM_RXWAITING: Now recieving status packet!\n");
break;

case COMM_RXTIMEOUT:
printf("COMM_RXTIMEOUT: There is no status packet!\n");
break;

case COMM_RXCORRUPT:
printf("COMM_RXCORRUPT: Incorrect status packet!\n");
break;

default:
printf("This is unknown error code!\n");
break;
}
}

// Print error bit of status packet
void PrintErrorCode()
{
if(dxl_get_rxpacket_error(ERRBIT_VOLTAGE) == 1)
printf("Input voltage error!\n");

if(dxl_get_rxpacket_error(ERRBIT_ANGLE) == 1)
printf("Angle limit error!\n");

if(dxl_get_rxpacket_error(ERRBIT_OVERHEAT) == 1)
printf("Overheat error!\n");

if(dxl_get_rxpacket_error(ERRBIT_RANGE) == 1)
printf("Out of range error!\n");

if(dxl_get_rxpacket_error(ERRBIT_CHECKSUM) == 1)
printf("Checksum error!\n");

if(dxl_get_rxpacket_error(ERRBIT_OVERLOAD) == 1)
printf("Overload error!\n");

if(dxl_get_rxpacket_error(ERRBIT_INSTRUCTION) == 1)
printf("Instruction code error!\n");
}

zhenli
05-30-2013, 06:26 AM
How to change the rotation direction ,all data to set GOAL_SPEED is clock wise rotation.


dxl_write_word( DEFAULT_ID, CW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_L, 0 );
dxl_write_word( DEFAULT_ID, CCW_Angle_H, 0 );
dxl_write_word( DEFAULT_ID, P_GOAL_SPEED_L, 1023 ); ?????
dxl_write_word( DEFAULT_ID, P_GOAL_SPEED_H, 4 ); ????

tician
05-30-2013, 07:35 AM
Since you are writing a full word with each command, DO NOT USE THE _H ADDRESS.



#include <stdio.h>
#include <termio.h>
#include <unistd.h>
#include <dynamixel.h>

// Control table address
#define P_CW_ANGLE_L 6
#define P_CCW_ANGLE_L 8

#define P_GOAL_POSITION_L 30
#define P_MOVING_SPEED_L 32
#define P_PRESENT_POSITION_L 36
#define P_PRESENT_SPEED_L 38
#define P_MOVING 46

// Defulat setting
#define DEFAULT_BAUDNUM 1 // 1Mbps
#define DEFAULT_ID 3 //ID motor

void PrintCommStatus(int CommStatus);
void PrintErrorCode(void);

int main()
{
int baudnum = 1;
int GoalPos[2] = {0, 1023};
//int GoalPos[2] = {0, 4095}; // for Ex series
int index = 0;
int deviceIndex = 0;
int Moving, PresentPos;
int CommStatus;

printf( "\n\nRead/Write example for Linux\n\n" );
///////// Open USB2Dynamixel ////////////
if( dxl_initialize(deviceIndex, baudnum) == 0 )
{
printf( "Failed to open USB2Dynamixel!\n" );
printf( "Press Enter key to terminate...\n" );
getchar();
return 0;
}
else
printf( "Succeed to open USB2Dynamixel!\n" );


/// Enable wheel mode
dxl_write_word( DEFAULT_ID, P_CW_ANGLE_L, 0 );
dxl_write_word( DEFAULT_ID, P_CCW_ANGLE_L, 0);

/// Default angle limits
//dxl_write_word( DEFAULT_ID, P_CW_ANGLE_L, 0 );
//dxl_write_word( DEFAULT_ID, P_CCW_ANGLE_L, 1023);


while(1)
{
int speed = whatever_you_want_between_0_and_1023;
int dir_cw = 1; // 1 for CW, 0 for CCW

printf( "Press Enter key to continue!(press ESC and Enter to quit)\n" );
if(getchar() == 0x1b)
break;
printf( "Press Enter key to continue!(press ESC and Enter to quit)\n" );

// move CW
dxl_write_word( DEFAULT_ID, P_MOVING_SPEED_L, (speed&0x03FF) | (dir_cw<<10) );

if(getchar() == 0x1b)
break;

// move CCW
dir_cw = 0;
dxl_write_word( DEFAULT_ID, P_MOVING_SPEED_L, (speed&0x03FF) | (dir_cw<<10) );
}

// Close device
dxl_terminate();
printf( "Press Enter key to terminate...\n" );
getchar();
return 0;
}
// Print communication result
void PrintCommStatus(int CommStatus)
{
switch(CommStatus)
{
case COMM_TXFAIL:
printf("COMM_TXFAIL: Failed transmit instruction packet!\n");
break;

case COMM_TXERROR:
printf("COMM_TXERROR: Incorrect instruction packet!\n");
break;

case COMM_RXFAIL:
printf("COMM_RXFAIL: Failed get status packet from device!\n");
break;

case COMM_RXWAITING:
printf("COMM_RXWAITING: Now recieving status packet!\n");
break;

case COMM_RXTIMEOUT:
printf("COMM_RXTIMEOUT: There is no status packet!\n");
break;

case COMM_RXCORRUPT:
printf("COMM_RXCORRUPT: Incorrect status packet!\n");
break;

default:
printf("This is unknown error code!\n");
break;
}
}

// Print error bit of status packet
void PrintErrorCode()
{
if(dxl_get_rxpacket_error(ERRBIT_VOLTAGE) == 1)
printf("Input voltage error!\n");

if(dxl_get_rxpacket_error(ERRBIT_ANGLE) == 1)
printf("Angle limit error!\n");

if(dxl_get_rxpacket_error(ERRBIT_OVERHEAT) == 1)
printf("Overheat error!\n");

if(dxl_get_rxpacket_error(ERRBIT_RANGE) == 1)
printf("Out of range error!\n");

if(dxl_get_rxpacket_error(ERRBIT_CHECKSUM) == 1)
printf("Checksum error!\n");

if(dxl_get_rxpacket_error(ERRBIT_OVERLOAD) == 1)
printf("Overload error!\n");

if(dxl_get_rxpacket_error(ERRBIT_INSTRUCTION) == 1)
printf("Instruction code error!\n");
}