Sun Movement (Y/Z movement) - c++

I'm wondering the best way to simulate a sunrise/sunset on the y and z axis. At the moment it does what I want but is moving too fast (say every 3 seconds it's already completed an entire sun path and is already moving in reverse back to the origin).
I know this has to do with seconds variable combined with sin and cos, as this function is called and moves the light's position every frame. Basically I want it to be linked to my game's timer of 50:
50 seconds it's sunrise
25 seconds it's noon
0 seconds it's sunset/game over
Currently I have:
lightPosition = Point_E3d(0,
std::abs(100 *std::cos(seconds)),
-100 * std::sin(seconds));
Wondering what's the correct code format to achieve this effect.

This is just simple trigonometry. The period (Time until the function repeats) of sine(x * n) and cosine(x * n) are both 2*pi / n. In this case, n = 1, so the period is 6.28, meaning one full day (and night) will last 6.28 seconds. If you want to increase the period, multiply your seconds argument by a number smaller than one. A little bit of algebra shows that:
period of sin(x * n) = 2*pi / n
period of sin(.1256 * x) = 2*pi / .1256 = 6.28 / 0.1256 = 50
Therefore, take sine and cosine of seconds * 0.1256, rather than just seconds.
lightPosition = Point_E3d(0,
std::abs(100 *std::cos(seconds * 0.1256 )),
-100 * std::sin(seconds * 0.1256));
Note that this is also including the night time. If you want just the 12 hour day time period to last 50 seconds, multiply by half of 0.1256, aka 0.0628.

Related

Turn turtlebot2 10 degrees about its axis

How are you? How can I turn turtlebot2 10 degrees about its axis and then pause.
Note: The robot will not move, it will just rotate 10 degrees once every say 20 seconds.
I tried setting the Twist() object's angular velocity in the Z direction but only one wheel moves and ultimately the robot is displaced.
below is my code:
angular_velocity = radians(10) #10 degs / s
r = rospy.Rate(5) #5Hz
#rospy.loginfo("starting loop")
while not rospy.is_shutdown():
rospy.loginfo("in loop")
new_angle = (angle + new_angle) % 360
real_angle = real_angle + angle
#real_angle = rea1_angle + 5
rospy.loginfo("after addition")
new_angle = real_angle % 360
turn_cmd.angular.z = angular_velocity #turns 10 degrees a second
#turn at 10 degrees a second for 1 second
for i in range(5):
self.cmd_vel.publish(turn_cmd)
r.sleep()
r.sleep()
# wait 40s
for x in range(200):
self.cmd_vel.publish(Twist()) #publish ) to stop the bot at that point
# stop the turtle and gather data as u wait
r.sleep()
try:
data = "get some data from external source"
if(data):
try:
#rospy.loginfo("w(rads/$
comb_d.write( str(data)
except:
rospy.loginfo("failed or bad data)
pass
r.sleep()
comb_d.close()
def shutdown(self):
# stop turtlebot
rospy.loginfo("Stop turning")
self.cmd_vel.publish(Twist())
The above is my logic. But not only does the robot move, it also does not turn 10 degrees as I expect.
What am i doing wrong?
Thank you very much.
Am using ROS indigo kobuki and turtlebot2
That being said - on slightly different note - what would be the favorable values for the rospy.Rate() function and the inner for loop to achieve the 10 or even 30 degree rotation at a relative higher angular velocity, say 25 degrees per second. Because it seems the robot does not work well with low velocities such as 10 degs/s. Some times it does not move at all when low velocities are given. Eitherway, thanks.

Physics simulation gives (very) inaccurate positions for simple trajectories calculus

I want to implement a physics engine in a game in order to compute trajectories of bodies with forces applied to them.
This engine would calculate each state of the object based on its previous state. Of course this means a lot of calculation between two units of time to be sufficiently precise.
To do that properly, I wanted first to know how big are the differences between this method of getting positions, and with kinematic equations.
So I made this code which stores the positions (x, y, z) given by the simulations and by the equations in a file.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "header.h"
Body nouveauCorps(Body body, Vector3 force, double deltaT){
double m = body.mass;
double t = deltaT;
//Newton's second law:
double ax = force.x/m;
double ay = force.y/m;
double az = force.z/m;
body.speedx += ax*t;
body.speedy += ay*t;
body.speedz += az*t;
body.x +=t*body.speedx;
body.y +=t*body.speedy;
body.z +=t*body.speedz;
return body;
}
int main()
{
//Initial conditions:
double posX = 1.4568899;
double posY = 5.6584225;
double posZ = -8.8944444;
double speedX = 0.232323;
double speedY = -1.6565656;
double speedZ = -8.6565656;
double mass = 558.74;
//Force applied:
Vector3 force = {5.8745554, -97887.568, 543.5875};
Body body = {posX, posY, posZ, speedX, speedY, speedZ, mass};
double duration = 10.0;
double pointsPS = 100.0; //Points Per Second
double pointsTot = duration * pointsPS;
char name[20];
sprintf(name, "BN_%fs-%fpts.txt", duration, pointsPS);
remove(name);
FILE* fichier = NULL;
fichier = fopen(name, "w");
for(int i=1; i<=pointsTot; i++){
body = nouveauCorps(body, force, duration/pointsTot);
double t = i/pointsPS;
//Make a table: TIME | POS_X, Y, Z by simulation | POS_X, Y, Z by modele (reference)
fprintf(fichier, "%e \t %e \t %e \t %e \t %e \t %e \t %e\n", t, body.x, body.y, body.z, force.x*(t*t)/2.0/mass + speedX*t + posX, force.y*(t*t)/2.0/mass + speedY*t + posY, force.z*(t*t)/2.0/mass + speedZ*t + posZ);
}
return 0;
}
The problem is that with simple numbers (like with a simple fall in a -9.81 gravity field) I got nice positions, but with bigger (and quite random) numbers, I get inaccurate positions.
Is that a floating point issue?
Here are the results, with relative errors. (Note: label axes are in French, Temps = Time).
Graphs
Black+dashed : values from kinematic equations
Red : 100 points per second
Orange : 1000 points per second
Green : 10000 points per second
This is not a floating point issue. In fact, even if you were using exact arithmetic you'd see the same problem.
This error is really fundamental to numerical integration itself and the particular method you're using and the ODE you're solving.
In this case you're using an integration scheme known as Forward Euler. This is probably the simplest approach to solving a first-order ODE. Of course, this leaves it with some undesirable features.
For one, it introduces error at each step. The size of the error is O(Δt²). That means the error over a single time step is roughly proportional to the square of the size of the time step. So if you cut the size of the time step in half, roughly you drop the incremental error to 1/4 the value.
But since you decrease the time step, you have to make more steps to simulate the same amount of time. So you're adding up more but smaller errors. This is why the cumulative error is O(Δt). So really over the whole simulated time if you take time steps that are half as big, you get half as much cumulative error.
Ultimately this cumulative error is what you're seeing. And you can see in your error plot that the ultimate error ends up decreasing by about a factor of 10 each time you increase the number of time steps by a factor of 10: because the time step is 10 times smaller, so the total error ends up about 10 times smaller.
The other issue is that Forward Euler exhibits what's known as conditional stability. This means it's possible for the cumulative error to grow without bound in certain cases. To see why, let's look at a simple ODE:
x' = -k * x
Where k is some constant. The exact solution of this ODE is x(t) = x(0) * exp( -k * t ). So as long as k is positive, x should tend to 0 as time increases.
However, if we try to approximate this using Forward Euler, we get something that looks like this:
x(t + Δt) = x(t) + Δt * ( -k * x[n] )
= ( 1 - k * Δt ) * x(t)
This is a simple recurrence relation that we can solve:
x(t) = ( 1 - k * Δt )^(t / Δt) * x(0)
Now, we know the exact solution tens to 0 as t gets larger. But the Forward Euler solution only does that if |1 - k * Δt| < 1. Notice how that expression depends on the step size as well as the k term from our ODE. If k is really really big, we need a really really tiny time step to keep the solution from blowing up. This is why it possesses what's known as conditional stability: the stability of the solution is conditional on the time step.
There are also a number of other issues, but this is a broad topic and I can't cover everything in a single answer.

Python movement of hands on analogue clock

I am trying to draw a clock face in which the second hand moves as the time changes.
I am using the following to calculate the points on my circle:
def points_on_circle():
global time, radius, centre, x, y
theta = time% math.pi * 2
c = math.cos(theta)
s = math.sin(theta)
x= centre[0] + radius * c
y =centre[1] + radius * s
return x,y
my timer 'ticks' every tenth second, the radius of my circle is 50, the centre is at (150,150) which is also the origin of my hand, the other end of the hand being (x,y) as calculated above. How do I calculate , I assume by multiplying time by some constant, how fast the x,y should change for this circle ( but for any circle) .
I am using CodeSkulptor from Coursera to try to do this ( the original assignment created a digital timer which I am done. This is not part of the homework ( yet??)
The hand rotates 2 Pi radians every 60 seconds. Assuming you're syncing with real time, time.time() will return the current time in seconds (and milliseconds which I suggest you ignore). If you take the time and first do numseconds = int(time.time()) % 60, you now need to translate that, which is a simple as numseconds * 2 * pi / 60. (Example: numseconds = 0, theta = 0, numseconds = 15, theta = pi /2 (90 degrees).
You will also need to play with your equations as normally theta=0 implies the line is horizontal pointing right (which would be numseconds = 15) and theta=Pi implies the line is vertical pointing up (which would be numseconds = 0)

Movespeed calculation issue

This is in C++ and I'm using VC++ 2010.
I am creating a tile-based game, each tile is 32 pixels. If you are given an amount of time, and in that time you want to move an image 32 pixels in a direction, how would I calculate the amount to move per each frame? The frame rate is not fixed and I have access to the frame delta time.
If you need more information just ask.
The basic formula you need to calculate it is:
P pixels / S seconds * delta T seconds/frame = X pixels/frame
For example we'll use your tile size and move it in 1 second and the current frame rate is 30 fps.
32 pixels / 1 second * .033 seconds/frame = 1.056 pixels/frame
int P = 32;
double S = 1.0;
double T = getFrameTime();
double X = P / S * T;

Simple Euler Physics, Weird Behaviour

I have this simple euler integrator. For finding precise collision times it should handle negative dt's as well (I divide the frame time and simulate back when I detect a collision).
For some reason
someBody.update(1.0);
someBody.update(-0.3);
someBody.update(-0.3);
someBody.update(0.6);
gives different results than:
someBody.update(1.0);
It might be because I use euler instead of RK4 or verlet?
Here's the code for the integrator:
void Body::update(double dt)
{
if (dt > 0) velocity += acceleration * (dt*dt);
else velocity -= acceleration * (dt*dt);
pos += velocity * dt;
rotation += angularVelocity * dt;
}
Thanks a lot!
Maarten
The reason is math. Let's focus on velocity variable:
If you call:
someBody.update(1.0)
you'll get:
velocity += acceleration * 1
But if you call:
someBody.update(1.0);
someBody.update(-0.3);
someBody.update(-0.3);
someBody.update(0.6);
you will get:
velocity += acceleration * (1 - 0.3^2 - 0.32^2 + 0.6^2)
(which gives velocity += acceleration * 1.18)
You should have simply velocity += acceleration * dt;
Suspect floating point error accumulation in Body::update.
Example: 1 + 2 + 3 + 4 = 10 but 1.0 + 2.0 + 3.0 + 4.0 = something else.
The easiest fix is to round the results after each major computation step.
Thanks, the acceleration was indeed wrong.
I use a fixed timestep for each frame. This function is to run the simulation for partial frames. So I ignore the accaleraion completely now. This way everything within a frame happens linearly and the acceleration is only added in between frames.
The problem persists though. I think it might be the floating point errors as poited out by Magicianeer.
Although I think these errors would not add up so dramatically. In around 50 frames a bouncing object goes from it's full height (100) to about half that height. In around 200 frames it's still on the floor. When I don't call multiple the updates within the frame it's all fine.
I'll try keeping the position at the end of the frame and putting it back after doing the partial frame simulations. That way the errors won't add up over multiple frames.