Author Topic: Slope floor  (Read 5445 times)

Sarawuth

  • Newbie
  • *
  • Posts: 4
    • View Profile
Slope floor
« on: April 01, 2014, 02:30:47 AM »
Is it possible to make balanduino run  and get balance when  move from normal floor to slope floor/platform?

Ahmed

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Slope floor
« Reply #1 on: April 01, 2014, 12:13:24 PM »
AFAIK no, the PID controller in the balanduino requires the user to set the balancing angle. I think that this can be done however using another form of full state feedback control and an observer model to estimate slope.

Ahmed

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Slope floor
« Reply #2 on: April 02, 2014, 06:33:08 PM »
Now that I think about it, if another PID controller is set to control the balancing angle with the wheel velocity as its control input, it would be possible to have the balanduino automatically balance at an angle that would minimize the wheel velocity error, which would be the balancing angle.

tkj

  • Administrator
  • Newbie
  • *****
  • Posts: 4
    • View Profile
Re: Slope floor
« Reply #3 on: April 03, 2014, 07:36:14 PM »
Actually it should be possible, but the PID parameters would need to be tweaked.
Currently the Balanduino has one PID loop for keeping the balance, but together with this loop there is actually also another controller that keeps track of the encoder.
An unexpected change in encoder value will also influence the motor speed, so if the gain of this controller is increased, this should increase the stability on sloped floors.
Best regards
Thomas Jespersen
www.balanduino.com

Ahmed

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Slope floor
« Reply #4 on: April 04, 2014, 12:23:35 AM »
I've studied the balanduino code for position error correction (Back to spot feature), it is almost like a fuzzy controller but with hard limits (multiple zones without overlap). If this controller is replaced with a PID controller with separate tunable gains, with the wheel velocity error as input, a setpoint of zero (unless it is required to move the robot forward or backward) and the output as the angle offset (constrained to +/-45 degrees) that would be added to the default balancing angle of 180, it should work.
« Last Edit: April 04, 2014, 12:25:59 AM by Ahmed »

Lauszus

  • Administrator
  • Full Member
  • *****
  • Posts: 131
    • View Profile
Re: Slope floor
« Reply #5 on: April 06, 2014, 04:20:07 PM »
This is on the top of the list of things I need to implement!

Quote
I've studied the balanduino code for position error correction (Back to spot feature), it is almost like a fuzzy controller but with hard limits (multiple zones without overlap). If this controller is replaced with a PID controller with separate tunable gains, with the wheel velocity error as input, a setpoint of zero (unless it is required to move the robot forward or backward) and the output as the angle offset (constrained to +/-45 degrees) that would be added to the default balancing angle of 180, it should work

I have tried exactly that previously, but it did not work as intended. You can see it in the PID branch: https://github.com/TKJElectronics/Balanduino/tree/pid.

Ahmed

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Slope floor
« Reply #6 on: April 06, 2014, 05:14:00 PM »
I have tried exactly that previously, but it did not work as intended. You can see it in the PID branch: https://github.com/TKJElectronics/Balanduino/tree/pid.

I've been working on it too, and apparently we both reached more-or-less the same point. I got mine to balance and change the target angle but it is still drifting off after a few seconds.

In your implementation you have the input as wheelPosition, output as the +/- offset of the restAngle and the setpoint as the targetPosition.

Code: [Select]
PID encoders_pid(&wheelPosition, &restAngle, &targetPosition, 0, 0, 0, DIRECT);
Code: [Select]
encoders_pid.Compute();
    restAngle += cfg.targetAngle;

In my approach I'm using the input as the error in wheelPosition, output as the +/- offset of the restAngle and the setpoint as zero (basically the same thing).

Code: [Select]
Setpoint=0;

int32_t wheelPosition = getWheelsPosition();
int32_t positionError = wheelPosition - targetPosition;
Input= positionError;
PID AnglePID(&Input, &Output, &Setpoint,1,0.1,0, DIRECT);

Code: [Select]
AnglePID.Compute();
cfg.targetAngle = constrain(cfg.targetAngle + (Output/100),145,215)

What made a big improvement during my implementation is constraining the restAngle to +/- 35 degrees as you can see above.
« Last Edit: April 06, 2014, 05:23:43 PM by Ahmed »

Lauszus

  • Administrator
  • Full Member
  • *****
  • Posts: 131
    • View Profile
Re: Slope floor
« Reply #7 on: April 06, 2014, 11:34:31 PM »
Yeah both codes will produce the same behaviour.
I am struggling with finding any good PID values, as it starts to drift in one direction after a few seconds as you also have experienced.

Quote
Code: [Select]
AnglePID.Compute();
cfg.targetAngle = constrain(cfg.targetAngle + (Output/100),145,215)

What made a big improvement during my implementation is constraining the restAngle to +/- 35 degrees as you can see above.

I have just limited the output like so:
Code: [Select]
encoders_pid.SetOutputLimits(-10, 10); // Set output limits

Note also that you can download another version of the Android app, that will allow you to set the PID values for the encoders too: https://github.com/TKJElectronics/BalanduinoAndroidApp/tree/pid.
If you can figure out how to compile the code, then just let me know and I will send you the APK.

You could also easily modify the Processing application to set the encoder PID values.

Lauszus

  • Administrator
  • Full Member
  • *****
  • Posts: 131
    • View Profile
Re: Slope floor
« Reply #8 on: April 07, 2014, 12:04:53 AM »
I just tried it again and it is now able to stand upright, but it oscillates back and forth.

Btw I divided the PID values by 1000, as they should be pretty low.

Ahmed

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Slope floor
« Reply #9 on: April 07, 2014, 01:36:54 AM »
I already have mine balancing too, I started out by dividing it by 100 as you can see from my code
Code: [Select]
cfg.targetAngle = constrain(cfg.targetAngle + (Output/100),145,215)
I tried dividing by 1000 as you did but the response was too slow because I was limiting my PID output to

Code: [Select]
  AnglePID.SetOutputLimits(-5,5);
The problem right now with mine is it exhibits oscillatory behavior and then after some time the oscillation amplitude magnifies and it drifts off.

Also note that limiting the output of the PID controller with SetOutputLimits doesn't limit the final targetAngle because the output of the PID controller is added to the restAngle as an offset. That's why I constrained my final targetAngle to 145 and 215 degrees.

Have you tried using the wheelVelocity as the input to the PID controller and zero as the Setpoint? I'm testing this right now and it's giving me good results. (The balanduino wheel velocity should decrease as the target angle becomes closer to the balancing angle)
« Last Edit: April 07, 2014, 01:52:26 AM by Ahmed »

Ahmed

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Slope floor
« Reply #10 on: April 07, 2014, 01:41:59 AM »
Also, are we sure that the PID controller output should be DIRECT or should be REVERSE? I've tried it with both and for some reason REVERSE is also working with almost exactly the same results.

EDIT: No, after some testing I've confirmed it's DIRECT. I now have it balancing well, still with oscillation but after it finds the balancing angle it keeps balanced. The issues i'm having is it is slow to determine the balancing angle when a change occurs (plane is tilted or eccentric mass is added) so it will keep oscillating for a while to determine the new balancing angle. This I guess can be solved by better tuning the PID controller.

BTW; So far I'm having better luck with a PD controller instead of a PID controller, but could be a false positive, I'm still checking it out. (Kp=15, Kd=5)
« Last Edit: April 07, 2014, 02:59:45 AM by Ahmed »

Lauszus

  • Administrator
  • Full Member
  • *****
  • Posts: 131
    • View Profile
Re: Slope floor
« Reply #11 on: April 07, 2014, 04:21:04 PM »
Quote
Also note that limiting the output of the PID controller with SetOutputLimits doesn't limit the final targetAngle because the output of the PID controller is added to the restAngle as an offset. That's why I constrained my final targetAngle to 145 and 215 degrees.
No that is not correct. Please have an extra look at my code. Note that I do not modify the targetAngle, as it is intended to be adjusted if the weight is not perfectly in the center. For instance I used this when I mounted a GoPro on the back:


So targetAngle is a constant and I simply limit the restAngle to +-10 degrees. Finally I add the targetAngle (normally 180 degrees) . The result is that I have a restAngle from 170 to 190 degrees.

Quote
Have you tried using the wheelVelocity as the input to the PID controller and zero as the Setpoint? I'm testing this right now and it's giving me good results. (The balanduino wheel velocity should decrease as the target angle becomes closer to the balancing angle)
I have also tried this previously without much success, but two minds is always better than one ;)

Quote
BTW; So far I'm having better luck with a PD controller instead of a PID controller, but could be a false positive, I'm still checking it out. (Kp=15, Kd=5)
Have you forked the Balanduino code on Github? I would love to try it out. Also are these values divided by 100 in your code?

Lauszus

  • Administrator
  • Full Member
  • *****
  • Posts: 131
    • View Profile
Re: Slope floor
« Reply #12 on: April 07, 2014, 04:29:13 PM »
I also just tried to use the wheel velocity as the input instead, but I don't seem to get the same performance as you do. Please share your code, so I can see how it is implemented in your code.

Ahmed

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Slope floor
« Reply #13 on: April 08, 2014, 12:02:42 AM »
No I haven't forked it on Github but Here's the progress I've made so far. It can balance without any eccentric mass added, and if you gradually change the center of gravity by adding eccentric mass to the body it will eventually find the new balancing angle. But it takes too long and keeps oscillating around for a while till it finds it. (Can't do sudden changes)

Sorry if my code is a bit sloppy :-)
« Last Edit: April 08, 2014, 12:46:11 AM by Ahmed »

Ahmed

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Slope floor
« Reply #14 on: April 13, 2014, 03:51:03 AM »
Hey Lauszus,

I've modified my code quite a bit, and now I have it finally working. It is balancing well with acceptable performance using a PD controller that only activates outside a certain zone of position error, note that the gains still need a little bit of tuning and the zone that the controller gets activated in might also need more consideration. Please check attached code and tell me what you think.



I'm using gains for the main balanduino PID controller of Kp=7.5, Ki=2 & Kd=3.

Finally, there is quite a major issue that I think we didn't consider, while we can get the robot to balance on inclines, if you reorient (spin) the robot so that it's facing the other way (180 degrees) while it's on the incline, the controller can't adjust fast enough to reverse the tilt angle all the way around. A possible solution is to read the orientation reading from the IMU (Z axis) and "invert" the PWM values going to the motors?
« Last Edit: April 13, 2014, 03:54:41 AM by Ahmed »