Video summary

06252021 Lawn Tractor Meeting

Main summary

Key takeaways

Technology

High-level project

  • Goal: verify and calibrate steering / rotational-velocity measurements on an autonomous lawn tractor using multiple sensors, then use that to command precise steering (target turn diameter) via Ackermann steering commands.
  • Approach: compare rotational velocity from three independent sources — wheel odometry, IMU gyroscope, and GPS-derived heading — and use ROS tooling (rosbag, topics, PlotJuggler) to validate and calibrate the system.

Sensor sources and processing (what Jeff did)

Wheel odometry

  • Encoders on the two rear wheels produce standard nav_msgs/Odometry (position, orientation quaternion, Twist.linear.x, Twist.angular.z).
  • Pitfall: the Odometry message does not contain a direct “heading” field — orientation is stored as a quaternion and via TF. Plotting a quaternion component as if it were yaw produced misleading results.
  • Vulnerable to wheel slip (dry/slick grass), axle articulation, and wheels leaving the ground at different times. These effects can cause incorrect forward speed and rotational data, especially at higher speeds.

IMU gyroscope (SparkFun / other IMU boards)

  • Jeff read raw gyroscope output (deg/s) directly from a SparkFun board that printed ASCII lines, bypassing full sensor fusion.
  • Implemented a ROS Python node to parse ASCII, convert deg/s → rad/s, and publish as a Float32 topic for plotting and comparison.
  • Rationale: avoid opaque or noisy black-box IMU fusion and obtain a direct rotational-velocity reference.

GPS / u‑blox nav messages

  • Used u-blox nav_pvt/static heading and navsat-derived velocity vector (navsat_fix_velocity) as another rotational/velocity source.
  • GPS velocities arrived in varying units (e.g., mm/s), requiring mapping/scaling.
  • Implemented a ROS node to convert static heading (0–360°) deltas into rotational velocity; needed special handling for wrap/rollover at the 0↔360 boundary.
  • Observed that the static heading field is often the cleanest GPS-derived heading.

Tools, logging and visualization

  • rosbag to record runs and PlotJuggler for realtime/topic plotting.
    • PlotJuggler ignores string topics; Jeff converted raw ASCII string outputs into numeric ROS topics for plotting.
  • Used a bag→CSV per-topic export tool for offline analysis in Excel.
  • Excel used to handle wrap-around and compute deltas/rotational velocities when needed.

Key findings and calibration workflow

  • After parsing and unit/scale fixes, gyroscope and odometry rotational velocities matched closely under controlled (slow, low-slip) conditions.
  • Wheel slip on dry grass caused odometry to overestimate forward speed (encoders spun). Recommendation: limit speed (Jeff kept it under ~0.8–1.0 m/s) to avoid slipping and obtain reliable odometry.
  • Geometric observation: full-left steering produced ~2 m diameter circle. This is useful for computing steering angles and validating control.
  • Calibration plan:
    1. Use a converter node (planner or external) that converts desired rotational velocity (ω) into an Ackermann steering angle using wheelbase and track parameters.
    2. Command a known forward speed and ω (e.g., 1 m/s, 1 rad/s) to compute and apply a steering angle.
    3. Measure actual rotation from wheel odometry, IMU gyro, and GPS; adjust a single scale factor until commanded vs measured rotational velocities match.

Implementation notes & workarounds

  • IMU selection / drivers:
    • SparkFun “razor” style boards are convenient if they provide ASCII-printed raw values.
    • Other IMUs (Adafruit, Tinkerforge) often require I²C reads and applying scale factors to raw binary; check available ROS drivers — some publish raw gyro topics.
  • Normalize units early: deg ↔ rad, mm/s ↔ m/s, etc., to avoid confusion.
  • Heading wrap-around (0–360°) must be handled when computing deltas: detect large jumps and adjust by ±360° before differentiating; avoid sampling across the wrap boundary when possible.

Practical tutorials / troubleshooting guidance

Publish raw gyroscope as a ROS numeric topic

  • Read device output (ASCII or I²C registers), parse gyro value in deg/s.
  • Convert deg/s → rad/s and publish as a Float32 topic for plotting and downstream use.

Plotting and logging

  • Record runs with rosbag and visualize with PlotJuggler.
  • If data is stored as strings, parse into numeric topics or export per-topic CSV for Excel analysis.

Steering / steering-angle calibration

  • Use a rotational-velocity → Ackermann-angle converter (planner-provided or external) with correct wheelbase/track width.
  • Command known v and ω to compute target steering angle; apply to vehicle and tune a scale factor so the vehicle follows the requested circle.

Joystick → motor control (Bob’s troubleshooting)

  • Power joystick potentiometer from correct reference (e.g., 3.3V on Teensy) to match ADC reference and avoid exceeding pin ratings.
  • Read analog (e.g., analogRead 0–1023). Mechanical travel may yield a sub-range (e.g., 300–800).
  • Subtract center reading to get signed range (e.g., −150..+150).
  • Apply a deadband around zero (e.g., ±10) to prevent drift.
  • Map signed range to a control range (e.g., −100..+100).
  • Implement motorPower(value):
    • Use sign for direction bit (forward/reverse).
    • Map magnitude 0..100 to PWM 0..255.
    • Output direction and PWM to motor driver.
  • For steering with a linear actuator: use position control (not open-loop velocity). Add a potentiometer or steering-angle sensor and implement a simple closed-loop controller to move actuator to the commanded position.
  • Teensy-specific: analogResolution can increase ADC bit depth (e.g., 12 bits) if higher resolution is required.

Radio / remote control tips

  • Adafruit Feather LoRa boards are viable; either stack Feather boards or use a small wired radio module to the microcontroller.
  • Start with vendor libraries and example “hello world” packet transfers before integrating joystick/motor logic.
  • Consider IO-pin counts (Teensy 3.2 vs 3.5) when choosing between stacking boards or wiring small modules.

CNC / real-time control discussion (Christian)

  • Traditional LinuxCNC-style systems often require older x86 hardware or a real-time Linux kernel; modern OS power-saving and thermal throttling can break timing.
  • Raspberry Pi 4 can be a modern alternative for some setups; performance varies (step rates ~20 kHz reported depending on configuration).
  • Mesa FPGA boards can offload low-level motion/step generation over Ethernet and greatly improve determinism. They handle stepping/encoder logic; higher-level motion and PID can still run on a host with real-time extensions.

Tools, hardware and libraries mentioned

  • Software: ROS, rosbag, PlotJuggler
  • IMUs: SparkFun Razor (example firmware), Adafruit IMU, Tinkerforge
  • GPS: u-blox F9P (nav_pvt static heading), navsat_fix messages
  • Microcontrollers / radios: Teensy (3.2, 3.5), Adafruit Feather LoRa
  • Offline analysis: Excel, CSV export utilities
  • Steering: Ackermann steering messages / planner converters (Jeff referenced an existing node that converts ω to steering angle; planner integrations such as teb_local_planner may be relevant)

Common pitfalls called out

  • Confusing Odometry quaternion fields with heading — extract yaw properly from the quaternion or TF.
  • Unit mismatches and scaling (deg ↔ rad, mm/s ↔ m/s) are common — normalize units early.
  • Heading wrap-around producing huge deltas when differentiating — detect and correct wrap or ignore samples across the boundary.
  • String topics in rosbag are not directly plottable — convert to numeric topics.
  • Wheel slip, varying ground contact, and vehicle articulation produce odometry errors; slow speeds and sensor-fusion checks help.
  • IMU full fusion may obscure issues — raw gyro readings can be simpler and more reliable for rotational rate.

Next steps (Jeff)

  • Finalize a robust node to convert GPS heading → rotational velocity with wrap/large-delta protection.
  • Run the calibration loop: command ω → get steering angle → send to vehicle → measure actual rotation with all three sensors and tune the final scale factor until actual ≈ commanded.
  • Re-run outdoor tests with rosbag capturing all three sources and plot together for validation.

Main speakers / sources

  • Jeff — primary presenter (ROS, sensors, calibration, plotting workflow)
  • Bob — joystick and motor-control troubleshooting (Teensy, potentiometer/joystick, motor driver)
  • Christian — CNC / real-time control discussion (LinuxCNC, Raspberry Pi 4, Mesa boards)
  • Others referenced: Javier, Matt, Juan, Al, Roger (moderation/comments)

No further action.

Original video