How to calculate speed from acceleration using systemC AMS and TDF modeling formalism - systemc

I have a constant acceleration and I need to calculate the instantaneous speed and the travelled distance.
So we know that the speed is the integral of acceleration and the travelled distance is the integral of the speed.
Using systemC AMS with the TDF modeling formalism, there isn't the integral operator, but there is the Laplace transform operator instead.
The schema for the speed and distance calculation that I would realize is the follow:
NB:
// Declaration of private variables of SCA_TDF_MODULE
sca_tdf::sca_ltf_nd lft;
sca_util::sca_vector<double> num, den;
// initialisation of variables
num(0) = 1.0;
den(0) = 1.0;
So I thought that I could calculate the speed using the sca_tdf::sca_ltf_nd in this way:
if (throttle_is_active) {
speed.write(lft(num, den, 2.78)); // speed is an output port
// distance ....
}
But I'm not sure that is right, and I don't know how to save this value to calculate the travelled distance using the ltf again.
The definition of tdf module can be found here.
Anyone can help me please?
see also SystemC AMS Users Guide provided with the proof-of-concept library

The coefficients in SystemC-AMS are defined as follows:
H(s) = (num(0) + num(1)*s + num(2)*s**2 ...) / (den(0) + den(1)*s + den(2)*s**2 ...)
-> the coefficients for an integrator are:
num(0)=1.0;
den(0)=0.0;
den(1)=1.0;

Related

Using the piecewise function of the IBM CPLEX python API, but the problem cannot be solved

I try to use MILP (Mixed Integer Linear Programming) to calculate the unit commitment problem. (unit commitment: An optimization problem trying to find the best scheduling of generator)
Because the relationship between generator power and cost is a quadratic function, so I use piecewise function to convert power to cost.
I modify the answer on this page:
unit commitment problem using piecewise-linear approximation become MIQP
The simple program structure is like this:
from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
#after 4 buses, additional buses of a given size are cheaper
f1=mdl.piecewise(0, [(0,0),(4,2000),(10,4400)], 0.8)
f2=mdl.piecewise(0, [(0,0),(4,1600),(10,3520)], 0.8)
cost1= f1(nbbus40)
cost2 = f2(nbbus30)
mdl.minimize(cost1+ cost1)
mdl.solve()
mdl.report()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
which gives
* model buses solved with
objective = 3520.000
nbBus40 = 0
nbBus30 = 10.0
The answer is perfect but there is no way to apply my example.
I used a piecewise function to formulate a piecewise linear relationship between power and cost, and got a new object (cost1), and then calculated the minimum value of this object.
The following is my actual code(simply):
(min1,miny1), (pw1_1,pw1_1y),(pw1_2,pw1_2y), (max1,maxy1) are the breakpoints on the power-cost curve.
pwl_func_1phase = ucpm.piecewise(
0,
[(0,0),(min1,miny1),
(pw1_1,pw1_1y),
(pw1_2,pw1_2y),
(max1,maxy1)
],
0
)
#df_decision_vars_spinning is a dataframe store Optimization variables
df_decision_vars_spinning.at[
(units,period),
'variable_cost'
] = pwl_func_1phase(
df_decision_vars_spinning.at[
(units,period),
'production'
]
)
total_variable_cost = ucpm.sum(
(df_decision_vars_spinning.variable_cost))
ucpm.minimize(total_variable_cost )
I don’t know what causes this optimization problem can't be solve. Here is my complete code :
https://colab.research.google.com/drive/1JSKfOf0Vzo3E3FywsxcDdOz4sAwCgOHd?usp=sharing
With an unlimited edition of CPLEX, your model solves (though very slowly). Here are two ideas to better control what happens in solve()
use solve(log_output=True) to print the log: you'll see the gap going down
set a mip gap: setting mip gap to 5% stops the solve at 36s
ucpm.parameters.mip.tolerances.mipgap = 0.05
ucpm.solve(log_output=True)
Not an answer, but to illustrate my comment.
Let's say we have as the cost curve
cost = α + β⋅power^2
Furthermore, we are minimizing cost.
We can approximate using a few linear curves. Here I have drawn a few:
Let's say each linear curve has the form
cost = a(i) + b(i)⋅power
for i=1,...,n (n=number of linear curves).
It is easy to see that is we write:
min cost
cost ≥ a(i) + b(i)⋅power ∀i
we have a good approximation for the quadratic cost curve. This is exactly as I said in the comment.
No binary variables were used here.

Heuristic for an A* Path Finding GPS

I'm developing a GPS system and to do that I'd like to use the A* algorithm. I have a graph where the vertex are the source / target and the edges are the streets. For that I have a database with following info:
id;"Street Name";source;target;GeoCoordinateX1;GeoCoordinateY1;GeoCoordinateX2;GeoCoordinateY2
Each of these lines represent an edge. Using the coordinates the aim is using one path finding algorithm get the shortest and fastest path. I already developed djikstra algorithm but now I'm trying to find a really good heuristic.
I'd like to know if there's an heuristic that is more accurate or efficient. I read that I could use Manhattan, Euclidian or Diagonal distance. I think Euclidian would be a good choice but then the cost of the g funciton wouldnt be the same of the heuristic funcion h. I'd get the shortest path but it'd take longer. Is there any way to get the good and the profit?
Best regards
For most coordinate based pathfinding, the cost function used in A* is 'distance'. Each vertex in your graph is a gps coordinate along a street, so the distance between each vertex is calculated like this using the Haversine formula:
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}
In order to find the fastest path, the cost function will be 'estimated travel time'. In order to calculate this, you need the 'speed limit' for each edge between vertices (street), as well as the distance calculated above.
The cost function is very simple: cost in hours = distance / speed = km / (km/h)
Google maps has an API to find the shortest/fastest paths for many different modes of transportation, and it will save you a lot of effort. It also takes into account traffic, bus schedules and other factors that would be difficult to consider in your project.
If this is a hobby project, continue and you'll learn a lot about pathfinding. Feel free to learn from my favourite A* guide on Amit Patel's website. If you'd like to learn about all the cool options you have for pathfinding, I have an in-depth guide that I wrote for this answer. People in academia commonly write tutorials on the essential algorithms and google searches can find research papers about variants on these algorithms.

How do I calculate distance between GPS co-ordinates using Microcontroller chip

I need to calculate the distance between GPS co-ordinates to calculate distance being traveled. I've tried both the Haversine and Vincenty algorithms, which work fine on my desktop PC, but when I use the same code for MSP430 chip using CCS IDE, the IDE is throwing error saying that "program will not fit into available memory".
Is there any other alternative method or code to find the distance between two GPS co-ordinates? which will fit in available memory of MSP430 Microcontroller ?
It's not surprising that you're running out of memory, because the microcontroller you are using, the Texas Instruments MSP430F2274, has only 32kB of flash, and 1kB of RAM.
There are several approaches to solving your problem, each with different tradeoffs. Here are three:
Use another microcontroller that has more memory (there are many in the MSP430 family).
Optimize your code to fit in the available space.
Use a simpler formula than the Vincenty or Haversine.
I'll address the two latter approaches below.
Optimize Your Code
Depending on the accuracy requirements of your application, optimizing your existing code might be a better approach than using a simpler formula than Vincenty or Haversine.
A Simple Way to Optimize
Perhaps simply setting the compiler to optimize for size will solve your problem. In the MSP430 toolset, use the --opt_for_speed=0 switch. According to the MSP430 Optimizing C/C++ Compiler User's Guide (v15.9.0.STS) (page 62), this switch:
enables optimizations geared towards improving the code size with a
high risk of worsening or impacting performance.
So you might very easily get things to work by using this switch, at the cost of trading away speed for memory space.
A More Involved Way to Optimize
Assuming you are using the floating point math library provided with your compiler, you might be able to still use Vincenty or Haversine if you replace the math library with a more space-efficient version. The CORDIC fixed-point algorithms provide iterative approaches to calculating the trigonometric functions, that trade away speed for space efficiency. If you roll your own math library, you might achieve a good balance between space, speed, and accuracy. A 16-bit version of the CORDIC approach for sine() and cosine() for the MSP430 is here; you will need to determine whether it provides the degree of accuracy and precision you need.
Use a Different Formula
In general, the various algorithms that calculate distance between two points on the earth represent a trade-off between accuracy and complexity. The Vincenty algorithm you cited is much more accurate than the Haversine, as it more correctly represents the earth as an oblate spheroid instead of as a sphere of radius R; hence the math is more complex.
For reference, the Haversine method (which assumes the earth is a perfect sphere) is shown here:
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin^2(dlat/2) + cos(lat1) * cos(lat2) * sin^2(dlon/2)
c = 2 * arcsin(min(1,sqrt(a)))
d = R * c
The intermediate result c is the distance in radians. The distance d is in the same units as R (radius of the earth).
As you can see, the Haversine employs an arcsin() in the calculation.
You can simplify the math further by employing the Polar Coordinate Flat-Earth method:
a = pi/2 - lat1
b = pi/2 - lat2
c = sqrt(a^2 + b^2 - 2 * a * b * cos(lon2 - lon1)
d = R * c
Notice that there is no arcsin() in this calculation, but there is a sqrt().
A discussion of the accuracy tradeoffs between the Haversine and the Polar Coordinate Flat-Earth methods is here, question Q5.1.
See also
How do I calculate distance between GPS co-ordinates on a processor with poor floating point support?
http://www.faqs.org/faqs/geography/infosystems-faq/ Question Q5.1
Geographical Distance (Wikipedia)

Gravitational Pull

Does anyone know of a tutorial that would deal with gravitational pull of two objects? Eg. a satellite being drawn to the moon (and possibly sling shot past it).
I have a small Java game that I am working on and I would like to implement his feature in it.
I have the formula for gravitational attraction between two bodies, but when I try to use it in my game, nothing happens?
There are two object on the screen, one of which will always be stationary while the other one moves in a straight line at a constant speed until it comes within the detection range of the stationary object. At which point it should be drawn to the stationary object.
First I calculate the distance between the two objects, and depending on their mass and this distance, I update the x and y coordinates.
But like I said, nothing happens. Am I not implementing the formula correctly?
I have included some code to show what I have so far.
This is the instance when the particle collides with the gates detection range, and should start being pulled towards it
for (int i = 0; i < particle.length; i++)
{
// **************************************************************************************************
// GATE COLLISION
// **************************************************************************************************
// Getting the instance when a Particle collides with a Gate
if (getDistanceBetweenObjects(gate.getX(), particle[i].getX(), gate.getY(), particle[i].getY()) <=
sumOfRadii(particle[i].getRadius(), barrier.getRadius()))
{
particle[i].calcGravPull(particle[i].getMass(), barrier.getMass(),
getDistanceBetweenObjects(gate.getX(), particle[i].getX(), gate.getY(), particle[i].getY()));
}
And the method in my Particle class to do the movement
// Calculate the gravitational pull between objects
public void calcGravPull(int mass1, int mass2, double distBetweenObjects)
{
double gravityPull;
gravityPull = GRAV_CONSTANT * ((mass1 * mass2) / (distBetweenObjects * distBetweenObjects));
x += gravityPull;
y += gravityPull;
}
Your formula has problems. You're calculating the gravitational force, and then applying it as if it were an acceleration. Acceleration is force divided by mass, so you need to divide the force by the small object's mass. Therefore, GRAV_CONSTANT * ((mass1) / (distBetweenObjects * distBetweenObjects)) is the formula for acceleration of mass2.
Then you're using it as if it were a positional adjustment, not a velocity adjustment (which an acceleration is). Keep track of the velocity of the moving mass, use that to adjust its position, and use the acceleration to change that velocity.
Finally, you're using acceleration as a scalar when it's really a vector. Calculate the angle from the moving mass to the stationary mass, and if you're representing it as angle from the positive x-axis multiply the x acceleration by the cosine of the angle, and the y acceleration by the sine of the angle.
That will give you a correct representation of gravity.
If it does nothing, check the coordinates to see what is happening. Make sure the stationary mass is large enough to have an effect. Gravity is a very weak force, and you'll have no significant effect with much smaller than a planetary mass.
Also, make sure you're using the correct gravitational constant for the units you're using. The constant you find in the books is for the MKS system - meters, kilograms, and seconds. If you're using kilometers as units of length, you need to multiply the constant by a million, or alternately multiply the length by a thousand before plugging it into the formula.
Your algorithm is correct. Probably the gravitational pull you compute is too small to be seen. I'd remove GRAV_CONSTANT and try again.
BTW if you can gain a bit of speed moving the result of getDistanceBetweenObjects() in a temporary variable.

How to calculate deceleration needed to reach a certain speed over a certain distance?

I've tried the typical physics equations for this but none of them really work because the equations deal with constant acceleration and mine will need to change to work correctly. Basically I have a car that can be going at a large range of speeds and needs to slow down and stop over a given distance and time as it reaches the end of its path.
So, I have:
V0, or the current speed
Vf, or the speed I want to reach (typically 0)
t, or the amount of time I want to take to reach the end of my path
d, or the distance I want to go as I change from V0 to Vf
I want to calculate
a, or the acceleration needed to go from V0 to Vf
The reason this becomes a programming-specific question is because a needs to be recalculated every single timestep as the car keeps stopping. So, V0 constantly is changed to be V0 from last timestep plus the a that was calculated last timestep. So essentially it will start stopping slowly then will eventually stop more abruptly, sort of like a car in real life.
EDITS:
All right, thanks for the great responses. A lot of what I needed was just some help thinking about this. Let me be more specific now that I've got some more ideas from you all:
I have a car c that is 64 pixels from its destination, so d=64. It is driving at 2 pixels per timestep, where a timestep is 1/60 of a second. I want to find the acceleration a that will bring it to a speed of 0.2 pixels per timestep by the time it has traveled d.
d = 64 //distance
V0 = 2 //initial velocity (in ppt)
Vf = 0.2 //final velocity (in ppt)
Also because this happens in a game loop, a variable delta is passed through to each action, which is the multiple of 1/60s that the last timestep took. In other words, if it took 1/60s, then delta is 1.0, if it took 1/30s, then delta is 0.5. Before acceleration is actually applied, it is multiplied by this delta value. Similarly, before the car moves again its velocity is multiplied by the delta value. This is pretty standard stuff, but it might be what is causing problems with my calculations.
Linear acceleration a for a distance d going from a starting speed Vi to a final speed Vf:
a = (Vf*Vf - Vi*Vi)/(2 * d)
EDIT:
After your edit, let me try and gauge what you need...
If you take this formula and insert your numbers, you get a constant acceleration of -0,0309375. Now, let's keep calling this result 'a'.
What you need between timestamps (frames?) is not actually the acceleration, but new location of the vehicle, right? So you use the following formula:
Sd = Vi * t + 0.5 * t * t * a
where Sd is the current distance from the start position at current frame/moment/sum_of_deltas, Vi is the starting speed, and t is the time since the start.
With this, your decceleration is constant, but even if it is linear, your speed will accomodate to your constraints.
If you want a non-linear decceleration, you could find some non-linear interpolation method, and interpolate not acceleration, but simply position between two points.
location = non_linear_function(time);
The four constraints you give are one too many for a linear system (one with constant acceleration), where any three of the variables would suffice to compute the acceleration and thereby determine the fourth variables. However, the system is way under-specified for a completely general nonlinear system -- there may be uncountably infinite ways to change acceleration over time while satisfying all the constraints as given. Can you perhaps specify better along what kind of curve acceleration should change over time?
Using 0 index to mean "at the start", 1 to mean "at the end", and D for Delta to mean "variation", given a linearly changing acceleration
a(t) = a0 + t * (a1-a0)/Dt
where a0 and a1 are the two parameters we want to compute to satisfy all the various constraints, I compute (if there's been no misstep, as I did it all by hand):
DV = Dt * (a0+a1)/2
Ds = Dt * (V0 + ((a1-a0)/6 + a0/2) * Dt)
Given DV, Dt and Ds are all given, this leaves 2 linear equations in the unknowns a0 and a1 so you can solve for these (but I'm leaving things in this form to make it easier to double check on my derivations!!!).
If you're applying the proper formulas at every step to compute changes in space and velocity, it should make no difference whether you compute a0 and a1 once and for all or recompute them at every step based on the remaining Dt, Ds and DV.
If you're trying to simulate a time-dependent acceleration in your equations, it just means that you should assume that. You have to integrate F = ma along with the acceleration equations, that's all. If acceleration isn't constant, you just have to solve a system of equations instead of just one.
So now it's really three vector equations that you have to integrate simultaneously: one for each component of displacement, velocity, and acceleration, or nine equations in total. The force as a function of time will be an input for your problem.
If you're assuming 1D motion you're down to three simultaneous equations. The ones for velocity and displacement are both pretty easy.
In real life, a car's stopping ability depends on the pressure on the brake pedal, any engine braking that's going on, surface conditions, and such: also, there's that "grab" at the end when the car really stops. Modeling that is complicated, and you're unlikely to find good answers on a programming website. Find some automotive engineers.
Aside from that, I don't know what you're asking for. Are you trying to determine a braking schedule? As in there's a certain amount of deceleration while coasting, and then applying the brake? In real driving, the time is not usually considered in these maneuvers, but rather the distance.
As far as I can tell, your problem is that you aren't asking for anything specific, which suggests that you really haven't figured out what you actually want. If you'd provide a sample use for this, we could probably help you. As it is, you've provided the bare bones of a problem that is either overdetermined or way underconstrained, and there's really nothing we can do with that.
if you need to go from 10m/s to 0m/s in 1m with linear acceleration you need 2 equations.
first find the time (t) it takes to stop.
v0 = initial velocity
vf = final velocity
x0 = initial displacement
xf = final displacement
a = constant linear acceleration
(xf-x0)=.5*(v0-vf)*t
t=2*(xf-x0)/(v0-vf)
t=2*(1m-0m)/(10m/s-0m/s)
t=.2seconds
next to calculate the linear acceleration between x0 & xf
(xf-x0)=(v0-vf)*t+.5*a*t^2
(1m-0m)=(10m/s-0m/s)*(.2s)+.5*a*((.2s)^2)
1m=(10m/s)*(.2s)+.5*a*(.04s^2)
1m=2m+a*(.02s^2)
-1m=a*(.02s^2)
a=-1m/(.02s^2)
a=-50m/s^2
in terms of gravity (g's)
a=(-50m/s^2)/(9.8m/s^2)
a=5.1g over the .2 seconds from 0m to 10m
Problem is either overconstrained or underconstrained (a is not constant? is there a maximum a?) or ambiguous.
Simplest formula would be a=(Vf-V0)/t
Edit: if time is not constrained, and distance s is constrained, and acceleration is constant, then the relevant formulae are s = (Vf+V0)/2 * t, t=(Vf-V0)/a which simplifies to a = (Vf2 - V02) / (2s).