Given the following data
Orientation of the device (CMAttitude - Quaternion or Rotation Matrix)
Acceleration Vector (CMAcceleration - userAcceleration --> without gravity)
Is there a way to get the acceleration and deceleration of a car placing the device in an arbitrary orientation into the car?
If not what would be the best approach to get the acceleration and deceleration by positioning the device in a fixed position inside the car?
Any hints or solution approached would be highly appreciated.
Thanks in advance!
Edit:
I tried to implement the suggested approach from this answer Using CMDeviceMotion and CMAttitude to isolate vertical or horizontal acceleration to isolate the vertical and horizontal acceleration.
I set the reference frame to CMAttitudeReferenceFrameXMagneticNorthZVertical
//Quaternion Conjugation
CMQuaternion quaternion = newMotion.attitude.quaternion;
GLKQuaternion conjugated_quaternion = GLKQuaternionMake(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
conjugated_quaternion = GLKQuaternionConjugate(conjugated_quaternion);
//Rotation of Accelerometer vector with quanternion
GLKVector3 acceleromationVector = GLKVector3Make(newMotion.userAcceleration.x, newMotion.userAcceleration.y, newMotion.userAcceleration.z);
GLKVector3 accelerometionVector_toReferenceFrame = GLKQuaternionRotateVector3(conjugated_quaternion, acceleromationVector);
//Horizontal Acceleration
float horizontalAcceleration = sqrtf(powf(accelerometionVector_toReferenceFrame.x,2)+powf(accelerometionVector_toReferenceFrame.y,2));
In the suggested answer the reference frame which should be used is North-East-Down. Would this be the same than CMAttitudeReferenceFrameXMagneticNorthZVertical? Or could it be that this is the wron reference frame and thus the results of this implementation turn out to be wrong?
You're looking for an algorithm not a functionality in the device itself. I don't believe there is a feature in any apple's iDevice that allows you to get the current ** deceleration/acceleration**
Use The Kinematic Equations: a = (Vf - Vi) / t
a: Acceleration
Vf: final velocity
Vi: initial velocity
t: time difference between Vi and Vf
This is what I would do to get the de/acceleration:
Calculate Vf = d/t say the car moves for a 10 km (this is d distance in meters) in 10 seconds (this is t time in seconds) you should be able get the final velocity Vf.
Assume Vi = 0 at first calculation then keep track of it by assigning current-Vi = previous-Vf
Calculate de/acceleration a = (Vf - Vi) / t
Remember deceleration is just a negative acceleration
Edit: You can also use userAcceleration defined in CMDeviceMotion.h
Related
My code for physics in my game is this:
-- dt = time after each update
self.x = math.floor(self.x + math.sin(self.angle)*self.speed*dt)
self.y = math.floor(self.y - math.cos(self.angle)*self.speed*dt)
-- addVector(speed,angle,speed2,angle2)
self.speed,self.angle = addVector(self.speed,self.angle,g,math.pi)`
when it hits the ground, the code for it to bounce is :
self.angle = math.pi - self.angle
self.y = other.y - self.r`
the function addVector is defined here:
x = math.sin(angle)*speed + math.sin(angle2)*speed2
y = math.cos(angle)*speed + math.cos(angle2)*speed2
v = math.sqrt(x^2 + y^2)
a = math.pi/2 - math.atan(y,x)
return v,a
but when I place a single ball in the simulation without any drag or elasticity, the height of the ball after each bounce keeps getting higher. Any idea what may be causing the problem?
Edit: self.r is the radius, self.x and self.y are the position of the centre of the ball.
Your Y axis is increasing downward and decreasing upward.
Making self.y = math.floor(..) moves your ball a bit upward every frame.
The solution is to store your coordinates with maximal precision.
You could make new variable y_for_drawing = math.floor(y) to draw the ball at pixel with integer coordinates, but your main y value must have fractional part.
I’ve managed to get your code to run and reproduce the behavior you are seeing. I also find it difficult to figure out the issue. Here’s why: movement physics involves position, which is affected by a velocity vector, which in turn is affected by an acceleration vector. In your code these are all there, but are in no way clearly separated. There are trig functions and floor functions all interacting in a way that makes it difficult to see what role they are playing in the final position calculation.
By far the best and easiest-to-understand tutorial to help you implement basic physics lime this is The Nature of Code (free to read online, with interactive examples). As an exercise I ported most of the early exercises into Lua. I would suggest you see how he clearly separates the position, velocity and acceleration calculations.
As an experiemnt, increase g to a much higher number. When I did that, I noticed the ball would eventually settle to the ground, but of course the bouces were too fast and it didnt bounce in a way that seems natural.
Also, define other.y - it doesnt seem to affect the bouncing issue, but just to be clear on what that is.
I am using PanGesture Recognizer in Swift for iOS. Inside the action method, I am calling 3rd party method, that takes move direction and speed. From this, it calculates position of object:
objectPos += normalize(move) * speed
Problem is, that if I put my finger on a certain object and move with fingers, objects is not at the same position under my finger. It starts to move slower / faster. Moving directions are OK. Problem is with acceleration / decceleration - if I move faster, objects move faster.
In gesture callback I have tried:
let move = recognizer.translation(in: self.view);
let speed = sqrt((move.x * move.x) + (move.y * move.y));
and
let move = recognizer.velocity(in: self.view);
let speed = dt * sqrt((move.x * move.x) + (move.y * move.y));
Usually dt = 1.0 / 60.0. It is the gesture callback refresh rate (in code, I am calculating dt manually using difference of CFAbsoluteTimeGetCurrent()). Without this, If I use velocity directly to calculate speed, movement is too fast.
I have tried to calculate difference manually by subtracting current and last position, but still no luck.
I have also tried to "change speed" accoring to current view width and height, but none ot if worked. I am probably missing something, but dont know what.
It would be easier if you just computed the moves of the object based on acceleration when the user stops touching the object.
As long as the user has their finger on the object, it is much easier to just set the position of the object to the position you get from the pan gesture recognizer.
Ok... I have found the problem. Movement of th eobject it in screen normalized coordinates with corners [0,0] - [1,1]. So movement in Y axis (height) was correct, but in X axis (width) the speed was about half.
Multiply move.x with correct aspect ratio solved the problem. Basically, the moevement in X axis is enlarged manually.
I am using the device accelerometer and try to smooth the Accelerometer Data CMAcceleration.
I am doing this with help of this code:
-(void)proccessAccelerometerData:(CMAcceleration)accelData {
currentAccelX = (kUpdateInterval * accelData.x) + ((1.0 - kUpdateInterval) * currentAccelX);
currentAccelY = (kUpdateInterval * accelData.y) + ((1.0 - kUpdateInterval) * currentAccelY);
}
Which currentAccelX and currentAccelY is the last accelerometer x and y data.
Now, I have the smooth x and y values, What is my value of x or y to determine id the user move the device left/right/up/down?
Just to make things more clear, for example, let's say that I have 4 buttons, one for each direction left/right/up/down and I want to determine which direction the user user swipe the device? (not swipe gesture).
Thanks in advance!
Assuming you hold the device in portrait orientation, the x-Axis indicates the movement to the left and right (positive x is to the right and negative x to the left).
The y-Axis indicates the movement of the device up and down (positive y is upwards and negative y is downwards).
The z-Axis indicates the movement of the device forwards and backwards (positive z is towards the user and negative z is away from the user).
There is an info graphic by Apple: developer.apple.com
I am creating a game which uses accelerometer to move ball (football model game).
function acc(e)
physics.setGravity(e.xInstant*(screenW/4), -1*e.yInstant*(screenH/4))
end
But this code not giving a smooth flow of game. Can u guys help me for right option
You either need to "calibrate" or to change the algorithm. I would try calibrate first: replace your acc() with
function acc(e)
local calibX = 1
local calibY = 1
-- physics.setGravity(calibX * e.xInstant*(screenW/4), -calibY * e.yInstant*(screenH/4))
print(e.xInstant, e.yInstant, e.zInstant)
end
and do the tilting that you feel is "not smooth", looking at the values printed when you do that. This will tell you what calibX and Y should be, set them then uncomment the physics line, comment out the print line, try again, until you get it right. For example, if the x and y instant are around 10, you could try calibX = 0.1 or less.
If you can't find values for calibration coefficients that give you desired motion, you need to change your algorithm. For example, if you are trying to simulate the tilt of your device as though it was a table on which a marble rolls, and tilting the table should make marble move, then changing gravity is not the way to do it. You want to apply a horizontal force which is equal to g*sin(theta) where g is gravity and theta is the tilt angle of the device side-to-side. The formula is slightly more complex if you allow tilt along the other direction.
I have a physics body, and I want it to move forward in the direction that it is facing. I'm only thirteen which I hope explains why I'm so bad at trigonometry. Can anyone tell me how to do this in Corona?
I'm gonna assume you want to push your object with a force. Either way we'll need to get an x and y component of the direction your body is facing. Here's how to get the x and y from the rotation angle:
-- body is your physics body
local angle = math.rad(body.rotation) -- we need angle in radians
local xComp = math.cos(angle) -- the x component
local yComp = -math.sin(angle) -- the y component is negative because
-- "up" the screen is negative
(note: if this doesn't give the facing direction, you may need to add 90, 180, or 270 degrees to your angle, for example: math.rad(body.rotation+90) )
The above code will give you the x and y components of the unit vector in the direction of the rotation. You'll probably also need some multiplier to get the magnitude of force you want.
local forceMag = 0.5 -- change this value to apply more or less force
-- now apply the force
body:applyLinearImpulse(forceMag*xComp, forceMag*yComp, body.x, body.y)
Here's where I got the math: http://www.mathopenref.com/trigprobslantangle.html. Using a unit vector simplifies the math because the hypotenuse is always 1
How about making your own character moving towards an angle before using the confusing physics?
angle = math.rad(Insert the angle you want here)
character.x = character.x - math.sin(angle)
character.y = character.y + math.cos(angle)
Er. You don't need Trigonometry just to move the object.
Add
object:translate(distanceToMoveInXAxis,distanceToMoveInYAxis)
Or if you want to perform a transition,
transition.to(object,{x=object.x + distanceToMoveInXAxis,y=object.y + distanceToMoveInYAxis})