123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #include "SIM_Precland.h"
- #include "AP_HAL/AP_HAL.h"
- #include "AP_Math/AP_Math.h"
- #include "AP_Common/Location.h"
- #include <stdio.h>
- using namespace SITL;
- const AP_Param::GroupInfo SIM_Precland::var_info[] = {
-
-
-
-
-
- AP_GROUPINFO("ENABLE", 0, SIM_Precland, _enable, 0),
-
-
-
-
-
-
-
- AP_GROUPINFO("LAT", 1, SIM_Precland, _origin_lat, 0),
-
-
-
-
-
-
-
- AP_GROUPINFO("LON", 2, SIM_Precland, _origin_lon, 0),
-
-
-
-
-
-
-
- AP_GROUPINFO("HEIGHT", 3, SIM_Precland, _origin_height, 0),
-
-
-
-
-
-
-
- AP_GROUPINFO("YAW", 4, SIM_Precland, _orient_yaw, 0),
-
-
-
-
-
-
- AP_GROUPINFO("RATE", 5, SIM_Precland, _rate, 100),
-
-
-
-
-
- AP_GROUPINFO("TYPE", 6, SIM_Precland, _type, SIM_Precland::PRECLAND_TYPE_CYLINDER),
-
-
-
-
-
-
- AP_GROUPINFO("ALT_LMT", 7, SIM_Precland, _alt_limit, 15),
-
-
-
-
-
-
- AP_GROUPINFO("DIST_LMT", 8, SIM_Precland, _dist_limit, 10),
- AP_GROUPEND
- };
- void SIM_Precland::update(const Location &loc, const Vector3f &position)
- {
- const uint32_t now = AP_HAL::millis();
- if (!_enable) {
- _healthy = false;
- return;
- }
- if (is_zero(_alt_limit) || _dist_limit < 1.0f) {
- _healthy = false;
- return;
- }
- if (now - _last_update_ms < 1000.0f * (1.0f / _rate)) {
- return;
- }
- _last_update_ms = now;
- const float distance_z = -position.z;
- const float origin_height_m = _origin_height * 0.01f;
- if (distance_z > _alt_limit + origin_height_m) {
- _healthy = false;
- return;
- }
- const Location origin_center(static_cast<int32_t>(_origin_lat * 1.0e7f),
- static_cast<int32_t>(_origin_lon * 1.0e7f),
- static_cast<int32_t>(_origin_height),
- Location::AltFrame::ABOVE_HOME);
- Vector2f center;
- if (!origin_center.get_vector_xy_from_origin_NE(center)) {
- _healthy = false;
- return;
- }
- center = center * 0.01f;
- switch (_type) {
- case PRECLAND_TYPE_CONE: {
- const float in_radius = distance_z * _dist_limit / (_alt_limit + origin_height_m);
- if (norm(position.x - center.x, position.y - center.y) > in_radius) {
- _healthy = false;
- return;
- }
- break;
- }
- case PRECLAND_TYPE_SPHERE: {
- if (norm(position.x - center.x, position.y - center.y, distance_z - _origin_height) > (_alt_limit + origin_height_m)) {
- _healthy = false;
- return;
- }
- break;
- }
- default:
- case PRECLAND_TYPE_CYLINDER: {
- if (norm(position.x - center.x, position.y - center.y) > _dist_limit) {
- _healthy = false;
- return;
- }
- break;
- }
- }
- _target_pos = position - Vector3f(center.x, center.y, origin_height_m);
- _healthy = true;
- }
- void SIM_Precland::set_default_location(float lat, float lon, int16_t yaw) {
- if (is_zero(_origin_lat) && is_zero(_origin_lon)) {
- _origin_lat = lat;
- _origin_lon = lon;
- _orient_yaw = yaw;
- }
- }
|