Hi, I’m a newbie to Unity and can’t figure out how to tell if my phone is accelerating or decelerating on the z axis using Input.gyro.userAcceleration for an object I only want to move forward when the phone does. I don’t really need to know how far or anything–just if the phone is moving frontward or backward. What I mean is for example if I walk backwards quickly, at first input.gyro.userAccerlation.z shows acceleration in the negative direction compared to the direction I’m facing but as I slow I start getting opposite z values and I need a way to figure out that those positive values aren’t REALLY due to new forward movement so I can know the direction is still backwards (just slowing down). What happens is my script ignores the background motion at first (like it should) but then starts interpreting it as forward motion and moves my object and I can’t figure out a way to tell the difference. Does that make sense? Thanks! -D
deceleration is just acceleration in the opposite direction of the velocity.
Thanks! … but I don’t have a velocity because I haven’t moved anything yet. lol. How do I get it in a situation like mine–where I only want to move something if the gyro says it moved forward vs it moving backwards? Sorry I’m so dense. I’m learning though.
If you don’t have a velocity, that means you’re not moving. Any motion is an acceleration.
How do you decelerate from no movement?
This isn’t deceleration.
This is direction.
The acceleration vector is that… a vector. It has magnitude and direction. Imagine a vector as an arrow in 3-space from 0,0,0 to the <x,y,z> of the vector. The length of it is the magnitude, and the orientation is the direction.
If you want to know if it’s moving “forward”… well, you need to first declare what IS forward and what IS backward? Which directions are those?
Now once you have the vectors defined for forward and backward (backward usually just being -forward). You can know if an acceleration is in the direction of forward by getting the dot product of the acceleration on forward. If it’s positive, it’s in that direction… if it’s negative it’s against that direction.
Lets just define forward as ‘Vector3.forward’ (which is <0,0,1>). You might do this as:
if(Vector3.Dot(Input.gyro.userAcceleration, Vector3.forward) > 0f))
{
//we're accelerating in the direction of Vector3.forward, do something
}
Note… Vector3.forward may not necessarily be your definition of forward. You’ll need to figure this out for yourself.
Also note… just because you’re accelerating forward doesn’t mean you can’t ALSO be accelerating left and right as well. If you want to do something about that… well you need to also define your conditions for that too.
Wow, thanks! But I think my problem isn’t so much detecting if it’s forward or backward. It’s more when the forward is really forward (I think).
If I do “print (Vector3.Dot(Input.gyro.userAcceleration, Vector3.forward) )” and jump back with the phone, I see a bunch of big negative numbers followed by a bunch of almost as big positive numbers that scale back down quickly. So what happens is my script ignores the negatives (like it should) but then sees the positives and thinks “Hey I’m moving forward” but I’m not! It’s kind of a bounce effect I guess tho I’m careful to keep the phone from ever bouncing forward. It’s like while it slows down it sees the slowing as getting a forward acceleration. Maybe somethings wrong with my phone lol.
I think what he is asking is how to skip over the input generated by “braking” the phone.
I.E when you move the phone up and stop the phone will register “up,up,up,down” due to the gyro being pushed back from the stop.
Sorry I can’t help, never did anything on mobile
You might need to keep an average velocity, that way you would be able to know if it was decelerating from moving backwards or if it was starting to move forward.
I think what he is asking is how to skip over the input generated by “braking” the phone.
YES! Braking–that’s a good word for it!
You might need to keep an average velocity, that way you would be able to know if it was decelerating from moving backwards or if it was starting to move forward.
Hmmm… maybe that’s the trick–to do it as an average. Just not sure how to decide what range to average to be sure I’m not missing true forward motion.
I did try comparing it to the last frame’s acceleration–like, if this update shows positive direction–but the last one showed a negative (above a certain range) direction – then consider it a “brake” and don’t move. But that got me nowhere. My head hurts–it seemed like it should be so easy just to know if the phone is going forward or backward!
I have become a slave of the low pass filter (if that’s even it’s name) it might be usefull for you here.
//With 1> a >0, and while a decreases the value persist more over time (new data is less relevant)
averageAccel= (1-a) * averageAccel+ a * acceleration;
You will get an average (not real average) of the accel on the last changes.
So if Dir(averageAccel) != Dir(acceleration) => is breaking;
Tweak the a value as you see fit.
Thanks again! I don’t think that averaging gets clear enough data, or else I’m doing something stupid. Probably the second one.
Here’s a basic idea of what I did, but no matter how I toy with the accelConstant or tinker with “FudgeFactor” does it work. It either misses a bunch of correct forward motions, or accepts a bunch of brakes as forward motions incorrectly.
float dot = Vector3.Dot(z_forward, z_acceleration);
mag= Input.gyro.userAcceleration.magnitude;
averageAccel= (1-accelConstant) * averageAccel+ accelConstant * Input.gyro.userAcceleration.z;
if ((mag> required_mag) && (dot > 0) && (Input.gyro.userAcceleration.z < averageAccel * Fudgefactor))
// Move forward! {
Shoot. After searching the web endlessly (lots of similar questions but no answers) and trying lots of stuff, I’ve come to the conclusion that it’s pretty much an impossible task. There’s just no way to dependably figure out the difference between braking and sudden forward acceleration on a phone using just the accelerometor and gyro. Kinda crazy but true. :(