123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- #include "AP_Rally.h"
- #include <AP_AHRS/AP_AHRS.h>
- #include <AP_Logger/AP_Logger.h>
- #include <StorageManager/StorageManager.h>
- StorageAccess AP_Rally::_storage(StorageManager::StorageRally);
- assert_storage_size<RallyLocation, 15> _assert_storage_size_RallyLocation;
- #if APM_BUILD_TYPE(APM_BUILD_ArduCopter)
- #define RALLY_LIMIT_KM_DEFAULT 0.3f
- #define RALLY_INCLUDE_HOME_DEFAULT 1
- #elif APM_BUILD_TYPE(APM_BUILD_ArduPlane)
- #define RALLY_LIMIT_KM_DEFAULT 5.0f
- #define RALLY_INCLUDE_HOME_DEFAULT 0
- #elif APM_BUILD_TYPE(APM_BUILD_APMrover2)
- #define RALLY_LIMIT_KM_DEFAULT 0.5f
- #define RALLY_INCLUDE_HOME_DEFAULT 1
- #else
- #define RALLY_LIMIT_KM_DEFAULT 1.0f
- #define RALLY_INCLUDE_HOME_DEFAULT 0
- #endif
- const AP_Param::GroupInfo AP_Rally::var_info[] = {
-
-
-
-
- AP_GROUPINFO("TOTAL", 0, AP_Rally, _rally_point_total_count, 0),
-
-
-
-
-
-
- AP_GROUPINFO("LIMIT_KM", 1, AP_Rally, _rally_limit_km, RALLY_LIMIT_KM_DEFAULT),
-
-
-
-
-
- AP_GROUPINFO("INCL_HOME", 2, AP_Rally, _rally_incl_home, RALLY_INCLUDE_HOME_DEFAULT),
- AP_GROUPEND
- };
- AP_Rally::AP_Rally()
- {
- #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
- if (_singleton != nullptr) {
- AP_HAL::panic("Rally must be singleton");
- }
- #endif
- _singleton = this;
- AP_Param::setup_object_defaults(this, var_info);
- }
- bool AP_Rally::get_rally_point_with_index(uint8_t i, RallyLocation &ret) const
- {
- if (i >= (uint8_t) _rally_point_total_count) {
- return false;
- }
- _storage.read_block(&ret, i * sizeof(RallyLocation), sizeof(RallyLocation));
- if (ret.lat == 0 && ret.lng == 0) {
- return false;
- }
- return true;
- }
- void AP_Rally::truncate(uint8_t num)
- {
- if (num > _rally_point_total_count) {
-
- return;
- }
- _rally_point_total_count.set_and_save_ifchanged(num);
- }
- bool AP_Rally::append(const RallyLocation &loc)
- {
- const uint8_t current_total = get_rally_total();
- _rally_point_total_count.set_and_save_ifchanged(current_total + 1);
- if (!set_rally_point_with_index(current_total, loc)) {
- _rally_point_total_count.set_and_save_ifchanged(current_total);
- return false;
- }
- return true;
- }
- bool AP_Rally::set_rally_point_with_index(uint8_t i, const RallyLocation &rallyLoc)
- {
- if (i >= (uint8_t) _rally_point_total_count) {
- return false;
- }
- if (i >= get_rally_max()) {
- return false;
- }
- _storage.write_block(i * sizeof(RallyLocation), &rallyLoc, sizeof(RallyLocation));
- _last_change_time_ms = AP_HAL::millis();
- AP::logger().Write_RallyPoint(_rally_point_total_count, i, rallyLoc);
- return true;
- }
- Location AP_Rally::rally_location_to_location(const RallyLocation &rally_loc) const
- {
- Location ret = {};
-
- ret.relative_alt = false;
-
-
-
- ret.alt = (rally_loc.alt*100UL) + AP::ahrs().get_home().alt;
- ret.lat = rally_loc.lat;
- ret.lng = rally_loc.lng;
- return ret;
- }
- bool AP_Rally::find_nearest_rally_point(const Location ¤t_loc, RallyLocation &return_loc) const
- {
- float min_dis = -1;
- for (uint8_t i = 0; i < (uint8_t) _rally_point_total_count; i++) {
- RallyLocation next_rally;
- if (!get_rally_point_with_index(i, next_rally)) {
- continue;
- }
- Location rally_loc = rally_location_to_location(next_rally);
- float dis = current_loc.get_distance(rally_loc);
- if (is_valid(rally_loc) && (dis < min_dis || min_dis < 0)) {
- min_dis = dis;
- return_loc = next_rally;
- }
- }
-
- if ((_rally_limit_km > 0) && (min_dis > _rally_limit_km*1000.0f)) {
- return false;
- }
-
- return min_dis >= 0;
- }
- Location AP_Rally::calc_best_rally_or_home_location(const Location ¤t_loc, float rtl_home_alt) const
- {
- RallyLocation ral_loc = {};
- Location return_loc = {};
- const struct Location &home_loc = AP::ahrs().get_home();
-
-
- return_loc = home_loc;
- return_loc.alt = rtl_home_alt;
- return_loc.relative_alt = false;
- if (find_nearest_rally_point(current_loc, ral_loc)) {
- Location loc = rally_location_to_location(ral_loc);
-
- if (!_rally_incl_home || (current_loc.get_distance(loc) < current_loc.get_distance(return_loc))) {
- return_loc = rally_location_to_location(ral_loc);
- }
- }
- return return_loc;
- }
- AP_Rally *AP_Rally::_singleton;
- namespace AP {
- AP_Rally *rally()
- {
- return AP_Rally::get_singleton();
- }
- }
|