♻️ crazy refactor

This commit is contained in:
2026-03-11 22:52:01 +01:00
parent 35223b3560
commit 4115447022
34 changed files with 4255 additions and 102 deletions

View File

@@ -0,0 +1,23 @@
# Rotary cartpole (Furuta pendulum) — real hardware config.
# Describes the physical device for the SerialRunner.
# Robot-specific constants that don't belong in the runner config
# (which is machine-specific: port, baud) or the env config
# (which is task-specific: rewards, max_steps).
encoder:
ppr: 11 # pulses per revolution (before quadrature)
gear_ratio: 30.0 # gearbox ratio
# counts_per_rev = ppr × gear_ratio × 4 (quadrature) = 1320
safety:
max_motor_angle_deg: 90.0 # hard termination limit (0 = disabled)
soft_limit_deg: 40.0 # progressive penalty ramp starts here
reset:
drive_speed: 80 # PWM magnitude for bang-bang drive-to-center
deadband: 15 # encoder count threshold to consider "centered"
drive_timeout: 3.0 # seconds before giving up on drive-to-center
settle_angle_deg: 2.0 # pendulum angle threshold for "still" (degrees)
settle_vel_dps: 5.0 # pendulum velocity threshold (deg/s)
settle_duration: 0.5 # how long pendulum must stay still (seconds)
settle_timeout: 30.0 # give up waiting after this (seconds)

View File

@@ -1,19 +1,20 @@
# Rotary cartpole (Furuta pendulum) — robot hardware config.
# Lives next to the URDF so all robot-specific settings are in one place.
# Tuned robot config — generated by src.sysid.optimize
# Original: robot.yaml
# Run `python -m src.sysid.visualize` to compare real vs sim.
urdf: rotary_cartpole.urdf
actuators:
- joint: motor_joint
type: motor # direct torque control
gear: 0.064 # stall torque @ 58.8% PWM: 0.108 × 150/255 = 0.064 N·m
ctrl_range: [-1.0, 1.0]
damping: 0.003 # viscous back-EMF only (small)
filter_tau: 0.03 # mechanical time constant ~30ms (37mm gearmotor)
- joint: motor_joint
type: motor
gear: 0.176692
ctrl_range:
- -1.0
- 1.0
damping: 0.009505
filter_tau: 0.040906
joints:
motor_joint:
armature: 0.0001 # reflected rotor inertia: ~1e-7 × 30² = 9e-5 kg·m²
frictionloss: 0.03 # disabled — may slow MJX (constraint-based solver)
armature: 0.001389
frictionloss: 0.002179
pendulum_joint:
damping: 0.0001 # bearing friction
damping: 6.1e-05

View File

@@ -1,106 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version='1.0' encoding='utf-8'?>
<robot name="rotary_cartpole">
<!-- Fixed world frame -->
<link name="world"/>
<!-- Base: motor housing, fixed to world -->
<link name="world" />
<link name="base_link">
<inertial>
<origin xyz="-0.00011 0.00117 0.06055" rpy="0 0 0"/>
<mass value="0.921"/>
<inertia ixx="0.002385" iyy="0.002484" izz="0.000559"
ixy="0.0" iyz="-0.000149" ixz="6e-06"/>
<origin xyz="-0.00011 0.00117 0.06055" rpy="0 0 0" />
<mass value="0.921" />
<inertia ixx="0.002385" iyy="0.002484" izz="0.000559" ixy="0.0" iyz="-0.000149" ixz="6e-06" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<mesh filename="meshes/base_link.stl" scale="0.001 0.001 0.001"/>
<mesh filename="meshes/base_link.stl" scale="0.001 0.001 0.001" />
</geometry>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<mesh filename="meshes/base_link.stl" scale="0.001 0.001 0.001"/>
<mesh filename="meshes/base_link.stl" scale="0.001 0.001 0.001" />
</geometry>
</collision>
</link>
<joint name="base_joint" type="fixed">
<parent link="world"/>
<child link="base_link"/>
<parent link="world" />
<child link="base_link" />
</joint>
<!-- Arm: horizontal rotating arm driven by motor.
Real mass ~10g (Fusion assumed dense material, exported 279g). -->
<link name="arm">
<inertial>
<origin xyz="0.00005 0.0065 0.00563" rpy="0 0 0"/>
<mass value="0.010"/>
<inertia ixx="2.70e-06" iyy="7.80e-07" izz="2.44e-06"
ixy="0.0" iyz="7.20e-08" ixz="0.0"/>
<origin xyz="0.014950488360794875 0.006089886527968399 0.004470745447817278" rpy="0 0 0" />
<mass value="0.012391951282440451" />
<inertia ixx="2.70e-06" iyy="7.80e-07" izz="2.44e-06" ixy="0.0" iyz="7.20e-08" ixz="0.0" />
</inertial>
<visual>
<origin xyz="0.006947 -0.00395 -0.14796" rpy="0 0 0"/>
<origin xyz="0.006947 -0.00395 -0.14796" rpy="0 0 0" />
<geometry>
<mesh filename="meshes/arm_1.stl" scale="0.001 0.001 0.001"/>
<mesh filename="meshes/arm_1.stl" scale="0.001 0.001 0.001" />
</geometry>
</visual>
<collision>
<origin xyz="0.006947 -0.00395 -0.14796" rpy="0 0 0"/>
<origin xyz="0.006947 -0.00395 -0.14796" rpy="0 0 0" />
<geometry>
<mesh filename="meshes/arm_1.stl" scale="0.001 0.001 0.001"/>
<mesh filename="meshes/arm_1.stl" scale="0.001 0.001 0.001" />
</geometry>
</collision>
</link>
<!-- Motor joint: base → arm, rotates around vertical z-axis -->
<joint name="motor_joint" type="revolute">
<origin xyz="-0.006947 0.00395 0.14796" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="arm"/>
<axis xyz="0 0 1"/>
<limit lower="-1.5708" upper="1.5708" effort="10.0" velocity="200.0"/>
<dynamics damping="0.001"/>
<origin xyz="-0.006947 0.00395 0.14796" rpy="0 0 0" />
<parent link="base_link" />
<child link="arm" />
<axis xyz="0 0 1" />
<limit lower="-1.5708" upper="1.5708" effort="10.0" velocity="200.0" />
<dynamics damping="0.001" />
</joint>
<!-- Pendulum: swings freely at the end of the arm.
Real mass: 5g pendulum + 10g weight at the tip (70mm from bearing) = 15g total.
(Fusion assumed dense material, exported 57g for the pendulum alone.) -->
<link name="pendulum">
<inertial>
<!-- Combined CoM: 5g rod (CoM ~35mm) + 10g tip weight at 70mm from pivot.
Tip at (0.07, -0.07, 0) → 45° diagonal in +X/-Y.
CoM = (5×0.035+10×0.07)/15 = 0.0583 along both +X and -Y.
Inertia tensor rotated 45° to match diagonal rod axis. -->
<origin xyz="0.1583 -0.0983 -0.0" rpy="0 0 0"/>
<mass value="0.015"/>
<inertia ixx="6.16e-06" iyy="6.16e-06" izz="1.23e-05"
ixy="6.10e-06" iyz="0.0" ixz="0.0"/>
<origin xyz="0.06432778588634695 -0.05999895841669392 0.0008769789937631209" rpy="0 0 0" />
<mass value="0.035508993892747365" />
<inertia ixx="3.139576982078822e-05" iyy="9.431951659638859e-06" izz="4.07315891863556e-05" ixy="-1.8892943833253423e-06" iyz="0.0" ixz="0.0" />
</inertial>
<visual>
<origin xyz="0.006895 -0.023224 -0.162953" rpy="0 0 0"/>
<origin xyz="0.006895 -0.023224 -0.162953" rpy="0 0 0" />
<geometry>
<mesh filename="meshes/pendulum_1.stl" scale="0.001 0.001 0.001"/>
<mesh filename="meshes/pendulum_1.stl" scale="0.001 0.001 0.001" />
</geometry>
</visual>
<collision>
<origin xyz="0.006895 -0.023224 -0.162953" rpy="0 0 0"/>
<origin xyz="0.006895 -0.023224 -0.162953" rpy="0 0 0" />
<geometry>
<mesh filename="meshes/pendulum_1.stl" scale="0.001 0.001 0.001"/>
<mesh filename="meshes/pendulum_1.stl" scale="0.001 0.001 0.001" />
</geometry>
</collision>
</link>
<!-- Pendulum joint: arm → pendulum, bearing axis along Y.
Joint origin corrected from mesh analysis (Fusion2URDF was 180mm off).
rpy pitch +90° so qpos=0 = pendulum hanging down (gravity-stable). -->
<joint name="pendulum_joint" type="continuous">
<origin xyz="0.000052 0.019274 0.014993" rpy="0 1.5708 0"/>
<parent link="arm"/>
<child link="pendulum"/>
<axis xyz="0 -1 0"/>
<dynamics damping="0.0001"/>
<origin xyz="0.000052 0.019274 0.014993" rpy="0 1.5708 0" />
<parent link="arm" />
<child link="pendulum" />
<axis xyz="0 -1 0" />
<dynamics damping="0.0001" />
</joint>
</robot>
</robot>

View File

@@ -0,0 +1,70 @@
{
"best_params": {
"arm_mass": 0.012391951282440451,
"arm_com_x": 0.014950488360794875,
"arm_com_y": 0.006089886527968399,
"arm_com_z": 0.004470745447817278,
"pendulum_mass": 0.035508993892747365,
"pendulum_com_x": 0.06432778588634695,
"pendulum_com_y": -0.05999895841669392,
"pendulum_com_z": 0.0008769789937631209,
"pendulum_ixx": 3.139576982078822e-05,
"pendulum_iyy": 9.431951659638859e-06,
"pendulum_izz": 4.07315891863556e-05,
"pendulum_ixy": -1.8892943833253423e-06,
"actuator_gear": 0.17669161390939517,
"actuator_filter_tau": 0.040905643692382504,
"motor_damping": 0.009504542103348917,
"pendulum_damping": 6.128535042404019e-05,
"motor_armature": 0.0013894759540138252,
"motor_frictionloss": 0.002179448047511452
},
"best_cost": 0.7471380533090072,
"recording": "/Users/victormylle/Library/CloudStorage/SeaDrive-VictorMylle(cloud.optimize-it.be)/My Libraries/Projects/AI/RL-Framework/assets/rotary_cartpole/recordings/capture_20260311_215608.npz",
"param_names": [
"arm_mass",
"arm_com_x",
"arm_com_y",
"arm_com_z",
"pendulum_mass",
"pendulum_com_x",
"pendulum_com_y",
"pendulum_com_z",
"pendulum_ixx",
"pendulum_iyy",
"pendulum_izz",
"pendulum_ixy",
"actuator_gear",
"actuator_filter_tau",
"motor_damping",
"pendulum_damping",
"motor_armature",
"motor_frictionloss"
],
"defaults": {
"arm_mass": 0.01,
"arm_com_x": 5e-05,
"arm_com_y": 0.0065,
"arm_com_z": 0.00563,
"pendulum_mass": 0.015,
"pendulum_com_x": 0.1583,
"pendulum_com_y": -0.0983,
"pendulum_com_z": 0.0,
"pendulum_ixx": 6.16e-06,
"pendulum_iyy": 6.16e-06,
"pendulum_izz": 1.23e-05,
"pendulum_ixy": 6.1e-06,
"actuator_gear": 0.064,
"actuator_filter_tau": 0.03,
"motor_damping": 0.003,
"pendulum_damping": 0.0001,
"motor_armature": 0.0001,
"motor_frictionloss": 0.03
},
"timestamp": "2026-03-11T22:08:04.782736",
"history_summary": {
"first_cost": 3.909456214944022,
"final_cost": 0.7471380533090072,
"generations": 200
}
}