Closed ShubhamNandi closed 4 months ago
Hello,
thank you for the example. I would need a little more information on the following:
Depending on these information the delay might be expected. Here are some reasons:
Probably there are more options..
Hi @EvilEli
THE SCENARIO: We are trying to actuate 3 motors driven by 3 Indvidual festo drivers for a robotic arm. we have a ROS system that is generating a set of points with velocity (trajectory) for the movement of the arm.
Observations: so far we have observed that the api function position_task()
when send a point to execute to the driver, the driver internally accelerates and then decelerates per point. Since this is happening per point, after one point the motor tends to go to zero velocity and then for the next point it accelerates back. We have concluded that this is the reason why the jitter is visible.
What we are trying to achieve is that we want to update point on the fly i.e. send continuous points so that the trajectory is executed properly.
Any inputs on this would be of help
Thank you :)
Given this information I assume the problem lays in the wait_for_completion()
part.
By issuing a position task the drive calculates the complete trajectory from the starting point to the ending point (with resulting speed of zero) using the parametrized acc/dec and velocity limits.
That means the wait_for_completion()
task will return as soon as the drives have all reached (or almost reached) velocity zero.
However, it is possible to "update" ongoing position tasks when using configure_continuous_update(True)
which you are already doing. You should just be able to overwrite with a new position_task.
I guess you'll need to skip the wait_for_completion()
part and determine the point when to issue the next position task in a different manner.
@EvilEli
I was under the same assumption that using configure_continuous_update(True)
should do the job. Below is an example for the same, but still the jitter exists also after checking the velocity curve from the moto, it is seen that the motor tends to zero after every point.
def motor_set_values(positions, velocities):
motor1.position_task(scale_up_pos(positions[0]), scale_up_vel(velocities[0]),absolute=True, nonblocking=True)
motor2.position_task(scale_up_pos(positions[1]), scale_up_vel(velocities[1]),absolute=True, nonblocking=True)
motor3.position_task(scale_up_pos(positions[2]), scale_up_vel(velocities[2]),absolute=True, nonblocking=True)
# Callback for the trajectory points
def trajectory_callback(data):
num_traj_points = len(data.result.planned_trajectory.joint_trajectory.points)
print("Number of points in trajectory: ", num_traj_points)
if num_traj_points == 0:
print("No points in trajectory")
return
for i in range(num_traj_points):
if i == 0:
continue
if i == num_traj_points - 1:
break
print("Point ", i, " : ", data.result.planned_trajectory.joint_trajectory.points[i].positions)
print("Velocities: ", data.result.planned_trajectory.joint_trajectory.points[i].velocities)
motor_set_values(data.result.planned_trajectory.joint_trajectory.points[i].positions, data.result.planned_trajectory.joint_trajectory.points[i].velocities)
sleep_time = data.result.planned_trajectory.joint_trajectory.points[i+1].time_from_start - data.result.planned_trajectory.joint_trajectory.points[i].time_from_start
rospy.sleep(sleep_time.to_sec() * 0.5 )
print("Point ", i, " reached")
print("#"*50)
print("Trajectory completed")
print("#"*50)
This code is running based on time and trying to update the points on the fly but still no visible changes observed
Just for me to clarify: Does the motor velocity tend to zero before or after a new position_task has been started?
Just for me to clarify: Does the motor velocity tend to zero before or after a new position_task has been started?
Before the new position like it ends the previous position with vel tending to zero then gets it up once the new position task is received
Alright. This suggests to me that the drive behaves as I would expect. A position task is a complete point-to-point motion. That means given the target position it calculates a trajectory to arrive at that position (while satisfying velocity, acceleration and jerk constraints) with a resulting velocity 0 at arrival time. As a result your drive will at some point prior to arrival start to decelerate in order to arrive at the target position with velocity 0. You have a few options to overcome this with your time based approach:
1. Put the target position behind your actual target:
The point must be further away than the distance travelled during the deceleration phase.
3. Use velocity task instead to avoid the deceleration ramp at all:
Be aware that the drive only registers an updated velocity when the absolute value of the velocity changes.
See example velocity_nonblock.py for reference.
Okay will try this! but this seems like no so reliable workaround, any other method that you can suggest ?
Another option I could think of would involve changing the telegram (i.e. switch from point-to-point to velocity mode). If you want to avoid positioning trajectories to be used, you might probably go for a velocity telegram (i.e. telegram 1 or telegram 102). You can find an example here: https://github.com/Festo-se/festo-edcon/blob/main/src/edcon/cli/tg1.py
Also make sure to configure the correct telegram in the drive.
Trying to send consecutive positions via the 'position_task' but there is gitter/delay while going from one point to the other
Here is a Sample Code for further clarification