{"name": "wheeled_biped", "description": "Johnny 6. Chassis 318x280x170mm, 200mm segments, 380mm track, 125mm wheels.", "sim": {"timestep": 0.002, "control_hz": 100, "integrator": "implicitfast", "gravity": [0, 0, -9.81]}, "world": {"floor": {"friction": [1.0, 0.005, 0.0001], "size": 12.0, "bank_deg": 0.0, "pitch_deg": 0.0}}, "root": {"name": "chassis", "pos": [0, 0, 0.425], "float": true, "geoms": [{"type": "box", "size": [0.125, 0.14, 0.085], "pos": [0, 0, 0], "mass": 1.866, "rgba": [0.24, 0.3, 0.38, 1]}, {"type": "box", "size": [0.159, 0.14, 0.051000000000000004], "pos": [0, 0, 0], "mass": 0.933, "rgba": [0.24, 0.3, 0.38, 1]}, {"type": "cylinder", "from": [0.125, -0.14, 0.051000000000000004], "to": [0.125, 0.14, 0.051000000000000004], "radius": 0.034, "mass": 0.078, "rgba": [0.24, 0.3, 0.38, 1]}, {"type": "cylinder", "from": [0.125, -0.14, -0.051000000000000004], "to": [0.125, 0.14, -0.051000000000000004], "radius": 0.034, "mass": 0.078, "rgba": [0.24, 0.3, 0.38, 1]}, {"type": "cylinder", "from": [-0.125, -0.14, 0.051000000000000004], "to": [-0.125, 0.14, 0.051000000000000004], "radius": 0.034, "mass": 0.078, "rgba": [0.24, 0.3, 0.38, 1]}, {"type": "cylinder", "from": [-0.125, -0.14, -0.051000000000000004], "to": [-0.125, 0.14, -0.051000000000000004], "radius": 0.034, "mass": 0.078, "rgba": [0.24, 0.3, 0.38, 1]}, {"type": "box", "size": [0.004, 0.1, 0.045], "pos": [0.16, 0, 0.0], "mass": 0.02, "rgba": [0.15, 0.85, 0.35, 1], "name": "front_panel", "collide": false, "note": "green = front. The chassis is symmetric otherwise."}], "sites": [{"name": "imu", "pos": [0, 0, 0.07], "note": "fusion IMU mounted near the top face"}], "children": [{"name": "l_thigh", "pos": [0, 0.145, 0.0], "joint": {"name": "l_hip", "type": "hinge", "axis": [0, 1, 0], "range_deg": [-90, 90], "damping": 0.08, "armature": 0.008, "frictionloss": 0.01}, "geoms": [{"type": "box", "size": [0.02, 0.005, 0.1], "pos": [0, 0, -0.1], "mass": 0.745, "rgba": [0.62, 0.65, 0.7, 1]}], "children": [{"name": "l_shank", "pos": [0, 0.01, -0.2], "joint": {"name": "l_knee", "type": "hinge", "axis": [0, 1, 0], "damping": 0.06, "armature": 0.006, "frictionloss": 0.01, "note": "300 deg total, 150 each way from straight; limited so cables cannot pinch", "range_deg": [-150, 150]}, "geoms": [{"type": "box", "size": [0.018, 0.005, 0.1], "pos": [0, 0, -0.1], "mass": 0.31, "rgba": [0.62, 0.65, 0.7, 1]}], "children": [{"name": "l_wheel", "pos": [0, 0.035, -0.2], "joint": {"name": "l_wheel_j", "type": "hinge", "axis": [0, 1, 0], "continuous": true, "damping": 0.002, "armature": 0.004}, "geoms": [{"type": "cylinder", "from": [0, -0.02, 0], "to": [0, 0.02, 0], "radius": 0.0625, "mass": 0.455, "rgba": [0.12, 0.12, 0.14, 1], "contact": true, "collide": false}, {"type": "ellipsoid", "mass": 0.01, "rgba": [0.1, 0.1, 0.12, 0.0], "friction": [1.5, 0.006, 0.0002], "contact": true, "collide": true, "note": "crowned tyre: point contact, true 40mm width", "size": [0.0625, 0.02, 0.0625], "render": false}], "sites": [{"name": "l_foot", "pos": [0, 0, 0], "type": "sphere", "size": [0.0675]}]}, {"name": "l_roller", "pos": [0, 0.03, 0.0], "joint": {"name": "l_roller_j", "type": "hinge", "axis": [0, 1, 0], "continuous": true, "damping": 0.001, "armature": 0.001}, "geoms": [{"type": "cylinder", "from": [0, -0.012, 0], "to": [0, 0.012, 0], "radius": 0.05, "mass": 0.09, "rgba": [0.35, 0.37, 0.42, 1], "collide": false}, {"type": "ellipsoid", "mass": 0.01, "rgba": [0.35, 0.37, 0.42, 0.0], "friction": [1.0, 0.004, 0.0002], "contact": true, "size": [0.05, 0.012, 0.05], "render": false, "note": "crowned roller: point contact, true 24mm width"}], "note": "free-spinning 100mm knee roller: the robot sits on these"}]}]}, {"name": "r_thigh", "pos": [0, -0.145, 0.0], "joint": {"name": "r_hip", "type": "hinge", "axis": [0, 1, 0], "range_deg": [-90, 90], "damping": 0.08, "armature": 0.008, "frictionloss": 0.01}, "geoms": [{"type": "box", "size": [0.02, 0.005, 0.1], "pos": [0, 0, -0.1], "mass": 0.745, "rgba": [0.62, 0.65, 0.7, 1]}], "children": [{"name": "r_shank", "pos": [0, -0.01, -0.2], "joint": {"name": "r_knee", "type": "hinge", "axis": [0, 1, 0], "damping": 0.06, "armature": 0.006, "frictionloss": 0.01, "note": "300 deg total, 150 each way from straight; limited so cables cannot pinch", "range_deg": [-150, 150]}, "geoms": [{"type": "box", "size": [0.018, 0.005, 0.1], "pos": [0, 0, -0.1], "mass": 0.31, "rgba": [0.62, 0.65, 0.7, 1]}], "children": [{"name": "r_wheel", "pos": [0, -0.035, -0.2], "joint": {"name": "r_wheel_j", "type": "hinge", "axis": [0, 1, 0], "continuous": true, "damping": 0.002, "armature": 0.004}, "geoms": [{"type": "cylinder", "from": [0, -0.02, 0], "to": [0, 0.02, 0], "radius": 0.0625, "mass": 0.455, "rgba": [0.12, 0.12, 0.14, 1], "contact": true, "collide": false}, {"type": "ellipsoid", "mass": 0.01, "rgba": [0.1, 0.1, 0.12, 0.0], "friction": [1.5, 0.006, 0.0002], "contact": true, "collide": true, "note": "crowned tyre: point contact, true 40mm width", "size": [0.0625, 0.02, 0.0625], "render": false}], "sites": [{"name": "r_foot", "pos": [0, 0, 0], "type": "sphere", "size": [0.0675]}]}, {"name": "r_roller", "pos": [0, -0.03, 0.0], "joint": {"name": "r_roller_j", "type": "hinge", "axis": [0, 1, 0], "continuous": true, "damping": 0.001, "armature": 0.001}, "geoms": [{"type": "cylinder", "from": [0, -0.012, 0], "to": [0, 0.012, 0], "radius": 0.05, "mass": 0.09, "rgba": [0.35, 0.37, 0.42, 1], "collide": false}, {"type": "ellipsoid", "mass": 0.01, "rgba": [0.35, 0.37, 0.42, 0.0], "friction": [1.0, 0.004, 0.0002], "contact": true, "size": [0.05, 0.012, 0.05], "render": false, "note": "crowned roller: point contact, true 24mm width"}], "note": "free-spinning 100mm knee roller: the robot sits on these"}]}]}]}, "actuators": [{"name": "l_hip_a", "joint": "l_hip", "mode": "position", "kp": 180.0, "kv": 9.0, "motor": "D5050", "gear_ratio": 5.088, "action_scale": 0.7}, {"name": "l_knee_a", "joint": "l_knee", "mode": "position", "kp": 180.0, "kv": 9.0, "motor": "D5050", "gear_ratio": 5.088, "action_scale": 0.7}, {"name": "r_hip_a", "joint": "r_hip", "mode": "position", "kp": 180.0, "kv": 9.0, "motor": "D5050", "gear_ratio": 5.088, "action_scale": 0.7}, {"name": "r_knee_a", "joint": "r_knee", "mode": "position", "kp": 180.0, "kv": 9.0, "motor": "D5050", "gear_ratio": 5.088, "action_scale": 0.7}, {"name": "l_wheel_a", "joint": "l_wheel_j", "mode": "torque", "motor": "DD-4125", "gear_ratio": 1.0, "ctrl_range": [-1.4, 1.4], "force_range": [-1.4, 1.4]}, {"name": "r_wheel_a", "joint": "r_wheel_j", "mode": "torque", "motor": "DD-4125", "gear_ratio": 1.0, "ctrl_range": [-1.4, 1.4], "force_range": [-1.4, 1.4]}], "sensors": [{"name": "gyro", "type": "gyro", "site": "imu", "rate_hz": 200, "noise": 0.005, "bias": 0.02, "in_obs": true, "part": "MPU-6050", "note": "gyro, +-500 deg/s range"}, {"name": "accel", "type": "accelerometer", "site": "imu", "rate_hz": 200, "noise": 0.25, "bias": 0.05, "in_obs": true, "scale": 0.1, "part": "MPU-6050", "note": "accel, +-4g. noise dominated by chassis vibration, not the part"}, {"name": "mag", "type": "magnetometer", "site": "imu", "rate_hz": 100, "noise": 0.03, "bias": 0.08, "in_obs": true, "scale": 1.0, "part": "9-DoF IMU magnetometer", "motor_coupling": 0.35, "note": "hard/soft-iron plus motor interference; heading only, useless for tilt"}, {"name": "l_hip_pos", "type": "jointpos", "joint": "l_hip", "rate_hz": 500, "noise": 0.003, "bias": 0.004, "in_obs": true}, {"name": "l_knee_pos", "type": "jointpos", "joint": "l_knee", "rate_hz": 500, "noise": 0.003, "bias": 0.004, "in_obs": true}, {"name": "r_hip_pos", "type": "jointpos", "joint": "r_hip", "rate_hz": 500, "noise": 0.003, "bias": 0.004, "in_obs": true}, {"name": "r_knee_pos", "type": "jointpos", "joint": "r_knee", "rate_hz": 500, "noise": 0.003, "bias": 0.004, "in_obs": true}, {"name": "l_hip_vel", "type": "jointvel", "joint": "l_hip", "rate_hz": 500, "noise": 0.05, "in_obs": true, "scale": 0.1}, {"name": "l_knee_vel", "type": "jointvel", "joint": "l_knee", "rate_hz": 500, "noise": 0.05, "in_obs": true, "scale": 0.1}, {"name": "r_hip_vel", "type": "jointvel", "joint": "r_hip", "rate_hz": 500, "noise": 0.05, "in_obs": true, "scale": 0.1}, {"name": "r_knee_vel", "type": "jointvel", "joint": "r_knee", "rate_hz": 500, "noise": 0.05, "in_obs": true, "scale": 0.1}, {"name": "l_wheel_vel", "type": "jointvel", "joint": "l_wheel_j", "rate_hz": 500, "noise": 0.1, "in_obs": true, "scale": 0.05}, {"name": "r_wheel_vel", "type": "jointvel", "joint": "r_wheel_j", "rate_hz": 500, "noise": 0.1, "in_obs": true, "scale": 0.05}, {"name": "l_touch", "type": "touch", "site": "l_foot", "rate_hz": 200, "in_obs": false}, {"name": "r_touch", "type": "touch", "site": "r_foot", "rate_hz": 200, "in_obs": false}], "init": {"qpos": {"l_hip": 0.4363, "l_knee": -0.8727, "r_hip": 0.4363, "r_knee": -0.8727}, "noise": {"joint": 0.05, "base_z": 0.01, "base_rpy": 0.05, "base_vel": 0.05}}, "task": {"type": "balance_and_drive", "target_height": 0.425, "command": {"vx_range": [-0.6, 0.6], "wz_range": [-1.0, 1.0], "resample_s": 4.0}, "episode_s": 12.0, "terminate": {"max_tilt_deg": 55, "min_height": 0.255}, "reward": {"alive": 1.0, "upright": 2.0, "height": 8.0, "track_vx": 1.5, "track_wz": 0.6, "torque": 0.0015, "action_rate": 0.02, "joint_nominal": 0.3, "yaw_drift": 0.2}}, "domain_randomisation": {"enabled": true, "mass_scale": [0.85, 1.15], "com_offset": 0.012, "friction_scale": [0.6, 1.4], "actuator_gain_scale": [0.85, 1.15], "latency_steps": [0, 3], "push": {"every_s": 3.0, "impulse": [0.0, 1.0]}}, "motors": {"D5050": {"kv": 300, "voltage": 24, "rated_torque": 1.2, "max_torque": 2.4, "rated_w": 650, "max_w": 1300, "mass": 0.305, "efficiency": 0.94, "note": "50x50mm, 14 pole, 12-36V. 0.94 covers one gear mesh plus one belt."}, "DD-4125": {"kv": 300, "voltage": 22.2, "no_load_current_a": 1.5, "rated_current_a": 18.5, "rated_w": 470, "no_load_rpm": 6480, "mass": 0.305, "efficiency": 1.0, "kt_nm_per_a": 0.0276, "rated_torque": 0.47, "max_torque": 1.4, "note": "peak is DRIVER-limited, not motor-limited. Set the FOC current limit to ~50A burst so the hardware matches. Tried 2:1 gearing and reverted it: a balancing robot's acceleration is its LEAN (a = g*tan(lean)), not its torque, so double the torque changed 0-0.8 m/s by 0.03s. It also doubled the control loop gain and made the robot chatter at full torque."}}, "estimator": {"enabled": true, "type": "fused", "note": "BNO055/BNO085-class chip outputs fused orientation directly", "tilt_noise_deg": 0.4, "tilt_drift_deg": 1.0, "heading_noise_deg": 1.5, "heading_drift_deg": 3.0, "motor_coupling_deg": 6.0, "rate_hz": 100, "latency_ms": 10}, "poses": {"sit": {"l_hip": -0.5235987755982988, "l_knee": 2.356194490192345, "r_hip": -0.5235987755982988, "r_knee": 2.356194490192345, "note": "rollers+wheels down, chassis 200mm, knee 0.26Nm, wheels only 80mm from the mass"}, "stand": {"l_hip": 0.0, "l_knee": 0.0, "r_hip": 0.0, "r_knee": 0.0, "note": "legs straight: zero knee torque, tallest, easiest to balance"}, "crouch": {"l_hip": 0.4363, "l_knee": -0.8727, "r_hip": 0.4363, "r_knee": -0.8727, "note": "working stance with travel in hand"}}}