This document provides a comprehensive overview of the STM32 firmware for the self driving robot, including tunable parameters and important file descriptions.
| Role | Member |
|---|---|
| Android | Hilarius Jeremy |
| Image | Wu Chengrui |
| Algorithms | Zi Yuan |
| Algorithms | Andy |
| RPI | Joel |
| RPI | Siaw Xuan |
| STM | Dylan |
| STM | Karthik |
The following table lists all configurable parameters in the codebase:
| Parameter | Description | Location | Default Value |
|---|---|---|---|
| PID Control | |||
PID_KP |
Proportional gain for speed control PID | MDP/Core/Src/control.c:20 |
2.0f |
PID_KI |
Integral gain for speed control PID | MDP/Core/Src/control.c:21 |
0.5f |
PID_KD |
Derivative gain for speed control PID | MDP/Core/Src/control.c:22 |
0.01f |
PID_MAX_OUT |
Maximum PID output (PWM percent) | MDP/Core/Src/control.c:14 |
100.0f |
PID_MAX_IOUT |
Integral output clamp to prevent windup | MDP/Core/Src/control.c:15 |
40.0f |
PID_MAX_DOUT |
Derivative output clamp to reduce noise | MDP/Core/Src/control.c:16 |
40.0f |
CONTROL_DT_S |
PID control loop period (seconds) | MDP/Core/Src/control.c:11 |
0.01f |
| Motor Control | |||
MIN_MOTOR_SPEED_PERCENT |
Minimum PWM to overcome motor stiction | MDP/Core/Src/motor.c:13 |
54.0f |
| Movement System | |||
V_MAX_TICKS_PER_DT |
Maximum speed during cruise (ticks/10ms) | MDP/Core/Src/movements.c:22 |
24.0f |
V_MIN_TICKS_PER_DT |
Minimum speed to overcome friction | MDP/Core/Src/movements.c:23 |
4.0f |
YAW_KP_TICKS_PER_DEG |
Heading correction gain | MDP/Core/Src/movements.c:29 |
3.0f |
g_accel_dist_cm |
Acceleration distance (cm) | MDP/Core/Src/movements.c:16 |
10.0f |
g_decel_dist_cm |
Deceleration distance (cm) | MDP/Core/Src/movements.c:17 |
15.0f |
| Turn Control | |||
TURN_BASE_TICKS_PER_DT |
Base speed for turns (ticks/10ms) | MDP/Core/Src/movements.c:33 |
25 |
TURN_YAW_TARGET_DEG |
Target turn angle (degrees) | MDP/Core/Src/movements.c:34 |
90.0f |
TURN_YAW_TOLERANCE_DEG |
Turn completion tolerance | MDP/Core/Src/movements.c:35 |
0.5f |
TURN_YAW_SLOW_BAND_DEG |
Deceleration zone for turns | MDP/Core/Src/movements.c:36 |
10.0f |
TURN_MIN_TICKS_PER_DT |
Minimum turn speed | MDP/Core/Src/movements.c:37 |
4 |
g_turn_spinup_ticks |
Turn startup delay (100Hz ticks) | MDP/Core/Src/movements.c:39 |
100 |
| Turn Differential | |||
TURN_DEFAULT_PROFILE |
Default turn profile applied at startup | MDP/Core/Src/movements.c:45 |
MOVE_TURN_PROFILE_PRIMARY |
TURN_PROFILE_PRIMARY_STEER_MAG |
Servo command magnitude for primary turn profile | MDP/Core/Src/movements.c:46 |
90.9f |
TURN_PROFILE_PRIMARY_OUTER_RATIO |
Outer-wheel speed multiplier for primary turn profile | MDP/Core/Src/movements.c:47 |
1.759f |
TURN_PROFILE_SECONDARY_STEER_MAG |
Servo command magnitude for alternate turn profile | MDP/Core/Src/movements.c:49 |
100.0f |
TURN_PROFILE_SECONDARY_OUTER_RATIO |
Outer-wheel speed multiplier for alternate turn profile | MDP/Core/Src/movements.c:50 |
2.0f |
WHEEL_CIRC_CM |
Wheel circumference | MDP/Core/Src/movements.c:55 |
20.73f |
COUNTS_PER_REV |
Encoder counts per wheel revolution | MDP/Core/Src/movements.c:56 |
1560.0f |
| IMU Settings | |||
IMU_DT_S |
IMU update period (seconds) | MDP/Core/Src/imu.c:34 |
0.01f |
GZ_DEADBAND_DPS |
Gyro noise deadband (deg/s) | MDP/Core/Src/imu.c:37 |
0.4f |
| AHRS Filter | |||
s_beta |
Madgwick filter gain (convergence rate) | MDP/Core/Src/madgwick.c:8 |
0.1f |
s_dt |
Madgwick sample period (seconds) | MDP/Core/Src/madgwick.c:9 |
0.01f |
| Servo Configuration | |||
| Servo Min Pulse | Minimum servo pulse width (μs) | MDP/Core/Src/main.c:835 |
1050 |
| Servo Center Pulse | Center servo pulse width (μs) | MDP/Core/Src/main.c:835 |
1500 |
| Servo Max Pulse | Maximum servo pulse width (μs) | MDP/Core/Src/main.c:835 |
2600 |
| OLED Display | |||
| OLED Update Delay | Display refresh period (ms) | Various tasks in main.c |
100 |
Purpose: Implements the main speed control system using PID controllers for both wheels.
Key Functions:
control_init(): Initializes PID controllers with configured gains and limitscontrol_tick(): Main control loop called at 100 Hz, reads encoders and applies PID controlcontrol_set_target_ticks_per_dt(): Sets target speeds in encoder ticks per 10msHAL_TIM_PeriodElapsedCallback(): Timer interrupt handler that triggers control loop
Important Features:
- Dual PID controllers for independent left/right wheel speed control
- Encoder-based speed measurement using differential tick counting
- Configurable gains, output limits, and anti-windup protection
Purpose: Generic PID controller implementation with time-step awareness.
Key Functions:
PID_init_with_dt(): Initializes PID structure with gains, limits, and timestepPID_calc_with_dt(): Computes PID output with proper time scalingPID_clear(): Resets PID internal statePID_SPEED_1(),PID_SPEED_2(),PID_SPEED_T(): Specialized PID functions for different speed modes
Important Features:
- Time-step compensated integral and derivative terms
- Configurable output clamping for each PID component
- Support for multiple PID instances
Purpose: Low-level motor control with PWM generation and encoder reading.
Key Functions:
motor_init(): Initializes PWM channels and encoder timersmotor_set_speeds(): Sets motor speeds with deadzone compensationmotor_stop(): Immediately stops both motorsmotor_brake_ms(): Applies active braking for specified durationmotor_get_left_encoder_counts(),motor_get_right_encoder_counts(): Read raw encoder valuesmotor_reset_encoders(): Zeros encoder counters
Important Features:
- Automatic PWM scaling to overcome motor deadzone
- Independent left/right motor control
- Support for forward/reverse operation with proper H-bridge control
Purpose: Servo motor control for steering system.
Key Functions:
Servo_Attach(): Associates servo with timer channel and pulse width limitsServo_Start(),Servo_Stop(): Enable/disable servo PWM outputServo_WriteUS(): Sets servo position by pulse width in microsecondsServo_WriteAngle(): Sets servo position by angle (-100 to +100)Servo_Center(): Moves servo to center position
Important Features:
- Flexible pulse width mapping for different servo types
- Angle-based interface for intuitive steering control
- Automatic pulse width clamping for safety
Purpose: High-level movement primitives with trajectory planning and IMU feedback.
Key Functions:
move_start_straight(): Initiates straight-line movement with trapezoidal velocity profilemove_start_turn(): Initiates Ackermann steering turns with IMU feedbackmove_tick_100Hz(): Main movement state machine, called at 100 Hzmove_abort(): Emergency stop functionmove_is_active(): Returns movement status
Important Features:
- Trapezoidal velocity profiles for smooth acceleration/deceleration
- IMU-based heading correction for straight-line driving
- Ackermann steering model for realistic turning behavior
- Configurable motion parameters for different robot configurations
Purpose: IMU sensor interface with gyroscope integration and magnetometer support.
Key Functions:
imu_init(): Initializes IMU sensor and calibrates gyroscope biasimu_update_yaw_100Hz(): Integrates gyroscope data to estimate headingimu_get_yaw(): Returns current heading estimateimu_zero_yaw(): Resets heading referenceimu_calibrate_mag_*(): Magnetometer calibration functions
Important Features:
- Automatic gyroscope bias calibration on startup
- Continuous heading integration with wraparound handling
- Magnetometer calibration support for absolute heading
- Noise filtering and deadband processing
Purpose: Ultrasonic distance sensor interface using input capture.
Key Functions:
ultrasonic_init_ex(): Configures ultrasonic sensor on specified timerultrasonic_trigger(): Initiates distance measurementultrasonic_get_distance_cm(): Returns measured distanceHAL_TIM_IC_CaptureCallback(): Input capture interrupt handler
Important Features:
- Non-blocking distance measurement using timer input capture
- Automatic echo pulse width calculation
- Configurable trigger GPIO and capture timer
Purpose: OLED display driver for status information and debugging.
Key Functions:
OLED_Init(): Initializes OLED display hardwareOLED_Clear(): Clears display bufferOLED_ShowString(),OLED_ShowNumber(): Display text and numbersOLED_Refresh_Gram(): Updates physical display from buffer
Important Features:
- Buffered display updates for smooth rendering
- Text and numeric display functions
- SPI-based communication with display controller
Purpose: Simple user button interface for manual control.
Key Functions:
user_is_pressed(): Returns current button state
Important Features:
- Debounced button reading
- Used for manual movement control and testing
Purpose: Low-level driver for ICM20948 9-DOF IMU sensor.
Key Functions:
ICM20948_Init(): Initializes the ICM20948 sensor over I2CICM20948_ReadGyro(): Reads raw gyroscope data (deg/s)ICM20948_ReadAccel(): Reads raw accelerometer data (g)ICM20948_ReadMag(): Reads magnetometer data (μT)ICM20948_SetBank(): Switches register banks for configuration
Important Features:
- I2C communication with configurable address (0x68/0x69)
- Raw sensor data conversion to engineering units
- Multi-bank register interface for full feature access
- Configurable sample rates and sensitivity ranges
Purpose: Madgwick AHRS algorithm for sensor fusion and orientation estimation.
Key Functions:
madgwick_init(): Initializes filter with sample rate and gainmadgwick_update_imu(): Updates orientation using gyro/accel datamadgwick_get_euler(): Returns roll, pitch, yaw anglesmadgwick_get_quaternion(): Returns quaternion representation
Important Features:
- Gradient descent algorithm for orientation estimation
- Gyroscope drift compensation using accelerometer
- Configurable filter gain (
s_beta = 0.1f) for tuning convergence vs. noise - Quaternion-based calculations for singularity-free rotation handling
Tunable Parameters:
s_beta: Algorithm gain (higher = faster convergence, more noise sensitivity)s_dt: Sample period in seconds (should match IMU update rate)
Purpose: Main application entry point with hardware initialization and FreeRTOS tasks.
Key Tasks:
StartDefaultTask(): Main program logic (Await button press > Calibrate sensors > Perform instructions)control_task(): 100 Hz PID control for responsive speed regulationoled_task(): Handles OLED display
Important Features:
- Complete hardware peripheral initialization
- FreeRTOS task definitions for concurrent operation
- Timer configurations for PWM, encoders, and control loops
- Servo initialization with calibrated pulse widths
- Speed targets: Expressed as encoder ticks per 10ms control period
- PWM outputs: Percentage values from -100 to +100
- Distances: Centimeters for movement commands
- Angles: Degrees for heading and steering
- Start with conservative gains:
Kp=2.0,Ki=0.5,Kd=0.01 - Increase
Kpuntil system oscillates, then reduce by 20-30% - Add
Kito eliminate steady-state error (watch for integral windup) - Add small
Kdto reduce overshoot (watch for noise amplification) - Adjust
PID_MAX_IOUTandPID_MAX_DOUTto prevent excessive integral/derivative action
- Calibrate
WHEEL_CIRC_CMandCOUNTS_PER_REVfor accurate distance measurement - Adjust
V_MAX_TICKS_PER_DTandV_MIN_TICKS_PER_DTbased on motor characteristics - Tune
YAW_KP_TICKS_PER_DEGfor straight-line tracking (start low to avoid oscillation) - Set
g_accel_dist_cmandg_decel_dist_cmbased on desired motion smoothness
- Determine
MIN_MOTOR_SPEED_PERCENTby finding minimum PWM for reliable motor startup - Ensure motors can start reliably at this percentage
- Increase if motors stall, decrease if they start too aggressively
- Start with default
s_beta = 0.1ffor balanced performance - Increase
s_betafor faster convergence to true orientation (more noise sensitive) - Decrease
s_betafor smoother filtering (slower convergence) - Ensure
s_dtmatches actual IMU update rate for accurate integration
- Control Loop: 100 Hz PID control provides responsive speed regulation
- Movement Planning: High-level trajectory generation with sensor feedback
- Sensor Fusion: IMU and encoder data combined for accurate navigation (not used)
- Modular Design: Clear separation between low-level control and high-level planning
- Use OLED display to monitor real-time values during tuning
- Button-driven test sequences in
main.cfor systematic parameter testing - Encoder tick counts provide direct feedback on motion accuracy
- IMU heading values help diagnose turning and straight-line performance