Files
TG3/tg3_local_teleop/config.toml

278 lines
11 KiB
TOML

[network]
# Direct OmniSocket KCP input. No robot-side ZMQ receiving proxy is used.
transport = "omnisocket"
omnisocket_server = "192.168.5.14:14049"
omnisocket_peer_id = "tg3-009027fa8190-robot"
omnisocket_expected_sender = "tg3-009027fa8190-iarm"
omnisocket_max_packet_age_ms = 300.0
# The deployed OmniSocket receiver does not exchange a Hub heartbeat while idle.
# Re-register periodically with make-before-break so a Hub restart cannot leave
# a false connected state and healthy refreshes never create a routing gap.
# Active traffic resets this timer and is never interrupted by this refresh.
omnisocket_idle_session_refresh_s = 30.0
# The native session can remain blocked on an old connection after the public
# Hub disappears. An active session that receives no business frame for this
# interval exits so systemd creates a completely fresh session.
omnisocket_restart_after_stale_s = 2.0
# Retained only as a direct-LAN fallback when transport is changed to "zmq".
iarm_endpoint = "tcp://192.168.5.14:5003"
expected_iarm_id = "IArm009027FA8190"
expected_iarm_type = "TS1P"
minimum_arm_frequency_hz = 30.0
[ros]
command_topic = "/encoder_identical_joint"
rl_state_topic = "/hric/robot/rl_state"
arm_state_topic = "/freq_change/arm_status"
home_service = "/tg3_local_teleop/return_home"
cancel_home_service = "/tg3_local_teleop/cancel_home"
publish_rate_hz = 50.0
[robot]
required_state = "HBWALK"
required_status = "running"
state_timeout_s = 1.0
arm_state_timeout_s = 0.25
[control]
# OmniSocket start/stop is timed on EAI before any business frame is sent.
# This value remains for the direct-ZMQ fallback latch.
auto_home_on_stop = true
start_stop_hold_seconds = 3.0
max_slew_rad_s = 1.0
# This custom margin is checked only when teleoperation starts. It is not
# checked while collecting/following. Vendor limit protection is unchanged.
joint_limit_margin_rad = 0.03
# Joint order: left 11..17, then right 21..27. Values are the TG3.0 limits
# from the supplied 26.04.x SDK document, expressed in radians.
joint_lower_rad = [
-2.8449, -0.1920, -2.8449, -2.5482, -2.8449, -1.3265, -1.3265,
-2.8449, -3.3336, -2.8449, -2.5482, -2.8449, -1.3265, -1.3265,
]
joint_upper_rad = [
2.8449, 3.3336, 2.8449, 0.1920, 2.8449, 1.3265, 1.3265,
2.8449, 0.1920, 2.8449, 0.1920, 2.8449, 1.3265, 1.3265,
]
[data_collection]
# Left joystick press (L3) is a dedicated raw xTELE field and is not registered
# by the installed xTELE 0.1.2 button handlers. It only toggles recording while
# a validated teleoperation session is armed. Z+C STOP/safety disarm always
# ends an active recording without delaying robot control or Home.
enabled = true
button_hold_seconds = 1.0
button_release_seconds = 0.5
# This threshold qualifies only the L3 button edge; it is not a robot-motion
# watchdog and does not restore the removed 0.25 s network disarm gate.
button_input_timeout_s = 0.25
control_retry_seconds = 0.5
ack_timeout_seconds = 5.0
heartbeat_interval_seconds = 0.5
heartbeat_timeout_seconds = 3.0
status_stale_seconds = 4.0
control_topic = "/tg3/data_collection/control"
status_topic = "/tg3/data_collection/status"
iarm_frame_topic = "/tg3/data_collection/iarm_frame"
base_directory = "/home/nvidia/tg3_data_collection"
# Failed/incomplete payloads are discarded after the error is reported through
# recorder status and journal. Completed READY episodes remain only until the
# PS sync has durably verified its local copy and requests exact-episode removal.
retain_failed_episodes = false
minimum_free_gib = 100.0
max_duration_seconds = 1800.0
# Explicit data whitelist; never replace this with `-a` on the live robot.
# RGB is recorded through image_transport JPEG and 16UC1 depth through its
# lossless compressedDepth PNG transport. Only the head RGB-D camera is in the
# whitelist. It is optional and is discovered whenever its service is running.
# /robot_state is the authoritative measured robot state.
topics = [
"/robot_state",
"/encoder_identical_joint",
"/arm/cmd",
"/freq_change/arm_status",
"/data_logger/arm_status",
"/left_hand/set_motor_multi",
"/right_hand/set_motor_multi",
"/left_hand/motor_status",
"/right_hand/motor_status",
"/left_hand/touch_status",
"/right_hand/touch_status",
"/hric/robot/cmd_vel",
"/hric/robot/cmd_vel_status",
"/hric/robot/rl_state",
"/head/cmd",
"/imu_data",
"/power/board/key_status",
"/power/board/status",
"/power/battery/status",
"/ob_camera_head/color/image_raw/compressed",
"/ob_camera_head/color/camera_info",
"/ob_camera_head/color/metadata",
"/ob_camera_head/depth/image_raw/compressedDepth",
"/ob_camera_head/depth/camera_info",
"/ob_camera_head/depth/metadata",
"/tf_static",
"/tg3/data_collection/control",
"/tg3/data_collection/status",
"/tg3/data_collection/iarm_frame",
]
# Refuse a new episode if these core streams are absent from the live ROS
# graph. Other whitelisted streams may appear later and rosbag discovery will
# subscribe to them without restarting the recorder.
required_topics = [
"/robot_state",
"/encoder_identical_joint",
"/freq_change/arm_status",
"/left_hand/motor_status",
"/right_hand/motor_status",
"/hric/robot/rl_state",
"/tg3/data_collection/control",
"/tg3/data_collection/status",
"/tg3/data_collection/iarm_frame",
]
# Optional sensor groups never block capture or core READY. Their message
# counts and whole-episode average rates are recorded in manifest.json as
# absent/healthy/partial/low_rate quality observations. The Orbbec driver
# targets 30 Hz; 20 Hz leaves room for discovery and compression jitter.
[data_collection.optional_topic_groups.head_rgbd]
topics = [
"/ob_camera_head/color/image_raw/compressed",
"/ob_camera_head/color/camera_info",
"/ob_camera_head/color/metadata",
"/ob_camera_head/depth/image_raw/compressedDepth",
"/ob_camera_head/depth/camera_info",
"/ob_camera_head/depth/metadata",
]
[data_collection.optional_topic_groups.head_rgbd.minimum_topic_rates_hz]
"/ob_camera_head/color/image_raw/compressed" = 20.0
"/ob_camera_head/depth/image_raw/compressedDepth" = 20.0
[locomotion]
# Once Z+C has armed teleoperation and both sticks have been observed neutral,
# left-stick vertical directly controls translation and right-stick horizontal
# directly controls in-place yaw. No locomotion button or second hold is used.
enabled = true
command_topic = "/hric/robot/cmd_vel"
# This bridge never publishes FSM commands. The robot must already report
# HBWALK/running through the existing safety gate before velocity is allowed.
# Match the TG3 secondary-development TwistStamped example.
frame_id = "pelvis"
joystick_deadzone = 0.2
joystick_expo = 2.0
# Turning is linear after the deadzone so medium right-stick travel is not
# suppressed by the quadratic forward-motion curve. The official yaw cap is
# unchanged.
yaw_joystick_expo = 1.0
# TianGong secondary-development /cmd_vel limits for full/half-body walking:
# linear.x [-0.8, +1.0] m/s and angular.z [-0.8, +0.8] rad/s.
max_forward_m_s = 1.0
max_reverse_m_s = 0.8
max_angular_rad_s = 0.8
forward_axis_sign = 1.0
yaw_axis_sign = -1.0
zero_burst_frames = 10
[head]
# Camera-pitch mode: after Z+C arms teleoperation and the right-stick vertical
# axis has been observed neutral once, hold left Z while pushing the right stick
# up/down. While Z is held, right-stick yaw is suppressed so camera adjustment
# cannot accidentally turn the robot. No R3 is used.
enabled = true
command_topic = "/head/cmd"
state_topic = "/robot_state"
pitch_motor_id = 2
frame_id = "head"
mode = 0
label = 151
max_current_a = 1.0
command_speed_rad_s = 0.2
# Documented mechanical range is -15..+58 deg. Keep the commissioned visual
# working range at -10..+50 deg and always start from fresh measured feedback.
min_pitch_rad = -0.1745329252
max_pitch_rad = 0.872664626
max_pitch_speed_rad_s = 0.2
max_pitch_accel_rad_s2 = 0.5
pitch_axis_sign = -1.0
joystick_deadzone = 0.1
max_integration_dt_s = 0.1
input_timeout_s = 0.3
feedback_timeout_s = 0.25
# Existing vendor nodes advertise /head/cmd publishers. They are allowed when
# idle, but any actual foreign message leases head control for this interval;
# our bridge resumes only after quiet plus another neutral-stick observation.
foreign_command_quiet_s = 1.0
self_command_window_s = 0.25
[hands]
# TianGong 3.0 on this robot uses BrainCo Revo2 hands. Commands are published
# only while the same physical 3-second teleoperation latch is armed.
enabled = true
left_command_topic = "/left_hand/set_motor_multi"
right_command_topic = "/right_hand/set_motor_multi"
left_status_topic = "/left_hand/motor_status"
right_status_topic = "/right_hand/motor_status"
status_timeout_s = 0.25
# Vendor robot_tele_server uses mode 5 and an 800 ms expected duration.
mode = 5
duration_ms = 800
position_min = 1
position_max = 1000
# Commissioning limit: no commanded motor may change faster than 400/1000 of
# its full stroke per second. The driver keeps its own current/stall protection.
slew_units_per_s = 400.0
invert_scalar = false
# Scalar hand.position=0 is the robot's measured default-open pose. The closed
# endpoint is the conservative BrainCoRevo2 "normal" grasp from the installed
# xTELE GestureController.
# Order: thumb bend, thumb rotation, index, middle, ring, little.
open_normalized = [0.4, 0.4, 0.05, 0.05, 0.05, 0.05]
closed_normalized = [0.9, 0.5, 0.45, 0.52, 0.52, 0.45]
# Right B owns a robot-side, release-guarded bilateral pointing gesture while
# a teleop session is armed. Both activation and deactivation require one continuous
# 1-second hold, separated by at least 0.5 seconds of stable release. A new
# session is always release-locked. The pose is xTELE GestureController's
# BrainCoRevo2 gesture 2 ("single index finger"), state 0, in motor order:
# thumb bend, thumb rotation, index, middle, ring, little.
right_b_point_gesture_enabled = true
right_b_point_gesture_hold_seconds = 1.0
right_b_point_gesture_release_seconds = 0.5
right_b_point_pose_normalized = [0.2, 0.688, 0.0, 0.98, 0.98, 0.98]
# Right A is a momentary, robot-side pose: hold A to move the right hand to
# this measured BrainCo MotorStatus position and release A to resume the
# existing right-hand input (or an active right-B gesture). A new teleop
# session must first observe A released for 0.5 seconds. The normal hand slew
# limit remains in force; these are raw driver positions, not normalized data.
right_a_pose_enabled = true
right_a_pose_release_seconds = 0.5
right_a_pose_positions = [428, 735, 500, 77, 77, 72]
[home]
# Deliberately slower than manual teleoperation. This Home pose was captured
# from the robot's real arm feedback on 2026-08-06. Joint order is 11..17,
# followed by 21..27; values are radians. Home is not the motor-zero pose.
slew_rad_s = 0.25
joint_goal_rad = [
0.1842578799, 0.1234146282, 0.0396494754, -0.4828015864,
-0.0024294013, 0.0065013529, -0.0040423824,
0.1721130311, -0.1383204311, -0.0142812012, -0.3408825397,
0.0026911981, 0.0039934102, -0.0030838961,
]
# Abort if the commanded trajectory gets more than ~4.6 degrees ahead of
# measured robot motion.
max_tracking_error_rad = 0.08
command_tolerance_rad = 0.005
actual_tolerance_rad = 0.03
settle_s = 1.0
timeout_s = 30.0