It's been a hectic 3 weeks with an unexpected trip to Florida for a family emergency and only returning a couple of days ago. Not too much has been happening on the gait generation software. I did get some time yesterday to do some coding and testing where I had the test leg moving from one location to another in a relatively straight line using the IK engine to develop the endpoints for the leg tip. The tip ran fairly straight for about 9 inches and then makes a 1-2 inch swing at the end of movement. I suspect there might be some calibration issues involved, will devise some test to verify.
Later today I want to work some more to refine the software and test out some other ideas. I want the leg to have a smooth stepping motion without any stopping when a leg tip touches down and another leg tip lifts up. It should be a smooth action without any jerking so the tip should start to move in the direction of travel just before it touches down so there is a smooth transition.
I hope to spend some time on the programming during the holidays since we aren't going anywhere this year, would be nice to figure this out before the start of a new year.
It's been a hectic 3 weeks with an unexpected trip to Florida for a family emergency and only returning a couple of days ago. Not too much has been happening on the gait generation software. I did get some time yesterday to do some coding and testing where I had the test leg moving from one location to another in a relatively straight line using the IK engine to develop the endpoints for the leg tip. The tip ran fairly straight for about 9 inches and then makes a 1-2 inch swing at the end of movement. I suspect there might be some calibration issues involved, will devise some test to verify.
Later today I want to work some more to refine the software and test out some other ideas. I want the leg to have a smooth stepping motion without any stopping when a leg tip touches down and another leg tip lifts up. It should be a smooth action without any jerking so the tip should start to move in the direction of travel just before it touches down so there is a smooth transition.
I hope to spend some time on the programming during the holidays since we aren't going anywhere this year, would be nice to figure this out before the start of a new year.
Thanks for the update, Bob. It's been a long haul, but I know you will get there and we are all routing for you.!
To say this is a very neat project is an understatement. I just joined the forum and saw this post and quite enjoyed reading about this what you're constructing, wiring, and programming. The youtube link didn't work for me... url not found. I'm definitely looking forward to seeing more of this project
Welcome to the forums!
Which youtube link could you not connect to? Most have been working lately.
Got some programming work done over the last few days on the gait engine. I've been studying a couple of example code selections for Hexapods and have had some problems figuring out what is going on in the code. I even coded my leg to use a variant of the Phoenix Hexapod code but it doesn't work the way I expected. For example, there is a point in the gait where the leg tip is picked up off the floor, it swings to a position but there is no place that I can see in the code where the leg tip is moved back to the original position. I would like to program a variation of this gait engine since it is very versatile but this has been driving me nuts. Anyone with any insight on the Phoenix code that could explain where the leg tip moves down?
This is the longest break I've had in 4 years in posting on this robot. Family issues have taken priority but things are getting settled so I should have more time to spend on the robot. Even though I wasn't able to work directly on the robot, I was studying code and figured out several items that I was having issues with. This weekend I was able to put some of that work into code and had some pretty good success in getting a leg to move the way I expected. One of the first things I noticed is that the leg moves up and down at the same time the leg starts to move side to side. This could be an issue with the leg tip dragging. I will try a delay to allow the leg to start moving up or down just before the coma starts moving.
Thanks for the update Bob! It has been a while, but we were going through the holidays, that's to be expected.
Good news is you are still plodding on.
I'm not planning on giving up on this one! The software phase has gone much slower than I originally expected. But the individual leg software code is pretty good, shouldn't be too much more in the way of changes for it.
I am seeing some hesitation in the leg movements during a gait movement. This is most likely due to the leg code using a leg done flag so that new incoming position requests are ignored until the current leg movement completes. This was to prevent the leg motors from hunting around the requested position once the PID routine got the leg to the right position. I want to try and remove that flag and put in a timer to trigger the flag. This would allow a series of input commands to come in, (assuming each command is received before the interval expires) the leg software would then continuously respond to each request even if it hadn't completed the previous command. If there is a break in the command requests for the leg, then the leg done flag is set after a short interval. That should remove the hesitation as the motors would not be continually accelerating and decelerating for each individual command. It should also speed up the movement as the PID controller will sense the amount of error (difference between actual and requested position) and request a faster motor speed.
I've been spending some time experimenting with some modified gait code that I borrowed from the Phoenix hexapod project over on the Trossen Robotics website. I gotten it to work to a certain extent but it is geared around using hobby servos and I think I'm running into too many issues that I have been trying to code around. So I'm going to backtrack and go back to a variant of Paul K.'s hexapod code for a propellor. I had coded a variant up a while back that worked fairly well and with my better understanding of the code base that his code was developed from, I think his version can be more easily modified to run my leg setup.
I did work on modifying the leg done command and saw some improvement in leg response to multiple commands coming into the controller. I'm still not totally satisfied but it will do for now.
I've been videoing several of the test programs, I want to put together a compilation of testing that shows the leg movement getting smoother over time but so far I don't have anything smooth to show!
@DiverBob,
I can't even imagine the complexity of programming you have to deal with, especially after seeing this bot on TV motivate just a short distance.
I had some success today with programming the leg movement. The biggest problem I'm running into is having way too many variables to keep track of in my head as I'm programming. I find myself using the wrong variable in the code resulting in some unexpected movements. It is settling down now, working on programming a simple tripod gait with 3 legs down and moving the body as the other 3 legs reset themselves. I'm using a fairly small leg movement of only 12 inches to start with and only running a single leg. This keeps the troubleshooting easier, not as many things to keep track of just yet. Hope to have the leg moving through a complete movement cycle by the end of day tomorrow.
Had some success with the gait engine and am able to get a single leg to cycle through the motions now. Was only getting the leg to move in one direction but finally got the code right to get a full swing of the leg around the coxa pivot point.
I am getting some excessive movement out of the tibia motor where it is not moving smoothly and appears to be 'hunting' around the requested set point. I need to look into that issue now. I did pick up a neat capacitive angular encoder that is good to the 0.01 degrees of motion, I may have to try it out and see if that might help out. I think the amount of tibia movement is very small as compared to the coxa and femur so noise in the precision potentiometer might be giving too many false position readings which then has a larger impact on the small movements needed. Figuring out how to mount the encoder could be a fun trick since I didn't design this into the leg mechanics. I don't want to make a bunch of mechanical changes for something like this, I may put together something simple to check out the encoder concept and see how well it works.
Had some success with the gait engine and am able to get a single leg to cycle through the motions now. Was only getting the leg to move in one direction but finally got the code right to get a full swing of the leg around the coxa pivot point.
I am getting some excessive movement out of the tibia motor where it is not moving smoothly and appears to be 'hunting' around the requested set point. I need to look into that issue now. I did pick up a neat capacitive angular encoder that is good to the 0.01 degrees of motion, I may have to try it out and see if that might help out. I think the amount of tibia movement is very small as compared to the coxa and femur so noise in the precision potentiometer might be giving too many false position readings which then has a larger impact on the small movements needed. Figuring out how to mount the encoder could be a fun trick since I didn't design this into the leg mechanics. I don't want to make a bunch of mechanical changes for something like this, I may put together something simple to check out the encoder concept and see how well it works.
Bob
Bob,
Why don't you look into the Austrian Microsystems encoders like the AS5040 and the AS4055. Duane Deign developed some software for the 4055 and I modified it for the 5040. It would give you very precise positioning for less than 360 degrees. Duane was attempting to use in a servo but the motor noise in close proximity was causing errors. But if you have some physical separation it might be a solution to your tibia movement problem.
Jim
Diverbob: Continued congrats and good luck on your well-documented and long-term project. I pledge to make you a free flamethrower for your bot as son as it takes its first steps.
Thanks for the flame thrower offer! That would be quite the sight to have a big robot following you with a flamethrower, should keep people from getting too close!
The tibia potentiometer is physically located inside the linear actuator so I can't easily change the gearing. I thought that an option would be to remove the top cover where the potentiometer sits and attach the capacitive encoder in its place. I may not be able to close the cover but then it would give me an excuse to get a 3D printer so I could design a new cover....
The encoder I have is a CUI Inc, AMT102-V series. It seems pretty good from the spec sheets. I haven't had time to try and interface it to the propellor yet. I originally got it as a possible replacement for the potentiometer on the coxa (that would have been much easier to replace physically) but my coxa issues appear to be minimal when I went to the PID controller software design. I need to check over in the Propellor forum and see if anyone has written an interface yet.
I've been video'ing my gait engine attempts, I'll compile them into a short video of testing soon. I don't know if I got all the weird and unexpected movements documented but I've seen a lot of wacky moves out of the leg. It's even kicked me a couple of times on some of its more extreme moves. Good thing it's on a test stand and only one leg is moving right now.
Finally got a day off and some time to work with the robot for a while. With the code I had written, small IK changes were not being identified (the leg movement resolution is too large to react to some of the smaller values) and not being added to the movement request (over time the small movements add up to actually start a movement) so the leg movement was being very jerky. Rather than use FP, I multiplied all the values by 100 so I could work with integer math instead, just converting the values back just before they are transmitted back to the leg motors. That helped with some of the jerks that were happening. I also experimented with various delay values since the signal that all the motors have completed their last movement command isn't being very reliable. Any motor that doesn't finish a movement command errors and the all done signal is lost. That will also require some more intense troubleshooting.
Continuing to work on the robot as time permits, work has been taking up more time lately and interfering with my hobby time!
I put together a video of 7 tests I ran to develop the gait engine. I Adobe Premier it looks good but it messed up the video when it uploaded it to YouTube so I had to delete it. I'll try again later.
While testing I realized the leg was not making a full swing around the coxa so I got that fixed. I figured out that some of the jerkiness I'm seeing while the leg moves is due to the motors not syncing well with each other. There is a motor done flag that I transmit to the master computer but I'm getting poorer results when I use it to control the motor starts. I did modify the PID controller to allow faster movements with small angle changes, this speeds things up but still seeing more jerking than I like. I'm sure if I put some weight on the leg then the jerks would get dampened out to a degree. I'm not quite ready to take that step. I want to wire in another leg and see how the gait engine responds but that might be a bit premature right now.
During our refueling outage I get one day off after 4, 12+ hour days so I'm pretty beat most evenings but managed to spend some quality time on my day off with the robot. An issue I've been dealing with (more precisely I've been coding around) is the motor done flag. Each leg motor has a Done flag and the slave transmits a flag back to the master when all motors have completed their movements. The problem is that the individual motor cogs each set their individual flags independently but the main code loop that has the transmit and receive code is typically waiting for the next input signal so the transmitted All Done flag has never been correct.
Since I am using all cogs on the slave, I first looked for a cog that had the least amount of overhead which turned out to be the ADC routine. To this cog I added code to check when all motor done flags were set and only then set a unused output pin on the slave. This pin is direct wired to an pin configured as a input on the master, bypassing the serial interface. On the master computer the selected pin is checked in the main gait loop and used to synchronize the motors by not issuing the next movement command until the previous movement has completed. This turns out better than expected and revealed a some issues with my gait routine that I couldn't see easily when the leg is moving continuously.
One thing I see is that I will need to have more complexity involved with a leg movement to get everything moving smoothly. The leg movement is getting closer but still pretty rough in that the movements are jerky. The motors also complete their movements at different times so I need to experiment with slowing down the speed of some of the faster movements. This should become much easier now that I have a good flag for signaling when all the motors are done moving.
If I do understand you right, your leg moves jerky because the three motors need a different time to reach their desired position.
One way to solve this could be slicing the movement into smaller moves, using your new all done flag.
All movements done is a good thing to have, but I think for smooth movement you might break one movement into more time-slices, using your 'all stop flag' to wait for a 'all partial movements are done so far', and then just move in smaller increments (all values shifted by 2 to make 4 consequent movements)?
I am not sure if you are able to change the speed of your motors. Say letting the femur motor running slower for this movement and faster for another one.
Because the goal seem to be that all motors start at the same time and stop at the same time, making the movement more fluid.
There is some Algorithm for line drawing, called Bresenham(?).
It basically looks for the minimum needed pixel to be drawn for the line and take this as step, calculating x and y values for every dot. The trick is that depending on the angle sometimes the x-difference is the step count, or the y-difference.
Same can work for 3 axis.
Basically the motor needing the smallest amount of steps has to run at a slower pace as the motor needing the biggest step count. Proportional.
It does not really matter if you count in encoder steps or calculate angles. The goal is the same.
Since you are using HB25's I guess you are working with angles of degrees for each motor. So you need to get the difference of position between actual position and wanted position. For each motor of the leg. This differences are the base values to calculate with.
Since Mul add div are quite expensive on the prop I would just shift. To make two consequent movements shift by one (div by 2), to make 4 movements, shift by 2 (div by 4) or to make 8 shift by 3.
Say motor1 is at current position 100 (whatever 100 now may be)
You want to go to 199 (whatever 199 may be)
And motor2 is at current position 50 (whatever 50 now may be)
You want to go to 70 (whatever 70 may be)
currently you send serial 'Motor1 go to position 199'.
and you send serial 'Motor2 go to position 70'.
I skip motor3 because I am lazy.
But slicing this you could do the following int math.
step1 = (199 - 100) >> 2
so (futurePos-currentPos) / 4 is resulting in 24
step2 = (70 - 50) >> 2
so (futurePos-currentPos) / 4 is resulting in 5
send serial 'Motor1 go to position 100+step1'
send serial 'Motor2 go to position 50+step2'
send serial 'Motor1 go to position 100+step1+step1'
send serial 'Motor2 go to position 50+step2+step2'
send serial 'Motor1 go to position 100+step1+step1+step1'
send serial 'Motor2 go to position 50+step2+step2+step2'
send serial 'Motor1 go to position 199'
send serial 'Motor2 go to position 70'
Doing this still ends up precisely at the point 199 and 70. The tree steps before have a small rounding problem (maybe to small), but the last one will fix that.
Basically this works with as much steps you want, but just power of 2, so divide by 2,4,8,16 works, 10 does not.
If the step size is zero the motor does not need to move, because the last step is < step size. So it is OK if that motor moves just on the last step. Or not at all if no movement is needed.
As more steps you use as less jerky your movement will get.
And you do not need to change any software on the leg-controller, just on the master-controller, sending smaller movements and waiting for all done flag.
In the master the IK routine calculates the next position of the leg in angles for each motor. This angle information is then broken down in a repeat loop that repeats 40 times to move each motor 1/40th of the distance. The master sends out a separate movement command 40 times for each motor. My initial test of using the MotorDone flag had the check placed after this loop completed. I'm going to put the check for the flag within the repeat loop and see how that works. In theory each motor would move that 1/40th of its calculated movement and then wait for the other motors to finish their move before the next movement command is transmitted. This should have the effect of getting the motors in sync. I do have the ability to control individual motor speed using commands from the master so that can be used to help 'tune' the system for better response.
What do they say about great minds think alike! I just need some time to see how that works and if it smooths out the motion some. The leg tip is moving more or less in a straight line but it does tend to wander about some as the motors try to catch up with the position commands coming in. I had been using a pause of 25 milliseconds that gave the best result. My last run with the MotorDone flag I removed the pause entirely and got better results.
Today was a much needed day off from work so I headed down to the workshop for some robot work. I made the change to use the MotorDone flag after each increment of the motors. Since I divide a step by 40, the flag is checked quite a bit. In practice the leg was moving much more precisely (as expected) but the movement time was increased by a significant amount. I played around with many of the variables I have for overall motor speed and the speed settings for various levels of error in the PID loop which brought back some of the speed but then also brought back the jerkiness. I need to have a good think on this one, maybe the PID loop needs to be dynamic where it automatically updates the amount of error introduced each time a new command is received instead of waiting to complete the previous command. If the previous command was not completed then the error value would be larger and a higher motor speed is automatically selected. I also exit the PID loop once the error goes low enough, this was to prevent 'hunting' around the requested position since the ADC output values sometimes result in a error value that activates the motors. Hmmmmmm. Back to the drawing board for some more thinking and testing. This part of the project has been much harder than the hardware design and building....
Got some more programming time available now that I'm not on 12+ hour working days!
I made some changes to the resolution variable, instead of being fixed at a value of 40, I take the distance to be moved and divide it up into 0.25 inch intervals. This should make a much more consistent movement interval for any input change.
I also changed the Proportional section of the PID control to change the low end speeds. I figured out that I needed more power at the low power/error levels to overcome friction and get a more reasonable response time. While I was at it, I optimized the loop and simplified the coding. The best solution would be to use assembly language for the PID an dADC routines but that isn't my area of expertise.
I tested the changes in direct manual mode and saw some improvements in the response time. Next tests will be with the master computer again and see how well that works.
Lots of testing of a single attached leg to get the gait engine and inverse kinematics to work. The IK is pretty good, now the process involves tweaking the leg variables to smooth out the motion and keep the leg motors synchronized. I made some changes to the PI loop since the physical leg movement angles were very small, the PI error was always very small resulting in a slow movement. I increased the speed at the lower error rates and found a good medium between movement and minimizing overshoot. I also completely re-wrote the gait engine to account for some of the differences between a servo and DC motors acting like servos. The attached video is a short compilation of some of the tests. I didn't always have the camera available during some of the more 'dramatic' moves.
I am continuing to get the single leg movement smoother and will start adding additional legs to the gait at some point. I got a DC-DC power converter for 12v to 5v @ 5 amps to power the computer systems from the main battery. I still have to work out how to install it since it turned out to be larger than expected.
Thanks for the updates Bob
I've been following you from the beginnings of this project.
It looks like you are getting very close to getting your project working as you intended.
I really like the video of your latest testings.
Thanks
Garyg
Its been a while since I last posted on the Hexapod (still haven't come up with a name...) status thread. Actually there has been very little work done on it this summer, too much work, bicycling, and preparing for retirement to allow enough time in the basement shop. However, with the advent of colder weather I expect to start spending time on the coding once again.
As I left the code the last time, there is a problem with the amount of 'jerkiness' that the leg experiences during movement under IK. When I reduce the size of the movement steps to reduce the jerk, then the slow nature of the Spin code becomes a factor, and the leg moves unacceptably slow. I also believe that the position sensors in the motors are not sensitive enough (too much noise in the potentiometers) for the PID loop and contribute their own delays to the movement.
That leaves me with a couple of choices. One would be to re-write the PID in assembly (since I haven't done assembly for years and never on the prop) which could take quite a bit of time. The other choice would be to continue to see if I can continue to optimize the current spin version of the PID loop to get a better response (lots of testing, pretty much what I was doing until summer started). The bad part of option 2 has been the lack of progress causing a corresponding lack of motivation. Additionally I have been looking at magnetic position encoders that could be attached to the leg and use them as a better feedback mechanism instead of the internal potentiometers. That would require some re-design work on the legs to mount them and then coding them in.
I hope to get back to regularly posting progress reports again however up until my summer break there had not been a whole lot of progress which was sapping my motivation. Any suggestions from anyone would be appreciated if you can think of what could be done to get this rolling again.
Thanks for any help that comes this way! I may be a bit slow in responding to questions since I started night shift last week and will be on it through most of December (lots of work at the plant going on this time).
Did some testing of the 3 axis and monitored the movement data. Still seeing a lot of 'noise'' in the output from the position potentiometers. This causes confusion in the PID loop and is leading to motor overshoot and increased reaction time. So I've decided to add encoders to each axis to help fix this issue. The limitations I have are that I only have a single cog unassigned on each leg controller and I will have to figure out how to install the encoder. The preferable method would be to remove the old pot inside the motor housing and replace it there but the available area is pretty small. Another option is to use a angular encoder and just measure the actual angles that the leg is at instead of motor rotations. That allows more space for an encoder but it isn't as clean for mounting as the other option. Plus, the mechanical design will have to be tweaked to get the angles right.
So tonight I will be doing some studying, I remember seeing some capacitive angular encoders a while back that measured down to either a tenth or hundredth of a degree. The options for mounting will be a factor also. Any recommendations, has anyone tried these out yet with a Prop?
Comments
Later today I want to work some more to refine the software and test out some other ideas. I want the leg to have a smooth stepping motion without any stopping when a leg tip touches down and another leg tip lifts up. It should be a smooth action without any jerking so the tip should start to move in the direction of travel just before it touches down so there is a smooth transition.
I hope to spend some time on the programming during the holidays since we aren't going anywhere this year, would be nice to figure this out before the start of a new year.
Thanks for the update, Bob. It's been a long haul, but I know you will get there and we are all routing for you.!
Which youtube link could you not connect to? Most have been working lately.
Bob
Good news is you are still plodding on.
I am seeing some hesitation in the leg movements during a gait movement. This is most likely due to the leg code using a leg done flag so that new incoming position requests are ignored until the current leg movement completes. This was to prevent the leg motors from hunting around the requested position once the PID routine got the leg to the right position. I want to try and remove that flag and put in a timer to trigger the flag. This would allow a series of input commands to come in, (assuming each command is received before the interval expires) the leg software would then continuously respond to each request even if it hadn't completed the previous command. If there is a break in the command requests for the leg, then the leg done flag is set after a short interval. That should remove the hesitation as the motors would not be continually accelerating and decelerating for each individual command. It should also speed up the movement as the PID controller will sense the amount of error (difference between actual and requested position) and request a faster motor speed.
I did work on modifying the leg done command and saw some improvement in leg response to multiple commands coming into the controller. I'm still not totally satisfied but it will do for now.
I've been videoing several of the test programs, I want to put together a compilation of testing that shows the leg movement getting smoother over time but so far I don't have anything smooth to show!
Bob
I can't even imagine the complexity of programming you have to deal with, especially after seeing this bot on TV motivate just a short distance.
I am getting some excessive movement out of the tibia motor where it is not moving smoothly and appears to be 'hunting' around the requested set point. I need to look into that issue now. I did pick up a neat capacitive angular encoder that is good to the 0.01 degrees of motion, I may have to try it out and see if that might help out. I think the amount of tibia movement is very small as compared to the coxa and femur so noise in the precision potentiometer might be giving too many false position readings which then has a larger impact on the small movements needed. Figuring out how to mount the encoder could be a fun trick since I didn't design this into the leg mechanics. I don't want to make a bunch of mechanical changes for something like this, I may put together something simple to check out the encoder concept and see how well it works.
Bob
Less physical range but more precise readings?
just a thought.
Mike
Why don't you look into the Austrian Microsystems encoders like the AS5040 and the AS4055. Duane Deign developed some software for the 4055 and I modified it for the 5040. It would give you very precise positioning for less than 360 degrees. Duane was attempting to use in a servo but the motor noise in close proximity was causing errors. But if you have some physical separation it might be a solution to your tibia movement problem.
Jim
Every bot needs a "TV moment"!
http://forums.parallax.com/discussion/139372/playing-with-fire
The tibia potentiometer is physically located inside the linear actuator so I can't easily change the gearing. I thought that an option would be to remove the top cover where the potentiometer sits and attach the capacitive encoder in its place. I may not be able to close the cover but then it would give me an excuse to get a 3D printer so I could design a new cover....
The encoder I have is a CUI Inc, AMT102-V series. It seems pretty good from the spec sheets. I haven't had time to try and interface it to the propellor yet. I originally got it as a possible replacement for the potentiometer on the coxa (that would have been much easier to replace physically) but my coxa issues appear to be minimal when I went to the PID controller software design. I need to check over in the Propellor forum and see if anyone has written an interface yet.
I've been video'ing my gait engine attempts, I'll compile them into a short video of testing soon. I don't know if I got all the weird and unexpected movements documented but I've seen a lot of wacky moves out of the leg. It's even kicked me a couple of times on some of its more extreme moves. Good thing it's on a test stand and only one leg is moving right now.
Continuing to work on the robot as time permits, work has been taking up more time lately and interfering with my hobby time!
While testing I realized the leg was not making a full swing around the coxa so I got that fixed. I figured out that some of the jerkiness I'm seeing while the leg moves is due to the motors not syncing well with each other. There is a motor done flag that I transmit to the master computer but I'm getting poorer results when I use it to control the motor starts. I did modify the PID controller to allow faster movements with small angle changes, this speeds things up but still seeing more jerking than I like. I'm sure if I put some weight on the leg then the jerks would get dampened out to a degree. I'm not quite ready to take that step. I want to wire in another leg and see how the gait engine responds but that might be a bit premature right now.
Since I am using all cogs on the slave, I first looked for a cog that had the least amount of overhead which turned out to be the ADC routine. To this cog I added code to check when all motor done flags were set and only then set a unused output pin on the slave. This pin is direct wired to an pin configured as a input on the master, bypassing the serial interface. On the master computer the selected pin is checked in the main gait loop and used to synchronize the motors by not issuing the next movement command until the previous movement has completed. This turns out better than expected and revealed a some issues with my gait routine that I couldn't see easily when the leg is moving continuously.
One thing I see is that I will need to have more complexity involved with a leg movement to get everything moving smoothly. The leg movement is getting closer but still pretty rough in that the movements are jerky. The motors also complete their movements at different times so I need to experiment with slowing down the speed of some of the faster movements. This should become much easier now that I have a good flag for signaling when all the motors are done moving.
Bob
One way to solve this could be slicing the movement into smaller moves, using your new all done flag.
All movements done is a good thing to have, but I think for smooth movement you might break one movement into more time-slices, using your 'all stop flag' to wait for a 'all partial movements are done so far', and then just move in smaller increments (all values shifted by 2 to make 4 consequent movements)?
I am not sure if you are able to change the speed of your motors. Say letting the femur motor running slower for this movement and faster for another one.
Because the goal seem to be that all motors start at the same time and stop at the same time, making the movement more fluid.
There is some Algorithm for line drawing, called Bresenham(?).
It basically looks for the minimum needed pixel to be drawn for the line and take this as step, calculating x and y values for every dot. The trick is that depending on the angle sometimes the x-difference is the step count, or the y-difference.
Same can work for 3 axis.
Basically the motor needing the smallest amount of steps has to run at a slower pace as the motor needing the biggest step count. Proportional.
It does not really matter if you count in encoder steps or calculate angles. The goal is the same.
Since you are using HB25's I guess you are working with angles of degrees for each motor. So you need to get the difference of position between actual position and wanted position. For each motor of the leg. This differences are the base values to calculate with.
Since Mul add div are quite expensive on the prop I would just shift. To make two consequent movements shift by one (div by 2), to make 4 movements, shift by 2 (div by 4) or to make 8 shift by 3.
Say motor1 is at current position 100 (whatever 100 now may be)
You want to go to 199 (whatever 199 may be)
And motor2 is at current position 50 (whatever 50 now may be)
You want to go to 70 (whatever 70 may be)
currently you send serial 'Motor1 go to position 199'.
and you send serial 'Motor2 go to position 70'.
I skip motor3 because I am lazy.
But slicing this you could do the following int math.
step1 = (199 - 100) >> 2
so (futurePos-currentPos) / 4 is resulting in 24
step2 = (70 - 50) >> 2
so (futurePos-currentPos) / 4 is resulting in 5
send serial 'Motor1 go to position 100+step1'
send serial 'Motor2 go to position 50+step2'
send serial 'Motor1 go to position 100+step1+step1'
send serial 'Motor2 go to position 50+step2+step2'
send serial 'Motor1 go to position 100+step1+step1+step1'
send serial 'Motor2 go to position 50+step2+step2+step2'
send serial 'Motor1 go to position 199'
send serial 'Motor2 go to position 70'
Doing this still ends up precisely at the point 199 and 70. The tree steps before have a small rounding problem (maybe to small), but the last one will fix that.
Basically this works with as much steps you want, but just power of 2, so divide by 2,4,8,16 works, 10 does not.
If the step size is zero the motor does not need to move, because the last step is < step size. So it is OK if that motor moves just on the last step. Or not at all if no movement is needed.
As more steps you use as less jerky your movement will get.
And you do not need to change any software on the leg-controller, just on the master-controller, sending smaller movements and waiting for all done flag.
Go Bob GO!
you have a wonderful project there.
Mike
In the master the IK routine calculates the next position of the leg in angles for each motor. This angle information is then broken down in a repeat loop that repeats 40 times to move each motor 1/40th of the distance. The master sends out a separate movement command 40 times for each motor. My initial test of using the MotorDone flag had the check placed after this loop completed. I'm going to put the check for the flag within the repeat loop and see how that works. In theory each motor would move that 1/40th of its calculated movement and then wait for the other motors to finish their move before the next movement command is transmitted. This should have the effect of getting the motors in sync. I do have the ability to control individual motor speed using commands from the master so that can be used to help 'tune' the system for better response.
What do they say about great minds think alike! I just need some time to see how that works and if it smooths out the motion some. The leg tip is moving more or less in a straight line but it does tend to wander about some as the motors try to catch up with the position commands coming in. I had been using a pause of 25 milliseconds that gave the best result. My last run with the MotorDone flag I removed the pause entirely and got better results.
Now to get some time to experiment some more.
Bob
Bob
I made some changes to the resolution variable, instead of being fixed at a value of 40, I take the distance to be moved and divide it up into 0.25 inch intervals. This should make a much more consistent movement interval for any input change.
I also changed the Proportional section of the PID control to change the low end speeds. I figured out that I needed more power at the low power/error levels to overcome friction and get a more reasonable response time. While I was at it, I optimized the loop and simplified the coding. The best solution would be to use assembly language for the PID an dADC routines but that isn't my area of expertise.
I tested the changes in direct manual mode and saw some improvements in the response time. Next tests will be with the master computer again and see how well that works.
I am continuing to get the single leg movement smoother and will start adding additional legs to the gait at some point. I got a DC-DC power converter for 12v to 5v @ 5 amps to power the computer systems from the main battery. I still have to work out how to install it since it turned out to be larger than expected.
I've been following you from the beginnings of this project.
It looks like you are getting very close to getting your project working as you intended.
I really like the video of your latest testings.
Thanks
Garyg
As I left the code the last time, there is a problem with the amount of 'jerkiness' that the leg experiences during movement under IK. When I reduce the size of the movement steps to reduce the jerk, then the slow nature of the Spin code becomes a factor, and the leg moves unacceptably slow. I also believe that the position sensors in the motors are not sensitive enough (too much noise in the potentiometers) for the PID loop and contribute their own delays to the movement.
That leaves me with a couple of choices. One would be to re-write the PID in assembly (since I haven't done assembly for years and never on the prop) which could take quite a bit of time. The other choice would be to continue to see if I can continue to optimize the current spin version of the PID loop to get a better response (lots of testing, pretty much what I was doing until summer started). The bad part of option 2 has been the lack of progress causing a corresponding lack of motivation. Additionally I have been looking at magnetic position encoders that could be attached to the leg and use them as a better feedback mechanism instead of the internal potentiometers. That would require some re-design work on the legs to mount them and then coding them in.
I hope to get back to regularly posting progress reports again however up until my summer break there had not been a whole lot of progress which was sapping my motivation. Any suggestions from anyone would be appreciated if you can think of what could be done to get this rolling again.
Thanks for any help that comes this way! I may be a bit slow in responding to questions since I started night shift last week and will be on it through most of December (lots of work at the plant going on this time).
Bob Sweeney
So tonight I will be doing some studying, I remember seeing some capacitive angular encoders a while back that measured down to either a tenth or hundredth of a degree. The options for mounting will be a factor also. Any recommendations, has anyone tried these out yet with a Prop?