0

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.

cat_herder
  • 51
  • 6
  • My bad. That was a typo. I fixed it. – cat_herder Oct 31 '22 at 15:35
  • "I can't figure out how to insert a v3 array " you already have v3 in the graph `v3.append(vf*i)` `plt.plot(t, v3)` if you want to make it constant do `v3.append(vf)` so it doesn't get multiplied by `i` –  Oct 31 '22 at 15:35
  • I want a conditional statement for the v3 array. If reaching the final position requires more time than the time it takes to reach max velocity, then the v3 array is shoehorned in between v1 and v2. I've tried using an if statement with array slices, but I can't get anything to work. – cat_herder Oct 31 '22 at 15:39
  • if you have tried to use conditionals you should post what you have tried, what result you got and how it is different from the desired result. You posted the initial conditions. For this particular conditions what are the values of v1, v2 and v3 that you expect? –  Oct 31 '22 at 15:41

0 Answers0