![]() |
Keeping two motors in sync
Excuse any ignorance I may have since I am reaching out on behalf of our programing team. We have two lead screws that we are trying to keep in sync with each other. We are using these encoders which are mechanically attached to the screws. http://www.andymark.com/product-p/am-2899.htm
Does anyoen have any ideas or input as to how they would incorporate a PID loop that would take the encoder values and slow the faster screw down so that both are in sync? I know it may seem simple to some btu our team is strugling to find an exampl as to how to implement this type of design. ANy info or direction is appreciated. Thanks. http://cdn3.volusion.com/vyfsn.knvgw...jpg?1421043935 |
Re: Keeping two motors in sync
how close are the screws to each other? The easiest way to do this is to tie them mechanically together with a chain and a pair of sprockets.
|
Re: Keeping two motors in sync
What is the driver interface to the lead screws? Is the driver commanding speed or position? speed: driver pulls joystick back and expects the leadscrews to turn faster in proportion to how far he pulls back position: driver pulls joystick back and expects the leadscrews to "follow" the joystick angle (height proportional to joystick angle). |
Re: Keeping two motors in sync
What ether said. The key question is if your pid loop is controlling position or speed.
If you're controlling speed then it's nearly hopeless, since any speed errors will build up over time into large position errors. If you're controlling position, then it's relatively easy. I'm assuming you have basic familiarity with position PID loops, though. With that caveat, you have two options: 1. Pick one of the screws as a master. This is the only screw you directly command a position for. Set up the other screw as a slave by passing the master's feedback position as the position setpoint/command for the slave. pro: slightly easier to set up, guarantees the slave will be at the same position as the master, even if the master hangs up. Con: slave will always trail the master, since the best it can do is zero error to the master position, and there's bound to be some error. Best for really tightly controlled servos. 2. Two separate pid loops, one for each screw. Command for both pid loops is a single position value that you slowly ramp from one position to the next. Instant changes won't work, because each screw will try to get there as fast as possible, which means at different speeds. Slowly ramping the commanded position means each screw follows the ramped position second by second, which means the screws go up evenly since they're both trying to hit the same target. pros: even movement aside from whatever error is in your pid. Con's: somewhat more complicated, you need to ramp the position somewhat slower than the top speed of the slower motor. Ramping the position too fast means the motors can't keep up and it basically turns back into the instant setpoint change scenario |
Re: Keeping two motors in sync
Thank you all. We are doing this by position not speed. Are there any examples of code that you may know of that are similar to this setup? If not no big deal, thought this was common enough that there may be.
|
Re: Keeping two motors in sync
Quote:
If you are committed to doing this electronically, Ether posted an architecture in another thread that could work. First you need to "Home" your carriage to a known stop each time you boot and zero your two encoders while you know the carriage is level. Then you make one motor a "partial" slave to the other. In a PID like loop, you drive the master to the desired position P as sensed by encoder E1. You simultaneously drive the second motor to the same position P as sensed by encoder E2 but in addition add the error between the master and slave (E2-E1). This way both motors start moving at the same time, but you also drive the error in final position towards zero. If you update your motor drive voltages fast enough, you may be able to match velocities as well. |
Re: Keeping two motors in sync
Yes we thought our programing team was capable of this so we did not tie them with a timing belt. We have it 100% built and at this time adding the mechanical tie is not realistic since this is the last day. We do have the limit switches for the home position the problem is our programing team bit off more than they could chew so now we are tryign to help them. That wahy I was looking for sample code of PID loops in C++
|
Re: Keeping two motors in sync
|
Re: Keeping two motors in sync
We started out with 2 motors and 2 encoders on a lift with 2 PID loops and could not keep the 2 in sync close enough to prevent binding. We linked them with a criss-cross chain and 2 sprockets and then tied them together in software under the control of 1 PID controller and 1 encoder.
Here was the code we used to tie them together. We like to implement limit switches and inverting of motors if needed as close to the hardware as possible. This ensures the motors are never fighting each other. Code:
/*Code:
/* |
Re: Keeping two motors in sync
Quote:
OBTW, by "criss-cross chain", you don't mean a figure 8, do you? It's an idea I had about two years ago when thinking about linkage drives, and that we tried to implement as a novelty in our "infinite possibilities" sign over the pit last year. Operationally, it sounds like a recipe for short chain life. |
Re: Keeping two motors in sync
Important question. Are the two lead screws pushing the same carriage, or are they pushing separate carriages?
On our bot, we have two screws and two independent carriages. Each carriage lifts one side of the crate. So we only have to stay mostly level, since we won't have any binding issues or anything. I modified the PID controller class so it ramps setpoints, and we're running two PID loops that ramp the setpoint position at the same rate. If the screws start level, the setpoint positions will stay level since they're moving at the same rate. The screws aren't guaranteed to stay level due to following error, but they manage fairly well. The biggest problem is that (currently) the moving setpoint is the only synchronization between the sides. If the left side jams or hits max command and starts falling behind the setpoint, the right side doesn't know or care and will continue merrily on its way. Practically speaking, this limits our max speed, since we have to make sure we never have to hit max command for either motor, even under varying battery conditions and loading. That's obviously not ideal, but I'm still working out the most robust way to tackle that problem. Anyways, I have code for this approach if you're interested. Another approach is what Ether talks about in this thread. There, you're semi-slaving one motor to another, and just commanding pure setpoint positions. I think that will work as well, and will take care of things if the master motor jams or maxes out, but it still doesn't handle things if the slave motor jams or maxes out. You're basically assuming that the master motor/screw is the weaker/easier to jam of the two. I don't have code for that, so you'd have to work out your own modifications to the PIDController class. |
Re: Keeping two motors in sync
We have the same setup as you two lead screws with two seperate carriages each with their own motors and encoders. So binding is only an issue with the tote. We would like to keep it within 2 inches. We can tolerate more but within 2 is acceptable.
If you dont mind giving us an example we would greatly appreciate it. I could email you or PM you. Our programers understand the concept of PID but were not sure what values to put where. After some reading its becoming more clear, but we have never done it so not sure what we dont know. Our main problem is that with no load at full speed one side is slightly faster. We want the PID to slow the faster since the slower woudl already be at 100%. So based on this I assume we woudl make our slower lift the "master" and slave the faster side to track the slower? I understand what your saying about the master side continuing even if the other side got stoped for some reason. I would assume you could code it so that if a max seperation value was exceeded you could stop the higher side. Thanks for your response. This will be our project over the next few weeks. |
Re: Keeping two motors in sync
I don't have code for a master-slave system yet. I do have C++ code for a PIDController derivative that will let you smoothly ramp the setpoint from A to B at a given rate. As long as you have the PID loops tuned well and you keep the rate below the max speed for your slower side, things should work and stay level.
I should've asked earlier, but what language are you guys using? If it's C++, I can cleanup and better document my code tonight and post it tomorrow. If it's Java, I'll have to port things, which will take a day or two, and won't be tested, obviously. If it's Labview.... I'll have to think about how to approach the problem in Labview. |
Re: Keeping two motors in sync
I threw this together quickly. Can you guys critique it? Maybe someone can debug it on real hardware, or in a simulation. Code:
double change, PosCmd, error1, e1pos, error1i, |
Re: Keeping two motors in sync
I am wondering about the slave part:
Quote:
|
Re: Keeping two motors in sync
Quote:
Quote:
|
Re: Keeping two motors in sync
Quote:
If P*error < i2bLimit, then the I term will halt the slave, quickly or slowly depending on I and possibly reverse it and drag it back down to e1pos. Things would obviously settle down somewhere near where P*error = i2bLimit, or at e1pos, once the I term stopped oscillating around e1pos. If P*error > i2bLimit, then e2is going to go past e1pos and stabilize wherever P*error finds drops down below i2bLimit. Ether, I think your pseudo code implements your proposed controller correctly, I'm just not entirely certain the actual dynamics would work as intended. I think it'd take a good deal of tweaking to get your slave's I value tuned well enough that it's going to fight that RLPC trying to drag it upwards with ever increasing error. Here's something that just popped into my head. What if you limit the RLPC sort of how you limit the integral error? Since we're not doing proper servoing with fatal following errors or anything, we can just choose to slow down (or stop) the ramp if a motor gets in a bind. Super Pseudo code: 1. Calculate RLPC as above, probably saving the change value / actual increment. 2. Calculate output commands for both motors as 2 standard independent PIDs following the RLPC. 3. If both motor outputs are less than abs(1.0) then you're done and you set values and wait for the next loop. 4. If a motor value is >= abs(1.0), then you back calculate the necessary incremental change to hit 1.0 output on the limited motor. Go back to step 1, but with your new (temporary) rate limit (which may be 0). Make sure you only loop back at most twice. Any more would be pointless since you've already tried to reduce things for both motors. It's a good bit trickier with the back calculating and all, but I think it accomplishes our actual goal. If I'm thinking about it correctly, then what should happen is if either side gets stuck, the RLPC just stops moving. The free side will servo up to the RLPC, obviously, but the RLPC should only be a small-ish distance ahead. Whatever error it takes to get the stuck side to hit 1.0 output. (Possibly we ignore the I and D terms when figuring this.) I think initial moves from standstill and reversals would be interesting, since limiting the rate to only what's currently achievable by the motor would act as a defacto soft-ish start. With an RLPC controller (which is the modified PID I've already implemented) the starts can be a little bumpy, since you can pretty quickly hit maximum output cause your setpoint has infinite acceleration and the motors don't. The setpoint can get far ahead of the normal steady state error, so the motors can over shoot once they break free and start moving. Mind you, it'll run a little strange what with the speeding up and slowing down, but I think if your PIDs are already pretty stable, it shouldn't add any weird oscillations from the two systems interacting with each other through mechanical delay. Worst case is the RLPC just stops moving completely because the two sides are oscillating around it out of phase and at max command values. You'd have to throw up your hands and curse me for peddling hare-brained poorly thought out control algorithms, but your system would probably survive. |
Re: Keeping two motors in sync
Quote:
|
Re: Keeping two motors in sync
Quote:
The best way to settle the matter I guess is to run it on hardware or a simulation. |
Re: Keeping two motors in sync
This is fundamentally no different than getting a differential drive robot to drive straight. You want both sides of the mechanism to end up in the same place at the same time.
In drivetrains people often use a controller that is something like: Code:
output_steering = PID(steering_error)distance_error is usually computed as: Code:
distance_error = desired_distance - (left_distance + right_distance) / 2This has worked well on hundreds of FIRST robots for driving, and generalizes as a simple way for coordinating two separate mechanisms. You just need to be careful with how you handle saturation/integral windup and you're golden. |
Re: Keeping two motors in sync
Quote:
For an elevator the synchronization is important because of binding. For drivetrains it's important because the final location of the robot depends on the sides staying in sync during the journey.. Quote:
Quote:
Quote:
|
Re: Keeping two motors in sync
Quote:
|
Re: Keeping two motors in sync
Quote:
In the generalized motor synchronization case, using (left_distance - right_distance) would be fine. Using a trajectory generator to make nice smooth, non-saturated position setpoint profiles is a great way to help solve the saturation/windup problem. |
Re: Keeping two motors in sync
Quote:
|
Re: Keeping two motors in sync
1 Attachment(s)
So here's a stripped down version of our robot code with just the lift stuff and the rate controlled PID that I worked up.
There's some features I added to the PID class that may not be relevant to your system. I added a Kv term for velocity feedforward based on whatever your ramp rate is. There's also limit switches integrated in there so the PID stops if a limit is hit in the direction you're moving. It both prohibits motor command in that direction, and updates the target setpoint to whatever the current position is when you run into a limit. If you're not using limits, just leave those blank or set to NULL and that logic will be skipped. To accommodate different wiring practices, the bool limitHit parameter sets what value indicates that a limit has been hit/tripped. There's a few others as well, so ask if there's any confusion |
Re: Keeping two motors in sync
Quote:
Edit: moved attachments here. |
Re: Keeping two motors in sync
This is amazing. I am learned so much. Kevin, Ether, and Jared. You have helped more than you know. I wish I had more to say but I am busy reading whay you wrote and this site which has helped me wrap myhead around the variables and acronyms you have been using. Thanks.
|
| All times are GMT -5. The time now is 13:12. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi