-
Notifications
You must be signed in to change notification settings - Fork 4
/
joystick_ppm.cpp
162 lines (132 loc) · 4.24 KB
/
joystick_ppm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "joystick_ppm.h"
#include <cmath>
#include <iostream>
ppm_mixer::ppm_mixer(ppm_target& target)
: m_target(target)
{}
void ppm_mixer::set_mixing_value(unsigned char ppm_channel_id,
float value,
int mixing_id,
bool no_write)
{
this->m_map[ppm_channel_id][mixing_id] = value;
float fSum = 0.0f;
for (auto v : this->m_map[ppm_channel_id])
{
fSum += v.second;
}
if (!no_write)
this->m_target.setChannelValue(ppm_channel_id,
fSum);
}
int joystick_ppm::axis_mapping_target::s_mixingid_counter = -2;
joystick_ppm::joystick_ppm(const configuration& config, ppm_target& target)
: m_config(config),
m_mixer(target)
{
}
void joystick_ppm::onAxisUpdated(unsigned char number)
{
// check if there is a mapping
auto item = this->m_config.AxisMappings.find(number);
auto value = this->get_axis(number);
if (item != this->m_config.AxisMappings.end())
{
// calc mapping
auto& mapping = item->second;
// apply trim
value += mapping.user_trim;
// apply factor
value *= mapping.factor;
// apply expo. this is from https://www.rcgroups.com/forums/showpost.php?p=38339227&postcount=6
value = ((1 - mapping.expo) * std::pow(value, 3.0f)) + (mapping.expo * value);
// apply offset
value += mapping.offset;
// set value
this->m_mixer.set_mixing_value(mapping.ppm_channel_id,
value,
mapping.mixing_id);
}
// check if this axis is to be buttonized
auto item2 = this->m_config.Buttonizations.find(number);
if (item2 != this->m_config.Buttonizations.end())
{
// check if low or high
auto& virt = item2->second;
this->updateVirtualButton(virt.low_button_id, (value < -0.5));
this->updateVirtualButton(virt.high_button_id, (value > 0.5));
}
}
void joystick_ppm::updateVirtualButton(unsigned char number, bool value)
{
bool bUpdate = true;
auto item = this->m_mapVirtualButtons.find(number);
if (item != this->m_mapVirtualButtons.end())
{
bUpdate = item->second != value;
}
this->m_mapVirtualButtons[number] = value;
if (bUpdate)
{
this->put_button(number, value);
}
}
void joystick_ppm::onButtonUpdated(unsigned char number)
{
// get value first
auto value = this->get_button(number);
// check if there is a mapping
auto& map = (value ? this->m_config.ButtonPressActions : this->m_config.ButtonReleaseActions);
auto item = map.find(number);
if (item != map.end())
{
auto& action = item->second;
if (action.type == ButtonActionType::SetValue)
{
// directly setting value is easy-cheesy
this->m_mixer.set_mixing_value(action.axis_or_channel_id, action.value);
}
else if (action.type == ButtonActionType::AddTrim)
{
// we are going to modify trim
auto axis = this->m_config.AxisMappings.find(action.axis_or_channel_id);
if (axis != this->m_config.AxisMappings.end())
{
auto& mapping = axis->second;
if (action.type == ButtonActionType::AddTrim)
mapping.user_trim += action.value;
// re-calc the axis and send to the PPM stream
this->onAxisUpdated(action.axis_or_channel_id);
// save config
this->saveTrimValue(action.axis_or_channel_id, mapping.user_trim);
}
}
else if (action.type == ButtonActionType::AddSubTrim)
{
// save subtrim in our map
auto& subtrim = this->m_mapSubtrims[action.axis_or_channel_id];
subtrim += action.value;
// write to PPM stream. mixing id "-1" == subtrim
this->m_mixer.set_mixing_value(action.axis_or_channel_id, subtrim, -1);
// save config
this->saveSubtrimValue(action.axis_or_channel_id, subtrim);
}
}
}
void joystick_ppm::loadUserTrim(unsigned char axis_number, float trim)
{
auto axis = this->m_config.AxisMappings.find(axis_number);
if (axis != this->m_config.AxisMappings.end())
{
auto& mapping = axis->second;
mapping.user_trim = trim;
}
}
void joystick_ppm::loadUserSubtrim(unsigned char ppm_channel_id, float subtrim)
{
this->m_mapSubtrims[ppm_channel_id] = subtrim;
// also save in mixer
this->m_mixer.set_mixing_value(ppm_channel_id, subtrim, -1, true);
}
void joystick_ppm::saveTrimValue(unsigned char axis_number, float trim) {}
void joystick_ppm::saveSubtrimValue(unsigned char axis_number, float trim) {}