[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" minimum_free_gib = 100.0 max_duration_seconds = 1800.0 # A camera endpoint merely existing is insufficient: completed episodes must # also sustain this conservative average rate across the rosbag data span. # The driver targets 30 Hz; 20 Hz tolerates startup/discovery jitter while # rejecting a stream that only delivered a few frames or stopped mid-episode. minimum_topic_rates_hz."/ob_camera_waist/color/image_raw/compressed" = 20.0 minimum_topic_rates_hz."/ob_camera_waist/depth/image_raw/compressedDepth" = 20.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. Waist RGB-D is required because that # camera is enabled on this robot. Head RGB-D stays optional: rosbag discovers # and records it automatically whenever orbbec_head.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", "/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", "/ob_camera_waist/color/image_raw/compressed", "/ob_camera_waist/color/camera_info", "/ob_camera_waist/color/metadata", "/ob_camera_waist/depth/image_raw/compressedDepth", "/ob_camera_waist/depth/camera_info", "/ob_camera_waist/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", "/ob_camera_waist/color/image_raw/compressed", "/ob_camera_waist/color/camera_info", "/ob_camera_waist/color/metadata", "/ob_camera_waist/depth/image_raw/compressedDepth", "/ob_camera_waist/depth/camera_info", "/ob_camera_waist/depth/metadata", "/tf_static", "/tg3/data_collection/control", "/tg3/data_collection/status", "/tg3/data_collection/iarm_frame", ] [locomotion] # The two original immediate bindings are independent: right C + left-stick # vertical controls translation; left Z + right-stick horizontal controls # in-place yaw. Both act on the next 50 Hz tick, with no second hold. 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" hold_seconds = 0.0 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 [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 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] [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