Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
0
Question by vprofeta · Feb 24, 2016 at 01:20 PM · rotationphysics

Cart-pole system: how to apply the correct physics

Hi there!

I have worked on a simple 2D game. It consists on the cart-pole balance task, Roughly, one has to keep a pole that is attached to a cart pointing up during an arbitrary period of time. To beat gravity that pulls the pole down, it is necessary to impose the right amount of force upon the pole by moving the cart. This kind of task has been considered a benchmark in algorithm learning and its physics is described in this paper (http://coneural.org/florian/papers/05_cart_pole.pdf).

To do that I am using mouse inputs.

First approach I locked the cart displacement in one dimension and used Input.mousePosition.x to control it. To create the cart-pole system I added "hinge joint" to the cart (both the cart and the pole have rigidbody). Since only movement in x-axis was allowed, the pole could rotate only around the z-axis. The problem with this approach is that the pole seems to be insensitive to FORCES generated by the cart. That is , gravity starts its job it is almost impossible to correct pole trajectory. The pole is dragged by the cart, but there is almost no influence of the cart on the pole ROTATION.

Second approach Considering that it did not work out as I expected, I used AddTorque() taking cart acceleration as argument. Something on these lines:

 rb.AddTorque(new Vector3(0, 0, 1) * cartAcceleration, ForceMode.Acceleration);

However, it did not work either.

Third approach

After toying around with many variations of the two first approaches, I decided to code all the physics by myself using the equations (23) and (24) of the paper mentioned above. However, after the pole displaces more than (roughly) 10 degrees from the vertical line it starts to spin out all over the places. The angle seems to increase (or decrease) continuously and suddenly it jumps to more than one cycle sometimes. In addition, it loses its constraint to be "attached" to the cart and translates as well.

Here is one of the versions of the code that I have tried. It refers to the a script attached to the Pole that reads the values of interest from another script attached to the Cart.

 using UnityEngine;
 using System.Collections.Generic;
 
 public class Pole : MonoBehaviour 
 {
       // in order: cart speed, cart acceleration, pole angular velocity, pole angular acceleration
        List<float> states = new List<float>(){0, 0, 0, 0}; 
     List<float> newStates = new List<float>();
     float massCart;
     float massPole;
     float poleLength;
     float theta;
     float theta_dot;
     float theta_ddot;
     float positionX;
     float positionY;
     float cartX;
     float cartY;
     GameObject cart;
     float cartX_dot;
     float cartX_ddot;
     float sign;
 
     void Start () 
     {
         cart = GameObject.Find("Cart");
         massPole = GetComponent<Rigidbody>().mass;
         poleLength = GetComponent<Transform>().transform.localScale.y;
         theta = GetComponent<Transform>().transform.localEulerAngles.z;
         massCart = cart.GetComponent<Rigidbody>().mass;
     }
 
     void FixedUpdate () 
     {
         cartX = cart.GetComponent<Transform>().transform.position.x;
         cartY = cart.GetComponent<Transform>().transform.position.y;
         sign = Mathf.Sign(states[1]);
         newStates = CalcDerivs(states, massCart, massPole, poleLength, theta, sign);
         theta = theta + newStates[2] * Time.deltaTime;
         states[2] = states[2] + newStates[3] * Time.deltaTime; // angular vel
         states[3] = newStates[3];    // angular accel
         positionX = cartX + Mathf.Sin(theta) * poleLength;
         positionY = cartY + Mathf.Cos(theta) * poleLength;
         transform.position = new Vector3(positionX, positionY, 0);
         states[0] = GameObject.Find("Cart").GetComponent<CartMotion>().velocityN;
         states[1] = GameObject.Find("Cart").GetComponent<CartMotion>().cartAcceleration;
         transform.localEulerAngles =new Vector3(0, 0, Mathf.Rad2Deg * theta);
 
     }
 
     static List<float> CalcDerivs(List<float> states, float massCart, 
         float massPole, float poleLength, float theta, float sign)
     {
         float gravity = 9.81f;
         float force = states[1] * (massCart + massPole);
         float force = states[1] * (massCart + massPole) -
             (massPole * poleLength *
                 (Mathf.Pow(states[2], 2) * Mathf.Sin(theta) - states[3] * Mathf.Cos(theta)));
         float numerator = gravity * Mathf.Sin(theta) + Mathf.Cos(theta) *
             ((-sign * force - massPole * poleLength * Mathf.Pow(states[2], 2) * Mathf.Sin(theta)) /
                 (massPole + massCart));
         float denominator = poleLength *
             ((4 / 3) -
                 (massPole * Mathf.Pow(Mathf.Cos(theta), 2) /
                     (massPole + massCart)));
 
         float theta_ddot = numerator / denominator;
         List<float> newStates = new List<float>() { states[0], states[1], states[2], theta_ddot, force };
 
         return newStates;
     }
 }

A side note: there are some variable that I do not use in this part of the code, e.g. states[0]. I have checked by printing results of many different variables that "cartAcceleration" and "force" do not change erratically as theta (the angle of the pole does). The reason why I prefer something like the third approach is the fact that I can make explicit relations with other objects with specific physics like that.

I appreciate any help.

Comment
Add comment
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

1 Reply

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

Answer by vprofeta · Mar 05, 2016 at 01:02 AM

After some days without touching this part of the code, I realized that I actually need only one equation (the first one), since F = cartMass * cartAccel. Thus, I entered cartAccel directly in the first equation and multiplied it by the values of mass of the cart. Finally, I filtered the mouse input to get a smooth acceleration and improve control over the pole.

Comment
Add comment · 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

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Car tutorial physics models rotating randomly? 1 Answer

Update speed and physics makes my rigidbody jiggle 2 Answers

Compute the torque needed to rotate an object at a constant rate 3 Answers

move player to its rotating direction? 2 Answers

Returning a rigidbody back to its original x and z rotations through physics forces. 2 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