AP_OADatabase.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #pragma once
  2. #include <AP_HAL/AP_HAL.h>
  3. #include <AP_Common/Location.h>
  4. #include <GCS_MAVLink/GCS_MAVLink.h>
  5. #if !HAL_MINIMIZE_FEATURES
  6. #include <AP_Param/AP_Param.h>
  7. class AP_OADatabase {
  8. public:
  9. AP_OADatabase();
  10. /* Do not allow copies */
  11. AP_OADatabase(const AP_OADatabase &other) = delete;
  12. AP_OADatabase &operator=(const AP_OADatabase&) = delete;
  13. // get singleton instance
  14. static AP_OADatabase *get_singleton() {
  15. return _singleton;
  16. }
  17. enum OA_DbItemImportance {
  18. Low, Normal, High
  19. };
  20. struct OA_DbItem {
  21. Location loc; // location of object. TODO: turn this into Vector2Int to save memory
  22. uint32_t timestamp_ms; // system time that object was last updated
  23. float radius; // objects radius in meters
  24. uint8_t send_to_gcs; // bitmask of mavlink comports to which details of this object should be sent
  25. OA_DbItemImportance importance;
  26. };
  27. void init();
  28. void update();
  29. // push a location into the database
  30. void queue_push(const Location &loc, const uint32_t timestamp_ms, const float distance, const float angle);
  31. // returns true if database is healthy
  32. bool healthy() const { return (_queue.items != nullptr) && (_database.items != nullptr); }
  33. // fetch an item in database. Undefined result when i >= _database.count.
  34. const OA_DbItem& get_item(uint32_t i) const { return _database.items[i]; }
  35. // get radius (in meters) of objects in database
  36. float get_accuracy() const { return _database.filter_m; }
  37. // get number of items in the database
  38. uint16_t database_count() const { return _database.count; }
  39. // empty queue and try and put into database. Return true if there's more work to do
  40. bool process_queue();
  41. // send ADSB_VEHICLE mavlink messages
  42. void send_adsb_vehicle(mavlink_channel_t chan, uint16_t interval_ms);
  43. static const struct AP_Param::GroupInfo var_info[];
  44. private:
  45. // initialise
  46. void init_queue();
  47. void init_database();
  48. // check queue and database sizes and adjust filter criteria to optimize use
  49. void optimize_db_filter();
  50. // database item management
  51. void database_item_add(const OA_DbItem &item);
  52. void database_item_refresh(const uint16_t index, const uint32_t timestamp_ms, const float radius);
  53. void database_item_remove(const uint16_t index);
  54. void database_items_remove_all_expired();
  55. // get bitmask of gcs channels item should be sent to based on its importance
  56. // returns 0xFF (send to all channels) if should be sent or 0 if it should not be sent
  57. uint8_t get_send_to_gcs_flags(const OA_DbItemImportance importance);
  58. // used to determine the filter radius
  59. float get_radius(const OA_DbItemImportance importance);
  60. // returns true if database item "index" is close to "item"
  61. bool is_close_to_item_in_database(const uint16_t index, const OA_DbItem &item) const;
  62. // enum for use with _OUTPUT parameter
  63. enum class OA_DbOutputLevel {
  64. OUTPUT_LEVEL_DISABLED = 0,
  65. OUTPUT_LEVEL_SEND_HIGH = 1,
  66. OUTPUT_LEVEL_SEND_HIGH_AND_NORMAL = 2,
  67. OUTPUT_LEVEL_SEND_ALL = 3
  68. };
  69. // parameters
  70. AP_Int16 _queue_size_param; // queue size
  71. AP_Int16 _database_size_param; // db size
  72. AP_Int8 _database_expiry_seconds; // objects expire after this timeout
  73. AP_Int8 _output_level; // controls which items should be sent to GCS
  74. struct {
  75. ObjectBuffer<OA_DbItem> *items; // thread safe incoming queue of points from proximity sensor to be put into database
  76. uint16_t size; // cached value of _queue_size_param.
  77. HAL_Semaphore sem; // semaphore for multi-thread use of queue
  78. } _queue;
  79. struct {
  80. OA_DbItem *items; // array of objects in the database
  81. float filter_m = 0.2f; // object avoidance database optimization level radius. Min distance between each fence point. Larger means lower resolution
  82. const float filter_max_m = 10.0f; // filter value max size allowed to grow to
  83. const float filter_min_m = 0.011f; // worst case resolution of int32 lat/lng value at equator is 1.1cm;
  84. const float filter_grow_rate = 1.03f; // db filter how fast you grow to reduce items getting into dB
  85. const float filter_shrink_rate = 0.99f; // db filter how fast you shrink to increase items getting into dB
  86. const float radius_grow_rate = 1.10f; // db item radius growth over time. Resets if refreshed, otherwise decaying items grow
  87. uint16_t count; // number of objects in the items array
  88. uint16_t size; // cached value of _database_size_param that sticks after initialized
  89. } _database;
  90. uint16_t _next_index_to_send[MAVLINK_COMM_NUM_BUFFERS]; // index of next object in _database to send to GCS
  91. uint16_t _highest_index_sent[MAVLINK_COMM_NUM_BUFFERS]; // highest index in _database sent to GCS
  92. uint32_t _last_send_to_gcs_ms[MAVLINK_COMM_NUM_BUFFERS];// system time that send_adsb_vehicle was last called
  93. float _radius_importance_low = _database.filter_m;
  94. float _radius_importance_normal = _database.filter_m;
  95. float _radius_importance_high = _database.filter_m;
  96. static AP_OADatabase *_singleton;
  97. };
  98. #else
  99. class AP_OADatabase {
  100. public:
  101. static AP_OADatabase *get_singleton() { return nullptr; }
  102. void init() {};
  103. void queue_push(const Location &loc, const uint32_t timestamp_ms, const float distance, const float angle) {};
  104. bool healthy() const { return false; }
  105. void send_adsb_vehicle(mavlink_channel_t chan, uint16_t interval_ms) {};
  106. };
  107. #endif // #if !HAL_MINIMIZE_FEATURES
  108. namespace AP {
  109. AP_OADatabase *oadatabase();
  110. };