47 #include "physical_constants.h"
51 #include "attitudeactual.h"
52 #include "camerastabsettings.h"
53 #include "cameradesired.h"
54 #include "homelocation.h"
55 #include "manualcontrolcommand.h"
56 #include "modulesettings.h"
58 #include "poilocation.h"
59 #include "positionactual.h"
60 #include "tabletinfo.h"
65 #define SAMPLE_PERIOD_MS 10
66 #define LOAD_DELAY 7000
76 float inputs[CAMERASTABSETTINGS_INPUT_NUMELEM];
85 void *ctx,
void *obj,
int len);
87 void *ctx,
void *obj,
int len);
88 static void applyFF(uint8_t index,
float dT_ms,
float *attitude, CameraStabSettingsData* cameraStab);
91 #if defined(CAMERASTAB_POI_MODE)
92 static void tablet_info_flag_update(
const UAVObjEvent *ev,
93 void *ctx,
void *obj,
int len);
94 static void tablet_info_process();
95 static bool tablet_info_updated =
false;
108 #ifdef MODULE_CameraStab_BUILTIN
109 module_enabled =
true;
111 uint8_t module_state[MODULESETTINGS_ADMINSTATE_NUMELEM];
112 ModuleSettingsAdminStateGet(module_state);
113 if (module_state[MODULESETTINGS_ADMINSTATE_CAMERASTAB] == MODULESETTINGS_ADMINSTATE_ENABLED) {
114 module_enabled =
true;
116 module_enabled =
false;
120 if (CameraStabSettingsInitialize() == -1) {
121 module_enabled =
false;
125 if (module_enabled) {
130 module_enabled =
false;
138 if (AttitudeActualInitialize() == -1 || CameraDesiredInitialize() == -1) {
139 module_enabled =
false;
145 #if defined(CAMERASTAB_POI_MODE)
146 if (PoiLocationInitialize() == -1 || TabletInfoInitialize() == -1) {
147 module_enabled =
false;
150 TabletInfoConnectCallback(tablet_info_flag_update);
168 .
obj = AttitudeActualHandle(),
184 void *ctx,
void *obj,
int len)
186 (void) ev; (void) ctx; (void) obj; (void) len;
187 if (ev->obj != AttitudeActualHandle())
190 float accessories[MANUALCONTROLCOMMAND_ACCESSORY_NUMELEM];
192 ManualControlCommandAccessoryGet(accessories);
212 AttitudeActualRollGet(&attitude);
215 AttitudeActualPitchGet(&attitude);
218 AttitudeActualYawGet(&attitude);
221 float rt_ms = (float)settings->AttitudeFilter;
226 if (settings->Input[
i] != CAMERASTABSETTINGS_INPUT_NONE && settings->Input[
i] != CAMERASTABSETTINGS_INPUT_POI) {
227 int idx = settings->Input[
i] - CAMERASTABSETTINGS_INPUT_ACCESSORY0;
229 if ((idx >= 0) && (idx < MANUALCONTROLCOMMAND_ACCESSORY_NUMELEM)) {
232 rt_ms = (float) settings->InputFilter;
233 switch (settings->StabilizationMode[
i]) {
234 case CAMERASTABSETTINGS_STABILIZATIONMODE_ATTITUDE:
235 input = accessories[idx] * settings->InputRange[
i];
236 csd->
inputs[
i] = (rt_ms / (rt_ms + dT_ms)) *
csd->
inputs[
i] + (dT_ms / (rt_ms + dT_ms)) * input;
238 case CAMERASTABSETTINGS_STABILIZATIONMODE_AXISLOCK:
239 input_rate = accessories[idx] * settings->InputRate[
i];
240 if (fabsf(input_rate) > settings->MaxAxisLockRate)
258 #if defined(CAMERASTAB_POI_MODE)
259 else if (settings->Input[
i] == CAMERASTABSETTINGS_INPUT_POI) {
262 tablet_info_process();
264 PositionActualData positionActual;
265 PositionActualGet(&positionActual);
267 PoiLocationGet(&poi);
271 dLoc[0] = poi.North - positionActual.North;
272 dLoc[1] = poi.East - positionActual.East;
273 dLoc[2] = poi.Down - positionActual.Down;
276 float distance = sqrtf(powf(dLoc[0], 2) + powf(dLoc[1], 2));
277 float pitch = atan2f(-dLoc[2], distance) * RAD2DEG;
278 float yaw = atan2f(dLoc[1], dLoc[0]) * RAD2DEG;
285 case CAMERASTABSETTINGS_INPUT_ROLL:
288 case CAMERASTABSETTINGS_INPUT_PITCH:
290 CameraDesiredDeclinationSet(&pitch);
293 case CAMERASTABSETTINGS_INPUT_YAW:
294 CameraDesiredBearingSet(&yaw);
303 applyFF(
i, dT_ms, &attitude, settings);
310 CameraDesiredRollSet(&output);
313 CameraDesiredPitchSet(&output);
316 CameraDesiredYawSet(&output);
333 static void applyFF(uint8_t index,
float dT_ms,
float *attitude, CameraStabSettingsData* cameraStab)
337 accumulator += (*attitude -
csd->
FFlastAttitude[index]) * cameraStab->FeedForward[index];
339 *attitude += accumulator;
341 float filter = (
float) cameraStab->FeedForwardTime / dT_ms;
343 accumulator -= accumulator / filter;
349 *attitude += accumulator;
353 float maxDelta = cameraStab->MaxAccel * dT_ms / 1000.0f;
354 if(fabsf(delta) > maxDelta)
366 void *ctx,
void *obj,
int len)
368 (void) ev; (void) ctx; (void) obj; (void) len;
373 #if defined(CAMERASTAB_POI_MODE)
378 static void tablet_info_flag_update(
const UAVObjEvent *ev,
379 void *ctx,
void *obj,
int len)
381 (void) ev; (void) ctx; (void) obj; (void) len;
383 if (ev->
obj == NULL || ev->
obj != TabletInfoHandle())
386 tablet_info_updated =
true;
392 static void tablet_info_process() {
395 if (tablet_info_updated ==
false)
397 tablet_info_updated =
false;
399 TabletInfoData tablet;
400 TabletInfoGet(&tablet);
401 if (tablet.Connected == TABLETINFO_CONNECTED_TRUE && tablet.POI == TABLETINFO_POI_TRUE)
404 HomeLocationGet(&homeLocation);
409 lat = homeLocation.Latitude / 10.0e6f * DEG2RAD;
410 alt = homeLocation.Altitude;
413 T[0] = alt+6.378137E6f;
414 T[1] = cosf(lat)*(alt+6.378137E6f);
417 float dL[3] = {(tablet.Latitude - homeLocation.Latitude) / 10.0e6f * DEG2RAD,
418 (tablet.Longitude - homeLocation.Longitude) / 10.0e6f * DEG2RAD,
421 poi.North = T[0] * dL[0];
422 poi.East = T[1] * dL[1];
423 poi.Down = T[2] * dL[2];
424 PoiLocationSet(&poi);
431 #if defined(PIOS_INCLUDE_CAN)
440 #if defined(PIOS_INCLUDE_CAN)
441 AttitudeActualData attitude;
442 AttitudeActualGet(&attitude);
444 CameraDesiredData cameraDesired;
445 CameraDesiredGet(&cameraDesired);
449 .fc_pitch = attitude.Pitch,
450 .fc_yaw = attitude.Yaw,
452 .setpoint_pitch = cameraDesired.Declination,
453 .setpoint_yaw = cameraDesired.Bearing
uint32_t PIOS_Thread_Systime(void)
static struct CameraStab_data * csd
CameraStabSettingsData settings
struct _msp_pid_item pitch
static void settings_updated_cb(const UAVObjEvent *ev, void *ctx, void *obj, int len)
float FFfilterAccumulator[MAX_AXES]
void * PIOS_malloc(size_t size)
int32_t CameraStabInitialize(void)
static float T[3]
Scales used in NED transform (local tangent plane approx).
float FFlastFilteredAttitude[MAX_AXES]
int32_t EventPeriodicCallbackCreate(UAVObjEvent *ev, UAVObjEventCallback cb, uint16_t periodMs)
float attitude_filtered[MAX_AXES]
float inputs[CAMERASTABSETTINGS_INPUT_NUMELEM]
static void gimbal_can_message()
#define MODULE_INITCALL(ifn, sfn)
float FFlastAttitude[MAX_AXES]
static volatile FlightStatsSettingsData settings
int32_t CameraStabStart(void)
Event dispatcher, distributes object events as callbacks. Alternative to using tasks and queues...
int32_t PIOS_CAN_TxData(uintptr_t id, enum pios_can_messages, uint8_t *data)
Transmit a data message with a particular message ID.
static HomeLocationData homeLocation
float bound_sym(float val, float range)
Bound input value within range (plus or minus)
static void attitudeUpdated(const UAVObjEvent *ev, void *ctx, void *obj, int len)
Message to tell gimbal the desired setpoint and FC state.
Includes PiOS and core architecture components.
PiOS CAN interface header.
static void applyFF(uint8_t index, float dT_ms, float *attitude, CameraStabSettingsData *cameraStab)