2 * This file is part of INAV.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with INAV. If not, see <http://www.gnu.org/licenses/>.
20 #ifdef USE_HEADTRACKER
27 #include <build/debug.h>
28 #include <config/parameter_group_ids.h>
30 #include "settings_generated.h"
32 #include "common/time.h"
33 #include "common/maths.h"
35 #include "drivers/time.h"
41 #include "drivers/headtracker_common.h"
43 PG_REGISTER_WITH_RESET_TEMPLATE(headTrackerConfig_t
, headTrackerConfig
, PG_HEADTRACKER_CONFIG
, 1);
45 PG_RESET_TEMPLATE(headTrackerConfig_t
, headTrackerConfig
,
46 .devType
= SETTING_HEADTRACKER_TYPE_DEFAULT
,
47 .pan_ratio
= SETTING_HEADTRACKER_PAN_RATIO_DEFAULT
,
48 .tilt_ratio
= SETTING_HEADTRACKER_TILT_RATIO_DEFAULT
,
49 .roll_ratio
= SETTING_HEADTRACKER_ROLL_RATIO_DEFAULT
,
52 static headTrackerDevice_t
*commonHeadTrackerDevice
= NULL
;
54 void headTrackerCommonInit(void)
58 void headTrackerCommonSetDevice(headTrackerDevice_t
*headTrackerDevice
)
60 SD(fprintf(stderr
, "[headTracker]: device added %p\n", headTrackerDevice
));
61 commonHeadTrackerDevice
= headTrackerDevice
;
64 headTrackerDevice_t
*headTrackerCommonDevice(void)
66 return commonHeadTrackerDevice
;
69 void headTrackerCommonProcess(headTrackerDevice_t
*headTrackerDevice
, timeUs_t currentTimeUs
)
71 if (headTrackerDevice
&& headTrackerDevice
->vTable
->process
&& headTrackerCommonIsReady(headTrackerDevice
)) {
72 headTrackerDevice
->vTable
->process(headTrackerDevice
, currentTimeUs
);
76 headTrackerDevType_e
headTrackerCommonGetDeviceType(const headTrackerDevice_t
*headTrackerDevice
)
78 if (!headTrackerDevice
|| !headTrackerDevice
->vTable
->getDeviceType
) {
79 return HEADTRACKER_UNKNOWN
;
82 return headTrackerDevice
->vTable
->getDeviceType(headTrackerDevice
);
85 bool headTrackerCommonIsReady(const headTrackerDevice_t
*headTrackerDevice
)
87 if (headTrackerDevice
&& headTrackerDevice
->vTable
->isReady
) {
88 return headTrackerDevice
->vTable
->isReady(headTrackerDevice
);
93 int headTrackerCommonGetPan(const headTrackerDevice_t
*headTrackerDevice
)
95 if(headTrackerDevice
&& headTrackerDevice
->vTable
&& headTrackerDevice
->vTable
->getPan
) {
96 return headTrackerDevice
->vTable
->getPan(headTrackerDevice
);
99 return constrain((headTrackerDevice
->pan
* headTrackerConfig()->pan_ratio
) + 0.5f
, HEADTRACKER_RANGE_MIN
, HEADTRACKER_RANGE_MAX
);
102 int headTrackerCommonGetTilt(const headTrackerDevice_t
*headTrackerDevice
)
104 if(headTrackerDevice
&& headTrackerDevice
->vTable
&& headTrackerDevice
->vTable
->getTilt
) {
105 return headTrackerDevice
->vTable
->getTilt(headTrackerDevice
);
108 return constrain((headTrackerDevice
->tilt
* headTrackerConfig()->tilt_ratio
) + 0.5f
, HEADTRACKER_RANGE_MIN
, HEADTRACKER_RANGE_MAX
);
111 int headTrackerCommonGetRoll(const headTrackerDevice_t
*headTrackerDevice
)
113 if(headTrackerDevice
&& headTrackerDevice
->vTable
&& headTrackerDevice
->vTable
->getRoll
) {
114 return headTrackerDevice
->vTable
->getRollPWM(headTrackerDevice
);
117 return constrain((headTrackerDevice
->roll
* headTrackerConfig()->roll_ratio
) + 0.5f
, HEADTRACKER_RANGE_MIN
, HEADTRACKER_RANGE_MAX
);
120 int headTracker2PWM(int value
)
122 return constrain(scaleRange(value
, HEADTRACKER_RANGE_MIN
, HEADTRACKER_RANGE_MAX
, PWM_RANGE_MIN
, PWM_RANGE_MAX
), PWM_RANGE_MIN
, PWM_RANGE_MAX
);
125 int headTrackerCommonGetPanPWM(const headTrackerDevice_t
*headTrackerDevice
)
127 if(headTrackerDevice
&& headTrackerDevice
->vTable
&& headTrackerDevice
->vTable
->getPanPWM
) {
128 return headTrackerDevice
->vTable
->getPanPWM(headTrackerDevice
);
131 return headTracker2PWM(headTrackerCommonGetPan(headTrackerDevice
));
134 int headTrackerCommonGetTiltPWM(const headTrackerDevice_t
*headTrackerDevice
)
136 if(headTrackerDevice
&& headTrackerDevice
->vTable
&& headTrackerDevice
->vTable
->getTiltPWM
) {
137 return headTrackerDevice
->vTable
->getTiltPWM(headTrackerDevice
);
140 return headTracker2PWM(headTrackerCommonGetTilt(headTrackerDevice
));
143 int headTrackerCommonGetRollPWM(const headTrackerDevice_t
*headTrackerDevice
)
145 if(headTrackerDevice
&& headTrackerDevice
->vTable
&& headTrackerDevice
->vTable
->getRollPWM
) {
146 return headTrackerDevice
->vTable
->getRollPWM(headTrackerDevice
);
149 return headTracker2PWM(headTrackerCommonGetRoll(headTrackerDevice
));
153 #ifdef headTracker_UNIT_TEST
154 void taskUpdateHeadTracker(timeUs_t currentTimeUs
)
158 void taskUpdateHeadTracker(timeUs_t currentTimeUs
)
164 headTrackerDevice_t
*headTrackerDevice
= headTrackerCommonDevice();
166 if(headTrackerDevice
) {
167 headTrackerCommonProcess(headTrackerDevice
, currentTimeUs
);
171 // TODO: check if any headTracker types are enabled
172 bool headTrackerCommonIsEnabled(void)
174 if (commonHeadTrackerDevice
&& headTrackerCommonIsReady(commonHeadTrackerDevice
)) {
181 bool headTrackerCommonIsValid(const headTrackerDevice_t
*dev
) {
182 if(dev
&& dev
->vTable
&& dev
->vTable
->isValid
) {
183 return dev
->vTable
->isValid(dev
);
186 return micros() < dev
->expires
;