3D Projectile Motion
Skills: MATLAB, Kinematics, trajectory generation
Demo:
Projectile Model:
“A projectile motion is a motion where a ball is fired in the air at an angle and is allowed to moved under the force of gravity”. I woke up one morning and remembered this definition from my physics teacher in secondary school. As an engineering student, I wanted to vizualize it once more using a software tool like Matlab, as these fundamental concepts never dies once you grasp it.
Goal
The goal of this experimentation was to shoot a sperical projectile (ball, stone, etc.) and control it with the help of inputs to achieve a desired location. Then the projectile flies according to the laws of physics and thus accelerated by the force of gravity to the ground.
Inputs:
- Initial Velocity: $v_0$
- Angle from x-y plane: $\theta$
- Angle from x-axis: $\phi$
output
- To graphically visualise the trajectory from start to target point.
Equation of motion:
From the free body diagram above, the equation of motion was evaluated in vector and each component is independent. Therefore they can be written as;
- x-direction: $m\frac{d^2}{dt^2}x(t) = 0$
- y-direction: $m\frac{d^2}{dt^2}y(t) = 0$
- z-direction: $m\frac{d^2}{dt^2}z(t) = -mg_z$
Intergrating twice the above equation yield
- $x(t) = x_0 + v_{x,0}t$
- $y(t) = y_0 + v_{y,0}t$
- $z(t) = z_0 + v_{z,0}t - \frac{1}{2}gt^2$
Once more specifying the initial positions (x_0,y_0,z_0) in order to compute the inital velocity $v_0$,
- $v_{0,x} = v_0cos(\phi)cos(\theta)$
- $v_{0,y} = v_0sin(\phi)cos(\theta)$
- $v_{0,x} = v_0sin(\theta)$
After jumping into Matlab and spending most of the time to visualise, The result was quite satisfactory. The matlab code is displayed below as follows.
Matlab Script:
%% Projectile motion
clc; clear; close;
%% Shooter parameters
params = sys_params; g = params.gravity;
% maximum number of points for simulation
nmax = 80;
% initial conditions
p0 = [0; 0; 0];
phi = -15; % from -90 to 90
theta = 60; % from 0 to 90
v0 = 21;
% desired position
pd = [40; -10; 0];
% time required to hit the ground
tmax = (2*v0*sind(theta))/g;
[t,X] = myFlightModel(phi, theta, p0, v0, tmax, nmax);
%% target circle
% Define the center and radius of the circle
centerX = pd(1); % x-coordinate of the center
centerY = pd(2); % y-coordinate of the center
radius = 5; % radius of the circle
% Generate points along the circumference of the circle
alpha = linspace(0, 2*pi, 100); % Generate 100 points around the circle
x = centerX + radius * cos(alpha);
y = centerY + radius * sin(alpha);
z = zeros(size(x)); % Z-coordinates are all zero for the XY plane
%% Plot
for i=1:nmax
% 3D scatter plot with initial condition
plot3(p0(1), p0(2), p0(3),'.g','markersize',30);
hold on;
% target circle
plot3(x, y, z, 'g','LineWidth',2);
hold on;
% plot trajectory
ball = plot3(X(1,i),X(2,i),X(3,i),'.r','markersize',40);
% draw path
plot3(X(1,:),X(2,:),X(3,:), '.r','markersize',5);
% draw shadow
shadow = plot3(X(1,i),X(2,i),0*X(3,i), '.k', 'markersize',20);
if i >= nmax-1
delete(shadow); % Clear the last 2 plot
end
% draw desired point
% plot3(pd(1), pd(2), pd(3),'.g','markersize',30);
grid on; % Display the grid
% Label the axes
xlabel('X-axis'); ylabel('Y-axis'); zlabel('Z-axis');
% Set the plot title
title('3D Projectile motion');
axis([-15,50,-25,25,0,40])
set(gca,"Clipping","off")
drawnow;
end
%% Projectile function
function [t,X]=myFlightModel(phi, theta, p0, v0, tmax, nmax)
t=linspace(0,tmax,nmax);
%--------------------------------------
params = sys_params; g = params.gravity;
x0 = p0(1); y0 = p0(2); z0 = p0(3);
v_x0 = v0*cosd(theta).*cosd(phi);
v_y0 = v0*cosd(theta).*sind(phi);
v_z0 = v0*sind(theta);
x = x0 + v_x0*t; y = y0 + v_y0*t; z = z0 + v_z0*t - 0.5*g*t.^2;
X=[x;y;z];
% --------------------------------------
end
%% system parameters
function [ params ] = sys_params()
% Physical properties
params.gravity = 9.81;
params.mass = 0.0638;
params.arm_length = 0.086;
% Actuator limits
params.u_min = 0;
params.u_max = 1.2*params.mass*params.gravity;
end