I'm trying to model the motion of a robotic arm in Python. I want it to start from an initial position of 0 degrees and initial velocity of 0 deg/sec. It has a constant acceleration of 0.5 deg/sec**2 and a max velocity of 3 deg/sec. For now I am assuming that the arm moves in a straight line. The resulting graph of time vs velocity should look like a trapezoid: a positive diagonal line accelerating up to a max velocity, a straight line at max velocity, and then a negative diagonal line decelerating back down to zero.
What I want to do is enter a degree value so I can find the time it takes to reach max velocity, the time when it begins decelerating, and the time when it reaches the degree value I entered. If the degree value is small enough, then the graph will not have a straight line because the arm did not reach max velocity.
Here is the script I've built so far.
import numpy as np
import matplotlib.pyplot as plt
u = 0 #initial velocity
a = 0.5 #acceleration
vf = 3 #max velocity
max_t = (vf - u)/a #time to reach max velocity at constant a
t = np.linspace(0, max_t)
v1 = []
v2 = []
v3 = []
for i in t:
v1.append(u + a*i)
v3.append(vf*i)
v2.append(vf - a*i)
plt.plot(t, v1)
plt.plot(t, v2)
plt.plot(t, v3)
plt.grid()
I can't figure out how to insert a v3 array into the graph that represents a constant velocity. The array would have to be conditional. If the degree value requires more time than 2max_t, then a third v3 array would be inserted between the v1 and v2 arrays. On the other hand, if the degree value requires less time than 2max_t, max velocity will not be reached and the graph will look more like a pyramid.
I realize that I need some code for the degree measurement, which will then define the time array. Unfortunately, I keep going in circles trying to interpolate a time array from a position array, because the two seem to be dependent on each other.
If I'm on the right track, then where do I go from here? If I'm way off base, what am I doing wrong and what can I do to fix it?
Edit:
I kind of started again from scratch, though I gleaned information from my previous script to build a new one. I made three sets of three arrays. Each set is composed of a position array, a velocity array, and a time array. Sets 1 and 2 feature the acceleration and deceleration, respectively, of the robotic arm. The desired slew position is the variable m. That value is divided by 2 (n = m/2) for the first and second arrays. The resulting plot looks like a pyramid.
So that part works just fine. However, if n is greater than the critical value z, then the final position array p2 overshoots by a certain amount. For example, using the values in the script below, n is greater than z by about 1.1.
I've tried adding and subtracting different position slices in all three arrays, but I still can't figure out how to get rid of that annoying overshoot. Here is the script.
import matplotlib.pyplot as plt
import numpy as np
u = 0 #initial velocity
a = 0.41 #acceleration
vf = 2.3 #max velocity
m = 15 #desired slew poistion
n = m/2 #divides the position between two array to allow for
#acceleration and deceleration
#results in a position overshoot if n > z
z = 6.45121951 #critical; the robotic arm reaches max velocity at this position
max_t = (vf - u)/a #time required to reach max velocity
p1 = np.linspace(0, n) #position array; acceration from u
s = 0
p = 0
if n > z:
s = n
p = n + (n - z)
p3 = np.linspace(s, p) #position array; constant velocity
if n <= z:
b = n
c = 2*n
if n > z:
b = p
c = p + n
p2 = np.linspace(b, c - (n - z)) # position array; deceleration to 0
v1 = np.linspace(0, vf) #velocity array; increasing from u toward vf
v2 = np.linspace(vf, 0) #velocity array; drecreasing from vf to 0
d = 0
e = 0
if n > z:
d = vf
e = vf
v3 = np.linspace(d, e) #velocity array; constant velocity
t1 = np.linspace(0, max_t) #time array; time required to reach max_t
f = 0
g = 0
h = max_t
j = 2*max_t
if n > z:
f = max_t
g = max_t + p3[-1]/v3[-1]
h = max_t + p3[-1]/v3[-1]
j = 2*max_t + p3[-1]/v3[-1]
t3 = np.linspace(f, g) #time array; time spent at constant velocity
t2 = np.linspace(h, j) #time array; time required to reach 0 from max_t
plt.figure(0)
plt.plot(p1, v1, color='b', label='Array 1')
plt.plot(p2, v2, color='r', label='Array 2')
plt.plot(p3, v3, color='g', label='Array 3')
plt.xlabel('Position')
plt.ylabel('Velocity')
plt.legend()
plt.grid()
Any help would be greatly appreciated. Thanks.