PX4 Firmware
PX4 Autopilot Software http://px4.io
navigator_main.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2013-2017 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 /**
34  * @file navigator_main.cpp
35  *
36  * Handles mission items, geo fencing and failsafe navigation behavior.
37  * Published the position setpoint triplet for the position controller.
38  *
39  * @author Lorenz Meier <lorenz@px4.io>
40  * @author Jean Cyr <jean.m.cyr@gmail.com>
41  * @author Julian Oes <julian@oes.ch>
42  * @author Anton Babushkin <anton.babushkin@me.com>
43  * @author Thomas Gubler <thomasgubler@gmail.com>
44  */
45 
46 #include "navigator.h"
47 
48 #include <float.h>
49 #include <sys/stat.h>
50 
51 #include <dataman/dataman.h>
52 #include <drivers/drv_hrt.h>
53 #include <lib/ecl/geo/geo.h>
54 #include <lib/mathlib/mathlib.h>
55 #include <px4_platform_common/px4_config.h>
56 #include <px4_platform_common/defines.h>
57 #include <px4_platform_common/posix.h>
58 #include <px4_platform_common/tasks.h>
59 #include <systemlib/mavlink_log.h>
60 
61 /**
62  * navigator app start / stop handling function
63  *
64  * @ingroup apps
65  */
66 extern "C" __EXPORT int navigator_main(int argc, char *argv[]);
67 
68 #define GEOFENCE_CHECK_INTERVAL 200000
69 
70 using namespace time_literals;
71 
72 namespace navigator
73 {
75 }
76 
78  ModuleParams(nullptr),
79  _loop_perf(perf_alloc(PC_ELAPSED, "navigator")),
80  _geofence(this),
81  _mission(this),
82  _loiter(this),
83  _takeoff(this),
84  _land(this),
85  _precland(this),
86  _rtl(this),
87  _rcLoss(this),
88  _dataLinkLoss(this),
89  _engineFailure(this),
90  _gpsFailure(this),
91  _follow_target(this)
92 {
93  /* Create a list of our possible navigation types */
105 
106  _handle_back_trans_dec_mss = param_find("VT_B_DEC_MSS");
107  _handle_reverse_delay = param_find("VT_B_REV_DEL");
108 
109  _local_pos_sub = orb_subscribe(ORB_ID(vehicle_local_position));
110  _vehicle_status_sub = orb_subscribe(ORB_ID(vehicle_status));
111 
112  reset_triplets();
113 }
114 
116 {
117  orb_unsubscribe(_local_pos_sub);
119 }
120 
121 void
123 {
124  updateParams();
125 
128  }
129 
132  }
133 }
134 
135 void
137 {
138  bool have_geofence_position_data = false;
139 
140  /* Try to load the geofence:
141  * if /fs/microsd/etc/geofence.txt load from this file */
142  struct stat buffer;
143 
144  if (stat(GEOFENCE_FILENAME, &buffer) == 0) {
145  PX4_INFO("Loading geofence from %s", GEOFENCE_FILENAME);
147  }
148 
149  params_update();
150 
151  /* wakeup source(s) */
152  px4_pollfd_struct_t fds[2] {};
153 
154  /* Setup of loop */
155  fds[0].fd = _local_pos_sub;
156  fds[0].events = POLLIN;
157  fds[1].fd = _vehicle_status_sub;
158  fds[1].events = POLLIN;
159 
160  /* rate-limit position subscription to 20 Hz / 50 ms */
161  orb_set_interval(_local_pos_sub, 50);
162 
163  hrt_abstime last_geofence_check = 0;
164 
165  while (!should_exit()) {
166 
167  /* wait for up to 1000ms for data */
168  int pret = px4_poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 1000);
169 
170  if (pret == 0) {
171  /* Let the loop run anyway, don't do `continue` here. */
172 
173  } else if (pret < 0) {
174  /* this is undesirable but not much we can do - might want to flag unhappy status */
175  PX4_ERR("poll error %d, %d", pret, errno);
176  px4_usleep(10000);
177  continue;
178 
179  } else {
180  if (fds[0].revents & POLLIN) {
181  /* success, local pos is available */
182  orb_copy(ORB_ID(vehicle_local_position), _local_pos_sub, &_local_pos);
183  }
184  }
185 
187 
188  orb_copy(ORB_ID(vehicle_status), _vehicle_status_sub, &_vstatus);
189 
190  /* gps updated */
191  if (_gps_pos_sub.updated()) {
193 
195  have_geofence_position_data = true;
196  }
197  }
198 
199  /* global position updated */
200  if (_global_pos_sub.updated()) {
202 
204  have_geofence_position_data = true;
205  }
206  }
207 
208  // check for parameter updates
210  // clear update
211  parameter_update_s pupdate;
212  _parameter_update_sub.copy(&pupdate);
213 
214  // update parameters from storage
215  params_update();
216  }
217 
221 
223  vehicle_command_s cmd{};
225 
226  if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_GO_AROUND) {
227 
228  // DO_GO_AROUND is currently handled by the position controller (unacknowledged)
229  // TODO: move DO_GO_AROUND handling to navigator
230  publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);
231 
232  } else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_REPOSITION) {
233 
236 
237  // store current position as previous position and goal as next
242 
244  rep->current.loiter_direction = 1;
245  rep->current.type = position_setpoint_s::SETPOINT_TYPE_LOITER;
246 
247  // If no argument for ground speed, use default value.
248  if (cmd.param1 <= 0 || !PX4_ISFINITE(cmd.param1)) {
250 
251  } else {
252  rep->current.cruising_speed = cmd.param1;
253  }
254 
257 
258  // Go on and check which changes had been requested
259  if (PX4_ISFINITE(cmd.param4)) {
260  rep->current.yaw = cmd.param4;
261  rep->current.yaw_valid = true;
262 
263  } else {
264  rep->current.yaw = NAN;
265  rep->current.yaw_valid = false;
266  }
267 
268  if (PX4_ISFINITE(cmd.param5) && PX4_ISFINITE(cmd.param6)) {
269 
270  // Position change with optional altitude change
271  rep->current.lat = (cmd.param5 < 1000) ? cmd.param5 : cmd.param5 / (double)1e7;
272  rep->current.lon = (cmd.param6 < 1000) ? cmd.param6 : cmd.param6 / (double)1e7;
273 
274  if (PX4_ISFINITE(cmd.param7)) {
275  rep->current.alt = cmd.param7;
276 
277  } else {
279  }
280 
281  } else if (PX4_ISFINITE(cmd.param7) && curr->current.valid
282  && PX4_ISFINITE(curr->current.lat)
283  && PX4_ISFINITE(curr->current.lon)) {
284 
285  // Altitude without position change
286  rep->current.lat = curr->current.lat;
287  rep->current.lon = curr->current.lon;
288  rep->current.alt = cmd.param7;
289 
290  } else {
291  // All three set to NaN - hold in current position
295  }
296 
297  rep->previous.valid = true;
298  rep->current.valid = true;
299  rep->next.valid = false;
300 
301  // CMD_DO_REPOSITION is acknowledged by commander
302 
303  } else if (cmd.command == vehicle_command_s::VEHICLE_CMD_NAV_TAKEOFF) {
305 
306  // store current position as previous position and goal as next
311 
313  rep->current.loiter_direction = 1;
314  rep->current.type = position_setpoint_s::SETPOINT_TYPE_TAKEOFF;
315 
316  if (home_position_valid()) {
317  rep->current.yaw = cmd.param4;
318  rep->previous.valid = true;
319 
320  } else {
321  rep->current.yaw = get_local_position()->yaw;
322  rep->previous.valid = false;
323  }
324 
325  if (PX4_ISFINITE(cmd.param5) && PX4_ISFINITE(cmd.param6)) {
326  rep->current.lat = (cmd.param5 < 1000) ? cmd.param5 : cmd.param5 / (double)1e7;
327  rep->current.lon = (cmd.param6 < 1000) ? cmd.param6 : cmd.param6 / (double)1e7;
328 
329  } else {
330  // If one of them is non-finite, reset both
331  rep->current.lat = (double)NAN;
332  rep->current.lon = (double)NAN;
333  }
334 
335  rep->current.alt = cmd.param7;
336 
337  rep->current.valid = true;
338  rep->next.valid = false;
339 
340  // CMD_NAV_TAKEOFF is acknowledged by commander
341 
342  } else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_LAND_START) {
343 
344  /* find NAV_CMD_DO_LAND_START in the mission and
345  * use MAV_CMD_MISSION_START to start the mission there
346  */
347  if (_mission.land_start()) {
348  vehicle_command_s vcmd = {};
349  vcmd.command = vehicle_command_s::VEHICLE_CMD_MISSION_START;
351  publish_vehicle_cmd(&vcmd);
352 
353  } else {
354  PX4_WARN("planned mission landing not available");
355  }
356 
357  publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);
358 
359  } else if (cmd.command == vehicle_command_s::VEHICLE_CMD_MISSION_START) {
360  if (_mission_result.valid && PX4_ISFINITE(cmd.param1) && (cmd.param1 >= 0)) {
361  if (!_mission.set_current_mission_index(cmd.param1)) {
362  PX4_WARN("CMD_MISSION_START failed");
363  }
364  }
365 
366  // CMD_MISSION_START is acknowledged by commander
367 
368  } else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_CHANGE_SPEED) {
369  if (cmd.param2 > FLT_EPSILON) {
370  // XXX not differentiating ground and airspeed yet
371  set_cruising_speed(cmd.param2);
372 
373  } else {
375 
376  /* if no speed target was given try to set throttle */
377  if (cmd.param3 > FLT_EPSILON) {
378  set_cruising_throttle(cmd.param3 / 100);
379 
380  } else {
382  }
383  }
384 
385  // TODO: handle responses for supported DO_CHANGE_SPEED options?
386  publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);
387 
388  } else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI
389  || cmd.command == vehicle_command_s::VEHICLE_CMD_NAV_ROI
390  || cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_LOCATION
391  || cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_WPNEXT_OFFSET
392  || cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_NONE) {
393  _vroi = {};
394 
395  switch (cmd.command) {
396  case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI:
397  case vehicle_command_s::VEHICLE_CMD_NAV_ROI:
398  _vroi.mode = cmd.param1;
399  break;
400 
401  case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_LOCATION:
402  _vroi.mode = vehicle_command_s::VEHICLE_ROI_LOCATION;
403  _vroi.lat = cmd.param5;
404  _vroi.lon = cmd.param6;
405  _vroi.alt = cmd.param7;
406  break;
407 
408  case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_WPNEXT_OFFSET:
409  _vroi.mode = vehicle_command_s::VEHICLE_ROI_WPNEXT;
410  _vroi.pitch_offset = (float)cmd.param5 * M_DEG_TO_RAD_F;
411  _vroi.roll_offset = (float)cmd.param6 * M_DEG_TO_RAD_F;
412  _vroi.yaw_offset = (float)cmd.param7 * M_DEG_TO_RAD_F;
413  break;
414 
415  case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_NONE:
416  _vroi.mode = vehicle_command_s::VEHICLE_ROI_NONE;
417  break;
418 
419  default:
420  _vroi.mode = vehicle_command_s::VEHICLE_ROI_NONE;
421  break;
422  }
423 
425 
427 
428  publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);
429  }
430  }
431 
432  /* Check for traffic */
433  check_traffic();
434 
435  /* Check geofence violation */
436  if (have_geofence_position_data &&
437  (_geofence.getGeofenceAction() != geofence_result_s::GF_ACTION_NONE) &&
438  (hrt_elapsed_time(&last_geofence_check) > GEOFENCE_CHECK_INTERVAL)) {
439 
440  bool inside = _geofence.check(_global_pos, _gps_pos, _home_pos,
442  last_geofence_check = hrt_absolute_time();
443  have_geofence_position_data = false;
444 
448 
449  if (!inside) {
450  /* inform other apps via the mission result */
452 
453  /* Issue a warning about the geofence violation once */
455  mavlink_log_critical(&_mavlink_log_pub, "Geofence violation");
457  }
458 
459  } else {
460  /* inform other apps via the mission result */
462 
463  /* Reset the _geofence_violation_warning_sent field */
465  }
466 
468  }
469 
470  /* Do stuff according to navigation state set by commander */
471  NavigatorMode *navigation_mode_new{nullptr};
472 
473  switch (_vstatus.nav_state) {
474  case vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION:
476 
477  _mission.set_execution_mode(mission_result_s::MISSION_EXECUTION_MODE_NORMAL);
478  navigation_mode_new = &_mission;
479 
480  break;
481 
482  case vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER:
484  navigation_mode_new = &_loiter;
485  break;
486 
487  case vehicle_status_s::NAVIGATION_STATE_AUTO_RCRECOVER:
489  navigation_mode_new = &_rcLoss;
490  break;
491 
492  case vehicle_status_s::NAVIGATION_STATE_AUTO_RTL: {
494 
495  const bool rtl_activated = _previous_nav_state != vehicle_status_s::NAVIGATION_STATE_AUTO_RTL;
496 
497  switch (rtl_type()) {
498  case RTL::RTL_LAND: // use mission landing
499  case RTL::RTL_CLOSEST:
500  if (rtl_activated) {
501  if (rtl_type() == RTL::RTL_LAND) {
502  mavlink_and_console_log_info(get_mavlink_log_pub(), "RTL LAND activated");
503 
504  } else {
505  mavlink_and_console_log_info(get_mavlink_log_pub(), "RTL Closest landing point activated");
506  }
507 
508  }
509 
510  // if RTL is set to use a mission landing and mission has a planned landing, then use MISSION to fly there directly
511  if (on_mission_landing() && !get_land_detected()->landed) {
512  _mission.set_execution_mode(mission_result_s::MISSION_EXECUTION_MODE_FAST_FORWARD);
513  navigation_mode_new = &_mission;
514 
515  } else {
516  navigation_mode_new = &_rtl;
517  }
518 
519  break;
520 
521  case RTL::RTL_MISSION:
523  // the mission contains a landing spot
524  _mission.set_execution_mode(mission_result_s::MISSION_EXECUTION_MODE_FAST_FORWARD);
525 
526  if (_navigation_mode != &_mission) {
527  if (_navigation_mode == nullptr) {
528  // switching from an manual mode, go to landing if not already landing
529  if (!on_mission_landing()) {
531  }
532 
533  } else {
534  // switching from an auto mode, continue the mission from the closest item
536  }
537  }
538 
539  if (rtl_activated) {
540  mavlink_and_console_log_info(get_mavlink_log_pub(), "RTL Mission activated, continue mission");
541  }
542 
543  navigation_mode_new = &_mission;
544 
545  } else {
546  // fly the mission in reverse if switching from a non-manual mode
547  _mission.set_execution_mode(mission_result_s::MISSION_EXECUTION_MODE_REVERSE);
548 
549  if ((_navigation_mode != nullptr && (_navigation_mode != &_rtl || _mission.get_mission_changed())) &&
551  (!get_land_detected()->landed)) {
552  // determine the closest mission item if switching from a non-mission mode, and we are either not already
553  // mission mode or the mission waypoints changed.
554  // The seconds condition is required so that when no mission was uploaded and one is available the closest
555  // mission item is determined and also that if the user changes the active mission index while rtl is active
556  // always that waypoint is tracked first.
557  if ((_navigation_mode != &_mission) && (rtl_activated || _mission.get_mission_waypoints_changed())) {
559  }
560 
561  if (rtl_activated) {
562  mavlink_and_console_log_info(get_mavlink_log_pub(), "RTL Mission activated, fly mission in reverse");
563  }
564 
565  navigation_mode_new = &_mission;
566 
567  } else {
568  if (rtl_activated) {
569  mavlink_and_console_log_info(get_mavlink_log_pub(), "RTL Mission activated, fly to home");
570  }
571 
572  navigation_mode_new = &_rtl;
573  }
574  }
575 
576  break;
577 
578  default:
579  if (rtl_activated) {
580  mavlink_and_console_log_info(get_mavlink_log_pub(), "RTL HOME activated");
581  }
582 
583  navigation_mode_new = &_rtl;
584  break;
585 
586  }
587 
588  break;
589  }
590 
591  case vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF:
593  navigation_mode_new = &_takeoff;
594  break;
595 
596  case vehicle_status_s::NAVIGATION_STATE_AUTO_LAND:
598  navigation_mode_new = &_land;
599  break;
600 
601  case vehicle_status_s::NAVIGATION_STATE_AUTO_PRECLAND:
603  navigation_mode_new = &_precland;
605  break;
606 
607  case vehicle_status_s::NAVIGATION_STATE_AUTO_RTGS:
609  navigation_mode_new = &_dataLinkLoss;
610  break;
611 
612  case vehicle_status_s::NAVIGATION_STATE_AUTO_LANDENGFAIL:
614  navigation_mode_new = &_engineFailure;
615  break;
616 
617  case vehicle_status_s::NAVIGATION_STATE_AUTO_LANDGPSFAIL:
619  navigation_mode_new = &_gpsFailure;
620  break;
621 
622  case vehicle_status_s::NAVIGATION_STATE_AUTO_FOLLOW_TARGET:
624  navigation_mode_new = &_follow_target;
625  break;
626 
627  case vehicle_status_s::NAVIGATION_STATE_MANUAL:
628  case vehicle_status_s::NAVIGATION_STATE_ACRO:
629  case vehicle_status_s::NAVIGATION_STATE_ALTCTL:
630  case vehicle_status_s::NAVIGATION_STATE_POSCTL:
631  case vehicle_status_s::NAVIGATION_STATE_DESCEND:
632  case vehicle_status_s::NAVIGATION_STATE_TERMINATION:
633  case vehicle_status_s::NAVIGATION_STATE_OFFBOARD:
634  case vehicle_status_s::NAVIGATION_STATE_STAB:
635  default:
636  navigation_mode_new = nullptr;
637  _can_loiter_at_sp = false;
638  break;
639  }
640 
641  // update the vehicle status
643 
644  /* we have a new navigation mode: reset triplet */
645  if (_navigation_mode != navigation_mode_new) {
646  // We don't reset the triplet if we just did an auto-takeoff and are now
647  // going to loiter. Otherwise, we lose the takeoff altitude and end up lower
648  // than where we wanted to go.
649  //
650  // FIXME: a better solution would be to add reset where they are needed and remove
651  // this general reset here.
652  if (!(_navigation_mode == &_takeoff &&
653  navigation_mode_new == &_loiter)) {
654  reset_triplets();
655  }
656  }
657 
658  _navigation_mode = navigation_mode_new;
659 
660  /* iterate through navigation modes and set active/inactive for each */
661  for (unsigned int i = 0; i < NAVIGATOR_MODE_ARRAY_SIZE; i++) {
663  }
664 
665  /* if we landed and have not received takeoff setpoint then stay in idle */
666  if (_land_detected.landed &&
667  !((_vstatus.nav_state == vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF)
668  || (_vstatus.nav_state == vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION))) {
669 
670  _pos_sp_triplet.current.type = position_setpoint_s::SETPOINT_TYPE_IDLE;
673 
675 
676  _pos_sp_triplet.next.valid = false;
677  }
678 
679  /* if nothing is running, set position setpoint triplet invalid once */
682  reset_triplets();
683  }
684 
687  }
688 
691  }
692 
694  }
695 }
696 
697 int Navigator::task_spawn(int argc, char *argv[])
698 {
699  _task_id = px4_task_spawn_cmd("navigator",
700  SCHED_DEFAULT,
701  SCHED_PRIORITY_NAVIGATION,
702  1800,
703  (px4_main_t)&run_trampoline,
704  (char *const *)argv);
705 
706  if (_task_id < 0) {
707  _task_id = -1;
708  return -errno;
709  }
710 
711  return 0;
712 }
713 
714 Navigator *Navigator::instantiate(int argc, char *argv[])
715 {
716  Navigator *instance = new Navigator();
717 
718  if (instance == nullptr) {
719  PX4_ERR("alloc failed");
720  }
721 
722  return instance;
723 }
724 
725 int
727 {
728  PX4_INFO("Running");
729 
731  return 0;
732 }
733 
734 void
736 {
739  _pos_sp_triplet_updated = false;
740 }
741 
742 float
744 {
745  return _param_nav_acc_rad.get();
746 }
747 
748 float
750 {
751  return get_acceptance_radius(_param_nav_acc_rad.get());
752 }
753 
754 float
756 {
758  return _param_nav_fw_alt_rad.get();
759 
760  } else if (get_vstatus()->vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROVER) {
761  return INFINITY;
762 
763  } else {
764  float alt_acceptance_radius = _param_nav_mc_alt_rad.get();
765 
767 
768  if ((pos_ctrl_status.timestamp > _pos_sp_triplet.timestamp)
769  && pos_ctrl_status.altitude_acceptance > alt_acceptance_radius) {
770  alt_acceptance_radius = pos_ctrl_status.altitude_acceptance;
771  }
772 
773  return alt_acceptance_radius;
774  }
775 }
776 
777 float
779 {
782 
783  if (next_sp.type == position_setpoint_s::SETPOINT_TYPE_LAND && next_sp.valid) {
784  // Use separate (tighter) altitude acceptance for clean altitude starting point before landing
785  return _param_nav_fw_altl_rad.get();
786  }
787  }
788 
790 }
791 
792 float
794 {
795  /* there are three options: The mission-requested cruise speed, or the current hover / plane speed */
796  if (_vstatus.vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) {
799 
800  } else {
801  return -1.0f;
802  }
803 
804  } else {
807 
808  } else {
809  return -1.0f;
810  }
811  }
812 }
813 
814 void
816 {
817  if (_vstatus.vehicle_type == vehicle_status_s::VEHICLE_TYPE_ROTARY_WING) {
819 
820  } else {
822  }
823 }
824 
825 void
827 {
830 }
831 
832 void
834 {
835  _pos_sp_triplet.current.valid = false;
837  _pos_sp_triplet.next.valid = false;
839 }
840 
841 float
843 {
844  /* Return the mission-requested cruise speed, or default FW_THR_CRUISE value */
846  return _mission_throttle;
847 
848  } else {
849  return -1.0f;
850  }
851 }
852 
853 float
854 Navigator::get_acceptance_radius(float mission_item_radius)
855 {
856  float radius = mission_item_radius;
857 
858  // XXX only use navigation capabilities for now
859  // when in fixed wing mode
860  // this might need locking against a commanded transition
861  // so that a stale _vstatus doesn't trigger an accepted mission item.
862 
864 
865  if ((pos_ctrl_status.timestamp > _pos_sp_triplet.timestamp) && pos_ctrl_status.acceptance_radius > radius) {
866  radius = pos_ctrl_status.acceptance_radius;
867  }
868 
869  return radius;
870 }
871 
872 float
873 Navigator::get_yaw_acceptance(float mission_item_yaw)
874 {
875  float yaw = mission_item_yaw;
876 
878 
879  // if yaw_acceptance from position controller is NaN overwrite the mission item yaw such that
880  // the waypoint can be reached from any direction
881  if ((pos_ctrl_status.timestamp > _pos_sp_triplet.timestamp) && !PX4_ISFINITE(pos_ctrl_status.yaw_acceptance)) {
882  yaw = pos_ctrl_status.yaw_acceptance;
883  }
884 
885  return yaw;
886 }
887 
888 void
889 Navigator::load_fence_from_file(const char *filename)
890 {
891  _geofence.loadFromFile(filename);
892 }
893 
894 /**
895  * Creates a fake traffic measurement with supplied parameters.
896  *
897  */
898 void Navigator::fake_traffic(const char *callsign, float distance, float direction, float traffic_heading,
899  float altitude_diff, float hor_velocity, float ver_velocity)
900 {
901  double lat, lon;
902  waypoint_from_heading_and_distance(get_global_position()->lat, get_global_position()->lon, direction, distance, &lat,
903  &lon);
904  float alt = get_global_position()->alt + altitude_diff;
905 
906  // float vel_n = get_global_position()->vel_n;
907  // float vel_e = get_global_position()->vel_e;
908  // float vel_d = get_global_position()->vel_d;
909 
912  tr.icao_address = 1234;
913  tr.lat = lat; // Latitude, expressed as degrees
914  tr.lon = lon; // Longitude, expressed as degrees
915  tr.altitude_type = 0;
916  tr.altitude = alt;
917  tr.heading = traffic_heading; //-atan2(vel_e, vel_n); // Course over ground in radians
918  tr.hor_velocity = hor_velocity; //sqrtf(vel_e * vel_e + vel_n * vel_n); // The horizontal velocity in m/s
919  tr.ver_velocity = ver_velocity; //-vel_d; // The vertical velocity in m/s, positive is up
920  strncpy(&tr.callsign[0], callsign, sizeof(tr.callsign) - 1);
921  tr.callsign[sizeof(tr.callsign) - 1] = 0;
922  tr.emitter_type = 0; // Type from ADSB_EMITTER_TYPE enum
923  tr.tslc = 2; // Time since last communication in seconds
924  tr.flags = transponder_report_s::PX4_ADSB_FLAGS_VALID_COORDS | transponder_report_s::PX4_ADSB_FLAGS_VALID_HEADING |
925  transponder_report_s::PX4_ADSB_FLAGS_VALID_VELOCITY |
926  transponder_report_s::PX4_ADSB_FLAGS_VALID_ALTITUDE |
927  transponder_report_s::PX4_ADSB_FLAGS_VALID_CALLSIGN; // Flags to indicate various statuses including valid data fields
928  tr.squawk = 6667;
929 
930  uORB::PublicationQueued<transponder_report_s> tr_pub{ORB_ID(transponder_report)};
931  tr_pub.publish(tr);
932 }
933 
935 {
936  double lat = get_global_position()->lat;
937  double lon = get_global_position()->lon;
938  float alt = get_global_position()->alt;
939 
940  // TODO for non-multirotors predicting the future
941  // position as accurately as possible will become relevant
942  // float vel_n = get_global_position()->vel_n;
943  // float vel_e = get_global_position()->vel_e;
944  // float vel_d = get_global_position()->vel_d;
945 
946  bool changed = _traffic_sub.updated();
947 
948  float horizontal_separation = 500;
949  float vertical_separation = 500;
950 
951  while (changed) {
952 
954  _traffic_sub.copy(&tr);
955 
956  uint16_t required_flags = transponder_report_s::PX4_ADSB_FLAGS_VALID_COORDS |
957  transponder_report_s::PX4_ADSB_FLAGS_VALID_HEADING |
958  transponder_report_s::PX4_ADSB_FLAGS_VALID_VELOCITY | transponder_report_s::PX4_ADSB_FLAGS_VALID_ALTITUDE;
959 
960  if ((tr.flags & required_flags) != required_flags) {
961  changed = _traffic_sub.updated();
962  continue;
963  }
964 
965  float d_hor, d_vert;
967  tr.lat, tr.lon, tr.altitude, &d_hor, &d_vert);
968 
969 
970  // predict final altitude (positive is up) in prediction time frame
971  float end_alt = tr.altitude + (d_vert / tr.hor_velocity) * tr.ver_velocity;
972 
973  // Predict until the vehicle would have passed this system at its current speed
974  float prediction_distance = d_hor + 1000.0f;
975 
976  // If the altitude is not getting close to us, do not calculate
977  // the horizontal separation.
978  // Since commercial flights do most of the time keep flight levels
979  // check for the current and for the predicted flight level.
980  // we also make the implicit assumption that this system is on the lowest
981  // flight level close to ground in the
982  // (end_alt - horizontal_separation < alt) condition. If this system should
983  // ever be used in normal airspace this implementation would anyway be
984  // inappropriate as it should be replaced with a TCAS compliant solution.
985 
986  if ((fabsf(alt - tr.altitude) < vertical_separation) || ((end_alt - horizontal_separation) < alt)) {
987 
988  double end_lat, end_lon;
989  waypoint_from_heading_and_distance(tr.lat, tr.lon, tr.heading, prediction_distance, &end_lat, &end_lon);
990 
991  struct crosstrack_error_s cr;
992 
993  if (!get_distance_to_line(&cr, lat, lon, tr.lat, tr.lon, end_lat, end_lon)) {
994 
995  if (!cr.past_end && (fabsf(cr.distance) < horizontal_separation)) {
996 
997  // direction of traffic in human-readable 0..360 degree in earth frame
998  int traffic_direction = math::degrees(tr.heading) + 180;
999 
1000  switch (_param_nav_traff_avoid.get()) {
1001 
1002  case 0: {
1003  /* ignore */
1004  PX4_WARN("TRAFFIC %s, hdg: %d", tr.flags & transponder_report_s::PX4_ADSB_FLAGS_VALID_CALLSIGN ? tr.callsign :
1005  "unknown",
1006  traffic_direction);
1007  break;
1008  }
1009 
1010  case 1: {
1011  mavlink_log_critical(&_mavlink_log_pub, "WARNING TRAFFIC %s at heading %d, land immediately",
1012  tr.flags & transponder_report_s::PX4_ADSB_FLAGS_VALID_CALLSIGN ? tr.callsign : "unknown",
1013  traffic_direction);
1014  break;
1015  }
1016 
1017  case 2: {
1018  mavlink_log_critical(&_mavlink_log_pub, "AVOIDING TRAFFIC %s heading %d, returning home",
1019  tr.flags & transponder_report_s::PX4_ADSB_FLAGS_VALID_CALLSIGN ? tr.callsign : "unknown",
1020  traffic_direction);
1021 
1022  // set the return altitude to minimum
1023  _rtl.set_return_alt_min(true);
1024 
1025  // ask the commander to execute an RTL
1026  vehicle_command_s vcmd = {};
1027  vcmd.command = vehicle_command_s::VEHICLE_CMD_NAV_RETURN_TO_LAUNCH;
1028  publish_vehicle_cmd(&vcmd);
1029  break;
1030  }
1031  }
1032  }
1033  }
1034  }
1035 
1036  changed = _traffic_sub.updated();
1037  }
1038 }
1039 
1040 bool
1042 {
1043  // only abort if currently landing and position controller status updated
1044  bool should_abort = false;
1045 
1047  && _pos_sp_triplet.current.type == position_setpoint_s::SETPOINT_TYPE_LAND) {
1048 
1050  position_controller_landing_status_s landing_status{};
1051 
1052  // landing status from position controller must be newer than navigator's last position setpoint
1053  if (_pos_ctrl_landing_status_sub.copy(&landing_status)) {
1054  if (landing_status.timestamp > _pos_sp_triplet.timestamp) {
1055  should_abort = landing_status.abort_landing;
1056  }
1057  }
1058  }
1059  }
1060 
1061  return should_abort;
1062 }
1063 
1064 bool
1066 {
1067  return _vstatus.is_vtol &&
1069  && _param_nav_force_vt.get();
1070 }
1071 
1072 int Navigator::custom_command(int argc, char *argv[])
1073 {
1074  if (!is_running()) {
1075  print_usage("not running");
1076  return 1;
1077  }
1078 
1079  if (!strcmp(argv[0], "fencefile")) {
1080  get_instance()->load_fence_from_file(GEOFENCE_FILENAME);
1081  return 0;
1082 
1083  } else if (!strcmp(argv[0], "fake_traffic")) {
1084  get_instance()->fake_traffic("LX007", 500, 1.0f, -1.0f, 100.0f, 90.0f, 0.001f);
1085  get_instance()->fake_traffic("LX55", 1000, 0, 0, 100.0f, 90.0f, 0.001f);
1086  get_instance()->fake_traffic("LX20", 15000, 1.0f, -1.0f, 280.0f, 90.0f, 0.001f);
1087  return 0;
1088  }
1089 
1090  return print_usage("unknown command");
1091 }
1092 
1093 int navigator_main(int argc, char *argv[])
1094 {
1095  return Navigator::main(argc, argv);
1096 }
1097 
1098 void
1100 {
1102 
1103  /* lazily publish the mission result only once available */
1105 
1106  /* reset some of the flags */
1110 
1111  _mission_result_updated = false;
1112 }
1113 
1114 void
1116 {
1117  if (!_mission_result.failure) {
1118  _mission_result.failure = true;
1120  mavlink_log_critical(&_mavlink_log_pub, "%s", reason);
1121  }
1122 }
1123 
1124 void
1126 {
1127  vcmd->timestamp = hrt_absolute_time();
1131  vcmd->confirmation = false;
1132  vcmd->from_external = false;
1133 
1134  // The camera commands are not processed on the autopilot but will be
1135  // sent to the mavlink links to other components.
1136  switch (vcmd->command) {
1141  vcmd->target_component = 100; // MAV_COMP_ID_CAMERA
1142  break;
1143 
1144  default:
1146  break;
1147  }
1148 
1149  _vehicle_cmd_pub.publish(*vcmd);
1150 }
1151 
1152 void
1154 {
1155  vehicle_command_ack_s command_ack = {};
1156 
1157  command_ack.timestamp = hrt_absolute_time();
1158  command_ack.command = cmd.command;
1159  command_ack.target_system = cmd.source_system;
1160  command_ack.target_component = cmd.source_component;
1161  command_ack.from_external = false;
1162 
1163  command_ack.result = result;
1164  command_ack.result_param1 = 0;
1165  command_ack.result_param2 = 0;
1166 
1167  _vehicle_cmd_ack_pub.publish(command_ack);
1168 }
1169 
1170 int Navigator::print_usage(const char *reason)
1171 {
1172  if (reason) {
1173  PX4_WARN("%s\n", reason);
1174  }
1175 
1176  PRINT_MODULE_DESCRIPTION(
1177  R"DESCR_STR(
1178 ### Description
1179 Module that is responsible for autonomous flight modes. This includes missions (read from dataman),
1180 takeoff and RTL.
1181 It is also responsible for geofence violation checking.
1182 
1183 ### Implementation
1184 The different internal modes are implemented as separate classes that inherit from a common base class `NavigatorMode`.
1185 The member `_navigation_mode` contains the current active mode.
1186 
1187 Navigator publishes position setpoint triplets (`position_setpoint_triplet_s`), which are then used by the position
1188 controller.
1189 
1190 )DESCR_STR");
1191 
1192  PRINT_MODULE_USAGE_NAME("navigator", "controller");
1193  PRINT_MODULE_USAGE_COMMAND("start");
1194  PRINT_MODULE_USAGE_COMMAND_DESCR("fencefile", "load a geofence file from SD card, stored at etc/geofence.txt");
1195  PRINT_MODULE_USAGE_COMMAND_DESCR("fake_traffic", "publishes 3 fake transponder_report_s uORB messages");
1196  PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
1197 
1198  return 0;
1199 }
bool land_start()
Definition: mission.cpp:429
#define VEHICLE_TYPE_FIXED_WING
position_setpoint_triplet_s _pos_sp_triplet
triplet of position setpoints
Definition: navigator.h:355
#define PARAM_INVALID
Handle returned when a parameter cannot be found.
Definition: param.h:103
geofence_result_s _geofence_result
Definition: navigator.h:354
uORB::Subscription _home_pos_sub
home position subscription
Definition: navigator.h:323
uORB::SubscriptionData< position_controller_status_s > _position_controller_status_sub
Definition: navigator.h:330
bool home_position_valid()
Definition: navigator.h:166
uORB::PublicationQueued< vehicle_command_s > _vehicle_cmd_pub
Definition: navigator.h:340
float get_distance_to_point_global_wgs84(double lat_now, double lon_now, float alt_now, double lat_next, double lon_next, float alt_next, float *dist_xy, float *dist_z)
Definition: geo.cpp:523
void run() override
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer)
Definition: uORB.cpp:90
uORB::Subscription _vehicle_command_sub
vehicle commands (onboard and offboard)
Definition: navigator.h:328
void publish_position_setpoint_triplet()
Publish a new position setpoint triplet for position controllers.
Land _land
class for handling land commands
Definition: navigator.h:374
orb_advert_t _mavlink_log_pub
the uORB advert to send messages over mavlink
Definition: navigator.h:337
float get_default_altitude_acceptance_radius()
Get the default altitude acceptance radius (i.e.
vehicle_gps_position_s _gps_pos
gps position
Definition: navigator.h:346
float _mission_throttle
Definition: navigator.h:392
measure the time elapsed performing an event
Definition: perf_counter.h:56
NavigatorMode * _navigation_mode_array[NAVIGATOR_MODE_ARRAY_SIZE]
array of navigation modes
Definition: navigator.h:383
float get_acceptance_radius()
Get the acceptance radius.
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
Definition: parameters.cpp:589
Definition of geo / math functions to perform geodesic calculations.
bool is_planned_mission() const
Definition: navigator.h:268
vehicle_local_position_s _local_pos
local vehicle position
Definition: navigator.h:348
static int custom_command(int argc, char *argv[])
bool _geofence_violation_warning_sent
prevents spaming to mavlink
Definition: navigator.h:363
vehicle_global_position_s _global_pos
global vehicle position
Definition: navigator.h:345
int main(int argc, char **argv)
Definition: main.cpp:3
float get_cruising_throttle()
Get the target throttle.
struct position_setpoint_s next
uORB::Subscription _global_pos_sub
global position subscription
Definition: navigator.h:321
bool abort_landing()
int orb_set_interval(int handle, unsigned interval)
Definition: uORB.cpp:126
Definition: I2C.hpp:51
param_t _handle_back_trans_dec_mss
Definition: navigator.h:385
bool publish(const T &data)
Publish the struct.
int px4_poll(px4_pollfd_struct_t *fds, nfds_t nfds, int timeout)
int print_status() override
NavigatorMode * _navigation_mode
abstract pointer to current navigation mode class
Definition: navigator.h:370
struct position_setpoint_triplet_s * get_takeoff_triplet()
Definition: navigator.h:155
bool _pos_sp_triplet_updated
flags if position SP triplet needs to be published
Definition: navigator.h:366
struct position_setpoint_s previous
float _param_reverse_delay
Definition: navigator.h:388
uORB::Subscription _pos_ctrl_landing_status_sub
position controller landing status subscription
Definition: navigator.h:326
#define GEOFENCE_FILENAME
Definition: geofence.h:55
struct vehicle_land_detected_s * get_land_detected()
Definition: navigator.h:157
home_position_s _home_pos
home position for RTL
Definition: navigator.h:343
static bool is_running()
Definition: dataman.cpp:415
LidarLite * instance
Definition: ll40ls.cpp:65
uint16_t item_do_jump_remaining
constexpr T degrees(T radians)
Definition: Limits.hpp:91
void printStatus()
print Geofence status to the console
Definition: geofence.cpp:578
#define FLT_EPSILON
High-resolution timer with callouts and timekeeping.
vehicle_roi_s _vroi
vehicle ROI
Definition: navigator.h:358
mission_result_s _mission_result
Definition: navigator.h:344
GpsFailure _gpsFailure
class that handles the OBC gpsfailure loss mode
Definition: navigator.h:380
Geofence _geofence
class that handles the geofence
Definition: navigator.h:362
vehicle_land_detected_s _land_detected
vehicle land_detected
Definition: navigator.h:347
perf_counter_t _loop_perf
loop performance counter
Definition: navigator.h:360
Navigator * g_navigator
void set_return_alt_min(bool min)
Definition: rtl.cpp:230
int getGeofenceAction()
Definition: geofence.h:129
int _vehicle_status_sub
local position subscription
Definition: navigator.h:319
int orb_subscribe(const struct orb_metadata *meta)
Definition: uORB.cpp:75
uORB::Publication< mission_result_s > _mission_result_pub
Definition: navigator.h:333
void reset_cruising_speed()
Reset cruising speed to default values.
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
struct position_setpoint_s current
uint16_t get_land_start_index() const
Definition: mission.h:89
bool publish(const T &data)
Publish the struct.
Definition: Publication.hpp:68
void check_traffic()
Check nearby traffic for potential collisions.
void publish_vehicle_command_ack(const vehicle_command_s &cmd, uint8_t result)
void reset_triplets()
Set triplets to invalid.
bool _mission_result_updated
flags if mission result has seen an update
Definition: navigator.h:368
bool get_mission_changed() const
Definition: mission.h:92
int rtl_type()
Definition: navigator.h:279
PrecLand _precland
class for handling precision land commands
Definition: navigator.h:375
struct vehicle_global_position_s * get_global_position()
Definition: navigator.h:156
uORB::Publication< vehicle_roi_s > _vehicle_roi_pub
Definition: navigator.h:335
#define perf_alloc(a, b)
Definition: px4io.h:59
void waypoint_from_heading_and_distance(double lat_start, double lon_start, float bearing, float dist, double *lat_target, double *lon_target)
Creates a waypoint from given waypoint, distance and bearing see http://www.movable-type.co.uk/scripts/latlong.html.
Definition: geo.cpp:303
bool get_mission_finished() const
Definition: mission.h:91
float get_cruising_speed()
Get the cruising speed.
bool set_current_mission_index(uint16_t index)
Definition: mission.cpp:282
bool check(const vehicle_global_position_s &global_position, const vehicle_gps_position_s &gps_position, const home_position_s home_pos, bool home_position_set)
Return whether the system obeys the geofence.
Definition: geofence.cpp:190
uORB::Subscription _gps_pos_sub
gps position subscription
Definition: navigator.h:322
int orb_unsubscribe(int handle)
Definition: uORB.cpp:85
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
static hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.
Definition: drv_hrt.h:102
DATAMANAGER driver.
uint8_t _previous_nav_state
nav_state of the previous iteration
Definition: navigator.h:351
static int print_usage(const char *reason=nullptr)
EngineFailure _engineFailure
class that handles the engine failure mode (FW only!)
Definition: navigator.h:379
void perf_end(perf_counter_t handle)
End a performance event.
static Navigator * instantiate(int argc, char *argv[])
vehicle_status_s _vstatus
vehicle status
Definition: navigator.h:349
void set_closest_item_as_current()
Definition: mission.cpp:309
void set_execution_mode(const uint8_t mode)
Set a new mission mode and handle the switching between the different modes.
Definition: mission.cpp:315
bool updated()
Check if there is a new update.
void params_update()
uint64_t timestamp
Definition: vehicle_roi.h:59
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
Definition: drv_hrt.h:58
uint8_t mode
Definition: vehicle_roi.h:66
RCLoss _rcLoss
class that handles RTL according to OBC rules (rc loss mode)
Definition: navigator.h:377
const T & get() const
float pitch_offset
Definition: vehicle_roi.h:64
bool get_land_start_available() const
Definition: mission.h:90
Mission _mission
class that handles the missions
Definition: navigator.h:371
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
Definition: parameters.cpp:370
FollowTarget _follow_target
Definition: navigator.h:381
float roll_offset
Definition: vehicle_roi.h:63
uORB::Subscription _parameter_update_sub
param update subscription
Definition: navigator.h:325
uORB::Subscription _traffic_sub
traffic subscription
Definition: navigator.h:327
struct position_setpoint_triplet_s * get_position_setpoint_triplet()
Definition: navigator.h:153
uint16_t item_changed_index
uORB::PublicationQueued< vehicle_command_ack_s > _vehicle_cmd_ack_pub
Definition: navigator.h:339
DataLinkLoss _dataLinkLoss
class that handles the OBC datalink loss mode
Definition: navigator.h:378
param_t _handle_reverse_delay
Definition: navigator.h:386
float _mission_cruising_speed_fw
Definition: navigator.h:391
void set_cruising_throttle(float throttle=-1.0f)
Set the target throttle.
Definition: navigator.h:240
static int task_spawn(int argc, char *argv[])
bool start_mission_landing()
Definition: navigator.h:270
void load_fence_from_file(const char *filename)
Load fence from file.
float yaw_offset
Definition: vehicle_roi.h:65
void publish_vehicle_cmd(vehicle_command_s *vcmd)
float get_loiter_radius()
Definition: navigator.h:171
Takeoff _takeoff
class for handling takeoff commands
Definition: navigator.h:373
float get_default_acceptance_radius()
Returns the default acceptance radius defined by the parameter.
float get_yaw_acceptance(float mission_item_yaw)
Get the yaw acceptance given the current mission item.
~Navigator() override
float distance
Definition: geo.h:70
int loadFromFile(const char *filename)
Load a single inclusion polygon, replacing any already existing polygons.
Definition: geofence.cpp:436
struct position_setpoint_triplet_s * get_reposition_triplet()
Definition: navigator.h:154
RTL _rtl
class that handles RTL
Definition: navigator.h:376
bool on_mission_landing()
Definition: navigator.h:269
bool _pos_sp_triplet_published_invalid_once
flags if position SP triplet has been published once to UORB
Definition: navigator.h:367
orb_advert_t * get_mavlink_log_pub()
Definition: navigator.h:261
bool get_mission_waypoints_changed() const
Definition: mission.h:93
bool update(void *dst)
Update the struct.
uORB::Subscription _land_detected_sub
vehicle land detected subscription
Definition: navigator.h:324
struct vehicle_status_s * get_vstatus()
Definition: navigator.h:159
bool isHomeRequired()
Definition: geofence.cpp:569
void set_mission_result_updated()
Definition: navigator.h:146
bool past_end
Definition: geo.h:69
uORB::Publication< geofence_result_s > _geofence_result_pub
Definition: navigator.h:332
int get_distance_to_line(struct crosstrack_error_s *crosstrack_error, double lat_now, double lon_now, double lat_start, double lon_start, double lat_end, double lon_end)
Definition: geo.cpp:375
float _param_back_trans_dec_mss
Definition: navigator.h:387
Loiter _loiter
class that handles loiter
Definition: navigator.h:372
float _mission_cruising_speed_mc
Definition: navigator.h:390
bool copy(void *dst)
Copy the struct.
void set_mission_failure(const char *reason)
void fake_traffic(const char *callsign, float distance, float direction, float traffic_heading, float altitude_diff, float hor_velocity, float ver_velocity)
Generate an artificial traffic indication.
void publish_mission_result()
Publish the mission result so commander and mavlink know what is going on.
void perf_begin(perf_counter_t handle)
Begin a performance event.
bool _can_loiter_at_sp
flags if current position SP can be used to loiter
Definition: navigator.h:365
float get_altitude_acceptance_radius()
Get the altitude acceptance radius.
uORB::Publication< position_setpoint_triplet_s > _pos_sp_triplet_pub
Definition: navigator.h:334
void set_mode(PrecLandMode mode)
Definition: precland.h:76
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
struct vehicle_local_position_s * get_local_position()
Definition: navigator.h:158
int getSource()
Definition: geofence.h:128
void set_cruising_speed(float speed=-1.0f)
Set the cruising speed.
void run(bool active)