-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Dynamixel XC430 on Tool Interface #94
Comments
S RebootServo ID [Type [Slope Offset]]Change Of course, there is currently NO way to get the data collected for any servo address other than 1 or 3 (joints 7 or 6) back from the robot, but that will come. Probably need to expand Currently, @jonfurniss has shown that the Physical User Interface works for recording and playback with the 430's, but there are issues because the units are wrong. If you tell a 320 to move 1, that is 0.29' but a 430, it's 0.08789' The plan is use JointsCal and HomeOffset values to correct for those units. The units for JointsCal are a bit confusing. They are a ratio between arcseconds and the amount a joint moves with a single step of the motor; or in the case of servos, a single unit change in the commanded goal. To avoid floating point numbers, they are specified by In the past, values for Joint 6 or Joint 7 would NOT be changed by the firmware at all. They were just passed through to the servo. This was the way of it for 'a' and 'p' and for Now the firmware is adding the corresponding element of HomeOffset and then multiplying the value sent by the corresponding element of the JointsCal array. This correction is now in place, but there was no way to set numbers into those correction factors because the RebootServo has been modified to optionally accept JointsCal and HomeOffset values along with the servo type. If the servo type is not specified, JointsCal and HomeOffset are not changed. If only the type is specified, 1 and 0 are assumed for the slope and offset. case 29: // ServoReset
//printf("Servo Reboot %d",a2);
if (a3) {
//need to translate 3->5, 1->6, 2->7, 4->8 and so on. ServoAddr(joint) does the opposite.
i = NUM_JOINTS + a2 - 1; //4->8, 5->9
switch (a2) {
case 1: i = 6; break; //J7, zero indexed
case 2: i = 7; break; //J8
case 3: i = 5; break; //J6
default: break;
}
ServoData[a2].ServoType = (enum ServoTypes)a3;
if (a3>0) { //if the servo type was supplied
if (0 == a4) {a4=(3600*360);};
JointsCal[i] = (float)a4 / (3600*360);
HomeOffset[i] = a5;
printf("With slope %f offset %d, ", JointsCal[i], HomeOffset[i]);
}
printf("Servo %d joint %d set to type %d \n", a2, i+1, a3);
}
RebootServo(a2);
return 0; And now the For example: Default Mode Just powering on the robot, or doing a Compatibility Mode But XL-430 Mode Then if you want better accuracy, with your XL-430 installed, you do
Arcsecond Mode And finally, going forward, we should (perhaps) have DDE send J6 and J7 positions in arcseconds which would need Notice that the HomeOffset is applied first and then the resulting value is multiplied by JointsCal. This means that the units for HomeOffset are those the user is sending. If you are sending XL-320 units, specify the offset in XL-320 units. If you are sending arcseconds, specify the offset in arcseconds. e.g. When the 'P' move is done: void moverobotPID(int a1,int a2,int a3,int a4,int a5) {
a1 -= HomeOffset[0];
...
a1=(int)((double)a1 * JointsCal[0]); and then the movement is processed. And in the standard status values, the servo positions to be returned are computed like this: |
MonitoringUpdate monitor thread to read which ever servos have been rebooted, according to the type supplied. Supports up to 20 servo id's or rather servo id's 1 to 20. Only ID's 3 (J6) and 1 (J7) are currently readable via the standard status responses. Possibilities
|
Address Issue #94 See the issue for extensive additional documentation. Line 5607, minor change to keep a 'z' oplet without any parameter from crashing DexRun. Sleep is important to give servos time to reboot during setup. Removed mention of master / slave.
For joints 6 and 7, the standard move all joints and other commands work. For additional servo id's we need to send ServoSetX commands to set the goal position. James W wrote and tested this code. It translates the desired position setting to the hex format needed to send a binary value. function num_to_hex(num, size = 12){
let num_array = Vector.make_matrix(1, Math.round(2 * size / 3))[0]
let num_str = num.toString(16)
for(let i = 0; i < num_str.length; i++){
num_array[i] = num_str[num_str.length - i - 1]
}
let str = ""
for(let i = 0; i < num_array.length ; i += 2){
str += "%" + num_array[i + 1] + num_array[i]
}
return str
}
function set_430_angle(id, angle){
let size = 12
return make_ins("S", "ServoSetX", id, 116, size, num_to_hex(Math.round(4096 * angle / 360), size))
}
new Job({
name: "test",
do_list: [
set_430_angle(4, 0),
Robot.wait_until(1),
set_430_angle(4, 1*90),
Robot.wait_until(1),
set_430_angle(4, 2*90),
Robot.wait_until(1),
set_430_angle(4, 3*90)
]
}) The Servo at ID 4 was setup in Defaults.make_ins with
|
Note for the future: If you run an XC-430 with commands for an XL-320, it will probably cause the servo to start reporting a hardware error, the light will blink, and it will refuse to operate. This happens because the goal position address for the XL-320 overlaps the Temperature Limit setting for the XC-430. And you can set a temperature limit of as little as 0'C. The servo will then only operate if it's frozen. To verify this is the case, read back address 31 with To recover from this error, send |
jonfurniss commented on Oct 9 DDE currently has a built in offset when sending move all joints to J6 (servo ID 3) of 148.48° or 512 XL-320 (148.48°/0.29°/Dynamixel step) units. So a command of 0° from DDE has the XL-320 in the middle of its movement. When operating the XC-430s from DDE in compatibility mode, we need to account for the larger motion range of the XC-430 as well as the built in DDE offset. When parsing the RebootServo command, DexRun.c first assigns the slope, then the offset, so we need to do the offset with respect to XL-320 units, not XC-430 units. Joint 6 CompatibilityDexter's 0° position is 180° off from the XC-430's 0 Dynamixel unit position, so 180°/0.29°/XL-320 step ~= 620 Dynamixel units. Then 620-512 = 108 is the offset in Defaults.make_ins that has the J6 (servo ID 3) XC-430 behaving as expected. Note: Changes to the code to bring it in-line with the homeoffsets for other joints mean that this value must be negative because it will be subtracted from the commanded position. Joint 7 CompatibilityBecause the gripper end effector has TWO gears vs one between the power takeoff on the servo and the linear gear, larger values close the gripper rather than open it as it would on the XL-320.
In order to accomplish this, we must use a negative ratio and provide a positive offset to bias the results back into a positive range. Again, that bias must be in XL-320 units. So if the new gripper is closed when the XC-430 is at 3300 / (0.29 / 0.088) = 1001 for the correct offset. If we want to be at the removal point when DDE is told to go to 100, which is 345 to the XL-320, the offset and ratio moves the XC-430 to 2158 and that appears to be correct; the end effector is lined up for removal. The normal maximum open value for the old servos was about 150, but with the XC-320's we can go to 277 before the bias causes us to hit 0. Values larger than this will not work, as the location would then be negative. Defaults.make_ins for CompatibilityFor setting up a gripper with Servo 3 as joint 6 and Servo 1 as joint 7, paste the following code at the bottom of Defaults.make_ins.
|
The XL-320s have a limited rotational range which sometimes limits our ability to do things. The XC430 doesn't cost much more and provides higher torque, stronger body, and continuous rotation modes. It is, however, physically larger and so is not a direct replacement. It also has a completely different memory map and more complex operating modes.
We are looking at the XC-430-W240:
https://emanual.robotis.com/docs/en/dxl/x/xc430-w240/
r 0 #Servo ID, Addr, Len
There is a new #Servo # Addr Len for the 'r' (read from robot) oplet that lets you query a servo directly and get back the result. I'm hoping it might be helpful for reading back torques really quickly (faster than the monitor mode) or for diagnosing Servo issues. e.g.
Sending an
S RebootServo 1;
does not resolve the error. Sending anS ServoSet2X 1 34 59;
Set Max Min voltage 0x22 0x3B gets me a packet status error of 0x84 which is "Data Range Error: Data to be written in the corresponding Address is outside the range of the minimum/maximum value"So it's looking like our days of running the servos at 5 volts when they are spec'd for a min of 6 volts are over. Supporting the XC430's will apparently require another power supply... Not sure why the XL320's were willing to work at 5 volts and the XC430's don't seem to be.
We do, as it happens, have an extra power supply ready to go:
https://workspace.circuitmaker.com/Projects/Details/James-Newton-2/Dexter-Tool-Interface-Servo-Power-Supply
But it's another item on the BOM, it's hard to find a place to mount it, and getting them made is a pain. When I designed it, I looked for anything we could just buy from China, but didn't find anything that met the requirements. The XL320 max voltage is 8.4, but the XC430 will run on up to 14.8, so a more commonly available 12 volt unit like:
http://filecenter.deltaww.com/Products/download/01/0102/datasheet/DS_V36SE12004.pdf
will now work. If you get the "negative logic" version, be sure to short the "ON/OFF" input the ground to get it to work. On the "positive logic" version, you must leave that pin floating.
Servo Read code: (place in the 'r' handler)
Useful instructions:
S ServoSetX ID Addr Len [Data]
Added a new ServoSetX set parameter which can take several parameters:
Internally ServoSet2X and ServoSet are replaced with ServoSetX.
TODO: Should ServoSet be removed from the code and ServoSetX be renamed to ServoSet.
The text was updated successfully, but these errors were encountered: