diff --git a/.gitignore b/.gitignore index 7ed1b05..10d90fb 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,8 @@ __pycache__/ *$py.class *.so *.so.* -!src/ufactory_lerobot/devices/umi/xvlib/lib*.so -!src/ufactory_lerobot/devices/umi/xvlib/lib*.so.* +!src/lerobot_robot_ufactory/devices/umi/xvlib/lib*.so +!src/lerobot_robot_ufactory/devices/umi/xvlib/lib*.so.* *.egg *.egg-info/ dist/ diff --git a/config/gello/xarm5_gello_record_config.yaml b/config/gello/xarm5_gello_record_config.yaml index 03fff87..fed67a8 100644 --- a/config/gello/xarm5_gello_record_config.yaml +++ b/config/gello/xarm5_gello_record_config.yaml @@ -1,5 +1,5 @@ -RobotConfig: - _target_: ufactory_lerobot.robots.uf_robot.UFRobotConfig +robot: + type: uf::robot id: "uf_robot" robot_dof: 5 control_space: "joint" @@ -7,20 +7,9 @@ RobotConfig: gripper_type: 1 start_joints: [0, 0, -90, 90, 0] -DatasetRecordConfig: - _target_: lerobot.scripts.lerobot_record.DatasetRecordConfig - # root of local repo: /home//.cache/huggingface/lerobot (default) - root: "/home/uf/Data/lerobot_datas/record/ufactory/xarm5_gello_datas" - repo_id: "ufactory/xarm5_gello_datas" - single_task: "Pick up the purple grape and drop into the box on the left." - fps: 30 - episode_time_s: 60 # max duration for one episode - reset_time_s: 20 # (invalid) time for resetting env between episodes - push_to_hub: False - # make sure to edit with your correct configurations! -TeleoperatorConfig: - _target_: ufactory_lerobot.teleoperators.gello_teleop.GelloTeleopConfig +teleop: + type: uf::gello_teleop port: "/dev/serial/by-id/usb-FTDI_USB__-__Serial_Converter_FTAJZYC7-if00-port0" joint_ids: [1, 2, 4, 6, 7] joint_signs: [1, 1, -1, 1, 1] @@ -28,3 +17,12 @@ TeleoperatorConfig: gripper_id: 8 torque_joint_ids: [3, 5] +dataset: + # root of local repo: /home//.cache/huggingface/lerobot (default) + root: "/home/uf/Data/lerobot_datas/record/ufactory/xarm5_gello_datas" + repo_id: "ufactory/xarm5_gello_datas" + single_task: "Pick up the purple grape and drop into the box on the left." + fps: 30 + episode_time_s: 60 # max duration for one episode + reset_time_s: 20 # time for resetting env between episodes + push_to_hub: False diff --git a/config/gello/xarm6_gello_record_config.yaml b/config/gello/xarm6_gello_record_config.yaml index e495b41..873cb82 100644 --- a/config/gello/xarm6_gello_record_config.yaml +++ b/config/gello/xarm6_gello_record_config.yaml @@ -1,5 +1,5 @@ -RobotConfig: - _target_: ufactory_lerobot.robots.uf_robot.UFRobotConfig +robot: + type: uf::robot id: "uf_robot" robot_dof: 6 control_space: "joint" @@ -7,20 +7,9 @@ RobotConfig: gripper_type: 1 start_joints: [0, 0, -90, 0, 90, 0] -DatasetRecordConfig: - _target_: lerobot.scripts.lerobot_record.DatasetRecordConfig - # root of local repo: /home//.cache/huggingface/lerobot (default) - root: "/home/uf/Data/lerobot_datas/record/ufactory/xarm6_gello_datas" - repo_id: "ufactory/xarm6_gello_datas" - single_task: "Pick up the purple grape and drop into the box on the left." - fps: 30 - episode_time_s: 60 # max duration for one episode - reset_time_s: 20 # (invalid) time for resetting env between episodes - push_to_hub: False - # make sure to edit with your correct configurations! -TeleoperatorConfig: - _target_: ufactory_lerobot.teleoperators.gello_teleop.GelloTeleopConfig +teleop: + type: uf::gello_teleop port: "/dev/serial/by-id/usb-FTDI_USB__-__Serial_Converter_FTAJZYC7-if00-port0" joint_ids: [1, 2, 4, 5, 6, 7] joint_signs: [1, 1, -1, 1, 1, 1] @@ -28,3 +17,12 @@ TeleoperatorConfig: gripper_id: 8 torque_joint_ids: [3] +dataset: + # root of local repo: /home//.cache/huggingface/lerobot (default) + root: "/home/uf/Data/lerobot_datas/record/ufactory/xarm6_gello_datas" + repo_id: "ufactory/xarm6_gello_datas" + single_task: "Pick up the purple grape and drop into the box on the left." + fps: 30 + episode_time_s: 60 # max duration for one episode + reset_time_s: 20 # time for resetting env between episodes + push_to_hub: False diff --git a/config/gello/xarm7_gello_record_config.yaml b/config/gello/xarm7_gello_record_config.yaml index 5a872db..7091508 100644 --- a/config/gello/xarm7_gello_record_config.yaml +++ b/config/gello/xarm7_gello_record_config.yaml @@ -1,5 +1,5 @@ -RobotConfig: - _target_: ufactory_lerobot.robots.uf_robot.UFRobotConfig +robot: + type: uf::robot id: "uf_robot" robot_dof: 7 control_space: "joint" @@ -7,21 +7,19 @@ RobotConfig: gripper_type: 1 start_joints: [0, 0, 0, 90, 0, 90, 0] -DatasetRecordConfig: - _target_: lerobot.scripts.lerobot_record.DatasetRecordConfig +# make sure to edit with your correct configurations! +teleop: + type: uf::gello_teleop + id: "gello_teleop" + port: "/dev/serial/by-id/usb-FTDI_USB__-__Serial_Converter_FTAJZYC7-if00-port0" + start_joints: [0, 0, 0, 90, 0, 90, 0] + +dataset: # root of local repo: /home//.cache/huggingface/lerobot (default) root: "/home/uf/Data/lerobot_datas/record/ufactory/xarm6_gello_datas" repo_id: "ufactory/xarm6_gello_datas" single_task: "Pick up the purple grape and drop into the box on the left." fps: 30 episode_time_s: 60 # max duration for one episode - reset_time_s: 20 # (invalid) time for resetting env between episodes + reset_time_s: 20 # time for resetting env between episodes push_to_hub: False - -# make sure to edit with your correct configurations! -TeleoperatorConfig: - _target_: ufactory_lerobot.teleoperators.gello_teleop.GelloTeleopConfig - id: "gello_teleop" - port: "/dev/serial/by-id/usb-FTDI_USB__-__Serial_Converter_FTAJZYC7-if00-port0" - start_joints: [0, 0, 0, 90, 0, 90, 0] - diff --git a/config/pika/pika_record_config.yaml b/config/pika/pika_record_config.yaml index cdcee73..de417b1 100644 --- a/config/pika/pika_record_config.yaml +++ b/config/pika/pika_record_config.yaml @@ -1,21 +1,29 @@ -RobotConfig: - _target_: ufactory_lerobot.robots.uf_mock_robot.UFMockRobotConfig +robot: + type: uf::mock_robot id: "uf_mock_robot" control_space: "cartesian" gripper_type: 2 state_offset_action: 3 - + teleop_id: "pika_xxxx" cameras: fisheye: - _target_: lerobot.cameras.opencv.configuration_opencv.OpenCVCameraConfig + type: opencv index_or_path: "/dev/v4l/by-id/usb-DECXIN_CAMERA_DECXIN_CAMERA_01.00.00-video-index0" width: 640 height: 480 fps: 30 fourcc: "MJPG" -DatasetRecordConfig: - _target_: lerobot.scripts.lerobot_record.DatasetRecordConfig +# make sure to edit with your correct configurations! +teleop: + type: uf::pika_teleop + id: "pika_xxxx" + # port: "/dev/ttyUSB0" + scale_xyz: 1.5 + tracker_to_robot_eef: [0, 0, 0, 180, -90, 0] + robot_base_pose: [400, 0, 400, 180, 0, 0] + +dataset: # root of local repo: /home//.cache/huggingface/lerobot (default) root: "/home/uf/Data/lerobot_datas/record/ufactory/pika_datas" repo_id: "ufactory/pika_datas" @@ -24,11 +32,3 @@ DatasetRecordConfig: episode_time_s: 60 # max duration for one episode reset_time_s: 20 # (invalid) time for resetting env between episodes push_to_hub: False - -# make sure to edit with your correct configurations! -TeleoperatorConfig: - _target_: ufactory_lerobot.teleoperators.pika_teleop.PikaTeleopConfig - # port: "/dev/ttyUSB0" - scale_xyz: 1.5 - tracker_to_robot_eef: [0, 0, 0, 180, -90, 0] - robot_base_pose: [400, 0, 400, 180, 0, 0] diff --git a/config/pika/xarm7_pika_record_config.yaml b/config/pika/xarm7_pika_record_config.yaml index 145851e..a23199d 100644 --- a/config/pika/xarm7_pika_record_config.yaml +++ b/config/pika/xarm7_pika_record_config.yaml @@ -1,5 +1,5 @@ -RobotConfig: - _target_: ufactory_lerobot.robots.uf_robot.UFRobotConfig +robot: + type: uf::robot id: "uf_robot" robot_dof: 7 control_space: "cartesian" @@ -8,18 +8,24 @@ RobotConfig: max_linear_velocity: 200 start_joints: [-0.2, -13.9, -0.3, 52.6, 0.9, 66.6, 0.2] start_tcp_pose: [400, 0, 400, 180, 0, 0] - cameras: fisheye: - _target_: lerobot.cameras.opencv.configuration_opencv.OpenCVCameraConfig + type: opencv index_or_path: "/dev/v4l/by-id/usb-DECXIN_CAMERA_DECXIN_CAMERA_01.00.00-video-index0" width: 640 height: 480 fps: 30 fourcc: "MJPG" -DatasetRecordConfig: - _target_: lerobot.scripts.lerobot_record.DatasetRecordConfig +# make sure to edit with your correct configurations! +teleop: + type: uf::pika_teleop + # port: "/dev/ttyUSB0" + scale_xyz: 1.5 + tracker_to_robot_eef: [0, 0, 0, 180, -90, 0] + robot_base_pose: [400, 0, 400, 180, 0, 0] + +dataset: # root of local repo: /home//.cache/huggingface/lerobot (default) root: "/home/uf/Data/lerobot_datas/record/ufactory/xarm7_pika_datas" repo_id: "ufactory/xarm7_pika_datas" @@ -28,11 +34,3 @@ DatasetRecordConfig: episode_time_s: 60 # max duration for one episode reset_time_s: 20 # (invalid) time for resetting env between episodes push_to_hub: False - -# make sure to edit with your correct configurations! -TeleoperatorConfig: - _target_: ufactory_lerobot.teleoperators.pika_teleop.PikaTeleopConfig - # port: "/dev/ttyUSB0" - scale_xyz: 1.5 - tracker_to_robot_eef: [0, 0, 0, 180, -90, 0] - robot_base_pose: [400, 0, 400, 180, 0, 0] diff --git a/config/spacemouse/xarm7_spacemouse_record_config.yaml b/config/spacemouse/xarm7_spacemouse_record_config.yaml index 15dd00c..db2b2a8 100644 --- a/config/spacemouse/xarm7_spacemouse_record_config.yaml +++ b/config/spacemouse/xarm7_spacemouse_record_config.yaml @@ -1,5 +1,5 @@ -RobotConfig: - _target_: ufactory_lerobot.robots.uf_robot.UFRobotConfig +robot: + type: uf::robot id: "uf_robot" robot_dof: 7 control_space: "cartesian" @@ -8,20 +8,25 @@ RobotConfig: cameras: overhead: - _target_: lerobot.cameras.realsense.configuration_realsense.RealSenseCameraConfig + type: intelrealsense serial_number_or_name: "Intel RealSense D435I" width: 640 height: 480 fps: 30 tool: - _target_: lerobot.cameras.realsense.configuration_realsense.RealSenseCameraConfig + type: intelrealsense serial_number_or_name: "Intel RealSense D435" width: 640 height: 480 fps: 30 -DatasetRecordConfig: - _target_: lerobot.scripts.lerobot_record.DatasetRecordConfig +# space mouse +teleop: + type: uf::spacemouse_teleop + max_value: 300 + use_gripper: False + +dataset: # root: /home//.cache/huggingface/lerobot (default) root: "/home/uf/Data/lerobot_datas/record/ufactory/xarm7_pushT" repo_id: "ufactory/xarm7_pushT" @@ -30,9 +35,3 @@ DatasetRecordConfig: episode_time_s: 60 # max duration for one episode reset_time_s: 20 # (invalid) time for resetting env between episodes push_to_hub: False - -# space mouse -TeleoperatorConfig: - _target_: ufactory_lerobot.teleoperators.space_mouse.SpaceMouseTeleopConfig - max_value: 300 - use_gripper: False \ No newline at end of file diff --git a/config/umi/dual_umi_record_config.yaml b/config/umi/dual_umi_record_config.yaml index ba42ec8..354b10f 100644 --- a/config/umi/dual_umi_record_config.yaml +++ b/config/umi/dual_umi_record_config.yaml @@ -1,42 +1,44 @@ -RobotConfig: - _target_: ufactory_lerobot.robots.uf_mock_robot.MultipleUFMockRobotConfig +robot: + type: uf::multiple_mock_robot id: "multiple_uf_mock_robots" robots: left: - _target_: ufactory_lerobot.robots.uf_mock_robot.UFMockRobotConfig + type: uf::mock_robot id: "left_uf_mock_robot" control_space: "cartesian" gripper_type: 1 state_offset_action: 3 + teleop_id: "umi_250801DR48FP26001318" cameras: fisheye: - _target_: ufactory_lerobot.cameras.umi_camera.configuration_umi.UmiCameraConfig + type: uf::umi_camera serial_number: "250801DR48FP26001318" width: 1280 height: 1280 fps: 30 right: - _target_: ufactory_lerobot.robots.uf_mock_robot.UFMockRobotConfig + type: uf::mock_robot id: "right_uf_mock_robot" control_space: "cartesian" gripper_type: 1 state_offset_action: 3 + teleop_id: "umi_250801DR48FP26001295" cameras: fisheye: - _target_: ufactory_lerobot.cameras.umi_camera.configuration_umi.UmiCameraConfig + type: uf::umi_camera serial_number: "250801DR48FP26001295" width: 1280 height: 1280 fps: 30 # make sure to edit with your correct configurations! -TeleoperatorConfig: - _target_: ufactory_lerobot.teleoperators.umi_teleop.MultipleUmiTeleopConfig +teleop: + type: uf::multiple_umi_teleop id: "multiple_teleops" teleops: left: - _target_: ufactory_lerobot.teleoperators.umi_teleop.UmiTeleopConfig - id: "left_teleop" + type: uf::umi_teleop + id: "umi_250801DR48FP26001318" serial_number: "250801DR48FP26001318" use_vive_tracker: False vive_tracker_id: "LHR-555DC7BF" @@ -44,8 +46,8 @@ TeleoperatorConfig: tracker_to_robot_eef: [0, 0, 0, 0, 0, -90] robot_base_pose: [400, 0, 150, -90, 0, 0] right: - _target_: ufactory_lerobot.teleoperators.umi_teleop.UmiTeleopConfig - id: "right_teleop" + type: uf::umi_teleop + id: "umi_250801DR48FP26001295" serial_number: "250801DR48FP26001295" use_vive_tracker: False vive_tracker_id: "LHR-2425BAD3" @@ -53,15 +55,14 @@ TeleoperatorConfig: tracker_to_robot_eef: [0, 0, 0, 0, 0, -90] robot_base_pose: [400, 0, 150, 90, 0, 0] -DatasetRecordConfig: - _target_: lerobot.scripts.lerobot_record.DatasetRecordConfig +dataset: # root of local repo: /home//.cache/huggingface/lerobot (default) root: "/home/uf/Data/lerobot_datas/record/ufactory/dual_xarm6_umi_datas" - repo_id: "ufactory/dual_xarm6_umi_datas" + repo_id: "ufactory/dual_umi_datas" single_task: "Pick up the purple grape and drop into the box on the left." fps: 60 episode_time_s: 60 # max duration for one episode - reset_time_s: 20 # (invalid) time for resetting env between episodes + reset_time_s: 20 # time for resetting env between episodes num_episodes: 100 push_to_hub: False diff --git a/config/umi/dual_xarm6_umi_record_config.yaml b/config/umi/dual_xarm6_umi_record_config.yaml index 008f9ed..aefd464 100644 --- a/config/umi/dual_xarm6_umi_record_config.yaml +++ b/config/umi/dual_xarm6_umi_record_config.yaml @@ -1,12 +1,12 @@ -RobotConfig: - _target_: ufactory_lerobot.robots.uf_robot.MultipleUFRobotConfig +robot: + type: uf::multiple_robot id: "multiple_uf_robots" async_connect: True async_configure: True async_action: False robots: left: - _target_: ufactory_lerobot.robots.uf_robot.UFRobotConfig + type: uf::robot id: "left_uf_robot" robot_dof: 6 control_space: "cartesian" @@ -15,16 +15,23 @@ RobotConfig: max_linear_velocity: 200 start_joints: [-14.7, 25.6, -49.6, -282.5, 95.9, -65.9] start_tcp_pose: [400, 0, 150, -90, 0, 0] + teleop_id: "umi_250801DR48FP26001318" + # no_action: True cameras: fisheye: - _target_: lerobot.cameras.opencv.configuration_opencv.OpenCVCameraConfig + # type: uf::umi_camera + # serial_number: "250801DR48FB26001379" + # width: 1280 + # height: 1280 + # fps: 30 + type: opencv index_or_path: "/dev/v4l/by-id/usb-XVisio_Technology_XVisio_vSLAM_250801DR48FB26001379-video-index0" width: 1280 height: 1280 fps: 100 fourcc: "YUYV" right: - _target_: ufactory_lerobot.robots.uf_robot.UFRobotConfig + type: uf::robot id: "right_uf_robot" robot_dof: 6 control_space: "cartesian" @@ -33,9 +40,16 @@ RobotConfig: max_linear_velocity: 200 start_joints: [14.5, 25.5, -49.6, -76.8, 95.9, 66.6] start_tcp_pose: [400, 0, 150, 90, 0, 0] + teleop_id: "umi_250801DR48FP26001295" + # no_action: True cameras: fisheye: - _target_: lerobot.cameras.opencv.configuration_opencv.OpenCVCameraConfig + # type: uf::umi_camera + # serial_number: "250801DR48FB26001396" + # width: 1280 + # height: 1280 + # fps: 30 + type: opencv index_or_path: "/dev/v4l/by-id/usb-XVisio_Technology_XVisio_vSLAM_250801DR48FB26001396-video-index0" width: 1280 height: 1280 @@ -43,13 +57,13 @@ RobotConfig: fourcc: "YUYV" # make sure to edit with your correct configurations! -TeleoperatorConfig: - _target_: ufactory_lerobot.teleoperators.umi_teleop.MultipleUmiTeleopConfig +teleop: + type: uf::multiple_umi_teleop id: "multiple_teleops" teleops: left: - _target_: ufactory_lerobot.teleoperators.umi_teleop.UmiTeleopConfig - id: "left_teleop" + type: uf::umi_teleop + id: "umi_250801DR48FP26001318" serial_number: "250801DR48FP26001318" use_vive_tracker: False vive_tracker_id: "LHR-555DC7BF" @@ -57,8 +71,8 @@ TeleoperatorConfig: tracker_to_robot_eef: [0, 0, 0, 0, 0, -90] robot_base_pose: [400, 0, 150, -90, 0, 0] right: - _target_: ufactory_lerobot.teleoperators.umi_teleop.UmiTeleopConfig - id: "right_teleop" + type: uf::umi_teleop + id: "umi_250801DR48FP26001295" serial_number: "250801DR48FP26001295" use_vive_tracker: False vive_tracker_id: "LHR-2425BAD3" @@ -66,15 +80,14 @@ TeleoperatorConfig: tracker_to_robot_eef: [0, 0, 0, 0, 0, -90] robot_base_pose: [400, 0, 150, 90, 0, 0] -DatasetRecordConfig: - _target_: lerobot.scripts.lerobot_record.DatasetRecordConfig +dataset: # root of local repo: /home//.cache/huggingface/lerobot (default) root: "/home/uf/Data/lerobot_datas/record/ufactory/dual_xarm6_umi_datas" repo_id: "ufactory/dual_xarm6_umi_datas" single_task: "Pick up the purple grape and drop into the box on the left." fps: 60 episode_time_s: 60 # max duration for one episode - reset_time_s: 20 # (invalid) time for resetting env between episodes + reset_time_s: 20 # time for resetting env between episodes num_episodes: 100 push_to_hub: False diff --git a/config/umi/umi_record_config.yaml b/config/umi/umi_record_config.yaml index 6fcd1a6..3b202ee 100644 --- a/config/umi/umi_record_config.yaml +++ b/config/umi/umi_record_config.yaml @@ -1,19 +1,21 @@ -RobotConfig: - _target_: ufactory_lerobot.robots.uf_mock_robot.UFMockRobotConfig +robot: + type: uf::mock_robot id: "uf_mock_robot" control_space: "cartesian" gripper_type: 1 state_offset_action: 3 + teleop_id: "umi_250801DR48FP26001295" cameras: fisheye: - _target_: ufactory_lerobot.cameras.umi_camera.configuration_umi.UmiCameraConfig + type: uf::umi_camera serial_number: "250801DR48FP26001295" width: 1280 height: 1280 fps: 100 -TeleoperatorConfig: - _target_: ufactory_lerobot.teleoperators.umi_teleop.UmiTeleopConfig +teleop: + type: uf::umi_teleop + id: "umi_250801DR48FP26001295" serial_number: "250801DR48FP26001295" use_vive_tracker: False vive_tracker_id: "LHR-2425BAD3" @@ -21,14 +23,13 @@ TeleoperatorConfig: tracker_to_robot_eef: [0, 0, 0, 0, 0, -90] robot_base_pose: [400, 0, 400, 180, 0, 0] -DatasetRecordConfig: - _target_: lerobot.scripts.lerobot_record.DatasetRecordConfig +dataset: # root of local repo: /home//.cache/huggingface/lerobot (default) root: "/home/uf/Data/lerobot_datas/record/ufactory/umi_datas" repo_id: "ufactory/umi_datas" single_task: "Pick up the purple grape and drop into the box on the left." fps: 60 episode_time_s: 60 # max duration for one episode - reset_time_s: 20 # (invalid) time for resetting env between episodes + reset_time_s: 20 # time for resetting env between episodes num_episodes: 100 push_to_hub: False \ No newline at end of file diff --git a/config/umi/xarm6_umi_record_config.yaml b/config/umi/xarm6_umi_record_config.yaml index 8612c7b..bfae4b0 100644 --- a/config/umi/xarm6_umi_record_config.yaml +++ b/config/umi/xarm6_umi_record_config.yaml @@ -1,5 +1,5 @@ -RobotConfig: - _target_: ufactory_lerobot.robots.uf_robot.UFRobotConfig +robot: + type: uf::robot id: "uf_robot" robot_dof: 6 control_space: "cartesian" @@ -10,15 +10,15 @@ RobotConfig: start_tcp_pose: [400, 0, 400, 180, 0, 0] cameras: fisheye: - _target_: lerobot.cameras.opencv.configuration_opencv.OpenCVCameraConfig + type: opencv index_or_path: "/dev/v4l/by-id/usb-XVisio_Technology_XVisio_vSLAM_250801DR48FB26001396-video-index0" width: 1280 height: 1280 fps: 100 fourcc: "YUYV" -TeleoperatorConfig: - _target_: ufactory_lerobot.teleoperators.umi_teleop.UmiTeleopConfig +teleop: + type: uf::umi_teleop serial_number: "250801DR48FP26001295" use_vive_tracker: False vive_tracker_id: "LHR-2425BAD3" @@ -26,14 +26,13 @@ TeleoperatorConfig: tracker_to_robot_eef: [0, 0, 0, 0, 0, -90] robot_base_pose: [400, 0, 400, 180, 0, 0] -DatasetRecordConfig: - _target_: lerobot.scripts.lerobot_record.DatasetRecordConfig +dataset: # root of local repo: /home//.cache/huggingface/lerobot (default) root: "/home/uf/Data/lerobot_datas/record/ufactory/xarm6_umi_datas" repo_id: "ufactory/xarm6_umi_datas" single_task: "Pick up the purple grape and drop into the box on the left." fps: 60 episode_time_s: 60 # max duration for one episode - reset_time_s: 20 # (invalid) time for resetting env between episodes + reset_time_s: 20 # time for resetting env between episodes num_episodes: 100 push_to_hub: False \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index fc49591..6384b66 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,14 +3,14 @@ requires = ["setuptools>=68.0", "wheel>=0.42"] build-backend = "setuptools.build_meta" [project] -name = "ufactory_lerobot" +name = "lerobot_robot_ufactory" version = "0.1.0" description = "UFACTORY 机械臂与 LeRobot 框架集成" readme = "README.md" license = { text = "Apache-2.0" } requires-python = ">=3.10" authors = [ - { name = "ufactory_lerobot Contributors" }, + { name = "lerobot_robot_ufactory Contributors" }, ] keywords = ["robotics", "lerobot", "ufactory", "xarm", "imitation-learning"] classifiers = [ @@ -32,11 +32,11 @@ dependencies = [ ] [project.scripts] -uf-robot-teleop = "ufactory_lerobot.scripts.uf_robot_teleop:main" -uf-lerobot-record = "ufactory_lerobot.scripts.uf_lerobot_record:main" -uf-lerobot-eval = "ufactory_lerobot.scripts.uf_lerobot_eval:main" -uf-vive-calibrate = "ufactory_lerobot.scripts.vive_calibrate:main" -uf-camera-view = "ufactory_lerobot.scripts.uf_camera_view:main" +uf-robot-teleop = "lerobot_robot_ufactory.scripts.uf_robot_teleop:main" +uf-lerobot-record = "lerobot_robot_ufactory.scripts.uf_lerobot_record:main" +uf-lerobot-eval = "lerobot_robot_ufactory.scripts.uf_lerobot_eval:main" +uf-vive-calibrate = "lerobot_robot_ufactory.scripts.vive_calibrate:main" +uf-camera-view = "lerobot_robot_ufactory.scripts.uf_camera_view:main" [project.optional-dependencies] # GELLO 遥操作 @@ -64,7 +64,7 @@ include-package-data = true where = ["src"] [tool.setuptools.package-data] -"ufactory_lerobot.devices.umi.xvlib" = ["*.so", "*.so.*"] +"lerobot_robot_ufactory.devices.umi.xvlib" = ["*.so", "*.so.*"] [tool.ruff] line-length = 100 diff --git a/src/ufactory_lerobot/__init__.py b/src/lerobot_robot_ufactory/__init__.py similarity index 51% rename from src/ufactory_lerobot/__init__.py rename to src/lerobot_robot_ufactory/__init__.py index 32a92c2..c52e431 100644 --- a/src/ufactory_lerobot/__init__.py +++ b/src/lerobot_robot_ufactory/__init__.py @@ -1,6 +1,6 @@ -from ufactory_lerobot.cameras.utils import make_cameras_from_configs as _uf_make_cameras_from_configs -from ufactory_lerobot.robots.utils import make_robot_from_config as _uf_make_robot_from_config -from ufactory_lerobot.teleoperators.utils import make_teleoperator_from_config as _uf_make_teleoperator_from_config +from lerobot_robot_ufactory.cameras.utils import make_cameras_from_configs as _uf_make_cameras_from_configs +from lerobot_robot_ufactory.robots.utils import make_robot_from_config as _uf_make_robot_from_config +from lerobot_robot_ufactory.teleoperators.utils import make_teleoperator_from_config as _uf_make_teleoperator_from_config import lerobot.cameras as _lerobot_cameras import lerobot.robots as _lerobot_robot import lerobot.teleoperators as _lerobot_teleoperators @@ -15,11 +15,11 @@ _lerobot_cameras_utils.make_cameras_from_configs = _uf_make_cameras_from_configs _lerobot_robot_utils.make_robot_from_config = _uf_make_robot_from_config _lerobot_teleoperators_utils.make_teleoperator_from_config = _uf_make_teleoperator_from_config # register plugin -import ufactory_lerobot.cameras.umi_camera -import ufactory_lerobot.robots.uf_robot -import ufactory_lerobot.robots.uf_mock_robot -import ufactory_lerobot.teleoperators.uf_mock_teleop -import ufactory_lerobot.teleoperators.gello_teleop -import ufactory_lerobot.teleoperators.pika_teleop -import ufactory_lerobot.teleoperators.space_mouse -import ufactory_lerobot.teleoperators.umi_teleop +import lerobot_robot_ufactory.cameras.umi_camera +import lerobot_robot_ufactory.robots.uf_robot +import lerobot_robot_ufactory.robots.uf_mock_robot +import lerobot_robot_ufactory.teleoperators.uf_mock_teleop +import lerobot_robot_ufactory.teleoperators.gello_teleop +import lerobot_robot_ufactory.teleoperators.pika_teleop +import lerobot_robot_ufactory.teleoperators.space_mouse +import lerobot_robot_ufactory.teleoperators.umi_teleop diff --git a/src/ufactory_lerobot/cameras/__init__.py b/src/lerobot_robot_ufactory/cameras/__init__.py similarity index 100% rename from src/ufactory_lerobot/cameras/__init__.py rename to src/lerobot_robot_ufactory/cameras/__init__.py diff --git a/src/ufactory_lerobot/cameras/umi_camera/__init__.py b/src/lerobot_robot_ufactory/cameras/umi_camera/__init__.py similarity index 100% rename from src/ufactory_lerobot/cameras/umi_camera/__init__.py rename to src/lerobot_robot_ufactory/cameras/umi_camera/__init__.py diff --git a/src/ufactory_lerobot/cameras/umi_camera/camera_umi.py b/src/lerobot_robot_ufactory/cameras/umi_camera/camera_umi.py similarity index 97% rename from src/ufactory_lerobot/cameras/umi_camera/camera_umi.py rename to src/lerobot_robot_ufactory/cameras/umi_camera/camera_umi.py index aaaf2e3..cba1a71 100644 --- a/src/ufactory_lerobot/cameras/umi_camera/camera_umi.py +++ b/src/lerobot_robot_ufactory/cameras/umi_camera/camera_umi.py @@ -51,7 +51,7 @@ class UmiCamera(Camera): self.rotation: int | None = get_cv2_rotation(config.rotation) self.last_frame = None - from ufactory_lerobot.devices.umi.xvlib import XVLib + from lerobot_robot_ufactory.devices.umi.xvlib import XVLib self.xvlib = XVLib(self.serial_number) self.xvlib.xv_color_camera_init() diff --git a/src/ufactory_lerobot/cameras/umi_camera/configuration_umi.py b/src/lerobot_robot_ufactory/cameras/umi_camera/configuration_umi.py similarity index 100% rename from src/ufactory_lerobot/cameras/umi_camera/configuration_umi.py rename to src/lerobot_robot_ufactory/cameras/umi_camera/configuration_umi.py diff --git a/src/ufactory_lerobot/cameras/utils.py b/src/lerobot_robot_ufactory/cameras/utils.py similarity index 100% rename from src/ufactory_lerobot/cameras/utils.py rename to src/lerobot_robot_ufactory/cameras/utils.py diff --git a/src/lerobot_robot_ufactory/context.py b/src/lerobot_robot_ufactory/context.py new file mode 100644 index 0000000..17ca708 --- /dev/null +++ b/src/lerobot_robot_ufactory/context.py @@ -0,0 +1,28 @@ +"""上下文变量,用于跨模块共享运行时对象,避免属性注入。""" +import contextvars + +_active_teleops: contextvars.ContextVar = contextvars.ContextVar("active_teleops", default={}) + + +def register_teleop(teleop) -> None: + """注册 teleop, 以 teleop.id 为 key""" + teleops = _active_teleops.get() + teleops[teleop.id] = teleop + _active_teleops.set(teleops) + + +def unregister_teleop(teleop) -> None: + """移除 teleop""" + teleops = _active_teleops.get() + teleops.pop(teleop.id, None) + _active_teleops.set(teleops) + + +def get_active_teleop(teleop_id: str | None = None): + """获取 active teleop。不传 id 返回第一个;传 id 返回对应 teleop。""" + teleops = _active_teleops.get() + if not teleops: + return None + if teleop_id is not None: + return teleops.get(teleop_id) + return next(iter(teleops.values())) diff --git a/src/ufactory_lerobot/devices/__init__.py b/src/lerobot_robot_ufactory/devices/__init__.py similarity index 100% rename from src/ufactory_lerobot/devices/__init__.py rename to src/lerobot_robot_ufactory/devices/__init__.py diff --git a/src/ufactory_lerobot/devices/pika/__init__.py b/src/lerobot_robot_ufactory/devices/pika/__init__.py similarity index 100% rename from src/ufactory_lerobot/devices/pika/__init__.py rename to src/lerobot_robot_ufactory/devices/pika/__init__.py diff --git a/src/ufactory_lerobot/devices/pika/pika_device.py b/src/lerobot_robot_ufactory/devices/pika/pika_device.py similarity index 87% rename from src/ufactory_lerobot/devices/pika/pika_device.py rename to src/lerobot_robot_ufactory/devices/pika/pika_device.py index 7f6661a..8c2d54c 100644 --- a/src/ufactory_lerobot/devices/pika/pika_device.py +++ b/src/lerobot_robot_ufactory/devices/pika/pika_device.py @@ -72,6 +72,7 @@ class PikaDevice(object): # _pika_sense_port = None # _pika_gripper_port = None # _lock = threading.Lock() + PIKA_DEVICE_MAP = {} def __init__(self, dev_type=1, **kwargs): """ @@ -144,6 +145,9 @@ class PikaDevice(object): if self._dev_type not in [1, 3]: return None if self._pika_sense is None: + if self._pika_sense_port in self.PIKA_DEVICE_MAP: + self._pika_sense = self.PIKA_DEVICE_MAP[self._pika_sense_port] + return self._pika_sense from pika.sense import Sense # 初始化Sense对象 self._pika_sense = Sense(port=self._pika_sense_port) @@ -152,6 +156,7 @@ class PikaDevice(object): logger.error('连接Pika Sense设备失败') exit(1) logger.info('Pika Sense设备连接成功') + self.PIKA_DEVICE_MAP[self._pika_sense_port] = self._pika_sense # 注册共享 # 配置Vive Tracker(可选) # sense.set_vive_tracker_config(config_path='path/to/config', lh_config='lighthouse_config') @@ -186,16 +191,19 @@ class PikaDevice(object): if self._dev_type not in [2, 3]: return None if self._pika_gripper is None: - if self._dev_type in [2, 3]: - from pika.gripper import Gripper - self._pika_gripper = Gripper(port=self._pika_gripper_port) - # 连接设备 - if not self._pika_gripper.connect(): - logger.error('连接Pika Gripper设备失败') - if self._dev_type in [1, 3]: - self.pika_sense.disconnect() - exit(1) - logger.info('Pika Gripper设备连接成功') + if self._pika_gripper_port in self.PIKA_DEVICE_MAP: + self._pika_gripper = self.PIKA_DEVICE_MAP[self._pika_gripper_port] + return self._pika_gripper + from pika.gripper import Gripper + self._pika_gripper = Gripper(port=self._pika_gripper_port) + self.PIKA_DEVICE_MAP[self._pika_gripper_port] = self._pika_gripper # 注册共享 + # 连接设备 + if not self._pika_gripper.connect(): + logger.error('连接Pika Gripper设备失败') + if self._dev_type in [1, 3]: + self.pika_sense.disconnect() + exit(1) + logger.info('Pika Gripper设备连接成功') return self._pika_gripper diff --git a/src/ufactory_lerobot/devices/umi/__init__.py b/src/lerobot_robot_ufactory/devices/umi/__init__.py similarity index 100% rename from src/ufactory_lerobot/devices/umi/__init__.py rename to src/lerobot_robot_ufactory/devices/umi/__init__.py diff --git a/src/ufactory_lerobot/devices/umi/vive_tracker/__init__.py b/src/lerobot_robot_ufactory/devices/umi/vive_tracker/__init__.py similarity index 100% rename from src/ufactory_lerobot/devices/umi/vive_tracker/__init__.py rename to src/lerobot_robot_ufactory/devices/umi/vive_tracker/__init__.py diff --git a/src/ufactory_lerobot/devices/umi/vive_tracker/transformations.py b/src/lerobot_robot_ufactory/devices/umi/vive_tracker/transformations.py similarity index 100% rename from src/ufactory_lerobot/devices/umi/vive_tracker/transformations.py rename to src/lerobot_robot_ufactory/devices/umi/vive_tracker/transformations.py diff --git a/src/ufactory_lerobot/devices/umi/vive_tracker/vive_tracker.py b/src/lerobot_robot_ufactory/devices/umi/vive_tracker/vive_tracker.py similarity index 100% rename from src/ufactory_lerobot/devices/umi/vive_tracker/vive_tracker.py rename to src/lerobot_robot_ufactory/devices/umi/vive_tracker/vive_tracker.py diff --git a/src/ufactory_lerobot/devices/umi/xvlib/__init__.py b/src/lerobot_robot_ufactory/devices/umi/xvlib/__init__.py similarity index 100% rename from src/ufactory_lerobot/devices/umi/xvlib/__init__.py rename to src/lerobot_robot_ufactory/devices/umi/xvlib/__init__.py diff --git a/src/ufactory_lerobot/devices/umi/xvlib/libopencv_core.so.4.2 b/src/lerobot_robot_ufactory/devices/umi/xvlib/libopencv_core.so.4.2 similarity index 100% rename from src/ufactory_lerobot/devices/umi/xvlib/libopencv_core.so.4.2 rename to src/lerobot_robot_ufactory/devices/umi/xvlib/libopencv_core.so.4.2 diff --git a/src/ufactory_lerobot/devices/umi/xvlib/libopencv_imgproc.so.4.2 b/src/lerobot_robot_ufactory/devices/umi/xvlib/libopencv_imgproc.so.4.2 similarity index 100% rename from src/ufactory_lerobot/devices/umi/xvlib/libopencv_imgproc.so.4.2 rename to src/lerobot_robot_ufactory/devices/umi/xvlib/libopencv_imgproc.so.4.2 diff --git a/src/ufactory_lerobot/devices/umi/xvlib/libxvlib.so b/src/lerobot_robot_ufactory/devices/umi/xvlib/libxvlib.so similarity index 100% rename from src/ufactory_lerobot/devices/umi/xvlib/libxvlib.so rename to src/lerobot_robot_ufactory/devices/umi/xvlib/libxvlib.so diff --git a/src/ufactory_lerobot/devices/umi/xvlib/xvlib.py b/src/lerobot_robot_ufactory/devices/umi/xvlib/xvlib.py similarity index 100% rename from src/ufactory_lerobot/devices/umi/xvlib/xvlib.py rename to src/lerobot_robot_ufactory/devices/umi/xvlib/xvlib.py diff --git a/src/ufactory_lerobot/robots/__init__.py b/src/lerobot_robot_ufactory/robots/__init__.py similarity index 100% rename from src/ufactory_lerobot/robots/__init__.py rename to src/lerobot_robot_ufactory/robots/__init__.py diff --git a/src/ufactory_lerobot/robots/uf_mock_robot/__init__.py b/src/lerobot_robot_ufactory/robots/uf_mock_robot/__init__.py similarity index 100% rename from src/ufactory_lerobot/robots/uf_mock_robot/__init__.py rename to src/lerobot_robot_ufactory/robots/uf_mock_robot/__init__.py diff --git a/src/ufactory_lerobot/robots/uf_mock_robot/multiple_uf_mock_robot.py b/src/lerobot_robot_ufactory/robots/uf_mock_robot/multiple_uf_mock_robot.py similarity index 70% rename from src/ufactory_lerobot/robots/uf_mock_robot/multiple_uf_mock_robot.py rename to src/lerobot_robot_ufactory/robots/uf_mock_robot/multiple_uf_mock_robot.py index 23a6046..9f84744 100644 --- a/src/ufactory_lerobot/robots/uf_mock_robot/multiple_uf_mock_robot.py +++ b/src/lerobot_robot_ufactory/robots/uf_mock_robot/multiple_uf_mock_robot.py @@ -15,60 +15,61 @@ class MultipleUFMockRobot(Robot): def __init__(self, config: MultipleUFMockRobotConfig): super().__init__(config) self.config = config - self.keys = [] - self.robots = [] + self.robots: dict[str, UFMockRobot] = {} for key, robot_config in self.config.robots.items(): - self.keys.append(key) - self.robots.append(UFMockRobot(robot_config, prefix=key)) + self.robots[key] = UFMockRobot(robot_config, prefix=key) + + self.cameras = {} + for robot in self.robots.values(): + self.cameras.update(robot.cameras) @property def observation_features(self) -> dict: observation_features = {} - for robot in self.robots: + for robot in self.robots.values(): observation_features.update(robot.observation_features) return observation_features @property def action_features(self) -> dict: action_features = {} - for robot in self.robots: + for robot in self.robots.values(): action_features.update(robot.action_features) return action_features @property def is_connected(self) -> bool: - return all(robot.is_connected for robot in self.robots) + return all(robot.is_connected for robot in self.robots.values()) @property def is_calibrated(self) -> bool: - return all(robot.is_calibrated for robot in self.robots) + return all(robot.is_calibrated for robot in self.robots.values()) def connect(self, calibrate: bool = True) -> None: - for robot in self.robots: + for robot in self.robots.values(): robot.connect(calibrate=calibrate) def calibrate(self) -> None: - for robot in self.robots: + for robot in self.robots.values(): robot.calibrate() def configure(self) -> None: - for robot in self.robots: + for robot in self.robots.values(): robot.configure() def disconnect(self) -> None: - for robot in self.robots: + for robot in self.robots.values(): robot.disconnect() def get_observation(self) -> RobotObservation: - observations = [robot.get_observation() for robot in self.robots] + observations = [robot.get_observation() for robot in self.robots.values()] combined_observation = RobotObservation() for obs in observations: combined_observation.update(obs) return combined_observation def send_action(self, action: RobotAction) -> RobotAction: - for i in range(len(self.keys)): - key = self.keys[i] + for key, robot in self.robots.items(): action_subset = {k: v for k, v in action.items() if k.startswith(f"{key}.")} - self.robots[i].send_action(action_subset) + robot.send_action(action_subset) return action diff --git a/src/ufactory_lerobot/robots/uf_mock_robot/multiple_uf_mock_robot_config.py b/src/lerobot_robot_ufactory/robots/uf_mock_robot/multiple_uf_mock_robot_config.py similarity index 73% rename from src/ufactory_lerobot/robots/uf_mock_robot/multiple_uf_mock_robot_config.py rename to src/lerobot_robot_ufactory/robots/uf_mock_robot/multiple_uf_mock_robot_config.py index b3c8409..0a33e3c 100644 --- a/src/ufactory_lerobot/robots/uf_mock_robot/multiple_uf_mock_robot_config.py +++ b/src/lerobot_robot_ufactory/robots/uf_mock_robot/multiple_uf_mock_robot_config.py @@ -1,11 +1,13 @@ -from dataclasses import dataclass +from dataclasses import dataclass, field from lerobot.robots import RobotConfig from .uf_mock_robot_config import UFMockRobotConfig @RobotConfig.register_subclass("uf::multiple_mock_robot") @dataclass class MultipleUFMockRobotConfig(RobotConfig): - robots: dict[str, UFMockRobotConfig] + robots: dict[str, RobotConfig] = field( + default_factory=lambda: {} + ) def __post_init__(self): super().__post_init__() diff --git a/src/ufactory_lerobot/robots/uf_mock_robot/uf_mock_robot.py b/src/lerobot_robot_ufactory/robots/uf_mock_robot/uf_mock_robot.py similarity index 96% rename from src/ufactory_lerobot/robots/uf_mock_robot/uf_mock_robot.py rename to src/lerobot_robot_ufactory/robots/uf_mock_robot/uf_mock_robot.py index 9048598..5b7f588 100644 --- a/src/ufactory_lerobot/robots/uf_mock_robot/uf_mock_robot.py +++ b/src/lerobot_robot_ufactory/robots/uf_mock_robot/uf_mock_robot.py @@ -1,6 +1,7 @@ import numpy as np from lerobot.cameras.utils import make_cameras_from_configs from lerobot.robots import Robot +from lerobot_robot_ufactory.context import get_active_teleop from .uf_mock_robot_config import UFMockRobotConfig @@ -31,7 +32,6 @@ class UFMockRobot(Robot): self._jnt_obs_has_vel = config.observe_joint_vel if self._control_space == "joint" else False self._is_connected = False self._is_calibrated =True - self._teleop = self.config.teleop self._cache_num = self.config.state_offset_action self._teleop_actions = [] @@ -98,7 +98,8 @@ class UFMockRobot(Robot): pass # CHECK! currently No-op def get_observation(self) -> dict[str, np.ndarray]: - new_act = self._teleop.get_action() + teleop = get_active_teleop(self.config.teleop_id) + new_act = teleop.get_action() if teleop else {} # Capture images from cameras for cam_key, cam in self.cameras.items(): new_act[f"{self.prefix}{cam_key}"] = cam.async_read() diff --git a/src/ufactory_lerobot/robots/uf_mock_robot/uf_mock_robot_config.py b/src/lerobot_robot_ufactory/robots/uf_mock_robot/uf_mock_robot_config.py similarity index 91% rename from src/ufactory_lerobot/robots/uf_mock_robot/uf_mock_robot_config.py rename to src/lerobot_robot_ufactory/robots/uf_mock_robot/uf_mock_robot_config.py index 492b216..7ca3cbc 100644 --- a/src/ufactory_lerobot/robots/uf_mock_robot/uf_mock_robot_config.py +++ b/src/lerobot_robot_ufactory/robots/uf_mock_robot/uf_mock_robot_config.py @@ -5,6 +5,7 @@ from lerobot.robots import RobotConfig @RobotConfig.register_subclass("uf::mock_robot") @dataclass class UFMockRobotConfig(RobotConfig): + teleop_id: str cameras: dict[str, CameraConfig] = field( default_factory=lambda: {} ) @@ -13,7 +14,6 @@ class UFMockRobotConfig(RobotConfig): control_space: str = "joint" gripper_type: int = 1 # 1: xArm Gripper, 10: Pika Gripper observe_joint_vel: bool = False # only effective in joint control mode - teleop: None = None # from lerobot.teleoperators import Teleoperator state_offset_action: int = 3 # the number of previous teleop actions to be included in the observation def __post_init__(self): diff --git a/src/ufactory_lerobot/robots/uf_robot/__init__.py b/src/lerobot_robot_ufactory/robots/uf_robot/__init__.py similarity index 100% rename from src/ufactory_lerobot/robots/uf_robot/__init__.py rename to src/lerobot_robot_ufactory/robots/uf_robot/__init__.py diff --git a/src/ufactory_lerobot/robots/uf_robot/multiple_uf_robot.py b/src/lerobot_robot_ufactory/robots/uf_robot/multiple_uf_robot.py similarity index 100% rename from src/ufactory_lerobot/robots/uf_robot/multiple_uf_robot.py rename to src/lerobot_robot_ufactory/robots/uf_robot/multiple_uf_robot.py diff --git a/src/ufactory_lerobot/robots/uf_robot/multiple_uf_robot_config.py b/src/lerobot_robot_ufactory/robots/uf_robot/multiple_uf_robot_config.py similarity index 76% rename from src/ufactory_lerobot/robots/uf_robot/multiple_uf_robot_config.py rename to src/lerobot_robot_ufactory/robots/uf_robot/multiple_uf_robot_config.py index ba1bc53..af6b16d 100644 --- a/src/ufactory_lerobot/robots/uf_robot/multiple_uf_robot_config.py +++ b/src/lerobot_robot_ufactory/robots/uf_robot/multiple_uf_robot_config.py @@ -1,11 +1,13 @@ -from dataclasses import dataclass +from dataclasses import dataclass, field from lerobot.robots import RobotConfig from .uf_robot_config import UFRobotConfig @RobotConfig.register_subclass("uf::multiple_robot") @dataclass class MultipleUFRobotConfig(RobotConfig): - robots: dict[str, UFRobotConfig] + robots: dict[str, RobotConfig] = field( + default_factory=lambda: {} + ) async_connect: bool = True async_configure: bool = True async_action: bool = False diff --git a/src/ufactory_lerobot/robots/uf_robot/uf_robot.py b/src/lerobot_robot_ufactory/robots/uf_robot/uf_robot.py similarity index 99% rename from src/ufactory_lerobot/robots/uf_robot/uf_robot.py rename to src/lerobot_robot_ufactory/robots/uf_robot/uf_robot.py index db14656..6c4bf03 100644 --- a/src/ufactory_lerobot/robots/uf_robot/uf_robot.py +++ b/src/lerobot_robot_ufactory/robots/uf_robot/uf_robot.py @@ -10,7 +10,7 @@ from dataclasses import dataclass from threading import Thread, Event, Lock from lerobot.robots import Robot from lerobot.cameras.utils import make_cameras_from_configs -from ufactory_lerobot.devices.pika import PikaDevice +from lerobot_robot_ufactory.devices.pika import PikaDevice from .uf_robot_config import UFRobotConfig from xarm.wrapper import XArmAPI from xarm.core.utils import convert diff --git a/src/ufactory_lerobot/robots/uf_robot/uf_robot_config.py b/src/lerobot_robot_ufactory/robots/uf_robot/uf_robot_config.py similarity index 100% rename from src/ufactory_lerobot/robots/uf_robot/uf_robot_config.py rename to src/lerobot_robot_ufactory/robots/uf_robot/uf_robot_config.py diff --git a/src/ufactory_lerobot/robots/utils.py b/src/lerobot_robot_ufactory/robots/utils.py similarity index 100% rename from src/ufactory_lerobot/robots/utils.py rename to src/lerobot_robot_ufactory/robots/utils.py diff --git a/src/ufactory_lerobot/scripts/uf_camera_view.py b/src/lerobot_robot_ufactory/scripts/uf_camera_view.py similarity index 100% rename from src/ufactory_lerobot/scripts/uf_camera_view.py rename to src/lerobot_robot_ufactory/scripts/uf_camera_view.py diff --git a/src/lerobot_robot_ufactory/scripts/uf_download_resources.py b/src/lerobot_robot_ufactory/scripts/uf_download_resources.py new file mode 100644 index 0000000..de44ddd --- /dev/null +++ b/src/lerobot_robot_ufactory/scripts/uf_download_resources.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +"""Download XVSDK binaries and UMI shared libraries after install.""" +import os +import sys +import urllib.request +import subprocess +import site + +RESOURCES = "https://raw.githubusercontent.com/xArm-Developer/ufactory_resources/main/fastumi" + +FILES = [ + # (url_path, subdir) + ("libxvlib.so", ""), + ("opencv/libopencv_core.so.4.2", ""), + ("opencv/libopencv_imgproc.so.4.2", ""), +] + +DEB_FILE = "sdk/XVSDK_focal_amd64.deb" + + +def get_pkg_dir(): + """Find the installed ufactory_lerobot package directory.""" + for sp in site.getsitepackages(): + path = os.path.join(sp, "ufactory_lerobot", "devices", "umi", "xvlib") + if os.path.isdir(path): + return path + # fallback: try user site + usp = site.getusersitepackages() + if usp: + return os.path.join(usp, "ufactory_lerobot", "devices", "umi", "xvlib") + sys.exit("Error: cannot find installed ufactory_lerobot package.") + + +def download(url, dest): + print(f" -> {dest}") + os.makedirs(os.path.dirname(dest), exist_ok=True) + urllib.request.urlretrieve(url, dest) + + +def main(): + pkg_dir = get_pkg_dir() + print(f"Installing to: {pkg_dir}\n") + + for name, subdir in FILES: + url = f"{RESOURCES}/{name}" + dest = os.path.join(pkg_dir, os.path.basename(name)) + print(f"Downloading {name} ...") + download(url, dest) + + # .deb: download to /tmp and install + deb_url = f"{RESOURCES}/{DEB_FILE}" + deb_path = "/tmp/XVSDK_focal_amd64.deb" + print(f"\nDownloading {DEB_FILE} ...") + download(deb_url, deb_path) + + print("\nInstalling XVSDK ...") + ret = subprocess.run(["sudo", "dpkg", "-i", deb_path]).returncode + if ret != 0: + subprocess.run(["sudo", "apt", "install", "-y", "--fix-broken"]) + os.unlink(deb_path) + + print("\nDone.") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/ufactory_lerobot/scripts/uf_lerobot_eval.py b/src/lerobot_robot_ufactory/scripts/uf_lerobot_eval.py similarity index 95% rename from src/ufactory_lerobot/scripts/uf_lerobot_eval.py rename to src/lerobot_robot_ufactory/scripts/uf_lerobot_eval.py index e5f6425..17234ed 100644 --- a/src/ufactory_lerobot/scripts/uf_lerobot_eval.py +++ b/src/lerobot_robot_ufactory/scripts/uf_lerobot_eval.py @@ -1,15 +1,13 @@ -import yaml +import sys import argparse import logging import time import math -import torch from pathlib import Path from dataclasses import asdict, dataclass from pprint import pformat -from contextlib import nullcontext import numpy as np -import ufactory_lerobot # patch +import lerobot_robot_ufactory # patch from lerobot.scripts.lerobot_record import register_third_party_plugins from lerobot.datasets.pipeline_features import aggregate_pipeline_dataset_features, create_initial_features from lerobot.datasets.utils import build_dataset_frame, combine_feature_dicts @@ -39,8 +37,8 @@ from lerobot.configs import parser from lerobot.configs.policies import PreTrainedConfig from lerobot.scripts.lerobot_record import DatasetRecordConfig from lerobot.datasets.lerobot_dataset import LeRobotDataset -from ufactory_lerobot.utils.utils import instantiate_from_dict, init_keyboard_listener -from ufactory_lerobot.devices.umi.vive_tracker.transformations import Transformations +from lerobot_robot_ufactory.utils.utils import init_keyboard_listener +from lerobot_robot_ufactory.devices.umi.vive_tracker.transformations import Transformations def continuous_rotvec(new_rv, prev_rv): @@ -98,6 +96,7 @@ def compute_target_axis_angle(rot_prev, rot_delta): class EvalConfig: robot: RobotConfig dataset: DatasetRecordConfig + teleop: dict = None # no use # Whether to control the robot with a policy policy: PreTrainedConfig | None = None n_episodes: int = 50 @@ -414,26 +413,19 @@ def eval_loop(cfg: EvalConfig, relative=False, rx_continuous=False): if not is_headless() and listener is not None: listener.stop() +@parser.wrap() +def get_cfg(cfg: EvalConfig) -> EvalConfig: + return cfg + def main(): parser = argparse.ArgumentParser(description='configuration args') - parser.add_argument('-c', '--config', type=str, required=True, - help='configuration file path, e.g.my_config.yaml') - parser.add_argument('--policy.path', type=str, required=True, - help='configuration file path, e.g.my_config.yaml') parser.add_argument('--relative', action='store_true', help='is relative motion or not') parser.add_argument('--rx_continuous', action='store_true', help='rx continuous or not') - args = parser.parse_args() - try: - with open(args.config, 'r') as f: - cfg = yaml.safe_load(f) - except Exception as e: - print(f"Error loading config yaml file: {e}") - else: - register_third_party_plugins() - config = instantiate_from_dict(cfg) - - eval_cfg = EvalConfig(robot=config["RobotConfig"], dataset=config["DatasetRecordConfig"]) - eval_loop(eval_cfg, args.relative, args.rx_continuous) + args, unknown = parser.parse_known_args() + sys.argv = [sys.argv[0]] + unknown + register_third_party_plugins() + cfg = get_cfg() + eval_loop(cfg, args.relative, args.rx_continuous) if __name__ == "__main__": diff --git a/src/ufactory_lerobot/scripts/uf_lerobot_record.py b/src/lerobot_robot_ufactory/scripts/uf_lerobot_record.py similarity index 95% rename from src/ufactory_lerobot/scripts/uf_lerobot_record.py rename to src/lerobot_robot_ufactory/scripts/uf_lerobot_record.py index b3ea386..6549d7e 100644 --- a/src/ufactory_lerobot/scripts/uf_lerobot_record.py +++ b/src/lerobot_robot_ufactory/scripts/uf_lerobot_record.py @@ -1,4 +1,4 @@ -import yaml +import sys import copy import time import queue @@ -7,11 +7,11 @@ import logging import shutil import threading from pathlib import Path -import ufactory_lerobot # patch +import lerobot_robot_ufactory # patch from lerobot.scripts.lerobot_record import * -from ufactory_lerobot.teleoperators.uf_mock_teleop import UFMockTeleop -from ufactory_lerobot.teleoperators.base_teleop import UFBaseTeleop -from ufactory_lerobot.utils.utils import instantiate_from_dict, init_keyboard_listener +from lerobot_robot_ufactory.teleoperators.uf_mock_teleop import UFMockTeleop +from lerobot_robot_ufactory.teleoperators.base_teleop import UFBaseTeleop +from lerobot_robot_ufactory.utils.utils import init_keyboard_listener def _get_dataset_writer(dataset): @@ -344,17 +344,14 @@ def record_loop( timestamp = time.perf_counter() - start_episode_t -@parser.wrap() def record(cfg: RecordConfig, async_save: bool = False) -> LeRobotDataset: init_logging() logging.info(pformat(asdict(cfg))) if cfg.display_data: init_rerun(session_name="recording") - teleop = make_teleoperator_from_config(cfg.teleop) if cfg.teleop is not None else None - if hasattr(cfg.robot, "teleop"): - cfg.robot.teleop = teleop robot = make_robot_from_config(cfg.robot) + teleop = make_teleoperator_from_config(cfg.teleop) if cfg.teleop is not None else None teleop_action_processor, robot_action_processor, robot_observation_processor = make_default_processors() @@ -592,31 +589,28 @@ def record(cfg: RecordConfig, async_save: bool = False) -> LeRobotDataset: log_say("Exiting", cfg.play_sounds) return dataset +@parser.wrap() +def get_cfg(cfg: RecordConfig) -> RecordConfig: + return cfg def main(): parser = argparse.ArgumentParser(description='configuration args') - parser.add_argument('-c', '--config', type=str, required=True, - help='configuration file path, e.g.my_config.yaml') - parser.add_argument('-r', '--resume', + parser.add_argument('-r', action='store_true', # specify --resume if resume needs to be True default=False, help='Whether contitue recording on existing dataset (default: False)') - parser.add_argument('-a', '--async-save', + parser.add_argument('-a', '--async_save', action='store_true', default=False, help='Enable async background saving (default: False)') - args = parser.parse_args() - try: - with open(Path(args.config).expanduser(), 'r') as f: - cfg = yaml.safe_load(f) - except Exception as e: - print(f"Error loading config yaml file: {e}") - else: - register_third_party_plugins() - config = instantiate_from_dict(cfg) - - record_cfg = RecordConfig(resume=args.resume, play_sounds=False, robot=config["RobotConfig"], dataset=config["DatasetRecordConfig"], teleop=config["TeleoperatorConfig"]) - record(record_cfg, async_save=args.async_save) + args, unknown = parser.parse_known_args() + sys.argv = [sys.argv[0]] + unknown + register_third_party_plugins() + cfg = get_cfg() + if args.r: + cfg.resume = True + cfg.play_sounds = False + record(cfg, async_save=args.async_save) if __name__ == "__main__": diff --git a/src/ufactory_lerobot/scripts/uf_robot_teleop.py b/src/lerobot_robot_ufactory/scripts/uf_robot_teleop.py similarity index 85% rename from src/ufactory_lerobot/scripts/uf_robot_teleop.py rename to src/lerobot_robot_ufactory/scripts/uf_robot_teleop.py index a0fa902..f11f36d 100644 --- a/src/ufactory_lerobot/scripts/uf_robot_teleop.py +++ b/src/lerobot_robot_ufactory/scripts/uf_robot_teleop.py @@ -1,11 +1,11 @@ -import yaml +import sys import argparse import logging import time from pathlib import Path from dataclasses import asdict, dataclass from pprint import pformat -import ufactory_lerobot # patch +import lerobot_robot_ufactory # patch from lerobot.scripts.lerobot_record import register_third_party_plugins from lerobot.processor import ( make_default_processors, @@ -23,14 +23,16 @@ from lerobot.utils.robot_utils import precise_sleep from lerobot.utils.utils import ( init_logging, ) -from ufactory_lerobot.utils.utils import instantiate_from_dict, is_headless, init_keyboard_listener -from ufactory_lerobot.teleoperators.base_teleop import UFBaseTeleop +from lerobot.configs import parser +from lerobot_robot_ufactory.utils.utils import is_headless, init_keyboard_listener +from lerobot_robot_ufactory.teleoperators.base_teleop import UFBaseTeleop @dataclass class TeleopConfig: robot: RobotConfig teleop: TeleoperatorConfig + dataset: dict = None # no use fps: int = 30 @@ -167,24 +169,17 @@ def teleop_loop(cfg: TeleopConfig): if is_evt and listener is not None: listener.stop() +@parser.wrap() +def get_cfg(cfg: TeleopConfig) -> TeleopConfig: + return cfg + def main(): parser = argparse.ArgumentParser(description='configuration args') - parser.add_argument('-c', '--config', type=str, required=True, - help='configuration file path, e.g.my_config.yaml') - parser.add_argument('-f', '--fps', type=int, default=30, - help='control loop frequency in Hz (default: 30)') - args = parser.parse_args() - try: - with open(Path(args.config).expanduser(), 'r') as f: - cfg = yaml.safe_load(f) - except Exception as e: - print(f"Error loading config yaml file: {e}") - else: - register_third_party_plugins() - config = instantiate_from_dict(cfg, ignore_cameras=True) - - teleop_cfg = TeleopConfig(robot=config["RobotConfig"], teleop=config["TeleoperatorConfig"], fps=args.fps) - teleop_loop(teleop_cfg) + args, unknown = parser.parse_known_args() + sys.argv = [sys.argv[0]] + unknown + register_third_party_plugins() + cfg = get_cfg() + teleop_loop(cfg) if __name__ == "__main__": diff --git a/src/ufactory_lerobot/scripts/vive_calibrate.py b/src/lerobot_robot_ufactory/scripts/vive_calibrate.py similarity index 100% rename from src/ufactory_lerobot/scripts/vive_calibrate.py rename to src/lerobot_robot_ufactory/scripts/vive_calibrate.py diff --git a/src/ufactory_lerobot/teleoperators/__init__.py b/src/lerobot_robot_ufactory/teleoperators/__init__.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/__init__.py rename to src/lerobot_robot_ufactory/teleoperators/__init__.py diff --git a/src/ufactory_lerobot/teleoperators/base_teleop/__init__.py b/src/lerobot_robot_ufactory/teleoperators/base_teleop/__init__.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/base_teleop/__init__.py rename to src/lerobot_robot_ufactory/teleoperators/base_teleop/__init__.py diff --git a/src/ufactory_lerobot/teleoperators/base_teleop/base_teleop.py b/src/lerobot_robot_ufactory/teleoperators/base_teleop/base_teleop.py similarity index 66% rename from src/ufactory_lerobot/teleoperators/base_teleop/base_teleop.py rename to src/lerobot_robot_ufactory/teleoperators/base_teleop/base_teleop.py index ef9d612..8efb141 100644 --- a/src/ufactory_lerobot/teleoperators/base_teleop/base_teleop.py +++ b/src/lerobot_robot_ufactory/teleoperators/base_teleop/base_teleop.py @@ -1,4 +1,5 @@ from lerobot.teleoperators import Teleoperator +from lerobot_robot_ufactory.context import register_teleop, unregister_teleop class UFBaseTeleop(Teleoperator): @@ -9,6 +10,12 @@ class UFBaseTeleop(Teleoperator): super().__init__(config) self.config = config + def connect(self, calibrate: bool = False) -> None: + register_teleop(self) + + def disconnect(self): + unregister_teleop(self) + def set_teleop_enabled(self, enabled: bool, obs=None): """ 启用/停用遥操作 diff --git a/src/ufactory_lerobot/teleoperators/gello_teleop/__init__.py b/src/lerobot_robot_ufactory/teleoperators/gello_teleop/__init__.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/gello_teleop/__init__.py rename to src/lerobot_robot_ufactory/teleoperators/gello_teleop/__init__.py diff --git a/src/ufactory_lerobot/teleoperators/gello_teleop/gello_teleop.py b/src/lerobot_robot_ufactory/teleoperators/gello_teleop/gello_teleop.py similarity index 99% rename from src/ufactory_lerobot/teleoperators/gello_teleop/gello_teleop.py rename to src/lerobot_robot_ufactory/teleoperators/gello_teleop/gello_teleop.py index f79d5a2..4bea1b3 100644 --- a/src/ufactory_lerobot/teleoperators/gello_teleop/gello_teleop.py +++ b/src/lerobot_robot_ufactory/teleoperators/gello_teleop/gello_teleop.py @@ -103,6 +103,7 @@ class GelloTeleop(UFBaseTeleop): self.configure() self._is_connected = True + super().connect(calibrate) logger.info(f"{self} connected.") @property diff --git a/src/ufactory_lerobot/teleoperators/gello_teleop/gello_teleop_config.py b/src/lerobot_robot_ufactory/teleoperators/gello_teleop/gello_teleop_config.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/gello_teleop/gello_teleop_config.py rename to src/lerobot_robot_ufactory/teleoperators/gello_teleop/gello_teleop_config.py diff --git a/src/ufactory_lerobot/teleoperators/pika_teleop/__init__.py b/src/lerobot_robot_ufactory/teleoperators/pika_teleop/__init__.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/pika_teleop/__init__.py rename to src/lerobot_robot_ufactory/teleoperators/pika_teleop/__init__.py diff --git a/src/ufactory_lerobot/teleoperators/pika_teleop/pika_teleop.py b/src/lerobot_robot_ufactory/teleoperators/pika_teleop/pika_teleop.py similarity index 97% rename from src/ufactory_lerobot/teleoperators/pika_teleop/pika_teleop.py rename to src/lerobot_robot_ufactory/teleoperators/pika_teleop/pika_teleop.py index 2b49200..5899c22 100644 --- a/src/ufactory_lerobot/teleoperators/pika_teleop/pika_teleop.py +++ b/src/lerobot_robot_ufactory/teleoperators/pika_teleop/pika_teleop.py @@ -5,8 +5,8 @@ import math from typing import Any from threading import Thread, Event, Lock from lerobot.utils.errors import DeviceNotConnectedError -from ufactory_lerobot.devices.pika import PikaDevice -from ufactory_lerobot.devices.umi.vive_tracker.transformations import Transformations +from lerobot_robot_ufactory.devices.pika import PikaDevice +from lerobot_robot_ufactory.devices.umi.vive_tracker.transformations import Transformations from ..base_teleop import UFBaseTeleop from .pika_teleop_config import PikaTeleopConfig @@ -87,6 +87,7 @@ class PikaTeleop(UFBaseTeleop, Thread): pass def connect(self, calibrate: bool = False) -> None: + super().connect(calibrate) self.start() def disconnect(self): diff --git a/src/ufactory_lerobot/teleoperators/pika_teleop/pika_teleop_config.py b/src/lerobot_robot_ufactory/teleoperators/pika_teleop/pika_teleop_config.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/pika_teleop/pika_teleop_config.py rename to src/lerobot_robot_ufactory/teleoperators/pika_teleop/pika_teleop_config.py diff --git a/src/ufactory_lerobot/teleoperators/space_mouse/__init__.py b/src/lerobot_robot_ufactory/teleoperators/space_mouse/__init__.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/space_mouse/__init__.py rename to src/lerobot_robot_ufactory/teleoperators/space_mouse/__init__.py diff --git a/src/ufactory_lerobot/teleoperators/space_mouse/space_mouse.py b/src/lerobot_robot_ufactory/teleoperators/space_mouse/space_mouse.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/space_mouse/space_mouse.py rename to src/lerobot_robot_ufactory/teleoperators/space_mouse/space_mouse.py diff --git a/src/ufactory_lerobot/teleoperators/space_mouse/space_mouse_config.py b/src/lerobot_robot_ufactory/teleoperators/space_mouse/space_mouse_config.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/space_mouse/space_mouse_config.py rename to src/lerobot_robot_ufactory/teleoperators/space_mouse/space_mouse_config.py diff --git a/src/ufactory_lerobot/teleoperators/uf_mock_teleop/__init__.py b/src/lerobot_robot_ufactory/teleoperators/uf_mock_teleop/__init__.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/uf_mock_teleop/__init__.py rename to src/lerobot_robot_ufactory/teleoperators/uf_mock_teleop/__init__.py diff --git a/src/ufactory_lerobot/teleoperators/uf_mock_teleop/uf_mock_teleop.py b/src/lerobot_robot_ufactory/teleoperators/uf_mock_teleop/uf_mock_teleop.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/uf_mock_teleop/uf_mock_teleop.py rename to src/lerobot_robot_ufactory/teleoperators/uf_mock_teleop/uf_mock_teleop.py diff --git a/src/ufactory_lerobot/teleoperators/uf_mock_teleop/uf_mock_teleop_config.py b/src/lerobot_robot_ufactory/teleoperators/uf_mock_teleop/uf_mock_teleop_config.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/uf_mock_teleop/uf_mock_teleop_config.py rename to src/lerobot_robot_ufactory/teleoperators/uf_mock_teleop/uf_mock_teleop_config.py diff --git a/src/ufactory_lerobot/teleoperators/umi_teleop/__init__.py b/src/lerobot_robot_ufactory/teleoperators/umi_teleop/__init__.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/umi_teleop/__init__.py rename to src/lerobot_robot_ufactory/teleoperators/umi_teleop/__init__.py diff --git a/src/ufactory_lerobot/teleoperators/umi_teleop/multiple_umi_teleop.py b/src/lerobot_robot_ufactory/teleoperators/umi_teleop/multiple_umi_teleop.py similarity index 97% rename from src/ufactory_lerobot/teleoperators/umi_teleop/multiple_umi_teleop.py rename to src/lerobot_robot_ufactory/teleoperators/umi_teleop/multiple_umi_teleop.py index d2dccc0..3608e15 100644 --- a/src/ufactory_lerobot/teleoperators/umi_teleop/multiple_umi_teleop.py +++ b/src/lerobot_robot_ufactory/teleoperators/umi_teleop/multiple_umi_teleop.py @@ -40,6 +40,7 @@ class MultipleUmiTeleop(UFBaseTeleop): return all(teleop.is_calibrated for teleop in self.teleops.values()) def connect(self, calibrate: bool = True) -> None: + super().connect(calibrate) for teleop in self.teleops.values(): teleop.connect(calibrate=calibrate) @@ -52,6 +53,7 @@ class MultipleUmiTeleop(UFBaseTeleop): teleop.configure() def disconnect(self) -> None: + super().disconnect() for teleop in self.teleops.values(): teleop.disconnect() diff --git a/src/ufactory_lerobot/teleoperators/umi_teleop/multiple_umi_teleop_config.py b/src/lerobot_robot_ufactory/teleoperators/umi_teleop/multiple_umi_teleop_config.py similarity index 87% rename from src/ufactory_lerobot/teleoperators/umi_teleop/multiple_umi_teleop_config.py rename to src/lerobot_robot_ufactory/teleoperators/umi_teleop/multiple_umi_teleop_config.py index 0872dac..9894e03 100644 --- a/src/ufactory_lerobot/teleoperators/umi_teleop/multiple_umi_teleop_config.py +++ b/src/lerobot_robot_ufactory/teleoperators/umi_teleop/multiple_umi_teleop_config.py @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from dataclasses import dataclass +from dataclasses import dataclass, field from lerobot.teleoperators import TeleoperatorConfig from .umi_teleop_config import UmiTeleopConfig @@ -22,7 +22,9 @@ from .umi_teleop_config import UmiTeleopConfig @TeleoperatorConfig.register_subclass("uf::multiple_umi_teleop") @dataclass class MultipleUmiTeleopConfig(TeleoperatorConfig): - teleops: dict[str, UmiTeleopConfig] + teleops: dict[str, TeleoperatorConfig] = field( + default_factory=lambda: {} + ) def __post_init__(self): self.id = 'multiple_umi_teleop' if self.id is None else self.id \ No newline at end of file diff --git a/src/ufactory_lerobot/teleoperators/umi_teleop/umi_teleop.py b/src/lerobot_robot_ufactory/teleoperators/umi_teleop/umi_teleop.py similarity index 95% rename from src/ufactory_lerobot/teleoperators/umi_teleop/umi_teleop.py rename to src/lerobot_robot_ufactory/teleoperators/umi_teleop/umi_teleop.py index 225f8be..2c6954d 100644 --- a/src/ufactory_lerobot/teleoperators/umi_teleop/umi_teleop.py +++ b/src/lerobot_robot_ufactory/teleoperators/umi_teleop/umi_teleop.py @@ -3,8 +3,8 @@ import math from typing import Any from lerobot.utils.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from ufactory_lerobot.devices.umi.vive_tracker.transformations import Transformations -from ufactory_lerobot.devices.umi.vive_tracker import ViveTracker +from lerobot_robot_ufactory.devices.umi.vive_tracker.transformations import Transformations +from lerobot_robot_ufactory.devices.umi.vive_tracker import ViveTracker from ..base_teleop import UFBaseTeleop from .umi_teleop_config import UmiTeleopConfig @@ -26,7 +26,7 @@ class UmiTeleop(UFBaseTeleop): self.tracker = None self.xvlib = None - # from ufactory_lerobot.devices.umi.xvlib import XVLib + # from lerobot_robot_ufactory.devices.umi.xvlib import XVLib # self.tracker = ViveTracker() if self.config.use_vive_tracker else None # self.xvlib = XVLib(self.config.serial_number, not self.config.use_vive_tracker, self.config.use_gripper) @@ -84,7 +84,7 @@ class UmiTeleop(UFBaseTeleop): pass def connect(self, calibrate: bool = False) -> None: - from ufactory_lerobot.devices.umi.xvlib import XVLib + from lerobot_robot_ufactory.devices.umi.xvlib import XVLib self.tracker = ViveTracker() if self.config.use_vive_tracker else None self.xvlib = XVLib(self.config.serial_number, not self.config.use_vive_tracker, self.config.use_gripper) if not self.config.use_vive_tracker: @@ -92,8 +92,10 @@ class UmiTeleop(UFBaseTeleop): if self.config.use_gripper: self.xvlib.xv_clamp_stream_init() self._is_connected = True + super().connect(calibrate) def disconnect(self): + super().disconnect() if self.xvlib: self.xvlib.xv_uninit() self._is_connected = False diff --git a/src/ufactory_lerobot/teleoperators/umi_teleop/umi_teleop_config.py b/src/lerobot_robot_ufactory/teleoperators/umi_teleop/umi_teleop_config.py similarity index 94% rename from src/ufactory_lerobot/teleoperators/umi_teleop/umi_teleop_config.py rename to src/lerobot_robot_ufactory/teleoperators/umi_teleop/umi_teleop_config.py index e4ff7e2..400bddb 100644 --- a/src/ufactory_lerobot/teleoperators/umi_teleop/umi_teleop_config.py +++ b/src/lerobot_robot_ufactory/teleoperators/umi_teleop/umi_teleop_config.py @@ -30,4 +30,4 @@ class UmiTeleopConfig(TeleoperatorConfig): robot_base_pose: Tuple[float, ...] = (300, 0, 300, 180, -90, 0) # [x, y, z, roll(°), pitch(°), yaw(°)] def __post_init__(self): - self.id = 'umi_teleop' if self.id is None else self.id + self.id = self.serial_number if self.id is None else self.id diff --git a/src/ufactory_lerobot/teleoperators/utils.py b/src/lerobot_robot_ufactory/teleoperators/utils.py similarity index 100% rename from src/ufactory_lerobot/teleoperators/utils.py rename to src/lerobot_robot_ufactory/teleoperators/utils.py diff --git a/src/ufactory_lerobot/utils/__init__.py b/src/lerobot_robot_ufactory/utils/__init__.py similarity index 100% rename from src/ufactory_lerobot/utils/__init__.py rename to src/lerobot_robot_ufactory/utils/__init__.py diff --git a/src/ufactory_lerobot/utils/utils.py b/src/lerobot_robot_ufactory/utils/utils.py similarity index 100% rename from src/ufactory_lerobot/utils/utils.py rename to src/lerobot_robot_ufactory/utils/utils.py