SIM_Precland.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. #include "SIM_Precland.h"
  14. #include "AP_HAL/AP_HAL.h"
  15. #include "AP_Math/AP_Math.h"
  16. #include "AP_Common/Location.h"
  17. #include <stdio.h>
  18. using namespace SITL;
  19. // table of user settable parameters
  20. const AP_Param::GroupInfo SIM_Precland::var_info[] = {
  21. // @Param: ENABLE
  22. // @DisplayName: Preland device Sim enable/disable
  23. // @Description: Allows you to enable (1) or disable (0) the Preland simulation
  24. // @Values: 0:Disabled,1:Enabled
  25. // @User: Advanced
  26. AP_GROUPINFO("ENABLE", 0, SIM_Precland, _enable, 0),
  27. // @Param: LAT
  28. // @DisplayName: Precland device origin's latitude
  29. // @Description: Precland device origin's latitude
  30. // @Units: deg
  31. // @Increment: 0.000001
  32. // @Range: -90 90
  33. // @User: Advanced
  34. AP_GROUPINFO("LAT", 1, SIM_Precland, _origin_lat, 0),
  35. // @Param: LON
  36. // @DisplayName: Precland device origin's longitude
  37. // @Description: Precland device origin's longitude
  38. // @Units: deg
  39. // @Increment: 0.000001
  40. // @Range: -180 180
  41. // @User: Advanced
  42. AP_GROUPINFO("LON", 2, SIM_Precland, _origin_lon, 0),
  43. // @Param: HEIGHT
  44. // @DisplayName: Precland device origin's height above sealevel
  45. // @Description: Precland device origin's height above sealevel
  46. // @Units: cm
  47. // @Increment: 1
  48. // @Range: 0 10000
  49. // @User: Advanced
  50. AP_GROUPINFO("HEIGHT", 3, SIM_Precland, _origin_height, 0),
  51. // @Param: YAW
  52. // @DisplayName: Precland device systems rotation from north
  53. // @Description: Precland device systems rotation from north
  54. // @Units: deg
  55. // @Increment: 1
  56. // @Range: -180 +180
  57. // @User: Advanced
  58. AP_GROUPINFO("YAW", 4, SIM_Precland, _orient_yaw, 0),
  59. // @Param: RATE
  60. // @DisplayName: Precland device update rate
  61. // @Description: Precland device rate. e.g led patter refresh rate, RF message rate, etc.
  62. // @Units: Hz
  63. // @Range: 0 200
  64. // @User: Advanced
  65. AP_GROUPINFO("RATE", 5, SIM_Precland, _rate, 100),
  66. // @Param: TYPE
  67. // @DisplayName: Precland device radiance type
  68. // @Description: Precland device radiance type: it can be a cylinder, a cone, or a sphere.
  69. // @Values: 0:cylinder,1:cone,2:sphere
  70. // @User: Advanced
  71. AP_GROUPINFO("TYPE", 6, SIM_Precland, _type, SIM_Precland::PRECLAND_TYPE_CYLINDER),
  72. // @Param: ALT_LIMIT
  73. // @DisplayName: Precland device alt range
  74. // @Description: Precland device maximum range altitude
  75. // @Units: m
  76. // @Range: 0 100
  77. // @User: Advanced
  78. AP_GROUPINFO("ALT_LMT", 7, SIM_Precland, _alt_limit, 15),
  79. // @Param: DIST_LIMIT
  80. // @DisplayName: Precland device lateral range
  81. // @Description: Precland device maximum lateral range
  82. // @Units: m
  83. // @Range: 5 100
  84. // @User: Advanced
  85. AP_GROUPINFO("DIST_LMT", 8, SIM_Precland, _dist_limit, 10),
  86. AP_GROUPEND
  87. };
  88. void SIM_Precland::update(const Location &loc, const Vector3f &position)
  89. {
  90. const uint32_t now = AP_HAL::millis();
  91. if (!_enable) {
  92. _healthy = false;
  93. return;
  94. }
  95. if (is_zero(_alt_limit) || _dist_limit < 1.0f) {
  96. _healthy = false;
  97. return;
  98. }
  99. if (now - _last_update_ms < 1000.0f * (1.0f / _rate)) {
  100. return;
  101. }
  102. _last_update_ms = now;
  103. const float distance_z = -position.z;
  104. const float origin_height_m = _origin_height * 0.01f;
  105. if (distance_z > _alt_limit + origin_height_m) {
  106. _healthy = false;
  107. return;
  108. }
  109. const Location origin_center(static_cast<int32_t>(_origin_lat * 1.0e7f),
  110. static_cast<int32_t>(_origin_lon * 1.0e7f),
  111. static_cast<int32_t>(_origin_height),
  112. Location::AltFrame::ABOVE_HOME);
  113. Vector2f center;
  114. if (!origin_center.get_vector_xy_from_origin_NE(center)) {
  115. _healthy = false;
  116. return;
  117. }
  118. center = center * 0.01f; // cm to m
  119. switch (_type) {
  120. case PRECLAND_TYPE_CONE: {
  121. const float in_radius = distance_z * _dist_limit / (_alt_limit + origin_height_m);
  122. if (norm(position.x - center.x, position.y - center.y) > in_radius) {
  123. _healthy = false;
  124. return;
  125. }
  126. break;
  127. }
  128. case PRECLAND_TYPE_SPHERE: {
  129. if (norm(position.x - center.x, position.y - center.y, distance_z - _origin_height) > (_alt_limit + origin_height_m)) {
  130. _healthy = false;
  131. return;
  132. }
  133. break;
  134. }
  135. default:
  136. case PRECLAND_TYPE_CYLINDER: {
  137. if (norm(position.x - center.x, position.y - center.y) > _dist_limit) {
  138. _healthy = false;
  139. return;
  140. }
  141. break;
  142. }
  143. }
  144. _target_pos = position - Vector3f(center.x, center.y, origin_height_m);
  145. _healthy = true;
  146. }
  147. void SIM_Precland::set_default_location(float lat, float lon, int16_t yaw) {
  148. if (is_zero(_origin_lat) && is_zero(_origin_lon)) {
  149. _origin_lat = lat;
  150. _origin_lon = lon;
  151. _orient_yaw = yaw;
  152. }
  153. }