Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to clear the cache #122

Open
simeoncapy opened this issue Oct 21, 2024 · 5 comments
Open

How to clear the cache #122

simeoncapy opened this issue Oct 21, 2024 · 5 comments

Comments

@simeoncapy
Copy link

In my code, I get several commands from my controller and then send them to the xArm with the set_position function. However, the commands seem to be added to a cache, making all the processes super slow (even continuing after the script stops).

I couldn't find a function to discard all previous commands before sending a new one. Is there a way to do it?

For the problem with the robot moving after the script stops, I guess I can call the reset function in the destructor.

@penglongxiang
Copy link

hi @simeoncapy, what is your control scenario? set_position is a cached command and it can be cancelled with set_state(4) to make it stop. Are you updating the command at a high frequency? In that case maybe you should consider set_servo_cartesian() in mode 1, which is designed for fixed high-frequency command update scenario, refer to this example. Please note under this mode the command is executed immediately and the speed and acceleration parameters are not effective, please control the step command and frequency with caution.

@simeoncapy
Copy link
Author

hello @penglongxiang thanks for your answer!
Yes, I am updating with quite a high frequency: the commands are sent via ROS from Unity, so every frame. But I am using a threshold value to not use the command if the controller moved less than a centimetre. Even with this, it's quite a lot.

I will look at the code you shared to check if it's suitable (especially for safety regarding speed and acc), otherwise, I can use set_state(4) and then set_state(0), I guess.

@simeoncapy
Copy link
Author

simeoncapy commented Oct 21, 2024

I'm going back @penglongxiang
So I tried the set_servo_cartesian function, and indeed the speed is not applied and it goes too fast (sometimes it is blocked because of high current).

Then I tried to switch the state, but it's not working, the robot is not moving, so maybe it is too fast. (sometimes I got the error 9)

Here is a piece of my code, called by the ROS callback. In this case pos_or_joint_values contains the end effector desired position as [x, y, z, roll, pitch, yaw].

self.arm.set_state(4)
if self.arm.mode != 0:                    
    self.arm.set_mode(0)
self.arm.set_state(state=0)
                
self.arm.set_position(pos_or_joint_values[0], pos_or_joint_values[1], pos_or_joint_values[2],
                                      pos_or_joint_values[3], pos_or_joint_values[4], pos_or_joint_values[5], 
                                      speed=self.TRANS_SPEED, wait=wait, is_radian=False)

Just to be sure, set_position is the position of the robot end effector, right? Since there is also set_tool_position, I am a bit confused.

@penglongxiang
Copy link

I see, if you are not updating the command at servo rate (>50Hz), then there is another mode you can try. Which is the online planning mode (mode 7), in this mode, the API will still be set_position(). Difference is only the latest received command will be effective (previous command will be interrupted upon new command reception) and the robot will adjust to the latest target with controlled max velocity and acceleration. Please refer to this example. This may better suit your application.

set_tool_position() is for command given in tool coordinate system, use set_position() if you are commanding in base coordinate system.

@simeoncapy
Copy link
Author

Thanks for the answer. I used the mode 7, it's better and follows my command more, but it looks like it stills has a cache. For example, when I stop it continues to move. I did a test with a lower frequency (10 Hz).

Moreover, what is the command get_position behaviour while the robot is still moving?

Because sometimes, I send the command to a position, and the result is totally different:

[ARC.xarm_controller]: 6. Moving EE of robot to: [206.32426298028565, 0.01537450160831213, 112.217177230896, -179.74323899414065, -2.9472808837890625, -107.90946518927814]
[ARC.xarm_controller]: 6.5 ret: 0
[ARC.xarm_controller]: 7. Moved, Robot EE position: [461.945709, 0.0, 161.182434, -180.00002, -0.0, -0.0] (code = 0)
self.get_logger().info(f"6. Moving EE of robot to: {pos_or_joint_values}")
if not self.simulation_only:
    if self.arm.mode != 7:
        self.arm.set_mode(7)
        self.arm.set_state(state=0)
                        
    ret = self.arm.set_position(pos_or_joint_values[0], pos_or_joint_values[1], pos_or_joint_values[2],
                            #pos_or_joint_values[3], pos_or_joint_values[4], pos_or_joint_values[5], 
                            speed=self.TRANS_SPEED, wait=wait, is_radian=False)
    # ret = self.arm.set_servo_cartesian(pos_or_joint_values, speed=self.TRANS_SPEED, is_radian=False)
    self.get_logger().info(f"6.5 ret: {ret}")
    time.sleep(0.01)
    checked_pos = self.arm.get_position(is_radian=False)
    self.end_effector_current_pos = checked_pos[1][:6] if checked_pos[0] == 0 else pos_or_joint_values
    self.get_logger().info(f"7. Moved, Robot EE position: {self.end_effector_current_pos} (code = {checked_pos[0]})")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants