Inconsistencies in .csv path following (success and errors)

I have been working on a program which reads a path from a .csv file and uses path blending to move the robot arm along that path. I am basically getting the arm to draw pictures on a whiteboard and giving it the trajectories in a .csv. The results of this program are very inconsistent. When I first turn on the computer and run it, it works perfectly with no errors. However, after a few times of running it, I suddenly get the same error over and over again no matter what I do. I have tried finding and deleting troublesome points from the csv file, jogging in between runs, reloading the file, etc. I don’t want to have to reboot the control computer every time I want to repeat this program. Here is my .csv file and a pdf of my code .
b.csv (3.1 KB)
drawfromcsv.pdf (117.7 KB)

This is the error I get:

Blockquote
Error executing program: file “drawfromcsv.py” line 59:
AttributeError:‘MoveItErrorCodes’ object has no attribute ‘error_message’
Traceback: (most recent call last):
File “”, line 1, in
File “/home/pathpilot/nc_files/robot_programs/drawfromcsv.py”, line 65, in main
start()
File “/home/pathpilot/nc_files/robot_programs/drawfromcsv.py”, line 59, in main
sync()
AttributeError:‘MoveItErrorCodes’ object has no attribute ‘error_message’

When I switch the log level to debug, I get some additional info messages saying:

Blockquote
joining velocity or acceleration limit violated and below minimum scaling factor
Info: Program errored, full traceback:
File “/opt/ros/noetic/lib/python3/dist-packages/robot_command/program_interpreter/interpreter.py”, line 483, in worker
process._churn_and_check_pause()
File “/opt/ros/noetic/lib/python3/dist-packages/robot_command/program_interpreter/interpreter.py”, line 722, in _churn_and_check_pause
self._command_switch.get(command.command, lambda data: None)(
File “/opt/ros/noetic/lib/python3/dist-packages/robot_command/program_interpreter/interpreter.py”, line 420, in
InterpreterCommand.Start: lambda data: self._fsm.start(data=data),
File “/usr/local/lib/python3.8/dist-packages/fysom/init.py”, line 315, in fn
self.transition()
File “/usr/local/lib/python3.8/dist-packages/fysom/init.py”, line 310, in _tran
self._after_event(e)
File “/usr/local/lib/python3.8/dist-packages/fysom/init.py”, line 342, in _after_event
return getattr(self, fnname)(e)
File “/opt/ros/noetic/lib/python3/dist-packages/robot_command/program_interpreter/interpreter.py”, line 697, in _start_program
exec(f’‘‘while True: {name}()\n’’', namespace)
File “”, line 1, in
File “/home/pathpilot/nc_files/robot_programs/drawfromcsv.py”, line 65, in main
start()
File “/home/pathpilot/nc_files/robot_programs/drawfromcsv.py”, line 59, in start
sync()
File “/opt/ros/noetic/lib/python3/dist-packages/robot_command/rpl/command.py”, line 189, in run_command
self._execute_async_commands()
File “/opt/ros/noetic/lib/python3/dist-packages/robot_command/rpl/command.py”, line 167, in _execute_async_commands
result = cmd.execute()
File “/opt/ros/noetic/lib/python3/dist-packages/robot_command/rpl/command.py”, line 78, in execute
result.append(self.commands[-1].execute(data, last=True))
File “/opt/ros/noetic/lib/python3/dist-packages/robot_command/execution_commands/movel.py”, line 147, in execute
plan = self._plan_sequence(sequence)
File “/opt/ros/noetic/lib/python3/dist-packages/robot_command/execution_commands/move_commands.py”, line 397, in _plan_sequence
self._handle_planning_error_context(error_details, planning_time)
File “/opt/ros/noetic/lib/python3/dist-packages/robot_command/execution_commands/move_commands.py”, line 84, in _handle_planning_error_context
message = f"Planning move failed after {planning_time:.3f}s: {error_details.error_message}"

Have you made any progress on this?

Based on my limited knowledge (i.e. a week of hands-on experimenting with the ZA6), the TRPL move commands are pretty fragile. It’s relatively easy to find move operations that throw an error.

I wonder if someone from Tormach could talk a bit about this? I took a brief look today but couldn’t find the actual implementation of movej.

I have not made any more progress so far, it is still being pretty inconsistent in how it runs. I’m hoping that if I work on accessing the ROS API to run my code instead that I may have better results, will update if I figure anything out.

Dear @Alex_Janis,

Thank you for reporting the motion planning issue with the multi-segment move. I’ve reviewed your logs and believe I can help identify the root cause. I think it appears to be related to a near-singularity pose in your robot configuration, but more tests are required.

Current Investigation Status: I’ve successfully tested your program in simulation with the following frame parameters:

svg_frame = [300, 0, 200, 0, 0, 0]
tool_1 = [0, 0, 0, 180, 0, 0]

The program has been running without errors for approximately 10 minutes in simulation mode (without ZA6 hardware). I’ve tested several path blending variations, all of which executed successfully:

  • set_path_blending(True, 0.0)
  • set_path_blending(True, 0.001)
  • set_path_blending(True, 1.0)

Note that according to the TRPL documentation, the blending parameter is expressed in meters. I think it might actually be converted to your active linear units, but I need to check this.

To help diagnose your issue, I need the following information:

  1. Your active user_frame and tool_frame parameters from the Frames tab
  2. Your PathPilot Robot version
  3. Whether you experience the same error in simulation mode
  4. The specific segment ID from your .csv file where the failure occurs
  5. The joint values when the program operates correctly, particularly focusing on J5 values. Have you noticed J5 near 0 degrees during this program execution?

Important Context: A near-wrist-singularity pose occurs when J5 joint value approaches 0 degrees. This condition can significantly impact motion planning and overall robot performance.

Recommended Troubleshooting Steps:

  1. Try running the program with different blending parameters
  2. Try running the program with slower velocity values for movel moves
  3. Test the program in simulation mode using both your configuration and my frame presets
  4. Experiment with slight translations of your user frame to see if you can reproduce or resolve the error, moving your user_frame will change the J5 values at each point you reach in the 3D space.
  5. Consider using a tool_frame with your drawing tool that is rotated wirth respect to robot red flange such that when the pen is above the desired drawing surface, J5 is always far away from the singularity.
  6. Monitor joint values throughout the program execution, paying special attention to positions where the robot performs well

The singularity issue can be particularly challenging when trying to maintain smooth robot motion while keeping the motion plan within desired tolerances. Once you provide the requested information, I can offer more specific guidance for your setup.

Please let me know if you need any clarification or have additional questions. Thank you for your patience.

1 Like

I’d like to add a little more information to this thread.
I’m not surprised to find out that a program that commands moves near a singularity succeeds sometimes and fails other times. I’ve observed this behavior (with a similar amount of frustration) before. It’s most common during either moves that pass through or very close to a singularity, or during large linear moves. Moves involving movej() that don’t go through singularities don’t have issues.

ROS is great at many things, one of them being its ability to dynamically plan around a changing collision scene. As such, ROS by default re-plans trajectories every time you press cycle start. You might think that, if it successfully planned a trajectory once, it would do the same thing again the next time, but it’s not a caching planner. It has no knowledge of what happened before. This is the way ROS works - great for autonomous mobile robotics, but less great for an industrial manipulator.
We discussed implementing a trajectory caching mechanism, but instead chose to achieve determinism by allowing customers to specify the arm configuration of the goal pose.

I have two recommendations:

  1. Try to kinematically arrange your robot and work area to avoid the singularity (likely a wrist singularity).
  2. Unless you need a linear move, stick to movej(). When we’ve done machine tending, welding, etc., we always use movej() and joints-type waypoints for the macro positioning, switching to movej() to a cartesian pose only when we need to offset to a local coordinate system (e.g. the vise in the milling machine) and movel() only when we need to move in a straight line (e.g. when picking or placing the workpiece, and only for the last 50cm of motion).
  3. movej() to a cartesian pose can be non-deterministic (there are multiple different robot poses that result in the same tool control point and orientation). If your movej() to a cartesian pose-type waypoint is a large move command (displaces more than a few centimeters, try constraining it further with the NUT/FUT/etc. arm configuration.

Best of luck with the programming and please keep posting these questions so we can help you with your implementations and so we know where to focus our efforts. Thanks!

1 Like