Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
cam_gimbal.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2003 Pascal Brisset, Antoine Drouin
3 * 2025 Gautier Hattenberger <gautier.hattenberger@enac.fr>
4 *
5 * This file is part of paparazzi.
6 *
7 * paparazzi is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * paparazzi is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with paparazzi; see the file COPYING. If not, write to
19 * the Free Software Foundation, 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 *
22 */
28#include "cam_gimbal.h"
29#include "autopilot.h"
30#if FIXEDWING_FIRMWARE
32#else
34#endif
35#include "generated/modules.h"
36#include "generated/airframe.h"
38#include "state.h"
39#include "modules/core/abi.h"
41
42// Default idle command
43#ifndef CAM_GIMBAL_PAN0
44#define CAM_GIMBAL_PAN0 0
45#endif
46#ifndef CAM_GIMBAL_TILT0
47#define CAM_GIMBAL_TILT0 0
48#endif
49
50// Minimum and maximum angles
51// used to convert angles to commands, assuming a linear interpolation
52#ifndef CAM_GIMBAL_PAN_MAX
53#define CAM_GIMBAL_PAN_MAX RadOfDeg(90.f)
54#endif
55#ifndef CAM_GIMBAL_PAN_MIN
56#define CAM_GIMBAL_PAN_MIN -CAM_GIMBAL_PAN_MAX
57#endif
58#ifndef CAM_GIMBAL_TILT_MAX
59#define CAM_GIMBAL_TILT_MAX RadOfDeg(90.f)
60#endif
61#ifndef CAM_GIMBAL_TILT_MIN
62#define CAM_GIMBAL_TILT_MIN -CAM_GIMBAL_TILT_MAX
63#endif
64
65// Default position and orientation of the gimbal in body frame
66#ifndef CAM_GIMBAL_POS_X
67#define CAM_GIMBAL_POS_X 0.f
68#endif
69#ifndef CAM_GIMBAL_POS_Y
70#define CAM_GIMBAL_POS_Y 0.f
71#endif
72#ifndef CAM_GIMBAL_POS_Z
73#define CAM_GIMBAL_POS_Z 0.f
74#endif
75#ifndef CAM_GIMBAL_TO_BODY_PHI
76#define CAM_GIMBAL_TO_BODY_PHI 0.f
77#endif
78#ifndef CAM_GIMBAL_TO_BODY_THETA
79#define CAM_GIMBAL_TO_BODY_THETA 0.f
80#endif
81#ifndef CAM_GIMBAL_TO_BODY_PSI
82#define CAM_GIMBAL_TO_BODY_PSI 0.f
83#endif
84
85// Global cam structure
87
88// ABI message bind
90
92{
95}
96
97static void send_cam(struct transport_tx *trans, struct link_device *dev)
98{
103 pprz_msg_send_CAM(trans, dev, AC_ID, &phi, &theta, &x, &y);
104}
105
106#if CAM_SHOW_COORDINATES
107static void send_cam_point(struct transport_tx *trans, struct link_device *dev)
108{
109 struct LlaCoor_f target_lla;
110 struct EcefCoor_f target_ecef;
115}
116#endif
117
127static void default_compute_angles(struct FloatVect3 dir, float *pan, float *tilt)
128{
129 *pan = atan2f(dir.y, dir.x);
130 *tilt = asinf(-dir.z);
131}
132
134static void cam_gimbal_angles(struct CamGimbal *cam)
135{
136 Bound(cam->pan_angle, cam->pan_min, cam->pan_max);
137 Bound(cam->tilt_angle, cam->tilt_min, cam->tilt_max);
138
139 if (!cam->lock) {
140 float delta_pan = cam->pan_max - cam->pan_min;
141 float delta_tilt = cam->tilt_max - cam->tilt_min;
142 cam->pan_cmd = (int16_t) MAX_PPRZ * ((2.f / delta_pan) * (cam->pan_angle - cam->pan_min) - 1.f);
143 cam->tilt_cmd = (int16_t) MAX_PPRZ * ((2.f / delta_tilt) * (cam->tilt_angle - cam->tilt_min) - 1.f);
144 }
145}
146
148static void cam_gimbal_target(struct CamGimbal *cam)
149{
151 struct NedCoor_f pos = *stateGetPositionNed_f();
152 struct NedCoor_f target;
153 ENU_OF_TO_NED(target, cam->target_pos);
154
155 // compute looking direction in gimbal frame
156 // o: Earth frame (ltp)
157 // b: body frame
158 // g: gimbal frame
159 // D/o = normalized(Pt/o - Pg/o = Pt/o - (Pb/o + Pg/b))
160 struct FloatVect3 dir_ltp;
162 VECT3_SUB(dir_ltp, cam->gimbal_pos);
164 // rotate D/o to get D/g = Rg/o D/o = inv(Rb/g) Rb/o D/o
165 struct FloatVect3 dir_body;
167 struct FloatVect3 dir_gimbal;
168 float_rmat_transp_vmult(&dir_gimbal, &cam->gimbal_to_body, &dir_body);
169 // compute angles from direction
170 cam->compute_angles(dir_gimbal, &cam->pan_angle, &cam->tilt_angle);
171 // apply angles
173}
174
176static void cam_gimbal_nadir(struct CamGimbal *cam)
177{
179 target.z -= 10.f; // force looking below current position
182}
183
184
186{
187 if (cam->target_wp_id < nb_waypoint) {
188 struct EnuCoor_f target;
189 target.x = WaypointX(cam->target_wp_id);
190 target.y = WaypointY(cam->target_wp_id);
191 target.z = Min(0.f, stateGetPositionEnu_f()->z); // ground alt or A/C alt if lower
194 }
195}
196
198{
199#ifdef TRAFFIC_INFO
200 struct EnuCoor_f target = *acInfoGetPositionEnu_f(cam.target_ac_id);
202#endif
203}
204
206{
207 cam_gimbal_set_pan_command(cam, cam->pan_joystick);
208 cam_gimbal_set_tilt_command(cam, cam->tilt_joystick);
209}
210
212 float pan_max, float pan_min,
213 float tilt_max, float tilt_min)
214{
215 cam->pan_max = pan_max;
216 cam->pan_min = pan_min;
217 cam->tilt_max = tilt_max;
218 cam->tilt_min = tilt_min;
219}
220
223 struct FloatVect3 gimbal_pos)
224{
226 cam->gimbal_pos = gimbal_pos;
227}
228
230{
231 cam->compute_angles = compute_angles;
232}
233
235{
236 if (mode < CAM_GIMBAL_MODE_NB) {
237 cam->mode = mode;
238 } else {
239 cam->mode = CAM_GIMBAL_MODE_OFF;
240 }
241}
242
243void cam_gimbal_set_lock(struct CamGimbal *cam, bool lock)
244{
245 cam->lock = lock;
246}
247
249{
250 cam->pan_cmd = TRIM_PPRZ(pan);
251}
252
254{
255 cam->tilt_cmd = TRIM_PPRZ(tilt);
256}
257
258void cam_gimbal_set_angles_rad(struct CamGimbal *cam, float pan, float tilt)
259{
260 cam->pan_angle = pan;
261 cam->tilt_angle = tilt;
262 Bound(cam->pan_angle, cam->pan_min, cam->pan_max);
263 Bound(cam->tilt_angle, cam->tilt_min, cam->tilt_max);
264}
265
266void cam_gimbal_set_angles_deg(struct CamGimbal *cam, float pan, float tilt)
267{
268 cam->pan_angle = RadOfDeg(pan);
269 cam->tilt_angle = RadOfDeg(tilt);
270 Bound(cam->pan_angle, cam->pan_min, cam->pan_max);
271 Bound(cam->tilt_angle, cam->tilt_min, cam->tilt_max);
272}
273
275{
276 cam->target_pos = target;
277}
278
280{
281 if (wp_id < nb_waypoint) {
282 cam->target_wp_id = wp_id;
283 }
284}
285
287{
288 cam->target_ac_id = ac_id;
289}
290
291
295{
296 switch (cam->mode) {
300 break;
303 break;
306 break;
309 break;
312 break;
315 break;
318 break;
319 default:
320 break;
321 }
322}
323
352
356{
358
359 // update command if possible
360#ifdef COMMAND_CAM_PAN
362#endif
363#ifdef COMMAND_CAM_TILT
365#endif
366}
367
Main include for ABI (AirBorneInterface).
#define ABI_BROADCAST
Broadcast address.
Definition abi_common.h:58
Event structure to store callbacks in a linked list.
Definition abi_common.h:67
Core autopilot interface common to all firmwares.
#define CAM_GIMBAL_TILT0
Definition cam_gimbal.c:47
void cam_gimbal_set_tilt_command(struct CamGimbal *cam, int16_t tilt)
Definition cam_gimbal.c:253
void cam_gimbal_set_angles_deg(struct CamGimbal *cam, float pan, float tilt)
Definition cam_gimbal.c:266
void cam_gimbal_run(struct CamGimbal *cam)
Run camera control.
Definition cam_gimbal.c:294
void cam_gimbal_set_mode(struct CamGimbal *cam, uint8_t mode)
Definition cam_gimbal.c:234
static void send_cam(struct transport_tx *trans, struct link_device *dev)
Definition cam_gimbal.c:97
#define CAM_GIMBAL_POS_Z
Definition cam_gimbal.c:73
static void cam_gimbal_nadir(struct CamGimbal *cam)
Point straight down.
Definition cam_gimbal.c:176
#define CAM_GIMBAL_TO_BODY_PHI
Definition cam_gimbal.c:76
#define CAM_GIMBAL_PAN0
Definition cam_gimbal.c:44
static void cam_gimbal_angles(struct CamGimbal *cam)
Computes the servo values from pan and tilt angles.
Definition cam_gimbal.c:134
void cam_gimbal_init(void)
Init module.
Definition cam_gimbal.c:326
void cam_gimbal_set_wp_id(struct CamGimbal *cam, uint8_t wp_id)
Definition cam_gimbal.c:279
void cam_gimbal_set_lock(struct CamGimbal *cam, bool lock)
Definition cam_gimbal.c:243
static void joystick_cb(uint8_t sender_id UNUSED, int16_t roll, int16_t pitch, int16_t yaw UNUSED, int16_t throttle UNUSED)
Definition cam_gimbal.c:91
#define CAM_GIMBAL_POS_Y
Definition cam_gimbal.c:70
static void cam_gimbal_target(struct CamGimbal *cam)
Computes the right angles from target position.
Definition cam_gimbal.c:148
void cam_gimbal_set_target_pos(struct CamGimbal *cam, struct EnuCoor_f target)
Definition cam_gimbal.c:274
void cam_gimbal_set_ac_id(struct CamGimbal *cam, uint8_t ac_id)
Definition cam_gimbal.c:286
static void cam_gimbal_joystick(struct CamGimbal *cam UNUSED)
Definition cam_gimbal.c:205
#define CAM_GIMBAL_TO_BODY_PSI
Definition cam_gimbal.c:82
static void default_compute_angles(struct FloatVect3 dir, float *pan, float *tilt)
Default callback function to compute gimbal pan/tilt angle from a looking direction (unit vector in g...
Definition cam_gimbal.c:127
#define CAM_GIMBAL_TILT_MIN
Definition cam_gimbal.c:62
void cam_gimbal_setup_angles(struct CamGimbal *cam, float pan_max, float pan_min, float tilt_max, float tilt_min)
Definition cam_gimbal.c:211
#define CAM_GIMBAL_PAN_MIN
Definition cam_gimbal.c:56
static abi_event joystick_ev
Definition cam_gimbal.c:89
#define CAM_GIMBAL_PAN_MAX
Definition cam_gimbal.c:53
void cam_gimbal_periodic(void)
Periodic call (run control)
Definition cam_gimbal.c:355
static void cam_gimbal_waypoint_target(struct CamGimbal *cam)
Definition cam_gimbal.c:185
#define CAM_GIMBAL_TO_BODY_THETA
Definition cam_gimbal.c:79
#define CAM_GIMBAL_TILT_MAX
Definition cam_gimbal.c:59
void cam_gimbal_set_angles_callback(struct CamGimbal *cam, cam_angles_from_dir compute_angles)
Definition cam_gimbal.c:229
void cam_gimbal_setup_mounting(struct CamGimbal *cam, struct FloatEulers gimbal_to_body_eulers, struct FloatVect3 gimbal_pos)
Definition cam_gimbal.c:221
#define CAM_GIMBAL_POS_X
Definition cam_gimbal.c:67
void cam_gimbal_set_angles_rad(struct CamGimbal *cam, float pan, float tilt)
Definition cam_gimbal.c:258
struct CamGimbal cam_gimbal
Definition cam_gimbal.c:86
static void cam_gimbal_ac_target(struct CamGimbal *cam UNUSED)
Definition cam_gimbal.c:197
void cam_gimbal_set_pan_command(struct CamGimbal *cam, int16_t pan)
Definition cam_gimbal.c:248
Pan/Tilt camera gimbal control.
int16_t tilt_cmd
tilt command [pprz]
Definition cam_gimbal.h:60
#define CAM_GIMBAL_MODE_TARGET
Definition cam_gimbal.h:39
float pan_angle
pan angle [rad]
Definition cam_gimbal.h:71
#define CAM_GIMBAL_MODE_OFF
Definition cam_gimbal.h:35
int16_t pan_cmd
pan command [pprz]
Definition cam_gimbal.h:59
#define CAM_GIMBAL_MODE_ANGLES
Definition cam_gimbal.h:37
#define CAM_GIMBAL_MODE_JOYSTICK
Definition cam_gimbal.h:36
#define CAM_GIMBAL_MODE_NB
Definition cam_gimbal.h:42
int16_t pan_joystick
pan command from joystick
Definition cam_gimbal.h:76
struct EnuCoor_f target_pos
target point in ENU world frame [m]
Definition cam_gimbal.h:73
float tilt_angle
tilt angle [rad]
Definition cam_gimbal.h:72
void(* cam_angles_from_dir)(struct FloatVect3 dir, float *pan, float *tilt)
Function pointer to return cam angle from a specified direction.
Definition cam_gimbal.h:53
#define CAM_GIMBAL_MODE_NADIR
Definition cam_gimbal.h:38
int16_t tilt_joystick
tilt command from joystick
Definition cam_gimbal.h:77
#define CAM_GIMBAL_MODE_AC_TARGET
Definition cam_gimbal.h:41
#define CAM_GIMBAL_MODE_WAYPOINT
Definition cam_gimbal.h:40
#define UNUSED(x)
Hardware independent code for commands handling.
const uint8_t nb_waypoint
Definition common_nav.c:43
#define WaypointX(_wp)
Definition common_nav.h:45
#define WaypointY(_wp)
Definition common_nav.h:46
#define Min(x, y)
Definition esc_dshot.c:109
static struct EnuCoor_f * acInfoGetPositionEnu_f(uint8_t ac_id)
Get position in local ENU coordinates (float).
#define float_rmat_of_eulers
void float_rmat_transp_vmult(struct FloatVect3 *vb, struct FloatRMat *m_b2a, struct FloatVect3 *va)
rotate 3D vector by transposed rotation matrix.
static void float_vect3_normalize(struct FloatVect3 *v)
normalize 3D vector in place
void float_rmat_vmult(struct FloatVect3 *vb, struct FloatRMat *m_a2b, struct FloatVect3 *va)
rotate 3D vector by rotation matrix.
euler angles
rotation matrix
#define VECT3_SUB(_a, _b)
#define VECT3_DIFF(_c, _a, _b)
#define ENU_OF_TO_NED(_po, _pi)
static struct FloatRMat * stateGetNedToBodyRMat_f(void)
Get vehicle body attitude rotation matrix (float).
Definition state.h:1300
static struct LtpDef_f * stateGetNedOrigin_f(void)
Get the coordinate NED frame origin (float)
Definition state.h:566
static struct EnuCoor_f * stateGetPositionEnu_f(void)
Get position in local ENU coordinates (float).
Definition state.h:848
static struct NedCoor_f * stateGetPositionNed_f(void)
Get position in local NED coordinates (float).
Definition state.h:839
uint16_t foo
Definition main_demo5.c:58
#define MAX_PPRZ
Definition paparazzi.h:8
#define TRIM_PPRZ(pprz)
Definition paparazzi.h:11
void ecef_of_enu_point_f(struct EcefCoor_f *ecef, struct LtpDef_f *def, struct EnuCoor_f *enu)
void lla_of_ecef_f(struct LlaCoor_f *out, struct EcefCoor_f *in)
float y
in meters
float x
in meters
float z
in meters
vector in EarthCenteredEarthFixed coordinates
vector in East North Up coordinates Units: meters
vector in Latitude, Longitude and Altitude
vector in North East Down coordinates Units: meters
static const float dir[]
static uint8_t mode
mode holds the current sonar mode mode = 0 used at high altitude, uses 16 wave patterns mode = 1 used...
Definition sonar_bebop.c:65
API to get/set the generic vehicle states.
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
struct target_t target
Definition target_pos.c:65
int16_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint16_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition telemetry.h:66
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
short int16_t
Typedef defining 16 bit short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.