AP_OpticalFlow_HereFlow.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include <AP_HAL/AP_HAL.h>
  2. #if HAL_WITH_UAVCAN
  3. #include "AP_OpticalFlow_HereFlow.h"
  4. #include <AP_BoardConfig/AP_BoardConfig_CAN.h>
  5. #include <AP_UAVCAN/AP_UAVCAN.h>
  6. #include <com/hex/equipment/flow/Measurement.hpp>
  7. extern const AP_HAL::HAL& hal;
  8. #define debug_flow_uavcan(level_debug, can_driver, fmt, args...) do { if ((level_debug) <= AP::can().get_debug_level_driver(can_driver)) { hal.console->printf(fmt, ##args); }} while (0)
  9. //UAVCAN Frontend Registry Binder
  10. UC_REGISTRY_BINDER(MeasurementCb, com::hex::equipment::flow::Measurement);
  11. uint8_t AP_OpticalFlow_HereFlow::_node_id = 0;
  12. AP_OpticalFlow_HereFlow* AP_OpticalFlow_HereFlow::_driver = nullptr;
  13. AP_UAVCAN* AP_OpticalFlow_HereFlow::_ap_uavcan = nullptr;
  14. /*
  15. constructor - registers instance at top Flow driver
  16. */
  17. AP_OpticalFlow_HereFlow::AP_OpticalFlow_HereFlow(OpticalFlow &flow) :
  18. OpticalFlow_backend(flow)
  19. {
  20. if (_driver) {
  21. AP_HAL::panic("Only one instance of Flow supported!");
  22. }
  23. _driver = this;
  24. }
  25. //links the HereFlow messages to the backend
  26. void AP_OpticalFlow_HereFlow::subscribe_msgs(AP_UAVCAN* ap_uavcan)
  27. {
  28. if (ap_uavcan == nullptr) {
  29. return;
  30. }
  31. auto* node = ap_uavcan->get_node();
  32. uavcan::Subscriber<com::hex::equipment::flow::Measurement, MeasurementCb> *measurement_listener;
  33. measurement_listener = new uavcan::Subscriber<com::hex::equipment::flow::Measurement, MeasurementCb>(*node);
  34. // Register method to handle incoming HereFlow measurement
  35. const int measurement_listener_res = measurement_listener->start(MeasurementCb(ap_uavcan, &handle_measurement));
  36. if (measurement_listener_res < 0) {
  37. AP_HAL::panic("UAVCAN Flow subscriber start problem\n\r");
  38. return;
  39. }
  40. }
  41. //updates driver states based on received HereFlow messages
  42. void AP_OpticalFlow_HereFlow::handle_measurement(AP_UAVCAN* ap_uavcan, uint8_t node_id, const MeasurementCb &cb)
  43. {
  44. if (_driver == nullptr) {
  45. return;
  46. }
  47. //protect from data coming from duplicate sensors,
  48. //as we only handle one Here Flow at a time as of now
  49. if (_ap_uavcan == nullptr) {
  50. _ap_uavcan = ap_uavcan;
  51. _node_id = node_id;
  52. }
  53. if (_ap_uavcan == ap_uavcan && _node_id == node_id) {
  54. WITH_SEMAPHORE(_driver->_sem);
  55. _driver->new_data = true;
  56. _driver->flowRate = Vector2f(cb.msg->flow_integral[0], cb.msg->flow_integral[1]);
  57. _driver->bodyRate = Vector2f(cb.msg->rate_gyro_integral[0], cb.msg->rate_gyro_integral[1]);
  58. _driver->integral_time = cb.msg->integration_interval;
  59. _driver->surface_quality = cb.msg->quality;
  60. }
  61. }
  62. void AP_OpticalFlow_HereFlow::update()
  63. {
  64. _push_state();
  65. }
  66. // Read the sensor
  67. void AP_OpticalFlow_HereFlow::_push_state(void)
  68. {
  69. WITH_SEMAPHORE(_sem);
  70. if (!new_data) {
  71. return;
  72. }
  73. struct OpticalFlow::OpticalFlow_state state;
  74. const Vector2f flowScaler = _flowScaler();
  75. //setup scaling based on parameters
  76. float flowScaleFactorX = 1.0f + 0.001f * flowScaler.x;
  77. float flowScaleFactorY = 1.0f + 0.001f * flowScaler.y;
  78. float integralToRate = 1.0f / integral_time;
  79. //Convert to Raw Flow measurement to Flow Rate measurement
  80. state.flowRate = Vector2f(flowRate.x * flowScaleFactorX,
  81. flowRate.y * flowScaleFactorY) * integralToRate;
  82. state.bodyRate = bodyRate * integralToRate;
  83. state.surface_quality = surface_quality;
  84. _applyYaw(state.flowRate);
  85. _applyYaw(state.bodyRate);
  86. // hal.console->printf("DRV: %u %f %f\n", state.surface_quality, flowRate.length(), bodyRate.length());
  87. _update_frontend(state);
  88. new_data = false;
  89. }
  90. #endif // HAL_WITH_UAVCAN