urko_18
04-13-2018, 06:52 AM
Hi again, everybody!
As some of you already know I am improving a program to control a robotic arm with four dynamixel motors (2 MX64 and 2 mx106) in Arduino.
My biggest problem is to control the torque, what I want is to make a collaborative robot, and for that, I need to know the torque that the robot will have everytime, so in the case that the torque is too high, to stop the robot.
My program, today, is the following: (in this case I have set a torque limit of 500 and a serial.print of "Warning torque is exceed", as a test)
#include <ax12.h> //Include ArbotiX DYNAMIXEL library
const int SERVO_ID[] = {1, 2, 3, 4};
const int servo_count = sizeof(SERVO_ID) / sizeof(*SERVO_ID); //the compiler calculate the amount of servos
int repetitions, interrupt_state;
double Speed;
int m = 400; //columns
int pos2[] = {3820, 400, 230, 2395}; //rest position of the dynamixel motors
void setup()
{
dxlInit(1000000); //start dynamixel library at 1mbps to communicate with the servos
Serial.begin(9600); //start serial at 9600 for reporting data.
for (int i = 0; i < servo_count; ++i)
{
Relax(SERVO_ID[i]);
Serial.print(F("ID: "));
Serial.println(SERVO_ID[i]);
}
delay(1000);
}
void loop()
{
Serial.println(F("How many times do you want to repeat the sequence?"));
while (Serial.available() == 0) {}
repetitions = Serial.parseInt();
Serial.print(F("repetitions = "));
Serial.println(repetitions);
delay(3000);
Serial.println(F("How fast do you want to repeat the sequence?"));
Serial.println(F(" 1 = Slow 2 = Normal 3 = Fast"));
while (Serial.available() == 0) {}
Speed = Serial.parseInt();
if (Speed <= 0 || Speed >= 4)
{
Serial.println(F("You have entered a wrong value"));
return;
}
if (Speed == 1)
{
Speed = 1000;
}
else if (Speed == 2)
{
Speed = 700;
}
else if (Speed == 3)
{
Speed = 400;
}
Serial.print(F("Speed = "));
Serial.print(Speed, 0);
Serial.println(F(" microseconds"));
delay(3000);
Serial.print(F("Positions vector "));
Serial.print(F(": ["));
int positionn[servo_count][m]; //Matrix of movements
for (int i = 0; i < m; i++) // structure to create columns
{
for (int j = 0; j < servo_count; j++) // structure to create columns
{
positionn[j][i] = dxlGetPosition(SERVO_ID[j]); //read and save the actual position
}
delay(10);
for (int j = 0; j < servo_count; j++) // structure to create columns
{
Serial.print(positionn[j][i]); //Display the vector
Serial.print(F(", "));
}
}
Serial.print(F("]\n"));
delay(5000);
Serial.println(F("The servos will move to the initial position."));
/***The servos will move according to registered movements***/
for (int a = 0; a < repetitions; a++) //Repetition of the process (a = number of sequences)
{
Serial.print(F("SEQUENCE "));
Serial.println(a + 1);
int position[servo_count];
int turns[servo_count];
int pos1[servo_count];
int pos2[servo_count];
int current[servo_count];
int torque_limit = 500;
int torque[servo_count];
for (int i = 0; i < servo_count; i++)
{
current[i] = positionn[i][0];
position[i] = positionn[i][0];
turns[i] = 0;
pos1[i] = dxlGetPosition(SERVO_ID[i]); //Actual servo position
pos2[i] = positionn[i][0]; //Initial position of the movement (objective)
}
for (int servo = 0; servo < servo_count; ++servo)
{
go_to_position(pos1, pos2, servo); //Function that moves the robot to the initial position
}
Serial.println(F("Now the servos will do the registered movements."));
delay(2000);
for (int movement = 0; movement < m; movement++)
{
for (int servo = 0; servo < servo_count; servo++)
{
if (positionn[servo][movement] != current[servo])
{
int next_pos = 1;
if (positionn[servo][movement] < current[servo])
next_pos = -1;
while (positionn[servo][movement] != current[servo])
{
current[servo] += next_pos;
delayMicroseconds(Speed);
dxlSetGoalPosition(SERVO_ID[servo], current[servo]);
torque[servo] = dxlGetTorque(SERVO_ID[servo]);
Serial.println(torque[servo]);
if (torque[servo] > torque_limit)
{
Serial.println("WARNING torque limit exceed");
}
if (current[servo] == position[servo] + MX_MAX_POSITION_VALUE)
{
position[servo] = current[servo];
turns[servo]++;
}
else if (current[servo] == position[servo] - MX_MAX_POSITION_VALUE)
{
position[servo] = current[servo];
turns[servo]--;
}
}
}
}
}
for (int i = 0; i < servo_count; i++)
{
Serial.print(F("Turns engine "));
Serial.print(i + 1);
Serial.print(F(": "));
Serial.println(turns[i]);
Serial.println(" ");
}
}
delay(3000);
/****REST POSITION****/
Serial.println(F("The robot will move to the resting position."));
int pos1[servo_count];
for (int i = 0; i < servo_count; i++)
{
pos1[i] = dxlGetPosition(SERVO_ID[i]); //Actual servo position
}
for (int servo = 0; servo < servo_count; ++servo)
{
go_to_position(pos1, pos2, servo); //Function that moves the robot to the initial position
}
delay(1000);
dxlTorqueOffAll();
Serial.println(F("END!"));
}
void go_to_position(int pos1[], int pos2[], int servo)//function
{
while (pos1[servo] != pos2[servo])
{
if (pos2[servo] < pos1[servo])
{
dxlSetGoalPosition(SERVO_ID[servo], pos1[servo]);
pos1[servo]--;
delayMicroseconds(800);
}
else if (pos2[servo] > pos1[servo])
{
dxlSetGoalPosition(SERVO_ID[servo], pos1[servo]);
pos1[servo]++;
delayMicroseconds(800);
}
}
}
The problem is that when the robot is moving, when the program prints on the serial monitor the torque that the motors support at all times:
torque[servo] = dxlGetTorque(SERVO_ID[servo]);
Serial.println(torque[servo]);
Almost always gives me a value of -1, and as much as I try to put some obstacle to the robot (with the intention of raising the torque and the message "Warning torque is exceed"), usually does not usually vary the value.
So, I do not know if maybe using dxlGetTorque (ID) is not the correct option, or if what fails is that the ArbotiX-M that is not able to process as much data as position and torque at the same time or i don´t know ...
I hope someone can give me their opinion !!
Many thanks!!
As some of you already know I am improving a program to control a robotic arm with four dynamixel motors (2 MX64 and 2 mx106) in Arduino.
My biggest problem is to control the torque, what I want is to make a collaborative robot, and for that, I need to know the torque that the robot will have everytime, so in the case that the torque is too high, to stop the robot.
My program, today, is the following: (in this case I have set a torque limit of 500 and a serial.print of "Warning torque is exceed", as a test)
#include <ax12.h> //Include ArbotiX DYNAMIXEL library
const int SERVO_ID[] = {1, 2, 3, 4};
const int servo_count = sizeof(SERVO_ID) / sizeof(*SERVO_ID); //the compiler calculate the amount of servos
int repetitions, interrupt_state;
double Speed;
int m = 400; //columns
int pos2[] = {3820, 400, 230, 2395}; //rest position of the dynamixel motors
void setup()
{
dxlInit(1000000); //start dynamixel library at 1mbps to communicate with the servos
Serial.begin(9600); //start serial at 9600 for reporting data.
for (int i = 0; i < servo_count; ++i)
{
Relax(SERVO_ID[i]);
Serial.print(F("ID: "));
Serial.println(SERVO_ID[i]);
}
delay(1000);
}
void loop()
{
Serial.println(F("How many times do you want to repeat the sequence?"));
while (Serial.available() == 0) {}
repetitions = Serial.parseInt();
Serial.print(F("repetitions = "));
Serial.println(repetitions);
delay(3000);
Serial.println(F("How fast do you want to repeat the sequence?"));
Serial.println(F(" 1 = Slow 2 = Normal 3 = Fast"));
while (Serial.available() == 0) {}
Speed = Serial.parseInt();
if (Speed <= 0 || Speed >= 4)
{
Serial.println(F("You have entered a wrong value"));
return;
}
if (Speed == 1)
{
Speed = 1000;
}
else if (Speed == 2)
{
Speed = 700;
}
else if (Speed == 3)
{
Speed = 400;
}
Serial.print(F("Speed = "));
Serial.print(Speed, 0);
Serial.println(F(" microseconds"));
delay(3000);
Serial.print(F("Positions vector "));
Serial.print(F(": ["));
int positionn[servo_count][m]; //Matrix of movements
for (int i = 0; i < m; i++) // structure to create columns
{
for (int j = 0; j < servo_count; j++) // structure to create columns
{
positionn[j][i] = dxlGetPosition(SERVO_ID[j]); //read and save the actual position
}
delay(10);
for (int j = 0; j < servo_count; j++) // structure to create columns
{
Serial.print(positionn[j][i]); //Display the vector
Serial.print(F(", "));
}
}
Serial.print(F("]\n"));
delay(5000);
Serial.println(F("The servos will move to the initial position."));
/***The servos will move according to registered movements***/
for (int a = 0; a < repetitions; a++) //Repetition of the process (a = number of sequences)
{
Serial.print(F("SEQUENCE "));
Serial.println(a + 1);
int position[servo_count];
int turns[servo_count];
int pos1[servo_count];
int pos2[servo_count];
int current[servo_count];
int torque_limit = 500;
int torque[servo_count];
for (int i = 0; i < servo_count; i++)
{
current[i] = positionn[i][0];
position[i] = positionn[i][0];
turns[i] = 0;
pos1[i] = dxlGetPosition(SERVO_ID[i]); //Actual servo position
pos2[i] = positionn[i][0]; //Initial position of the movement (objective)
}
for (int servo = 0; servo < servo_count; ++servo)
{
go_to_position(pos1, pos2, servo); //Function that moves the robot to the initial position
}
Serial.println(F("Now the servos will do the registered movements."));
delay(2000);
for (int movement = 0; movement < m; movement++)
{
for (int servo = 0; servo < servo_count; servo++)
{
if (positionn[servo][movement] != current[servo])
{
int next_pos = 1;
if (positionn[servo][movement] < current[servo])
next_pos = -1;
while (positionn[servo][movement] != current[servo])
{
current[servo] += next_pos;
delayMicroseconds(Speed);
dxlSetGoalPosition(SERVO_ID[servo], current[servo]);
torque[servo] = dxlGetTorque(SERVO_ID[servo]);
Serial.println(torque[servo]);
if (torque[servo] > torque_limit)
{
Serial.println("WARNING torque limit exceed");
}
if (current[servo] == position[servo] + MX_MAX_POSITION_VALUE)
{
position[servo] = current[servo];
turns[servo]++;
}
else if (current[servo] == position[servo] - MX_MAX_POSITION_VALUE)
{
position[servo] = current[servo];
turns[servo]--;
}
}
}
}
}
for (int i = 0; i < servo_count; i++)
{
Serial.print(F("Turns engine "));
Serial.print(i + 1);
Serial.print(F(": "));
Serial.println(turns[i]);
Serial.println(" ");
}
}
delay(3000);
/****REST POSITION****/
Serial.println(F("The robot will move to the resting position."));
int pos1[servo_count];
for (int i = 0; i < servo_count; i++)
{
pos1[i] = dxlGetPosition(SERVO_ID[i]); //Actual servo position
}
for (int servo = 0; servo < servo_count; ++servo)
{
go_to_position(pos1, pos2, servo); //Function that moves the robot to the initial position
}
delay(1000);
dxlTorqueOffAll();
Serial.println(F("END!"));
}
void go_to_position(int pos1[], int pos2[], int servo)//function
{
while (pos1[servo] != pos2[servo])
{
if (pos2[servo] < pos1[servo])
{
dxlSetGoalPosition(SERVO_ID[servo], pos1[servo]);
pos1[servo]--;
delayMicroseconds(800);
}
else if (pos2[servo] > pos1[servo])
{
dxlSetGoalPosition(SERVO_ID[servo], pos1[servo]);
pos1[servo]++;
delayMicroseconds(800);
}
}
}
The problem is that when the robot is moving, when the program prints on the serial monitor the torque that the motors support at all times:
torque[servo] = dxlGetTorque(SERVO_ID[servo]);
Serial.println(torque[servo]);
Almost always gives me a value of -1, and as much as I try to put some obstacle to the robot (with the intention of raising the torque and the message "Warning torque is exceed"), usually does not usually vary the value.
So, I do not know if maybe using dxlGetTorque (ID) is not the correct option, or if what fails is that the ArbotiX-M that is not able to process as much data as position and torque at the same time or i don´t know ...
I hope someone can give me their opinion !!
Many thanks!!