Projectile in Rotating Reference Frame: Part 2

1 likes

Previously I mentioned the two potential pathways for my simulation.

  1. Spinninig the frame and use Opencv to detect the position of the ball
  2. Calculate the position of the ball based on the theory and change the ball's position frame by frame

See the Pen XWjLqpE by steven oh (@stevenohohohohoh) on CodePen.


I have updated the simulation. I added on-page buttons and input fields where I can directly change the parameters of the simulation. Respectively, "degree per frame", "x-force" and "y-force". Degree per frame is the speed of the rotation, and x, y forces just force vectors that push the ball. I also added the screen-recording function which records the screen as the button is pressed, and stops as the "stop" button is pressed. The video is then automatically downloaded.

Recording the animation

async function startRecording() {
  stream = await navigator.mediaDevices.getDisplayMedia({
    video: { mediaSource: "screen" },
  });
  recorder = new MediaRecorder(stream);

  const chunks = [];
  recorder.ondataavailable = (e) => chunks.push(e.data);
  recorder.onstop = (e) => {
    const completeBlob = new Blob(chunks, { type: chunks[0].type });
    setVideo(completeBlob);
  };

  recorder.start();
}

function download(blob_url) {
  var fileName = "video.mp4";
  var a = document.createElement("a");
  a.href = blob_url;
  a.download = fileName;
  a.textContent = "DOWNLOAD " + fileName;
  
  document.getElementById("download").appendChild(a);
  a.click();
}

The screen-recording function saves the video into a Blob. For people like me who don't know what a Blob is

A Blob is an opaque reference to, or handle for, a chunk of data. The name comes from SQL databases, where it means “Binary Large Object.” In JavaScript, Blobs often represent binary data, and they can be large, but neither is required: a Blob could also represent the contents of a small text file.

Opencv reading the coordinates

import cv2
import numpy as np
import csv
import pandas as pd

# Open the video
cap = cv2.VideoCapture('video-5.mp4')
x_c = []
y_c = []
circles_all = []
i = 0

while True:
    success, new_frame = cap.read()
    # Take each frame
    if success:
        i += 1
        frame = new_frame
        crop_img = frame[200:2000, 600:2500].copy()
        gray = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY)
        circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1.5, minDist=505, param1=75, param2=30, minRadius=8,maxRadius=30)
        # ensure at least some circles were found
        if circles is not None:
            # convert the (x, y) coordinates and radius of the circles to integers
            circles = np.round(circles[0, :]).astype("int")
            # loop over the (x, y) coordinates and radius of the circles
            for x, y, r in circles:
                print(x, y)
                x_c.append(x)
                y_c.append(y)
                circles_all.append([x, y, r])
                # draw the circle in the output image, then draw a rectangle
                # corresponding to the center of the circle
                cv2.circle(crop_img, (x, y), r, (0, 255, 0), 4)
                cv2.rectangle(crop_img, (x - 5, y - 5),
                              (x + 5, y + 5), (0, 128, 255), -1)

        #cv2.imshow('hi', crop_img)
        #cv2.waitKey(0)
    else:
        crop_img = frame[200:2000, 600:2500].copy()
        for (x, y, r) in circles_all:
            # draw the circle in the output image, then draw a rectangle
            # corresponding to the center of the circle
            cv2.circle(crop_img, (x, y), 7, (255, 0, 0), -1)
            #cv2.rectangle(crop_img, (x - 5, y - 5),(x + 5, y + 5), (0, 128, 255), -1)
        
        cv2.imwrite('lastframe.jpg', crop_img)
        break

print("Number of captured frames: ", i)
print("The length of list is: ", len(circles_all)) 
cv2.destroyAllWindows()
df = pd.DataFrame({ "x" : np.array(x_c), "y" : np.array(y_c)})
df.to_csv("coord.csv", index=False)

The screen recording records the whole screen, including the toolbar and tabs in the browser - this can be confusing for an Opencv program. Therefore, for each frame, I cropped the frame so only the rotating circle and the ball is left. Then, I used

 HoughCircles
function to search for a circle with the specified parameters like min and max radius, the minimum distance between the center of this circle to another circle.etc. Gotta give credit to soysoy444 this time, he helped me debug and it was super helpful. Anyways, this program returns the x positions and y positions of the ball for each frame, and I was able to save it in a CSV file.

I recorded a random example (I made the ball go in a circle) and graphed the x and y positions of the ball with respect to time.

y-position of the ball and x-position of the ball


I also recorded a projectile in a non-inertial frame. Since the coordinate system in Opencv is like the 4th quadrant in the Cartesian plane but with positive y-values, I also attached an image of the position graph with the correct Cartesian coordinates(in the 4th quadrant)

Now that I can collect data for the experiment, my next target will be to first fine-tune my data-collecting process and then begin researching more about the theory.


Leave a Comment
/200 Characters