diff --git a/conf/modules/object_tracking.xml b/conf/modules/object_tracking.xml new file mode 100644 index 0000000000..33192ed5b1 --- /dev/null +++ b/conf/modules/object_tracking.xml @@ -0,0 +1,34 @@ + + + + + + Control a rotorcraft heading to track an object detected by a camera + + Data are coming from FOLLOW_TARGET ABI message + +
+ + + + + +
+
+ + + + + + + + +
+ +
+ + + + +
+ diff --git a/sw/airborne/modules/ctrl/object_tracking.c b/sw/airborne/modules/ctrl/object_tracking.c new file mode 100644 index 0000000000..fbe7fd6672 --- /dev/null +++ b/sw/airborne/modules/ctrl/object_tracking.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2018 Gautier Hattenberger + * + * This file is part of paparazzi + * + * paparazzi is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * paparazzi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with paparazzi; see the file COPYING. If not, see + * . + */ +/** + * @file "modules/ctrl/object_tracking.c" + * @author Gautier Hattenberger + * Control a rotorcraft heading to track an object detected by a camera + */ + +#include "modules/ctrl/object_tracking.h" + +#include "firmwares/rotorcraft/navigation.h" +#include "subsystems/abi.h" +#include "generated/airframe.h" +#include "generated/modules.h" + +// ABI message binding ID +#ifndef OBJECT_TRACKING_ID +#define OBJECT_TRACKING_ID ABI_BROADCAST +#endif + +// Timout in seconds before entering search mode +#ifndef OBJECT_TRACKING_TIMEOUT +#define OBJECT_TRACKING_TIMEOUT 3.0f +#endif + +// Turn rate in tracking mode (rad/s) +#ifndef OBJECT_TRACKING_RATE +#define OBJECT_TRACKING_RATE RadOfDeg(10) +#endif + +// Turn rate in search mode (rad/s) +#ifndef OBJECT_TRACKING_SEARCH_RATE +#define OBJECT_TRACKING_SEARCH_RATE RadOfDeg(20) +#endif + +// Send debug message +#ifndef OBJECT_TRACKING_DEBUG +#define OBJECT_TRACKING_DEBUG FALSE +#endif + +#if OBJECT_TRACKING_DEBUG +#include "subsystems/datalink/downlink.h" +#include "pprzlink/messages.h" +#include "mcu_periph/uart.h" +#endif + +float object_tracking_rate; // in rad/s +float object_tracking_search_rate; // in rad/s + +static uint8_t object_frame; // relative or global coordinates +static float object_bearing; +static float object_height; +static float timeout; + +abi_event object_ev; + +static const float nav_dt = 1.f / NAV_FREQ; + +// callback on follow target message +static void get_object(uint8_t sender_id __attribute__((unused)), + uint32_t id __attribute__((unused)), + uint8_t frame, float bearing, float height, + float distance __attribute__((unused))) +{ + object_frame = frame; + object_bearing = bearing; + object_height = height; + timeout = 0.f; +} + +void object_tracking_init(void) +{ + object_tracking_search_rate = OBJECT_TRACKING_SEARCH_RATE; + object_tracking_rate = OBJECT_TRACKING_RATE; + + object_frame = 0; // relative coordinates + object_bearing = 0.f; + object_height = 0.f; + timeout = OBJECT_TRACKING_TIMEOUT; // start in search mode + + // Bind to camera message + AbiBindMsgFOLLOW_TARGET(OBJECT_TRACKING_ID, &object_ev, get_object); +} + +void object_tracking_run(void) +{ + if (timeout < OBJECT_TRACKING_TIMEOUT) { + timeout += nav_dt; + // compute expected heading + float target_heading = object_bearing; + if (!bit_is_set(object_frame, 0)) { + target_heading += stateGetNedToBodyEulers_f()->psi; // relative frame + } + float diff = target_heading - ANGLE_FLOAT_OF_BFP(nav_heading); + FLOAT_ANGLE_NORMALIZE(diff); + BoundAbs(diff, object_tracking_rate * nav_dt) + nav_heading += ANGLE_BFP_OF_REAL(diff); +#if OBJECT_TRACKING_DEBUG + float msg[] = { + target_heading, + object_bearing, + object_height, + timeout + }; + DOWNLINK_SEND_PAYLOAD_FLOAT(DefaultChannel, DefaultDevice, 4, msg); +#endif + } else { + nav_heading += ANGLE_BFP_OF_REAL(object_tracking_search_rate * nav_dt); + } + INT32_COURSE_NORMALIZE(nav_heading); +} + diff --git a/sw/airborne/modules/ctrl/object_tracking.h b/sw/airborne/modules/ctrl/object_tracking.h new file mode 100644 index 0000000000..c3e72a5568 --- /dev/null +++ b/sw/airborne/modules/ctrl/object_tracking.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2018 Gautier Hattenberger + * + * This file is part of paparazzi + * + * paparazzi is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * paparazzi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with paparazzi; see the file COPYING. If not, see + * . + */ +/** + * @file "modules/ctrl/object_tracking.h" + * @author Gautier Hattenberger + * Control a rotorcraft heading to track an object detected by a camera + */ + +#ifndef OBJECT_TRACKING_H +#define OBJECT_TRACKING_H + +#include "std.h" + +/** max turn rate in control mode in rad/s + */ +extern float object_tracking_rate; + +/** max turn rate in search mode in rad/s + */ +extern float object_tracking_search_rate; + +/** init function + */ +extern void object_tracking_init(void); + +/** run function + * + * should be called in a flight plan stay block using pre_call + * + * ex: + * + * + * + * + */ +extern void object_tracking_run(void); + +#endif +