Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
9 years ago.
*Programming problem* how to stop and hold the position of the dynamixel motor ?
Hello all,
I am controlling the dynamixel motor, RX-64 using joystick from the application board.
I am using lpc1768 module
I programmed it in such a way.
for example, when joystick is pushed up, it will go to a 180 degrees vice versa for joystick being pushed down will go to 0 degrees.
However, I would like it to stop and hold at its position at any point of time where I stop pushing the joystick up or down.
i.e when RX-64 is on the way rotating from 0 to 180, I stop pushing joystick at 100 degrees and I hope that the motor shaft hold at 100 degrees.
This are my codes.
Thank you
Eugene
1 Answer
9 years ago.
use mx28.GetPosition() to read the current location and then set that as the goal position. The system should then try to hold the current location.
For future reference, if you use <<code>> before and <</code>>
after your code (put each on it's own line) you can copy and past the code in and it formats correctly. It's a little easier than posting an image of it.
Do I need to add in a for loop and use the iteration number, i as angle for the position? I have an error in this line:
for (i=0;i<=800;i++); mx28.SetMovingSpeed(servo1, 100, false); mx28.GetPresentPosition(servo1,i); mx28.SetGoalPosition(servo1,i);
Error: Argument of type "int" is incompatible with parameter of type "std::uint16_t *" in "MX28/main.cpp", Line: 24, Col: 52
By using GetPresentPosition, will the motor only run when I push up the joystick and stop running once I stop pushing the joystick?
Thank you
posted by 20 Apr 2015The syntax for getPosition isn't the same as setGoalPosition. It returns a float of the current position. At least it does in the libraries I found, they don't seem to quite match the syntax you are using but since you didn't say which library you are using I had to guess.
You only want to set the goal position once, when the button is first released. Something along these lines,
bool moving = false; while(1) { if (up) { moving = true; ... } else if (down) { moving = true; ... } else if (moving) { // we were moving but button was released moving = false; mx28.SetGoalPosition(servo1,mx28.getPresentPosition(servo1)); // set the goal to the current location } }
#include "mbed.h" #include "MX28.h" #define MX28_DEBUG MX28 mx28 (p9, p10, 57142); DigitalIn up(p15); DigitalIn down(p12); bool moving = false; int main() { uint8_t servo1 = 0x01; while (1) { if (up == 1) { mx28.SetMovingSpeed(servo1, 100, true); moving = true; } else if (down == 1) { mx28.SetMovingSpeed(servo1, 100, true); moving = true; } else { mx28.SetMovingSpeed(servo2, 100, false); mx28.SetGoalPosition(servo1, mx28.GetPresentPosition(servo1)); } } }
These are my codes to run dynamixel RX-64. I am using MX28.h library.
I understand what are you trying to teach me about the getpresentposition but may I ask what '&presentPosition' should I set as complier prompts me this error.
Error: Too few arguments in function call in "MX28/main.cpp", Line: 39, Col: 80
Also, if I do not use mx28.SetGoalPosition for the if(up==1) and else if(down==1) statement, how can I make it rotate in the opposite direction for (down==1) ?
Sorry to trouble you. I have only learnt mbed few days ago :(
Thank you for your time! Eugene
posted by 20 Apr 2015Which MX28.h library? The search here is not great and many libraries have multiple versions. Can you post a link to the page please.
posted by 20 Apr 2015http://developer.mbed.org/users/GIPetrou/code/MX28/
I uses this version of mx28.h library.
posted by 20 Apr 2015OK I think this should be the correct syntax.
#include "mbed.h" #include "MX28.h" #define MX28_DEBUG MX28 mx28 (p9, p10, 57142); DigitalIn up(p15); DigitalIn down(p12); int main() { bool moving = false; uint8_t servo1 = 0x01; while (1) { if (up == 1) { mx28.SetMovingSpeed(servo1, 100, true); mx28.SetGoalPosition(servo1,800); moving = true; } else if (down == 1) { mx28.SetMovingSpeed(servo1, 100, true); mx28.SetGoalPosition(servo1,100); moving = true; } else if (moving) { uint16_t currentPos; mx28.GetPresentPosition(servo1,¤tPos); // read the position moving = false; mx28.SetMovingSpeed(servo1, 100, false); mx28.SetGoalPosition(servo1, currentPos); // set the current position as the goal } } }
Note the else if (moving) on the code for stationary. This means that that code is only run when the button is first released, after that no new commands are sent to the motor until either up or down are pressed. We've set the goal for the motor, I would hope it would try to hold that location until we tell it otherwise.
Since all the moving speeds are the same you could probably set that before the start of the while loop rather than before every command but it should't hurt anything doing it this way.
As for you're other questions earlier, the bits within the up/down code should be the same as before with the addition of setting moving to true, I skipped those lines since they were unchanged and I couldn't copy/paste them.
One other lazy trick in c, anything other than 0 is considered true. Since a digital input will either be 0 or 1. which means that
if (up) { do something }
will have exactly the same effect as
if (up == 1) { do something }
This is a personal coding style issue, I find the shorter version cleaner in this situation.
posted by 20 Apr 2015