PDA

View Full Version : [Question(s)] HR-OS1 Has anyone added additional servos ?



ShirleyWang
03-02-2016, 01:12 AM
Hi everyone,

We are trying to add two new servos as robot's hands, not replace servo No.5 and No.6. So, we add names and numbers of these two servos in related files. And then use "dxl_monitor" to set the numbers to be 21 and 22. But there are some problems in rme.

1. I create a new motion page with one step in rme. The value of two new servos have been saved in motion file. When playing this new page, the servos from No.1 to No.20 can work as usual, but two new servos doesn't work.

2. I copy an existing page as a new page. Obviously, it doesn't have the value of two new servos in step column, just show "----". So I copy the value of step 7 to a step. When playing the page, all the servos do not work.

3. If I change the value of two new servos in an existing page directly, this page will not work either.

4. The new servos can only work when I change the value in step 07. Because function SetValue() in step 07 use function writeword() to change the value of servos in real time. But other steps only change and save the value in the motion file.

Has anyone added additional servos like us? Can new servos work in rme? I don't know why they doesn't work, I guess the reason is about the format of motion file. Any suggestions? Sorry for my bad English.:wink:

Shirley

r3n33
03-02-2016, 03:29 PM
Hi Shirley

I have not gone through the process of adding servos to the HR-OS1 but I have taken a look at the source code. To play back motions in rme the Action.cpp motion module is called upon and it appears there are a few requirements to be met for new servos to be included.

Have you also corrected NUMBER_OF_JOINTS and ID_MAX in JointData.h?
https://github.com/Interbotix/HROS1-Framework/blob/master/Framework/include/JointData.h

It also appears rme is not prepared to display information about the added servos so it is likely changes will be needed there as well.
https://github.com/Interbotix/HROS1-Framework/blob/master/Linux/project/rme/cmd_process.cpp#L368

RME also checks for ID_20_ROW which will need to be expanded upon and modified:
https://github.com/Interbotix/HROS1-Framework/blob/master/Linux/project/rme/cmd_process.h#L49
https://github.com/Interbotix/HROS1-Framework/blob/master/Linux/project/rme/cmd_process.cpp#L198
https://github.com/Interbotix/HROS1-Framework/blob/master/Linux/project/rme/cmd_process.cpp#L899

So that's about what I'm noticing at first glance. More code modifications will be necessary beyond adding the names and ID's of the new servos it would seem. Hope this helps.

ShirleyWang
03-04-2016, 12:41 AM
Hi r3n33

Thank you for your suggestions. Yes, I have modified the code in above files, so RME can show the rows of two servos, like this.

ID: 1(R_SHO_PITCH)[0461] 0387|---- ---- ---- ---- ---- ---- 55 init
ID: 2(L_SHO_PITCH)[????] 0641|---- ---- ---- ---- ---- ---- 55 Page Number:0001
ID: 3(R_SHO_ROLL) [????] 0460|---- ---- ---- ---- ---- ---- 55 Address:0x00200
ID: 4(L_SHO_ROLL) [????] 0563|---- ---- ---- ---- ---- ---- 55 Play Count:001
ID: 5(R_ELBOW) [????] 0452|---- ---- ---- ---- ---- ---- 55 Page Step:001
ID: 6(L_ELBOW) [????] 0572|---- ---- ---- ---- ---- ---- 55 Page Speed:032
ID: 7(R_HIP_YAW) [????] 0510|---- ---- ---- ---- ---- ---- 55 Accel Time:032
ID: 8(L_HIP_YAW) [????] 0510|---- ---- ---- ---- ---- ---- 55 Link to Next:000
ID: 9(R_HIP_ROLL) [????] 0512|---- ---- ---- ---- ---- ---- 55 Link to Exit:000
ID:10(L_HIP_ROLL) [????] 0510|---- ---- ---- ---- ---- ---- 55 000
ID:11(R_HIP_PITCH)[????] 0494|---- ---- ---- ---- ---- ---- 55
ID:12(L_HIP_PITCH)[????] 0521|---- ---- ---- ---- ---- ---- 55
ID:13(R_KNEE) [????] 0498|---- ---- ---- ---- ---- ---- 55
ID:14(L_KNEE) [????] 0514|---- ---- ---- ---- ---- ---- 55
ID:15(R_ANK_PITCH)[????] 0531|---- ---- ---- ---- ---- ---- 55
ID:16(L_ANK_PITCH)[????] 0488|---- ---- ---- ---- ---- ---- 55
ID:17(R_ANK_ROLL) [????] 0508|---- ---- ---- ---- ---- ---- 55
ID:18(L_ANK_ROLL) [????] 0507|---- ---- ---- ---- ---- ---- 55
ID:19(HEAD_PAN) [????] 0509|---- ---- ---- ---- ---- ---- 55
ID:20(HEAD_TILT) [????] 0512|---- ---- ---- ---- ---- ---- 55
ID:21(R_HAND) [????] ----|---- ---- ---- ---- ---- ---- 00
ID:22(L_HAND) [????] ----|---- ---- ---- ---- ---- ---- 00
PauseTime [ 000] 000| 000 000 000 000 000 000
Time(x 8msec) [ 000] 200| 000 000 000 000 000 000
STP7 STP0 STP1 STP2 STP3 STP4 STP5 STP6
]
And the value can be changed in step 7 which shows the current value of servos. But it seems not enough. So, maybe cannot add data of new servos into motion_4096.bin file? :(

Shirley

DresnerRobotics
03-05-2016, 07:11 PM
And the value can be changed in step 7 which shows the current value of servos. But it seems not enough. So, maybe cannot add data of new servos into motion_4096.bin file? :(

Shirley

I've actually done this before on some of the custom "Jimmy" robots we built over the course of the 21st Century Robot project, so I can tell you it does indeed work, it's just a bit cumbersome due to how the Darwin-OP framework was originally coded- most of the servo ID handling is hardcoded for 20 servos/darwin configuration, without any thought into scalability.

I believe you also have to initialize each page as 'new' in rme to get them to respond, otherwise they have the old servo ID tables. The way the binary motion file is handled is poorly documented to say the least.

I haven't actually done this in awhile, but you'll see some remnants of my code in the HROS5-Framework. Renee has some of it already and it sounds like you've figured out some, but here are my notes on what needs to be updated:

JointData.h

Update ID enum of JointData.h to include the new servos.


ID_L_ELBOW_YAW = 21,
ID_R_ELBOW_YAW = 22,
ID_MAX = 22,
NUMBER_OF_JOINTS = 23 //This is always ID_MAX + 1


JointData.cpp

If you want to be able to properly execute motion module handoffs, you need to update the new joints into one of the enable functions in JointData.cpp So if you added servos to the arms, you'd want to update the corresponding functions:


void JointData::SetEnableRightArmOnly(bool enable, bool exclusive)
{
SetEnable(ID_R_SHOULDER_PITCH, enable, exclusive);
SetEnable(ID_R_SHOULDER_ROLL, enable, exclusive);
SetEnable(ID_R_ELBOW, enable, exclusive);
SetEnable(ID_R_ELBOW_YAW, enable, exclusive);
SetEnable(ID_R_WRIST_YAW, enable, exclusive);
SetEnable(ID_R_GRIPPER, enable, exclusive);
}



dxl_monitor

This one is pretty easy as it populates based on JointData.h so most of the work is already done. You do need to tell it what string label/name you want it to output when it detects a recognized servo in the framework though. Here's changes to cmd_process.cpp for example:


case JointData::ID_HEAD_TILT:
return "HEAD_TILT";


case ArbotixPro::ID_CM:
return "ARBOTIX_PRO";


case JointData::ID_TORSO_ROTATE:
return "TORSO_ROTATE";


case JointData::ID_R_ELBOW_YAW:
return "R_ELBOW_YAW";

case JointData::ID_L_ELBOW_YAW:
return "L_ELBOW_YAW";


case JointData::ID_R_WRIST_YAW:
return "R_WRIST_YAW";


case JointData::ID_L_WRIST_YAW:
return "L_WRIST_YAW";


case JointData::ID_R_GRIPPER:
return "R_GRIPPER";


case JointData::ID_L_GRIPPER:
return "L_GRIPPER";


rme/action_editor

This gets a little trickier as there is a LOT hardcoded.

cmd_process.cpp change example where I've added 6 servos for a total of 26, and renamed all servo IDs via JointData.h

line 345~ in the DrawPage function

int res = system("clear"); res = 0;
// 80 01234567890123456789012345678901234567890123456789 012345678901234567890123456789 //24
printf( "ID: 1(RR_COXA) [ ] \n" );//0
printf( "ID: 2(RR_FEMUR) [ ] Page Number: \n" );//1
printf( "ID: 3(RR_TIBIA) [ ] Address: \n" );//2
printf( "ID: 4(RR_TARSUS) [ ] Play Count: \n" );//3
printf( "ID: 5(RM_COXA) [ ] Page Step: \n" );//4
printf( "ID: 6(RM_FEMUR) [ ] Page Speed: \n" );//5
printf( "ID: 7(RM_TIBIA) [ ] Accel Time: \n" );//6
printf( "ID: 8(RM_TARSUS) [ ] Link to Next: \n" );//7
printf( "ID: 9(RF_COXA) [ ] Link to Exit: \n" );//8
printf( "ID:10(RF_FEMUR) [ ] \n" );//9
printf( "ID:11(RF_TIBIA) [ ] \n" );//0
printf( "ID:12(RF_TARSUS) [ ] \n" );//1
printf( "ID:13(LR_COXA) [ ] \n" );//2
printf( "ID:14(LR_FEMUR) [ ] \n" );//3
printf( "ID:15(LR_TIBIA) [ ] \n" );//4
printf( "ID:16(LR_TARSUS) [ ] \n" );//5
printf( "ID:17(LM_COXA) [ ] \n" );//6
printf( "ID:18(LM_FEMUR) [ ] \n" );//7
printf( "ID:19(LM_TIBIA) [ ] \n" );//8
printf( "ID:20(LM_TARSUS) [ ] \n" );//9
printf( "ID:21(LF_COXA) [ ] \n" );//0
printf( "ID:22(LF_FEMUR) [ ] \n" );//1
printf( "ID:23(LF_TIBIA) [ ] \n" );//2
printf( "ID:24(LF_TARSUS) [ ] \n" );//3
printf( "ID:25(HEAD_PAN) [ ] \n" );//4
printf( "ID:26(HEAD_TILT) [ ] \n" );//5
printf( " PauseTime [ ] \n" );//6


Next you need to update cmd_process.h so it draws more rows in the terminal to account for additional servo, example:

line 8~


#define SCREEN_COL 80
#define SCREEN_ROW 30 //original value was 24, + 6 for additional servos.



line 31~


// Position of Row
#define ID_1_ROW 0
#define ID_2_ROW 1
#define ID_3_ROW 2
#define ID_4_ROW 3
#define ID_5_ROW 4
#define ID_6_ROW 5
#define ID_7_ROW 6
#define ID_8_ROW 7
#define ID_9_ROW 8
#define ID_10_ROW 9
#define ID_11_ROW 10
#define ID_12_ROW 11
#define ID_13_ROW 12
#define ID_14_ROW 13
#define ID_15_ROW 14
#define ID_16_ROW 15
#define ID_17_ROW 16
#define ID_18_ROW 17
#define ID_19_ROW 18
#define ID_20_ROW 19
//new servos here
#define ID_21_ROW 20
#define ID_22_ROW 21
#define ID_23_ROW 22
#define ID_24_ROW 23
#define ID_25_ROW 24
#define ID_26_ROW 25
//pause & speed row are sequentially enumerated from the prior value
//(0 through 25 in this case, 0 through 19 on stock darwin)
#define PAUSE_ROW 26 //originally 20
#define SPEED_ROW 27 //originally 21
#define CMD_ROW 29 //originally 23 (this is always SPEED_ROW + 2)




I believe that's it. Any other terminal programs would need to be updated in a similar manner. Let me know if this works for you.

ShirleyWang
03-06-2016, 10:23 PM
I believe that's it. Any other terminal programs would need to be updated in a similar manner. Let me know if this works for you.

Thanks, Tyberius. But it still doesn't work. I create a new motion file in main.cpp to initialize each page as new, is that right?

In cmd_process.cpp, I found these code in function PlayCmd():

if (arbotixpro->ReadWord(id, AXDXL::P_GOAL_POSITION_L, &value, 0) == ArbotixPro::SUCCESS)
{
MotionStatus::m_CurrentJoints.SetValue(id, value);
}


It will gets the value from address P_GOAL_POSITION_L=30, but the value of two new servos looks wrong. The value of first 20 servos are same as the value in the final step column. But the value of 21&22 are same as the current value of robot. Is it the reason why the new servos doesn't work? I didn't find the code that write the value into this address.

P.S. The range of two new servos is [0,500] not [0,1024], but I don't think it has any effect in this problem.

r3n33
03-07-2016, 01:13 PM
Do you have your modified code available on github? I'd be willing to take another look and could possibly test on my HR-OS1.

ShirleyWang
03-08-2016, 01:33 AM
Do you have your modified code available on github? I'd be willing to take another look and could possibly test on my HR-OS1.

I've just uploaded the code on github. Here it is. https://github.com/shirleyghost/HROS1-Framework
Thanks! :D

r3n33
03-08-2016, 11:12 AM
Great thank you!

The good news is your code modifications compiled successfully and allowed me to control the two new servos in rme.

These are the steps I took to validate your changes:

1. Configured two additional servos with ID 21 & 22
2. Compiled the framework changes by running 'make' command in .../HROS1-Framework/Linux/build/
3. Compiled and executed dxl_monitor to verify all of the servos were present.
4. Compiled and executed rme to create a new action page

In RME I navigated to an empty page and used the 'new' command to initialize a new page and inserted a few steps, configured the time, set a loop count, etc. Once my action page was setup I entered the 'play' command and all was well.

6483


http://www.youtube.com/watch?v=I8EgughtMo0

So your code looks OK to me and functions well. RME can be a little tricky to work with but Trossen has a helpful video (http://Great thank you! The good news is your code modifications compiled successfully and allowed me to control the two new servos in rme. These are the steps I took to validate your changes: 1. Configured two additional servos with ID 21 & 22 2. Compiled the framework changes by running 'make' command in .../HROS1-Framework/Linux/build/ 3. Compiled and executed dxl_monitor to verify all of the servos were present. 4. Compiled and executed rme to create a new action page In RME I navigated to an empty page and used the 'new' command to initialize a new page and inserted a few steps, configured the time, set a loop count, etc. Once my action page was setup I entered the 'play' command and all was well.
http://www.youtube.com/watch?v=I8EgughtMo0 So your code looks OK to me and functions well. RME can be a little tricky to work with but Trossen has a helpful video (that even I had to use to refresh myself)
http://www.youtube.com/watch?v=lOt36Otpp4Y) (that even I had to use to refresh myself).

ShirleyWang
03-08-2016, 08:14 PM
Great thank you!

The good news is your code modifications compiled successfully and allowed me to control the two new servos in rme.

These are the steps I took to validate your changes:

1. Configured two additional servos with ID 21 & 22
2. Compiled the framework changes by running 'make' command in .../HROS1-Framework/Linux/build/
3. Compiled and executed dxl_monitor to verify all of the servos were present.
4. Compiled and executed rme to create a new action page

So your code looks OK to me and functions well. RME can be a little tricky to work with but Trossen has a helpful video (http://Great thank you!The good news is your code modifications compiled successfully and allowed me to control the two new servos in rme. These are the steps I took to validate your changes:1. Configured two additional servos with ID 21 & 22 2. Compiled the framework changes by running 'make' command in .../HROS1-Framework/Linux/build/ 3. Compiled and executed dxl_monitor to verify all of the servos were present. 4. Compiled and executed rme to create a new action pageIn RME I navigated to an empty page and used the 'new' command to initialize a new page and inserted a few steps, configured the time, set a loop count, etc. Once my action page was setup I entered the 'play' command and all was well.
http://www.youtube.com/watch?v=I8EgughtMo0So your code looks OK to me and functions well. RME can be a little tricky to work with but Trossen has a helpful video (that even I had to use to refresh myself)
http://www.youtube.com/watch?v=lOt36Otpp4Y) (that even I had to use to refresh myself).

Thanks, Renee. I removed the directory and re-copy from github. It works this time. Oh, how stupid I am!


o(︶︿︶)o

r3n33
03-09-2016, 11:22 AM
Great news. I'm really glad it's working.

Who hasn't tried testing modified code from the wrong working directory? :p

ChicShaw
06-07-2016, 11:57 AM
Hello everyone....i would like to say i think you also have to initialize each page as 'new' in rme to get them to respond, otherwise they have the old servo ID tables. The way the binary motion file is handled is poorly documented to say the least.I haven't actually done this in awhile, but you'll see some remnants of my code in the HROS5-Framework. Renee has some of it already and it sounds like you've figured out some.

pcb prototypes (http://www.7pcb.co.uk/pcb-prototyping/)