Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
11
Question by SeveQ · Dec 20, 2011 at 11:27 PM · physicssimulation

PID controller simulation?

Hi there,

for my robot simulation I need a simulated PID controller. In several states of the simulation the robot AI tries to rotate the robot to a specific variable angle. Since the robot body is a rigid body it behaves like the real robot with inertia and stuff. So on a constant force at two points near the playingfield (contact points of the wheels) the robot begins to rotate with increasing speed at a constant rate (integrating behaviour). The PID controller should be able to stop the rotation once the desired angle has been reached by reversing the forces. While a simple P controller would result in a permanent frequency in which the robot rotates from the left to the right and back, a PID controller should be able to reduce the forces to a value that lets the robot reach the desired angle.

Well, to cut a long story short... is it applicable to use a discrete PID simulation algorithm within Unity? Or is Unity, as I assume, by far too slow to achieve a reasonable calculation speed for a good simulation?

What other ways are there to achieve a rotation to a desired angle with the premise that it has to use a rigid body and forces (i.e. the physics engine), instead of manipulating the transform directly?

Thanks a lot!

Hendrik

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jean-Fabre · Mar 13, 2014 at 12:23 PM 0
Share

Just to cross reference things: PID system available here as well: http://forum.unity3d.com/threads/68390-PID-controller

1 Reply

· Add your reply
  • Sort: 
avatar image
16
Best Answer

Answer by aldonaletto · Dec 22, 2011 at 01:13 AM

You can use a true PID controller in Unity for position, but not for rotation. The problem is the feedback signal: Unity stores the rotation as a quaternion, which cannot be translated to the 3-axes notation reliably (not a quaternion's fault: 3-axes notation is redundant, thus many different representations may be returned for the same quaternion).

But the show can go on! The quaternion->angle conversion is unreliable, but you can bet your life on the conversion angle->quaternion! The solution is to keep the current angle in a variable, calculate the proportional and differential errors (integral error only mess things up in this case), add them to generate the desired "torque" (angular acceleration, to be more precise), apply it to the angle, convert the angle to a quaternion and assign it to the object's rotation. It's simulated, but is physically correct, and works very well. The simulated PD controller (set to rotate around the Y axis) is:

 var targetAngle: float = 0; // the desired angle
 var curAngle: float; // current angle
 var accel: float; // applied accel
 var angSpeed: float = 0; // current ang speed
 var maxAccel: float = 180; // max accel in degrees/second2
 var maxASpeed: float = 90; // max angular speed in degrees/second
 var pGain: float = 20; // the proportional gain
 var dGain: float = 10; // differential gain
 private var lastError: float; 
 
 function Start(){
   targetAngle = transform.eulerAngles.y; // get the current angle just for start
   curAngle = targetAngle;
 }
 
 function FixedUpdate(){
   var error = targetAngle - curAngle; // generate the error signal
   var diff = (error - lastError)/ Time.deltaTime; // calculate differential error
   lastError = error;
   // calculate the acceleration:
   accel = error * pGain + diff * dGain;
   // limit it to the max acceleration
   accel = Mathf.Clamp(accel, -maxAccel, maxAccel);
   // apply accel to angular speed:
   angSpeed += accel * Time.deltaTime; 
   // limit max angular speed
   angSpeed = Mathf.Clamp(angSpeed, -maxASpeed, maxASpeed);
   curAngle += angSpeed * Time.deltaTime; // apply the rotation to the angle...
   // and make the object follow the angle (must be modulo 360)
   rigidbody.rotation = Quaternion.Euler(0, curAngle%360, 0); 
 }

You can set positive or negative angles, and the object will rotate to the desired angle - including angles > 360 or < -360.

BONUS SCRIPT: Since you're interested in PID controllers, that's a simple PID position controller entirely based on physics, that tries to reach the position set in targetPos. It works fine, but the parameters must be fine tuned to reach a stable operation:

 var targetPos = Vector3.zero; // the desired position
 var maxForce: float = 100; // the max force available
 var pGain: float = 20; // the proportional gain
 var iGain: float = 0.5; // the integral gain
 var dGain: float = 0.5; // differential gain
 private var integrator = Vector3.zero; // error accumulator
 private var lastError = Vector2.zero; 
 var curPos = Vector3.zero; // actual Pos
 var force = Vector3.zero; // current force
 
 function Start(){
   targetPos = transform.position;
 }
 
 function FixedUpdate(){
   curPos = transform.position;
   var error = targetPos - curPos; // generate the error signal
   integrator += error * Time.deltaTime; // integrate error
   var diff = (error - lastError)/ Time.deltaTime; // differentiate error
   lastError = error;
   // calculate the force summing the 3 errors with respective gains:
   force = error * pGain + integrator * iGain + diff * dGain;
   // clamp the force to the max value available
   force = Vector3.ClampMagnitude(force, maxForce);
   // apply the force to accelerate the rigidbody:
   rigidbody.AddForce(force);
 }



Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SeveQ · Dec 22, 2011 at 08:10 PM 0
Share

Alright. This works. It has been the integrating part of the PID that messed up the robot's behaviour, thanks a lot!

'cos I need to replace some parts of the simulation with "adapters" to the real world, later, I've adapted your solution to my needs regarding the exclusive use of forces.

Yes, you've read that right: later on I would like to use the AI part of the simulation to operate a real robot. So it's rather some sort of an emulation of the real robot's hardware which of course is subject to physical laws.

What I actually haven't understood is the part with the unreliable quaternion-to-angle conversation. I only use the vertical axis of the robot. The other two axes are fixed. On the other hand the vertical axis of the robot is locked against translational movement. So the body can only translate horizontally (x and z) and rotate around its vertical axis (y). As a result I assume I can rely on the eulerAngle.y value of the rigidbody's rotation to calculate the controller's error, can't I?

Well, it looks like I can. :)

avatar image aldonaletto · Dec 22, 2011 at 08:38 PM 0
Share

You're right: fixing the other axis in 0 rotation and locking them in physics makes the eulerAngles.y reliable. The problem is that the angle returned always range from 0 to 360: if the angle is reducing, when reaching zero it suddenly becomes 360 (and vice versa), producing a completely wrong error signal that makes the robot spins forever when an angle near to 0 or 360 is specified. This would not happen with a real robot, because the encoder doesn't have this modulo 360 problem.

avatar image SeveQ · Dec 22, 2011 at 09:13 PM 0
Share

Yeah, alright. I just need to figure out how to deal with this 360 overflow. It doesn't exist in the real world but it can evolve into a problem when then robot has rotated, lets say, for an accumulated angle of 720 degrees and the AI needs to return it to 90 degrees for example. But that's a different story and I'm going to find out by myself (I hope I will).

Well, your answer was a great help, thanks again!

avatar image MonsterSmurf · Mar 03, 2012 at 03:30 PM 1
Share

Hi,

Thanks for the solution, worked like a charm!

I had a very similar issue with the 360 overflow as well and I solved it by changing this line of code:

float error = targetPos - curPos;

to this:

float error = $$anonymous$$athf.DeltaAngle(curPos, targetPos);

I put the small change here just in case someone needs it :)

avatar image aldonaletto · Mar 03, 2012 at 05:08 PM 0
Share

Good solution! I'll check this latter.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

10 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Simulating the graphics of a rolling 3D ball in a 2D game 2 Answers

What would be the best approach to implement a conveyor belt? 0 Answers

Help with orbits 1 Answer

cloth simualtion problem 0 Answers

simulating real world camera in unity 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges