LP-311 Remove basic/advanced stabilization tab auto-switch (autotune/txpid lock issues)
[librepilot.git] / ground / gcs / src / plugins / config / mixercurve.cpp
blobce93206b05c6e2da5ceab0dee17fe877b320c44e
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 "mixercurve.h"
30 #include "ui_mixercurve.h"
32 #include "dblspindelegate.h"
34 #include <QWidget>
35 #include <QResizeEvent>
36 #include <math.h>
38 MixerCurve::MixerCurve(QWidget *parent) :
39 QFrame(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);
57 // paint the ui
58 UpdateCurveUI();
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()
74 delete m_mixerUI;
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);
93 break;
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);
101 break;
103 default:
104 break;
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);
112 ResetCurve();
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();
132 popup->popUp(this);
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);
197 GenerateCurve();
200 void MixerCurve::GenerateCurve()
202 double scale;
203 double newValue;
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);
227 } else {
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);
241 setCurve(&points);
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)
260 setMin(minValue);
261 setMax(maxValue);
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);
335 if (item) {
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);
348 if (item) {
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
362 UpdateCurveUI();
365 void MixerCurve::CurveMinChanged(double value)
367 QList<double> points = m_curve->getCurve();
368 points.removeFirst();
369 points.push_front(value);
370 setCurve(&points);
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();
378 points.removeLast();
379 points.append(value);
380 setCurve(&points);
383 void MixerCurve::showEvent(QShowEvent *event)
385 Q_UNUSED(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);