Best way to simulate a gyro sensor?

Post Reply
amatic
Posts: 13
Joined: Sun Oct 25, 2015 10:17 am

Best way to simulate a gyro sensor?

Post by amatic »

Hi, I was wondering what would be the best way to simulate a gyroscope in Bullet. I would need it to be reusable, so I suppose they should have their own physics object, is that correct?

Also, If getAngularVelocity gives rotation velocity around world axes, how do I get angular velocity of the body that the gyro is attached to?
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Best way to simulate a gyro sensor?

Post by drleviathan »

Balanced gyroscopes are used to track the orientation of moving things (submarines and airplanes), or to stabilize things (fancy cameras). Unbalanced gyroscopes suffer precession in a non-inertial reference frame and are used to as novelty toy and physics demonstration.

Tracking rotations and stabilizing them is easy to do in Bullet without the extra work of setting up a gyroscope, so I assume you want a precessing one. Bullet may be able to reproduce the precession of a spinning object. I vaguely recall a thread in these forums a while ago where someone claimed that it worked.

You would probably want to use a btPoint2PointConstraint. I believe constraints can go unstable in Bullet if the mass ratio between the connected objects is far from unity, however maybe not for just two objects that don't touch or collide with each other, you'll have to try and see.

Angular velocity is just a Vector3. You can use Quaternions to rotate a Vector3 into different coordinate systems. Something like this (although this is much more wordy than your implementation needs to be):

Code: Select all

btVector3 spinRateInWorldFrame = gyroBody->getAngularVelocity();
btQuaternion rotationFromBodyToWorld = gyroBody->getOrientation();
btQuaternion rotationFromWorldToBody = rotationFromWorldToBody.inverse();
btVector3 spinRateInGyroFrame =  rotationFromWorldToBody * spinRateInWorldFrame;
amatic
Posts: 13
Joined: Sun Oct 25, 2015 10:17 am

Re: Best way to simulate a gyro sensor?

Post by amatic »

Thank you for the response. I'm quite a noob in this, so I'm not sure if those formulas apply for simulating something like this http://www.robotshop.com/en/sensors-gyroscopes.html ?

I'm trying to make a balancing robot simulation. My first approach was to make a cart with 4 wheels, an inverted pendulum, and a single hinge between the pendulum rod and the cart. Then I use the hinge angle as input to the controller. That works.

Now I'd like to make something like a seqway, on two wheels. There are two wheel hinges, and they aren't useful for balancing. Instead, I need a gyroscope simulation, perhaps even add some noise and a settable sampling period.
btVector3 spinRateInWorldFrame = gyroBody->getAngularVelocity();
btQuaternion rotationFromBodyToWorld = gyroBody->getOrientation();
btQuaternion rotationFromWorldToBody = rotationFromWorldToBody.inverse();
btVector3 spinRateInGyroFrame = rotationFromWorldToBody * spinRateInWorldFrame;
I've copied these to my code, and I can't figure out how to multiply the quaternion rotationFromWorldToBody and vector3 spinRateinWorldFrame.
"Error: no suitable user-defined conversion between btQuaternion and btVector3 exists."
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Best way to simulate a gyro sensor?

Post by drleviathan »

Sounds like you don't need a real "physical gyroscope" but you need logic that can measure relative rotations. The good news is that this is much easier to do in Bullet than it is in the real world. Bullet has an API that can provide the world-frame rotation of a btRigidBody at any time. Objects that we build in the real-world don't have this capability... unless we put a gyroscope in them. So just use btRigidBody::getOrientation() to "read your gyro".

To actually use the orientation to make the object do what you want will require you to learn a lot about how to do rotation math.

Huh, you're right, there is no multiplication operator between btQuaternion and btVector3 that produces a rotated vector. I think I knew that but had forgotten. Nevertheless it blows my mind each time. This is a terrible omission from the Bullet math library. Perhaps someone in these forums can enlighten us as to why it was left out.
Basroil
Posts: 463
Joined: Fri Nov 30, 2012 4:50 am

Re: Best way to simulate a gyro sensor?

Post by Basroil »

Here's the biggest question:

What type of gyro sensor are you talking about? If you are trying to simulate a MEMS "gyro" sensor, you're going about it all wrong. Just read the angular velocity of your main body and add sensor uncertainty in your control method. MEMS type gyroscopes don't actually use spinning disks, so you can't simulate them as such.
amatic
Posts: 13
Joined: Sun Oct 25, 2015 10:17 am

Re: Best way to simulate a gyro sensor?

Post by amatic »

Basroil, sorry if this is a very noob question, but how do I get angular velocity of a simulated body, in the same way a gyro gets the angular velocity of the body it is attached to? If I'm not mistaken, the getAngularVelocity() returns the rotation rate around 'global axes', while I would need something like rotation around 'local axes'.
amatic
Posts: 13
Joined: Sun Oct 25, 2015 10:17 am

Re: Best way to simulate a gyro sensor?

Post by amatic »

OK, this seems to work:

Code: Select all

  btTransform trans;
  body->getMotionState()->getWorldTransform(trans);
  trans.setOrigin(btVector3(0, 0, 0)); 
  btVector3 anglVel = trans.inverse() * body->getAngularVelocity();
d3x0r
Posts: 51
Joined: Tue Dec 11, 2012 9:59 pm

Re: Best way to simulate a gyro sensor?

Post by d3x0r »

drleviathan wrote:
Huh, you're right, there is no multiplication operator between btQuaternion and btVector3 that produces a rotated vector. I think I knew that but had forgotten. Nevertheless it blows my mind each time. This is a terrible omission from the Bullet math library. Perhaps someone in these forums can enlighten us as to why it was left out.
quatRotate in btQuaternion.h
SIMD_FORCE_INLINE btVector3
quatRotate(const btQuaternion& rotation, const btVector3& v)

the operator cann't be overloaded based on return type so it has to be a different name?
Post Reply