Compare commits
77 Commits
main
...
feature-vi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d19a88ac6 | ||
|
|
ac4a1fc8f2 | ||
|
|
9047e71206 | ||
|
|
da61cf8709 | ||
|
|
c4f07c73fb | ||
|
|
3fc1de3a1a | ||
|
|
02f7c103c7 | ||
|
|
c1a7205e10 | ||
|
|
c929176625 | ||
|
|
f191008b5a | ||
|
|
a36903f467 | ||
|
|
2d4a1edb10 | ||
|
|
88dceb1a1a | ||
|
|
0b6f18729c | ||
|
|
385527dc2a | ||
|
|
2348200dc7 | ||
|
|
79187e6645 | ||
|
|
1c7605e397 | ||
|
|
68563e2162 | ||
|
|
5c3994da9d | ||
|
|
ac6bf49e75 | ||
|
|
4e0d53d41e | ||
|
|
19d59c50db | ||
|
|
1ee0c96bb6 | ||
|
|
4ec5ff7a05 | ||
|
|
c9fc59119e | ||
|
|
869e77d3c8 | ||
|
|
5cf006a3e5 | ||
|
|
40b38dfd00 | ||
|
|
b063044249 | ||
|
|
56ec283a44 | ||
|
|
acffa0e6db | ||
|
|
f56490c5b1 | ||
|
|
994f2a574f | ||
|
|
7f05981c15 | ||
|
|
34d4f4cce6 | ||
|
|
75b2dd5d3f | ||
|
|
0ced39b18d | ||
|
|
180fbe4789 | ||
| afc4d983c8 | |||
| 948785a1a8 | |||
| 9fe000911f | |||
| b4b3c3b80c | |||
| 1b69632c7b | |||
| f9992d8437 | |||
| 0992caae72 | |||
| 4f679c77ae | |||
| 1951dd8276 | |||
| e8f1021af1 | |||
| 79ade2d741 | |||
| 53e62e2714 | |||
| 3d79cf2eb8 | |||
| 9ecdb1be60 | |||
|
|
eed410e776 | ||
|
|
114ba598d0 | ||
|
|
7753f2f569 | ||
|
|
0ba8bf79e6 | ||
|
|
0b915a0dee | ||
|
|
e2227cce31 | ||
|
|
4721d7f7e6 | ||
|
|
212e652d72 | ||
| a96384e8f3 | |||
|
|
f0b847af96 | ||
|
|
897597ae6d | ||
|
|
37e650512e | ||
|
|
9a2f17f8b4 | ||
|
|
4ae6b84595 | ||
|
|
2e1fc55e47 | ||
|
|
100e06fe81 | ||
|
|
893bca0d2e | ||
|
|
948aba7e84 | ||
|
|
0b21c86d31 | ||
| b6934ff229 | |||
| ff116c9b72 | |||
| 967b7bdf9b | |||
| 74c6ee0046 | |||
| 4da85d16dc |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
build/
|
||||
install/
|
||||
log/
|
||||
logs/
|
||||
|
||||
.vscode/
|
||||
.venv/
|
||||
@@ -14,7 +14,6 @@ find_package(rclcpp_components REQUIRED)
|
||||
# find_package(<dependency> REQUIRED)
|
||||
|
||||
find_package(interfaces REQUIRED)
|
||||
find_package(brain_interfaces REQUIRED)
|
||||
find_package(std_msgs REQUIRED)
|
||||
find_package(smacc2 REQUIRED)
|
||||
find_package(smacc2_msgs REQUIRED)
|
||||
@@ -35,13 +34,17 @@ find_package(tf2_geometry_msgs REQUIRED)
|
||||
add_executable(brain_node
|
||||
src/brain_node.cpp
|
||||
src/cerebellum_node.cpp
|
||||
src/cerebellum_hooks.cpp
|
||||
src/cerebrum_node.cpp
|
||||
src/skill_manager.cpp
|
||||
src/calc_grasp_pose.cpp
|
||||
)
|
||||
|
||||
target_include_directories(brain_node PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>)
|
||||
$<INSTALL_INTERFACE:include>
|
||||
interfaces/include
|
||||
)
|
||||
|
||||
target_compile_features(brain_node PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17
|
||||
|
||||
@@ -51,7 +54,6 @@ ament_target_dependencies(brain_node
|
||||
rclcpp_action
|
||||
behaviortree_cpp
|
||||
interfaces
|
||||
brain_interfaces
|
||||
std_msgs
|
||||
smacc2
|
||||
smacc2_msgs
|
||||
@@ -76,6 +78,11 @@ install(TARGETS brain_node
|
||||
install(DIRECTORY config/
|
||||
DESTINATION share/${PROJECT_NAME}/config)
|
||||
|
||||
install(DIRECTORY launch/
|
||||
DESTINATION share/${PROJECT_NAME}/launch)
|
||||
|
||||
set (BUILD_TESTING OFF)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
if(NOT DEFINED ENV{SKIP_LINT})
|
||||
find_package(ament_lint_auto REQUIRED)
|
||||
@@ -103,7 +110,6 @@ if(BUILD_TESTING)
|
||||
rclcpp
|
||||
rclcpp_action
|
||||
interfaces
|
||||
brain_interfaces
|
||||
nav2_msgs
|
||||
std_srvs
|
||||
tf2
|
||||
@@ -158,14 +164,15 @@ if(BUILD_TESTING)
|
||||
smacc2_msgs
|
||||
ament_index_cpp
|
||||
interfaces
|
||||
brain_interfaces
|
||||
nav2_msgs
|
||||
std_srvs
|
||||
tf2
|
||||
tf2_ros
|
||||
tf2_geometry_msgs
|
||||
)
|
||||
target_include_directories(test_cerebellum_node PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
target_include_directories(test_cerebellum_node PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(test_cerebellum_node Boost::thread)
|
||||
target_link_libraries(test_cerebellum_node yaml-cpp)
|
||||
endif()
|
||||
@@ -183,7 +190,6 @@ if(BUILD_TESTING)
|
||||
rclcpp_action
|
||||
behaviortree_cpp
|
||||
interfaces
|
||||
brain_interfaces
|
||||
smacc2
|
||||
smacc2_msgs
|
||||
ament_index_cpp
|
||||
@@ -193,7 +199,9 @@ if(BUILD_TESTING)
|
||||
tf2_ros
|
||||
tf2_geometry_msgs
|
||||
)
|
||||
target_include_directories(test_cerebrum_node PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
target_include_directories(test_cerebrum_node PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(test_cerebrum_node Boost::thread)
|
||||
target_link_libraries(test_cerebrum_node yaml-cpp)
|
||||
endif()
|
||||
@@ -208,14 +216,16 @@ if(BUILD_TESTING)
|
||||
smacc2
|
||||
smacc2_msgs
|
||||
interfaces
|
||||
brain_interfaces
|
||||
nav2_msgs
|
||||
std_srvs
|
||||
tf2
|
||||
tf2_ros
|
||||
tf2_geometry_msgs
|
||||
)
|
||||
target_include_directories(test_sm_cerebellum PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
target_include_directories(test_sm_cerebellum PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(test_sm_cerebellum)
|
||||
endif()
|
||||
|
||||
# ExecuteBtAction end-to-end single skill test
|
||||
@@ -231,7 +241,6 @@ if(BUILD_TESTING)
|
||||
rclcpp_action
|
||||
behaviortree_cpp
|
||||
interfaces
|
||||
brain_interfaces
|
||||
smacc2
|
||||
smacc2_msgs
|
||||
ament_index_cpp
|
||||
@@ -241,7 +250,9 @@ if(BUILD_TESTING)
|
||||
tf2_ros
|
||||
tf2_geometry_msgs
|
||||
)
|
||||
target_include_directories(test_execute_bt_action PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
target_include_directories(test_execute_bt_action PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(test_execute_bt_action Boost::thread yaml-cpp)
|
||||
endif()
|
||||
|
||||
@@ -258,7 +269,6 @@ if(BUILD_TESTING)
|
||||
rclcpp_action
|
||||
behaviortree_cpp
|
||||
interfaces
|
||||
brain_interfaces
|
||||
smacc2
|
||||
smacc2_msgs
|
||||
ament_index_cpp
|
||||
@@ -268,7 +278,9 @@ if(BUILD_TESTING)
|
||||
tf2_ros
|
||||
tf2_geometry_msgs
|
||||
)
|
||||
target_include_directories(test_execute_bt_action_extended PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
target_include_directories(test_execute_bt_action_extended PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(test_execute_bt_action_extended Boost::thread yaml-cpp)
|
||||
endif()
|
||||
|
||||
@@ -283,8 +295,10 @@ if(BUILD_TESTING)
|
||||
if(TARGET ${test_name})
|
||||
target_compile_definitions(${test_name} PRIVATE BRAIN_DISABLE_SM=1)
|
||||
ament_target_dependencies(${test_name}
|
||||
rclcpp rclcpp_action behaviortree_cpp interfaces brain_interfaces smacc2 smacc2_msgs ament_index_cpp nav2_msgs std_srvs tf2 tf2_ros tf2_geometry_msgs)
|
||||
target_include_directories(${test_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
rclcpp rclcpp_action behaviortree_cpp interfaces smacc2 smacc2_msgs ament_index_cpp nav2_msgs std_srvs tf2 tf2_ros tf2_geometry_msgs)
|
||||
target_include_directories(${test_name} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(${test_name} Boost::thread yaml-cpp)
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -298,8 +312,10 @@ if(BUILD_TESTING)
|
||||
if(TARGET test_cerebrum_utils)
|
||||
target_compile_definitions(test_cerebrum_utils PRIVATE BRAIN_DISABLE_SM=1)
|
||||
ament_target_dependencies(test_cerebrum_utils
|
||||
rclcpp rclcpp_action behaviortree_cpp interfaces brain_interfaces smacc2 smacc2_msgs ament_index_cpp nav2_msgs std_srvs tf2 tf2_ros tf2_geometry_msgs)
|
||||
target_include_directories(test_cerebrum_utils PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
rclcpp rclcpp_action behaviortree_cpp interfaces smacc2 smacc2_msgs ament_index_cpp nav2_msgs std_srvs tf2 tf2_ros tf2_geometry_msgs)
|
||||
target_include_directories(test_cerebrum_utils PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(test_cerebrum_utils Boost::thread yaml-cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
115
src/brain/config/brain_node_params.yaml
Normal file
115
src/brain/config/brain_node_params.yaml
Normal file
@@ -0,0 +1,115 @@
|
||||
# Configuration file for brain node parameters
|
||||
# This file contains configurable parameters for cerebrum and cerebellum nodes
|
||||
|
||||
cerebrum_node:
|
||||
ros__parameters:
|
||||
# Timing parameters
|
||||
tick_rate_hz: 10.0
|
||||
rebuild_interval_ms: 5000
|
||||
stats_publish_interval_ms: 10000
|
||||
|
||||
# Configuration paths
|
||||
# robot_config_path: ""
|
||||
# skill_file_path: ""
|
||||
|
||||
# Behavior tree parameters
|
||||
default_bt_timeout: 300.0
|
||||
enable_sequence_rebuild: true
|
||||
|
||||
# Original cerebrum parameters
|
||||
node_timeout_sec: 60.0
|
||||
allow_bt_rebuild_during_execution: false
|
||||
allowed_action_skills: ""
|
||||
fixed_skill_sequence: ""
|
||||
random_skill_pick_count: 5
|
||||
|
||||
# Dynamic skill parameters (examples - these would be set per skill)
|
||||
# cerebrum:
|
||||
# bt:
|
||||
# VisionObjectRecognition:
|
||||
# topic: "vision_object_recognition"
|
||||
# payload_yaml: ""
|
||||
# timeout_ms: "10000"
|
||||
# Arm:
|
||||
# topic: "arm_control"
|
||||
# payload_yaml: ""
|
||||
# timeout_ms: "30000"
|
||||
# # Example instance-specific overrides
|
||||
# Arm:
|
||||
# s1_arm_move_to_object:
|
||||
# topic: "arm_control_specific"
|
||||
# payload_yaml: "{target_pose: {x: 0.1, y: 0.2, z: 0.3}}"
|
||||
# timeout_ms: "45000"
|
||||
|
||||
cerebellum_node:
|
||||
ros__parameters:
|
||||
# Action execution parameters
|
||||
abort_on_failure: true
|
||||
default_action_timeout_sec: 45.0
|
||||
vision_grasp_object_timeout_sec: 120.0
|
||||
|
||||
# Map parameters
|
||||
map_save_url: "/tmp/humanoid_map"
|
||||
map_save_image_format: "pgm"
|
||||
map_save_free_thresh: 0.25
|
||||
map_save_occupied_thresh: 0.65
|
||||
map_load_url: ""
|
||||
nav_goal_yaw_offset: 0.0
|
||||
nav_goal_distance_tolerance: 0.5
|
||||
slam_enable_mapping_default: true
|
||||
|
||||
# Configuration paths
|
||||
# robot_config_path: ""
|
||||
# robot_skill_file_path: ""
|
||||
|
||||
# Statistics parameters
|
||||
enable_stats_publisher: true
|
||||
stats_publish_interval_ms: 5000
|
||||
|
||||
# Skill-specific timeouts (format: "SkillA=30,SkillB=10")
|
||||
skill_timeouts: ""
|
||||
|
||||
# Arm-specific parameters
|
||||
arm_target_frame: "base_link_rightarm" # 右臂基座坐标系
|
||||
arm_transform_timeout_sec: 2.0 # 坐标变换超时时间
|
||||
|
||||
# Grasp pose calculation parameters
|
||||
top_cam_right_arm_z_threshold: 0.05 #满足右臂抓取的头部相机输出的z坐标阈值
|
||||
top_cam_right_arm_x_offset: 0.10 #右臂相机视觉识别时的x坐标偏移
|
||||
top_cam_right_arm_y: 0.33 #右臂相机视觉识别时的y坐标
|
||||
top_cam_right_arm_orientation: [-0.7071, 0.0, 0.0, 0.7071] #右臂相机视觉识别时的四元数
|
||||
top_cam_left_arm_z_threshold: -0.10 #满足左臂抓取的头部相机输出的z坐标阈值
|
||||
top_cam_left_arm_x_offset: 0.10 #左臂相机视觉识别时的x坐标偏移
|
||||
top_cam_left_arm_y: -0.33 #左臂相机视觉识别时的y坐标
|
||||
top_cam_left_arm_orientation: [0.7071, 0.0, 0.0, 0.7071] #左臂相机视觉识别时的四元数
|
||||
side_cam_right_arm_y_offset: 0.0 # 补偿右臂y轴方向的抓取偏差(前后)
|
||||
side_cam_right_arm_z_offset: 0.02 # 补偿右臂z轴方向的抓取偏差(左右)
|
||||
side_cam_left_arm_y_offset: 0.02 # 补偿左臂y轴方向的抓取偏差(前后)
|
||||
side_cam_left_arm_z_offset: 0.01 # 补偿左臂z轴方向的抓取偏差(左右)
|
||||
take_object_arm_x: -0.05 # 抓取物体时x坐标
|
||||
left_camera_frame: "LeftLink6" # 左臂相机坐标系
|
||||
right_camera_frame: "RightLink6" # 右臂相机坐标系
|
||||
target_frames: ["apple", "bottle", "medicine_box"] # 识别物体的列表
|
||||
target_frame: "medicine_box" # 默认识别物体
|
||||
grasp_palm_facings: ["down"] # 抓取时手掌朝向
|
||||
grasp_best_angles: [0.0] # 抓取时最佳角度
|
||||
grasp_type: "side" # 抓取类型
|
||||
grasp_safety_dist: 0.10 # 抓取安全距离
|
||||
grasp_finger_length: 0.17 # 抓取手指长度
|
||||
hand_control_default_mode: 1 # 手控制默认模式
|
||||
gripper_default_loc: 30 # 夹爪默认位置
|
||||
arm_cmd_type_take_photo: 100 # 拍照
|
||||
arm_cmd_type_pre_grasp: 101 # 预抓取
|
||||
arm_cmd_type_grasp: 102 # 抓取
|
||||
arm_cmd_type_take_object: 110 # 拿取动作
|
||||
arm_cmd_type_custom_min: 100 # 自定义动作最小值
|
||||
arm_cmd_type_custom_max: 120 # 自定义动作最大值
|
||||
gripper_default_speed: 0 # 夹爪默认速度
|
||||
gripper_default_torque: 0 # 夹爪默认力矩
|
||||
gripper_default_mode: 0 # 夹爪默认模式
|
||||
|
||||
# Service hook timeouts (seconds)
|
||||
vision_object_recognition_wait_timeout_sec: 2.0 # 物体识别服务调用超时时间
|
||||
vision_object_recognition_call_timeout_sec: 5.0 # 物体识别服务等待超时时间
|
||||
map_load_wait_timeout_sec: 2.0 # 地图加载服务调用超时时间
|
||||
map_load_call_timeout_sec: 5.0 # 地图加载服务等待超时时间
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
'
|
||||
- name: s1_arm_move_origin_position
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-5, -60, -30, 0, 0, -180, -175, 60, 30, 0, 0, 0]
|
||||
data_array: [-5, -55, -30, 0, 0, -180, -175, 55, 30, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s2_arm_move_to_snapshot_pose
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -35,17 +35,17 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -35, -40, 1, -70, -180, -95, 35, 40, -1, 70, -10]
|
||||
data_array: [-90, -30, -45, 0, 0, -180, -90, 30, 45, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s3_wheel_move_to_pickup_position
|
||||
params: 'move_distance: 0.5
|
||||
params: 'move_distance: 1.5
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s4_arm_grasp_box
|
||||
params: 'body_id: 0
|
||||
- name: s3_snapshot_action1
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -55,11 +55,95 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-80, -70, -25, 1, -85, -170, -100, 70, 25, -1, 85, -10]
|
||||
data_array: [-85, -35, -60, 1, -90, -175, -95, 35, 60, -1, 90, -5]
|
||||
|
||||
'
|
||||
- name: s3_snapshot_action2
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -40, -40, 1, -70, -170, -95, 40, 40, -1, 70, -10]
|
||||
|
||||
'
|
||||
- name: s3_snapshot_top_action1
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -40, -40, 1, -70, -170, -55, 50, 35, -40, 95, -60]
|
||||
|
||||
'
|
||||
- name: s3_snapshot_top_action2
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -40, -40, 1, -70, -170, -55, 70, 35, -40, 75, -60]
|
||||
|
||||
'
|
||||
- name: s3_snapshot_top_action3
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -40, -40, 1, -70, -170, -55, 50, 35, -40, 95, -60]
|
||||
|
||||
'
|
||||
- name: s4_arm_prepare_grasp_box
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-80, -75, 0, 0, -100, -80, -100, 75, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s4_arm_grasp_box
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-80, -81.8, 0, 0, -100, -80, -100, 81.8, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s5_arm_pickup_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -69,7 +153,7 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -70, -25, 1, -85, -170, -70, 70, 25, -1, 85, -10]
|
||||
data_array: [-110, -81.8, 0, 0, -100, -80, -70, 81.8, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s6_wheel_move_back_to_second_position
|
||||
@@ -85,13 +169,13 @@
|
||||
|
||||
'
|
||||
- name: s8_waist_bend_down
|
||||
params: 'move_pitch_degree: 25.0
|
||||
params: 'move_pitch_degree: 37.0
|
||||
|
||||
move_yaw_degree: 0
|
||||
|
||||
'
|
||||
- name: s9_arm_put_down_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -101,11 +185,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -70, -25, 1, -85, -150, -95, 70, 25, -1, 85, -30]
|
||||
data_array: [-110, -81.8, 0, 0, -100, -65, -70, 81.8, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s10_arm_release
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -115,11 +199,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -60, -25, 1, -85, -150, -95, 60, 25, -1, 85, -30]
|
||||
data_array: [-110, -78, 0, 0, -100, -65, -70, 78, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s10_arm_raise_up
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -129,13 +213,13 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -60, -25, 1, -85, -170, -70, 60, 25, -1, 85, -10]
|
||||
data_array: [-110, -78, 0, 0, -100, -65, -70, 78, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s11_waist_bend_up_and_turn_around
|
||||
params: 'move_pitch_degree: -25.0
|
||||
- name: s11_waist_bend_up
|
||||
params: 'move_pitch_degree: -37.0
|
||||
|
||||
move_yaw_degree: -90.0
|
||||
move_yaw_degree: 0.0
|
||||
|
||||
'
|
||||
- name: s12_waist_turn_around
|
||||
@@ -145,7 +229,7 @@
|
||||
|
||||
'
|
||||
- name: s13_arm_move_origin_position
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -155,11 +239,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-5, -60, -30, 0, 0, -180, -175, 60, 30, 0, 0, 0]
|
||||
data_array: [-5, -55, -30, 0, 0, -180, -175, 55, 30, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s14_arm_move_to_snapshot_pose
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -169,17 +253,45 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -35, -40, 1, -70, -180, -95, 35, 40, -1, 70, -10]
|
||||
data_array: [-90, -30, -45, 0, 0, -180, -90, 30, 45, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s14_arm_move_pre_origin_position
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-30, -55, -30, 0, -100, -65, -150, 55, 30, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s14_arm_move_origin_position
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-5, -55, -30, 0, 0, -180, -175, 55, 30, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s15_wheel_move_to_pickup_position
|
||||
params: 'move_distance: 0.5
|
||||
params: 'move_distance: 1.5
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s16_arm_grasp_box
|
||||
params: 'body_id: 0
|
||||
- name: s15_snapshot_action1
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -189,11 +301,95 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-80, -70, -25, 1, -85, -170, -100, 70, 25, -1, 85, -10]
|
||||
data_array: [-85, -35, -60, 1, -90, -175, -95, 35, 60, -1, 90, -5]
|
||||
|
||||
'
|
||||
- name: s15_snapshot_action2
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -40, -40, 1, -70, -170, -95, 40, 40, -1, 70, -10]
|
||||
|
||||
'
|
||||
- name: s15_snapshot_top_action1
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -40, -40, 1, -70, -170, -55, 50, 35, -40, 95, -60]
|
||||
|
||||
'
|
||||
- name: s15_snapshot_top_action2
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -40, -40, 1, -70, -170, -55, 70, 35, -40, 75, -60]
|
||||
|
||||
'
|
||||
- name: s15_snapshot_top_action3
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -40, -40, 1, -70, -170, -55, 50, 35, -40, 95, -60]
|
||||
|
||||
'
|
||||
- name: s16_arm_prepare_grasp_box
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-80, -75, 0, 0, -100, -80, -100, 75, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s16_arm_grasp_box
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-80, -81.8, 0, 0, -100, -80, -100, 81.8, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s17_arm_pickup_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -203,7 +399,7 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -70, -25, 1, -85, -170, -70, 70, 25, -1, 85, -10]
|
||||
data_array: [-110, -81.8, 0, 0, -100, -80, -70, 81.8, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s18_wheel_move_back_to_origin
|
||||
@@ -219,13 +415,13 @@
|
||||
|
||||
'
|
||||
- name: s20_waist_bend_down
|
||||
params: 'move_pitch_degree: 25.0
|
||||
params: 'move_pitch_degree: 37.0
|
||||
|
||||
move_yaw_degree: 0
|
||||
|
||||
'
|
||||
- name: s21_arm_put_down_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -235,11 +431,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -70, -25, 1, -85, -150, -95, 70, 25, -1, 85, -30]
|
||||
data_array: [-110, -81.8, 0, 0, -100, -65, -70, 81.8, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s22_arm_release
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -249,11 +445,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -60, -25, 1, -85, -150, -95, 60, 25, -1, 85, -30]
|
||||
data_array: [-110, -78, 0, 0, -100, -65, -70, 78, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s22_arm_raise_up
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -263,13 +459,13 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -60, -25, 1, -85, -170, -70, 60, 25, -1, 85, -10]
|
||||
data_array: [-110, -78, 0, 0, -100, -65, -70, 78, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s23_waist_bend_up_and_turn_around
|
||||
params: 'move_pitch_degree: -25.0
|
||||
- name: s23_waist_bend_up
|
||||
params: 'move_pitch_degree: -37.0
|
||||
|
||||
move_yaw_degree: -90.0
|
||||
move_yaw_degree: 0.0
|
||||
|
||||
'
|
||||
- name: s24_waist_turn_around
|
||||
@@ -279,7 +475,7 @@
|
||||
|
||||
'
|
||||
- name: s25_arm_move_origin_position
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -289,7 +485,7 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-5, -60, -30, 0, 0, -180, -175, 60, 30, 0, 0, 0]
|
||||
data_array: [-5, -55, -30, 0, 0, -180, -175, 55, 30, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s26_wheel_move_back_to_origin
|
||||
@@ -297,4 +493,32 @@
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s26_arm_move_pre_origin_position
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-30, -55, -30, 0, -100, -65, -150, 55, 30, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s26_arm_move_origin_position
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-5, -55, -30, 0, 0, -180, -175, 55, 30, 0, 0, 0]
|
||||
|
||||
'
|
||||
@@ -1,37 +1,62 @@
|
||||
<!--
|
||||
功能描述: 机器人搬运箱子流程1(单臂+底盘,3次重试)。
|
||||
流程: 清理完成标记 -> 机械臂回零 -> 底盘到抓取点 -> 多组拍照位与抓取位动作 -> 抓取抬起
|
||||
-> 底盘到放置点 -> 腰部下俯与放置并行 -> 松爪 -> 抬臂与腰部上仰并行 -> 回初始位
|
||||
-> 第二次抓取放置循环 -> 回原点。
|
||||
-->
|
||||
<root BTCPP_format="4">
|
||||
<BehaviorTree ID="MainTree">
|
||||
<Sequence name="root">
|
||||
<!-- Retry waist + arm + hand until HandControl_H succeeds -->
|
||||
<RetryUntilSuccessful name="retry_all_action" num_attempts="5">
|
||||
<RetryUntilSuccessful name="retry_all_action" num_attempts="3">
|
||||
<Sequence>
|
||||
<ClearDoneInstances_H name="clear_done_instances_retry" />
|
||||
<!-- <MoveHome_H name="s0_motion_move_home" /> -->
|
||||
<!-- <Arm_H name="s1_arm_move_origin_position" /> -->
|
||||
<Arm_H name="s2_arm_move_to_snapshot_pose" />
|
||||
<Arm_H name="s1_arm_move_origin_position" />
|
||||
<MoveWheel_H name="s3_wheel_move_to_pickup_position" />
|
||||
<Arm_H name="s2_arm_move_to_snapshot_pose" />
|
||||
<Arm_H name="s3_snapshot_action1" />
|
||||
<Arm_H name="s3_snapshot_action2" />
|
||||
<Arm_H name="s3_snapshot_top_action1" />
|
||||
<Arm_H name="s3_snapshot_top_action2" />
|
||||
<Arm_H name="s3_snapshot_top_action3" />
|
||||
<Arm_H name="s4_arm_prepare_grasp_box" />
|
||||
<Arm_H name="s4_arm_grasp_box" />
|
||||
<Arm_H name="s5_arm_pickup_box" />
|
||||
<MoveWheel_H name="s6_wheel_move_back_to_second_position" />
|
||||
<MoveWaist_H name="s7_waist_turn_around" />
|
||||
<MoveWaist_H name="s8_waist_bend_down" />
|
||||
<Arm_H name="s9_arm_put_down_box" />
|
||||
<Parallel name="parallel_action_3">
|
||||
<MoveWaist_H name="s8_waist_bend_down" />
|
||||
<Arm_H name="s9_arm_put_down_box" />
|
||||
</Parallel>
|
||||
<Arm_H name="s10_arm_release" />
|
||||
<Arm_H name="s10_arm_raise_up" />
|
||||
<MoveWaist_H name="s11_waist_bend_up_and_turn_around" />
|
||||
<!-- <MoveWaist_H name="s12_waist_turn_around" /> -->
|
||||
<!-- <Arm_H name="s13_arm_move_origin_position" /> -->
|
||||
<Arm_H name="s14_arm_move_to_snapshot_pose" />
|
||||
<Parallel name="parallel_action_4">
|
||||
<Arm_H name="s10_arm_raise_up" />
|
||||
<MoveWaist_H name="s11_waist_bend_up" />
|
||||
</Parallel>
|
||||
<Arm_H name="s14_arm_move_pre_origin_position" />
|
||||
<Arm_H name="s14_arm_move_origin_position" />
|
||||
<MoveWheel_H name="s15_wheel_move_to_pickup_position" />
|
||||
<Arm_H name="s14_arm_move_to_snapshot_pose" />
|
||||
<Arm_H name="s15_snapshot_action1" />
|
||||
<Arm_H name="s15_snapshot_action2" />
|
||||
<Arm_H name="s15_snapshot_top_action1" />
|
||||
<Arm_H name="s15_snapshot_top_action2" />
|
||||
<Arm_H name="s15_snapshot_top_action3" />
|
||||
<Arm_H name="s16_arm_prepare_grasp_box" />
|
||||
<Arm_H name="s16_arm_grasp_box" />
|
||||
<Arm_H name="s17_arm_pickup_box" />
|
||||
<MoveWheel_H name="s18_wheel_move_back_to_origin" />
|
||||
<MoveWaist_H name="s19_waist_turn_around" />
|
||||
<MoveWaist_H name="s20_waist_bend_down" />
|
||||
<Arm_H name="s21_arm_put_down_box" />
|
||||
<Parallel name="parallel_action_7">
|
||||
<MoveWaist_H name="s20_waist_bend_down" />
|
||||
<Arm_H name="s21_arm_put_down_box" />
|
||||
</Parallel>
|
||||
<Arm_H name="s22_arm_release" />
|
||||
<Arm_H name="s22_arm_raise_up" />
|
||||
<MoveWaist_H name="s23_waist_bend_up_and_turn_around" />
|
||||
<!-- <MoveWaist_H name="s24_waist_turn_around" /> -->
|
||||
<!-- <Arm_H name="s25_arm_move_origin_position" /> -->
|
||||
<Parallel name="parallel_action_8">
|
||||
<Arm_H name="s22_arm_raise_up" />
|
||||
<MoveWaist_H name="s23_waist_bend_up" />
|
||||
</Parallel>
|
||||
<Arm_H name="s26_arm_move_pre_origin_position" />
|
||||
<Arm_H name="s26_arm_move_origin_position" />
|
||||
<MoveWheel_H name="s26_wheel_move_back_to_origin" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
'
|
||||
- name: s1_arm_move_origin_position
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -60, -25, 1, -85, -170, -70, 60, 25, -1, 85, -10]
|
||||
data_array: [-5, -55, -30, 0, 0, -180, -175, 55, 30, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s2_wheel_move_to_origin_pickup_position
|
||||
@@ -33,13 +33,13 @@
|
||||
|
||||
'
|
||||
- name: s4_waist_bend_down
|
||||
params: 'move_pitch_degree: 25.0
|
||||
params: 'move_pitch_degree: 38.0
|
||||
|
||||
move_yaw_degree: 0.0
|
||||
|
||||
'
|
||||
- name: s5_arm_prepare_to_grasp
|
||||
params: 'body_id: 0
|
||||
- name: s4_arm_move_pre_origin_position
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -49,11 +49,109 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -60, -25, 1, -85, -150, -95, 60, 25, -1, 85, -30]
|
||||
data_array: [-30, -55, -30, 0, -100, -65, -150, 55, 30, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s4_arm_move_to_snapshot_pose
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-112, -70, 0, 0, -80, -160, -68, 70, 0, 0, 80, -20]
|
||||
|
||||
'
|
||||
- name: s4_snapshot_action1
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-105, -55, -35, 0, -110, -160, -75, 55, 35, 0, 110, -20]
|
||||
|
||||
'
|
||||
- name: s4_snapshot_action2
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-112, -70, 0, 0, -80, -160, -68, 70, 0, 0, 80, -20]
|
||||
|
||||
'
|
||||
- name: s4_snapshot_top_action1
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-112, -70, 0, 0, -80, -160, -30, 60, 35, -40, 85, -60]
|
||||
|
||||
'
|
||||
- name: s4_snapshot_top_action2
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-112, -70, 0, 0, -80, -160, -30, 80, 35, -40, 65, -55]
|
||||
|
||||
'
|
||||
- name: s4_snapshot_top_action3
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-112, -70, 0, 0, -80, -160, -30, 60, 35, -40, 85, -60]
|
||||
|
||||
'
|
||||
- name: s5_arm_prepare_to_grasp
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -75, 0, 0, -100, -65, -70, 75, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s6_arm_grasp_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -63,11 +161,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -70, -25, 1, -85, -150, -95, 70, 25, -1, 85, -30]
|
||||
data_array: [-110, -81.8, 0, 0, -100, -65, -70, 81.8, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s7_arm_pickup_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -77,13 +175,13 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -70, -25, 1, -85, -150, -70, 70, 25, -1, 85, -30]
|
||||
data_array: [-110, -81.8, 0, 0, -100, -65, -70, 81.8, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s8_waist_bend_up_and_turn_around
|
||||
params: 'move_pitch_degree: -25.0
|
||||
- name: s8_waist_bend_up
|
||||
params: 'move_pitch_degree: -38.0
|
||||
|
||||
move_yaw_degree: -90.0
|
||||
move_yaw_degree: 0.0
|
||||
|
||||
'
|
||||
- name: s9_waist_turn_around
|
||||
@@ -93,13 +191,13 @@
|
||||
|
||||
'
|
||||
- name: s10_wheel_move_to_putdown_position
|
||||
params: 'move_distance: 0.5
|
||||
params: 'move_distance: 1.5
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s11_arm_putdown_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -109,11 +207,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-80, -70, -25, 1, -85, -170, -100, 70, 25, -1, 85, -10]
|
||||
data_array: [-80, -81.8, 0, 0, -100, -80, -100, 81.8, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s12_arm_release_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -123,11 +221,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-80, -60, -25, 1, -85, -170, -100, 60, 25, -1, 85, -10]
|
||||
data_array: [-80, -75, 0, 0, -100, -80, -100, 75, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s12_arm_raise_up
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -137,7 +235,35 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -60, -25, 1, -85, -170, -70, 60, 25, -1, 85, -10]
|
||||
data_array: [-110, -75, 0, 0, -100, -80, -70, 75, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s13_arm_move_to_snapshot_pose
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-90, -30, -45, 0, 0, -180, -90, 30, 45, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s13_arm_move_origin_position
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-5, -55, -30, 0, 0, -180, -175, 55, 30, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s13_wheel_move_to_origin_pickup_position
|
||||
@@ -159,13 +285,13 @@
|
||||
|
||||
'
|
||||
- name: s15_waist_bend_down
|
||||
params: 'move_pitch_degree: 25.0
|
||||
params: 'move_pitch_degree: 38.0
|
||||
|
||||
move_yaw_degree: 0.0
|
||||
|
||||
'
|
||||
- name: s16_arm_prepare_to_grasp
|
||||
params: 'body_id: 0
|
||||
- name: s15_arm_move_pre_origin_position
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -175,11 +301,109 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -60, -25, 1, -85, -150, -95, 60, 25, -1, 85, -30]
|
||||
data_array: [-30, -55, -30, 0, -100, -65, -150, 55, 30, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s15_arm_move_to_snapshot_pose
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-112, -70, 0, 0, -80, -160, -68, 70, 0, 0, 80, -20]
|
||||
|
||||
'
|
||||
- name: s15_snapshot_action1
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-105, -55, -35, 0, -110, -160, -75, 55, 35, 0, 110, -20]
|
||||
|
||||
'
|
||||
- name: s15_snapshot_action2
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-112, -70, 0, 0, -80, -160, -68, 70, 0, 0, 80, -20]
|
||||
|
||||
'
|
||||
- name: s15_snapshot_top_action1
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-112, -70, 0, 0, -80, -160, -30, 60, 35, -40, 85, -60]
|
||||
|
||||
'
|
||||
- name: s15_snapshot_top_action2
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-112, -70, 0, 0, -80, -160, -30, 80, 35, -40, 65, -55]
|
||||
|
||||
'
|
||||
- name: s15_snapshot_top_action3
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-112, -70, 0, 0, -80, -160, -30, 60, 35, -40, 85, -60]
|
||||
|
||||
'
|
||||
- name: s16_arm_prepare_to_grasp
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -75, 0, 0, -100, -65, -70, 75, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s17_arm_grasp_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -189,11 +413,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-85, -70, -25, 1, -85, -150, -95, 70, 25, -1, 85, -30]
|
||||
data_array: [-110, -81.8, 0, 0, -100, -65, -70, 81.8, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s18_arm_pickup_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -203,13 +427,13 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -70, -25, 1, -85, -150, -70, 70, 25, -1, 85, -30]
|
||||
data_array: [-110, -81.8, 0, 0, -100, -65, -70, 81.8, 0, 0, 100, -115]
|
||||
|
||||
'
|
||||
- name: s19_waist_bend_up_and_turn_around
|
||||
params: 'move_pitch_degree: -25.0
|
||||
- name: s19_waist_bend_up
|
||||
params: 'move_pitch_degree: -38.0
|
||||
|
||||
move_yaw_degree: -90.0
|
||||
move_yaw_degree: 0.0
|
||||
|
||||
'
|
||||
- name: s20_waist_turn_around
|
||||
@@ -219,13 +443,13 @@
|
||||
|
||||
'
|
||||
- name: s21_wheel_move_to_putdown_position
|
||||
params: 'move_distance: 0.5
|
||||
params: 'move_distance: 1.5
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s22_arm_putdown_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -235,11 +459,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-80, -70, -25, 1, -85, -170, -100, 70, 25, -1, 85, -10]
|
||||
data_array: [-80, -81.8, 0, 0, -100, -80, -100, 81.8, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s23_arm_release_box
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -249,11 +473,11 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-80, -60, -25, 1, -85, -170, -100, 60, 25, -1, 85, -10]
|
||||
data_array: [-80, -75, 0, 0, -100, -80, -100, 75, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s23_arm_raise_up
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -263,7 +487,35 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-110, -60, -25, 1, -85, -170, -70, 60, 25, -1, 85, -10]
|
||||
data_array: [-110, -75, 0, 0, -100, -80, -70, 75, 0, 0, 100, -100]
|
||||
|
||||
'
|
||||
- name: s23_arm_move_to_snapshot_pose
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-90, -30, -45, 0, 0, -180, -90, 30, 45, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s23_arm_move_origin_position
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-5, -55, -30, 0, 0, -180, -175, 55, 30, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s24_wheel_move_to_origin_pickup_position
|
||||
@@ -273,7 +525,7 @@
|
||||
|
||||
'
|
||||
- name: s25_arm_move_origin_position
|
||||
params: 'body_id: 0
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
@@ -283,6 +535,6 @@
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [-5, -60, -30, 0, 0, -180, -175, 60, 30, 0, 0, 0]
|
||||
data_array: [-5, -55, -30, 0, 0, -180, -175, 55, 30, 0, 0, 0]
|
||||
|
||||
'
|
||||
@@ -1,37 +1,61 @@
|
||||
<!--
|
||||
功能描述: 机器人搬运箱子流程2(单臂+底盘+腰部俯仰,3次重试,适配高低位箱体)。
|
||||
流程: 回零 -> 底盘到抓取点 -> 预抓取位 -> 腰部下俯拍照 -> 多角度拍照识别 -> 抓取
|
||||
-> 抬起与腰部上仰并行 -> 底盘到放置点 -> 放置/松爪 -> 抬臂 -> 返回拍照位与回零
|
||||
-> 第二次抓取放置循环。
|
||||
-->
|
||||
<root BTCPP_format="4">
|
||||
<BehaviorTree ID="MainTree">
|
||||
<Sequence name="root">
|
||||
<!-- Retry waist + arm + hand until HandControl_H succeeds -->
|
||||
<RetryUntilSuccessful name="retry_all_action" num_attempts="5">
|
||||
<RetryUntilSuccessful name="retry_all_action" num_attempts="3">
|
||||
<Sequence>
|
||||
<ClearDoneInstances_H name="clear_done_instances_retry" />
|
||||
<Arm_H name="s1_arm_move_origin_position" />
|
||||
<MoveWheel_H name="s2_wheel_move_to_origin_pickup_position" />
|
||||
<MoveWaist_H name="s3_waist_turn_around" />
|
||||
<Arm_H name="s4_arm_move_pre_origin_position" />
|
||||
<Arm_H name="s4_arm_move_to_snapshot_pose" />
|
||||
<MoveWaist_H name="s4_waist_bend_down" />
|
||||
<Arm_H name="s4_snapshot_action1" />
|
||||
<Arm_H name="s4_snapshot_action2" />
|
||||
<Arm_H name="s4_snapshot_top_action1" />
|
||||
<Arm_H name="s4_snapshot_top_action2" />
|
||||
<Arm_H name="s4_snapshot_top_action3" />
|
||||
<Arm_H name="s5_arm_prepare_to_grasp" />
|
||||
<Arm_H name="s6_arm_grasp_box" />
|
||||
<Arm_H name="s7_arm_pickup_box" />
|
||||
<MoveWaist_H name="s8_waist_bend_up_and_turn_around" />
|
||||
<!-- <MoveWaist_H name="s9_waist_turn_around" /> -->
|
||||
<Parallel name="parallel_action_3">
|
||||
<Arm_H name="s7_arm_pickup_box" />
|
||||
<MoveWaist_H name="s8_waist_bend_up" />
|
||||
</Parallel>
|
||||
<MoveWheel_H name="s10_wheel_move_to_putdown_position" />
|
||||
<Arm_H name="s11_arm_putdown_box" />
|
||||
<Arm_H name="s12_arm_release_box" />
|
||||
<Arm_H name="s12_arm_raise_up" />
|
||||
<MoveWheel_H name="s13_wheel_move_to_origin_pickup_position" />
|
||||
<MoveWaist_H name="s14_waist_turn_around" />
|
||||
<Arm_H name="s13_arm_move_to_snapshot_pose" />
|
||||
<Arm_H name="s13_arm_move_origin_position" />
|
||||
<MoveWheel_H name="s15_wheel_move_to_second_pickup_position" />
|
||||
<Arm_H name="s15_arm_move_pre_origin_position" />
|
||||
<Arm_H name="s15_arm_move_to_snapshot_pose" />
|
||||
<MoveWaist_H name="s15_waist_bend_down" />
|
||||
<Arm_H name="s15_snapshot_action1" />
|
||||
<Arm_H name="s15_snapshot_action2" />
|
||||
<Arm_H name="s15_snapshot_top_action1" />
|
||||
<Arm_H name="s15_snapshot_top_action2" />
|
||||
<Arm_H name="s15_snapshot_top_action3" />
|
||||
<Arm_H name="s16_arm_prepare_to_grasp" />
|
||||
<Arm_H name="s17_arm_grasp_box" />
|
||||
<Arm_H name="s18_arm_pickup_box" />
|
||||
<MoveWaist_H name="s19_waist_bend_up_and_turn_around" />
|
||||
<!-- <MoveWaist_H name="s20_waist_turn_around" /> -->
|
||||
<Parallel name="parallel_action_7">
|
||||
<Arm_H name="s18_arm_pickup_box" />
|
||||
<MoveWaist_H name="s19_waist_bend_up" />
|
||||
</Parallel>
|
||||
<MoveWheel_H name="s21_wheel_move_to_putdown_position" />
|
||||
<Arm_H name="s22_arm_putdown_box" />
|
||||
<Arm_H name="s23_arm_release_box" />
|
||||
<Arm_H name="s23_arm_raise_up" />
|
||||
<Arm_H name="s23_arm_move_to_snapshot_pose" />
|
||||
<Arm_H name="s23_arm_move_origin_position" />
|
||||
<MoveWheel_H name="s24_wheel_move_to_origin_pickup_position" />
|
||||
<!-- <Arm_H name="s25_arm_move_origin_position" /> -->
|
||||
<Arm_H name="s25_arm_move_origin_position" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
- name: root
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: retry_vision_hand
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: VisionObjectRecognition_H
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: Arm_H
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 0
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: HandControl_H
|
||||
params: 'mode: 0
|
||||
|
||||
effort: 0.0
|
||||
|
||||
'
|
||||
@@ -1,15 +0,0 @@
|
||||
<root BTCPP_format="4">
|
||||
<BehaviorTree ID="MainTree">
|
||||
<Sequence name="root">
|
||||
<!-- Retry vision + hand until HandControl_H succeeds -->
|
||||
<RetryUntilSuccessful name="retry_vision_hand" num_attempts="5">
|
||||
<Sequence>
|
||||
<VisionObjectRecognition_H name="VisionObjectRecognition_H" />
|
||||
<Arm_H name="Arm_H" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
<!-- After Arm_H eventually succeeds, run the hand -->
|
||||
<HandControl_H name="HandControl_H" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
</root>
|
||||
406
src/brain/config/bt_vision_grasp_dual_arm.params.yaml
Normal file
406
src/brain/config/bt_vision_grasp_dual_arm.params.yaml
Normal file
@@ -0,0 +1,406 @@
|
||||
- name: root
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s1_right_hand_gripper_open
|
||||
params: &gripper_open 'loc: 0
|
||||
|
||||
speed: 150
|
||||
|
||||
torque: 20
|
||||
|
||||
mode: 2
|
||||
|
||||
'
|
||||
- name: s1_left_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s1_right_arm_initial
|
||||
params: &arm_inittial_right 'body_id: 1
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [0, 0, 0, 0, 0, 0, 80, -5, -112, -12, -62, 175]
|
||||
|
||||
'
|
||||
- name: s1_left_arm_initial
|
||||
params: &arm_inittial_left 'body_id: 0
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [100, 5, 112, 12, 62, 5, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s1_right_arm_pre_cam_take_photo
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [0, 0, 0, 0, 0, 0, 14.29, -34.07, -122.53, -76.89, 84.40, 112.89]
|
||||
|
||||
'
|
||||
- name: s1_left_arm_pre_cam_take_photo
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [165.80, 34.07, 122.53, 76.89, -84.40, 67.20, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s2_right_arm_cam_take_photo
|
||||
params: &right_arm_cam_take_photo 'body_id: 1
|
||||
|
||||
data_type: 100
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s2_left_arm_cam_take_photo
|
||||
params: &left_arm_cam_take_photo 'body_id: 0
|
||||
|
||||
data_type: 100
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s2_top_camera_vision_recg
|
||||
params: 'camera_position: top
|
||||
|
||||
'
|
||||
- name: s3_right_camera_vision_recg
|
||||
params: 'camera_position: right
|
||||
|
||||
'
|
||||
- name: s3_left_camera_vision_recg
|
||||
params: 'camera_position: left
|
||||
|
||||
'
|
||||
- name: s3_right_arm_vision_pre_grasp
|
||||
params: &pre_grasp_right 'body_id: 1
|
||||
|
||||
data_type: 101
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s3_left_arm_vision_pre_grasp
|
||||
params: &pre_grasp_left 'body_id: 0
|
||||
|
||||
data_type: 101
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_right_arm_vision_grasp
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 102
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_left_arm_vision_grasp
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 102
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_right_hand_gripper_close
|
||||
params: &gripper_close 'loc: 200
|
||||
|
||||
speed: 150
|
||||
|
||||
torque: 100
|
||||
|
||||
mode: 2
|
||||
|
||||
'
|
||||
- name: s4_left_hand_gripper_close
|
||||
params: *gripper_close
|
||||
- name: s4_right_arm_take_box
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 110
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_left_arm_take_box
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 110
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s5_right_arm_take_box_off
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [0, 0, 0, 0, 0, 0, 96.31, -103.06, 17.69, -53.40, -7.81, 143.19]
|
||||
|
||||
'
|
||||
- name: s5_left_arm_take_box_off
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [83.78, 103.06, -17.69, 53.40, 7.81, 36.90, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s7_right_arm_grasp_box
|
||||
params: &grasp_box_s7_s9_right 'body_id: 1
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [0, 0, 0, 0, 0, 0, 96.31, -103.06, 17.69, -53.40, -7.81, 143.19]
|
||||
|
||||
'
|
||||
- name: s7_left_arm_grasp_box
|
||||
params: &grasp_box_s7_s9_left 'body_id: 0
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [83.78, 103.06, -17.69, 53.40, 7.81, 36.90, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s7_right_arm_put_down_box
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [0, 0, 0, 0, 0, 0, 85.28, -103.86, 19.46, 40.34, -7.37, 49.94]
|
||||
|
||||
'
|
||||
- name: s7_left_arm_put_down_box
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [94.81, 103.86, -19.46, -40.33, 7.37, 130.15, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s8_right_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s8_left_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s9_right_arm_grasp_box
|
||||
params: *grasp_box_s7_s9_right
|
||||
- name: s9_left_arm_grasp_box
|
||||
params: *grasp_box_s7_s9_left
|
||||
- name: s11_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s11_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: s12_right_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s12_left_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s13_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s13_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: clear_done_instances_overall
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s14_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s14_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: clear_done_instances_vision
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: clear_done_instances_right_grasp
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: clear_done_instances_left_grasp
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s15_right_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s15_left_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s15_right_arm_pre_grasp
|
||||
params: *pre_grasp_right
|
||||
- name: s15_left_arm_pre_grasp
|
||||
params: *pre_grasp_left
|
||||
- name: s16_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s16_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: clear_done_instances_arm_vision
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s17_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s17_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: clear_done_instances_left_arm_vision
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: clear_done_instances_right_arm_vision
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s0_right_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s0_left_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s1_wheel_move_to_origin_pickup_position
|
||||
params: &origin_pickup_position 'move_distance: 0.0
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s6_wheel_move_to_putdown_position
|
||||
params: 'move_distance: -0.5
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s6_move_waist_turn_left_90
|
||||
params: 'move_pitch_degree: 0.0
|
||||
|
||||
move_yaw_degree: 90.0
|
||||
|
||||
'
|
||||
- name: s10_move_waist_turn_right_90
|
||||
params: &waist_turn_right_90 'move_pitch_degree: 0.0
|
||||
|
||||
move_yaw_degree: -90.0
|
||||
|
||||
'
|
||||
- name: s10_wheel_move_to_origin_pickup_position
|
||||
params: *origin_pickup_position
|
||||
- name: s15_left_arm_cam_take_photo
|
||||
params: *left_arm_cam_take_photo
|
||||
- name: s15_right_arm_cam_take_photo
|
||||
params: *right_arm_cam_take_photo
|
||||
- name: s15_right_arm_initial_vision
|
||||
params: *arm_inittial_right
|
||||
- name: s15_left_arm_initial_vision
|
||||
params: *arm_inittial_left
|
||||
- name: s15_right_arm_initial_grasp
|
||||
params: *arm_inittial_right
|
||||
- name: s15_left_arm_initial_grasp
|
||||
params: *arm_inittial_left
|
||||
- name: s15_right_arm_initial_cam
|
||||
params: *arm_inittial_right
|
||||
- name: s15_left_arm_initial_cam
|
||||
params: *arm_inittial_left
|
||||
351
src/brain/config/bt_vision_grasp_dual_arm.xml
Normal file
351
src/brain/config/bt_vision_grasp_dual_arm.xml
Normal file
@@ -0,0 +1,351 @@
|
||||
<!--
|
||||
功能描述: 双臂协同视觉抓取流程(不含底盘,含分阶段恢复与完成标记清理)。
|
||||
流程: 初始化状态变量 -> 头部相机视觉定位(失败进入视觉恢复)-> 双臂同步到手眼拍照位
|
||||
-> 串行左右手眼视觉识别 -> 双臂异步抓取(各自含抓取恢复)-> 双臂放置 -> 双臂回初始位。
|
||||
-->
|
||||
<root BTCPP_format="4" main_tree_to_execute="MainTree">
|
||||
<BehaviorTree ID="MainTree">
|
||||
<Sequence name="root">
|
||||
<Script code="right_arm_cam_take_photo:=false; left_arm_cam_take_photo:=false; right_arm_done:=false; left_arm_done:=false; right_vision_ok:=false; left_vision_ok:=false" />
|
||||
<RetryUntilSuccessful name="retry_vision_grasp" num_attempts="3">
|
||||
<Fallback name="fallback_main_action">
|
||||
<Sequence name="complete_pick_and_place">
|
||||
<!-- Phase 1: Shared Vision Setup (Top Camera) -->
|
||||
<Fallback name="shared_vision_with_recovery">
|
||||
<SubTree ID="vision_setup_subtree"/>
|
||||
<Sequence>
|
||||
<SubTree ID="vision_recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
|
||||
<!-- Move both arms to positions where their hand cameras can see potential objects -->
|
||||
<SubTree ID="dual_arm_cam_subtree" right_cam_status="{right_arm_cam_take_photo}" left_cam_status="{left_arm_cam_take_photo}"/>
|
||||
|
||||
<!-- Phase 2: Sequential Hand Vision -->
|
||||
<SubTree ID="sequential_hand_vision_subtree" right_done="{right_arm_done}" left_done="{left_arm_done}" right_cam_ok="{right_arm_cam_take_photo}" left_cam_ok="{left_arm_cam_take_photo}" right_v_ok="{right_vision_ok}" left_v_ok="{left_vision_ok}"/>
|
||||
|
||||
<!-- Phase 3: Independent Dual Arm Operation -->
|
||||
<SubTree ID="dual_arm_grasp_subtree_wrapper" right_v_ok="{right_vision_ok}" left_v_ok="{left_vision_ok}" right_done="{right_arm_done}" left_done="{left_arm_done}"/>
|
||||
|
||||
<!-- Phase 4: Dual Arm Putdown -->
|
||||
<SubTree ID="dual_arm_putdown_subtree_wrapper" right_done="{right_arm_done}" left_done="{left_arm_done}"/>
|
||||
|
||||
<!-- Phase 5: Dual Arm Hand Vision -->
|
||||
<Parallel name="dual_arm_init_action">
|
||||
<Arm_H name="s11_right_arm_initial" />
|
||||
<Arm_H name="s11_left_arm_initial" />
|
||||
</Parallel>
|
||||
|
||||
</Sequence>
|
||||
|
||||
<Sequence>
|
||||
<!-- Overall fallback recovery -->
|
||||
<SubTree ID="recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- Shared setup and head-camera vision -->
|
||||
<BehaviorTree ID="vision_setup_subtree">
|
||||
<Sequence name="vision_setup_root">
|
||||
<Parallel name="parallel_arm_init_action">
|
||||
<GripperCmd1_H name="s0_right_hand_gripper_open" />
|
||||
<GripperCmd0_H name="s0_left_hand_gripper_open" />
|
||||
<Arm_H name="s1_right_arm_initial" />
|
||||
<Arm_H name="s1_left_arm_initial" />
|
||||
</Parallel>
|
||||
<Parallel name="parallel_init_action">
|
||||
<GripperCmd1_H name="s1_right_hand_gripper_open" />
|
||||
<GripperCmd0_H name="s1_left_hand_gripper_open" />
|
||||
<!-- <Arm_H name="s1_right_arm_pre_cam_take_photo" />
|
||||
<Arm_H name="s1_left_arm_pre_cam_take_photo" /> -->
|
||||
</Parallel>
|
||||
<RetryUntilSuccessful name="retry_top_cam_vision" num_attempts="5">
|
||||
<VisionObjectRecognition_H name="s2_top_camera_vision_recg" />
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- Right Arm Specific Subtrees -->
|
||||
<BehaviorTree ID="right_arm_hand_vision_subtree">
|
||||
<Fallback name="right_hand_vision_fallback">
|
||||
<RetryUntilSuccessful name="retry_right_hand_cam_vision" num_attempts="5">
|
||||
<VisionObjectRecognition_H name="s3_right_camera_vision_recg" />
|
||||
</RetryUntilSuccessful>
|
||||
<Sequence>
|
||||
<Arm_H name="s15_right_arm_initial_vision" />
|
||||
<AlwaysFailure />
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="right_arm_grasp_subtree">
|
||||
<Sequence name="right_arm_grasp_root">
|
||||
<RetryUntilSuccessful name="retry_right_arm_grasp_action" num_attempts="1">
|
||||
<Sequence>
|
||||
<Arm_H name="s3_right_arm_vision_pre_grasp" />
|
||||
<Arm_H name="s4_right_arm_vision_grasp" />
|
||||
<GripperCmd1_H name="s4_right_hand_gripper_close" />
|
||||
<Arm_H name="s4_right_arm_take_box" />
|
||||
<Arm_H name="s5_right_arm_take_box_off" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="right_arm_putdown_subtree">
|
||||
<Sequence name="right_arm_putdown_root">
|
||||
<RetryUntilSuccessful name="retry_right_arm_putdown" num_attempts="1">
|
||||
<Sequence>
|
||||
<!-- <Arm_H name="s7_right_arm_grasp_box" /> -->
|
||||
<Arm_H name="s7_right_arm_put_down_box" />
|
||||
<GripperCmd1_H name="s8_right_hand_gripper_open" />
|
||||
<Arm_H name="s9_right_arm_grasp_box" />
|
||||
<!-- <Arm_H name="s11_right_arm_initial" /> -->
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- Left Arm Specific Subtrees -->
|
||||
<BehaviorTree ID="left_arm_hand_vision_subtree">
|
||||
<Fallback name="left_hand_vision_fallback">
|
||||
<RetryUntilSuccessful name="retry_left_hand_cam_vision" num_attempts="5">
|
||||
<VisionObjectRecognition_H name="s3_left_camera_vision_recg" />
|
||||
</RetryUntilSuccessful>
|
||||
<Sequence>
|
||||
<Arm_H name="s15_left_arm_initial_vision" />
|
||||
<AlwaysFailure />
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="left_arm_grasp_subtree">
|
||||
<Sequence name="left_arm_grasp_root">
|
||||
<RetryUntilSuccessful name="retry_left_arm_grasp_action" num_attempts="1">
|
||||
<Sequence>
|
||||
<Arm_H name="s3_left_arm_vision_pre_grasp" />
|
||||
<Arm_H name="s4_left_arm_vision_grasp" />
|
||||
<GripperCmd0_H name="s4_left_hand_gripper_close" />
|
||||
<Arm_H name="s4_left_arm_take_box" />
|
||||
<Arm_H name="s5_left_arm_take_box_off" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="left_arm_putdown_subtree">
|
||||
<Sequence name="left_arm_putdown_root">
|
||||
<RetryUntilSuccessful name="retry_left_arm_putdown" num_attempts="1">
|
||||
<Sequence>
|
||||
<!-- <Arm_H name="s7_left_arm_grasp_box" /> -->
|
||||
<Arm_H name="s7_left_arm_put_down_box" />
|
||||
<GripperCmd0_H name="s8_left_hand_gripper_open" />
|
||||
<Arm_H name="s9_left_arm_grasp_box" />
|
||||
<!-- <Arm_H name="s11_left_arm_initial" /> -->
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- Recovery Subtrees -->
|
||||
<BehaviorTree ID="recovery_subtree">
|
||||
<Sequence name="recovery_root">
|
||||
<Parallel name="overall_recovery_parallel">
|
||||
<GripperCmd1_H name="s12_right_hand_gripper_open" />
|
||||
<GripperCmd0_H name="s12_left_hand_gripper_open" />
|
||||
<Arm_H name="s13_right_arm_initial" />
|
||||
<Arm_H name="s13_left_arm_initial" />
|
||||
</Parallel>
|
||||
<ClearDoneInstances_H name="clear_done_instances_overall" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="vision_recovery_subtree">
|
||||
<Sequence name="vision_recovery_root">
|
||||
<Parallel name="arm_initial2">
|
||||
<Arm_H name="s14_right_arm_initial" />
|
||||
<Arm_H name="s14_left_arm_initial" />
|
||||
</Parallel>
|
||||
<ClearDoneInstances_H name="clear_done_instances_vision" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="right_arm_grasp_recovery_subtree">
|
||||
<Sequence name="right_grasp_recovery_root">
|
||||
<GripperCmd1_H name="s15_right_hand_gripper_open" />
|
||||
<Arm_H name="s15_right_arm_pre_grasp" />
|
||||
<Arm_H name="s15_right_arm_cam_take_photo" />
|
||||
<Arm_H name="s15_right_arm_initial_grasp" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_right_grasp" match="right" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="left_arm_grasp_recovery_subtree">
|
||||
<Sequence name="left_grasp_recovery_root">
|
||||
<GripperCmd0_H name="s15_left_hand_gripper_open" />
|
||||
<Arm_H name="s15_left_arm_pre_grasp" />
|
||||
<Arm_H name="s15_left_arm_cam_take_photo" />
|
||||
<Arm_H name="s15_left_arm_initial_grasp" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_left_grasp" match="left" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="arm_vision_recovery_subtree">
|
||||
<Sequence name="arm_vision_recovery_root">
|
||||
<Parallel name="arm_initial3">
|
||||
<Arm_H name="s16_right_arm_initial" />
|
||||
<Arm_H name="s16_left_arm_initial" />
|
||||
</Parallel>
|
||||
<ClearDoneInstances_H name="clear_done_instances_arm_vision" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="left_arm_vision_recovery_subtree">
|
||||
<Sequence name="left_arm_vision_recovery_root">
|
||||
<Parallel name="left_arm_initial">
|
||||
<Arm_H name="s17_left_arm_initial" />
|
||||
</Parallel>
|
||||
<ClearDoneInstances_H name="clear_done_instances_left_arm_vision" match="left" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="right_arm_vision_recovery_subtree">
|
||||
<Sequence name="right_arm_vision_recovery_root">
|
||||
<Parallel name="right_arm_initial">
|
||||
<Arm_H name="s17_right_arm_initial" />
|
||||
</Parallel>
|
||||
<ClearDoneInstances_H name="clear_done_instances_right_arm_vision" match="right" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
|
||||
<!-- 子树:双臂相机同步拍照位 -->
|
||||
<BehaviorTree ID="dual_arm_cam_subtree">
|
||||
<Sequence name="cam_sync_root">
|
||||
<Script code="right_cam_status:=false; left_cam_status:=false" />
|
||||
<Parallel name="dual_arm_cam_take_photo" success_count="2" failure_count="2">
|
||||
<!-- 右臂 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<Arm_H name="s2_right_arm_cam_take_photo" />
|
||||
<Script code="right_cam_status:=true" />
|
||||
</Sequence>
|
||||
<Arm_H name="s15_right_arm_initial_cam" />
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
<!-- 左臂 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<Arm_H name="s2_left_arm_cam_take_photo" />
|
||||
<Script code="left_cam_status:=true" />
|
||||
</Sequence>
|
||||
<Arm_H name="s15_left_arm_initial_cam" />
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
</Parallel>
|
||||
<ScriptCondition code="right_cam_status==true || left_cam_status==true" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- 子树:串行手眼视觉识别 -->
|
||||
<BehaviorTree ID="sequential_hand_vision_subtree">
|
||||
<Sequence name="hand_vision_root">
|
||||
<Script code="right_v_ok:=false; left_v_ok:=false" />
|
||||
<!-- 右臂视觉 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="right_done==false && right_cam_ok==true" />
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<SubTree ID="right_arm_hand_vision_subtree"/>
|
||||
<Script code="right_v_ok:=true" />
|
||||
</Sequence>
|
||||
<AlwaysFailure/>
|
||||
</Fallback>
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
<!-- 左臂视觉 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="left_done==false && left_cam_ok==true" />
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<SubTree ID="left_arm_hand_vision_subtree"/>
|
||||
<Script code="left_v_ok:=true" />
|
||||
</Sequence>
|
||||
<AlwaysFailure/>
|
||||
</Fallback>
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- 子树:异步双臂抓取 -->
|
||||
<BehaviorTree ID="dual_arm_grasp_subtree_wrapper">
|
||||
<Sequence name="grasp_sync_root">
|
||||
<Parallel name="dual_arm_asynchronous_grasp" success_count="2" failure_count="2">
|
||||
<!-- 右臂抓取 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="right_v_ok==true" />
|
||||
<SubTree ID="right_arm_grasp_subtree"/>
|
||||
<Script code="right_done:=true" />
|
||||
</Sequence>
|
||||
<Sequence>
|
||||
<ScriptCondition code="right_v_ok==true" />
|
||||
<SubTree ID="right_arm_grasp_recovery_subtree"/>
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
<!-- 左臂抓取 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="left_v_ok==true" />
|
||||
<SubTree ID="left_arm_grasp_subtree"/>
|
||||
<Script code="left_done:=true" />
|
||||
</Sequence>
|
||||
<Sequence>
|
||||
<ScriptCondition code="left_v_ok==true" />
|
||||
<SubTree ID="left_arm_grasp_recovery_subtree"/>
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
</Parallel>
|
||||
<ScriptCondition code="right_done==true || left_done==true" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- 子树:双臂放置流程 -->
|
||||
<BehaviorTree ID="dual_arm_putdown_subtree_wrapper">
|
||||
<Sequence name="putdown_sync_root">
|
||||
<Script code="left_p_ok:=false; right_p_ok:=false" />
|
||||
<Parallel name="dual_arm_putdown" success_count="2" failure_count="2">
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="left_done==true" />
|
||||
<SubTree ID="left_arm_putdown_subtree"/>
|
||||
<Script code="left_p_ok:=true" />
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="right_done==true" />
|
||||
<SubTree ID="right_arm_putdown_subtree"/>
|
||||
<Script code="right_p_ok:=true" />
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
</Parallel>
|
||||
<ScriptCondition code="left_p_ok==true || right_p_ok==true" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
</root>
|
||||
398
src/brain/config/bt_vision_grasp_dual_arm_demo1.params.yaml
Normal file
398
src/brain/config/bt_vision_grasp_dual_arm_demo1.params.yaml
Normal file
@@ -0,0 +1,398 @@
|
||||
- name: root
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s1_right_hand_gripper_open
|
||||
params: &gripper_open 'loc: 0
|
||||
|
||||
speed: 150
|
||||
|
||||
torque: 20
|
||||
|
||||
mode: 2
|
||||
|
||||
'
|
||||
- name: s1_left_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s1_right_arm_initial
|
||||
params: &arm_inittial_right 'body_id: 1
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [0, 0, 0, 0, 0, 0, 80, -5, -112, -12, -62, 175]
|
||||
|
||||
'
|
||||
- name: s1_left_arm_initial
|
||||
params: &arm_inittial_left 'body_id: 0
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [100, 5, 112, 12, 62, 5, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s1_right_arm_pre_cam_take_photo
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [0, 0, 0, 0, 0, 0, 14.29, -34.07, -122.53, -76.89, 84.40, 112.89]
|
||||
|
||||
'
|
||||
- name: s1_left_arm_pre_cam_take_photo
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [165.80, 34.07, 122.53, 76.89, -84.40, 67.20, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s2_right_arm_cam_take_photo
|
||||
params: &right_arm_cam_take_photo 'body_id: 1
|
||||
|
||||
data_type: 100
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s2_left_arm_cam_take_photo
|
||||
params: &left_arm_cam_take_photo 'body_id: 0
|
||||
|
||||
data_type: 100
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s2_top_camera_vision_recg
|
||||
params: 'camera_position: top
|
||||
|
||||
'
|
||||
- name: s3_right_camera_vision_recg
|
||||
params: 'camera_position: right
|
||||
|
||||
'
|
||||
- name: s3_left_camera_vision_recg
|
||||
params: 'camera_position: left
|
||||
|
||||
'
|
||||
- name: s3_right_arm_vision_pre_grasp
|
||||
params: &pre_grasp_right 'body_id: 1
|
||||
|
||||
data_type: 101
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s3_left_arm_vision_pre_grasp
|
||||
params: &pre_grasp_left 'body_id: 0
|
||||
|
||||
data_type: 101
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_right_arm_vision_grasp
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 102
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_left_arm_vision_grasp
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 102
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_right_hand_gripper_close
|
||||
params: &gripper_close 'loc: 200
|
||||
|
||||
speed: 150
|
||||
|
||||
torque: 100
|
||||
|
||||
mode: 2
|
||||
|
||||
'
|
||||
- name: s4_left_hand_gripper_close
|
||||
params: *gripper_close
|
||||
- name: s4_right_arm_take_box
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 110
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_left_arm_take_box
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 110
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s5_right_arm_take_box_off
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [0, 0, 0, 0, 0, 0, 96.31, -103.06, 17.69, -53.40, -7.81, 143.19]
|
||||
|
||||
'
|
||||
- name: s5_left_arm_take_box_off
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [83.78, 103.06, -17.69, 53.40, 7.81, 36.90, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s7_right_arm_grasp_box
|
||||
params: &grasp_box_s7_s9_right 'body_id: 1
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [0, 0, 0, 0, 0, 0, 96.31, -103.06, 17.69, -53.40, -7.81, 143.19]
|
||||
|
||||
'
|
||||
- name: s7_left_arm_grasp_box
|
||||
params: &grasp_box_s7_s9_left 'body_id: 0
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [83.78, 103.06, -17.69, 53.40, 7.81, 36.90, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s7_right_arm_put_down_box
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [0, 0, 0, 0, 0, 0, 85.28, -103.86, 19.46, 40.34, -7.37, 49.94]
|
||||
|
||||
'
|
||||
- name: s7_left_arm_put_down_box
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [94.81, 103.86, -19.46, -40.33, 7.37, 130.15, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
'
|
||||
- name: s8_right_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s8_left_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s9_right_arm_grasp_box
|
||||
params: *grasp_box_s7_s9_right
|
||||
- name: s9_left_arm_grasp_box
|
||||
params: *grasp_box_s7_s9_left
|
||||
- name: s11_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s11_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: s12_right_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s12_left_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s13_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s13_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: clear_done_instances_overall
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s14_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s14_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: clear_done_instances_vision
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: clear_done_instances_right_grasp
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: clear_done_instances_left_grasp
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s15_right_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s15_left_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s15_right_arm_pre_grasp
|
||||
params: *pre_grasp_right
|
||||
- name: s15_left_arm_pre_grasp
|
||||
params: *pre_grasp_left
|
||||
- name: s15_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s15_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: s16_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s16_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: clear_done_instances_arm_vision
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s17_right_arm_initial
|
||||
params: *arm_inittial_right
|
||||
- name: s17_left_arm_initial
|
||||
params: *arm_inittial_left
|
||||
- name: clear_done_instances_left_arm_vision
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: clear_done_instances_right_arm_vision
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s0_right_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s0_left_hand_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s1_wheel_move_to_origin_pickup_position
|
||||
params: &origin_pickup_position 'move_distance: 0.0
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s6_wheel_move_to_putdown_position
|
||||
params: 'move_distance: -0.5
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s6_move_waist_turn_left_90
|
||||
params: 'move_pitch_degree: 0.0
|
||||
|
||||
move_yaw_degree: 90.0
|
||||
|
||||
'
|
||||
- name: s10_move_waist_turn_right_90
|
||||
params: &waist_turn_right_90 'move_pitch_degree: 0.0
|
||||
|
||||
move_yaw_degree: -90.0
|
||||
|
||||
'
|
||||
- name: s10_wheel_move_to_origin_pickup_position
|
||||
params: *origin_pickup_position
|
||||
- name: s15_left_arm_cam_take_photo
|
||||
params: *left_arm_cam_take_photo
|
||||
- name: s15_right_arm_cam_take_photo
|
||||
params: *right_arm_cam_take_photo
|
||||
354
src/brain/config/bt_vision_grasp_dual_arm_demo1.xml
Normal file
354
src/brain/config/bt_vision_grasp_dual_arm_demo1.xml
Normal file
@@ -0,0 +1,354 @@
|
||||
<!--
|
||||
功能描述: 双臂协同视觉抓取演示流程1(全机身协作,含失败恢复与重试)。
|
||||
流程: 底盘移动到抓取工位 -> 头部相机定位 + 双臂手眼识别 -> 双臂异步抓取
|
||||
-> 底盘移动到放置工位并腰部旋转 -> 双臂放置 -> 腰部复位 -> 底盘回抓取位 -> 双臂回初始位。
|
||||
-->
|
||||
<root BTCPP_format="4" main_tree_to_execute="MainTree">
|
||||
<BehaviorTree ID="MainTree">
|
||||
<Sequence name="root">
|
||||
<Script code="right_arm_cam_take_photo:=false; left_arm_cam_take_photo:=false; right_arm_done:=false; left_arm_done:=false; right_vision_ok:=false; left_vision_ok:=false" />
|
||||
<RetryUntilSuccessful name="retry_vision_grasp" num_attempts="3">
|
||||
<Fallback name="fallback_main_action">
|
||||
<Sequence name="complete_pick_and_place">
|
||||
<!-- Phase 0: Move Wheel to Origin Pickup Position -->
|
||||
<MoveWheel_H name="s1_wheel_move_to_origin_pickup_position" />
|
||||
|
||||
<!-- Phase 1: Shared Vision Setup (Top Camera) -->
|
||||
<Fallback name="shared_vision_with_recovery">
|
||||
<SubTree ID="vision_setup_subtree"/>
|
||||
<Sequence>
|
||||
<SubTree ID="vision_recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
|
||||
<!-- Move both arms to positions where their hand cameras can see potential objects -->
|
||||
<SubTree ID="dual_arm_cam_subtree" right_cam_status="{right_arm_cam_take_photo}" left_cam_status="{left_arm_cam_take_photo}"/>
|
||||
|
||||
<!-- Phase 2: Sequential Hand Vision -->
|
||||
<SubTree ID="sequential_hand_vision_subtree" right_done="{right_arm_done}" left_done="{left_arm_done}" right_cam_ok="{right_arm_cam_take_photo}" left_cam_ok="{left_arm_cam_take_photo}" right_v_ok="{right_vision_ok}" left_v_ok="{left_vision_ok}"/>
|
||||
|
||||
<!-- Phase 3: Independent Dual Arm Operation -->
|
||||
<SubTree ID="dual_arm_grasp_subtree_wrapper" right_v_ok="{right_vision_ok}" left_v_ok="{left_vision_ok}" right_done="{right_arm_done}" left_done="{left_arm_done}"/>
|
||||
|
||||
<Parallel name="parallel_action_2">
|
||||
<MoveWheel_H name="s6_wheel_move_to_putdown_position" />
|
||||
<MoveWaist_H name="s6_move_waist_turn_left_90" />
|
||||
</Parallel>
|
||||
|
||||
<!-- Phase 4: Dual Arm Putdown -->
|
||||
<SubTree ID="dual_arm_putdown_subtree_wrapper" right_done="{right_arm_done}" left_done="{left_arm_done}"/>
|
||||
|
||||
<MoveWaist_H name="s10_move_waist_turn_right_90" />
|
||||
|
||||
<!-- Phase 5: Dual Arm Initialization -->
|
||||
<Parallel name="dual_arm_init_action">
|
||||
<MoveWheel_H name="s10_wheel_move_to_origin_pickup_position" />
|
||||
<Arm_H name="s11_right_arm_initial" />
|
||||
<Arm_H name="s11_left_arm_initial" />
|
||||
</Parallel>
|
||||
|
||||
</Sequence>
|
||||
|
||||
<Sequence>
|
||||
<!-- Overall fallback recovery -->
|
||||
<SubTree ID="recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- Shared setup and head-camera vision -->
|
||||
<BehaviorTree ID="vision_setup_subtree">
|
||||
<Sequence name="vision_setup_root">
|
||||
<Parallel name="parallel_arm_init_action">
|
||||
<GripperCmd1_H name="s0_right_hand_gripper_open" />
|
||||
<GripperCmd0_H name="s0_left_hand_gripper_open" />
|
||||
<Arm_H name="s1_right_arm_initial" />
|
||||
<Arm_H name="s1_left_arm_initial" />
|
||||
</Parallel>
|
||||
<Parallel name="parallel_init_action">
|
||||
<GripperCmd1_H name="s1_right_hand_gripper_open" />
|
||||
<GripperCmd0_H name="s1_left_hand_gripper_open" />
|
||||
<!-- <Arm_H name="s1_right_arm_pre_cam_take_photo" />
|
||||
<Arm_H name="s1_left_arm_pre_cam_take_photo" /> -->
|
||||
</Parallel>
|
||||
<RetryUntilSuccessful name="retry_top_cam_vision" num_attempts="5">
|
||||
<VisionObjectRecognition_H name="s2_top_camera_vision_recg" />
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- Right Arm Specific Subtrees -->
|
||||
<BehaviorTree ID="right_arm_hand_vision_subtree">
|
||||
<Sequence name="right_hand_vision_root">
|
||||
<RetryUntilSuccessful name="retry_right_hand_cam_vision" num_attempts="5">
|
||||
<VisionObjectRecognition_H name="s3_right_camera_vision_recg" />
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="right_arm_grasp_subtree">
|
||||
<Sequence name="right_arm_grasp_root">
|
||||
<RetryUntilSuccessful name="retry_right_arm_grasp_action" num_attempts="1">
|
||||
<Sequence>
|
||||
<Arm_H name="s3_right_arm_vision_pre_grasp" />
|
||||
<Arm_H name="s4_right_arm_vision_grasp" />
|
||||
<GripperCmd1_H name="s4_right_hand_gripper_close" />
|
||||
<Arm_H name="s4_right_arm_take_box" />
|
||||
<Arm_H name="s5_right_arm_take_box_off" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="right_arm_putdown_subtree">
|
||||
<Sequence name="right_arm_putdown_root">
|
||||
<RetryUntilSuccessful name="retry_right_arm_putdown" num_attempts="1">
|
||||
<Sequence>
|
||||
<!-- <Arm_H name="s7_right_arm_grasp_box" /> -->
|
||||
<Arm_H name="s7_right_arm_put_down_box" />
|
||||
<GripperCmd1_H name="s8_right_hand_gripper_open" />
|
||||
<Arm_H name="s9_right_arm_grasp_box" />
|
||||
<!-- <Arm_H name="s11_right_arm_initial" /> -->
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- Left Arm Specific Subtrees -->
|
||||
<BehaviorTree ID="left_arm_hand_vision_subtree">
|
||||
<Sequence name="left_hand_vision_root">
|
||||
<RetryUntilSuccessful name="retry_left_hand_cam_vision" num_attempts="5">
|
||||
<VisionObjectRecognition_H name="s3_left_camera_vision_recg" />
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="left_arm_grasp_subtree">
|
||||
<Sequence name="left_arm_grasp_root">
|
||||
<RetryUntilSuccessful name="retry_left_arm_grasp_action" num_attempts="1">
|
||||
<Sequence>
|
||||
<Arm_H name="s3_left_arm_vision_pre_grasp" />
|
||||
<Arm_H name="s4_left_arm_vision_grasp" />
|
||||
<GripperCmd0_H name="s4_left_hand_gripper_close" />
|
||||
<Arm_H name="s4_left_arm_take_box" />
|
||||
<Arm_H name="s5_left_arm_take_box_off" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="left_arm_putdown_subtree">
|
||||
<Sequence name="left_arm_putdown_root">
|
||||
<RetryUntilSuccessful name="retry_left_arm_putdown" num_attempts="1">
|
||||
<Sequence>
|
||||
<!-- <Arm_H name="s7_left_arm_grasp_box" /> -->
|
||||
<Arm_H name="s7_left_arm_put_down_box" />
|
||||
<GripperCmd0_H name="s8_left_hand_gripper_open" />
|
||||
<Arm_H name="s9_left_arm_grasp_box" />
|
||||
<!-- <Arm_H name="s11_left_arm_initial" /> -->
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- Recovery Subtrees -->
|
||||
<BehaviorTree ID="recovery_subtree">
|
||||
<Sequence name="recovery_root">
|
||||
<Parallel name="overall_recovery_parallel">
|
||||
<GripperCmd1_H name="s12_right_hand_gripper_open" />
|
||||
<GripperCmd0_H name="s12_left_hand_gripper_open" />
|
||||
<Arm_H name="s13_right_arm_initial" />
|
||||
<Arm_H name="s13_left_arm_initial" />
|
||||
</Parallel>
|
||||
<ClearDoneInstances_H name="clear_done_instances_overall" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="vision_recovery_subtree">
|
||||
<Sequence name="vision_recovery_root">
|
||||
<Parallel name="arm_initial2">
|
||||
<Arm_H name="s14_right_arm_initial" />
|
||||
<Arm_H name="s14_left_arm_initial" />
|
||||
</Parallel>
|
||||
<ClearDoneInstances_H name="clear_done_instances_vision" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="right_arm_grasp_recovery_subtree">
|
||||
<Sequence name="right_grasp_recovery_root">
|
||||
<GripperCmd1_H name="s15_right_hand_gripper_open" />
|
||||
<Arm_H name="s15_right_arm_pre_grasp" />
|
||||
<Arm_H name="s15_right_arm_cam_take_photo" />
|
||||
<Arm_H name="s15_right_arm_initial" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_right_grasp" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="left_arm_grasp_recovery_subtree">
|
||||
<Sequence name="left_grasp_recovery_root">
|
||||
<GripperCmd0_H name="s15_left_hand_gripper_open" />
|
||||
<Arm_H name="s15_left_arm_pre_grasp" />
|
||||
<Arm_H name="s15_left_arm_cam_take_photo" />
|
||||
<Arm_H name="s15_left_arm_initial" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_left_grasp" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="arm_vision_recovery_subtree">
|
||||
<Sequence name="arm_vision_recovery_root">
|
||||
<Parallel name="arm_initial3">
|
||||
<Arm_H name="s16_right_arm_initial" />
|
||||
<Arm_H name="s16_left_arm_initial" />
|
||||
</Parallel>
|
||||
<ClearDoneInstances_H name="clear_done_instances_arm_vision" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="left_arm_vision_recovery_subtree">
|
||||
<Sequence name="left_arm_vision_recovery_root">
|
||||
<Parallel name="left_arm_initial">
|
||||
<Arm_H name="s17_left_arm_initial" />
|
||||
</Parallel>
|
||||
<ClearDoneInstances_H name="clear_done_instances_left_arm_vision" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="right_arm_vision_recovery_subtree">
|
||||
<Sequence name="right_arm_vision_recovery_root">
|
||||
<Parallel name="right_arm_initial">
|
||||
<Arm_H name="s17_right_arm_initial" />
|
||||
</Parallel>
|
||||
<ClearDoneInstances_H name="clear_done_instances_right_arm_vision" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
|
||||
<!-- 子树:双臂相机同步拍照位 -->
|
||||
<BehaviorTree ID="dual_arm_cam_subtree">
|
||||
<Sequence name="cam_sync_root">
|
||||
<Script code="right_cam_status:=false; left_cam_status:=false" />
|
||||
<Parallel name="dual_arm_cam_take_photo" success_count="2" failure_count="2">
|
||||
<!-- 右臂 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<Arm_H name="s2_right_arm_cam_take_photo" />
|
||||
<Script code="right_cam_status:=true" />
|
||||
</Sequence>
|
||||
<Arm_H name="s15_right_arm_initial" />
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
<!-- 左臂 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<Arm_H name="s2_left_arm_cam_take_photo" />
|
||||
<Script code="left_cam_status:=true" />
|
||||
</Sequence>
|
||||
<Arm_H name="s15_left_arm_initial" />
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
</Parallel>
|
||||
<ScriptCondition code="right_cam_status==true || left_cam_status==true" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- 子树:串行手眼视觉识别 -->
|
||||
<BehaviorTree ID="sequential_hand_vision_subtree">
|
||||
<Sequence name="hand_vision_root">
|
||||
<Script code="right_v_ok:=false; left_v_ok:=false" />
|
||||
<!-- 右臂视觉 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="right_done==false && right_cam_ok==true" />
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<SubTree ID="right_arm_hand_vision_subtree"/>
|
||||
<Script code="right_v_ok:=true" />
|
||||
</Sequence>
|
||||
<AlwaysFailure/>
|
||||
</Fallback>
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
<!-- 左臂视觉 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="left_done==false && left_cam_ok==true" />
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<SubTree ID="left_arm_hand_vision_subtree"/>
|
||||
<Script code="left_v_ok:=true" />
|
||||
</Sequence>
|
||||
<AlwaysFailure/>
|
||||
</Fallback>
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- 子树:异步双臂抓取 -->
|
||||
<BehaviorTree ID="dual_arm_grasp_subtree_wrapper">
|
||||
<Sequence name="grasp_sync_root">
|
||||
<Parallel name="dual_arm_asynchronous_grasp" success_count="2" failure_count="2">
|
||||
<!-- 右臂抓取 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="right_v_ok==true" />
|
||||
<SubTree ID="right_arm_grasp_subtree"/>
|
||||
<Script code="right_done:=true" />
|
||||
</Sequence>
|
||||
<Sequence>
|
||||
<ScriptCondition code="right_v_ok==true" />
|
||||
<SubTree ID="right_arm_grasp_recovery_subtree"/>
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
<!-- 左臂抓取 -->
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="left_v_ok==true" />
|
||||
<SubTree ID="left_arm_grasp_subtree"/>
|
||||
<Script code="left_done:=true" />
|
||||
</Sequence>
|
||||
<Sequence>
|
||||
<ScriptCondition code="left_v_ok==true" />
|
||||
<SubTree ID="left_arm_grasp_recovery_subtree"/>
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
</Parallel>
|
||||
<ScriptCondition code="right_done==true || left_done==true" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<!-- 子树:双臂放置流程 -->
|
||||
<BehaviorTree ID="dual_arm_putdown_subtree_wrapper">
|
||||
<Sequence name="putdown_sync_root">
|
||||
<Script code="left_p_ok:=false; right_p_ok:=false" />
|
||||
<Parallel name="dual_arm_putdown" success_count="2" failure_count="2">
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="left_done==true" />
|
||||
<SubTree ID="left_arm_putdown_subtree"/>
|
||||
<Script code="left_p_ok:=true" />
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
<Fallback>
|
||||
<Sequence>
|
||||
<ScriptCondition code="right_done==true" />
|
||||
<SubTree ID="right_arm_putdown_subtree"/>
|
||||
<Script code="right_p_ok:=true" />
|
||||
</Sequence>
|
||||
<AlwaysSuccess/>
|
||||
</Fallback>
|
||||
</Parallel>
|
||||
<ScriptCondition code="left_p_ok==true || right_p_ok==true" />
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
</root>
|
||||
218
src/brain/config/bt_vision_grasp_left_arm.params.yaml
Normal file
218
src/brain/config/bt_vision_grasp_left_arm.params.yaml
Normal file
@@ -0,0 +1,218 @@
|
||||
- name: root
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: retry_vision_hand
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s1_move_waist_turn_right_90
|
||||
params: &waist_turn_right_90 'move_pitch_degree: 0.0
|
||||
|
||||
move_yaw_degree: -90.0
|
||||
|
||||
'
|
||||
- name: s1_gripper_open
|
||||
params: &gripper_open 'loc: 0
|
||||
|
||||
speed: 150
|
||||
|
||||
torque: 20
|
||||
|
||||
mode: 2
|
||||
|
||||
'
|
||||
- name: s1_left_arm_pre_cam_take_photo
|
||||
params: &pre_cam_take_photo 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [85, 25, 90, 0, 68, 90, 95, -25, -90, 0, -68, 90]
|
||||
|
||||
'
|
||||
- name: s1_wheel_move_to_origin_pickup_position
|
||||
params: 'move_distance: 0.5
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s2_left_arm_pre_cam_take_photo
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [120, 20, 80, 0, 80, 120, 60, -20, -80, 0, -80, 60]
|
||||
|
||||
'
|
||||
- name: s2_top_camera_vision_recg
|
||||
params: 'camera_position: top
|
||||
|
||||
'
|
||||
- name: s2_left_arm_cam_take_photo
|
||||
params: &arm_cam_take_photo 'body_id: 0
|
||||
|
||||
data_type: 100
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s3_left_camera_vision_recg
|
||||
params: 'camera_position: left
|
||||
|
||||
'
|
||||
- name: s3_left_arm_vision_pre_grasp
|
||||
params: &pre_grasp 'body_id: 0
|
||||
|
||||
data_type: 101
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_left_arm_vision_grasp
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 102
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_gripper_close
|
||||
params: 'loc: 200
|
||||
|
||||
speed: 150
|
||||
|
||||
torque: 100
|
||||
|
||||
mode: 2
|
||||
|
||||
'
|
||||
- name: s4_left_arm_take_box
|
||||
params: 'body_id: 0
|
||||
|
||||
data_type: 110
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s5_left_arm_grasp_box
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [84, 88, 45, 22, 16, 68, 95, -25, -90, 0, -68, 90]
|
||||
|
||||
'
|
||||
- name: s6_move_waist_turn_left_90
|
||||
params: 'move_pitch_degree: 0.0
|
||||
|
||||
move_yaw_degree: 90.0
|
||||
|
||||
'
|
||||
- name: s6_wheel_move_to_putdown_position
|
||||
params: 'move_distance: 0.0
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s7_left_arm_grasp_box
|
||||
params: &grasp_box_s7_s9 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [85, 88, -14, 22, 16, 68, 95, -25, -90, 0, -68, 90]
|
||||
|
||||
'
|
||||
- name: s7_left_arm_put_down_box
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [95, 88, -14, -22, 16, 112, 95, -25, -90, 0, -68, 90]
|
||||
|
||||
'
|
||||
- name: s8_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s9_left_arm_grasp_box
|
||||
params: *grasp_box_s7_s9
|
||||
- name: s10_move_waist_turn_right_90
|
||||
params: *waist_turn_right_90
|
||||
- name: s11_left_arm_pre_cam_take_photo
|
||||
params: *pre_cam_take_photo
|
||||
- name: s12_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s13_left_arm_pre_cam_take_photo
|
||||
params: *pre_cam_take_photo
|
||||
- name: s14_left_arm_pre_cam_take_photo
|
||||
params: *pre_cam_take_photo
|
||||
- name: s15_left_arm_pre_cam_take_photo
|
||||
params: *pre_cam_take_photo
|
||||
- name: s16_left_arm_pre_cam_take_photo
|
||||
params: *pre_cam_take_photo
|
||||
- name: s14_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s15_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s16_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s15_arm_pre_grasp
|
||||
params: *pre_grasp
|
||||
- name: s16_arm_pre_grasp
|
||||
params: *pre_grasp
|
||||
- name: s15_left_arm_cam_take_photo
|
||||
params: *arm_cam_take_photo
|
||||
- name: s16_left_arm_cam_take_photo
|
||||
params: *arm_cam_take_photo
|
||||
171
src/brain/config/bt_vision_grasp_left_arm.xml
Normal file
171
src/brain/config/bt_vision_grasp_left_arm.xml
Normal file
@@ -0,0 +1,171 @@
|
||||
<!--
|
||||
功能描述: 左臂独立视觉抓取流程(视觉/抓取/放置均带恢复与重试)。
|
||||
流程: 左臂到手眼拍照位 -> 相机识别目标 -> 预抓取/抓取/抬起 -> 送到放置位并松爪 -> 回到初始位。
|
||||
-->
|
||||
<root BTCPP_format="4" main_tree_to_execute="MainTree">
|
||||
<BehaviorTree ID="MainTree">
|
||||
<Sequence name="root">
|
||||
<RetryUntilSuccessful name="retry_vision_grasp" num_attempts="3">
|
||||
<Fallback name="fallback_main_action">
|
||||
<Sequence name="complete_pick_and_place">
|
||||
<!-- Vision with recovery -->
|
||||
<Fallback name="vision_with_recovery">
|
||||
<SubTree ID="vision_subtree"/>
|
||||
<Sequence>
|
||||
<SubTree ID="vision_recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
|
||||
<!-- Grasp with recovery -->
|
||||
<Fallback name="grasp_with_recovery">
|
||||
<SubTree ID="grasp_subtree"/>
|
||||
<Sequence>
|
||||
<SubTree ID="grasp_recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
|
||||
<!-- Putdown with recovery -->
|
||||
<Fallback name="putdown_with_recovery">
|
||||
<SubTree ID="putdown_subtree"/>
|
||||
<Sequence>
|
||||
<SubTree ID="putdown_recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
</Sequence>
|
||||
|
||||
<!-- Overall recovery if the entire sequence fails -->
|
||||
<!-- <Sequence>
|
||||
<SubTree ID="recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence> -->
|
||||
</Fallback>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="vision_subtree">
|
||||
<Sequence name="vision_root">
|
||||
<RetryUntilSuccessful name="retry_vision" num_attempts="1">
|
||||
<Sequence>
|
||||
<Arm_H name="s1_left_arm_pre_cam_take_photo" />
|
||||
<Parallel name="parallel_action_1">
|
||||
<!-- <MoveWheel_H name="s1_wheel_move_to_origin_pickup_position" /> -->
|
||||
<GripperCmd0_H name="s1_gripper_open" />
|
||||
<Arm_H name="s2_left_arm_pre_cam_take_photo" />
|
||||
</Parallel>
|
||||
<SubTree ID="vision_top_cam_subtree"/>
|
||||
|
||||
<Arm_H name="s2_left_arm_cam_take_photo" />
|
||||
<SubTree ID="vision_hand_cam_subtree"/>
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="vision_top_cam_subtree">
|
||||
<Sequence name="vision_top_cam_root">
|
||||
<RetryUntilSuccessful name="retry_top_cam_vision_recg_1" num_attempts="10">
|
||||
<VisionObjectRecognition_H name="s2_top_camera_vision_recg" />
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="vision_hand_cam_subtree">
|
||||
<Sequence name="vision_hand_cam_root">
|
||||
<RetryUntilSuccessful name="retry_hand_cam_vision_recg_1" num_attempts="10">
|
||||
<VisionObjectRecognition_H name="s3_left_camera_vision_recg" />
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="grasp_subtree">
|
||||
<Sequence name="grasp_root">
|
||||
<RetryUntilSuccessful name="retry_grasp" num_attempts="1">
|
||||
<Sequence>
|
||||
<Arm_H name="s3_left_arm_vision_pre_grasp" />
|
||||
<Arm_H name="s4_left_arm_vision_grasp" />
|
||||
<GripperCmd0_H name="s4_gripper_close" />
|
||||
<Arm_H name="s4_left_arm_take_box" />
|
||||
<Arm_H name="s5_left_arm_grasp_box" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="putdown_subtree">
|
||||
<Sequence name="putdown_root">
|
||||
<RetryUntilSuccessful name="retry_putdown" num_attempts="1">
|
||||
<Sequence>
|
||||
<!-- <Parallel name="parallel_action_2">
|
||||
<MoveWheel_H name="s6_wheel_move_to_putdown_position" />
|
||||
<MoveWaist_H name="s6_move_waist_turn_left_90" />
|
||||
</Parallel> -->
|
||||
<Arm_H name="s7_left_arm_grasp_box" />
|
||||
<Arm_H name="s7_left_arm_put_down_box" />
|
||||
<GripperCmd0_H name="s8_gripper_open" />
|
||||
<Arm_H name="s9_left_arm_grasp_box" />
|
||||
|
||||
<Parallel name="parallel_action_3">
|
||||
<!-- <MoveWaist_H name="s10_move_waist_turn_right_90" /> -->
|
||||
<Arm_H name="s11_left_arm_pre_cam_take_photo" />
|
||||
</Parallel>
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="recovery_subtree">
|
||||
<Sequence name="recovery_root">
|
||||
<RetryUntilSuccessful name="retry_recovery" num_attempts="1">
|
||||
<Sequence>
|
||||
<GripperCmd0_H name="s12_gripper_open" />
|
||||
<Arm_H name="s13_left_arm_pre_cam_take_photo" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_overall" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="vision_recovery_subtree">
|
||||
<Sequence name="vision_recovery_root">
|
||||
<RetryUntilSuccessful name="retry_vision_recovery" num_attempts="1">
|
||||
<Sequence>
|
||||
<!-- <GripperCmd0_H name="s14_gripper_open" /> -->
|
||||
<Arm_H name="s14_left_arm_pre_cam_take_photo" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_vision" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="grasp_recovery_subtree">
|
||||
<Sequence name="grasp_recovery_root">
|
||||
<RetryUntilSuccessful name="retry_grasp_recovery" num_attempts="1">
|
||||
<Sequence>
|
||||
<GripperCmd0_H name="s15_gripper_open" />
|
||||
<Arm_H name="s15_arm_pre_grasp" />
|
||||
<Arm_H name="s15_left_arm_cam_take_photo" />
|
||||
<Arm_H name="s15_left_arm_pre_cam_take_photo" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_grasp" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="putdown_recovery_subtree">
|
||||
<Sequence name="putdown_recovery_root">
|
||||
<RetryUntilSuccessful name="retry_putdown_recovery" num_attempts="1">
|
||||
<Sequence>
|
||||
<GripperCmd0_H name="s16_gripper_open" />
|
||||
<Arm_H name="s16_arm_pre_grasp" />
|
||||
<Arm_H name="s16_left_arm_cam_take_photo" />
|
||||
<Arm_H name="s16_left_arm_pre_cam_take_photo" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_putdown" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
</root>
|
||||
218
src/brain/config/bt_vision_grasp_right_arm.params.yaml
Normal file
218
src/brain/config/bt_vision_grasp_right_arm.params.yaml
Normal file
@@ -0,0 +1,218 @@
|
||||
- name: root
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: retry_vision_hand
|
||||
params: '{}
|
||||
|
||||
'
|
||||
- name: s1_move_waist_turn_right_90
|
||||
params: &waist_turn_right_90 'move_pitch_degree: 0.0
|
||||
|
||||
move_yaw_degree: -90.0
|
||||
|
||||
'
|
||||
- name: s1_gripper_open
|
||||
params: &gripper_open 'loc: 0
|
||||
|
||||
speed: 150
|
||||
|
||||
torque: 20
|
||||
|
||||
mode: 2
|
||||
|
||||
'
|
||||
- name: s1_right_arm_pre_cam_take_photo
|
||||
params: &pre_cam_take_photo 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [85, 25, 90, 0, 68, 90, 95, -25, -90, 0, -68, 90]
|
||||
|
||||
'
|
||||
- name: s1_wheel_move_to_origin_pickup_position
|
||||
params: 'move_distance: 0.5
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s2_right_arm_pre_cam_take_photo
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [120, 20, 80, 0, 80, 120, 60, -20, -80, 0, -80, 60]
|
||||
|
||||
'
|
||||
- name: s2_top_camera_vision_recg
|
||||
params: 'camera_position: top
|
||||
|
||||
'
|
||||
- name: s2_right_arm_cam_take_photo
|
||||
params: &arm_cam_take_photo 'body_id: 1
|
||||
|
||||
data_type: 100
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s3_right_camera_vision_recg
|
||||
params: 'camera_position: right
|
||||
|
||||
'
|
||||
- name: s3_right_arm_vision_pre_grasp
|
||||
params: &pre_grasp 'body_id: 1
|
||||
|
||||
data_type: 101
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_right_arm_vision_grasp
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 102
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s4_gripper_close
|
||||
params: 'loc: 200
|
||||
|
||||
speed: 150
|
||||
|
||||
torque: 100
|
||||
|
||||
mode: 2
|
||||
|
||||
'
|
||||
- name: s4_right_arm_take_box
|
||||
params: 'body_id: 1
|
||||
|
||||
data_type: 110
|
||||
|
||||
data_length: 0
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: []
|
||||
|
||||
'
|
||||
- name: s5_right_arm_grasp_box
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [85, 25, 90, 0, 68, 90, 96.30, -88.95, -45, -22.88, -16.30, 112.10]
|
||||
|
||||
'
|
||||
- name: s6_move_waist_turn_left_90
|
||||
params: 'move_pitch_degree: 0.0
|
||||
|
||||
move_yaw_degree: 90.0
|
||||
|
||||
'
|
||||
- name: s6_wheel_move_to_putdown_position
|
||||
params: 'move_distance: 0.0
|
||||
|
||||
move_angle: 0.0
|
||||
|
||||
'
|
||||
- name: s7_right_arm_grasp_box
|
||||
params: &grasp_box_s7_s9 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [85, 25, 90, 0, 68, 90, 96.30, -88.95, 13.98, -22.88, -16.30, 112.10]
|
||||
|
||||
'
|
||||
- name: s7_right_arm_put_down_box
|
||||
params: 'body_id: 2
|
||||
|
||||
data_type: 2
|
||||
|
||||
data_length: 12
|
||||
|
||||
command_id: 0
|
||||
|
||||
frame_time_stamp: 0
|
||||
|
||||
data_array: [85, 25, 90, 0, 68, 90, 85.78, -88.95, 13.97, 22.88, -16.29, 67.99]
|
||||
|
||||
'
|
||||
- name: s8_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s9_right_arm_grasp_box
|
||||
params: *grasp_box_s7_s9
|
||||
- name: s10_move_waist_turn_right_90
|
||||
params: *waist_turn_right_90
|
||||
- name: s11_right_arm_pre_cam_take_photo
|
||||
params: *pre_cam_take_photo
|
||||
- name: s12_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s13_right_arm_pre_cam_take_photo
|
||||
params: *pre_cam_take_photo
|
||||
- name: s14_right_arm_pre_cam_take_photo
|
||||
params: *pre_cam_take_photo
|
||||
- name: s15_right_arm_pre_cam_take_photo
|
||||
params: *pre_cam_take_photo
|
||||
- name: s16_right_arm_pre_cam_take_photo
|
||||
params: *pre_cam_take_photo
|
||||
- name: s14_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s15_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s16_gripper_open
|
||||
params: *gripper_open
|
||||
- name: s15_arm_pre_grasp
|
||||
params: *pre_grasp
|
||||
- name: s16_arm_pre_grasp
|
||||
params: *pre_grasp
|
||||
- name: s15_right_arm_cam_take_photo
|
||||
params: *arm_cam_take_photo
|
||||
- name: s16_right_arm_cam_take_photo
|
||||
params: *arm_cam_take_photo
|
||||
171
src/brain/config/bt_vision_grasp_right_arm.xml
Normal file
171
src/brain/config/bt_vision_grasp_right_arm.xml
Normal file
@@ -0,0 +1,171 @@
|
||||
<!--
|
||||
功能描述: 右臂独立视觉抓取流程(视觉/抓取/放置均带恢复与重试)。
|
||||
流程: 右臂到手眼拍照位 -> 相机识别目标 -> 预抓取/抓取/抬起 -> 送到放置位并松爪 -> 回到初始位。
|
||||
-->
|
||||
<root BTCPP_format="4" main_tree_to_execute="MainTree">
|
||||
<BehaviorTree ID="MainTree">
|
||||
<Sequence name="root">
|
||||
<RetryUntilSuccessful name="retry_vision_grasp" num_attempts="3">
|
||||
<Fallback name="fallback_main_action">
|
||||
<Sequence name="complete_pick_and_place">
|
||||
<!-- Vision with recovery -->
|
||||
<Fallback name="vision_with_recovery">
|
||||
<SubTree ID="vision_subtree"/>
|
||||
<Sequence>
|
||||
<SubTree ID="vision_recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
|
||||
<!-- Grasp with recovery -->
|
||||
<Fallback name="grasp_with_recovery">
|
||||
<SubTree ID="grasp_subtree"/>
|
||||
<Sequence>
|
||||
<SubTree ID="grasp_recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
|
||||
<!-- Putdown with recovery -->
|
||||
<Fallback name="putdown_with_recovery">
|
||||
<SubTree ID="putdown_subtree"/>
|
||||
<Sequence>
|
||||
<SubTree ID="putdown_recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence>
|
||||
</Fallback>
|
||||
</Sequence>
|
||||
|
||||
<!-- Overall recovery if the entire sequence fails -->
|
||||
<!-- <Sequence>
|
||||
<SubTree ID="recovery_subtree"/>
|
||||
<AlwaysFailure/>
|
||||
</Sequence> -->
|
||||
</Fallback>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="vision_subtree">
|
||||
<Sequence name="vision_root">
|
||||
<RetryUntilSuccessful name="retry_vision" num_attempts="1">
|
||||
<Sequence>
|
||||
<Arm_H name="s1_right_arm_pre_cam_take_photo" />
|
||||
<Parallel name="parallel_action_1">
|
||||
<!-- <MoveWheel_H name="s1_wheel_move_to_origin_pickup_position" /> -->
|
||||
<GripperCmd1_H name="s1_gripper_open" />
|
||||
<Arm_H name="s2_right_arm_pre_cam_take_photo" />
|
||||
</Parallel>
|
||||
<SubTree ID="vision_top_cam_subtree"/>
|
||||
|
||||
<Arm_H name="s2_right_arm_cam_take_photo" />
|
||||
<SubTree ID="vision_hand_cam_subtree"/>
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="vision_top_cam_subtree">
|
||||
<Sequence name="vision_top_cam_root">
|
||||
<RetryUntilSuccessful name="retry_top_cam_vision_recg_1" num_attempts="10">
|
||||
<VisionObjectRecognition_H name="s2_top_camera_vision_recg" />
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="vision_hand_cam_subtree">
|
||||
<Sequence name="vision_hand_cam_root">
|
||||
<RetryUntilSuccessful name="retry_hand_cam_vision_recg_1" num_attempts="10">
|
||||
<VisionObjectRecognition_H name="s3_right_camera_vision_recg" />
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="grasp_subtree">
|
||||
<Sequence name="grasp_root">
|
||||
<RetryUntilSuccessful name="retry_grasp" num_attempts="1">
|
||||
<Sequence>
|
||||
<Arm_H name="s3_right_arm_vision_pre_grasp" />
|
||||
<Arm_H name="s4_right_arm_vision_grasp" />
|
||||
<GripperCmd1_H name="s4_gripper_close" />
|
||||
<Arm_H name="s4_right_arm_take_box" />
|
||||
<Arm_H name="s5_right_arm_grasp_box" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="putdown_subtree">
|
||||
<Sequence name="putdown_root">
|
||||
<RetryUntilSuccessful name="retry_putdown" num_attempts="1">
|
||||
<Sequence>
|
||||
<!-- <Parallel name="parallel_action_2">
|
||||
<MoveWheel_H name="s6_wheel_move_to_putdown_position" />
|
||||
<MoveWaist_H name="s6_move_waist_turn_left_90" />
|
||||
</Parallel> -->
|
||||
<Arm_H name="s7_right_arm_grasp_box" />
|
||||
<Arm_H name="s7_right_arm_put_down_box" />
|
||||
<GripperCmd1_H name="s8_gripper_open" />
|
||||
<Arm_H name="s9_right_arm_grasp_box" />
|
||||
|
||||
<Parallel name="parallel_action_3">
|
||||
<!-- <MoveWaist_H name="s10_move_waist_turn_right_90" /> -->
|
||||
<Arm_H name="s11_right_arm_pre_cam_take_photo" />
|
||||
</Parallel>
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="recovery_subtree">
|
||||
<Sequence name="recovery_root">
|
||||
<RetryUntilSuccessful name="retry_recovery" num_attempts="1">
|
||||
<Sequence>
|
||||
<GripperCmd1_H name="s12_gripper_open" />
|
||||
<Arm_H name="s13_right_arm_pre_cam_take_photo" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_overall" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="vision_recovery_subtree">
|
||||
<Sequence name="vision_recovery_root">
|
||||
<RetryUntilSuccessful name="retry_vision_recovery" num_attempts="1">
|
||||
<Sequence>
|
||||
<!-- <GripperCmd1_H name="s14_gripper_open" /> -->
|
||||
<Arm_H name="s14_right_arm_pre_cam_take_photo" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_vision" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="grasp_recovery_subtree">
|
||||
<Sequence name="grasp_recovery_root">
|
||||
<RetryUntilSuccessful name="retry_grasp_recovery" num_attempts="1">
|
||||
<Sequence>
|
||||
<GripperCmd1_H name="s15_gripper_open" />
|
||||
<Arm_H name="s15_arm_pre_grasp" />
|
||||
<Arm_H name="s15_right_arm_cam_take_photo" />
|
||||
<Arm_H name="s15_right_arm_pre_cam_take_photo" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_grasp" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="putdown_recovery_subtree">
|
||||
<Sequence name="putdown_recovery_root">
|
||||
<RetryUntilSuccessful name="retry_putdown_recovery" num_attempts="1">
|
||||
<Sequence>
|
||||
<GripperCmd1_H name="s16_gripper_open" />
|
||||
<Arm_H name="s16_arm_pre_grasp" />
|
||||
<Arm_H name="s16_right_arm_cam_take_photo" />
|
||||
<Arm_H name="s16_right_arm_pre_cam_take_photo" />
|
||||
<ClearDoneInstances_H name="clear_done_instances_putdown" />
|
||||
</Sequence>
|
||||
</RetryUntilSuccessful>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
</root>
|
||||
55
src/brain/config/example_skill_config.yaml
Normal file
55
src/brain/config/example_skill_config.yaml
Normal file
@@ -0,0 +1,55 @@
|
||||
# Example configuration file showing how to configure skill-specific parameters
|
||||
# This can be used as an additional parameters file in addition to the main brain_node_params.yaml
|
||||
|
||||
cerebrum_node:
|
||||
ros__parameters:
|
||||
# Skill-specific parameters
|
||||
cerebrum:
|
||||
bt:
|
||||
VisionObjectRecognition:
|
||||
topic: "vision_object_recognition"
|
||||
payload_yaml: ""
|
||||
timeout_ms: "10000"
|
||||
Arm:
|
||||
topic: "arm_control"
|
||||
payload_yaml: ""
|
||||
timeout_ms: "30000"
|
||||
CameraTakePhoto:
|
||||
topic: "camera_take_photo"
|
||||
payload_yaml: ""
|
||||
timeout_ms: "5000"
|
||||
HandControl:
|
||||
topic: "hand_control"
|
||||
payload_yaml: ""
|
||||
timeout_ms: "5000"
|
||||
MoveWaist:
|
||||
topic: "move_waist"
|
||||
payload_yaml: ""
|
||||
timeout_ms: "10000"
|
||||
MoveLeg:
|
||||
topic: "move_leg"
|
||||
payload_yaml: ""
|
||||
timeout_ms: "15000"
|
||||
MoveWheel:
|
||||
topic: "move_wheel"
|
||||
payload_yaml: ""
|
||||
timeout_ms: "20000"
|
||||
MoveHome:
|
||||
topic: "move_home"
|
||||
payload_yaml: ""
|
||||
timeout_ms: "30000"
|
||||
GripperCmd:
|
||||
topic: "gripper_cmd0"
|
||||
payload_yaml: ""
|
||||
timeout_ms: "5000"
|
||||
|
||||
# Example instance-specific overrides
|
||||
Arm:
|
||||
s1_arm_move_to_object:
|
||||
topic: "arm_control_specific"
|
||||
payload_yaml: "{target_pose: {x: 0.1, y: 0.2, z: 0.3}}"
|
||||
timeout_ms: "45000"
|
||||
s2_arm_grasp_object:
|
||||
topic: "arm_control_grasp"
|
||||
payload_yaml: "{target_pose: {x: 0.15, y: 0.25, z: 0.35}, grip_force: 10.0}"
|
||||
timeout_ms: "50000"
|
||||
@@ -6,12 +6,18 @@
|
||||
version: 1.0.0
|
||||
config_params_path: [
|
||||
{config: /config/bt_carry_boxes_sch1.xml, param: /config/bt_carry_boxes_sch1.params.yaml},
|
||||
{config: /config/bt_carry_boxes_sch2.xml, param: /config/bt_carry_boxes_sch2.params.yaml}
|
||||
{config: /config/bt_carry_boxes_sch2.xml, param: /config/bt_carry_boxes_sch2.params.yaml},
|
||||
{config: /config/bt_vision_grasp_left_arm.xml, param: /config/bt_vision_grasp_left_arm.params.yaml},
|
||||
{config: /config/bt_vision_grasp_right_arm.xml, param: /config/bt_vision_grasp_right_arm.params.yaml},
|
||||
{config: /config/bt_vision_grasp_dual_arm.xml, param: /config/bt_vision_grasp_dual_arm.params.yaml}
|
||||
]
|
||||
|
||||
- name: cerebellum_node
|
||||
version: 1.0.0
|
||||
config_params_path: [
|
||||
{config: /config/bt_carry_boxes_sch1.xml, param: /config/bt_carry_boxes_sch1.params.yaml},
|
||||
{config: /config/bt_carry_boxes_sch2.xml, param: /config/bt_carry_boxes_sch2.params.yaml}
|
||||
{config: /config/bt_carry_boxes_sch2.xml, param: /config/bt_carry_boxes_sch2.params.yaml},
|
||||
{config: /config/bt_vision_grasp_left_arm.xml, param: /config/bt_vision_grasp_left_arm.params.yaml},
|
||||
{config: /config/bt_vision_grasp_right_arm.xml, param: /config/bt_vision_grasp_right_arm.params.yaml},
|
||||
{config: /config/bt_vision_grasp_dual_arm.xml, param: /config/bt_vision_grasp_dual_arm.params.yaml}
|
||||
]
|
||||
@@ -61,4 +61,18 @@
|
||||
description: "回到原点位姿"
|
||||
interfaces:
|
||||
- name: MoveHome.action
|
||||
default_topic: "MoveHome"
|
||||
default_topic: "MoveHome"
|
||||
|
||||
- name: GripperCmd0
|
||||
version: 1.0.0
|
||||
description: "夹爪0控制"
|
||||
interfaces:
|
||||
- name: GripperCmd.action
|
||||
default_topic: "gripper_cmd0"
|
||||
|
||||
- name: GripperCmd1
|
||||
version: 1.0.0
|
||||
description: "夹爪1控制"
|
||||
interfaces:
|
||||
- name: GripperCmd.action
|
||||
default_topic: "gripper_cmd1"
|
||||
BIN
src/brain/config/voice/inFinished.mp3
Normal file
BIN
src/brain/config/voice/inFinished.mp3
Normal file
Binary file not shown.
BIN
src/brain/config/voice/inScan.mp3
Normal file
BIN
src/brain/config/voice/inScan.mp3
Normal file
Binary file not shown.
BIN
src/brain/config/voice/inStart.mp3
Normal file
BIN
src/brain/config/voice/inStart.mp3
Normal file
Binary file not shown.
BIN
src/brain/config/voice/outFinished.mp3
Normal file
BIN
src/brain/config/voice/outFinished.mp3
Normal file
Binary file not shown.
BIN
src/brain/config/voice/outScan.mp3
Normal file
BIN
src/brain/config/voice/outScan.mp3
Normal file
Binary file not shown.
BIN
src/brain/config/voice/outStart.mp3
Normal file
BIN
src/brain/config/voice/outStart.mp3
Normal file
Binary file not shown.
BIN
src/brain/config/voice/scanFinished.mp3
Normal file
BIN
src/brain/config/voice/scanFinished.mp3
Normal file
Binary file not shown.
BIN
src/brain/config/voice/scaning.mp3
Normal file
BIN
src/brain/config/voice/scaning.mp3
Normal file
Binary file not shown.
@@ -249,6 +249,9 @@ public:
|
||||
std::function<void(const typename GoalHandle<ActionT>::WrappedResult &)> on_result,
|
||||
std::function<void(const std::shared_ptr<GoalHandle<ActionT>> &)> on_goal_response = nullptr)
|
||||
{
|
||||
if (entries_.find(name) != entries_.end()) {
|
||||
RCLCPP_WARN(node_->get_logger(), "[ActionClientRegistry] Overwriting existing client for '%s'", name.c_str());
|
||||
}
|
||||
entries_[name] =
|
||||
std::make_unique<Entry<ActionT>>(
|
||||
node_, name, std::move(make_goal), std::move(
|
||||
@@ -406,6 +409,87 @@ public:
|
||||
return wrapped_result;
|
||||
}
|
||||
|
||||
template<typename ActionT>
|
||||
std::optional<typename rclcpp_action::ClientGoalHandle<ActionT>::WrappedResult> send_and_wait_with_goal(
|
||||
const std::string & name,
|
||||
rclcpp::Logger logger,
|
||||
const typename ActionT::Goal & goal,
|
||||
std::chrono::nanoseconds timeout = std::chrono::seconds(30))
|
||||
{
|
||||
auto it = entries_.find(name);
|
||||
if (it == entries_.end()) {
|
||||
RCLCPP_ERROR(logger, "No action client registered for '%s'", name.c_str());
|
||||
return std::nullopt;
|
||||
}
|
||||
auto * e = dynamic_cast<Entry<ActionT> *>(it->second.get());
|
||||
if (!e) {
|
||||
RCLCPP_ERROR(logger, "Action client type mismatch for '%s'", name.c_str());
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!e->client) {return std::nullopt;}
|
||||
if (!e->client->wait_for_action_server(std::chrono::seconds(10))) {
|
||||
RCLCPP_ERROR(logger, "Action server '%s' not available", name.c_str());
|
||||
return std::nullopt;
|
||||
}
|
||||
auto opts = typename rclcpp_action::Client<ActionT>::SendGoalOptions{};
|
||||
if (e->on_feedback) {opts.feedback_callback = e->on_feedback;}
|
||||
if (e->on_result) {opts.result_callback = e->on_result;}
|
||||
if (e->on_goal_response) {opts.goal_response_callback = e->on_goal_response;}
|
||||
auto goal_future = e->client->async_send_goal(goal, opts);
|
||||
auto goal_deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5);
|
||||
if (goal_future.wait_until(goal_deadline) != std::future_status::ready) {
|
||||
RCLCPP_ERROR(logger, "Timed out waiting for goal response on '%s'", name.c_str());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
typename rclcpp_action::ClientGoalHandle<ActionT>::SharedPtr goal_handle;
|
||||
try {
|
||||
goal_handle = goal_future.get();
|
||||
} catch (const std::exception & ex) {
|
||||
RCLCPP_ERROR(logger, "Failed to get goal handle for '%s': %s", name.c_str(), ex.what());
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!goal_handle) {
|
||||
RCLCPP_WARN(logger, "Goal rejected for '%s'", name.c_str());
|
||||
return std::nullopt;
|
||||
}
|
||||
e->last_goal_handle = goal_handle;
|
||||
if (e->on_goal_response) {
|
||||
try {
|
||||
e->on_goal_response(goal_handle);
|
||||
} catch (const std::exception & ex) {
|
||||
RCLCPP_WARN(logger, "Goal response callback threw for '%s': %s", name.c_str(), ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
auto result_future = e->client->async_get_result(goal_handle);
|
||||
auto deadline = std::chrono::steady_clock::now() + timeout;
|
||||
if (result_future.wait_until(deadline) != std::future_status::ready) {
|
||||
RCLCPP_ERROR(logger, "Timed out waiting for result on '%s', sending cancel", name.c_str());
|
||||
try {
|
||||
e->client->async_cancel_goal(goal_handle);
|
||||
} catch (const std::exception & ex) {
|
||||
RCLCPP_WARN(logger, "Failed cancelling goal for '%s': %s", name.c_str(), ex.what());
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
typename rclcpp_action::ClientGoalHandle<ActionT>::WrappedResult wrapped_result;
|
||||
try {
|
||||
wrapped_result = result_future.get();
|
||||
} catch (const std::exception & ex) {
|
||||
RCLCPP_ERROR(logger, "Failed to get result for '%s': %s", name.c_str(), ex.what());
|
||||
return std::nullopt;
|
||||
}
|
||||
if (e->on_result) {
|
||||
try {
|
||||
e->on_result(wrapped_result);
|
||||
} catch (const std::exception & ex) {
|
||||
RCLCPP_WARN(logger, "Result callback threw for '%s': %s", name.c_str(), ex.what());
|
||||
}
|
||||
}
|
||||
return wrapped_result;
|
||||
}
|
||||
|
||||
private:
|
||||
rclcpp::Node * node_;
|
||||
std::unordered_map<std::string, std::unique_ptr<EntryBase>> entries_;
|
||||
|
||||
@@ -86,9 +86,12 @@ public:
|
||||
node) {}
|
||||
|
||||
/**
|
||||
* @brief Declare static ports. Currently none (empty list) simplifying dynamic XML generation.
|
||||
* @brief Declare static ports. Added "match" for selective clearing logic in ClearDoneInstances_H.
|
||||
*/
|
||||
static BT::PortsList providedPorts() {return {};}
|
||||
static BT::PortsList providedPorts()
|
||||
{
|
||||
return {BT::InputPort<std::string>("match")};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief First tick transition handler.
|
||||
@@ -274,8 +277,11 @@ private:
|
||||
std::ostringstream oss;
|
||||
oss <<
|
||||
"\n <root BTCPP_format=\"4\" >\n\n <BehaviorTree ID=\"MainTree\">\n <Sequence name=\"root_sequence\">\n";
|
||||
for (const auto & act : seq) {
|
||||
oss << " <" << act.type << " name=\"" << act.name << "\"";
|
||||
auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
for (size_t i = 0; i < seq.size(); ++i) {
|
||||
const auto & act = seq[i];
|
||||
// Append timestamp and sequence index to ensure global uniqueness of the instance name in the tree
|
||||
oss << " <" << act.type << " name=\"" << act.name << "_" << timestamp << "_" << i << "\"";
|
||||
for (const auto & kv : act.ports) {
|
||||
oss << " " << kv.first << "=\"" << kv.second << "\"";
|
||||
}
|
||||
|
||||
61
src/brain/include/brain/calc_grasp_pose.hpp
Normal file
61
src/brain/include/brain/calc_grasp_pose.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <tf2/LinearMath/Vector3.h>
|
||||
#include <tf2/LinearMath/Quaternion.h>
|
||||
#include <tf2/LinearMath/Matrix3x3.h>
|
||||
#include <tf2/LinearMath/Transform.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace brain {
|
||||
|
||||
struct Pose {
|
||||
tf2::Vector3 position;
|
||||
tf2::Quaternion orientation;
|
||||
};
|
||||
|
||||
struct GraspResult {
|
||||
std::string name;
|
||||
Pose pre_grasp_pose;
|
||||
Pose grasp_pose;
|
||||
};
|
||||
|
||||
class GraspPoseCalculator {
|
||||
public:
|
||||
GraspPoseCalculator();
|
||||
static GraspResult calculate(
|
||||
const tf2::Vector3& target_pos,
|
||||
const tf2::Quaternion& target_quat,
|
||||
const std::string& grasp_type = "side",
|
||||
double angle_deg = 0.0,
|
||||
const std::string& palm_facing = "down",
|
||||
double safety_dist = 0.06,
|
||||
double finger_length = 0.0,
|
||||
const std::string& arm = "right"
|
||||
);
|
||||
static double evaluate_grasp_quality(
|
||||
const tf2::Vector3& target_pos,
|
||||
double angle_deg,
|
||||
const std::string& arm = "right"
|
||||
);
|
||||
static std::vector<double> find_optimal_grasp_angles(
|
||||
const tf2::Vector3& target_pos,
|
||||
const std::string& arm = "right",
|
||||
int top_k = 3
|
||||
);
|
||||
|
||||
private:
|
||||
static bool rm_arm_algo_init_done_;
|
||||
|
||||
static GraspResult create_grasp_matrix(
|
||||
const tf2::Vector3& target_pos,
|
||||
const tf2::Vector3& approach_vec,
|
||||
const tf2::Vector3& palm_normal_vec,
|
||||
double safety_dist,
|
||||
double finger_length
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
} // namespace brain
|
||||
35
src/brain/include/brain/cerebellum_hooks.hpp
Normal file
35
src/brain/include/brain/cerebellum_hooks.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef BRAIN_CEREBELLUM_HOOKS_HPP_
|
||||
#define BRAIN_CEREBELLUM_HOOKS_HPP_
|
||||
|
||||
namespace brain
|
||||
{
|
||||
|
||||
class CerebellumNode;
|
||||
|
||||
class CerebellumHooks
|
||||
{
|
||||
public:
|
||||
static void ConfigureActionHooks(CerebellumNode * node);
|
||||
static void ConfigureArmSpaceControlHooks(CerebellumNode * node);
|
||||
static void ConfigureArmHooks(CerebellumNode * node);
|
||||
static void ConfigureHandControlHooks(CerebellumNode * node);
|
||||
static void ConfigureCameraTakePhotoHooks(CerebellumNode * node);
|
||||
static void ConfigureLegControlHooks(CerebellumNode * node);
|
||||
static void ConfigureVisionGraspObjectHooks(CerebellumNode * node);
|
||||
static void ConfigureSlamModeHooks(CerebellumNode * node);
|
||||
static void ConfigureNavigateToPoseHooks(CerebellumNode * node);
|
||||
static void ConfigureMoveWaistHooks(CerebellumNode * node);
|
||||
static void ConfigureMoveLegHooks(CerebellumNode * node);
|
||||
static void ConfigureMoveWheelHooks(CerebellumNode * node);
|
||||
static void ConfigureMoveHomeHooks(CerebellumNode * node);
|
||||
static void ConfigureGripperCmdControlHooks(CerebellumNode * node);
|
||||
|
||||
static void ConfigureServiceHooks(CerebellumNode * node);
|
||||
static void ConfigureVisionObjectRecognitionHooks(CerebellumNode * node);
|
||||
static void ConfigureMapLoadHooks(CerebellumNode * node);
|
||||
static void ConfigureMapSaveHooks(CerebellumNode * node);
|
||||
};
|
||||
|
||||
} // namespace brain
|
||||
|
||||
#endif // BRAIN_CEREBELLUM_HOOKS_HPP_
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <rclcpp/rclcpp.hpp>
|
||||
#include <rclcpp_action/rclcpp_action.hpp>
|
||||
#include <geometry_msgs/msg/pose_stamped.hpp>
|
||||
@@ -18,8 +20,11 @@
|
||||
#include <smacc2/smacc_signal_detector.hpp>
|
||||
#include "brain/sm_cerebellum.hpp" // for CerebellumData::ExecResult
|
||||
// For from_yaml<T>(YAML::Node)
|
||||
#include <sensor_msgs/msg/joint_state.hpp>
|
||||
#include "brain/payload_converters.hpp"
|
||||
#include "brain/robot_config.hpp"
|
||||
#include "brain/calc_grasp_pose.hpp"
|
||||
#include "interfaces/srv/inverse_kinematics.hpp"
|
||||
|
||||
namespace brain
|
||||
{
|
||||
@@ -41,7 +46,34 @@ public:
|
||||
*/
|
||||
explicit CerebellumNode(const rclcpp::NodeOptions & options = rclcpp::NodeOptions());
|
||||
|
||||
std::unordered_map<std::string, std::vector<geometry_msgs::msg::Pose>> arm_poses_;
|
||||
std::unordered_map<std::string, std::vector<std::vector<double>>> arm_angles_;
|
||||
|
||||
std::vector<double> left_arm_joint_angles_;
|
||||
std::vector<double> right_arm_joint_angles_;
|
||||
std::mutex joint_state_mutex_;
|
||||
|
||||
std::string camera_position_;
|
||||
|
||||
std::unordered_map<std::string, std::string> gripper_info_;
|
||||
|
||||
/**
|
||||
* @brief Call Inverse Kinematics service
|
||||
*
|
||||
* @param pos
|
||||
* @param quat
|
||||
* @param angles
|
||||
* @param arm_id
|
||||
* @return int
|
||||
*/
|
||||
int CallInverseKinematics(const tf2::Vector3& pos, const tf2::Quaternion& quat, std::vector<double>& angles, int arm_id);
|
||||
|
||||
private:
|
||||
struct GoalExecutionContext { std::atomic<bool> cancel{false}; };
|
||||
std::unordered_map<std::uintptr_t, std::shared_ptr<GoalExecutionContext>> goal_ctxs_;
|
||||
std::mutex goal_ctxs_mutex_;
|
||||
static thread_local const std::vector<interfaces::msg::SkillCall>* tls_current_calls_;
|
||||
static thread_local int tls_arm_body_id;
|
||||
// Generic action registry to support multiple actions via registration
|
||||
std::unique_ptr<ActionServerRegistry> action_registry_;
|
||||
std::unique_ptr<ActionClientRegistry> action_clients_;
|
||||
@@ -53,19 +85,64 @@ private:
|
||||
|
||||
// SMACC2 execution context
|
||||
std::unique_ptr<smacc2::SmExecution> sm_exec_;
|
||||
|
||||
// IK Client
|
||||
rclcpp::Client<interfaces::srv::InverseKinematics>::SharedPtr ik_client_;
|
||||
|
||||
// Parameters: abort policy, default action timeout, specific grasp timeout
|
||||
bool abort_on_failure_ {true};
|
||||
double default_action_timeout_sec_ {45.0};
|
||||
double vision_grasp_object_timeout_sec_ {120.0};
|
||||
std::string map_save_url_ {"/tmp/humanoid_map"};
|
||||
std::string map_save_image_format_ {"pgm"};
|
||||
double map_save_free_thresh_ {0.25};
|
||||
double map_save_occupied_thresh_ {0.65};
|
||||
std::string map_load_url_ {};
|
||||
double nav_goal_yaw_offset_ {0.0};
|
||||
double nav_goal_distance_tolerance_ {0.5};
|
||||
bool slam_enable_mapping_default_ {true};
|
||||
// ROS parameters (replacing hardcoded defaults)
|
||||
bool abort_on_failure_{true};
|
||||
double default_action_timeout_sec_{45.0};
|
||||
double vision_grasp_object_timeout_sec_{120.0};
|
||||
std::string map_save_url_{"/tmp/humanoid_map"};
|
||||
std::string map_save_image_format_{"pgm"};
|
||||
double map_save_free_thresh_{0.25};
|
||||
double map_save_occupied_thresh_{0.65};
|
||||
std::string map_load_url_{};
|
||||
double nav_goal_yaw_offset_{0.0};
|
||||
double nav_goal_distance_tolerance_{0.5};
|
||||
bool slam_enable_mapping_default_{true};
|
||||
|
||||
// Grasp pose calculation parameters
|
||||
double top_cam_right_arm_z_threshold_{0.05};
|
||||
double top_cam_right_arm_x_offset_{0.10};
|
||||
double top_cam_right_arm_y_{0.33};
|
||||
std::vector<double> top_cam_right_arm_orientation_{-0.7071, 0.0, 0.0, 0.7071};
|
||||
double top_cam_left_arm_z_threshold_{-0.10};
|
||||
double top_cam_left_arm_x_offset_{0.10};
|
||||
double top_cam_left_arm_y_{-0.33};
|
||||
std::vector<double> top_cam_left_arm_orientation_{0.7071, 0.0, 0.0, 0.7071};
|
||||
double side_cam_right_arm_y_offset_{0.02};
|
||||
double side_cam_right_arm_z_offset_{0.02};
|
||||
double side_cam_left_arm_y_offset_{0.03};
|
||||
double side_cam_left_arm_z_offset_{0.01};
|
||||
double take_object_arm_x_{-0.05};
|
||||
double vision_object_recognition_wait_timeout_sec_{2.0};
|
||||
double vision_object_recognition_call_timeout_sec_{5.0};
|
||||
double map_load_wait_timeout_sec_{2.0};
|
||||
double map_load_call_timeout_sec_{5.0};
|
||||
|
||||
std::string left_camera_frame_{"LeftLink6"};
|
||||
std::string right_camera_frame_{"RightLink6"};
|
||||
std::vector<std::string> target_frames_{"apple", "bottle", "medicine_box"};
|
||||
std::string target_frame_{"medicine_box"};
|
||||
std::vector<std::string> grasp_palm_facings_{"down"};
|
||||
std::vector<double> grasp_best_angles_{0.0};
|
||||
std::string grasp_type_{"side"};
|
||||
double grasp_safety_dist_{0.05};
|
||||
double grasp_finger_length_{0.20};
|
||||
|
||||
int hand_control_default_mode_{1};
|
||||
int gripper_default_loc_{30};
|
||||
int gripper_default_speed_{0};
|
||||
int gripper_default_torque_{0};
|
||||
int gripper_default_mode_{0};
|
||||
|
||||
int arm_cmd_type_take_photo_{100};
|
||||
int arm_cmd_type_pre_grasp_{101};
|
||||
int arm_cmd_type_grasp_{102};
|
||||
int arm_cmd_type_take_object_{110};
|
||||
int arm_cmd_type_custom_min_{100};
|
||||
int arm_cmd_type_custom_max_{120};
|
||||
|
||||
// Optional per-skill override timeout (skill_name -> seconds)
|
||||
std::unordered_map<std::string, double> skill_timeouts_;
|
||||
@@ -73,19 +150,31 @@ private:
|
||||
// Statistics: per-skill success/failure counters & sequence totals
|
||||
std::unordered_map<std::string, size_t> skill_success_counts_;
|
||||
std::unordered_map<std::string, size_t> skill_failure_counts_;
|
||||
size_t total_sequence_success_ {0};
|
||||
size_t total_sequence_failure_ {0};
|
||||
size_t total_sequence_success_{0};
|
||||
size_t total_sequence_failure_{0};
|
||||
|
||||
// ROS parameters (new additions)
|
||||
bool enable_stats_publisher_{true};
|
||||
int stats_publish_interval_ms_{5000};
|
||||
std::string robot_config_path_{""};
|
||||
|
||||
rclcpp::TimerBase::SharedPtr stats_timer_;
|
||||
double stats_log_interval_sec_ {30.0};
|
||||
std::mutex stats_mutex_;
|
||||
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr stats_pub_;
|
||||
std::unordered_map<std::string, geometry_msgs::msg::PoseStamped> target_pose_;
|
||||
std::string target_frame_{"bottle"};
|
||||
int64_t command_id_{0};
|
||||
int64_t command_id_left_arm_ {0};
|
||||
int64_t command_id_right_arm_{0};
|
||||
std::unordered_map<std::string, geometry_msgs::msg::Pose> final_arm_pose_;
|
||||
std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
|
||||
std::shared_ptr<tf2_ros::TransformListener> tf_listener_;
|
||||
std::string arm_target_frame_{"base_link_leftarm"};
|
||||
double arm_transform_timeout_sec_{0.2};
|
||||
std::string arm_target_frame_{"base_link_rightarm"};
|
||||
double arm_transform_timeout_sec_{1};
|
||||
|
||||
rclcpp::Subscription<sensor_msgs::msg::JointState>::SharedPtr joint_state_sub_;
|
||||
void JointStateCallback(const sensor_msgs::msg::JointState::SharedPtr msg);
|
||||
std::vector<double> right_hand_grab_width_;
|
||||
|
||||
// Current accepted sequence epoch (from client) used to filter/reject stale goals
|
||||
std::atomic<uint32_t> current_epoch_{0};
|
||||
@@ -103,6 +192,8 @@ private:
|
||||
std::atomic<double> nav2_last_distance_remaining_{std::numeric_limits<double>::quiet_NaN()};
|
||||
std::atomic<bool> nav2_last_goal_succeeded_{false};
|
||||
|
||||
friend class CerebellumHooks;
|
||||
|
||||
// ---- helpers ----
|
||||
/**
|
||||
* @brief Try to parse the current goal's per-call YAML payload into a typed object.
|
||||
@@ -114,8 +205,9 @@ private:
|
||||
template<typename T>
|
||||
bool TryParseCallPayload(const std::string & skill_name, T & out) const
|
||||
{
|
||||
if (last_calls_.empty()) {return false;}
|
||||
for (const auto & c : last_calls_) {
|
||||
const auto * calls = tls_current_calls_ ? tls_current_calls_ : &last_calls_;
|
||||
if (!calls || calls->empty()) {return false;}
|
||||
for (const auto & c : *calls) {
|
||||
if (c.name == skill_name && !c.payload_yaml.empty()) {
|
||||
try {
|
||||
auto node = YAML::Load(c.payload_yaml);
|
||||
@@ -131,26 +223,6 @@ private:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/** @brief Install application-specific action hook overrides for skill manager. */
|
||||
void ConfigureActionHooks();
|
||||
void ConfigureArmSpaceControlHooks();
|
||||
void ConfigureArmHooks();
|
||||
void ConfigureHandControlHooks();
|
||||
void ConfigureCameraTakePhotoHooks();
|
||||
void ConfigureLegControlHooks();
|
||||
void ConfigureVisionGraspObjectHooks();
|
||||
void ConfigureSlamModeHooks();
|
||||
void ConfigureNavigateToPoseHooks();
|
||||
void ConfigureMoveWaistHooks();
|
||||
void ConfigureMoveLegHooks();
|
||||
void ConfigureMoveWheelHooks();
|
||||
void ConfigureMoveHomeHooks();
|
||||
|
||||
/** @brief Install application-specific service hook overrides. */
|
||||
void ConfigureServiceHooks();
|
||||
void ConfigureVisionObjectRecognitionHooks();
|
||||
void ConfigureMapLoadHooks();
|
||||
void ConfigureMapSaveHooks();
|
||||
|
||||
/**
|
||||
* @brief Parse a raw comma / semicolon / whitespace separated list of skill names.
|
||||
@@ -258,6 +330,7 @@ private:
|
||||
* @brief Internal helper: run the action worker thread and emit RUN feedback until completion.
|
||||
* Extracted to reduce cyclomatic complexity of ExecuteActionSkill.
|
||||
* @param skill Skill name.
|
||||
* @param interface_name Interface base name for dispatching.
|
||||
* @param topic Action topic.
|
||||
* @param timeout_ns Timeout duration (nanoseconds).
|
||||
* @param index Skill index.
|
||||
@@ -268,8 +341,11 @@ private:
|
||||
*/
|
||||
bool RunActionSkillWithProgress(
|
||||
const std::string & skill,
|
||||
const std::string & interface_name,
|
||||
const std::string & topic,
|
||||
std::chrono::nanoseconds timeout_ns,
|
||||
const std::string & instance_name,
|
||||
uint32_t timeout_ms_override,
|
||||
int index,
|
||||
int total_skills,
|
||||
const std::shared_ptr<rclcpp_action::ServerGoalHandle<interfaces::action::ExecuteBtAction>> & goal_handle,
|
||||
@@ -279,6 +355,7 @@ private:
|
||||
* @brief Internal helper: run bilateral arm actions concurrently.
|
||||
* Extracted to reduce cyclomatic complexity of ExecuteActionSkill.
|
||||
* @param skill Skill name.
|
||||
* @param interface_name Interface base name for dispatching.
|
||||
* @param topic Action topic.
|
||||
* @param timeout Action timeout.
|
||||
* @param index Skill index.
|
||||
@@ -289,8 +366,11 @@ private:
|
||||
*/
|
||||
bool ExecuteBilateralArmAction(
|
||||
const std::string & skill,
|
||||
const std::string & interface_name,
|
||||
const std::string & topic,
|
||||
std::chrono::nanoseconds timeout,
|
||||
const std::string & instance_name,
|
||||
uint32_t timeout_ms_override,
|
||||
int index,
|
||||
int total_skills,
|
||||
const std::shared_ptr<rclcpp_action::ServerGoalHandle<interfaces::action::ExecuteBtAction>> & goal_handle,
|
||||
@@ -303,7 +383,7 @@ private:
|
||||
* @param detail [out] Detail / diagnostics.
|
||||
* @param start_progress Sequence progress prior to executing the service.
|
||||
* @param goal_handle Goal handle (used for feedback publishing).
|
||||
* @return true if successful.
|
||||
* @return true if successful.
|
||||
*/
|
||||
bool ExecuteServiceSkill(
|
||||
const std::string & skill,
|
||||
@@ -355,6 +435,9 @@ private:
|
||||
* @return Topic / action client key.
|
||||
*/
|
||||
std::string ResolveTopicForSkill(const std::string & skill) const;
|
||||
std::string ResolveTopicForSkillFromCalls(
|
||||
const std::vector<interfaces::msg::SkillCall> & calls,
|
||||
const std::string & skill) const;
|
||||
/**
|
||||
* @brief Finalize goal with summary result (success or abort) and log message.
|
||||
* @param goal_handle Goal handle.
|
||||
@@ -379,9 +462,17 @@ private:
|
||||
/** @brief Register ExecuteBtAction server with goal/execute handlers. */
|
||||
void SetupExecuteBtServer();
|
||||
|
||||
void RunExecuteBtGoalConcurrent(
|
||||
const std::shared_ptr<rclcpp_action::ServerGoalHandle<interfaces::action::ExecuteBtAction>> & goal_handle);
|
||||
|
||||
brain::CerebellumData::ExecResult ExecuteSequenceConcurrent(
|
||||
const std::shared_ptr<rclcpp_action::ServerGoalHandle<interfaces::action::ExecuteBtAction>> & goal_handle,
|
||||
const std::vector<std::string> & skills,
|
||||
const std::shared_ptr<GoalExecutionContext> & ctx);
|
||||
|
||||
/** @brief 将检测到的姿态转换到机械臂参考坐标系。 */
|
||||
bool TransformPoseToArmFrame(
|
||||
const geometry_msgs::msg::PoseStamped & source,
|
||||
const geometry_msgs::msg::PoseStamped & source, const std::string & arm_target_frame,
|
||||
geometry_msgs::msg::PoseStamped & transformed) const;
|
||||
|
||||
// NOTE: Additional future helpers (cancellation handling, concurrency) may be added here.
|
||||
|
||||
@@ -118,6 +118,20 @@ public:
|
||||
*/
|
||||
static std::vector<std::string> ParseListString(const std::string & raw);
|
||||
|
||||
/**
|
||||
* @brief Split a string by comma, ignoring commas inside quotes (single or double).
|
||||
* @param raw Input string.
|
||||
* @return Vector of tokens.
|
||||
*/
|
||||
static std::vector<std::string> SplitQuotedString(const std::string & raw);
|
||||
|
||||
/**
|
||||
* @brief Split a string by comma, preserving order and duplicates.
|
||||
* @param raw Input string.
|
||||
* @return Vector of tokens.
|
||||
*/
|
||||
static std::vector<std::string> SplitString(const std::string & raw);
|
||||
|
||||
/**
|
||||
* @brief Classify textual result detail (prefix or code= token) into ExecResultCode.
|
||||
* @param detail Input detail string.
|
||||
@@ -173,7 +187,10 @@ private:
|
||||
/** Declare per-skill instance parameter entries used to customize outgoing calls. */
|
||||
bool UpdateBtActionParamsForSkillInstance(const std::string & skill_name, const std::string & instance_name, const std::string & instance_params);
|
||||
/** Declare per-instance parameter entries used to customize a specific BT node occurrence. */
|
||||
bool DeclareBtActionParamsForSkillInstance(const std::string & skill_name, const std::string & instance_name);
|
||||
bool DeclareBtActionParamsForSkillInstance(
|
||||
const std::string & skill_name,
|
||||
const std::string & instance_name,
|
||||
std::string * out_instance_params = nullptr);
|
||||
/** Build a SkillCall message for given skill by consulting SkillSpec and per-skill params. */
|
||||
interfaces::msg::SkillCall BuildSkillCallForSkill(const std::string & skill_name) const;
|
||||
/** Build a SkillCall with optional per-instance override (cerebrum.bt.<Skill>.<Instance>.*). */
|
||||
@@ -203,13 +220,25 @@ private:
|
||||
rclcpp::Service<interfaces::srv::BtRebuild>::SharedPtr rebuild_service_;
|
||||
std::atomic<bool> bt_updating_{false};
|
||||
std::atomic<bool> bt_pending_run_{false};
|
||||
rclcpp::Time bt_execution_start_time_;
|
||||
// Encapsulated epoch+skill filter
|
||||
EpochSkillFilter epoch_filter_;
|
||||
// Current sequence skills (kept in original order for logging / statistics).
|
||||
std::vector<std::string> current_sequence_skills_;
|
||||
// Map of sequence index to override params for the current sequence.
|
||||
std::unordered_map<size_t, std::string> active_sequence_param_overrides_;
|
||||
// Mutex that protects both per_node_exec_ and epoch_skills_ updates.
|
||||
std::mutex exec_mutex_;
|
||||
|
||||
// Tracking currently running BT leaf instances (for serial/parallel reporting).
|
||||
std::unordered_set<std::string> running_leaf_keys_;
|
||||
// Index map for active RobotWorkInfo.action entries (key -> vector index).
|
||||
std::unordered_map<std::string, std::size_t> action_index_by_key_;
|
||||
// Parallel vector of action keys aligned with robot_work_info_.action.
|
||||
std::vector<std::string> action_keys_;
|
||||
// Map from BT node instance name to execution mode based on BT structure.
|
||||
std::unordered_map<std::string, std::string> action_exec_by_node_name_;
|
||||
|
||||
rclcpp::Publisher<interfaces::msg::RobotWorkInfo>::SharedPtr robot_work_info_pub_;
|
||||
interfaces::msg::RobotWorkInfo robot_work_info_;
|
||||
|
||||
@@ -237,6 +266,18 @@ private:
|
||||
std::optional<std::string> current_instance;
|
||||
};
|
||||
std::unordered_map<std::string, PerNodeExecInfo> per_node_exec_;
|
||||
|
||||
struct PerInstanceExecInfo
|
||||
{
|
||||
std::atomic<bool> in_flight {false};
|
||||
std::atomic<bool> finished {false};
|
||||
bool success {false};
|
||||
ExecResultCode result_code {ExecResultCode::UNKNOWN};
|
||||
rclcpp::Time start_time;
|
||||
double last_progress {0.0};
|
||||
};
|
||||
std::unordered_map<std::string, PerInstanceExecInfo> per_instance_exec_;
|
||||
std::unordered_set<std::string> done_instances_epoch_;
|
||||
// Set of already registered action client names (prevents duplicate registration & duplicate feedback).
|
||||
std::unordered_set<std::string> registered_actions_;
|
||||
// Per-BT-node execution timeout (seconds).
|
||||
@@ -253,11 +294,24 @@ private:
|
||||
std::vector<std::string> allowed_action_skills_;
|
||||
// Fixed skill sequence (if set, random selection is skipped entirely).
|
||||
std::optional<std::vector<std::string>> fixed_skill_sequence_;
|
||||
|
||||
// ROS parameters
|
||||
double tick_rate_hz_{10.0};
|
||||
int rebuild_interval_ms_{5000};
|
||||
int stats_publish_interval_ms_{10000};
|
||||
std::string robot_config_path_{""};
|
||||
std::string skill_file_path_{""};
|
||||
double default_bt_timeout_{300.0};
|
||||
bool enable_sequence_rebuild_{true};
|
||||
|
||||
/**
|
||||
* @brief Cancel the currently active ExecuteBtAction goal (if any).
|
||||
* @thread_safety Calls into ActionClientRegistry; assumed thread-safe for cancellation.
|
||||
*/
|
||||
void CancelActiveExecuteBtGoal();
|
||||
|
||||
void StopBehaviorTree(bool cancel_goals);
|
||||
|
||||
/**
|
||||
* @brief (Legacy) Update per-epoch allowed skills. Currently a no-op (handled by EpochSkillFilter).
|
||||
* @param skills Ignored.
|
||||
@@ -366,16 +420,33 @@ private:
|
||||
|
||||
/** Handle Trigger type rebuild request */
|
||||
void HandleTriggerRebuild(
|
||||
const std::shared_ptr<interfaces::srv::BtRebuild::Request> req,
|
||||
const std::shared_ptr<interfaces::srv::BtRebuild::Response> resp);
|
||||
|
||||
/** Handle Remote type rebuild request */
|
||||
void HandleRemoteRebuild(
|
||||
/** Handle Generic (Remote/Sequence) type rebuild request */
|
||||
void HandleGenericRebuild(
|
||||
const std::shared_ptr<interfaces::srv::BtRebuild::Request> req,
|
||||
const std::shared_ptr<interfaces::srv::BtRebuild::Response> resp);
|
||||
|
||||
/** Extract filename without extension from a path */
|
||||
std::string ExtractFilenameWithoutExtension(const std::string & path);
|
||||
|
||||
// Update robot_work_info_ leaf execution mode based on running_leaf_keys_.
|
||||
void UpdateLeafParallelismStatusLocked();
|
||||
|
||||
// Manage RobotWorkInfo.action entries (guarded by exec_mutex_).
|
||||
void AddActionInfoLocked(
|
||||
const std::string & key,
|
||||
const std::string & skill,
|
||||
const std::string & action_name,
|
||||
const std::string & params);
|
||||
void UpdateActionInfoStateLocked(const std::string & key, const std::string & state);
|
||||
void RemoveActionInfoLocked(const std::string & key);
|
||||
void ClearActionInfoLocked();
|
||||
|
||||
// Build map of BT node instance name -> execution mode (serial/parallel).
|
||||
void BuildActionExecutionMapLocked();
|
||||
|
||||
// Temporary override used so the generic ExecuteBtAction goal builder can
|
||||
// send a single-skill goal when a per-skill BT node starts.
|
||||
std::optional<std::string> single_skill_goal_override_;
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "interfaces/action/arm.hpp"
|
||||
#include "interfaces/action/arm_space_control.hpp"
|
||||
#include "interfaces/action/camera_take_photo.hpp"
|
||||
#include "interfaces/action/execute_bt_action.hpp"
|
||||
#include "interfaces/action/gripper_cmd.hpp"
|
||||
#include "interfaces/action/hand_control.hpp"
|
||||
#include "interfaces/action/leg_control.hpp"
|
||||
#include "interfaces/action/move_home.hpp"
|
||||
@@ -18,8 +20,12 @@
|
||||
#include "interfaces/action/move_wheel.hpp"
|
||||
#include "interfaces/action/slam_mode.hpp"
|
||||
#include "interfaces/action/vision_grasp_object.hpp"
|
||||
#include "interfaces/srv/bt_rebuild.hpp"
|
||||
#include "interfaces/srv/gripper_cmd.hpp"
|
||||
#include "interfaces/srv/map_load.hpp"
|
||||
#include "interfaces/srv/map_save.hpp"
|
||||
#include "interfaces/srv/motor_info.hpp"
|
||||
#include "interfaces/srv/motor_param.hpp"
|
||||
#include "interfaces/srv/vision_object_recognition.hpp"
|
||||
|
||||
|
||||
@@ -153,6 +159,70 @@ inline interfaces::action::MoveHome::Goal from_yaml<interfaces::action::MoveHome
|
||||
return g;
|
||||
}
|
||||
|
||||
// GripperCmd::Goal: loc, speed, torque, mode
|
||||
template<>
|
||||
inline interfaces::action::GripperCmd::Goal from_yaml<interfaces::action::GripperCmd::Goal>(const YAML::Node & n)
|
||||
{
|
||||
interfaces::action::GripperCmd::Goal g;
|
||||
if (n && n.IsMap()) {
|
||||
if (n["loc"]) g.loc = n["loc"].as<uint8_t>();
|
||||
if (n["speed"]) g.speed = n["speed"].as<uint8_t>();
|
||||
if (n["torque"]) g.torque = n["torque"].as<uint8_t>();
|
||||
if (n["mode"]) g.mode = n["mode"].as<uint8_t>();
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
// ExecuteBtAction::Goal: epoch, action_name, calls
|
||||
template<>
|
||||
inline interfaces::action::ExecuteBtAction::Goal from_yaml<interfaces::action::ExecuteBtAction::Goal>(const YAML::Node & n)
|
||||
{
|
||||
interfaces::action::ExecuteBtAction::Goal g;
|
||||
if (n && n.IsMap()) {
|
||||
if (n["epoch"]) g.epoch = n["epoch"].as<uint32_t>();
|
||||
if (n["action_name"]) g.action_name = n["action_name"].as<std::string>();
|
||||
// TODO: parse field `calls` of ROS type `interfaces/SkillCall[]` into g.calls (complex type)
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
// LegControl::Goal: target
|
||||
template<>
|
||||
inline interfaces::action::LegControl::Goal from_yaml<interfaces::action::LegControl::Goal>(const YAML::Node & n)
|
||||
{
|
||||
interfaces::action::LegControl::Goal g;
|
||||
if (n && n.IsMap()) {
|
||||
// geometry_msgs::msg::TwistStamped
|
||||
if (n) {
|
||||
if (n["frame_id"]) g.target.header.frame_id = n["frame_id"].as<std::string>();
|
||||
if (n["stamp_sec"]) g.target.header.stamp.sec = n["stamp_sec"].as<int32_t>();
|
||||
if (n["stamp_nanosec"]) g.target.header.stamp.nanosec = n["stamp_nanosec"].as<uint32_t>();
|
||||
if (auto lin = n["linear"]) {
|
||||
if (lin["x"]) g.target.twist.linear.x = lin["x"].as<double>();
|
||||
if (lin["y"]) g.target.twist.linear.y = lin["y"].as<double>();
|
||||
if (lin["z"]) g.target.twist.linear.z = lin["z"].as<double>();
|
||||
}
|
||||
if (auto ang = n["angular"]) {
|
||||
if (ang["x"]) g.target.twist.angular.x = ang["x"].as<double>();
|
||||
if (ang["y"]) g.target.twist.angular.y = ang["y"].as<double>();
|
||||
if (ang["z"]) g.target.twist.angular.z = ang["z"].as<double>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
// VisionGraspObject::Goal: object_id
|
||||
template<>
|
||||
inline interfaces::action::VisionGraspObject::Goal from_yaml<interfaces::action::VisionGraspObject::Goal>(const YAML::Node & n)
|
||||
{
|
||||
interfaces::action::VisionGraspObject::Goal g;
|
||||
if (n && n.IsMap()) {
|
||||
if (n["object_id"]) g.object_id = n["object_id"].as<std::string>();
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
// MoveToPosition::Goal: target_x, target_y
|
||||
template<>
|
||||
inline interfaces::action::MoveToPosition::Goal from_yaml<interfaces::action::MoveToPosition::Goal>(const YAML::Node & n)
|
||||
@@ -203,41 +273,61 @@ inline interfaces::action::ArmSpaceControl::Goal from_yaml<interfaces::action::A
|
||||
return g;
|
||||
}
|
||||
|
||||
// LegControl::Goal: target
|
||||
// GripperCmd::Request: devid, loc, speed, torque
|
||||
template<>
|
||||
inline interfaces::action::LegControl::Goal from_yaml<interfaces::action::LegControl::Goal>(const YAML::Node & n)
|
||||
inline interfaces::srv::GripperCmd::Request from_yaml<interfaces::srv::GripperCmd::Request>(const YAML::Node & n)
|
||||
{
|
||||
interfaces::action::LegControl::Goal g;
|
||||
interfaces::srv::GripperCmd::Request r;
|
||||
if (n && n.IsMap()) {
|
||||
// geometry_msgs::msg::TwistStamped
|
||||
if (n) {
|
||||
if (n["frame_id"]) g.target.header.frame_id = n["frame_id"].as<std::string>();
|
||||
if (n["stamp_sec"]) g.target.header.stamp.sec = n["stamp_sec"].as<int32_t>();
|
||||
if (n["stamp_nanosec"]) g.target.header.stamp.nanosec = n["stamp_nanosec"].as<uint32_t>();
|
||||
if (auto lin = n["linear"]) {
|
||||
if (lin["x"]) g.target.twist.linear.x = lin["x"].as<double>();
|
||||
if (lin["y"]) g.target.twist.linear.y = lin["y"].as<double>();
|
||||
if (lin["z"]) g.target.twist.linear.z = lin["z"].as<double>();
|
||||
}
|
||||
if (auto ang = n["angular"]) {
|
||||
if (ang["x"]) g.target.twist.angular.x = ang["x"].as<double>();
|
||||
if (ang["y"]) g.target.twist.angular.y = ang["y"].as<double>();
|
||||
if (ang["z"]) g.target.twist.angular.z = ang["z"].as<double>();
|
||||
}
|
||||
}
|
||||
if (n["devid"]) r.devid = n["devid"].as<uint8_t>();
|
||||
if (n["loc"]) r.loc = n["loc"].as<uint8_t>();
|
||||
if (n["speed"]) r.speed = n["speed"].as<uint8_t>();
|
||||
if (n["torque"]) r.torque = n["torque"].as<uint8_t>();
|
||||
}
|
||||
return g;
|
||||
return r;
|
||||
}
|
||||
|
||||
// VisionGraspObject::Goal: object_id
|
||||
// MotorInfo::Request: target, type, motor_ids
|
||||
template<>
|
||||
inline interfaces::action::VisionGraspObject::Goal from_yaml<interfaces::action::VisionGraspObject::Goal>(const YAML::Node & n)
|
||||
inline interfaces::srv::MotorInfo::Request from_yaml<interfaces::srv::MotorInfo::Request>(const YAML::Node & n)
|
||||
{
|
||||
interfaces::action::VisionGraspObject::Goal g;
|
||||
interfaces::srv::MotorInfo::Request r;
|
||||
if (n && n.IsMap()) {
|
||||
if (n["object_id"]) g.object_id = n["object_id"].as<std::string>();
|
||||
if (n["target"]) r.target = n["target"].as<std::string>();
|
||||
if (n["type"]) r.type = n["type"].as<std::string>();
|
||||
if (n["motor_ids"]) {
|
||||
auto vec = n["motor_ids"].as<std::vector<uint8_t>>();
|
||||
r.motor_ids.assign(vec.begin(), vec.end());
|
||||
}
|
||||
}
|
||||
return g;
|
||||
return r;
|
||||
}
|
||||
|
||||
// MotorParam::Request: motor_id, max_speed, add_acc, dec_acc
|
||||
template<>
|
||||
inline interfaces::srv::MotorParam::Request from_yaml<interfaces::srv::MotorParam::Request>(const YAML::Node & n)
|
||||
{
|
||||
interfaces::srv::MotorParam::Request r;
|
||||
if (n && n.IsMap()) {
|
||||
if (n["motor_id"]) r.motor_id = n["motor_id"].as<uint16_t>();
|
||||
if (n["max_speed"]) r.max_speed = n["max_speed"].as<uint16_t>();
|
||||
if (n["add_acc"]) r.add_acc = n["add_acc"].as<uint16_t>();
|
||||
if (n["dec_acc"]) r.dec_acc = n["dec_acc"].as<uint16_t>();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// BtRebuild::Request: type, config, param
|
||||
template<>
|
||||
inline interfaces::srv::BtRebuild::Request from_yaml<interfaces::srv::BtRebuild::Request>(const YAML::Node & n)
|
||||
{
|
||||
interfaces::srv::BtRebuild::Request r;
|
||||
if (n && n.IsMap()) {
|
||||
if (n["type"]) r.type = n["type"].as<std::string>();
|
||||
if (n["config"]) r.config = n["config"].as<std::string>();
|
||||
if (n["param"]) r.param = n["param"].as<std::string>();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
} // namespace brain
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "interfaces/action/arm.hpp"
|
||||
#include "interfaces/action/camera_take_photo.hpp"
|
||||
#include "interfaces/action/gripper_cmd.hpp"
|
||||
#include "interfaces/action/hand_control.hpp"
|
||||
#include "interfaces/action/move_home.hpp"
|
||||
#include "interfaces/action/move_leg.hpp"
|
||||
@@ -30,7 +31,8 @@ using SkillActionTypes = std::tuple<
|
||||
interfaces::action::MoveWaist,
|
||||
interfaces::action::MoveLeg,
|
||||
interfaces::action::MoveWheel,
|
||||
interfaces::action::MoveHome
|
||||
interfaces::action::MoveHome,
|
||||
interfaces::action::GripperCmd
|
||||
>;
|
||||
|
||||
using SkillServiceTypes = std::tuple<
|
||||
@@ -44,7 +46,7 @@ struct SkillActionTrait<interfaces::action::Arm>
|
||||
{
|
||||
static constexpr const char * skill_name = "Arm";
|
||||
static constexpr const char * default_topic = "ArmAction";
|
||||
static bool success(const interfaces::action::Arm::Result & r) {return (r.result == 0);}
|
||||
static bool success(const interfaces::action::Arm::Result & r, const std::string & instance_name) {(void)instance_name; return (r.result == 0);}
|
||||
static std::string message(const interfaces::action::Arm::Result & r) {(void)r; return "completed";}
|
||||
};
|
||||
|
||||
@@ -53,7 +55,7 @@ struct SkillActionTrait<interfaces::action::CameraTakePhoto>
|
||||
{
|
||||
static constexpr const char * skill_name = "CameraTakePhoto";
|
||||
static constexpr const char * default_topic = "";
|
||||
static bool success(const interfaces::action::CameraTakePhoto::Result & r) {return r.success;}
|
||||
static bool success(const interfaces::action::CameraTakePhoto::Result & r, const std::string & instance_name) {(void)instance_name; return r.success;}
|
||||
static std::string message(const interfaces::action::CameraTakePhoto::Result & r) {return r.message;}
|
||||
};
|
||||
|
||||
@@ -62,7 +64,7 @@ struct SkillActionTrait<interfaces::action::HandControl>
|
||||
{
|
||||
static constexpr const char * skill_name = "HandControl";
|
||||
static constexpr const char * default_topic = "";
|
||||
static bool success(const interfaces::action::HandControl::Result & r) {return r.success;}
|
||||
static bool success(const interfaces::action::HandControl::Result & r, const std::string & instance_name) {(void)instance_name; return r.success;}
|
||||
static std::string message(const interfaces::action::HandControl::Result & r) {return r.message;}
|
||||
};
|
||||
|
||||
@@ -70,8 +72,8 @@ template<>
|
||||
struct SkillActionTrait<interfaces::action::MoveWaist>
|
||||
{
|
||||
static constexpr const char * skill_name = "MoveWaist";
|
||||
static constexpr const char * default_topic = "";
|
||||
static bool success(const interfaces::action::MoveWaist::Result & r) {return r.success;}
|
||||
static constexpr const char * default_topic = "MoveWaist";
|
||||
static bool success(const interfaces::action::MoveWaist::Result & r, const std::string & instance_name) {(void)instance_name; return r.success;}
|
||||
static std::string message(const interfaces::action::MoveWaist::Result & r) {return r.message;}
|
||||
};
|
||||
|
||||
@@ -79,8 +81,8 @@ template<>
|
||||
struct SkillActionTrait<interfaces::action::MoveLeg>
|
||||
{
|
||||
static constexpr const char * skill_name = "MoveLeg";
|
||||
static constexpr const char * default_topic = "";
|
||||
static bool success(const interfaces::action::MoveLeg::Result & r) {return r.success;}
|
||||
static constexpr const char * default_topic = "MoveLeg";
|
||||
static bool success(const interfaces::action::MoveLeg::Result & r, const std::string & instance_name) {(void)instance_name; return r.success;}
|
||||
static std::string message(const interfaces::action::MoveLeg::Result & r) {return r.message;}
|
||||
};
|
||||
|
||||
@@ -88,8 +90,8 @@ template<>
|
||||
struct SkillActionTrait<interfaces::action::MoveWheel>
|
||||
{
|
||||
static constexpr const char * skill_name = "MoveWheel";
|
||||
static constexpr const char * default_topic = "";
|
||||
static bool success(const interfaces::action::MoveWheel::Result & r) {return r.success;}
|
||||
static constexpr const char * default_topic = "MoveWheel";
|
||||
static bool success(const interfaces::action::MoveWheel::Result & r, const std::string & instance_name) {(void)instance_name; return r.success;}
|
||||
static std::string message(const interfaces::action::MoveWheel::Result & r) {return r.message;}
|
||||
};
|
||||
|
||||
@@ -97,11 +99,35 @@ template<>
|
||||
struct SkillActionTrait<interfaces::action::MoveHome>
|
||||
{
|
||||
static constexpr const char * skill_name = "MoveHome";
|
||||
static constexpr const char * default_topic = "";
|
||||
static bool success(const interfaces::action::MoveHome::Result & r) {return r.success;}
|
||||
static constexpr const char * default_topic = "MoveHome";
|
||||
static bool success(const interfaces::action::MoveHome::Result & r, const std::string & instance_name) {(void)instance_name; return r.success;}
|
||||
static std::string message(const interfaces::action::MoveHome::Result & r) {return r.message;}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SkillActionTrait<interfaces::action::GripperCmd>
|
||||
{
|
||||
static constexpr const char * skill_name = "GripperCmd";
|
||||
static constexpr const char * default_topic = "gripper_cmd0";
|
||||
static bool success(const interfaces::action::GripperCmd::Result & r, const std::string & instance_name) {
|
||||
(void)instance_name;
|
||||
|
||||
if (r.result == 0) return false;
|
||||
|
||||
//如果instance_name中带有"open",则表示是打开手指的命令
|
||||
if (instance_name.find("open") != std::string::npos) {
|
||||
//如果r.state中包含"手指已到达指定的位置",则认为成功
|
||||
return r.state.find("手指已到达指定的位置") != std::string::npos;
|
||||
} else if (instance_name.find("close") != std::string::npos) {
|
||||
//如果r.state中包含"手指在闭合检测到物体",则认为成功
|
||||
return (r.state.find("手指在闭合检测到物体") != std::string::npos);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
static std::string message(const interfaces::action::GripperCmd::Result & r) {return r.state;}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SkillServiceTrait<interfaces::srv::VisionObjectRecognition>
|
||||
{
|
||||
|
||||
@@ -287,10 +287,17 @@ private:
|
||||
const std::string & topic,
|
||||
const std::string & internal_skill)
|
||||
{
|
||||
auto it = action_override_registrars_.find(base);
|
||||
// PRIORITY 1: Match exact skill name (e.g. "GripperCmd0") for highly specific overrides
|
||||
auto it = action_override_registrars_.find(internal_skill);
|
||||
// PRIORITY 2: Match interface base name (e.g. "GripperCmd") for generic overrides
|
||||
if (it == action_override_registrars_.end()) {
|
||||
it = action_override_registrars_.find(base);
|
||||
}
|
||||
|
||||
if (it != action_override_registrars_.end()) {
|
||||
it->second(topic, internal_skill);
|
||||
RCLCPP_INFO(node_->get_logger(), "Overridden action client registration: %s", base.c_str());
|
||||
RCLCPP_INFO(node_->get_logger(), "Registered action client '%s' via Hook on '%s'",
|
||||
internal_skill.c_str(), it->first.c_str());
|
||||
return;
|
||||
}
|
||||
using GoalHandle = typename ActionClientRegistry::GoalHandle<ActionT>;
|
||||
@@ -324,7 +331,7 @@ private:
|
||||
if (!result_cb) {
|
||||
result_cb = [this, internal_skill](const typename GoalHandle::WrappedResult & res) {
|
||||
if (res.code == rclcpp_action::ResultCode::SUCCEEDED && res.result &&
|
||||
SkillActionTrait<ActionT>::success(*res.result)) {
|
||||
SkillActionTrait<ActionT>::success(*res.result, "")) {
|
||||
RCLCPP_INFO(node_->get_logger(), "action succeeded: %s", internal_skill.c_str());
|
||||
} else if (res.code == rclcpp_action::ResultCode::CANCELED) {
|
||||
RCLCPP_WARN(node_->get_logger(), "action cancelled: %s", internal_skill.c_str());
|
||||
@@ -365,7 +372,7 @@ private:
|
||||
template<size_t I = 0, typename TupleT, typename RegistryT>
|
||||
bool dispatch_skill_action(
|
||||
const std::string & skill, const std::string & topic, RegistryT * reg,
|
||||
rclcpp::Logger logger, std::chrono::nanoseconds timeout, std::string & detail)
|
||||
rclcpp::Logger logger, std::chrono::nanoseconds timeout, const std::string & instance_name, std::string & detail)
|
||||
{
|
||||
if constexpr (I == std::tuple_size<TupleT>::value) {
|
||||
return false;
|
||||
@@ -374,7 +381,7 @@ bool dispatch_skill_action(
|
||||
if (skill == SkillActionTrait<ActionT>::skill_name) {
|
||||
auto opt = reg->template send_and_wait<ActionT>(topic, logger, timeout);
|
||||
if (opt && opt->code == rclcpp_action::ResultCode::SUCCEEDED && opt->result) {
|
||||
bool ok = SkillActionTrait<ActionT>::success(*opt->result);
|
||||
bool ok = SkillActionTrait<ActionT>::success(*opt->result, instance_name);
|
||||
detail = ok ? SkillActionTrait<ActionT>::message(*opt->result) : std::string(
|
||||
"result flag false");
|
||||
return ok;
|
||||
@@ -382,7 +389,7 @@ bool dispatch_skill_action(
|
||||
detail = "action failed";
|
||||
return false;
|
||||
}
|
||||
return dispatch_skill_action<I + 1, TupleT>(skill, topic, reg, logger, timeout, detail);
|
||||
return dispatch_skill_action<I + 1, TupleT>(skill, topic, reg, logger, timeout, instance_name, detail);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -149,10 +149,10 @@ struct StExecuting : smacc2::SmaccState<StExecuting, SmCerebellum>
|
||||
while (!d.execute_fn) {
|
||||
std::this_thread::sleep_for(5ms);
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
if (now - last_warn > 5s) {
|
||||
RCLCPP_WARN(this->getLogger(), "[SM] Still waiting for execute_fn to be set...");
|
||||
last_warn = now;
|
||||
}
|
||||
if (now - last_warn > 10s) {
|
||||
RCLCPP_WARN(this->getLogger(), "[SM] Still waiting for execute_fn to be set...");
|
||||
last_warn = now;
|
||||
}
|
||||
}
|
||||
try {
|
||||
auto res = d.execute_fn(this->getLogger());
|
||||
|
||||
42
src/brain/launch/brain.launch.py
Normal file
42
src/brain/launch/brain.launch.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from launch import LaunchDescription
|
||||
from launch.actions import DeclareLaunchArgument
|
||||
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
|
||||
from launch_ros.actions import Node
|
||||
from launch_ros.substitutions import FindPackageShare
|
||||
|
||||
|
||||
def generate_launch_description():
|
||||
# Declare launch arguments
|
||||
declare_params_file_cmd = DeclareLaunchArgument(
|
||||
'params_file',
|
||||
default_value=PathJoinSubstitution([
|
||||
FindPackageShare('brain'),
|
||||
'config',
|
||||
'brain_node_params.yaml'
|
||||
]),
|
||||
description='Full path to params file to load'
|
||||
)
|
||||
|
||||
# Get the params file path
|
||||
params_file = LaunchConfiguration('params_file')
|
||||
|
||||
# Create the brain node that runs both cerebrum and cerebellum
|
||||
brain_node = Node(
|
||||
package='brain',
|
||||
executable='brain_node',
|
||||
# name='brain_node',
|
||||
parameters=[params_file],
|
||||
output='screen',
|
||||
emulate_tty=True
|
||||
)
|
||||
|
||||
# Create the launch description
|
||||
ld = LaunchDescription()
|
||||
|
||||
# Declare launch arguments
|
||||
ld.add_action(declare_params_file_cmd)
|
||||
|
||||
# Add nodes
|
||||
ld.add_action(brain_node)
|
||||
|
||||
return ld
|
||||
56
src/brain/launch/brain_with_params.launch.py
Normal file
56
src/brain/launch/brain_with_params.launch.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from launch import LaunchDescription
|
||||
from launch.actions import DeclareLaunchArgument, OpaqueFunction
|
||||
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
|
||||
from launch_ros.actions import Node
|
||||
from launch_ros.substitutions import FindPackageShare
|
||||
from launch.conditions import IfCondition
|
||||
import os
|
||||
|
||||
|
||||
def launch_setup(context, *args, **kwargs):
|
||||
# Get the params file path
|
||||
params_file = LaunchConfiguration('params_file').perform(context)
|
||||
|
||||
# Create the brain node that runs both cerebrum and cerebellum
|
||||
brain_node = Node(
|
||||
package='brain',
|
||||
executable='brain_node',
|
||||
name='brain_node',
|
||||
parameters=[params_file],
|
||||
output='screen',
|
||||
emulate_tty=True,
|
||||
# Override specific parameters if needed
|
||||
arguments=[
|
||||
# Example of overriding individual parameters via command line
|
||||
# Uncomment and modify as needed
|
||||
# "--ros-args",
|
||||
# "-p", "tick_rate_hz:=20.0",
|
||||
# "-p", "default_action_timeout_sec:=60.0"
|
||||
]
|
||||
)
|
||||
|
||||
return [brain_node]
|
||||
|
||||
|
||||
def generate_launch_description():
|
||||
# Declare launch arguments
|
||||
declare_params_file_cmd = DeclareLaunchArgument(
|
||||
'params_file',
|
||||
default_value=PathJoinSubstitution([
|
||||
FindPackageShare('brain'),
|
||||
'config',
|
||||
'brain_node_params.yaml'
|
||||
]),
|
||||
description='Full path to params file to load'
|
||||
)
|
||||
|
||||
# Create the launch description
|
||||
ld = LaunchDescription()
|
||||
|
||||
# Declare launch arguments
|
||||
ld.add_action(declare_params_file_cmd)
|
||||
|
||||
# Add the opaque function to set up the nodes
|
||||
ld.add_action(OpaqueFunction(function=launch_setup))
|
||||
|
||||
return ld
|
||||
@@ -13,7 +13,6 @@
|
||||
<depend>rclcpp_components</depend>
|
||||
<depend>behaviortree_cpp</depend>
|
||||
<depend>interfaces</depend>
|
||||
<depend>brain_interfaces</depend>
|
||||
<depend>rclcpp_lifecycle</depend>
|
||||
<depend>rclcpp_action</depend>
|
||||
<depend>smacc2</depend>
|
||||
|
||||
@@ -25,8 +25,11 @@ int main(int argc, char ** argv)
|
||||
rclcpp::Logger logger = rclcpp::get_logger("brain_node");
|
||||
RCLCPP_INFO(logger, "Starting brain node...");
|
||||
|
||||
auto executor = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
|
||||
// Create node options with parameter overrides if provided
|
||||
rclcpp::NodeOptions options;
|
||||
// If command line arguments are provided, they will be handled by rclcpp::init
|
||||
|
||||
auto executor = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
|
||||
|
||||
auto cerebellum_node = std::make_shared<brain::CerebellumNode>(options);
|
||||
auto cerebrum_node = std::make_shared<brain::CerebrumNode>(options);
|
||||
|
||||
202
src/brain/src/calc_grasp_pose.cpp
Normal file
202
src/brain/src/calc_grasp_pose.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
#include "brain/calc_grasp_pose.hpp"
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <string.h>
|
||||
#include <rclcpp/rclcpp.hpp>
|
||||
#include <rclcpp/logger.hpp>
|
||||
|
||||
namespace brain {
|
||||
|
||||
bool GraspPoseCalculator::rm_arm_algo_init_done_ = false;
|
||||
|
||||
GraspPoseCalculator::GraspPoseCalculator()
|
||||
{
|
||||
}
|
||||
|
||||
tf2::Vector3 normalize_vector(const tf2::Vector3& v) {
|
||||
if (v.length() == 0) return v;
|
||||
return v.normalized();
|
||||
}
|
||||
|
||||
GraspResult GraspPoseCalculator::create_grasp_matrix(
|
||||
const tf2::Vector3& target_pos,
|
||||
const tf2::Vector3& approach_vec,
|
||||
const tf2::Vector3& palm_normal_vec,
|
||||
double safety_dist,
|
||||
double finger_length
|
||||
) {
|
||||
tf2::Vector3 z_axis = normalize_vector(approach_vec);
|
||||
tf2::Vector3 x_axis = normalize_vector(palm_normal_vec);
|
||||
tf2::Vector3 y_axis = z_axis.cross(x_axis);
|
||||
x_axis = y_axis.cross(z_axis);
|
||||
tf2::Matrix3x3 R_grasp(
|
||||
x_axis.x(), y_axis.x(), z_axis.x(),
|
||||
x_axis.y(), y_axis.y(), z_axis.y(),
|
||||
x_axis.z(), y_axis.z(), z_axis.z()
|
||||
);
|
||||
|
||||
tf2::Transform T_grasp;
|
||||
T_grasp.setIdentity();
|
||||
T_grasp.setOrigin(target_pos);
|
||||
T_grasp.setBasis(R_grasp);
|
||||
T_grasp.setOrigin(T_grasp.getOrigin() - z_axis * finger_length);
|
||||
tf2::Transform T_pre = T_grasp;
|
||||
T_pre.setOrigin(T_pre.getOrigin() - z_axis * safety_dist);
|
||||
|
||||
GraspResult result;
|
||||
result.grasp_pose.position = T_grasp.getOrigin();
|
||||
result.grasp_pose.orientation = T_grasp.getRotation();
|
||||
result.pre_grasp_pose.position = T_pre.getOrigin();
|
||||
result.pre_grasp_pose.orientation = T_pre.getRotation();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GraspResult GraspPoseCalculator::calculate(
|
||||
const tf2::Vector3& target_pos,
|
||||
const tf2::Quaternion& target_quat,
|
||||
const std::string& grasp_type,
|
||||
double angle_deg,
|
||||
const std::string& palm_facing,
|
||||
double safety_dist,
|
||||
double finger_length,
|
||||
const std::string& arm
|
||||
) {
|
||||
(void)target_quat;
|
||||
|
||||
bool is_left = (arm.find("left") != std::string::npos);
|
||||
|
||||
tf2::Vector3 V_world_up(-1.0, 0.0, 0.0);
|
||||
tf2::Vector3 V_world_down = -V_world_up;
|
||||
tf2::Vector3 P_shoulder(0, 0, 0);
|
||||
tf2::Vector3 V_sb = target_pos - P_shoulder;
|
||||
tf2::Vector3 V_horiz = V_sb - (V_sb.dot(V_world_up) * V_world_up);
|
||||
if (V_horiz.length() < 1e-3) {
|
||||
V_horiz = tf2::Vector3(0.0, 1.0, 0.0); // Default horizontal vector
|
||||
} else {
|
||||
V_horiz = normalize_vector(V_horiz);
|
||||
}
|
||||
tf2::Vector3 approach_vec;
|
||||
tf2::Vector3 palm_normal;
|
||||
std::string name_suffix;
|
||||
|
||||
if (grasp_type == "side") {
|
||||
// tf2::Vector3 V_horiz_sb(0, V_sb.y(), V_sb.z());
|
||||
double base_angle = 0.0;
|
||||
// if (V_horiz_sb.length() >= 1e-3) {
|
||||
// base_angle = std::atan2(V_horiz_sb.z(), V_horiz_sb.y());
|
||||
// }
|
||||
double rad = angle_deg * M_PI / 180.0;
|
||||
double angle = base_angle + rad;
|
||||
double dy = std::cos(angle);
|
||||
double dz = std::sin(angle);
|
||||
if (is_left) {
|
||||
dy = -dy;
|
||||
}
|
||||
approach_vec = tf2::Vector3(0, dy, dz); // Horizontal approach
|
||||
|
||||
if (palm_facing == "up") {
|
||||
palm_normal = V_world_up;
|
||||
name_suffix = "Side_Angle_" + std::to_string((int)angle_deg) + "_Palm_Up";
|
||||
} else {
|
||||
palm_normal = V_world_down;
|
||||
name_suffix = "Side_Angle_" + std::to_string((int)angle_deg) + "_Palm_Down";
|
||||
}
|
||||
} else if (grasp_type == "top") {
|
||||
approach_vec = V_world_down;
|
||||
palm_normal = V_horiz;
|
||||
name_suffix = "Top_Grasp";
|
||||
} else {
|
||||
approach_vec = V_horiz;
|
||||
palm_normal = V_world_down;
|
||||
name_suffix = "Side_Default";
|
||||
}
|
||||
|
||||
GraspResult result = create_grasp_matrix(target_pos, approach_vec, palm_normal, safety_dist, finger_length);
|
||||
result.name = name_suffix;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double GraspPoseCalculator::evaluate_grasp_quality(
|
||||
const tf2::Vector3& target_pos,
|
||||
double angle_deg,
|
||||
const std::string& arm
|
||||
) {
|
||||
double score = 0.0;
|
||||
bool is_right = (arm.find("right") != std::string::npos);
|
||||
// In this frame (Z is Right), angle > 0 moves towards Z (Right/Outward)
|
||||
bool is_outward = (is_right && angle_deg > 0) || (!is_right && angle_deg < 0);
|
||||
|
||||
if (is_outward) {
|
||||
score += 50.0;
|
||||
} else if (std::abs(angle_deg) < 1e-3) {
|
||||
score += 10.0;
|
||||
} else {
|
||||
score -= 50.0;
|
||||
}
|
||||
|
||||
double abs_angle = std::abs(angle_deg);
|
||||
if (abs_angle < 10.0) {
|
||||
score -= 20.0;
|
||||
} else if (abs_angle >= 20.0 && abs_angle <= 50.0) {
|
||||
score += 30.0;
|
||||
} else if (abs_angle > 60.0) {
|
||||
score -= 20.0;
|
||||
}
|
||||
|
||||
tf2::Vector3 P_shoulder(0, 0, 0);
|
||||
tf2::Vector3 V_sb = target_pos - P_shoulder;
|
||||
tf2::Vector3 V_horiz_sb(0, V_sb.y(), V_sb.z());
|
||||
|
||||
double base_angle = std::atan2(V_horiz_sb.z(), V_horiz_sb.y());
|
||||
double rad = angle_deg * M_PI / 180.0;
|
||||
double angle = base_angle + rad;
|
||||
|
||||
tf2::Vector3 approach_vec(0, std::cos(angle), std::sin(angle));
|
||||
tf2::Vector3 wrist_pos = target_pos - approach_vec * 0.2;
|
||||
double dist_shoulder_wrist = wrist_pos.length();
|
||||
|
||||
if (dist_shoulder_wrist > 0.8) {
|
||||
score -= 100.0;
|
||||
} else if (dist_shoulder_wrist < 0.2) {
|
||||
score -= 100.0;
|
||||
} else if (dist_shoulder_wrist >= 0.35 && dist_shoulder_wrist <= 0.65) {
|
||||
score += 20.0;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
std::vector<double> GraspPoseCalculator::find_optimal_grasp_angles(
|
||||
const tf2::Vector3& target_pos,
|
||||
const std::string& arm,
|
||||
int top_k
|
||||
) {
|
||||
std::vector<std::pair<double, double>> scored_angles;
|
||||
std::vector<double> angles;
|
||||
bool is_right = (arm.find("right") != std::string::npos);
|
||||
if (is_right) {
|
||||
for (double a = 0.0; a >= -60.0; a -= 5.0) angles.push_back(a);
|
||||
} else {
|
||||
for (double a = 0.0; a <= 60.0; a += 5.0) angles.push_back(a);
|
||||
}
|
||||
for (double angle : angles) {
|
||||
double score = evaluate_grasp_quality(target_pos, angle, arm);
|
||||
scored_angles.push_back({score, angle});
|
||||
}
|
||||
std::sort(scored_angles.begin(), scored_angles.end(),
|
||||
[](const std::pair<double, double>& a, const std::pair<double, double>& b) {
|
||||
return a.first > b.first;
|
||||
}
|
||||
);
|
||||
std::vector<double> result;
|
||||
for (int i = 0; i < std::min((int)scored_angles.size(), top_k); ++i) {
|
||||
result.push_back(scored_angles[i].second);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace brain
|
||||
1112
src/brain/src/cerebellum_hooks.cpp
Normal file
1112
src/brain/src/cerebellum_hooks.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -311,6 +311,8 @@ void SkillManager::register_interfaces_(const SkillSpec & s)
|
||||
return prefix + "/" + base;
|
||||
};
|
||||
|
||||
const std::string skill_snake = to_snake_case(s.name);
|
||||
|
||||
for (const auto & iface : s.interfaces) {
|
||||
auto parsed = parse_interface_entry(iface);
|
||||
if (!parsed) {
|
||||
@@ -323,8 +325,8 @@ void SkillManager::register_interfaces_(const SkillSpec & s)
|
||||
const std::string base_snake = to_snake_case(parsed->base);
|
||||
|
||||
auto resolve_topic_name = [&](const std::string & kind_suffix) {
|
||||
// Compute the prior default (prefix + base_snake), but allow per-trait default topic when provided.
|
||||
const std::string prefix_default = join_topic(prefix_value, base_snake);
|
||||
// Compute the prior default (prefix + skill_snake), but allow per-trait default topic when provided.
|
||||
const std::string prefix_default = join_topic(prefix_value, skill_snake);
|
||||
const auto & action_defaults = get_action_default_topics();
|
||||
const auto & service_defaults = get_service_default_topics();
|
||||
std::string trait_default;
|
||||
@@ -342,8 +344,10 @@ void SkillManager::register_interfaces_(const SkillSpec & s)
|
||||
yaml_override = it_yaml->second;
|
||||
}
|
||||
const bool has_trait_default = !trait_default.empty();
|
||||
const std::string computed_default = !yaml_override.empty() ? yaml_override : (has_trait_default ? trait_default : prefix_default);
|
||||
const std::string param_name = base_snake + "." + kind_suffix + "_name";
|
||||
// If skill name doesn't match interface base, it's a specific instance; prefer prefix_default (skill_snake) over generic trait_default.
|
||||
const std::string computed_default = !yaml_override.empty() ? yaml_override :
|
||||
((skill_snake == base_snake && has_trait_default) ? trait_default : prefix_default);
|
||||
const std::string param_name = skill_snake + "." + kind_suffix + "_name";
|
||||
std::string topic_override;
|
||||
if (node_->get_parameter(param_name, topic_override)) {
|
||||
// If user explicitly sets an empty parameter, fall back to computed_default.
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
project(brain_interfaces)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||
endif()
|
||||
|
||||
# find dependencies
|
||||
find_package(ament_cmake REQUIRED)
|
||||
# uncomment the following section in order to fill in
|
||||
# further dependencies manually.
|
||||
# find_package(<dependency> REQUIRED)
|
||||
find_package(rosidl_default_generators REQUIRED)
|
||||
find_package(std_msgs REQUIRED)
|
||||
find_package(geometry_msgs REQUIRED)
|
||||
find_package(builtin_interfaces REQUIRED)
|
||||
find_package(interfaces REQUIRED)
|
||||
|
||||
set(msg_files
|
||||
msg/Movej.msg
|
||||
)
|
||||
set(action_files
|
||||
)
|
||||
set(srv_files
|
||||
srv/VisionDemo.srv
|
||||
)
|
||||
|
||||
# uncomment the following section in order to fill in
|
||||
# further dependencies manually.
|
||||
# find_package(<dependency> REQUIRED)
|
||||
rosidl_generate_interfaces(${PROJECT_NAME}
|
||||
${msg_files}
|
||||
${action_files}
|
||||
${srv_files}
|
||||
|
||||
DEPENDENCIES
|
||||
std_msgs
|
||||
geometry_msgs
|
||||
builtin_interfaces
|
||||
interfaces
|
||||
)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
find_package(ament_lint_auto REQUIRED)
|
||||
# the following line skips the linter which checks for copyrights
|
||||
# comment the line when a copyright and license is added to all source files
|
||||
set(ament_cmake_copyright_FOUND TRUE)
|
||||
# the following line skips cpplint (only works in a git repo)
|
||||
# comment the line when this package is in a git repo and when
|
||||
# a copyright and license is added to all source files
|
||||
set(ament_cmake_cpplint_FOUND TRUE)
|
||||
ament_lint_auto_find_test_dependencies()
|
||||
endif()
|
||||
|
||||
ament_export_dependencies(rosidl_default_runtime)
|
||||
ament_package()
|
||||
@@ -1,5 +0,0 @@
|
||||
float32[] joint
|
||||
uint8 speed
|
||||
bool block
|
||||
uint8 trajectory_connect #0 代表立即规划,1 代表和下一条轨迹一起规划,当为 1 时,轨迹不会立即执行
|
||||
uint8 dof
|
||||
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="3">
|
||||
<name>brain_interfaces</name>
|
||||
<version>0.0.0</version>
|
||||
<description>TODO: Package description</description>
|
||||
<maintainer email="root@todo.todo">root</maintainer>
|
||||
<license>TODO: License declaration</license>
|
||||
|
||||
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||
<build_depend>rosidl_default_generators</build_depend>
|
||||
<depend>std_msgs</depend>
|
||||
<depend>geometry_msgs</depend>
|
||||
<depend>interfaces</depend>
|
||||
<exec_depend>rosidl_default_runtime</exec_depend>
|
||||
<test_depend>ament_lint_auto</test_depend>
|
||||
<test_depend>ament_lint_common</test_depend>
|
||||
|
||||
<member_of_group>rosidl_interface_packages</member_of_group>
|
||||
<export>
|
||||
<build_type>ament_cmake</build_type>
|
||||
</export>
|
||||
</package>
|
||||
@@ -1,8 +0,0 @@
|
||||
string camera_position
|
||||
|
||||
---
|
||||
|
||||
std_msgs/Header header
|
||||
string info
|
||||
bool success
|
||||
interfaces/PoseClassAndID[] objects
|
||||
@@ -44,64 +44,48 @@ private:
|
||||
|
||||
// Fake two types of objects (example: cup / bottle), each type gives 1~2 Poses
|
||||
interfaces::msg::PoseClassAndID obj1;
|
||||
obj1.class_name = "bottlex";
|
||||
obj1.class_name = "medicine_box";
|
||||
obj1.class_id = 1;
|
||||
|
||||
//{-0.9758, 0, 0.42, -0.5, 0.5, 0.5, -0.5};
|
||||
geometry_msgs::msg::Pose pose1; // 基本位姿
|
||||
// pose1.position.x = 0.9758;
|
||||
// pose1.position.y = 0;
|
||||
// pose1.position.z = 0.42;
|
||||
// pose1.orientation.x = -0.5;
|
||||
// pose1.orientation.y = 0.5;
|
||||
// pose1.orientation.z = 0.5;
|
||||
// pose1.orientation.w = -0.5;
|
||||
|
||||
//geometry_msgs.msg.Pose(position=geometry_msgs.msg.Point(x=-0.2851924786746129, y=-0.056353812689333635, z=1.073772448259523),
|
||||
//orientation=geometry_msgs.msg.Quaternion(x=-0.16713377464857188, y=-0.42460237568763715, z=-0.26706232441180955, w=0.8487972895879773))
|
||||
// pose1.position.x = -0.2851924786746129;
|
||||
// pose1.position.y = -0.056353812689333635;
|
||||
// pose1.position.z = 1.073772448259523;
|
||||
// pose1.orientation.x = -0.16713377464857188;
|
||||
// pose1.orientation.y = -0.42460237568763715;
|
||||
// pose1.orientation.z = -0.26706232441180955;
|
||||
// pose1.orientation.w = 0.8487972895879773;
|
||||
if (req->camera_position == "top") {
|
||||
//0.1647, 0.7436, -0.2081, 0.4809, 0.7398, 0.4006, 0.2469
|
||||
pose1.position.x = 0.1647;
|
||||
pose1.position.y = 0.7436;
|
||||
pose1.position.z = -0.2081;
|
||||
pose1.orientation.x = 0.4809;
|
||||
pose1.orientation.y = 0.7398;
|
||||
pose1.orientation.z = 0.4006;
|
||||
pose1.orientation.w = 0.2469;
|
||||
} else if (req->camera_position == "left") {
|
||||
//0.2320, -0.6137, 0.2141, 0.3670, 0.7705, -0.4314, 0.2924
|
||||
pose1.position.x = 0.2320;
|
||||
pose1.position.y = 0.6137;
|
||||
pose1.position.z = 0.2141;
|
||||
pose1.orientation.x = -0.3670;
|
||||
pose1.orientation.y = 0.7705;
|
||||
pose1.orientation.z = 0.4314;
|
||||
pose1.orientation.w = 0.2924;
|
||||
} else if (req->camera_position == "right") {
|
||||
//-0.0165, 0.0246, 0.4166, 0.2939, -0.2219, -0.6882, 0.6251
|
||||
pose1.position.x = -0.0165;
|
||||
pose1.position.y = 0.0246;
|
||||
pose1.position.z = 0.4166;
|
||||
pose1.orientation.x = 0.2939;
|
||||
pose1.orientation.y = -0.2219;
|
||||
pose1.orientation.z = -0.6882;
|
||||
pose1.orientation.w = 0.6251;
|
||||
}
|
||||
|
||||
//222.853, 514.124, 261.742
|
||||
//-0.65115316, 0.05180144, -0.19539139, 0.73153153
|
||||
//-0.63142093, 0.18186004, -0.12407289, 0.74353241
|
||||
pose1.position.x = 222.853;
|
||||
pose1.position.y = 514.124;
|
||||
pose1.position.z = 261.742;
|
||||
pose1.orientation.x = -0.65115316;
|
||||
pose1.orientation.y = 0.05180144;
|
||||
pose1.orientation.z = -0.19539139;
|
||||
pose1.orientation.w = 0.73153153;
|
||||
|
||||
obj1.pose_list.push_back(pose1);
|
||||
|
||||
// 第二个同类实例(示例)
|
||||
geometry_msgs::msg::Pose pose1b = pose1;
|
||||
pose1b.position.y += 0.05;
|
||||
obj1.pose_list.push_back(pose1b);
|
||||
|
||||
interfaces::msg::PoseClassAndID obj2;
|
||||
obj2.class_name = "cup";
|
||||
obj2.class_id = 2;
|
||||
geometry_msgs::msg::Pose pose2;
|
||||
pose2.position.x = 0.5;
|
||||
pose2.position.y = -0.2;
|
||||
pose2.position.z = 0.78;
|
||||
pose2.orientation.w = 1.0;
|
||||
obj2.pose_list.push_back(pose2);
|
||||
obj1.pose = pose1;
|
||||
obj1.grab_width = {0.046393, 0.065393, 0.046393}; // Example grab widths
|
||||
|
||||
res->objects.clear();
|
||||
res->objects.emplace_back(obj1);
|
||||
res->objects.emplace_back(obj2);
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Recognized " << res->objects.size() << " object classes (total instances: "
|
||||
<< (obj1.pose_list.size() + obj2.pose_list.size()) << ")";
|
||||
oss << "Recognized " << res->objects.size() << " object classes (total instances: " << res->objects.size() << ")";
|
||||
res->info = oss.str();
|
||||
} else {
|
||||
res->success = false;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
colcon build --packages-select brain_interfaces smacc2_msgs smacc2 brain
|
||||
#colcon build --packages-select brain_interfaces smacc2_msgs smacc2 brain arm_control leg_control vision_object_recg hand_control
|
||||
colcon build --packages-select smacc2_msgs smacc2 brain
|
||||
#colcon build --packages-select smacc2_msgs smacc2 brain arm_control leg_control vision_object_recg hand_control
|
||||
|
||||
0
src/scripts/euler_to_equa.py
Normal file → Executable file
0
src/scripts/euler_to_equa.py
Normal file → Executable file
0
src/scripts/euler_to_quaternion.py
Normal file → Executable file
0
src/scripts/euler_to_quaternion.py
Normal file → Executable file
45
src/scripts/gen_bt_params.py
Normal file → Executable file
45
src/scripts/gen_bt_params.py
Normal file → Executable file
@@ -116,25 +116,25 @@ def parse_action_file(path: str) -> List[Tuple[str, str]]:
|
||||
return fields
|
||||
|
||||
|
||||
def locate_action_file(interfaces_root: str, base: str) -> Optional[str]:
|
||||
action_dir = resolve_interface_subdir(interfaces_root, 'action')
|
||||
def locate_action_file(interfaces_root: str, base: str, type: str) -> Optional[str]:
|
||||
action_dir = resolve_interface_subdir(interfaces_root, type)
|
||||
# 1) Try as-is (CamelCase)
|
||||
candidate = os.path.join(action_dir, f'{base}.action')
|
||||
candidate = os.path.join(action_dir, f'{base}.{type}')
|
||||
if os.path.exists(candidate):
|
||||
return candidate
|
||||
# 2) Try CamelCase of snake
|
||||
camel = snake_to_camel(base)
|
||||
if camel != base:
|
||||
candidate2 = os.path.join(action_dir, f'{camel}.action')
|
||||
candidate2 = os.path.join(action_dir, f'{camel}.{type}')
|
||||
if os.path.exists(candidate2):
|
||||
return candidate2
|
||||
# 3) Try snake_case
|
||||
snake = to_snake(base)
|
||||
candidate3 = os.path.join(action_dir, f'{snake}.action')
|
||||
candidate3 = os.path.join(action_dir, f'{snake}.{type}')
|
||||
if os.path.exists(candidate3):
|
||||
return candidate3
|
||||
# 4) Case-insensitive lookup
|
||||
found = find_file_case_insensitive(action_dir, f'{base}.action')
|
||||
found = find_file_case_insensitive(action_dir, f'{base}.{type}')
|
||||
if found:
|
||||
return found
|
||||
# Not found
|
||||
@@ -220,6 +220,7 @@ def main():
|
||||
ap = argparse.ArgumentParser(description='Generate YAML params for BT nodes.')
|
||||
ap.add_argument('--xml', default='src/brain/config/bt_carry_boxes.xml', help='Path to BehaviorTree XML')
|
||||
ap.add_argument('--interfaces', default='../hivecore_robot_interfaces', help='Path to hivecore_robot_interfaces root')
|
||||
ap.add_argument('--skills', default='src/brain/config/robot_skills.yaml', help='Path to robot_skills.yaml')
|
||||
ap.add_argument('--out', default='src/brain/config/bt_carry_boxes.params.default.yaml', help='Output YAML path')
|
||||
args = ap.parse_args()
|
||||
|
||||
@@ -227,19 +228,49 @@ def main():
|
||||
repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
||||
xml_path = args.xml if os.path.isabs(args.xml) else os.path.join(repo_root, args.xml)
|
||||
interfaces_root = args.interfaces if os.path.isabs(args.interfaces) else os.path.join(repo_root, args.interfaces)
|
||||
skills_path = args.skills if os.path.isabs(args.skills) else os.path.join(repo_root, args.skills)
|
||||
out_path = args.out if os.path.isabs(args.out) else os.path.join(repo_root, args.out)
|
||||
|
||||
if not os.path.exists(xml_path):
|
||||
print(f'ERROR: XML not found: {xml_path}', file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
# Load mapping from skills.yaml if available
|
||||
skill_to_interface: Dict[str, str] = {}
|
||||
if os.path.exists(skills_path):
|
||||
try:
|
||||
with open(skills_path, 'r', encoding='utf-8') as f:
|
||||
skills_data = yaml.safe_load(f)
|
||||
if isinstance(skills_data, list):
|
||||
for skill in skills_data:
|
||||
name = skill.get('name')
|
||||
if not name: continue
|
||||
ifaces = skill.get('interfaces', [])
|
||||
for iface in ifaces:
|
||||
token = None
|
||||
if isinstance(iface, str):
|
||||
token = iface
|
||||
elif isinstance(iface, dict):
|
||||
token = iface.get('name')
|
||||
if token and '.' in token:
|
||||
base = token.split('.', 1)[0]
|
||||
skill_to_interface[name] = base
|
||||
break # Use first action/srv found
|
||||
except Exception as e:
|
||||
print(f"WARN: Failed to parse skills YAML {skills_path}: {e}", file=sys.stderr)
|
||||
|
||||
nodes = collect_bt_nodes(xml_path)
|
||||
results = []
|
||||
|
||||
for instance_name, node_tag in nodes:
|
||||
# Map tag to interface base by stripping trailing '_H' if present
|
||||
base = node_tag[:-2] if node_tag.endswith('_H') else node_tag
|
||||
action_file = locate_action_file(interfaces_root, base)
|
||||
# If tag (like SkillName_H) refers to a skill in robot_skills.yaml, resolve to its interface
|
||||
base = skill_to_interface.get(base, base)
|
||||
|
||||
action_file = locate_action_file(interfaces_root, base, "action")
|
||||
if action_file == None:
|
||||
action_file = locate_action_file(interfaces_root, base, "srv")
|
||||
fields: List[Tuple[str, str]] = parse_action_file(action_file) if action_file else []
|
||||
yaml_params = build_yaml_params_from_fields(fields)
|
||||
results.append({'name': instance_name, 'params': yaml_params})
|
||||
|
||||
4
src/scripts/gen_payload_converters.py
Normal file → Executable file
4
src/scripts/gen_payload_converters.py
Normal file → Executable file
@@ -348,6 +348,8 @@ def main():
|
||||
kind = kind.lower()
|
||||
header_snake = to_snake(base)
|
||||
if kind.startswith('action'):
|
||||
if base in added_actions:
|
||||
continue
|
||||
includes.add(f'"interfaces/action/{header_snake}.hpp"')
|
||||
# locate .action file in common subdirs
|
||||
action_dir = resolve_interface_subdir(interfaces_root, 'action')
|
||||
@@ -379,6 +381,8 @@ def main():
|
||||
converters.append(gen_converter_action(base, fields, header_snake))
|
||||
added_actions.add(base)
|
||||
elif kind.startswith('srv') or kind.startswith('service'):
|
||||
if base in added_srvs:
|
||||
continue
|
||||
includes.add(f'"interfaces/srv/{header_snake}.hpp"')
|
||||
srv_dir = resolve_interface_subdir(interfaces_root, 'srv')
|
||||
tried_paths = []
|
||||
|
||||
0
src/scripts/gen_robot_config.py
Normal file → Executable file
0
src/scripts/gen_robot_config.py
Normal file → Executable file
@@ -95,6 +95,7 @@ def parse_iface_item(item):
|
||||
return None
|
||||
|
||||
for entry in skills:
|
||||
skill_name = entry.get('name', '')
|
||||
if 'interfaces' not in entry:
|
||||
continue
|
||||
for iface in entry['interfaces']:
|
||||
@@ -105,13 +106,17 @@ for entry in skills:
|
||||
if kind == 'action':
|
||||
if base not in skill_action_types:
|
||||
skill_action_types.append(base)
|
||||
# Prefer default_topic from a skill whose name matches the interface base,
|
||||
# otherwise don't overwrite if we already have one from a prior matching or non-matching entry.
|
||||
if dtopic:
|
||||
action_default_map[base] = dtopic
|
||||
if base not in action_default_map or skill_name == base:
|
||||
action_default_map[base] = dtopic
|
||||
elif kind == 'srv':
|
||||
if base not in skill_service_types:
|
||||
skill_service_types.append(base)
|
||||
if dtopic:
|
||||
service_default_map[base] = dtopic
|
||||
if base not in service_default_map or skill_name == base:
|
||||
service_default_map[base] = dtopic
|
||||
|
||||
# Helper to map base name to include path / C++ type name.
|
||||
# Assumption: interfaces live in package `interfaces` and types are under `interfaces::action::Name` or `interfaces::srv::Name`.
|
||||
@@ -251,11 +256,11 @@ with OUT_HEADER.open('w') as out:
|
||||
result_fields = parse_action_result_fields(action_file_found) if action_file_found is not None else {}
|
||||
success_field, message_field, success_kind = pick_success_and_message_fields(result_fields)
|
||||
if success_kind == 'bool' and success_field is not None:
|
||||
out.write(f' static bool success(const {action_cpp_type(a)}::Result & r) {{return r.{success_field};}}\n')
|
||||
out.write(f' static bool success(const {action_cpp_type(a)}::Result & r, const std::string & instance_name) {{(void)instance_name; return r.{success_field};}}\n')
|
||||
elif success_kind == 'int_zero' and success_field is not None:
|
||||
out.write(f' static bool success(const {action_cpp_type(a)}::Result & r) {{return (r.{success_field} == 0);}}\n')
|
||||
out.write(f' static bool success(const {action_cpp_type(a)}::Result & r, const std::string & instance_name) {{(void)instance_name; return (r.{success_field} == 0);}}\n')
|
||||
else:
|
||||
out.write(f' static bool success(const {action_cpp_type(a)}::Result & r) {{(void)r; return true;}}\n')
|
||||
out.write(f' static bool success(const {action_cpp_type(a)}::Result & r, const std::string & instance_name) {{(void)instance_name; (void)r; return true;}}\n')
|
||||
if message_field is not None:
|
||||
out.write(f' static std::string message(const {action_cpp_type(a)}::Result & r) {{return r.{message_field};}}\n')
|
||||
else:
|
||||
|
||||
0
src/scripts/hand_eye_cali.py
Normal file → Executable file
0
src/scripts/hand_eye_cali.py
Normal file → Executable file
0
src/scripts/images_to_quaternions.py
Normal file → Executable file
0
src/scripts/images_to_quaternions.py
Normal file → Executable file
0
src/scripts/rotate_pose.py
Normal file → Executable file
0
src/scripts/rotate_pose.py
Normal file → Executable file
@@ -63,11 +63,20 @@ while [[ $# -gt 0 ]]; do
|
||||
esac
|
||||
done
|
||||
|
||||
timestamp() { date +"%Y%m%d_%H%M%S"; }
|
||||
# 获取当前日期用于归档 (例如: 20260114)
|
||||
date_day() { date +"%Y%m%d"; }
|
||||
# 获取可读的时间戳用于文件名 (例如: 2026-01-14_15-30-05)
|
||||
readable_timestamp() { date +"%Y-%m-%d_%H-%M-%S"; }
|
||||
|
||||
LOG_DIR="${WS_ROOT}/log/run/$(timestamp)"
|
||||
# 1. 统一存放路径到当天的目录下
|
||||
DAILY_LOG_ROOT="${WS_ROOT}/logs/$(date_day)"
|
||||
# 2. 为每次启动创建一个带时间的子目录 (保证多次运行不冲突)
|
||||
LOG_DIR="${DAILY_LOG_ROOT}/robot_logs_$(readable_timestamp)"
|
||||
mkdir -p "${LOG_DIR}"
|
||||
|
||||
# 强制 ROS 2 自身的内部日志也记录到此目录,防止散落在 ~/.ros/log
|
||||
export ROS_LOG_DIR="${LOG_DIR}"
|
||||
|
||||
pids=()
|
||||
names=()
|
||||
|
||||
@@ -75,12 +84,14 @@ start_node() {
|
||||
local name="$1"; shift
|
||||
local pkg="$1"; shift
|
||||
local exe="$1"; shift
|
||||
local log_file="${LOG_DIR}/${name}.log"
|
||||
# 3. 日志文件名可配置:在此处修改格式
|
||||
local node_ts=$(readable_timestamp)
|
||||
local log_file="${LOG_DIR}/${name}_${node_ts}.log"
|
||||
|
||||
if (( LOG_TO_FILES )); then
|
||||
echo "[run.sh] Starting ${name} -> ros2 run ${pkg} ${exe} (logs: ${log_file})"
|
||||
(
|
||||
# Disable ANSI colors in log files for readability
|
||||
# 禁用 ANSI 颜色以保持日志文件整洁
|
||||
RCUTILS_COLORIZED_OUTPUT=0 exec ros2 run "${pkg}" "${exe}" --ros-args --log-level "${LOG_LEVEL}"
|
||||
) >>"${log_file}" 2>&1 &
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user