2017-04-02 11:55:40 -03:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Author: Eugene Shamaev
|
|
|
|
*/
|
|
|
|
#ifndef AP_UAVCAN_H_
|
|
|
|
#define AP_UAVCAN_H_
|
|
|
|
|
|
|
|
#include <uavcan/uavcan.hpp>
|
|
|
|
|
|
|
|
#include <AP_HAL/CAN.h>
|
|
|
|
#include <AP_HAL/Semaphores.h>
|
|
|
|
#include <AP_GPS/AP_GPS.h>
|
|
|
|
#include <AP_Param/AP_Param.h>
|
|
|
|
|
|
|
|
#include <AP_GPS/GPS_Backend.h>
|
|
|
|
#include <AP_Baro/AP_Baro_Backend.h>
|
|
|
|
#include <AP_Compass/AP_Compass.h>
|
2018-02-16 18:32:50 -04:00
|
|
|
#include <AP_BattMonitor/AP_BattMonitor_Backend.h>
|
2017-04-02 11:55:40 -03:00
|
|
|
|
|
|
|
#include <uavcan/helpers/heap_based_pool_allocator.hpp>
|
2018-01-17 03:18:00 -04:00
|
|
|
#include <uavcan/equipment/indication/RGB565.hpp>
|
2017-04-02 11:55:40 -03:00
|
|
|
|
|
|
|
#ifndef UAVCAN_NODE_POOL_SIZE
|
|
|
|
#define UAVCAN_NODE_POOL_SIZE 8192
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef UAVCAN_NODE_POOL_BLOCK_SIZE
|
|
|
|
#define UAVCAN_NODE_POOL_BLOCK_SIZE 256
|
|
|
|
#endif
|
|
|
|
|
2018-03-09 11:36:21 -04:00
|
|
|
#ifndef UAVCAN_SRV_NUMBER
|
|
|
|
#define UAVCAN_SRV_NUMBER 18
|
2017-04-02 11:55:40 -03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define AP_UAVCAN_MAX_LISTENERS 4
|
|
|
|
#define AP_UAVCAN_MAX_GPS_NODES 4
|
|
|
|
#define AP_UAVCAN_MAX_MAG_NODES 4
|
|
|
|
#define AP_UAVCAN_MAX_BARO_NODES 4
|
2018-02-16 18:32:50 -04:00
|
|
|
#define AP_UAVCAN_MAX_BI_NUMBER 4
|
2017-04-02 11:55:40 -03:00
|
|
|
|
|
|
|
#define AP_UAVCAN_SW_VERS_MAJOR 1
|
|
|
|
#define AP_UAVCAN_SW_VERS_MINOR 0
|
|
|
|
|
|
|
|
#define AP_UAVCAN_HW_VERS_MAJOR 1
|
|
|
|
#define AP_UAVCAN_HW_VERS_MINOR 0
|
|
|
|
|
2018-01-17 03:18:00 -04:00
|
|
|
#define AP_UAVCAN_MAX_LED_DEVICES 4
|
|
|
|
#define AP_UAVCAN_LED_DELAY_MILLISECONDS 50
|
|
|
|
|
2017-04-02 11:55:40 -03:00
|
|
|
class AP_UAVCAN {
|
|
|
|
public:
|
|
|
|
AP_UAVCAN();
|
|
|
|
~AP_UAVCAN();
|
|
|
|
|
|
|
|
static const struct AP_Param::GroupInfo var_info[];
|
|
|
|
|
2018-03-09 18:00:16 -04:00
|
|
|
// Return uavcan from @iface or nullptr if it's not ready or doesn't exist
|
|
|
|
static AP_UAVCAN *get_uavcan(uint8_t iface);
|
|
|
|
|
2017-04-02 11:55:40 -03:00
|
|
|
// this function will register the listening class on a first free channel or on the specified channel
|
|
|
|
// if preferred_channel = 0 then free channel will be searched for
|
|
|
|
// if preferred_channel > 0 then listener will be added to specific channel
|
|
|
|
// return value is the number of assigned channel or 0 if fault
|
|
|
|
// channel numbering starts from 1
|
2017-05-06 06:13:44 -03:00
|
|
|
uint8_t register_gps_listener(AP_GPS_Backend* new_listener, uint8_t preferred_channel);
|
|
|
|
|
|
|
|
uint8_t register_gps_listener_to_node(AP_GPS_Backend* new_listener, uint8_t node);
|
|
|
|
|
|
|
|
uint8_t find_gps_without_listener(void);
|
|
|
|
|
2017-04-02 11:55:40 -03:00
|
|
|
// Removes specified listener from all nodes
|
|
|
|
void remove_gps_listener(AP_GPS_Backend* rem_listener);
|
|
|
|
|
|
|
|
// Returns pointer to GPS state connected with specified node.
|
|
|
|
// If node is not found and there are free space, locate a new one
|
|
|
|
AP_GPS::GPS_State *find_gps_node(uint8_t node);
|
|
|
|
|
|
|
|
// Updates all listeners of specified node
|
|
|
|
void update_gps_state(uint8_t node);
|
|
|
|
|
|
|
|
struct Baro_Info {
|
|
|
|
float pressure;
|
|
|
|
float pressure_variance;
|
|
|
|
float temperature;
|
|
|
|
float temperature_variance;
|
|
|
|
};
|
|
|
|
|
2017-05-06 06:13:44 -03:00
|
|
|
uint8_t register_baro_listener(AP_Baro_Backend* new_listener, uint8_t preferred_channel);
|
|
|
|
uint8_t register_baro_listener_to_node(AP_Baro_Backend* new_listener, uint8_t node);
|
2017-04-02 11:55:40 -03:00
|
|
|
void remove_baro_listener(AP_Baro_Backend* rem_listener);
|
|
|
|
Baro_Info *find_baro_node(uint8_t node);
|
2017-05-06 06:13:44 -03:00
|
|
|
uint8_t find_smallest_free_baro_node();
|
2017-04-02 11:55:40 -03:00
|
|
|
void update_baro_state(uint8_t node);
|
|
|
|
|
|
|
|
struct Mag_Info {
|
|
|
|
Vector3f mag_vector;
|
|
|
|
};
|
|
|
|
|
2017-05-06 06:13:44 -03:00
|
|
|
uint8_t register_mag_listener(AP_Compass_Backend* new_listener, uint8_t preferred_channel);
|
2017-04-02 11:55:40 -03:00
|
|
|
void remove_mag_listener(AP_Compass_Backend* rem_listener);
|
2018-01-15 11:12:28 -04:00
|
|
|
Mag_Info *find_mag_node(uint8_t node, uint8_t sensor_id);
|
2017-05-06 06:13:44 -03:00
|
|
|
uint8_t find_smallest_free_mag_node();
|
|
|
|
uint8_t register_mag_listener_to_node(AP_Compass_Backend* new_listener, uint8_t node);
|
2018-01-15 11:12:28 -04:00
|
|
|
void update_mag_state(uint8_t node, uint8_t sensor_id);
|
2017-04-02 11:55:40 -03:00
|
|
|
|
2018-02-16 18:32:50 -04:00
|
|
|
struct BatteryInfo_Info {
|
|
|
|
float temperature;
|
|
|
|
float voltage;
|
|
|
|
float current;
|
|
|
|
float remaining_capacity_wh;
|
|
|
|
float full_charge_capacity_wh;
|
|
|
|
uint8_t status_flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
uint8_t register_BM_bi_listener_to_id(AP_BattMonitor_Backend* new_listener, uint8_t id);
|
|
|
|
void remove_BM_bi_listener(AP_BattMonitor_Backend* rem_listener);
|
|
|
|
BatteryInfo_Info *find_bi_id(uint8_t id);
|
|
|
|
uint8_t find_smallest_free_bi_id();
|
|
|
|
void update_bi_state(uint8_t id);
|
|
|
|
|
2017-04-02 11:55:40 -03:00
|
|
|
// synchronization for RC output
|
2018-05-24 19:51:16 -03:00
|
|
|
void SRV_sem_take();
|
2018-03-09 11:36:21 -04:00
|
|
|
void SRV_sem_give();
|
2018-01-17 03:18:00 -04:00
|
|
|
|
|
|
|
// synchronization for LED output
|
|
|
|
bool led_out_sem_take();
|
|
|
|
void led_out_sem_give();
|
|
|
|
void led_out_send();
|
2017-04-02 11:55:40 -03:00
|
|
|
|
2018-02-08 19:42:58 -04:00
|
|
|
// output from do_cyclic
|
2018-03-09 11:36:21 -04:00
|
|
|
void SRV_send_servos();
|
|
|
|
void SRV_send_esc();
|
2018-02-08 19:42:58 -04:00
|
|
|
|
2017-04-02 11:55:40 -03:00
|
|
|
private:
|
|
|
|
// ------------------------- GPS
|
|
|
|
// 255 - means free node
|
|
|
|
uint8_t _gps_nodes[AP_UAVCAN_MAX_GPS_NODES];
|
|
|
|
// Counter of how many listeners are connected to this source
|
|
|
|
uint8_t _gps_node_taken[AP_UAVCAN_MAX_GPS_NODES];
|
|
|
|
// GPS data of the sources
|
|
|
|
AP_GPS::GPS_State _gps_node_state[AP_UAVCAN_MAX_GPS_NODES];
|
|
|
|
|
|
|
|
// 255 - means no connection
|
|
|
|
uint8_t _gps_listener_to_node[AP_UAVCAN_MAX_LISTENERS];
|
|
|
|
// Listeners with callbacks to be updated
|
|
|
|
AP_GPS_Backend* _gps_listeners[AP_UAVCAN_MAX_LISTENERS];
|
|
|
|
|
|
|
|
// ------------------------- BARO
|
|
|
|
uint8_t _baro_nodes[AP_UAVCAN_MAX_BARO_NODES];
|
|
|
|
uint8_t _baro_node_taken[AP_UAVCAN_MAX_BARO_NODES];
|
|
|
|
Baro_Info _baro_node_state[AP_UAVCAN_MAX_BARO_NODES];
|
|
|
|
uint8_t _baro_listener_to_node[AP_UAVCAN_MAX_LISTENERS];
|
|
|
|
AP_Baro_Backend* _baro_listeners[AP_UAVCAN_MAX_LISTENERS];
|
|
|
|
|
|
|
|
// ------------------------- MAG
|
|
|
|
uint8_t _mag_nodes[AP_UAVCAN_MAX_MAG_NODES];
|
|
|
|
uint8_t _mag_node_taken[AP_UAVCAN_MAX_MAG_NODES];
|
|
|
|
Mag_Info _mag_node_state[AP_UAVCAN_MAX_MAG_NODES];
|
2018-01-15 11:12:28 -04:00
|
|
|
uint8_t _mag_node_max_sensorid_count[AP_UAVCAN_MAX_MAG_NODES];
|
2017-04-02 11:55:40 -03:00
|
|
|
uint8_t _mag_listener_to_node[AP_UAVCAN_MAX_LISTENERS];
|
|
|
|
AP_Compass_Backend* _mag_listeners[AP_UAVCAN_MAX_LISTENERS];
|
2018-01-15 11:12:28 -04:00
|
|
|
uint8_t _mag_listener_sensor_ids[AP_UAVCAN_MAX_LISTENERS];
|
2017-04-02 11:55:40 -03:00
|
|
|
|
2018-02-16 18:32:50 -04:00
|
|
|
// ------------------------- BatteryInfo
|
|
|
|
uint16_t _bi_id[AP_UAVCAN_MAX_BI_NUMBER];
|
|
|
|
uint16_t _bi_id_taken[AP_UAVCAN_MAX_BI_NUMBER];
|
|
|
|
BatteryInfo_Info _bi_id_state[AP_UAVCAN_MAX_BI_NUMBER];
|
|
|
|
uint16_t _bi_BM_listener_to_id[AP_UAVCAN_MAX_LISTENERS];
|
|
|
|
AP_BattMonitor_Backend* _bi_BM_listeners[AP_UAVCAN_MAX_LISTENERS];
|
|
|
|
|
2017-04-02 11:55:40 -03:00
|
|
|
struct {
|
|
|
|
uint16_t pulse;
|
|
|
|
uint16_t safety_pulse;
|
|
|
|
uint16_t failsafe_pulse;
|
2018-05-24 07:23:00 -03:00
|
|
|
bool esc_pending;
|
|
|
|
bool servo_pending;
|
2018-03-09 11:36:21 -04:00
|
|
|
} _SRV_conf[UAVCAN_SRV_NUMBER];
|
2017-04-02 11:55:40 -03:00
|
|
|
|
|
|
|
bool _initialized;
|
2018-03-09 11:36:21 -04:00
|
|
|
uint8_t _SRV_armed;
|
|
|
|
uint8_t _SRV_safety;
|
2018-05-24 07:23:00 -03:00
|
|
|
uint32_t _SRV_last_send_us;
|
2017-04-02 11:55:40 -03:00
|
|
|
|
2018-01-17 03:18:00 -04:00
|
|
|
typedef struct {
|
|
|
|
bool enabled;
|
|
|
|
uint8_t led_index;
|
|
|
|
uavcan::equipment::indication::RGB565 rgb565_color;
|
|
|
|
} _led_device;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
bool broadcast_enabled;
|
|
|
|
_led_device devices[AP_UAVCAN_MAX_LED_DEVICES];
|
|
|
|
uint8_t devices_count;
|
|
|
|
uint64_t last_update;
|
|
|
|
} _led_conf;
|
|
|
|
|
2018-03-09 11:36:21 -04:00
|
|
|
AP_HAL::Semaphore *SRV_sem;
|
2018-01-17 03:18:00 -04:00
|
|
|
AP_HAL::Semaphore *_led_out_sem;
|
2017-04-02 11:55:40 -03:00
|
|
|
|
|
|
|
class SystemClock: public uavcan::ISystemClock, uavcan::Noncopyable {
|
|
|
|
SystemClock()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
uavcan::UtcDuration utc_adjustment;
|
|
|
|
virtual void adjustUtc(uavcan::UtcDuration adjustment)
|
|
|
|
{
|
|
|
|
utc_adjustment = adjustment;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual uavcan::MonotonicTime getMonotonic() const
|
|
|
|
{
|
|
|
|
uavcan::uint64_t usec = 0;
|
|
|
|
usec = AP_HAL::micros64();
|
|
|
|
return uavcan::MonotonicTime::fromUSec(usec);
|
|
|
|
}
|
|
|
|
virtual uavcan::UtcTime getUtc() const
|
|
|
|
{
|
|
|
|
uavcan::UtcTime utc;
|
|
|
|
uavcan::uint64_t usec = 0;
|
|
|
|
usec = AP_HAL::micros64();
|
|
|
|
utc.fromUSec(usec);
|
|
|
|
utc += utc_adjustment;
|
|
|
|
return utc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static SystemClock& instance()
|
|
|
|
{
|
|
|
|
static SystemClock inst;
|
|
|
|
return inst;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
uavcan::Node<0> *_node = nullptr;
|
|
|
|
|
|
|
|
uavcan::ISystemClock& get_system_clock();
|
|
|
|
uavcan::ICanDriver* get_can_driver();
|
|
|
|
uavcan::Node<0>* get_node();
|
|
|
|
|
|
|
|
// This will be needed to implement if UAVCAN is used with multithreading
|
|
|
|
// Such cases will be firmware update, etc.
|
|
|
|
class RaiiSynchronizer {
|
|
|
|
public:
|
|
|
|
RaiiSynchronizer()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
~RaiiSynchronizer()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
uavcan::HeapBasedPoolAllocator<UAVCAN_NODE_POOL_BLOCK_SIZE, AP_UAVCAN::RaiiSynchronizer> _node_allocator;
|
|
|
|
|
|
|
|
AP_Int8 _uavcan_node;
|
2017-05-06 06:13:44 -03:00
|
|
|
AP_Int32 _servo_bm;
|
|
|
|
AP_Int32 _esc_bm;
|
2018-05-24 07:23:00 -03:00
|
|
|
AP_Int16 _servo_rate_hz;
|
2017-05-06 06:13:44 -03:00
|
|
|
|
|
|
|
uint8_t _uavcan_i;
|
|
|
|
|
|
|
|
AP_HAL::CANManager* _parent_can_mgr;
|
2017-04-02 11:55:40 -03:00
|
|
|
|
|
|
|
public:
|
|
|
|
void do_cyclic(void);
|
|
|
|
bool try_init(void);
|
|
|
|
|
2018-03-09 11:36:21 -04:00
|
|
|
void SRV_set_safety_pwm(uint32_t chmask, uint16_t pulse_len);
|
|
|
|
void SRV_set_failsafe_pwm(uint32_t chmask, uint16_t pulse_len);
|
|
|
|
void SRV_force_safety_on(void);
|
|
|
|
void SRV_force_safety_off(void);
|
|
|
|
void SRV_arm_actuators(bool arm);
|
|
|
|
void SRV_write(uint16_t pulse_len, uint8_t ch);
|
2018-03-16 00:19:17 -03:00
|
|
|
void SRV_push_servos(void);
|
2018-01-17 03:18:00 -04:00
|
|
|
bool led_write(uint8_t led_index, uint8_t red, uint8_t green, uint8_t blue);
|
2017-05-06 06:13:44 -03:00
|
|
|
|
|
|
|
void set_parent_can_mgr(AP_HAL::CANManager* parent_can_mgr)
|
|
|
|
{
|
|
|
|
_parent_can_mgr = parent_can_mgr;
|
|
|
|
}
|
2017-04-02 11:55:40 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* AP_UAVCAN_H_ */
|