1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

OP-1590 Added implementation for PID Bank management.

Fixed a bug that prohibited fields not currently shown in gui ( in an
inactive pid bank ) to update from UAVO updates.
This commit is contained in:
m_thread 2014-11-04 00:51:47 +01:00
parent 0428cdfadc
commit 826d010119
4 changed files with 201 additions and 102 deletions

View File

@ -52,96 +52,14 @@
#include "qwt/src/qwt_scale_widget.h"
ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent),
boardModel(0), m_pidBankCount(0), m_currentPIDBank(0),
m_PIDCopyFromSignalMapper(new QSignalMapper()),
m_PIDCopyToSignalMapper(new QSignalMapper()),
m_PIDSwapSignalMapper(new QSignalMapper())
boardModel(0), m_pidBankCount(0), m_currentPIDBank(0)
{
ui = new Ui_StabilizationWidget();
ui->setupUi(this);
setupExpoPlot();
StabilizationSettings *stabSettings = qobject_cast<StabilizationSettings *>(getObject("StabilizationSettings"));
Q_ASSERT(stabSettings);
m_pidBankCount = stabSettings->getField("FlightModeMap")->getOptions().count();
// Set up fake tab widget stuff for pid banks support
m_pidTabBars.append(ui->basicPIDBankTabBar);
m_pidTabBars.append(ui->advancedPIDBankTabBar);
m_defaultPIDMenuAction = new QAction(QIcon(":configgadget/images/gear.png"), QString(), this);
QAction *restoreAllAction = new QAction(tr("Restore all to saved"), this);
connect(restoreAllAction, SIGNAL(triggered()), this, SLOT(restoreAllPIDBanks()));
QAction *resetAllAction = new QAction(tr("Reset all to default"), this);
connect(resetAllAction, SIGNAL(triggered()), this, SLOT(resetAllPIDBanks()));
QAction *restoreCurrentAction = new QAction(tr("Restore to saved"), this);
connect(restoreCurrentAction, SIGNAL(triggered()), this, SLOT(restoreCurrentAction()));
QAction *resetCurrentAction = new QAction(tr("Reset to default"), this);
connect(resetCurrentAction, SIGNAL(triggered()), this, SLOT(resetCurrentPIDBank()));
QAction *copyCurrentAction = new QAction(tr("Copy to others"), this);
connect(copyCurrentAction, SIGNAL(triggered()), this, SLOT(copyCurrentPIDBank()));
connect(m_PIDCopyFromSignalMapper, SIGNAL(mapped(int)), this, SLOT(copyFromBankToCurrent(int)));
connect(m_PIDCopyToSignalMapper, SIGNAL(mapped(int)), this, SLOT(copyToBankFromCurrent(int)));
connect(m_PIDSwapSignalMapper, SIGNAL(mapped(int)), this, SLOT(swapBankAndCurrent(int)));
foreach(QTabBar * tabBar, m_pidTabBars) {
for (int i = 0; i < m_pidBankCount; i++) {
tabBar->addTab(tr("Settings Bank %1").arg(i + 1));
tabBar->setTabData(i, QString("StabilizationSettingsBank%1").arg(i + 1));
QToolButton *tabButton = new QToolButton();
connect(this, SIGNAL(enableControlsChanged(bool)), tabButton, SLOT(setEnabled(bool)));
tabButton->setDefaultAction(m_defaultPIDMenuAction);
tabButton->setAutoRaise(true);
tabButton->setPopupMode(QToolButton::MenuButtonPopup);
QMenu *tabMenu = new QMenu();
QMenu *restoreMenu = new QMenu(tr("Restore"));
QMenu *resetMenu = new QMenu(tr("Reset"));
QMenu *copyMenu = new QMenu(tr("Copy"));
QMenu *swapMenu = new QMenu(tr("Swap"));
QAction *menuAction;
for (int j = 0; j < m_pidBankCount; j++) {
if (j == i) {
restoreMenu->addAction(restoreCurrentAction);
resetMenu->addAction(resetCurrentAction);
copyMenu->addAction(copyCurrentAction);
} else {
menuAction = new QAction(tr("Copy from %1").arg(j + 1), this);
connect(menuAction, SIGNAL(triggered()), m_PIDCopyFromSignalMapper, SLOT(map()));
m_PIDCopyFromSignalMapper->setMapping(menuAction, j + 1);
copyMenu->addAction(menuAction);
menuAction = new QAction(tr("Copy to %1").arg(j + 1), this);
connect(menuAction, SIGNAL(triggered()), m_PIDCopyToSignalMapper, SLOT(map()));
m_PIDCopyToSignalMapper->setMapping(menuAction, j + 1);
copyMenu->addAction(menuAction);
menuAction = new QAction(tr("Swap with %1").arg(j + 1), this);
connect(menuAction, SIGNAL(triggered()), m_PIDSwapSignalMapper, SLOT(map()));
m_PIDSwapSignalMapper->setMapping(menuAction, j + 1);
swapMenu->addAction(menuAction);
}
}
restoreMenu->addAction(restoreAllAction);
resetMenu->addAction(resetAllAction);
tabMenu->addMenu(copyMenu);
tabMenu->addMenu(swapMenu);
tabMenu->addMenu(resetMenu);
tabMenu->addMenu(restoreMenu);
tabButton->setMenu(tabMenu);
tabBar->setTabButton(i, QTabBar::RightSide, tabButton);
}
tabBar->setExpanding(false);
connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(pidBankChanged(int)));
}
for (int i = 0; i < m_pidBankCount; i++) {
if (i > 0) {
m_stabilizationObjectsString.append(",");
}
m_stabilizationObjectsString.append(m_pidTabBars.at(0)->tabData(i).toString());
}
setupPIDBanksGUI();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
@ -223,27 +141,100 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa
updateEnableControls();
}
void ConfigStabilizationWidget::setupPIDBanksGUI()
{
StabilizationSettings *stabSettings = qobject_cast<StabilizationSettings *>(getObject("StabilizationSettings"));
Q_ASSERT(stabSettings);
m_pidBankCount = stabSettings->getField("FlightModeMap")->getOptions().count();
// Set up fake tab widget stuff for pid banks support
m_pidTabBars.append(ui->basicPIDBankTabBar);
m_pidTabBars.append(ui->advancedPIDBankTabBar);
m_defaultPIDMenuAction = new QAction(QIcon(":configgadget/images/gear.png"), QString(), this);
QAction *restoreAllAction = new QAction(tr("Restore all to saved"), this);
connect(restoreAllAction, SIGNAL(triggered()), this, SLOT(restoreAllPIDBanks()));
QAction *resetAllAction = new QAction(tr("Reset all to default"), this);
connect(resetAllAction, SIGNAL(triggered()), this, SLOT(resetAllPIDBanks()));
QAction *restoreCurrentAction = new QAction(tr("Restore to saved"), this);
connect(restoreCurrentAction, SIGNAL(triggered()), this, SLOT(restoreCurrentAction()));
QAction *resetCurrentAction = new QAction(tr("Reset to default"), this);
connect(resetCurrentAction, SIGNAL(triggered()), this, SLOT(resetCurrentPIDBank()));
QAction *copyCurrentAction = new QAction(tr("Copy to others"), this);
connect(copyCurrentAction, SIGNAL(triggered()), this, SLOT(copyCurrentPIDBank()));
connect(&m_PIDCopyFromSignalMapper, SIGNAL(mapped(int)), this, SLOT(copyFromBankToCurrent(int)));
connect(&m_PIDCopyToSignalMapper, SIGNAL(mapped(int)), this, SLOT(copyToBankFromCurrent(int)));
connect(&m_PIDSwapSignalMapper, SIGNAL(mapped(int)), this, SLOT(swapBankAndCurrent(int)));
foreach(QTabBar * tabBar, m_pidTabBars) {
for (int i = 0; i < m_pidBankCount; i++) {
tabBar->addTab(tr("Settings Bank %1").arg(i + 1));
tabBar->setTabData(i, QString("StabilizationSettingsBank%1").arg(i + 1));
QToolButton *tabButton = new QToolButton();
connect(this, SIGNAL(enableControlsChanged(bool)), tabButton, SLOT(setEnabled(bool)));
tabButton->setDefaultAction(m_defaultPIDMenuAction);
tabButton->setAutoRaise(true);
tabButton->setPopupMode(QToolButton::InstantPopup);
tabButton->setToolTip(tr("The actions in this menu acts on all fields in the settings banks,\n"
"not only the ones visible on this tab or in this GUI."));
QMenu *tabMenu = new QMenu();
QMenu *restoreMenu = new QMenu(tr("Restore"));
QMenu *resetMenu = new QMenu(tr("Reset"));
QMenu *copyMenu = new QMenu(tr("Copy"));
QMenu *swapMenu = new QMenu(tr("Swap"));
QAction *menuAction;
for (int j = 0; j < m_pidBankCount; j++) {
if (j == i) {
restoreMenu->addAction(restoreCurrentAction);
resetMenu->addAction(resetCurrentAction);
copyMenu->addAction(copyCurrentAction);
} else {
menuAction = new QAction(tr("Copy from %1").arg(j + 1), this);
connect(menuAction, SIGNAL(triggered()), &m_PIDCopyFromSignalMapper, SLOT(map()));
m_PIDCopyFromSignalMapper.setMapping(menuAction, j);
copyMenu->addAction(menuAction);
menuAction = new QAction(tr("Copy to %1").arg(j + 1), this);
connect(menuAction, SIGNAL(triggered()), &m_PIDCopyToSignalMapper, SLOT(map()));
m_PIDCopyToSignalMapper.setMapping(menuAction, j);
copyMenu->addAction(menuAction);
menuAction = new QAction(tr("Swap with %1").arg(j + 1), this);
connect(menuAction, SIGNAL(triggered()), &m_PIDSwapSignalMapper, SLOT(map()));
m_PIDSwapSignalMapper.setMapping(menuAction, j);
swapMenu->addAction(menuAction);
}
}
restoreMenu->addAction(restoreAllAction);
resetMenu->addAction(resetAllAction);
tabMenu->addMenu(copyMenu);
tabMenu->addMenu(swapMenu);
tabMenu->addMenu(resetMenu);
tabMenu->addMenu(restoreMenu);
tabButton->setMenu(tabMenu);
tabBar->setTabButton(i, QTabBar::RightSide, tabButton);
}
tabBar->setExpanding(false);
connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(pidBankChanged(int)));
}
for (int i = 0; i < m_pidBankCount; i++) {
if (i > 0) {
m_stabilizationObjectsString.append(",");
}
m_stabilizationObjectsString.append(m_pidTabBars.at(0)->tabData(i).toString());
}
}
ConfigStabilizationWidget::~ConfigStabilizationWidget()
{
// Do nothing
if (m_PIDCopyFromSignalMapper) {
delete m_PIDCopyFromSignalMapper;
m_PIDCopyFromSignalMapper = NULL;
}
if (m_PIDCopyToSignalMapper) {
delete m_PIDCopyToSignalMapper;
m_PIDCopyToSignalMapper = NULL;
}
if (m_PIDSwapSignalMapper) {
delete m_PIDSwapSignalMapper;
m_PIDSwapSignalMapper = NULL;
}
}
void ConfigStabilizationWidget::refreshWidgetsValues(UAVObject *o)
{
ConfigTaskWidget::refreshWidgetsValues(o);
updateThrottleCurveFromObject();
ui->basicResponsivenessCheckBox->setChecked(ui->rateRollKp_3->value() == ui->ratePitchKp_4->value() &&
@ -416,41 +407,133 @@ void ConfigStabilizationWidget::replotExpoYaw(int value)
void ConfigStabilizationWidget::restoreAllPIDBanks()
{
qDebug() << "restoreAllPIDBanks";
for (int i = 0; i < m_pidBankCount; i++) {
restoreStabBank(i);
}
}
void ConfigStabilizationWidget::resetAllPIDBanks()
{
qDebug() << "resetAllPIDBanks";
for (int i = 0; i < m_pidBankCount; i++) {
resetStabBank(i);
}
}
void ConfigStabilizationWidget::restoreCurrentAction()
{
qDebug() << "restoreCurrentAction";
restoreStabBank(m_currentPIDBank);
}
void ConfigStabilizationWidget::resetStabBank(int bank)
{
UAVDataObject *stabBankObject =
dynamic_cast<UAVDataObject *>(getObject(QString("StabilizationSettingsBank%1").arg(bank + 1)));
if (stabBankObject) {
UAVDataObject * defaultStabBankObject = stabBankObject->dirtyClone();
quint8 data[stabBankObject->getNumBytes()];
defaultStabBankObject->pack(data);
stabBankObject->unpack(data);
}
}
void ConfigStabilizationWidget::restoreStabBank(int bank)
{
UAVObject *stabBankObject =
getObject(QString("StabilizationSettingsBank%1").arg(bank + 1));
if (stabBankObject) {
ObjectPersistence *objectPersistenceObject = ObjectPersistence::GetInstance(getObjectManager());
QTimer updateTimer(this);
QEventLoop eventLoop(this);
connect(&updateTimer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
connect(objectPersistenceObject, SIGNAL(objectUpdated(UAVObject *)), &eventLoop, SLOT(quit()));
ObjectPersistence::DataFields data;
data.Operation = ObjectPersistence::OPERATION_LOAD;
data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT;
data.ObjectID = stabBankObject->getObjID();
data.InstanceID = stabBankObject->getInstID();
objectPersistenceObject->setData(data);
objectPersistenceObject->updated();
updateTimer.start(500);
eventLoop.exec();
if (updateTimer.isActive()) {
stabBankObject->requestUpdate();
}
updateTimer.stop();
}
}
void ConfigStabilizationWidget::resetCurrentPIDBank()
{
qDebug() << "resetCurrentPIDBank";
resetStabBank(m_currentPIDBank);
}
void ConfigStabilizationWidget::copyCurrentPIDBank()
{
qDebug() << "copyCurrentPIDBank";
UAVObject *fromStabBankObject =
getObject(QString("StabilizationSettingsBank%1").arg(m_currentPIDBank + 1));
if (fromStabBankObject) {
quint8 fromStabBankObjectData[fromStabBankObject->getNumBytes()];
fromStabBankObject->pack(fromStabBankObjectData);
for (int i = 0; i < m_pidBankCount; i++) {
if (i != m_currentPIDBank) {
UAVObject *toStabBankObject =
getObject(QString("StabilizationSettingsBank%1").arg(i + 1));
if (toStabBankObject) {
toStabBankObject->unpack(fromStabBankObjectData);
}
}
}
}
}
void ConfigStabilizationWidget::copyFromBankToCurrent(int bank)
{
qDebug() << "copyFromBankToCurrent" << bank;
UAVObject *fromStabBankObject =
getObject(QString("StabilizationSettingsBank%1").arg(bank + 1));
UAVObject *toStabBankObject =
getObject(QString("StabilizationSettingsBank%1").arg(m_currentPIDBank + 1));
if (fromStabBankObject && toStabBankObject) {
quint8 data[fromStabBankObject->getNumBytes()];
fromStabBankObject->pack(data);
toStabBankObject->unpack(data);
}
}
void ConfigStabilizationWidget::copyToBankFromCurrent(int bank)
{
qDebug() << "copyToBankFromCurrent" << bank;
UAVObject *fromStabBankObject =
getObject(QString("StabilizationSettingsBank%1").arg(m_currentPIDBank + 1));
UAVObject *toStabBankObject =
getObject(QString("StabilizationSettingsBank%1").arg(bank + 1));
if (fromStabBankObject && toStabBankObject) {
quint8 data[fromStabBankObject->getNumBytes()];
fromStabBankObject->pack(data);
toStabBankObject->unpack(data);
}
}
void ConfigStabilizationWidget::swapBankAndCurrent(int bank)
{
qDebug() << "swapBankAndCurrent" << bank;
UAVObject *fromStabBankObject =
getObject(QString("StabilizationSettingsBank%1").arg(m_currentPIDBank + 1));
UAVObject *toStabBankObject =
getObject(QString("StabilizationSettingsBank%1").arg(bank + 1));
if (fromStabBankObject && toStabBankObject) {
quint8 fromStabBankObjectData[fromStabBankObject->getNumBytes()];
quint8 toStabBankObjectData[toStabBankObject->getNumBytes()];
fromStabBankObject->pack(fromStabBankObjectData);
toStabBankObject->pack(toStabBankObjectData);
toStabBankObject->unpack(fromStabBankObjectData);
fromStabBankObject->unpack(toStabBankObjectData);
}
}
void ConfigStabilizationWidget::realtimeUpdatesSlot(bool value)

View File

@ -68,13 +68,17 @@ private:
QwtPlotCurve m_expoPlotCurvePitch;
QwtPlotCurve m_expoPlotCurveYaw;
QwtPlotGrid m_plotGrid;
QSignalMapper *m_PIDCopyFromSignalMapper;
QSignalMapper *m_PIDCopyToSignalMapper;
QSignalMapper *m_PIDSwapSignalMapper;
QSignalMapper m_PIDCopyFromSignalMapper;
QSignalMapper m_PIDCopyToSignalMapper;
QSignalMapper m_PIDSwapSignalMapper;
void updateThrottleCurveFromObject();
void updateObjectFromThrottleCurve();
void setupExpoPlot();
void setupPIDBanksGUI();
void resetStabBank(int bank);
void restoreStabBank(int bank);
protected:
QString mapObjectName(const QString objectName);

View File

@ -295,8 +295,12 @@ void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
emit refreshWidgetsValuesRequested();
QList<WidgetBinding *> bindings = obj == NULL ? m_widgetBindingsPerObject.values() : m_widgetBindingsPerObject.values(obj);
foreach(WidgetBinding * binding, bindings) {
if (binding->isEnabled() && binding->field() != NULL && binding->widget() != NULL) {
setWidgetFromField(binding->widget(), binding->field(), binding);
if (binding->field() != NULL && binding->widget() != NULL) {
if (binding->isEnabled()) {
setWidgetFromField(binding->widget(), binding->field(), binding);
} else {
binding->updateValueFromObjectField();
}
}
}
setDirty(dirtyBack);
@ -1207,6 +1211,13 @@ void WidgetBinding::updateObjectFieldFromValue()
}
}
void WidgetBinding::updateValueFromObjectField()
{
if (m_field->getValue(m_index).isValid()) {
m_value = m_field->getValue(m_index);
}
}
ShadowWidgetBinding::ShadowWidgetBinding(QWidget *widget, double scale, bool isLimited)
{
m_widget = widget;

View File

@ -86,6 +86,7 @@ public:
void setValue(const QVariant &value);
void updateObjectFieldFromValue();
void updateValueFromObjectField();
private:
UAVObject *m_object;