# Arduino Forum

## Topics => Robotics => Topic started by: krille105 on Feb 01, 2018, 10:20 pm

Title: Balancing robot - Tuning
Post by: krille105 on Feb 01, 2018, 10:20 pm
We are doing a balancing robot in a school project which we are almost done with. The last part is to tune the robots's pid and to implement a steering control through an ESP8266 WiFi. The trouble we have is that the robot start oscillating back and forward along the targetAngle. The targetAngle is calculated through a PI based on the speed of the motors which is received from an encoder, but the robot still overdue the targetAngle and then starts to go back and forward until it reach full speed an falls. How do we solve the problem, by tuning the PID and PI or by implementing something else? (See video and part of the code below, in the next post posted by me)

(Edit) Code removed and moved to my next post.
Title: Re: Balancing robot - Tuning
Post by: jremington on Feb 01, 2018, 11:56 pm
The code fragment you posted is completely useless. Edit your post to include the entire code, posted using code tags.
Title: Re: Balancing robot - Tuning
Post by: Srijal97 on Feb 02, 2018, 08:26 pm
There is this project a friend of mine did: Balance Bot (https://github.com/heethesh/Balance-Bot). See if it helps in some way.
Title: Re: Balancing robot - Tuning
Post by: krille105 on Feb 14, 2018, 04:49 pm
The following code is the velocity PID that calculates the TargetAngle based on the targetVel which is 0. This makes it possible for the robot to balance even though the centre of gravity isn't in the middle. This should also prevent the robot from oscillate back and forth.
Code: [Select]
`double targetVel = 0;double velError;double integralVel;double lastVelError;double piSum;double kiVel = 0.0005;double kpVel = 0.009;void velocityPi() {    velError = targetVel-wheelVel;    integralVel = integralVel + velError*kiVel;    lastVelError = velError;    TargetAngle = velError * kpVel + integralVel;//TargetAngle is the output of the velocity PID, and is sent to the balancing pid.  }`

And this is the PID for balancing

Code: [Select]
`void loopPid(){  CurrentAngle = ypr[2] * 180/M_PI;  error = TargetAngle - CurrentAngle;  integral = integral + error*ki;  derivative = (error - lastError)*kd;  lastError = error;  pidsum = error*kp+derivative+integral;    if(pidsum>0)    {      digitalWrite(rightEngine1, LOW);      digitalWrite(rightEngine2, HIGH);        digitalWrite(leftEngine1, LOW);      digitalWrite(leftEngine2, HIGH);    }    else if (pidsum<0)    {      digitalWrite(rightEngine1, HIGH);      digitalWrite(rightEngine2, LOW);        digitalWrite(leftEngine1, HIGH);      digitalWrite(leftEngine2, LOW);      }     analogWrite(rightEnginePwm, 30+(abs(pidsum) * 5)*1);  analogWrite(leftEnginePwm, 30+(abs(pidsum) * 5)*1);}`

The problem is still left that it starts oscillate back and forth as on the video in the first post. Does anyone know how to prevent it from going back and forth?
Title: Re: Balancing robot - Tuning
Post by: jremington on Feb 16, 2018, 12:53 am
Unintentional oscillation is due to improper tuning or inadequate electromechanical design.  Kp may be much too high, or the motor/motor power behavior is too nonlinear for PID to compensate.

What are the magic numbers 5, 30 and 1 doing in the motor analogWrite() call? Where do you check for excessive values for PWM?
Title: Re: Balancing robot - Tuning
Post by: Srijal97 on Feb 16, 2018, 08:27 am
Create a GUI using the Tkinter library in Python with sliders for the PID gains. Send these gain values dynamically to your robot, and tune the values in run time. This would make the tuning process a ton easier and you would get better results.
Title: Re: Balancing robot - Tuning
Post by: krille105 on Feb 16, 2018, 06:58 pm
Unintentional oscillation is due to improper tuning or inadequate electromechanical design.  Kp may be much too high, or the motor/motor power behavior is too nonlinear for PID to compensate.

What are the magic numbers 5, 30 and 1 doing in the motor analogWrite() call? Where do you check for excessive values for PWM?
Yes, we removed + 30 PWM.
What do you mean with excessive values for PWM? If it is over 255, it will only send 255 anyway.

It works pretty well without the second PI (PID without derivative), but  the targetAngle needs to be exact in order for it to stand still. While using the second PI-loop for velocity (targetVelocity = zero) it doesn't correct itself fast enough, but if we raise the PI values it will start oscillating as of the targetAngle changes to much. How do we fix so it will try reach zero speed faster, without starting to oscillate because of the overreaction in targetAngle while it tries to correct itself. Should we use derivative aswell in the second PI loop?
Title: Re: Balancing robot - Tuning
Post by: jremington on Feb 17, 2018, 12:53 am
Remove the "5" as well, and go through the tuning process again.

For PID to work properly, almost all of the values sent to analogWrite() must be in the range of 0-255, with resolution (increments) of 1, if possible.

The "5" makes the latter impossible.
Title: Re: Balancing robot - Tuning
Post by: krille105 on Feb 17, 2018, 04:27 pm
This is how it looks right now after we removed the static PWM and adjusted some values. It does still start to oscillate.

Balancing robot project video (https://www.youtube.com/watch?v=HVaaONGRw2k&feature=youtu.be) (Sorry for the small screen, uploaded it from my mobile)
Title: Re: Balancing robot - Tuning
Post by: jremington on Feb 17, 2018, 05:07 pm
Obviously, it is not tuned correctly, or you have one or more serious program errors (wrong sign of derivative, etc.).