Projectile Prediction

tjthejuggler's icon

Hey people, I am trying to build a program that converts the position of a peak of a thrown ball into a sound file. Since the ball will only be at its peak for a fraction of second I cannot rely on the camera being able to know when it is there, so my plan is to predict when/where the ball will peak before it gets there and then have the appropriate sound file played when it gets there.

Does anyone know if this would be possible with max/msp/jitter? any help would be greatly appreciated. Thanks!

Roman Thilenius's icon

a thrown ball describes a parabola.

if you have velocity and angle, cos() and sin() is all you need to find the peak point.

dont know exactly, but google will tell you in a minute.

Roman Thilenius's icon

to correct myself: depending on what you got, the gravity constant is also needed. :)

Roman Thilenius's icon

$f1 = speed in km/s, $f2 = angle in degree.

time after which it reaches the highest point:

[expr ($f1*sin($f2))/0.00981*0.00981]

so max height of the ball:

[expr ($f1*sin($f2)) * (($f1*sin($f2))/0.00981*0.00981) - ( ((0.00981*0.00981) * ((($f1*sin($f2))/0.00981*0.00981)*(($f1*sin($f2))/0.00981*0.00981))) /2.)]

untested & probably wrong.

-110

tjthejuggler's icon

Thanks Roman. I appreciate the physics, but what I am wondering is whether or not it is possible to use MAX to get the speed and angle variables in real-time before the peak occurs. But just going off the fact that you skipped right over that and went to the physics of it, I am guessing that getting the variables(via a live camera) with MAX would be trivial. Do you know if this is the case?

It seems like it is, since all I need is 2 frames(and the amount of time b/w frames) to get the speed and angle, but i want to be sure before i start trying to tackle another language.

Thanks again!

spectro's icon

Assuming the ball *can* be framed in camera with little other movement it may be possible to employ frame differencing to detect when the change between frames is minimal - which is what will happen when the ball approaches its peak in the path. This would be easier than trying to predict the path based on its trajectory.

To that end, you may be able to repurpose something like the 'Hold Still' Jitter recipe by Andrew Benson outlined here https://cycling74.com/tutorials/jitter-recipes-book-3/ or alternatively search for other examples that employ this technique.

Alternately, an embedded accelerometer that transmits its data to a receiving device may be more accurate - but also more technically complex....

Roman Thilenius's icon

It seems like it is, since all I need is 2 frames(and the amount of time b/w frames) to get the speed and angle

yea i think so, too, and that should not be too difficult with jitter.
eventually you have to take the third dimension into account (one camera, two points, he?) when finding the speed.

and i believe that you should use meters and not kilometers per second; speed must be >1 to be able to square it properly:

[expr ($f1*sin($f2)) * (($f1*sin($f2))/9.81*9.81) - ( ((9.81*9.81) * ((($f1*sin($f2))/9.81*9.81)*(($f1*sin($f2))/9.81*9.81))) /2.)]

-110

Peter McCulloch's icon

My gut instinct is that you're going to have a hard time calculating this accurately, since you have to capture not only the velocity but the angle of it in multiple dimensions. A few degrees off (highly likely since it's being thrown) and values change dramatically, and the ball isn't going to have a lot of sample points (pixels) to make a comparison from, plus you have to judge this from a center point.

I'm assuming this is more of a low-velocity thing?

Some things to try:
A high contrast background with the ball; green screen would be great, but you could probably get by with something that's consistent and different enough from the ball. Try a bounding box algorithm, and look at delta Y. When it zeros out or flips sign, you're at the peak. (limited by the frame-rate of course)

You might experiment with a Wiimote and see what tossing it looks like in terms of its accelerometers. (it will be noisy, but there are way of smoothing it out, you're looking for a reversal of the angle in three dimensional space more or less) If that works well, you could see about a hardware-based solution.

tjthejuggler's icon

Using an accelerometer has been recomended to me before, however the problem with it would be that it would only be able to give me a peak height, not a peak x,y coordinate. I need more than just a height because i want to be able to have a full grid of sounds.

I do, however, have a kinect camera which may be useful for its depth finder.

Furthermore, I have found this and I have spoken with Joe Marshall(the guy who made it) briefly. He said his code is pretty complex, but recomended I use Processing to do what i want. So right now i am researching both max and processing.

>>A high contrast background with the ball

I am using balls with LEDs in them in a room with the lights off so my ball/background contrast situation is ideal.

>>>I’m assuming this is more of a low-velocity thing?

Ideally, with a hardware setup it would be as high/fast as i want to throw, but since i am just going for video tracking right now, I am not really going to shoot for more than about 4 feet over my head.

Thanks for all the help!

Roman Thilenius's icon

resolution and contrast are important, but gthre is another trick.

you could measure velocity and angle from several points at the jitter motion detection point and take the average of these values. this will introduce a tendency of higher accuracy which is limiting the inaccuracy of measurement and resolution.

the higher the resolution of the jitter part and the better the camera measurement (in best case 2 cameras to control start and end point of measurement, each looking at the balls flight from 90°), the shorter is the distance required to measure to get good results.

say if you throw a ball like 10 meters high and 20 meters far, it should be enough to measure its height with 2 cameras at 1 meter (after it leaves the hand) and 2,50, and then use the above expression (unless it contains errors, which is likely. but thats what the code should do, it should require camera 1 XY and camera 2 XY plus the time from y1 to y2 (the distance between the cameras) and then you feed velocity and angle into it to receive the max height of the future flight)

-110

-110

Peter McCulloch's icon

Have you tried the bounding box solution? (jit.findbounds)

If you can assume that your throw is perpendicular to the camera's center line, your calculations get a lot simpler. Not sure how flexible your setup needs to be, but it might be worth it to solve the orthogonal 2d case first.

To piggyback on what Roman said, you can use zl.stream to generate a series of the last n values. Instead of averaging, you might try a median filter (zl.median), since it's less affected by outliers.