Skip to content

Improve arm control with IK validation, synchronized movements, and vision tracking#3

Open
williankeller wants to merge 11 commits intomainfrom
claude/improve-arm-movements-igJP8
Open

Improve arm control with IK validation, synchronized movements, and vision tracking#3
williankeller wants to merge 11 commits intomainfrom
claude/improve-arm-movements-igJP8

Conversation

@williankeller
Copy link
Copy Markdown
Owner

Summary

This PR significantly enhances the robotic arm control system by adding inverse kinematics validation, implementing synchronized multi-joint movements, improving vision-based tracking with proportional control and smoothing, and refactoring servo control with easing functions.

Key Changes

Inverse Kinematics & Safety

  • Added reachability validation to solveRZ() - now returns bool to indicate if target position is achievable
  • Prevents invalid asin() calls by checking if the ratio is within [-1.0, 1.0] bounds
  • Added PI definition guard to prevent redefinition conflicts

Synchronized Joint Movement

  • Introduced moveJointsSynchronized() function to move multiple joints simultaneously with coordinated timing
  • All joints start and finish together, producing natural coordinated motion
  • Uses the longest travel distance to maintain 1° resolution across all joints
  • Refactored moveInitialPosition() and grab() sequences to use synchronized movements with clear phase comments

Servo Control Improvements

  • Enhanced setServoPosition() with configurable step delay and smooth easing
  • Implemented smoothStep() S-curve easing function for natural acceleration/deceleration
  • Improved logging output format for better readability

Vision Tracking Enhancements

  • Replaced hard-coded threshold logic with configurable constants (dead bands, smoothing factor, frame center)
  • Implemented proportional control for horizontal and vertical tracking with dead bands
  • Added exponential smoothing (0.15 factor) for fluid, responsive motion
  • Changed tracking variables from int to float for sub-degree precision
  • Improved distance calculation and depth-based adjustments

Cartesian Trajectory Interpolation

  • Implemented moveToPosition() with linear Cartesian space interpolation (10 waypoints)
  • Tracks last position to enable smooth straight-line end-effector paths
  • Validates each interpolated waypoint using IK reachability check
  • Falls back to direct movement on first call

Code Quality

  • Fixed gripper control bug: changed else if (value == 1) to else if (value == 0) for open command
  • Fixed position parsing: corrected comma indices for proper x,y,z,gripAngle extraction
  • Added F() macro for string literals to reduce RAM usage
  • Improved comments and documentation throughout

Implementation Details

  • Vision tracking now uses direct servo writes for responsive feedback during tracking
  • Synchronized movements use the same easing function as individual servo moves for consistency
  • All angle constraints are applied at the servo level to prevent out-of-bounds writes
  • Trajectory interpolation validates reachability at each step and gracefully handles unreachable positions

claude added 11 commits January 26, 2026 18:17
Phase 1 - Bug fixes:
- Fix gripper serial command: openGripper() was unreachable (duplicate value==1 check)
- Fix moveToPosition(): remove incorrect angle accumulation that double-counted
  current servo positions and added erroneous +2 offsets
- Fix position command parsing: z and gripAngle were parsing the same substring
- Add IK reachability validation: solveRZ() now returns bool and checks asin bounds
  to prevent NaN propagation from unreachable positions
- Add PI macro guard to prevent redefinition warnings

Phase 2 - Smooth motion:
- Replace linear interpolation with smoothStep easing (S-curve) in setServoPosition()
  for natural acceleration/deceleration instead of constant-velocity jerky starts/stops
- Add configurable stepDelayMs parameter for variable movement speeds

Phase 3 - Coordinated multi-joint movement:
- Add moveJointsSynchronized() for simultaneous multi-servo motion with easing,
  normalizing travel times so all joints start and finish together
- Update moveInitialPosition() to move all 5 joints simultaneously
- Rewrite grab() sequence with synchronized multi-joint phases instead of
  sequential single-servo moves

Phase 4 - Cartesian trajectory interpolation:
- moveToPosition() now interpolates through 10 waypoints in Cartesian space,
  solving IK at each point, producing straight-line end-effector paths instead
  of arc-shaped joint-space paths
- Track last commanded position for trajectory continuity between moves

Phase 5 - Vision tracking smoothing:
- Replace fixed-step increments with proportional control based on pixel error
- Add exponential moving average filter (alpha=0.15) for fluid tracking motion
- Add dead band thresholds to eliminate jitter near center
- Use float precision for sub-degree position tracking
- Write servos directly during tracking (skip easing for small continuous moves)
- Wrap string literals in F() macro to reduce SRAM usage

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
- Make HuskyLens initialization non-blocking: tries 3 times on boot,
  then continues in manual mode if not found. Servos attach first so
  the arm is functional immediately regardless of HuskyLens state.
- Add 'tracking on|off' serial command to enable/disable auto tracking
  at runtime. 'tracking on' retries HuskyLens connection if needed.
  'tracking off' returns arm to home position.
- Restructure loop() so serial commands are always processed first,
  independent of HuskyLens connection state.
- Extract command handling into handleCommand() and vision tracking
  into runVisionTracking() for cleaner separation.
- Add 'help' command listing all available serial commands.
- Add 'tracking' status query (send 'tracking' with no argument).
- Reset vision tracking positions on reset/tracking state changes.

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
Add command reference tables for joint control, sequences, IK
positioning, and vision tracking. Note that HuskyLens is optional
and the arm starts in manual mode by default.

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
Document servo pin assignments, default angles, power supply
requirements (6V/10A for MG996R servos), and HuskyLens I2C connection.

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
The wrist min was set to 89° which clamped grab() targets of 60° and
30° to 89°, preventing the gripper from tilting downward to reach
objects. Changed to 0° to match the physical clearance of the joint.

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
Revert wrist min angle back to 89° (straight position). The wrist
cannot physically go below 89° without twisting into the arm frame.
Update grab() sequence wrist targets from 60°/80°/30° to 89° so they
use the straightest valid position for reaching and dropping objects.

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
Higher wrist angles tilt the gripper downward (180° = fully down).
Updated grab() wrist targets to point gripper toward objects:
- Phase 1 (pre-grab): 150° moderate tilt down
- Phase 3 (reach): 170° near-full tilt to reach object
- Phase 6 (drop): 160° tilted down for releasing

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
Shoulder 50° was pushing the arm too far down, and elbow 160° exceeded
its physical max of 140° (clamped by constrain). Adjusted to shoulder
80°, elbow 130°, wrist 160° for a gentler reach at table level.

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
Replace elbow, wrist, and hand PWM servos with daisy-chained
LX-1501 bus servos using half-duplex serial protocol. Add teach
mode for recording and replaying arm positions by physically
moving the bus servos (torque disable + position readback).

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
The BusLinker handles half-duplex conversion between Arduino
full-duplex UART and the servo single-wire bus protocol. Servos
connect via PH2.0/3P daisy-chain cables to the BusLinker servo
interface.

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
Includes detailed specifications table (voltage, torque, speed,
current, accuracy, connector type) and notes the Hiwonder
BusLinker as the recommended controller board. Updated voltage
range to 6-8.4V per servo datasheet.

https://claude.ai/code/session_01DimPiPhcBhthiP8N3KucLK
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants