1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-10 18:24:11 +01:00

Merge remote-tracking branch 'origin/skarlsso/OP-1458_remove_delays_from_tx_wizard' into next

This commit is contained in:
Fredrik Larson 2014-09-19 06:07:20 +10:00
commit 8a5174de67
2 changed files with 145 additions and 38 deletions

View File

@ -55,7 +55,10 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
transmitterType(acro), transmitterType(acro),
// //
loop(NULL), loop(NULL),
skipflag(false) skipflag(false),
nextDelayedTimer(),
nextDelayedTick(0),
nextDelayedLatestActivityTick(0)
{ {
manualCommandObj = ManualControlCommand::GetInstance(getObjectManager()); manualCommandObj = ManualControlCommand::GetInstance(getObjectManager());
manualSettingsObj = ManualControlSettings::GetInstance(getObjectManager()); manualSettingsObj = ManualControlSettings::GetInstance(getObjectManager());
@ -395,6 +398,13 @@ void ConfigInputWidget::goToWizard()
flightModeSettingsData.Arming = FlightModeSettings::ARMING_ALWAYSDISARMED; flightModeSettingsData.Arming = FlightModeSettings::ARMING_ALWAYSDISARMED;
flightModeSettingsObj->setData(flightModeSettingsData); flightModeSettingsObj->setData(flightModeSettingsData);
accessoryDesiredObj0 = AccessoryDesired::GetInstance(getObjectManager(), 0);
accessoryDesiredObj1 = AccessoryDesired::GetInstance(getObjectManager(), 1);
accessoryDesiredObj2 = AccessoryDesired::GetInstance(getObjectManager(), 2);
// Use faster input update rate.
fastMdata();
// start the wizard // start the wizard
wizardSetUpStep(wizardWelcome); wizardSetUpStep(wizardWelcome);
ui->graphicsView->fitInView(m_txBackground, Qt::KeepAspectRatio); ui->graphicsView->fitInView(m_txBackground, Qt::KeepAspectRatio);
@ -412,7 +422,13 @@ void ConfigInputWidget::disableWizardButton(int value)
void ConfigInputWidget::wzCancel() void ConfigInputWidget::wzCancel()
{ {
dimOtherControls(false); dimOtherControls(false);
manualCommandObj->setMetadata(manualCommandObj->getDefaultMetadata());
// Cancel any ongoing delayd next trigger.
wzNextDelayedCancel();
// Restore original input update rate.
restoreMdata();
ui->stackedWidget->setCurrentIndex(0); ui->stackedWidget->setCurrentIndex(0);
if (wizardStep != wizardNone) { if (wizardStep != wizardNone) {
@ -426,8 +442,45 @@ void ConfigInputWidget::wzCancel()
flightModeSettingsObj->setData(previousFlightModeSettingsData); flightModeSettingsObj->setData(previousFlightModeSettingsData);
} }
void ConfigInputWidget::registerControlActivity()
{
nextDelayedLatestActivityTick = nextDelayedTick;
}
void ConfigInputWidget::wzNextDelayed()
{
nextDelayedTick++;
// Call next after the full 2500 ms timeout has been reached,
// or if no input activity has occurred the last 500 ms.
if (nextDelayedTick == 25 ||
nextDelayedTick - nextDelayedLatestActivityTick >= 5) {
wzNext();
}
}
void ConfigInputWidget::wzNextDelayedStart()
{
// Call wzNextDelayed every 100 ms, to see if it's time to go to the next page.
connect(&nextDelayedTimer, SIGNAL(timeout()), this, SLOT(wzNextDelayed()));
nextDelayedTimer.start(100);
}
// Cancel the delayed next timer, if it's active.
void ConfigInputWidget::wzNextDelayedCancel()
{
nextDelayedTick = 0;
nextDelayedLatestActivityTick = 0;
if (nextDelayedTimer.isActive()) {
nextDelayedTimer.stop();
disconnect(&nextDelayedTimer, SIGNAL(timeout()), this, SLOT(wzNextDelayed()));
}
}
void ConfigInputWidget::wzNext() void ConfigInputWidget::wzNext()
{ {
wzNextDelayedCancel();
// In identify sticks mode the next button can indicate // In identify sticks mode the next button can indicate
// channel advance // channel advance
if (wizardStep != wizardNone && if (wizardStep != wizardNone &&
@ -464,6 +517,10 @@ void ConfigInputWidget::wzNext()
break; break;
case wizardFinish: case wizardFinish:
wizardStep = wizardNone; wizardStep = wizardNone;
// Restore original input update rate.
restoreMdata();
// Leave setting the throttle neutral until the final Next press, // Leave setting the throttle neutral until the final Next press,
// else the throttle scaling causes the graphical stick movement to not // else the throttle scaling causes the graphical stick movement to not
// match the tx stick // match the tx stick
@ -492,6 +549,8 @@ void ConfigInputWidget::wzNext()
void ConfigInputWidget::wzBack() void ConfigInputWidget::wzBack()
{ {
wzNextDelayedCancel();
if (wizardStep != wizardNone && if (wizardStep != wizardNone &&
wizardStep != wizardIdentifySticks) { wizardStep != wizardIdentifySticks) {
wizardTearDownStep(wizardStep); wizardTearDownStep(wizardStep);
@ -623,12 +682,8 @@ void ConfigInputWidget::wizardSetUpStep(enum wizardSteps step)
break; break;
case wizardIdentifyLimits: case wizardIdentifyLimits:
{ {
accessoryDesiredObj0 = AccessoryDesired::GetInstance(getObjectManager(), 0);
accessoryDesiredObj1 = AccessoryDesired::GetInstance(getObjectManager(), 1);
accessoryDesiredObj2 = AccessoryDesired::GetInstance(getObjectManager(), 2);
setTxMovement(nothing); setTxMovement(nothing);
ui->wzText->setText(QString(tr("Please move all controls to their maximum extents on both directions.\n\nPress Next when ready."))); ui->wzText->setText(QString(tr("Please move all controls to their maximum extents on both directions.\n\nPress Next when ready.")));
fastMdata();
manualSettingsData = manualSettingsObj->getData(); manualSettingsData = manualSettingsObj->getData();
for (uint i = 0; i < ManualControlSettings::CHANNELMAX_NUMELEM; ++i) { for (uint i = 0; i < ManualControlSettings::CHANNELMAX_NUMELEM; ++i) {
// Preserve the inverted status // Preserve the inverted status
@ -665,7 +720,6 @@ void ConfigInputWidget::wizardSetUpStep(enum wizardSteps step)
} }
connect(manualCommandObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); connect(manualCommandObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks()));
ui->wzText->setText(QString(tr("Please check the picture below and correct all the sticks which show an inverted movement. Press Next when ready."))); ui->wzText->setText(QString(tr("Please check the picture below and correct all the sticks which show an inverted movement. Press Next when ready.")));
fastMdata();
break; break;
case wizardFinish: case wizardFinish:
dimOtherControls(false); dimOtherControls(false);
@ -675,7 +729,6 @@ void ConfigInputWidget::wizardSetUpStep(enum wizardSteps step)
ui->wzText->setText(QString(tr("You have completed this wizard, please check below if the picture mimics your sticks movement.\n\n" ui->wzText->setText(QString(tr("You have completed this wizard, please check below if the picture mimics your sticks movement.\n\n"
"IMPORTANT: These new settings have not been saved to the board yet. After pressing Next you will go to the Arming Settings " "IMPORTANT: These new settings have not been saved to the board yet. After pressing Next you will go to the Arming Settings "
"tab where you can set your desired arming sequence and save the configuration."))); "tab where you can set your desired arming sequence and save the configuration.")));
fastMdata();
break; break;
default: default:
Q_ASSERT(0); Q_ASSERT(0);
@ -732,7 +785,6 @@ void ConfigInputWidget::wizardTearDownStep(enum wizardSteps step)
disconnect(flightStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); disconnect(flightStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks()));
disconnect(accessoryDesiredObj0, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); disconnect(accessoryDesiredObj0, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks()));
manualSettingsObj->setData(manualSettingsData); manualSettingsObj->setData(manualSettingsData);
restoreMdata();
setTxMovement(nothing); setTxMovement(nothing);
break; break;
case wizardIdentifyInverted: case wizardIdentifyInverted:
@ -747,7 +799,6 @@ void ConfigInputWidget::wizardTearDownStep(enum wizardSteps step)
} }
extraWidgets.clear(); extraWidgets.clear();
disconnect(manualCommandObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); disconnect(manualCommandObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks()));
restoreMdata();
break; break;
case wizardFinish: case wizardFinish:
dimOtherControls(false); dimOtherControls(false);
@ -755,23 +806,33 @@ void ConfigInputWidget::wizardTearDownStep(enum wizardSteps step)
disconnect(manualCommandObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); disconnect(manualCommandObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks()));
disconnect(flightStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); disconnect(flightStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks()));
disconnect(accessoryDesiredObj0, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks())); disconnect(accessoryDesiredObj0, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(moveSticks()));
restoreMdata();
break; break;
default: default:
Q_ASSERT(0); Q_ASSERT(0);
} }
} }
static void fastMdataSingle(UAVDataObject *object, UAVObject::Metadata *savedMdata)
{
*savedMdata = object->getMetadata();
UAVObject::Metadata mdata = *savedMdata;
UAVObject::SetFlightTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_PERIODIC);
mdata.flightTelemetryUpdatePeriod = 150;
object->setMetadata(mdata);
}
static void restoreMdataSingle(UAVDataObject *object, UAVObject::Metadata *savedMdata)
{
object->setMetadata(*savedMdata);
}
/** /**
* Set manual control command to fast updates * Set manual control command to fast updates
*/ */
void ConfigInputWidget::fastMdata() void ConfigInputWidget::fastMdata()
{ {
manualControlMdata = manualCommandObj->getMetadata(); fastMdataSingle(manualCommandObj, &manualControlMdata);
UAVObject::Metadata mdata = manualControlMdata; fastMdataSingle(accessoryDesiredObj0, &accessoryDesiredMdata0);
UAVObject::SetFlightTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_PERIODIC);
mdata.flightTelemetryUpdatePeriod = 150;
manualCommandObj->setMetadata(mdata);
} }
/** /**
@ -779,7 +840,8 @@ void ConfigInputWidget::fastMdata()
*/ */
void ConfigInputWidget::restoreMdata() void ConfigInputWidget::restoreMdata()
{ {
manualCommandObj->setMetadata(manualControlMdata); restoreMdataSingle(manualCommandObj, &manualControlMdata);
restoreMdataSingle(accessoryDesiredObj0, &accessoryDesiredMdata0);
} }
/** /**
@ -849,7 +911,7 @@ void ConfigInputWidget::prevChannel()
for (int i = 1; i < order.length(); i++) { for (int i = 1; i < order.length(); i++) {
if (order[i] == currentChannelNum) { if (order[i] == currentChannelNum) {
if (!usedChannels.isEmpty() && if (!usedChannels.isEmpty() &&
usedChannels.back().channelIndex == currentChannelNum) { usedChannels.back().channelIndex == order[i - 1]) {
usedChannels.removeLast(); usedChannels.removeLast();
} }
setChannel(order[i - 1]); setChannel(order[i - 1]);
@ -861,25 +923,54 @@ void ConfigInputWidget::prevChannel()
void ConfigInputWidget::identifyControls() void ConfigInputWidget::identifyControls()
{ {
static const int DEBOUNCE_COUNT = 4;
static int debounce = 0; static int debounce = 0;
receiverActivityData = receiverActivityObj->getData(); receiverActivityData = receiverActivityObj->getData();
if (receiverActivityData.ActiveChannel == 255) { if (receiverActivityData.ActiveChannel == 255) {
return; return;
} }
if (channelDetected) { if (channelDetected) {
registerControlActivity();
return; return;
} else { }
receiverActivityData = receiverActivityObj->getData(); receiverActivityData = receiverActivityObj->getData();
currentChannel.group = receiverActivityData.ActiveGroup; currentChannel.group = receiverActivityData.ActiveGroup;
currentChannel.number = receiverActivityData.ActiveChannel; currentChannel.number = receiverActivityData.ActiveChannel;
if (currentChannel == lastChannel) {
++debounce; if (debounce == 0) {
} // Register a channel to be debounced.
lastChannel.group = currentChannel.group; lastChannel.group = currentChannel.group;
lastChannel.number = currentChannel.number; lastChannel.number = currentChannel.number;
lastChannel.channelIndex = currentChannelNum; lastChannel.channelIndex = currentChannelNum;
if (!usedChannels.contains(lastChannel) && debounce > 1) { ++debounce;
return;
}
if (currentChannel != lastChannel) {
// A new channel was seen. Only register it if we count down to 0.
--debounce;
return;
}
if (debounce < DEBOUNCE_COUNT) {
// We still haven't seen enough enough activity on this channel yet.
++debounce;
return;
}
// Channel has been debounced and it's enough record it.
if (usedChannels.contains(lastChannel)) {
// Channel is already recorded.
return;
}
// Record the channel.
channelDetected = true; channelDetected = true;
debounce = 0; debounce = 0;
usedChannels.append(lastChannel); usedChannels.append(lastChannel);
@ -887,15 +978,11 @@ void ConfigInputWidget::identifyControls()
manualSettingsData.ChannelGroups[currentChannelNum] = currentChannel.group; manualSettingsData.ChannelGroups[currentChannelNum] = currentChannel.group;
manualSettingsData.ChannelNumber[currentChannelNum] = currentChannel.number; manualSettingsData.ChannelNumber[currentChannelNum] = currentChannel.number;
manualSettingsObj->setData(manualSettingsData); manualSettingsObj->setData(manualSettingsData);
} else {
return;
}
}
// m_config->wzText->clear(); // m_config->wzText->clear();
setTxMovement(nothing); setTxMovement(nothing);
QTimer::singleShot(2500, this, SLOT(wzNext())); wzNextDelayedStart();
} }
void ConfigInputWidget::identifyLimits() void ConfigInputWidget::identifyLimits()

View File

@ -82,6 +82,10 @@ private:
{ {
return (group == rhs.group) && (number == rhs.number); return (group == rhs.group) && (number == rhs.number);
} }
bool operator !=(const channelsStruct & rhs) const
{
return !operator==(rhs);
}
int group; int group;
int number; int number;
int channelIndex; int channelIndex;
@ -92,24 +96,34 @@ private:
QEventLoop *loop; QEventLoop *loop;
bool skipflag; bool skipflag;
// Variables to support delayed transitions when detecting input controls.
QTimer nextDelayedTimer;
int nextDelayedTick;
int nextDelayedLatestActivityTick;
int currentChannelNum; int currentChannelNum;
QList<int> heliChannelOrder; QList<int> heliChannelOrder;
QList<int> acroChannelOrder; QList<int> acroChannelOrder;
UAVObject::Metadata manualControlMdata;
ManualControlCommand *manualCommandObj; ManualControlCommand *manualCommandObj;
ManualControlCommand::DataFields manualCommandData; ManualControlCommand::DataFields manualCommandData;
FlightStatus *flightStatusObj; FlightStatus *flightStatusObj;
FlightStatus::DataFields flightStatusData; FlightStatus::DataFields flightStatusData;
UAVObject::Metadata accessoryDesiredMdata0;
AccessoryDesired *accessoryDesiredObj0; AccessoryDesired *accessoryDesiredObj0;
AccessoryDesired *accessoryDesiredObj1; AccessoryDesired *accessoryDesiredObj1;
AccessoryDesired *accessoryDesiredObj2; AccessoryDesired *accessoryDesiredObj2;
AccessoryDesired::DataFields accessoryDesiredData0; AccessoryDesired::DataFields accessoryDesiredData0;
AccessoryDesired::DataFields accessoryDesiredData1; AccessoryDesired::DataFields accessoryDesiredData1;
AccessoryDesired::DataFields accessoryDesiredData2; AccessoryDesired::DataFields accessoryDesiredData2;
UAVObject::Metadata manualControlMdata;
ManualControlSettings *manualSettingsObj; ManualControlSettings *manualSettingsObj;
ManualControlSettings::DataFields manualSettingsData; ManualControlSettings::DataFields manualSettingsData;
ManualControlSettings::DataFields previousManualSettingsData; ManualControlSettings::DataFields previousManualSettingsData;
FlightModeSettings *flightModeSettingsObj; FlightModeSettings *flightModeSettingsObj;
FlightModeSettings::DataFields flightModeSettingsData; FlightModeSettings::DataFields flightModeSettingsData;
FlightModeSettings::DataFields previousFlightModeSettingsData; FlightModeSettings::DataFields previousFlightModeSettingsData;
@ -152,8 +166,14 @@ private:
void wizardSetUpStep(enum wizardSteps); void wizardSetUpStep(enum wizardSteps);
void wizardTearDownStep(enum wizardSteps); void wizardTearDownStep(enum wizardSteps);
void registerControlActivity();
void wzNextDelayedStart();
void wzNextDelayedCancel();
private slots: private slots:
void wzNext(); void wzNext();
void wzNextDelayed();
void wzBack(); void wzBack();
void wzCancel(); void wzCancel();
void goToWizard(); void goToWizard();