How to determine when to accelerate and decelerate to reach a given destination? - physics

I'm creating a computer game in which there is a computer-controlled car that needs to travel along a straight line (thus making this problem effectively 1-dimensional) and reach a destination coming to a rest at 0 velocity. This car "thinks" every second and decides whether (and by how much) to accelerate or decelerate.
To summarize, I want the car to accelerate as strongly as possible and then stop as rapidly as possible.
Here are the variables that the car must respect:
- RemainingDistance = Our current remaining distance to the destination in meters.
- Velocity = Our current velocity towards the destination in meters/second.
- MaxVelocity = The maximum speed the car can reach.
- Acceleration = The change in velocity per second. The car can change its acceleration every second to any number in the range [0, Acceleration].
- Deceleration = The change in velocity per second. The car can change its deceleration every second to any number in the range [0, Deceleration].
So to be as clear as I can, here's the math that runs every second to update the car simulation:
Acceleration = some amount between [Deceleration, Acceleration] as chosen by the computer
Velocity = Velocity + Acceleration
RemainingDistance = RemainingDistance - Velocity
So my question is: Every time the car "thinks", what formula(s) should it use to determine the ideal value of Acceleration in order to reach its destination (with a 0 final velocity) in as little time as possible?
(In the event that the car's initial velocity is too high and it can't decelerate fast enough to achieve 0 velocity by the time it reaches its destination, then it should come to a rest as close as possible to the destination.)
Please let me know if you have any questions.

Related

How to model a time-dependent vehicle routing problem with time windows in octapy?

I am looking to model a vehicle routing problem with time windows on OctaPy. Specifically, this problem involves traffic enforcement on public roads, so parking wardens need to survey carparks and road segments and visit them more than once during a 24-hour period.
I refer to the answer in the following question as foundation to develop my problem:
Is it possible to create a VRP solution using NetworkX?
I have a few questions regarding the modelling:
How does OctaPy model time-dependency, that is a different edge weight representing travel duration depending on the time of day?
How do I model the demand points if each point needs to be visited X times?
If a demand point is to be visited X times, how can I enforce a time window gap such that the duration between visits is at least a fixed duration (e.g. 1 hour)?
OptaPy models time-dependency the way you model time-dependency. That is, whatever you use to model time-dependency (may it be an edge, a list, a matrix, a class, etc.), OptaPy can use it in its constraints.
If X is known in advance, for each demand point, you create X copies of it and put it in the #problem_fact_collection_property field. If X is not known in advance, consider using real-time planning (https://www.optapy.org/docs/latest/repeated-planning/repeated-planning.html#realTimePlanning).
This depends on how you implement your time dependency. This would be easier when OptaPy supports the new VariableListener API for List Variable (as well as the builtin list shadow variables) that OptaPlanner has. Until then, you need to do the calculation in a function. Make Edge a #planning_entity and give it a inverse relation shadow variable (https://www.optapy.org/docs/latest/shadow-variable/shadow-variable.html#bidirectionalVariable). Add a method get_arrival_time(edge) to Vehicle that get the estimated time of visit for a given Edge in its visited_edges_list.
def less_than_one_hour_between(visit_1: Edge, visit_2: Edge):
visit_1_arrival_time = visit_1.vehicle.get_arrival_time(visit_1)
visit_2_arrival_time = visit_2.vehicle.get_arrival_time(visit_2)
duration = visit_2_arrival_time - visit_1_arrival_time
return timedelta(hours=0) <= duration <= timedelta(hours=1)
def one_hour_between_consecutive_visits(constraint_factory):
return (
constraint_factory.for_each(Edge)
.join(Edge, Joiners.equal(lambda edge: edge.graph_from_node),
Joiners.equal(lambda edge: edge.graph_to_node))
.filter(lambda a, b: a is not b and less_than_one_hour_between(a, b))
.penalize('less than 1 hour between visits', HardSoftScore.ONE_HARD)

Playing a simulation in fast-forward

I am working a simple game where users create structures in a sector, which is a 10x10 grid. Some structures generate resources and some consume resources. The sector itself might contain some resources outside of any structure. The generators and consumers are related. For example, a well might be generating water, then an splitter be consuming water and making hydrogen and oxygen, while a refinery is consuming hydrogen and oxygen and making rocket fuel, etc.
The rate at which they generate or consume resources can vary by structure - I call this the tick rate. Each time a consumer ticks, it will first attempt to extract those resources from the structures that surround it in the sector. If there are not enough, it will try to get them from the sector's storage. If it is still not enough, the structure will stop. Structures hold the resources that they generate up to some maximum. Once they are full, they will not generate more until some are consumed. If a structure is stopped, it will also not generate more resources, but the resources it already has can still be used by another adjacent structure.
It is not uncommon that there are patterns. For example, if the well is very slow, the splitter will turn off when the well runs out of water, and then the refinery will turn off when the splitter runs out of gases. Then when the well generates again, everything will turn back on.
When the user is playing a sector, I tick the sector continuously at the resolution of shortest tick rate of the sector's structures. This works fine. The pseudo-code looks like this:
const numTicks = (Date.now() - lastTickTime) / shortestTickTime;
let currentTickTime = lastTickTime;
for (i = 0; i < numTicks; i++) {
currentTickTime += shortestTickTime;
// check the consumers - all structures that are consumers
for (curConsumer of consumers) {
if (curConsumer.isRunning &&
(currentTickTime - curConsumer.lastTickTime >= curConsumer.tickRate) {
... check surrounding structures for resources
if (curConsumer.stillNeedsResources) {
... check sector for researches
}
if (curConsumer.stillNeedsResources) {
... no resources available
curConsumer.isRunning = false;
}
}
// check the generators - all structures that are generators
for (curGenerator of generators) {
if (curGenerator.isRunning &&
(currentTickTime - curGenerator.lastTickTime >= curGenerator.tickRate) {
... add the generated resources
}
}
}
}
Now I am dealing with the case of a user coming back to a sector after a long absence - say, a few days - when hundreds or thousands of ticks have passed. If I just naively try to play all of the ticks, it can take several seconds or several minutes to complete.
I am wondering if there are any tips or tricks for simulations of this kind for computing the net change without playing each tick. Or, alternately, if there are changes I can make to the simulation to make this easier to compute. Thanks!
Step 1: Convert the raw data into "graph of nodes" form, where each node represents a machine, and producers are at the bottom and consumers are at the top. For example it might look like:
|
(fuel)
|
Refinery
/ \
/ \
(hydrogen) (oxygen)
\ /
\ /
Splitter
|
(water)
|
well
Note: If a machine has an output buffer (or input buffer/s); then those buffers should be separate nodes. For example, if everything has output buffers it might look like this:
|
(fuel)
|
Refinery output buffer
|
(fuel)
|
Refinery
/ \
/ \
(hydrogen) (oxygen)
| |
Hydrogen Oxygen
output output
buffer buffer
| |
(hydrogen) (oxygen)
\ /
\ /
Splitter
|
(water)
|
Well output buffer
|
(water)
|
well
Step 2: Determine "current steady state average rates" by (initially) working from bottom up (producers to consumers). For example, if a well produces 1 unit of water every 4 ticks then assume it does produce an average of 0.25 water per tick; and if a splitter can convert 1 unit of water into 2 units of hydrogen and 1 unit of oxygen every 3 ticks then that's a max. rate of 0.333 water converted to 0.666 hydrogen and 0.333 oxygen, but you already know the well isn't producing water fast enough and can determine that the splitter will actually consume 0.25 water to produce 0.5 hydrogen and 0.25 oxygen.
Note that if a producer overproduces you will need to backtrack. For example, if a well produces 1 unit of water every 2 ticks then you'd assume it does produce an average of 0.5 water per tick; and if a splitter can convert 1 unit of water into 2 units of hydrogen and 1 unit of oxygen every 3 ticks then you know the well is producing more water than the splitter can consume and have to go back to the well and clamp its output to 0.333 water per tick.
Step 3: Determine when (how many ticks) until the next thing happens that will change the "current steady state average rates". If a resource can become depleted (e.g. the well runs dry) you need to know when that will happen. In the same way, if a "storage vessel" (an output buffer, input buffer, water tank, fuel storage chest, ...) becomes full or empty then you need to know when that will happen too. This is all based on the "current steady state average rates" you have - e.g. if a well's output buffer is empty and gains water (from well) at a rate of 0.5 water per tick and loses water (to splitter) at a rate of 0.33 water per tick; then you can calculate that the quantity it is storing increases at a rate of "0.5 - 0.33 = 0.17 per tick" and (combined with the buffer's capacity) calculate when the output buffer will become full.
Note that "how many ticks until the next thing happens" must also be limited to when you want to stop simulating.
Step 4: Advance time up until the next thing that happens. This mostly means updating the amount of stuff stored in "storage vessels" using the "current steady state average rates" you have; and then modifying any information (e.g. setting a well to "not functioning, ran dry").
Step 5: Repeat the previous steps until you reach the time you want. This is just "if(current_time < stop_time) goto step 2".
Step 6: Update the world with the final state of everything. This is mostly the reverse of step 1 - setting quantities in "storage vessels", marking resources as depleted, etc.
Notes:
You might need to add "transport" as a type of node. For example, if you have conveyor belts taking water from the well to the splitter then that can be simulated like a "storage vessel" but with lag time (e.g. if belt was empty and items start being put on the belt, then it's going to take "length * speed" time before items arrive at the other end).
If you want; you could add "breakdown" to the game (e.g. maybe there's a small chance that a splitter malfunctions and needs to be repaired). This is just an extra thing to take into account at step 3.
Don't forget that you can modify the game design to make it easier. For a start, I would avoid feedback loops (e.g. if the fuel from the reactor is fed into a generator to create power that is consumed by a splitter that ...) because this makes everything significantly harder. I'd also be tempted to avoid "variable speed" things (e.g. miners travelling between an ore field and a drop off point, where the distance the miners travel increases as closer parts of the ore field are consumed so the "average ore per tick" is increasing and never constant).
Don't forget that it's a game - it doesn't have to be 100% perfectly accurate, and only needs to be convincing enough to fool the player. If it's "slightly wrong" (e.g. an output buffer should have 23 items but only has 21 itmes) it's likely that nobody will ever notice.
Depending on other details; you might (or might not) consider stopping early and switching to "simulate one tick at a time". For example, if you need to simulate 12345600 ticks, then you could use the approach I've described for the first 12345500 ticks, then use the approach you already have to do the last 100 ticks. This can help to make some things (e.g. position of items on a conveyor belt) seem a lot more realistic.

Action Script 3. How to prevent lag bugs issues in flash games?

How to prevent lag bugs issues in flash games? For example If game have countdown timer 1 minute and player have to catch that much items that possible.
Here are following lag bugs issues:
If items moving (don't have static position) - that higher lag player
have, that slower items move;
Timer starting count slowly when player have lags (CPU usage 90-100%).
So for example If player without lags can get 100 points, player with slow / bad computer can get 4-6x more, like 400-600.
I think that because It's on client side, but how to move It to server side? Should I insert (and update) countdown time to database? But how to update It on every millisecond?
And how about items position solution? If player have big lags, items moving very very slowly, so easy to click on that, have you any ideas?
Moving the functionality to the server side doesn't solve the problem.
Now if there are many players connected to the server, the server will lag and give those players more time to react.
To make your logic independent from lag, do not base it on the screen update.
Because this assumes a constant time between screen updates (or frames)
Instead, make your logic based on the actual time that passed between frames.
Use getTimer to measure how much time passed between the current and the last frame.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/package.html
Of course, your logic should include calculations for what happens in between frames.
In order to mostly fix speed issues on the client you need to make all your speed related code based on actual time, not frames. For example:
Here is a fairly typical example code used to move an object based on frames:
// speed = pixels per frame
var xSpeed:Number = 5;
var ySpeed:Number = 5;
addEventListener(Event.ENTER_FRAME, update);
function update(e:Event):void {
player.x += xSpeed;
player.y += ySpeed;
}
While this code is simple and good enough for a single client, it is very dependent on the frame rate, and as you know the frame rate is very "elastic" and actual frame rate is heavily influenced by the client CPU speed.
Instead, here is an example where the movement is based on actual elapsed time:
// speed = pixels per second
var xSpeed:Number = 5 * stage.frameRate;
var ySpeed:Number = 5 * stage.frameRate;
var lastTime:int = getTimer();
addEventListener(Event.ENTER_FRAME, update);
function update(e:Event):void {
var currentTime:int = getTimer();
var elapsedSeconds:Number = (currentTime - lastTime) / 1000;
player.x += xSpeed * elapsedSeconds;
player.y += ySpeed * elapsedSeconds;
lastTime = currentTime;
}
The crucial part here is that the current time is tracked using getTimer(), and each update moves the player based on the actual elapsed time, not a fixed amount. I set the xSpeed and ySpeed to 5 * stage.frameRate to illustrate how it can be equivelent to the other example, but you don't have to do it that way. The end result is that the second example would have consistent speed of movement regardless of the actual frame rate.

measuring time between two rising edges in beaglebone

I am reading sensor output as square wave(0-5 volt) via oscilloscope. Now I want to measure frequency of one period with Beaglebone. So I should measure the time between two rising edges. However, I don't have any experience with working Beaglebone. Can you give some advices or sample codes about measuring time between rising edges?
How deterministic do you need this to be? If you can tolerate some inaccuracy, you can probably do it on the main Linux OS; if you want to be fancy pants, this seems like a potential use case for the BBB's PRU's (which I unfortunately haven't used so take this with substantial amounts of salt). I would expect you'd be able to write PRU code that just sits with an infinite outerloop and then inside that loop, start looping until it sees the pin shows 0, then starts looping until the pin shows 1 (this is the first rising edge), then starts counting until either the pin shows 0 again (this would then be the falling edge) or another loop to the next rising edge... either way, you could take the counter value and you should be able to directly convert that into time (the PRU is states as having fixed frequency for each instruction, and is a 200Mhz (50ns/instruction). Assuming your loop is something like
#starting with pin low
inner loop 1:
registerX = loadPin
increment counter
jump if zero registerX to inner loop 1
# pin is now high
inner loop 2:
registerX = loadPin
increment counter
jump if one registerX to inner loop 2
# pin is now low again
That should take 3 instructions per counter increment, so you can get the time as 3 * counter * 50 ns.
As suggested by Foon in his answer, the PRUs are a good fit for this task (although depending on your requirements it may be fine to use the ARM processor and standard GPIO). Please note that (as far as I know) both the regular GPIOs and the PRU inputs are based on 3.3V logic, and connecting a 5V signal might fry your board! You will need an additional component or circuit to convert from 5V to 3.3V.
I've written a basic example that measures timing between rising edges on the header pin P8.15 for my own purpose of measuring an engine's rpm. If you decide to use it, you should check the timing results against a known reference. It's about right but I haven't checked it carefully at all. It is implemented using PRU assembly and uses the pypruss python module to simplify interfacing.

Comparing a saved movement with other movement with Kinect

I need to develop an application where a user (physiotherapist) will perform a movement in front of the Kinect, I'll write the data movement in the database and then the patient will try to imitate this motion. The system will calculate the similarity between the movement recorded and executed.
My first idea is, during recording (each 5 second, by example), to store the position (x, y, z) of the points and then compare them in the execution time(by patient).
I know that this approach is too simple, because I imagine that in people of different sizes the skeleton is recognized differently, so the comparison is not reliable.
My question is about the best way to compare a saved motion with a movement executed (on the fly).
I have done this, where a doctors frame is projected onto the patients frame, but with the whole skeleton this doesn't work so well because of different bone heights :/. The code can be found here. It is in beta 2 code, the more current version can be found here, although it is not currently working perfectly
As for comparing, do something like this
for (int i = 0; i < patientList.Count; i++)
{
int diff = (int)Math.Abs(patientList[i] - doctorList[i]);
if (diff < 100) //or whatever number you want
{
Debug.WriteLine("Good Job");
}
}
I have abandoned the idea of a whole figure because of the bone heights mentioned by Fixus, so my current program looks some thing like:
EDIT
This is the concept of camparing two movements with kinect and calculate a similarity between the two movements I explain in depth.
Suppose I have the following 2 points, point A (0, 0, 0) and point B (1, 1, 1). Now I want to find the difference from point A to B, so I would subtract all of the X, Y, and Z numbers, so the difference is 1 X 1 Y 1 Z. That is the simple stuff. Now to implement it. The code I have written above, I would implement like this.
//get patient hand coordinates
double patienthandX = Canvas.GetLeft(patienthand);
double patienthandY = Canvas.GetTop(patienthand);
//get doctor hand coordinates
double doctorhandX = Canvas.GetLeft(doctorhand);
double doctorhandY = Canvas.GetTop(doctorhand);
//compare difference for each x and y
//take Absolute value so that it is positive
double diffhandX = Math.Abs(patienthandX - doctorhandX);
double diffhandY = Math.Abs(patienthandY - doctorhandY);
Now here comes another issue. The doctor coordinates are always the same, but what if the patient isn't standing where the doctor coordinates were recorded? Now we implement more simple math. Take this simple example. suppose I want point A(8, 2) to move to point B(4, 12). You multiply the x and y's of A to get to B. So I would multiply the X by .5, and the Y by 6. So for Kinect, I would put a element on the patients hip, then compare this to the doctors hip. Then multiply all of the doctor joints by that number to achieve the doctor joints on top of the patients (more or less). For example
double whatToMultiplyX = (double) doctorhipX / patienthipX;
double whatToMultiplyY = (double) doctorhipY / patienthipY;
This is all pretty simple, but bringing it together is the harder part. So far we, 1) Scale the doctor frames on top of the patient frames, 2) Calculate the difference. 3) Compare the difference throughout the entire rep. and 4) Reset for the next rep. This seems simple but it is not. To calculate the entire difference for the rep, do something like this:
//get patient hand coordinates
double patienthandX = Canvas.GetLeft(patienthand);
double patienthandY = Canvas.GetTop(patienthand);
//get doctor hand coordinates
double doctorhandX = Canvas.GetLeft(doctorhand);
double doctorhandY = Canvas.GetTop(doctorhand);
//compare difference for each x and y
//take Absolute value so that it is positive
double diffhandX = Math.Abs(patienthandX - doctorhandX);
double diffhandY = Math.Abs(patienthandY - doctrorhandY);
//+= so that it keeps adding to it.
totaldiffhandX += diffhandX;
totaldiffhandY += diffhandY;
Now we can compare, and say:
if (totaldiffhandX < 1000 && totaldiffhandY < 1000) //keep numbers pretty high since it is an entire rep
{
//reset difference
totaldiffhandX = 0;
totaldiffhandY = 0;
//tell the patient good job
Debug.WriteLine("Good Job");
}
This is pretty easy, but keep in mind you must do this for every single joint's x and y. Otherwise it will not work. Hope this Helps.
First of all remember that people are diffrent. Every person has diffrent height, width, weight, diffrent bones length etc etc
You`re code probably will never work cause of this.
Secondly you need to think more geometrically. Don`t think about points only, think with vectors, their directions. Each movement is movent of some vectors in some directions.
Then the proportion. You need to configure application for each user.
You have some pattern. The patter is your physiotherapist. You need to remember not only his movements but also his body. Arm length, leg length, distances etc. Each user that will be using your app also need to me mesured. Having all this data you can compare movement by scaling sizes and comparing directions of movent
Of course remember that there are some very simple moves like for example. They can be recognized by simple mathematic by checking actual position of the hand and checking direction of the movement. You need for this 3 control points and you`re at home :)
Gesture recognizing isn`t a simple thing