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
29 #include <QResizeEvent>
31 #include "mixercurve.h"
32 #include "dblspindelegate.h"
34 MixerCurve::MixerCurve(QWidget
*parent
) :
36 m_mixerUI(new Ui::MixerCurve
)
38 m_mixerUI
->setupUi(this);
40 // setup some convienence pointers
41 m_curve
= m_mixerUI
->CurveWidget
;
42 m_settings
= m_mixerUI
->CurveSettings
;
45 m_mixerUI
->SettingsGroup
->hide();
47 // create our spin delegate
48 m_spinDelegate
= new DoubleSpinDelegate();
50 // set the default mixer type
51 setMixerType(MixerCurve::MIXERCURVE_THROTTLE
);
56 // wire up our signals
57 connect(m_mixerUI
->CurveType
, SIGNAL(currentIndexChanged(int)), this, SLOT(CurveTypeChanged()));
58 connect(m_mixerUI
->ResetCurve
, SIGNAL(clicked()), this, SLOT(ResetCurve()));
59 connect(m_mixerUI
->PopupCurve
, SIGNAL(clicked()), this, SLOT(PopupCurve()));
60 connect(m_mixerUI
->GenerateCurve
, SIGNAL(clicked()), this, SLOT(GenerateCurve()));
61 connect(m_curve
, SIGNAL(curveUpdated()), this, SLOT(UpdateSettingsTable()));
62 connect(m_settings
, SIGNAL(cellChanged(int, int)), this, SLOT(SettingsTableChanged()));
63 connect(m_mixerUI
->CurveMin
, SIGNAL(valueChanged(double)), this, SLOT(CurveMinChanged(double)));
64 connect(m_mixerUI
->CurveMax
, SIGNAL(valueChanged(double)), this, SLOT(CurveMaxChanged(double)));
65 connect(m_mixerUI
->CurveStep
, SIGNAL(valueChanged(double)), this, SLOT(GenerateCurve()));
68 MixerCurve::~MixerCurve()
71 delete m_spinDelegate
;
74 void MixerCurve::setMixerType(MixerCurveType curveType
)
76 m_curveType
= curveType
;
78 m_mixerUI
->buttonGroup
->show();
79 m_mixerUI
->CurveMin
->setMaximum(1.0);
80 m_mixerUI
->CurveMax
->setMaximum(1.0);
82 switch (m_curveType
) {
83 case MixerCurve::MIXERCURVE_THROTTLE
:
85 m_mixerUI
->SettingsGroup
->setTitle("Throttle Curve");
86 m_curve
->setRange(0.0, 1.0);
87 m_mixerUI
->CurveMin
->setMinimum(0.0);
88 m_mixerUI
->CurveMax
->setMinimum(0.0);
91 case MixerCurve::MIXERCURVE_PITCH
:
93 m_mixerUI
->SettingsGroup
->setTitle("Pitch Curve");
94 m_curve
->setRange(-1.0, 1.0);
95 m_mixerUI
->CurveMin
->setMinimum(-1.0);
96 m_mixerUI
->CurveMax
->setMinimum(-1.0);
103 m_spinDelegate
->setRange(m_mixerUI
->CurveMin
->minimum(), m_mixerUI
->CurveMax
->maximum());
104 for (int i
= 0; i
< MixerCurveWidget::NODE_NUMELEM
; i
++) {
105 m_settings
->setItemDelegateForRow(i
, m_spinDelegate
);
111 void MixerCurve::ResetCurve()
113 m_mixerUI
->CurveMin
->setValue(m_mixerUI
->CurveMin
->minimum());
114 m_mixerUI
->CurveMax
->setValue(m_mixerUI
->CurveMax
->maximum());
115 m_mixerUI
->CurveType
->setCurrentIndex(m_mixerUI
->CurveType
->findText("Linear"));
117 initLinearCurve(MixerCurveWidget::NODE_NUMELEM
, getCurveMax(), getCurveMin());
119 UpdateSettingsTable();
122 void MixerCurve::PopupCurve()
124 m_mixerUI
->SettingsGroup
->show();
125 m_mixerUI
->PopupCurve
->hide();
127 PopupWidget
*popup
= new PopupWidget();
130 m_mixerUI
->SettingsGroup
->hide();
131 m_mixerUI
->PopupCurve
->show();
134 void MixerCurve::UpdateCurveUI()
136 // get the user settings
137 QString curveType
= m_mixerUI
->CurveType
->currentText();
140 m_mixerUI
->CurveStep
->setMinimum(0.0);
141 m_mixerUI
->CurveStep
->setMaximum(100.0);
142 m_mixerUI
->CurveStep
->setSingleStep(1.00);
144 // set default visible
145 m_mixerUI
->minLabel
->setVisible(true);
146 m_mixerUI
->CurveMin
->setVisible(true);
147 m_mixerUI
->maxLabel
->setVisible(false);
148 m_mixerUI
->CurveMax
->setVisible(false);
149 m_mixerUI
->stepLabel
->setVisible(false);
150 m_mixerUI
->CurveStep
->setVisible(false);
152 if (curveType
.compare("Flat") == 0) {
153 m_mixerUI
->minLabel
->setVisible(false);
154 m_mixerUI
->CurveMin
->setVisible(false);
155 m_mixerUI
->stepLabel
->setVisible(true);
156 m_mixerUI
->CurveStep
->setVisible(true);
157 m_mixerUI
->CurveStep
->setMinimum(m_mixerUI
->CurveMin
->minimum());
158 m_mixerUI
->CurveStep
->setMaximum(m_mixerUI
->CurveMax
->maximum());
159 m_mixerUI
->CurveStep
->setSingleStep(0.01);
160 m_mixerUI
->CurveStep
->setValue(m_mixerUI
->CurveMax
->value() / 2);
162 if (curveType
.compare("Linear") == 0) {
163 m_mixerUI
->maxLabel
->setVisible(true);
164 m_mixerUI
->CurveMax
->setVisible(true);
166 if (curveType
.compare("Step") == 0) {
167 m_mixerUI
->maxLabel
->setVisible(true);
168 m_mixerUI
->CurveMax
->setVisible(true);
169 m_mixerUI
->stepLabel
->setText("Step at");
170 m_mixerUI
->stepLabel
->setVisible(true);
171 m_mixerUI
->CurveStep
->setVisible(true);
173 m_mixerUI
->CurveStep
->setMinimum(1.0);
175 if (curveType
.compare("Exp") == 0) {
176 m_mixerUI
->maxLabel
->setVisible(true);
177 m_mixerUI
->CurveMax
->setVisible(true);
178 m_mixerUI
->stepLabel
->setText("Power");
179 m_mixerUI
->stepLabel
->setVisible(true);
180 m_mixerUI
->CurveStep
->setVisible(true);
182 m_mixerUI
->CurveStep
->setMinimum(1.0);
184 if (curveType
.compare("Log") == 0) {
185 m_mixerUI
->maxLabel
->setVisible(true);
186 m_mixerUI
->CurveMax
->setVisible(true);
187 m_mixerUI
->stepLabel
->setText("Power");
188 m_mixerUI
->stepLabel
->setVisible(true);
189 m_mixerUI
->CurveStep
->setVisible(true);
190 m_mixerUI
->CurveStep
->setMinimum(1.0);
196 void MixerCurve::GenerateCurve()
201 // get the user settings
202 double value1
= getCurveMin();
203 double value2
= getCurveMax();
204 double value3
= getCurveStep();
206 QString CurveType
= m_mixerUI
->CurveType
->currentText();
208 QList
<double> points
;
210 for (int i
= 0; i
< MixerCurveWidget::NODE_NUMELEM
; i
++) {
211 scale
= ((double)i
/ (double)(MixerCurveWidget::NODE_NUMELEM
- 1));
213 if (CurveType
.compare("Flat") == 0) {
214 points
.append(value3
);
216 if (CurveType
.compare("Linear") == 0) {
217 newValue
= value1
+ (scale
* (value2
- value1
));
218 points
.append(newValue
);
220 if (CurveType
.compare("Step") == 0) {
221 if (scale
* 100 < value3
) {
222 points
.append(value1
);
224 points
.append(value2
);
227 if (CurveType
.compare("Exp") == 0) {
228 newValue
= value1
+ (((exp(scale
* (value3
/ 10)) - 1)) / (exp((value3
/ 10)) - 1) * (value2
- value1
));
229 points
.append(newValue
);
231 if (CurveType
.compare("Log") == 0) {
232 newValue
= value1
+ (((log(scale
* (value3
* 2) + 1)) / (log(1 + (value3
* 2)))) * (value2
- value1
));
233 points
.append(newValue
);
241 Wrappers for mixercurvewidget.
243 void MixerCurve::initCurve(const QList
<double> *points
)
245 m_curve
->setCurve(points
);
246 UpdateSettingsTable();
249 QList
<double> MixerCurve::getCurve()
251 return m_curve
->getCurve();
254 void MixerCurve::initLinearCurve(int numPoints
, double maxValue
, double minValue
)
259 m_curve
->initLinearCurve(numPoints
, maxValue
, minValue
);
261 if (m_spinDelegate
) {
262 m_spinDelegate
->setRange(minValue
, maxValue
);
266 void MixerCurve::setCurve(const QList
<double> *points
)
268 m_curve
->setCurve(points
);
269 UpdateSettingsTable();
272 void MixerCurve::setMin(double value
)
274 // m_curve->setMin(value);
275 m_mixerUI
->CurveMin
->setMinimum(value
);
278 double MixerCurve::getMin()
280 return m_curve
->getMin();
283 void MixerCurve::setMax(double value
)
285 // m_curve->setMax(value);
286 m_mixerUI
->CurveMax
->setMaximum(value
);
289 double MixerCurve::getMax()
291 return m_curve
->getMax();
294 double MixerCurve::setRange(double min
, double max
)
296 return m_curve
->setRange(min
, max
);
299 void MixerCurve::setXAxisLabel(QString label
)
301 m_curve
->setXAxisLabel(label
);
304 void MixerCurve::setYAxisLabel(QString label
)
306 m_curve
->setYAxisLabel(label
);
309 double MixerCurve::getCurveMin()
311 return m_mixerUI
->CurveMin
->value();
314 double MixerCurve::getCurveMax()
316 return m_mixerUI
->CurveMax
->value();
319 double MixerCurve::getCurveStep()
321 return m_mixerUI
->CurveStep
->value();
324 void MixerCurve::UpdateSettingsTable()
326 QList
<double> points
= m_curve
->getCurve();
327 int ptCnt
= points
.count();
329 for (int i
= 0; i
< ptCnt
; i
++) {
330 QTableWidgetItem
*item
= m_settings
->item(i
, 0);
332 item
->setText(QString().sprintf("%.2f", points
.at((ptCnt
- 1) - i
)));
337 void MixerCurve::SettingsTableChanged()
339 QList
<double> points
;
341 for (int i
= 0; i
< m_settings
->rowCount(); i
++) {
342 QTableWidgetItem
*item
= m_settings
->item(i
, 0);
345 points
.push_front(item
->text().toDouble());
349 m_mixerUI
->CurveMin
->setValue(points
.first());
350 m_mixerUI
->CurveMax
->setValue(points
.last());
352 m_curve
->setCurve(&points
);
355 void MixerCurve::CurveTypeChanged()
357 // setup the ui for this curvetype
361 void MixerCurve::CurveMinChanged(double value
)
363 QList
<double> points
= m_curve
->getCurve();
364 points
.removeFirst();
365 points
.push_front(value
);
369 void MixerCurve::CurveMaxChanged(double value
)
371 // the max changed so redraw the curve
372 // mixercurvewidget::setCurve will trim any points above max
373 QList
<double> points
= m_curve
->getCurve();
375 points
.append(value
);
379 void MixerCurve::showEvent(QShowEvent
*event
)
383 m_settings
->resizeColumnsToContents();
384 m_settings
->setColumnWidth(0, (m_settings
->width() - m_settings
->verticalHeader()->width()));
386 int h
= (m_settings
->height() - m_settings
->horizontalHeader()->height()) / m_settings
->rowCount();
387 for (int i
= 0; i
< m_settings
->rowCount(); i
++) {
388 m_settings
->setRowHeight(i
, h
);
391 m_curve
->showEvent(event
);
394 void MixerCurve::resizeEvent(QResizeEvent
*event
)
396 m_settings
->resizeColumnsToContents();
397 m_settings
->setColumnWidth(0, (m_settings
->width() - m_settings
->verticalHeader()->width()));
399 int h
= (m_settings
->height() - m_settings
->horizontalHeader()->height()) / m_settings
->rowCount();
400 for (int i
= 0; i
< m_settings
->rowCount(); i
++) {
401 m_settings
->setRowHeight(i
, h
);
404 m_curve
->resizeEvent(event
);