Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Solver configuration passed to `Kinematics`. All fields have defaults.
| `diag_reg` | `0.0` | QP diagonal regularization |
| `dt` | `0.1` | Integration timestep per iteration |
| `max_iters` | `5` | IK iterations per solve |
| `velocity_limits` | `None` | Per-joint velocity limits (applied in rad/s from `config.py`); `None` = disabled |

Build from CLI args with `register_ik_args` + `ik_params_from_args`:

Expand Down
2 changes: 1 addition & 1 deletion src/openarm_control/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"geom": mujoco.mjtObj.mjOBJ_GEOM,
}

# Per-arm-joint velocity caps in rad/s at --vel-scale=1.0
# Per-arm-joint velocity caps in rad/s. Enabled via --limit-velocity.
ARM_JOINT_VELOCITY_LIMITS_RAD_S: list[float] = [
1.57, # joint1 DM 8009
1.57, # joint2 DM 8009
Expand Down
13 changes: 6 additions & 7 deletions src/openarm_control/kinematics.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,26 +316,25 @@ def register_ik_args(parser: argparse.ArgumentParser) -> None:
help="QP diagonal regularization (default: 0.0)",
)
parser.add_argument(
"--vel-scale",
type=float,
default=None,
help="Scale velocity limit safety. 1=90deg/s for shoulder. Unset = VelocityLimit disabled.",
"--limit-velocity",
action="store_true",
help="Enable per-joint velocity limits (caps in config.ARM_JOINT_VELOCITY_LIMITS_RAD_S).",
)
parser.add_argument(
"--tick-hz",
type=float,
default=500.0,
help="Dora tick rate in Hz; used only for --vel-scale unit conversion",
help="Dora tick rate in Hz; must match the dataflow timer (default: 500.0).",
)


def ik_params_from_args(args: argparse.Namespace) -> IKParams:
"""Build IKParams from parsed args (requires register_ik_args to have been called)."""
velocity_limits: dict[str, float] | None = None
if args.vel_scale is not None:
if args.limit_velocity:
velocity_limits = {
f"openarm_{side}_joint{i + 1}": _convert_velocity(
rad_per_sec=v * args.vel_scale,
rad_per_sec=v,
dt=args.dt,
max_iters=args.max_iters,
tick_hz=args.tick_hz,
Expand Down