2 ******************************************************************************
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @addtogroup GCSPlugins GCS Plugins
8 * @addtogroup ConfigPlugin Config Plugin
10 * @brief A MixerCurve Gadget used to update settings in the firmware
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "mixercurve.h"
30 #include "ui_mixercurve.h"
32 #include "dblspindelegate.h"
35 #include <QResizeEvent>
38 MixerCurve::MixerCurve(QWidget
*parent
) :
40 m_mixerUI(new Ui::MixerCurve
)
42 m_mixerUI
->setupUi(this);
44 // setup some convienence pointers
45 m_curve
= m_mixerUI
->CurveWidget
;
46 m_settings
= m_mixerUI
->CurveSettings
;
49 m_mixerUI
->SettingsGroup
->hide();
51 // create our spin delegate
52 m_spinDelegate
= new DoubleSpinDelegate();
54 // set the default mixer type
55 setMixerType(MixerCurve::MIXERCURVE_THROTTLE
);
60 // wire up our signals
61 connect(m_mixerUI
->CurveType
, SIGNAL(currentIndexChanged(int)), this, SLOT(CurveTypeChanged()));
62 connect(m_mixerUI
->ResetCurve
, SIGNAL(clicked()), this, SLOT(ResetCurve()));
63 connect(m_mixerUI
->PopupCurve
, SIGNAL(clicked()), this, SLOT(PopupCurve()));
64 connect(m_mixerUI
->GenerateCurve
, SIGNAL(clicked()), this, SLOT(GenerateCurve()));
65 connect(m_curve
, SIGNAL(curveUpdated()), this, SLOT(UpdateSettingsTable()));
66 connect(m_settings
, SIGNAL(cellChanged(int, int)), this, SLOT(SettingsTableChanged()));
67 connect(m_mixerUI
->CurveMin
, SIGNAL(valueChanged(double)), this, SLOT(CurveMinChanged(double)));
68 connect(m_mixerUI
->CurveMax
, SIGNAL(valueChanged(double)), this, SLOT(CurveMaxChanged(double)));
69 connect(m_mixerUI
->CurveStep
, SIGNAL(valueChanged(double)), this, SLOT(GenerateCurve()));
72 MixerCurve::~MixerCurve()
75 delete m_spinDelegate
;
78 void MixerCurve::setMixerType(MixerCurveType curveType
)
80 m_curveType
= curveType
;
82 m_mixerUI
->buttonGroup
->show();
83 m_mixerUI
->CurveMin
->setMaximum(1.0);
84 m_mixerUI
->CurveMax
->setMaximum(1.0);
86 switch (m_curveType
) {
87 case MixerCurve::MIXERCURVE_THROTTLE
:
89 m_mixerUI
->SettingsGroup
->setTitle("Throttle Curve");
90 m_curve
->setRange(0.0, 1.0);
91 m_mixerUI
->CurveMin
->setMinimum(0.0);
92 m_mixerUI
->CurveMax
->setMinimum(0.0);
95 case MixerCurve::MIXERCURVE_PITCH
:
97 m_mixerUI
->SettingsGroup
->setTitle("Pitch Curve");
98 m_curve
->setRange(-1.0, 1.0);
99 m_mixerUI
->CurveMin
->setMinimum(-1.0);
100 m_mixerUI
->CurveMax
->setMinimum(-1.0);
107 m_spinDelegate
->setRange(m_mixerUI
->CurveMin
->minimum(), m_mixerUI
->CurveMax
->maximum());
108 for (int i
= 0; i
< MixerCurveWidget::NODE_NUMELEM
; i
++) {
109 m_settings
->setItemDelegateForRow(i
, m_spinDelegate
);
115 void MixerCurve::ResetCurve()
117 m_mixerUI
->CurveMin
->setValue(m_mixerUI
->CurveMin
->minimum());
118 m_mixerUI
->CurveMax
->setValue(m_mixerUI
->CurveMax
->maximum());
119 m_mixerUI
->CurveType
->setCurrentIndex(m_mixerUI
->CurveType
->findText("Linear"));
121 initLinearCurve(MixerCurveWidget::NODE_NUMELEM
, getCurveMax(), getCurveMin());
123 UpdateSettingsTable();
126 void MixerCurve::PopupCurve()
128 m_mixerUI
->SettingsGroup
->show();
129 m_mixerUI
->PopupCurve
->hide();
131 PopupWidget
*popup
= new PopupWidget();
134 m_mixerUI
->SettingsGroup
->hide();
135 m_mixerUI
->PopupCurve
->show();
138 void MixerCurve::UpdateCurveUI()
140 // get the user settings
141 QString curveType
= m_mixerUI
->CurveType
->currentText();
144 m_mixerUI
->CurveStep
->setMinimum(0.0);
145 m_mixerUI
->CurveStep
->setMaximum(100.0);
146 m_mixerUI
->CurveStep
->setSingleStep(1.00);
148 // set default visible
149 m_mixerUI
->minLabel
->setVisible(true);
150 m_mixerUI
->CurveMin
->setVisible(true);
151 m_mixerUI
->maxLabel
->setVisible(false);
152 m_mixerUI
->CurveMax
->setVisible(false);
153 m_mixerUI
->stepLabel
->setVisible(false);
154 m_mixerUI
->CurveStep
->setVisible(false);
156 if (curveType
.compare("Flat") == 0) {
157 m_mixerUI
->minLabel
->setVisible(false);
158 m_mixerUI
->CurveMin
->setVisible(false);
159 m_mixerUI
->stepLabel
->setVisible(true);
160 m_mixerUI
->CurveStep
->setVisible(true);
161 m_mixerUI
->CurveStep
->setMinimum(m_mixerUI
->CurveMin
->minimum());
162 m_mixerUI
->CurveStep
->setMaximum(m_mixerUI
->CurveMax
->maximum());
163 m_mixerUI
->CurveStep
->setSingleStep(0.01);
164 m_mixerUI
->CurveStep
->setValue(m_mixerUI
->CurveMax
->value() / 2);
166 if (curveType
.compare("Linear") == 0) {
167 m_mixerUI
->maxLabel
->setVisible(true);
168 m_mixerUI
->CurveMax
->setVisible(true);
170 if (curveType
.compare("Step") == 0) {
171 m_mixerUI
->maxLabel
->setVisible(true);
172 m_mixerUI
->CurveMax
->setVisible(true);
173 m_mixerUI
->stepLabel
->setText("Step at");
174 m_mixerUI
->stepLabel
->setVisible(true);
175 m_mixerUI
->CurveStep
->setVisible(true);
177 m_mixerUI
->CurveStep
->setMinimum(1.0);
179 if (curveType
.compare("Exp") == 0) {
180 m_mixerUI
->maxLabel
->setVisible(true);
181 m_mixerUI
->CurveMax
->setVisible(true);
182 m_mixerUI
->stepLabel
->setText("Power");
183 m_mixerUI
->stepLabel
->setVisible(true);
184 m_mixerUI
->CurveStep
->setVisible(true);
186 m_mixerUI
->CurveStep
->setMinimum(1.0);
188 if (curveType
.compare("Log") == 0) {
189 m_mixerUI
->maxLabel
->setVisible(true);
190 m_mixerUI
->CurveMax
->setVisible(true);
191 m_mixerUI
->stepLabel
->setText("Power");
192 m_mixerUI
->stepLabel
->setVisible(true);
193 m_mixerUI
->CurveStep
->setVisible(true);
194 m_mixerUI
->CurveStep
->setMinimum(1.0);
200 void MixerCurve::GenerateCurve()
205 // get the user settings
206 double value1
= getCurveMin();
207 double value2
= getCurveMax();
208 double value3
= getCurveStep();
210 QString CurveType
= m_mixerUI
->CurveType
->currentText();
212 QList
<double> points
;
214 for (int i
= 0; i
< MixerCurveWidget::NODE_NUMELEM
; i
++) {
215 scale
= ((double)i
/ (double)(MixerCurveWidget::NODE_NUMELEM
- 1));
217 if (CurveType
.compare("Flat") == 0) {
218 points
.append(value3
);
220 if (CurveType
.compare("Linear") == 0) {
221 newValue
= value1
+ (scale
* (value2
- value1
));
222 points
.append(newValue
);
224 if (CurveType
.compare("Step") == 0) {
225 if (scale
* 100 < value3
) {
226 points
.append(value1
);
228 points
.append(value2
);
231 if (CurveType
.compare("Exp") == 0) {
232 newValue
= value1
+ (((exp(scale
* (value3
/ 10)) - 1)) / (exp((value3
/ 10)) - 1) * (value2
- value1
));
233 points
.append(newValue
);
235 if (CurveType
.compare("Log") == 0) {
236 newValue
= value1
+ (((log(scale
* (value3
* 2) + 1)) / (log(1 + (value3
* 2)))) * (value2
- value1
));
237 points
.append(newValue
);
245 Wrappers for mixercurvewidget.
247 void MixerCurve::initCurve(const QList
<double> *points
)
249 m_curve
->setCurve(points
);
250 UpdateSettingsTable();
253 QList
<double> MixerCurve::getCurve()
255 return m_curve
->getCurve();
258 void MixerCurve::initLinearCurve(int numPoints
, double maxValue
, double minValue
)
263 m_curve
->initLinearCurve(numPoints
, maxValue
, minValue
);
265 if (m_spinDelegate
) {
266 m_spinDelegate
->setRange(minValue
, maxValue
);
270 void MixerCurve::setCurve(const QList
<double> *points
)
272 m_curve
->setCurve(points
);
273 UpdateSettingsTable();
276 void MixerCurve::setMin(double value
)
278 // m_curve->setMin(value);
279 m_mixerUI
->CurveMin
->setMinimum(value
);
282 double MixerCurve::getMin()
284 return m_curve
->getMin();
287 void MixerCurve::setMax(double value
)
289 // m_curve->setMax(value);
290 m_mixerUI
->CurveMax
->setMaximum(value
);
293 double MixerCurve::getMax()
295 return m_curve
->getMax();
298 double MixerCurve::setRange(double min
, double max
)
300 return m_curve
->setRange(min
, max
);
303 void MixerCurve::setXAxisLabel(QString label
)
305 m_curve
->setXAxisLabel(label
);
308 void MixerCurve::setYAxisLabel(QString label
)
310 m_curve
->setYAxisLabel(label
);
313 double MixerCurve::getCurveMin()
315 return m_mixerUI
->CurveMin
->value();
318 double MixerCurve::getCurveMax()
320 return m_mixerUI
->CurveMax
->value();
323 double MixerCurve::getCurveStep()
325 return m_mixerUI
->CurveStep
->value();
328 void MixerCurve::UpdateSettingsTable()
330 QList
<double> points
= m_curve
->getCurve();
331 int ptCnt
= points
.count();
333 for (int i
= 0; i
< ptCnt
; i
++) {
334 QTableWidgetItem
*item
= m_settings
->item(i
, 0);
336 item
->setText(QString().sprintf("%.2f", points
.at((ptCnt
- 1) - i
)));
341 void MixerCurve::SettingsTableChanged()
343 QList
<double> points
;
345 for (int i
= 0; i
< m_settings
->rowCount(); i
++) {
346 QTableWidgetItem
*item
= m_settings
->item(i
, 0);
349 points
.push_front(item
->text().toDouble());
353 m_mixerUI
->CurveMin
->setValue(points
.first());
354 m_mixerUI
->CurveMax
->setValue(points
.last());
356 m_curve
->setCurve(&points
);
359 void MixerCurve::CurveTypeChanged()
361 // setup the ui for this curvetype
365 void MixerCurve::CurveMinChanged(double value
)
367 QList
<double> points
= m_curve
->getCurve();
368 points
.removeFirst();
369 points
.push_front(value
);
373 void MixerCurve::CurveMaxChanged(double value
)
375 // the max changed so redraw the curve
376 // mixercurvewidget::setCurve will trim any points above max
377 QList
<double> points
= m_curve
->getCurve();
379 points
.append(value
);
383 void MixerCurve::showEvent(QShowEvent
*event
)
387 m_settings
->resizeColumnsToContents();
388 m_settings
->setColumnWidth(0, (m_settings
->width() - m_settings
->verticalHeader()->width()));
390 int h
= (m_settings
->height() - m_settings
->horizontalHeader()->height()) / m_settings
->rowCount();
391 for (int i
= 0; i
< m_settings
->rowCount(); i
++) {
392 m_settings
->setRowHeight(i
, h
);
395 m_curve
->showEvent(event
);
398 void MixerCurve::resizeEvent(QResizeEvent
*event
)
400 m_settings
->resizeColumnsToContents();
401 m_settings
->setColumnWidth(0, (m_settings
->width() - m_settings
->verticalHeader()->width()));
403 int h
= (m_settings
->height() - m_settings
->horizontalHeader()->height()) / m_settings
->rowCount();
404 for (int i
= 0; i
< m_settings
->rowCount(); i
++) {
405 m_settings
->setRowHeight(i
, h
);
408 m_curve
->resizeEvent(event
);