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 run real-world example on a uFactory lite 6 robot #29

Open
jannwawerek opened this issue Nov 15, 2023 · 4 comments
Open

How to run real-world example on a uFactory lite 6 robot #29

jannwawerek opened this issue Nov 15, 2023 · 4 comments

Comments

@jannwawerek
Copy link

Great project!

I understand that the rtde_interpolation_controller.py is controlling the UR5.
Is there any way to use a uFactory lite 6 robot arm instead?

Thanks for your help!

@cheng-chi
Copy link
Collaborator

Hi @jannwawerek, I never used uFactory robots myself, however I think it should be easy to port RTDEInterpolationController over. You really just need to replace line 268 (rtde_c.servoL) with whatever uFactory's API that accept end-effector positional command.

@ruoshiliu
Copy link

ruoshiliu commented Nov 23, 2023

Upon some preliminary testing, velocity control (vc_set_cartesian_velocity) seems to work better than positional control (set_position) for xArm SDK. Here's a short script to control xArm series with spacemouse (adapted from demo_real_robot.py). Hope it's helpful.

"""
Usage:
(robodiff)$ python demo_xarm.py --robot_ip <ip_of_xarm> --max_speed 100

Robot movement:
Move your SpaceMouse to move the robot EEF (3 spatial DoF only).
Press SpaceMouse left button once to reset to initial pose.
"""

# %%
import time
from multiprocessing.managers import SharedMemoryManager
import click
import cv2
import sys
import numpy as np
import scipy.spatial.transform as st
from diffusion_policy.real_world.spacemouse_shared_memory import Spacemouse
from diffusion_policy.common.precise_sleep import precise_wait
from diffusion_policy.real_world.keystroke_counter import (
    KeystrokeCounter, Key, KeyCode
)

# xArm API
sys.path.append('/home/USER/xArm-Python-SDK')
from xarm.wrapper import XArmAPI

@click.command()
@click.option('--robot_ip', '-ri', default="192.168.1.220", required=False, help="UR5's IP address e.g. 192.168.0.204")
@click.option('--init_joints', '-j', is_flag=True, default=True, help="Whether to initialize robot joint configuration in the beginning.")
@click.option('--frequency', '-f', default=10, type=float, help="Control frequency in Hz.")
@click.option('--command_latency', '-cl', default=0.01, type=float, help="Latency between receiving SapceMouse command to executing on Robot in Sec.")
@click.option('--max_speed', '-ms', default=100, type=float, help="Max speed of the robot in mm/s.")
def main(robot_ip, init_joints, frequency, command_latency, max_speed):
    max_speed = max_speed * frequency
    dt = 1/frequency
    with SharedMemoryManager() as shm_manager:
        with KeystrokeCounter() as key_counter, \
            Spacemouse(shm_manager=shm_manager) as sm:

            arm = XArmAPI(robot_ip, is_radian=True)
            cv2.setNumThreads(1)

            # initialize xarm
            arm.motion_enable(enable=True)
            arm.set_mode(0)
            arm.set_state(state=0)
            time.sleep(1)
            if init_joints:
                arm.reset(wait=True)

            arm.set_mode(5)
            arm.set_state(0)

            
            time.sleep(1.0)
            print('Ready!')
            state = arm.get_position()
            target_pose = state[1]
            t_start = time.monotonic()
            iter_idx = 0
            stop = False
            is_recording = False
            while not stop:
                # calculate timing
                t_cycle_end = t_start + (iter_idx + 1) * dt
                t_sample = t_cycle_end - command_latency
                t_command_target = t_cycle_end + dt

                # handle key presses
                press_events = key_counter.get_press_events()
                stage = key_counter[Key.space]

                precise_wait(t_sample)
                # get teleop command
                sm_state = sm.get_motion_state_transformed()
                # print(sm_state)
                dpos = sm_state[:3] * (max_speed / frequency)
                drot_xyz = sm_state[3:] * (max_speed / frequency)
                
                drot_xyz[:] = 0

                drot = st.Rotation.from_euler('xyz', drot_xyz)
                target_pose[:3] += dpos
                target_pose[3:] = (drot * st.Rotation.from_rotvec(
                    target_pose[3:])).as_rotvec()

                speed = np.linalg.norm(dpos) / dt
                
                if sm.is_button_pressed(0):
                    arm.set_mode(0)
                    arm.set_state(0)
                    time.sleep(0.1)
                    arm.reset(wait=True)
                    arm.set_mode(5)
                    arm.set_state(0)
                
                dvel = dpos

                if speed > 0.1:
                    dvel = dpos * (max_speed / speed)
                else:
                    dvel *= 0
                    # continue

                print('scaled speed:', np.linalg.norm(dvel))

                x_velocity, y_velocity, z_velocity = dvel
                roll_velocity, pitch_velocity, yaw_velocity = drot_xyz
                print(f'x_velocity: {x_velocity}, y_velocity: {y_velocity}, z_velocity: {z_velocity}')
                print(f'roll_velocity: {roll_velocity}, pitch_velocity: {pitch_velocity}, yaw_velocity: {yaw_velocity}')

                arm.vc_set_cartesian_velocity([x_velocity, y_velocity, z_velocity, roll_velocity, pitch_velocity, yaw_velocity])

                precise_wait(t_cycle_end)
                iter_idx += 1

# %%
if __name__ == '__main__':
    main()

@manadaniel
Copy link

@ruoshiliu thank you very much for providing this hint as well as exemplary code! How did you came to this finding? What’s the issue with set_position? Have you tried the set_servo_cartesian method as well? That’s what I am going for currently, might be able to test tomorrow. Docs for set_servo_cartesian

@duidui6666
Copy link

你好@jannwawerek,我自己从未使用过 uFactory 机器人,但是我认为移植 RTDEInterpolationController 应该很容易。您实际上只需将第 268 行 (rtde_c.servoL) 替换为接受末端执行器位置命令的 uFactory 的 API。

Is it not necessary to obtain the robot arm status information? @cheng-chi

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

5 participants