ardupilot/libraries/AP_InertialSensor/AP_InertialSensor_Backend.h
Lucas De Marchi caae933c28 AP_InertialSensor: Add support for auxiliary buses
Add an AuxiliaryBus class that can be derived for specific
implementations in inertial sensor backends. It's an abstract
implementation so other libraries can use the auxiliary bus exported. In
order for this to succeed the backend implementation must split the
initialization of the sensor from the actual sample collecting, like is
done in MPU6000.

When AP_InertialSensor::get_auxiliary_bus() is called it will execute
following steps:
	a) Force the backends to be detected if it's the first time it's
	   being called
	b) Find the backend identified by the id
	c) call get_auxiliary_bus() on the backend so other libraries can
	   that AuxiliaryBus to initialize a slave device

Slave devices can be used by calling AuxiliaryBus::request_next_slave()
and are owned by the caller until AuxiliaryBus::register_periodic_read()
is called. From that time on the AuxiliaryBus object takes its ownership.
This way it's possible to do the necessary cleanup later without
introducing refcounts, that we don't have support to.

Between these 2 functions the caller can configure the slave device by
doing its specific initializations by calling the passthrough_*
functions. After the initial configuration and register_periodic_read()
is called only read() can be called.
2015-08-28 12:39:08 +10:00

129 lines
4.4 KiB
C++

// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
IMU driver backend class. Each supported gyro/accel sensor type
needs to have an object derived from this class.
Note that drivers can implement just gyros or just accels, and can
also provide multiple gyro/accel instances.
*/
#ifndef __AP_INERTIALSENSOR_BACKEND_H__
#define __AP_INERTIALSENSOR_BACKEND_H__
class AuxiliaryBus;
class AP_InertialSensor_Backend
{
public:
AP_InertialSensor_Backend(AP_InertialSensor &imu);
// we declare a virtual destructor so that drivers can
// override with a custom destructor if need be.
virtual ~AP_InertialSensor_Backend(void) {}
/*
* Update the sensor data. Called by the frontend to transfer
* accumulated sensor readings to the frontend structure via the
* _publish_gyro() and _publish_accel() functions
*/
virtual bool update() = 0;
/*
* return true if at least one accel sample is available in the backend
* since the last call to update()
*/
virtual bool accel_sample_available() = 0;
/*
* return true if at least one gyro sample is available in the backend
* since the last call to update()
*/
virtual bool gyro_sample_available() = 0;
/*
* Configure and start all sensors. The empty implementation allows
* subclasses to already start the sensors when it's detected
*/
virtual void start() { }
/*
* Return an AuxiliaryBus if backend has another bus it is able to export
*/
virtual AuxiliaryBus *get_auxiliar_bus() { return nullptr; }
/*
return the product ID
*/
int16_t product_id(void) const { return _product_id; }
int16_t get_id() const { return _id; }
protected:
// access to frontend
AP_InertialSensor &_imu;
void _rotate_and_correct_accel(uint8_t instance, Vector3f &accel);
void _rotate_and_correct_gyro(uint8_t instance, Vector3f &gyro);
void _publish_delta_velocity(uint8_t instance, const Vector3f &delta_velocity, float dt);
void _publish_delta_angle(uint8_t instance, const Vector3f &delta_angle);
// rotate gyro vector, offset and publish
void _publish_gyro(uint8_t instance, const Vector3f &gyro, bool rotate_and_correct = true);
// rotate accel vector, scale, offset and publish
void _publish_accel(uint8_t instance, const Vector3f &accel, bool rotate_and_correct = true);
// set accelerometer max absolute offset for calibration
void _set_accel_max_abs_offset(uint8_t instance, float offset);
// publish a temperature value
void _publish_temperature(uint8_t instance, float temperature);
// set accelerometer error_count
void _set_accel_error_count(uint8_t instance, uint32_t error_count);
// set gyro error_count
void _set_gyro_error_count(uint8_t instance, uint32_t error_count);
// backend should fill in its product ID from AP_PRODUCT_ID_*
int16_t _product_id;
// backend unique identifier or -1 if backend doesn't identify itself
int16_t _id = -1;
// return the default filter frequency in Hz for the sample rate
uint8_t _accel_filter_cutoff(void) const { return _imu._accel_filter_cutoff; }
// return the default filter frequency in Hz for the sample rate
uint8_t _gyro_filter_cutoff(void) const { return _imu._gyro_filter_cutoff; }
// return the requested sample rate in Hz
uint16_t get_sample_rate_hz(void) const;
// access to frontend dataflash
DataFlash_Class *get_dataflash(void) const {
return _imu._log_raw_data? _imu._dataflash : NULL;
}
// note that each backend is also expected to have a static detect()
// function which instantiates an instance of the backend sensor
// driver if the sensor is available
};
#endif // __AP_INERTIALSENSOR_BACKEND_H__