LP-56 - Better txpid option namings, fix tabs-spaces, tooltips. headers, variable...
[librepilot.git] / ground / openpilotgcs / src / plugins / config / mixercurve.cpp
blobb2cc03a6460fe2dc6c961613b12664b56320072f
1 /**
2 ******************************************************************************
4 * @file mixercurve.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @addtogroup GCSPlugins GCS Plugins
7 * @{
8 * @addtogroup ConfigPlugin Config Plugin
9 * @{
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
21 * for more details.
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 <QWidget>
29 #include <QResizeEvent>
30 #include <math.h>
31 #include "mixercurve.h"
32 #include "dblspindelegate.h"
34 MixerCurve::MixerCurve(QWidget *parent) :
35 QFrame(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);
53 // paint the ui
54 UpdateCurveUI();
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()
70 delete m_mixerUI;
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);
89 break;
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);
97 break;
99 default:
100 break;
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);
108 ResetCurve();
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();
128 popup->popUp(this);
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);
193 GenerateCurve();
196 void MixerCurve::GenerateCurve()
198 double scale;
199 double newValue;
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);
223 } else {
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);
237 setCurve(&points);
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)
256 setMin(minValue);
257 setMax(maxValue);
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);
331 if (item) {
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);
344 if (item) {
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
358 UpdateCurveUI();
361 void MixerCurve::CurveMinChanged(double value)
363 QList<double> points = m_curve->getCurve();
364 points.removeFirst();
365 points.push_front(value);
366 setCurve(&points);
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();
374 points.removeLast();
375 points.append(value);
376 setCurve(&points);
379 void MixerCurve::showEvent(QShowEvent *event)
381 Q_UNUSED(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);