Reputation: 31
I want my "Follow Coordinates System (FCS)" to reach the position of a "Set Coordinates System (SCS)" while maintaining a trapezoidal velocity profile using given parameters like limited velocity and acceleration. However, I am encountering issues such as fluctuations in the velocity and missing the target position, possibly due to precision errors. Despite testing various solutions, I have not been able to achieve consistently positive results.
linear_distance < 1e-3
), the SCS is moved randomly to a new position... For now, but
in the future, I want SCS to move randomly and unpredictably at any moment, without waiting for the FCS to reach it.for step in range(cycles):
axis_distance = np.array(current_scs[:3]) - np.array(current_fcs[:3])
linear_distance = np.linalg.norm(axis_distance)
breaking_distance = (linear_velocity[-1]**2) / (2 * max_deceleration)
# Acceleration or constant velocity phase
if linear_distance > breaking_distance:
if np.abs(max_velocity - linear_velocity[-1]) > max_acceleration * cycle_time: # Preventing overshooting max_velocity
linear_velocity.append(linear_velocity[-1] + max_acceleration * cycle_time)
else:
linear_velocity.append(max_velocity)
# Deceleration phase
else:
if linear_velocity[-1] > max_deceleration * cycle_time: # Preventing overshooting 0
linear_velocity.append(linear_velocity[-1] - max_deceleration * cycle_time)
else:
linear_velocity.append(0)
linear_acceleration.append((linear_velocity[-1] - linear_velocity[-2]) / cycle_time)
for i in range(3):
factor = axis_distance[i] / linear_distance if linear_distance != 0 else 0
new_axis_velocity = linear_velocity[-1] * factor
if velocity[i][-1] < new_axis_velocity:
velocity[i].append(velocity[i][-1] + np.min([max_acceleration * cycle_time, new_axis_velocity - velocity[i][-1]]))
#print(f"{step} accelerating at axis {i}")
elif velocity[i][-1] > new_axis_velocity:
velocity[i].append(velocity[i][-1] - np.min([max_deceleration * cycle_time, velocity[i][-1] - new_axis_velocity]))
#print(f"{step} decelerating at axis {i}")
else:
velocity[i].append(velocity[i][-1])
#print(f"{step} target velocity for axis {i} reached")
acceleration[i].append((velocity[i][-1] - velocity[i][-2]) / cycle_time)
current_fcs[i] += velocity[i][-1] * cycle_time
To track progress, I log the data and display it on graphs. That's why e.g. velocity is array of arrays now. It won't be when I finish. Here's one set of graphs:
As you can see FCS trajectory missed SCS at first, but then it hit and hit again it's next positions with slowing down correctly.
SCS reached at 5574 : linear_distance = 0.0008199809854013105, linear_velocity = 2.7999999999649416
SCS reached at 9163 : linear_distance = 0.0008934633980521272, linear_velocity = 0.7999999999478358
Wrong legend: orange here is linear acceleration!
And here is linear velocity after dividing to XYZ
I could keep trying to fix it, but I’m not sure if this is the right approach in the first place. I lack a background in control theory and motion planning.
I’m looking for feedback and any advice on addressing the issues I'm facing!
Upvotes: 1
Views: 35
Reputation: 21
If you want to do this in fixed time steps you need to take the following into account:
For a moving target some kind of control law is needed. The optimal solution depends on various details of the problem you're trying to solve.
Upvotes: 0