Problem Statement:
I am developing support for a new sensor module that combines both differential pressure (airspeed) and static pressure (baro) sensing with an onboard MCU. The sensor outputs a single 56-byte packet containing all measurements via I2C. Current architecture requires separate drivers in AP_Airspeed and AP_Baro, which creates challenges for:
- Coordinated access to the shared I2C device
- Maintaining data consistency between modules
- Managing different update rate requirements
Proposed Solution:
Create a new parent driver architecture with the following components:
- New Library:
AP_I2C_Sensors
(orAP_CombinedSensors
)
- Location:
libraries/AP_I2C_Sensors/
- Contains
AP_IADP_Singular
as a singleton managing the physical sensor
- Parent Driver Features:
- Implements single periodic callback (50Hz)
- Handles all I2C communication
- Parses complete sensor packet
- Provides thread-safe data access methods
- Supports different effective update rates for children
- Child Drivers:
AP_Airspeed_IADP
: Gets differential pressure (50Hz)AP_Baro_IADP
: Gets static pressure/temperature (10Hz)
Technical Benefits:
- Clean Architecture: Separation of hardware access from sensor-specific logic
- Thread Safety: Single point of synchronization
- Efficiency: No duplicate I2C transactions
- Maintainability: Changes isolated to one driver
- Flexibility: Adaptable to similar combined sensors
Implementation Details:
- New files:
libraries/AP_I2C_Sensors/AP_IADP_Singular.{h,cpp}
- Modified files:
- Child drivers in AP_Airspeed and AP_Baro
- Build system updates
Request for Feedback:
- Is the proposed library location appropriate?
- Any concerns about the singleton pattern for hardware access?
- Has anyone implemented a singleton/shared proxy backend that provides data to multiple ArduPilot frontend modules?
- Is there a preferred pattern for this? (e.g., global registration, proxy routing, HAL device sharing?)
- Should I manage my own static instance of the backend, or hook it in via a dedicated sensor manager?
Example Usage:
// Parent driver
auto sensor = AP_IADP_Singular::get_instance();
sensor->init(bus, address);
// Airspeed child
float diff_press;
sensor->get_differential_pressure(diff_press);
// Baro child
float static_press, temp;
sensor->get_static_pressure(static_press);
sensor->get_temperature(temp);
Cheers,
Theodosis