void ConfigStabilizationWidget::restoreStabBank(int bank) { UAVObject *stabBankObject = getStabBankObject(bank); 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(); } }
/** * Update the data of an object from a byte array (unpack). * If the object instance could not be found in the list, then a * new one is created. */ UAVObject* UAVTalk::updateObject(quint32 objId, quint16 instId, quint8* data) { // Get object UAVObject* obj = objMngr->getObject(objId, instId); // If the instance does not exist create it if (obj == NULL) { // Get the object type UAVObject* tobj = objMngr->getObject(objId); if (tobj == NULL) { return NULL; } // Make sure this is a data object UAVDataObject* dobj = dynamic_cast<UAVDataObject*>(tobj); if (dobj == NULL) { return NULL; } // Create a new instance, unpack and register UAVDataObject* instobj = dobj->clone(instId); if ( !objMngr->registerObject(instobj) ) { return NULL; } instobj->unpack(data); return instobj; } else { // Unpack data into object instance obj->unpack(data); return obj; } }
void ConfigStabilizationWidget::updateThrottleCurveFromObject() { bool dirty = isDirty(); UAVObject *stabBank = getObjectManager()->getObject(QString(m_stabTabBars.at(0)->tabData(m_currentStabSettingsBank).toString())); Q_ASSERT(stabBank); UAVObjectField *field = stabBank->getField("ThrustPIDScaleCurve"); Q_ASSERT(field); QList<double> curve; for (quint32 i = 0; i < field->getNumElements(); i++) { curve.append(field->getValue(i).toDouble()); } ui->thrustPIDScalingCurve->setCurve(&curve); field = stabBank->getField("EnableThrustPIDScaling"); Q_ASSERT(field); bool enabled = field->getValue() == "TRUE"; ui->enableThrustPIDScalingCheckBox->setChecked(enabled); ui->thrustPIDScalingCurve->setEnabled(enabled); setDirty(dirty); }
/** Callback once calibration is done on the board. Currently we don't have a way to tell if calibration is finished, so we have to use a timer. calibPhase2 is also connected to the AHRSCalibration object update signal. */ void ConfigAHRSWidget::calibPhase2() { UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSCalibration"))); // UAVObjectField *field = obj->getField(QString("measure_var")); // This is a bit weird, but it is because we are expecting an update from the // OP board with the correct calibration values, and those only arrive on the object update // which comes back from the board, and not the first object update signal which is in fast // the object update we did ourselves... Clear ? switch (phaseCounter) { case 0: phaseCounter++; m_ahrs->calibInstructions->setText("Getting results..."); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(calibPhase2())); // We need to echo back the results of calibration before changing to set mode obj->requestUpdate(); break; case 1: // This is the update with the right values (coming from the board) disconnect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(calibPhase2())); // Now update size of all the graphs drawVariancesGraph(); saveAHRSCalibration(); m_ahrs->calibInstructions->setText(QString("Calibration saved.")); m_ahrs->ahrsCalibStart->setEnabled(true); break; } }
/** * Initiate object retrieval, initialize queue with objects to be retrieved. */ void TelemetryMonitor::startRetrievingObjects() { // Clear object queue queue.clear(); // Get all objects, add metaobjects, settings and data objects with OnChange update mode to the queue QList< QList<UAVObject *> > objs = objMngr->getObjects(); for (int n = 0; n < objs.length(); ++n) { UAVObject *obj = objs[n][0]; UAVMetaObject *mobj = dynamic_cast<UAVMetaObject *>(obj); UAVDataObject *dobj = dynamic_cast<UAVDataObject *>(obj); UAVObject::Metadata mdata = obj->getMetadata(); if (mobj != NULL) { queue.enqueue(obj); } else if (dobj != NULL) { if (dobj->isSettings()) { queue.enqueue(obj); } else { if (UAVObject::GetFlightTelemetryUpdateMode(mdata) == UAVObject::UPDATEMODE_ONCHANGE) { queue.enqueue(obj); } } } } // Start retrieving qDebug() << tr("Starting to retrieve meta and settings objects from the autopilot (%1 objects)") .arg(queue.length()); retrieveNextObject(); }
void UAVObjectUtilManager::saveNextObject() { if (queue.isEmpty()) { return; } Q_ASSERT(saveState == IDLE); // Get next object from the queue UAVObject *obj = queue.head(); qDebug() << "Send save object request to board " << obj->getName(); ObjectPersistence *objper = dynamic_cast<ObjectPersistence *>(getObjectManager()->getObject(ObjectPersistence::NAME)); connect(objper, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(objectPersistenceTransactionCompleted(UAVObject *, bool))); connect(objper, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(objectPersistenceUpdated(UAVObject *))); saveState = AWAITING_ACK; if (obj != NULL) { ObjectPersistence::DataFields data; data.Operation = ObjectPersistence::OPERATION_SAVE; data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT; data.ObjectID = obj->getObjID(); data.InstanceID = obj->getInstID(); objper->setData(data); objper->updated(); } // Now: we are going to get two "objectUpdated" messages (one coming from GCS, one coming from Flight, which // will confirm the object was properly received by both sides) and then one "transactionCompleted" indicating // that the Flight side did not only receive the object but it did receive it without error. Last we will get // a last "objectUpdated" message coming from flight side, where we'll get the results of the objectPersistence // operation we asked for (saved, other). }
void UAVObjectBrowserWidget::onTreeItemExpanded(QModelIndex currentProxyIndex) { QModelIndex currentIndex = proxyModel->mapToSource(currentProxyIndex); TreeItem *item = static_cast<TreeItem*>(currentIndex.internalPointer()); TopTreeItem *top = dynamic_cast<TopTreeItem*>(item->parent()); //Check if current tree index is the child of the top tree item if (top) { ObjectTreeItem *objItem = dynamic_cast<ObjectTreeItem*>(item); //If the cast succeeds, then this is a UAVO if (objItem) { UAVObject *obj = objItem->object(); // Check for multiple instance UAVO if(!obj){ objItem = dynamic_cast<ObjectTreeItem*>(item->getChild(0)); obj = objItem->object(); } Q_ASSERT(obj); UAVObject::Metadata mdata = obj->getMetadata(); // Determine fastest update quint16 tmpUpdatePeriod = MAXIMUM_UPDATE_PERIOD; int accessType = UAVObject::GetGcsTelemetryUpdateMode(mdata); if (accessType != UAVObject::UPDATEMODE_MANUAL){ switch(accessType){ case UAVObject::UPDATEMODE_ONCHANGE: tmpUpdatePeriod = 0; break; case UAVObject::UPDATEMODE_PERIODIC: case UAVObject::UPDATEMODE_THROTTLED: tmpUpdatePeriod = std::min(mdata.gcsTelemetryUpdatePeriod, tmpUpdatePeriod); break; } } accessType = UAVObject::GetFlightTelemetryUpdateMode(mdata); if (accessType != UAVObject::UPDATEMODE_MANUAL){ switch(accessType){ case UAVObject::UPDATEMODE_ONCHANGE: tmpUpdatePeriod = 0; break; case UAVObject::UPDATEMODE_PERIODIC: case UAVObject::UPDATEMODE_THROTTLED: tmpUpdatePeriod = std::min(mdata.flightTelemetryUpdatePeriod, tmpUpdatePeriod); break; } } expandedUavoItems.insert(obj->getName(), tmpUpdatePeriod); if (tmpUpdatePeriod < updatePeriod){ updatePeriod = tmpUpdatePeriod; treeView->updateTimerPeriod(updatePeriod); } } } }
void UAVObjectBrowserWidget::requestUpdate() { ObjectTreeItem *objItem = findCurrentObjectTreeItem(); Q_ASSERT(objItem); UAVObject *obj = objItem->object(); Q_ASSERT(obj); obj->requestUpdate(); }
void UAVObjectBrowserWidget::sendUpdate() { ObjectTreeItem *objItem = findCurrentObjectTreeItem(); Q_ASSERT(objItem); objItem->apply(); UAVObject *obj = objItem->object(); Q_ASSERT(obj); obj->updated(); }
/** Saves the AHRS sensors calibration (to RAM and SD) */ void ConfigAHRSWidget::saveAHRSCalibration() { UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSCalibration"))); UAVObjectField *field = obj->getField(QString("measure_var")); field->setValue("SET"); obj->updated(); updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj); }
ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent),wasItMe(false) { m_config = new Ui_OutputWidget(); m_config->setupUi(this); ExtensionSystem::PluginManager *pm=ExtensionSystem::PluginManager::instance(); Core::Internal::GeneralSettings * settings=pm->getObject<Core::Internal::GeneralSettings>(); if(!settings->useExpertMode()) m_config->saveRCOutputToRAM->setVisible(false); UAVSettingsImportExportFactory * importexportplugin = pm->getObject<UAVSettingsImportExportFactory>(); connect(importexportplugin,SIGNAL(importAboutToBegin()),this,SLOT(stopTests())); // NOTE: we have channel indices from 0 to 9, but the convention for OP is Channel 1 to Channel 10. // Register for ActuatorSettings changes: for (unsigned int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) { OutputChannelForm *outputForm = new OutputChannelForm(i, this, i==0); m_config->channelLayout->addWidget(outputForm); connect(m_config->channelOutTest, SIGNAL(toggled(bool)), outputForm, SLOT(enableChannelTest(bool))); connect(outputForm, SIGNAL(channelChanged(int,int)), this, SLOT(sendChannelTest(int,int))); connect(outputForm, SIGNAL(formChanged()), this, SLOT(do_SetDirty())); } connect(m_config->channelOutTest, SIGNAL(toggled(bool)), this, SLOT(runChannelTests(bool))); // Configure the task widget // Connect the help button connect(m_config->outputHelp, SIGNAL(clicked()), this, SLOT(openHelp())); addApplySaveButtons(m_config->saveRCOutputToRAM,m_config->saveRCOutputToSD); // Track the ActuatorSettings object addUAVObject("ActuatorSettings"); // Associate the buttons with their UAVO fields addWidget(m_config->cb_outputRate4); addWidget(m_config->cb_outputRate3); addWidget(m_config->cb_outputRate2); addWidget(m_config->cb_outputRate1); addWidget(m_config->spinningArmed); disconnect(this, SLOT(refreshWidgetsValues(UAVObject*))); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObject* obj = objManager->getObject(QString("ActuatorCommand")); if(UAVObject::GetGcsTelemetryUpdateMode(obj->getMetadata()) == UAVObject::UPDATEMODE_ONCHANGE) this->setEnabled(false); connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(disableIfNotMe(UAVObject*))); connect(SystemSettings::GetInstance(objManager), SIGNAL(objectUpdated(UAVObject*)),this,SLOT(assignOutputChannels(UAVObject*))); refreshWidgetsValues(); }
void ConfigStabilizationWidget::copyFromBankToBank(int fromBank, int toBank) { UAVObject *fromStabBankObject = getStabBankObject(fromBank); UAVObject *toStabBankObject = getStabBankObject(toBank); if (fromStabBankObject && toStabBankObject) { quint8 data[fromStabBankObject->getNumBytes()]; fromStabBankObject->pack(data); toStabBankObject->unpack(data); } }
QString UsageTrackerPlugin::getUAVFieldValue(UAVObjectManager *objManager, QString objectName, QString fieldName, int index) const { UAVObject *object = objManager->getObject(objectName); if (object != NULL) { UAVObjectField *field = object->getField(fieldName); if (field != NULL) { return field->getValue(index).toString(); } } return tr("Unknown"); }
/** * Retrieve the next object in the queue */ void LoggingThread::retrieveNextObject() { // If queue is empty return if (queue.isEmpty()) { qDebug() << "Logging: Object retrieval completed"; return; } // Get next object from the queue UAVObject *obj = queue.dequeue(); // Connect to object connect(obj, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(transactionCompleted(UAVObject *, bool))); // Request update obj->requestUpdate(); }
bool UAVObject::operator ==(const UAVObject &other) { if((this->UAVObjGetInstance() == other.UAVObjGetID()) && (this->UAVObjGetInstance() == other.UAVObjGetInstance())) return true; else return false; }
void ConfigStabilizationWidget::copyCurrentStabBank() { UAVObject *fromStabBankObject = getStabBankObject(m_currentStabSettingsBank); if (fromStabBankObject) { quint8 fromStabBankObjectData[fromStabBankObject->getNumBytes()]; fromStabBankObject->pack(fromStabBankObjectData); for (int i = 0; i < m_stabSettingsBankCount; i++) { if (i != m_currentStabSettingsBank) { UAVObject *toStabBankObject = getStabBankObject(i); if (toStabBankObject) { toStabBankObject->unpack(fromStabBankObjectData); } } } } }
/** Launches the AHRS sensors calibration */ void ConfigAHRSWidget::launchAHRSCalibration() { m_ahrs->calibInstructions->setText("Estimating sensor variance..."); m_ahrs->ahrsCalibStart->setEnabled(false); UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSCalibration"))); UAVObjectField *field = obj->getField(QString("measure_var")); field->setValue("MEASURE"); obj->updated(); QTimer::singleShot(calibrationDelay*1000, this, SLOT(calibPhase2())); m_ahrs->calibProgress->setRange(0,calibrationDelay); phaseCounter = 0; progressBarIndex = 0; connect(&progressBarTimer, SIGNAL(timeout()), this, SLOT(incrementProgress())); progressBarTimer.start(1000); }
//! Query optional objects to determine which tabs can be configured void ConfigModuleWidget::recheckTabs() { UAVObject * obj; obj = getObjectManager()->getObject(AirspeedSettings::NAME); connect(obj, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectUpdated(UAVObject*,bool)), Qt::UniqueConnection); obj->requestUpdate(); obj = getObjectManager()->getObject(FlightBatterySettings::NAME); connect(obj, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectUpdated(UAVObject*,bool)), Qt::UniqueConnection); obj->requestUpdate(); obj = getObjectManager()->getObject(VibrationAnalysisSettings::NAME); connect(obj, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectUpdated(UAVObject*,bool)), Qt::UniqueConnection); obj->requestUpdate(); obj = getObjectManager()->getObject(HoTTSettings::NAME); connect(obj, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectUpdated(UAVObject*,bool)), Qt::UniqueConnection); obj->requestUpdate(); obj = getObjectManager()->getObject(GeoFenceSettings::NAME); connect(obj, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectUpdated(UAVObject*,bool)), Qt::UniqueConnection); obj->requestUpdate(); obj = getObjectManager()->getObject(PicoCSettings::NAME); connect(obj, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectUpdated(UAVObject*,bool)), Qt::UniqueConnection); obj->requestUpdate(); }
/** * Retrieve the next object in the queue */ void TelemetryMonitor::retrieveNextObject() { // If queue is empty return if ( queue.isEmpty() ) { qxtLog->debug("Object retrieval completed"); emit connected(); return; } // Get next object from the queue UAVObject* obj = queue.dequeue(); //qxtLog->trace( tr("Retrieving object: %1").arg(obj->getName()) ); // Connect to object connect(obj, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(transactionCompleted(UAVObject*,bool))); // Request update obj->requestUpdate(); objPending = obj; }
void ConfigStabilizationWidget::updateObjectFromThrottleCurve() { UAVObject *stabBank = getObjectManager()->getObject(QString(m_stabTabBars.at(0)->tabData(m_currentStabSettingsBank).toString())); Q_ASSERT(stabBank); UAVObjectField *field = stabBank->getField("ThrustPIDScaleCurve"); Q_ASSERT(field); QList<double> curve = ui->thrustPIDScalingCurve->getCurve(); for (quint32 i = 0; i < field->getNumElements(); i++) { field->setValue(curve.at(i), i); } field = stabBank->getField("EnableThrustPIDScaling"); Q_ASSERT(field); field->setValue(ui->enableThrustPIDScalingCheckBox->isChecked() ? "TRUE" : "FALSE"); }
/** * @brief UAVObjectUtilManager::saveNextObject * * Processes the save queue. */ void UAVObjectUtilManager::saveNextObject() { if ( queue.isEmpty() ) { return; } Q_ASSERT(saveState == IDLE); // Get next object from the queue (don't dequeue yet) UAVObject* obj = queue.head(); Q_ASSERT(obj); qDebug() << "Send save object request to board " << obj->getName(); ObjectPersistence * objectPersistence = ObjectPersistence::GetInstance(getObjectManager()); Q_ASSERT(objectPersistence); // "transactionCompleted" is emitted once the objectPersistence object is sent over the telemetry link. // Since its metadata state that it should be ACK'ed on flight telemetry, the transactionCompleted signal // will be triggered once the GCS telemetry manager receives an ACK from the flight controller, or times // out. the success value will reflect success or failure. connect(objectPersistence, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectPersistenceTransactionCompleted(UAVObject*,bool))); // After we update the objectPersistence UAVO, we need to listen to its "objectUpdated" event, which will occur // once the flight controller sends this object back to the GCS, with the "Operation" field set to "Completed" // or "Error". connect(objectPersistence, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(objectPersistenceUpdated(UAVObject *))); saveState = AWAITING_ACK; qDebug() << "[saveObjectToFlash] Moving on to AWAITING_ACK"; ObjectPersistence::DataFields data; data.Operation = ObjectPersistence::OPERATION_SAVE; data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT; data.ObjectID = obj->getObjID(); data.InstanceID = obj->getInstID(); objectPersistence->setData(data); objectPersistence->updated(); // Now: we are going to get the following: // - two "objectUpdated" messages (one coming from GCS, one coming from Flight, which will confirm the object // was properly received by both sides). This is because the metadata of objectPersistence has "FlightUpdateOnChange" // set to true. // - then one "transactionCompleted" indicating that the Flight side did not only receive the object but it did // receive it without error (that message will be triggered by reception of the ACK). // - Last we will get one last "objectUpdated" message coming from flight side, where we'll get the results of // the objectPersistence operation we asked for (saved, other). }
void UAVObjectBrowserWidget::onTreeItemCollapsed(QModelIndex currentProxyIndex) { QModelIndex currentIndex = proxyModel->mapToSource(currentProxyIndex); TreeItem *item = static_cast<TreeItem*>(currentIndex.internalPointer()); TopTreeItem *top = dynamic_cast<TopTreeItem*>(item->parent()); //Check if current tree index is the child of the top tree item if (top) { ObjectTreeItem *objItem = dynamic_cast<ObjectTreeItem*>(item); //If the cast succeeds, then this is a UAVO if (objItem) { UAVObject *obj = objItem->object(); // Check for multiple instance UAVO if(!obj){ objItem = dynamic_cast<ObjectTreeItem*>(item->getChild(0)); obj = objItem->object(); } Q_ASSERT(obj); //Remove the UAVO, getting its stored value first. quint16 tmpUpdatePeriod = expandedUavoItems.value(obj->getName()); expandedUavoItems.take(obj->getName()); // Check if this was the fastest UAVO if (tmpUpdatePeriod == updatePeriod){ // If so, search for the new fastest UAVO updatePeriod = MAXIMUM_UPDATE_PERIOD; foreach(tmpUpdatePeriod, expandedUavoItems) { if (tmpUpdatePeriod < updatePeriod) updatePeriod = tmpUpdatePeriod; } treeView->updateTimerPeriod(updatePeriod); } } }
foreach (QString objStr, strList) { // Add defaults UAVObject *obj = objManager->getObject(objStr); Q_ASSERT(obj); UAVObject::Metadata mdataDefault = obj->getDefaultMetadata(); QModelIndex index = schedulerModel->index(rowIndex,0, QModelIndex()); schedulerModel->setData(index, QString("%1ms").arg(mdataDefault.flightTelemetryUpdatePeriod)); // Save default metadata for later use defaultMdata.insert(obj->getName().append("Meta"), mdataDefault); // Connect live values to the "Current" column UAVDataObject *dobj = dynamic_cast<UAVDataObject*>(obj); Q_ASSERT(dobj); UAVMetaObject *mobj = dobj->getMetaObject(); connect(mobj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateCurrentColumn(UAVObject*))); // Updates the "Current" column with the live value updateCurrentColumn(mobj); rowIndex++; }
void ConfigStabilizationWidget::swapBankAndCurrent(int bank) { UAVObject *fromStabBankObject = getStabBankObject(m_currentStabSettingsBank); UAVObject *toStabBankObject = getStabBankObject(bank); if (fromStabBankObject && toStabBankObject) { quint8 fromStabBankObjectData[fromStabBankObject->getNumBytes()]; quint8 toStabBankObjectData[toStabBankObject->getNumBytes()]; fromStabBankObject->pack(fromStabBankObjectData); toStabBankObject->pack(toStabBankObjectData); toStabBankObject->unpack(fromStabBankObjectData); fromStabBankObject->unpack(toStabBankObjectData); } }
/** * Process an byte from the telemetry stream. * \param[in] rxbyte Received byte * \return Success (true), Failure (false) */ bool UAVTalk::processInputByte(quint8 rxbyte) { // Update stats stats.rxBytes++; rxPacketLength++; // update packet byte count // Receive state machine switch (rxState) { case STATE_SYNC: if (rxbyte != SYNC_VAL) { UAVTALK_QXTLOG_DEBUG("UAVTalk: Sync->Sync (" + QString::number(rxbyte) + " " + QString("0x%1").arg(rxbyte,2,16) + ")"); break; } // Initialize and update CRC rxCS = updateCRC(0, rxbyte); rxPacketLength = 1; rxState = STATE_TYPE; UAVTALK_QXTLOG_DEBUG("UAVTalk: Sync->Type"); break; case STATE_TYPE: // Update CRC rxCS = updateCRC(rxCS, rxbyte); if ((rxbyte & TYPE_MASK) != TYPE_VER) { rxState = STATE_SYNC; UAVTALK_QXTLOG_DEBUG("UAVTalk: Type->Sync"); break; } rxType = rxbyte; packetSize = 0; rxState = STATE_SIZE; UAVTALK_QXTLOG_DEBUG("UAVTalk: Type->Size"); rxCount = 0; break; case STATE_SIZE: // Update CRC rxCS = updateCRC(rxCS, rxbyte); if (rxCount == 0) { packetSize += rxbyte; rxCount++; UAVTALK_QXTLOG_DEBUG("UAVTalk: Size->Size"); break; } packetSize += (quint32)rxbyte << 8; if (packetSize < MIN_HEADER_LENGTH || packetSize > MAX_HEADER_LENGTH + MAX_PAYLOAD_LENGTH) { // incorrect packet size rxState = STATE_SYNC; UAVTALK_QXTLOG_DEBUG("UAVTalk: Size->Sync"); break; } rxCount = 0; rxState = STATE_OBJID; UAVTALK_QXTLOG_DEBUG("UAVTalk: Size->ObjID"); break; case STATE_OBJID: // Update CRC rxCS = updateCRC(rxCS, rxbyte); rxTmpBuffer[rxCount++] = rxbyte; if (rxCount < 4) { UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->ObjID"); break; } // Search for object, if not found reset state machine rxObjId = (qint32)qFromLittleEndian<quint32>(rxTmpBuffer); { UAVObject *rxObj = objMngr->getObject(rxObjId); if (rxObj == NULL && rxType != TYPE_OBJ_REQ) { stats.rxErrors++; rxState = STATE_SYNC; UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->Sync (badtype)"); break; } // Determine data length if (rxType == TYPE_OBJ_REQ || rxType == TYPE_ACK || rxType == TYPE_NACK) { rxLength = 0; rxInstanceLength = 0; } else { rxLength = rxObj->getNumBytes(); rxInstanceLength = (rxObj->isSingleInstance() ? 0 : 2); } // Check length and determine next state if (rxLength >= MAX_PAYLOAD_LENGTH) { stats.rxErrors++; rxState = STATE_SYNC; UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->Sync (oversize)"); break; } // Check the lengths match if ((rxPacketLength + rxInstanceLength + rxLength) != packetSize) { // packet error - mismatched packet size stats.rxErrors++; rxState = STATE_SYNC; UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->Sync (length mismatch)"); break; } // Check if this is a single instance object (i.e. if the instance ID field is coming next) if (rxObj == NULL) { // This is a non-existing object, just skip to checksum // and we'll send a NACK next. rxState = STATE_CS; UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->CSum (no obj)"); rxInstId = 0; rxCount = 0; } else if (rxObj->isSingleInstance()) { // If there is a payload get it, otherwise receive checksum if (rxLength > 0) { rxState = STATE_DATA; UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->Data (needs data)"); } else { rxState = STATE_CS; UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->Checksum"); } rxInstId = 0; rxCount = 0; } else { rxState = STATE_INSTID; UAVTALK_QXTLOG_DEBUG("UAVTalk: ObjID->InstID"); rxCount = 0; } } break; case STATE_INSTID: // Update CRC rxCS = updateCRC(rxCS, rxbyte); rxTmpBuffer[rxCount++] = rxbyte; if (rxCount < 2) { UAVTALK_QXTLOG_DEBUG("UAVTalk: InstID->InstID"); break; } rxInstId = (qint16)qFromLittleEndian<quint16>(rxTmpBuffer); rxCount = 0; // If there is a payload get it, otherwise receive checksum if (rxLength > 0) { rxState = STATE_DATA; UAVTALK_QXTLOG_DEBUG("UAVTalk: InstID->Data"); } else { rxState = STATE_CS; UAVTALK_QXTLOG_DEBUG("UAVTalk: InstID->CSum"); } break; case STATE_DATA: // Update CRC rxCS = updateCRC(rxCS, rxbyte); rxBuffer[rxCount++] = rxbyte; if (rxCount < rxLength) { UAVTALK_QXTLOG_DEBUG("UAVTalk: Data->Data"); break; } rxState = STATE_CS; UAVTALK_QXTLOG_DEBUG("UAVTalk: Data->CSum"); rxCount = 0; break; case STATE_CS: // The CRC byte rxCSPacket = rxbyte; if (rxCS != rxCSPacket) { // packet error - faulty CRC stats.rxErrors++; rxState = STATE_SYNC; UAVTALK_QXTLOG_DEBUG("UAVTalk: CSum->Sync (badcrc)"); break; } if (rxPacketLength != packetSize + 1) { // packet error - mismatched packet size stats.rxErrors++; rxState = STATE_SYNC; UAVTALK_QXTLOG_DEBUG("UAVTalk: CSum->Sync (length mismatch)"); break; } mutex->lock(); receiveObject(rxType, rxObjId, rxInstId, rxBuffer, rxLength); stats.rxObjectBytes += rxLength; stats.rxObjects++; mutex->unlock(); rxState = STATE_SYNC; UAVTALK_QXTLOG_DEBUG("UAVTalk: CSum->Sync (OK)"); break; default: rxState = STATE_SYNC; stats.rxErrors++; UAVTALK_QXTLOG_DEBUG("UAVTalk: ???->Sync"); } // Done return true; }
/** * Process an byte from the telemetry stream. * \param[in] rxbyte Received byte * \return Success (true), Failure (false) */ bool UAVTalk::processInputByte(quint8 rxbyte) { if (!objMngr || !io) // Pip return false; // Update stats stats.rxBytes++; rxPacketLength++; // update packet byte count // Receive state machine switch (rxState) { case STATE_SYNC: if (rxbyte != SYNC_VAL) break; // Initialize and update CRC rxCS = updateCRC(0, rxbyte); rxPacketLength = 1; rxState = STATE_TYPE; break; case STATE_TYPE: // Update CRC rxCS = updateCRC(rxCS, rxbyte); if ((rxbyte & TYPE_MASK) != TYPE_VER) { rxState = STATE_SYNC; break; } rxType = rxbyte; packetSize = 0; rxState = STATE_SIZE; rxCount = 0; break; case STATE_SIZE: // Update CRC rxCS = updateCRC(rxCS, rxbyte); if (rxCount == 0) { packetSize += rxbyte; rxCount++; break; } packetSize += (quint32)rxbyte << 8; if (packetSize < MIN_HEADER_LENGTH || packetSize > MAX_HEADER_LENGTH + MAX_PAYLOAD_LENGTH) { // incorrect packet size rxState = STATE_SYNC; break; } rxCount = 0; rxState = STATE_OBJID; break; case STATE_OBJID: // Update CRC rxCS = updateCRC(rxCS, rxbyte); rxTmpBuffer[rxCount++] = rxbyte; if (rxCount < 4) break; // Search for object, if not found reset state machine rxObjId = (qint32)qFromLittleEndian<quint32>(rxTmpBuffer); { UAVObject *rxObj = objMngr->getObject(rxObjId); if (rxObj == NULL) { stats.rxErrors++; rxState = STATE_SYNC; break; } // Determine data length if (rxType == TYPE_OBJ_REQ || rxType == TYPE_ACK) rxLength = 0; else rxLength = rxObj->getNumBytes(); // Check length and determine next state if (rxLength >= MAX_PAYLOAD_LENGTH) { stats.rxErrors++; rxState = STATE_SYNC; break; } // Check the lengths match if ((rxPacketLength + rxLength) != packetSize) { // packet error - mismatched packet size stats.rxErrors++; rxState = STATE_SYNC; break; } // Check if this is a single instance object (i.e. if the instance ID field is coming next) if (rxObj->isSingleInstance()) { // If there is a payload get it, otherwise receive checksum if (rxLength > 0) rxState = STATE_DATA; else rxState = STATE_CS; rxInstId = 0; rxCount = 0; } else { rxState = STATE_INSTID; rxCount = 0; } } break; case STATE_INSTID: // Update CRC rxCS = updateCRC(rxCS, rxbyte); rxTmpBuffer[rxCount++] = rxbyte; if (rxCount < 2) break; rxInstId = (qint16)qFromLittleEndian<quint16>(rxTmpBuffer); rxCount = 0; // If there is a payload get it, otherwise receive checksum if (rxLength > 0) rxState = STATE_DATA; else rxState = STATE_CS; break; case STATE_DATA: // Update CRC rxCS = updateCRC(rxCS, rxbyte); rxBuffer[rxCount++] = rxbyte; if (rxCount < rxLength) break; rxState = STATE_CS; rxCount = 0; break; case STATE_CS: // The CRC byte rxCSPacket = rxbyte; if (rxCS != rxCSPacket) { // packet error - faulty CRC stats.rxErrors++; rxState = STATE_SYNC; break; } if (rxPacketLength != packetSize + 1) { // packet error - mismatched packet size stats.rxErrors++; rxState = STATE_SYNC; break; } mutex->lock(); receiveObject(rxType, rxObjId, rxInstId, rxBuffer, rxLength); stats.rxObjectBytes += rxLength; stats.rxObjects++; mutex->unlock(); rxState = STATE_SYNC; break; default: rxState = STATE_SYNC; stats.rxErrors++; } // Done return true; }
ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_config = new Ui_OutputWidget(); m_config->setupUi(this); ExtensionSystem::PluginManager *pm=ExtensionSystem::PluginManager::instance(); Core::Internal::GeneralSettings * settings=pm->getObject<Core::Internal::GeneralSettings>(); if(!settings->useExpertMode()) m_config->saveRCOutputToRAM->setVisible(false); /* There's lots of situations where it's unsafe to run tests. * Import/export: */ UAVSettingsImportExportFactory * importexportplugin = pm->getObject<UAVSettingsImportExportFactory>(); connect(importexportplugin,SIGNAL(importAboutToBegin()),this,SLOT(stopTests())); /* Board connection/disconnection: */ TelemetryManager* telMngr = pm->getObject<TelemetryManager>(); connect(telMngr, SIGNAL(connected()), this, SLOT(stopTests())); connect(telMngr, SIGNAL(disconnected()), this, SLOT(stopTests())); /* When we go into wizards, etc.. time to stop this too. */ Core::ModeManager *modeMngr = Core::ModeManager::instance(); connect(modeMngr, SIGNAL(currentModeAboutToChange(Core::IMode *)), this, SLOT(stopTests())); connect(modeMngr, SIGNAL(currentModeChanged(Core::IMode *)), this, SLOT(stopTests())); // NOTE: we have channel indices from 0 to 9, but the convention for OP is Channel 1 to Channel 10. // Register for ActuatorSettings changes: for (unsigned int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) { OutputChannelForm *outputForm = new OutputChannelForm(i, this, i==0); m_config->channelLayout->addWidget(outputForm); connect(m_config->channelOutTest, SIGNAL(toggled(bool)), outputForm, SLOT(enableChannelTest(bool))); connect(outputForm, SIGNAL(channelChanged(int,int)), this, SLOT(sendChannelTest(int,int))); connect(outputForm, SIGNAL(formChanged()), this, SLOT(do_SetDirty())); } connect(m_config->channelOutTest, SIGNAL(toggled(bool)), this, SLOT(runChannelTests(bool))); connect(m_config->calibrateESC, SIGNAL(clicked()), this, SLOT(startESCCalibration())); // Configure the task widget // Connect the help button connect(m_config->outputHelp, SIGNAL(clicked()), this, SLOT(openHelp())); addApplySaveButtons(m_config->saveRCOutputToRAM,m_config->saveRCOutputToSD); // Track the ActuatorSettings object addUAVObject("ActuatorSettings"); // Associate the buttons with their UAVO fields addWidget(m_config->cb_outputRate6); addWidget(m_config->cb_outputRate5); addWidget(m_config->cb_outputRate4); addWidget(m_config->cb_outputRate3); addWidget(m_config->cb_outputRate2); addWidget(m_config->cb_outputRate1); addWidget(m_config->spinningArmed); // Cache all the combo boxes and labels lblList.clear(); lblList << m_config->chBank1 << m_config->chBank2 << m_config->chBank3 << m_config->chBank4 << m_config->chBank5 << m_config->chBank6; rateList.clear(); rateList << m_config->cb_outputRate1 << m_config->cb_outputRate2 << m_config->cb_outputRate3 << m_config->cb_outputRate4 << m_config->cb_outputRate5 << m_config->cb_outputRate6; resList.clear(); resList << m_config->cb_outputResolution1 << m_config->cb_outputResolution2 << m_config->cb_outputResolution3 << m_config->cb_outputResolution4 << m_config->cb_outputResolution5 << m_config->cb_outputResolution6; // Get the list of output resolutions and assign to the resolution dropdowns ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager()); Q_ASSERT(actuatorSettings); UAVObjectField *resolutions = actuatorSettings->getField("TimerPwmResolution"); Q_ASSERT(resolutions); QList<QComboBox*>::iterator resIter; for (resIter = resList.begin(); resIter != resList.end(); resIter++) { QComboBox *res = *resIter; res->clear(); res->addItems(resolutions->getOptions()); addWidget(res); connect(res, SIGNAL(currentIndexChanged(int)), this, SLOT(refreshWidgetRanges())); } QList<QComboBox*>::iterator rateIter; for (rateIter = rateList.begin(); rateIter != rateList.end(); rateIter++) { QComboBox *rate = *rateIter; connect(rate, SIGNAL(currentIndexChanged(int)), this, SLOT(refreshWidgetRanges())); } disconnect(this, SLOT(refreshWidgetsValues(UAVObject*))); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObject* obj = objManager->getObject(QString("ActuatorCommand")); if(UAVObject::GetGcsTelemetryUpdateMode(obj->getMetadata()) == UAVObject::UPDATEMODE_ONCHANGE) this->setEnabled(false); connect(SystemSettings::GetInstance(objManager), SIGNAL(objectUpdated(UAVObject*)),this,SLOT(assignOutputChannels(UAVObject*))); refreshWidgetsValues(); }
// Slot called by the menu manager on user action void UAVSettingsImportExportFactory::importUAVSettings() { // ask for file name QString fileName; QString filters = tr("UAVObjects XML files (*.uav);; XML files (*.xml)"); fileName = QFileDialog::getOpenFileName(0, tr("Import UAV Settings"), "", filters); if (fileName.isEmpty()) { return; } // Now open the file QFile file(fileName); QDomDocument doc("UAVObjects"); file.open(QFile::ReadOnly | QFile::Text); if (!doc.setContent(file.readAll())) { QMessageBox msgBox; msgBox.setText(tr("File Parsing Failed.")); msgBox.setInformativeText(tr("This file is not a correct XML file")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.exec(); return; } file.close(); // find the root of settings subtree emit importAboutToBegin(); qDebug() << "Import about to begin"; QDomElement root = doc.documentElement(); if (root.tagName() == "uavobjects") { root = root.firstChildElement("settings"); } if (root.isNull() || (root.tagName() != "settings")) { QMessageBox msgBox; msgBox.setText(tr("Wrong file contents")); msgBox.setInformativeText(tr("This file does not contain correct UAVSettings")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.exec(); return; } // We are now ok: setup the import summary dialog & update it as we // go along. ImportSummaryDialog swui((QWidget *)Core::ICore::instance()->mainWindow()); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); swui.show(); QDomNode node = root.firstChild(); while (!node.isNull()) { QDomElement e = node.toElement(); if (e.tagName() == "object") { // - Read each object QString uavObjectName = e.attribute("name"); uint uavObjectID = e.attribute("id").toUInt(NULL, 16); // Sanity Check: UAVObject *obj = objManager->getObject(uavObjectName); if (obj == NULL) { // This object is unknown! qDebug() << "Object unknown:" << uavObjectName << uavObjectID; swui.addLine(uavObjectName, "Error (Object unknown)", false); } else { // - Update each field // - Issue and "updated" command bool error = false; bool setError = false; QDomNode field = node.firstChild(); while (!field.isNull()) { QDomElement f = field.toElement(); if (f.tagName() == "field") { UAVObjectField *uavfield = obj->getField(f.attribute("name")); if (uavfield) { QStringList list = f.attribute("values").split(","); if (list.length() == 1) { if (false == uavfield->checkValue(f.attribute("values"))) { qDebug() << "checkValue returned false on: " << uavObjectName << f.attribute("values"); setError = true; } else { uavfield->setValue(f.attribute("values")); } } else { // This is an enum: int i = 0; QStringList list = f.attribute("values").split(","); foreach(QString element, list) { if (false == uavfield->checkValue(element, i)) { qDebug() << "checkValue(list) returned false on: " << uavObjectName << list; setError = true; } else { uavfield->setValue(element, i); } i++; } } } else { error = true; } } field = field.nextSibling(); } obj->updated(); if (error) { swui.addLine(uavObjectName, "Warning (Object field unknown)", true); } else if (uavObjectID != obj->getObjID()) { qDebug() << "Mismatch for Object " << uavObjectName << uavObjectID << " - " << obj->getObjID(); swui.addLine(uavObjectName, "Warning (ObjectID mismatch)", true); } else if (setError) { swui.addLine(uavObjectName, "Warning (Objects field value(s) invalid)", false); } else { swui.addLine(uavObjectName, "OK", true); } }
ConfigAHRSWidget::ConfigAHRSWidget(QWidget *parent) : ConfigTaskWidget(parent) { m_ahrs = new Ui_AHRSWidget(); m_ahrs->setupUi(this); // Initialization of the Paper plane widget m_ahrs->sixPointsHelp->setScene(new QGraphicsScene(this)); paperplane = new QGraphicsSvgItem(); paperplane->setSharedRenderer(new QSvgRenderer()); paperplane->renderer()->load(QString(":/configgadget/images/paper-plane.svg")); paperplane->setElementId("plane-horizontal"); m_ahrs->sixPointsHelp->scene()->addItem(paperplane); m_ahrs->sixPointsHelp->setSceneRect(paperplane->boundingRect()); // Initialization of the AHRS bargraph graph m_ahrs->ahrsBargraph->setScene(new QGraphicsScene(this)); QSvgRenderer *renderer = new QSvgRenderer(); ahrsbargraph = new QGraphicsSvgItem(); renderer->load(QString(":/configgadget/images/ahrs-calib.svg")); ahrsbargraph->setSharedRenderer(renderer); ahrsbargraph->setElementId("background"); ahrsbargraph->setObjectName("background"); m_ahrs->ahrsBargraph->scene()->addItem(ahrsbargraph); m_ahrs->ahrsBargraph->setSceneRect(ahrsbargraph->boundingRect()); // Initialize the 9 bargraph values: QMatrix lineMatrix = renderer->matrixForElement("accel_x"); QRectF rect = lineMatrix.mapRect(renderer->boundsOnElement("accel_x")); qreal startX = rect.x(); qreal startY = rect.y()+ rect.height(); // maxBarHeight will be used for scaling it later. maxBarHeight = rect.height(); // Then once we have the initial location, we can put it // into a QGraphicsSvgItem which we will display at the same // place: we do this so that the heading scale can be clipped to // the compass dial region. accel_x = new QGraphicsSvgItem(); accel_x->setSharedRenderer(renderer); accel_x->setElementId("accel_x"); m_ahrs->ahrsBargraph->scene()->addItem(accel_x); accel_x->setPos(startX, startY); accel_x->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("accel_y"); rect = lineMatrix.mapRect(renderer->boundsOnElement("accel_y")); startX = rect.x(); startY = rect.y()+ rect.height(); accel_y = new QGraphicsSvgItem(); accel_y->setSharedRenderer(renderer); accel_y->setElementId("accel_y"); m_ahrs->ahrsBargraph->scene()->addItem(accel_y); accel_y->setPos(startX,startY); accel_y->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("accel_z"); rect = lineMatrix.mapRect(renderer->boundsOnElement("accel_z")); startX = rect.x(); startY = rect.y()+ rect.height(); accel_z = new QGraphicsSvgItem(); accel_z->setSharedRenderer(renderer); accel_z->setElementId("accel_z"); m_ahrs->ahrsBargraph->scene()->addItem(accel_z); accel_z->setPos(startX,startY); accel_z->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("gyro_x"); rect = lineMatrix.mapRect(renderer->boundsOnElement("gyro_x")); startX = rect.x(); startY = rect.y()+ rect.height(); gyro_x = new QGraphicsSvgItem(); gyro_x->setSharedRenderer(renderer); gyro_x->setElementId("gyro_x"); m_ahrs->ahrsBargraph->scene()->addItem(gyro_x); gyro_x->setPos(startX,startY); gyro_x->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("gyro_y"); rect = lineMatrix.mapRect(renderer->boundsOnElement("gyro_y")); startX = rect.x(); startY = rect.y()+ rect.height(); gyro_y = new QGraphicsSvgItem(); gyro_y->setSharedRenderer(renderer); gyro_y->setElementId("gyro_y"); m_ahrs->ahrsBargraph->scene()->addItem(gyro_y); gyro_y->setPos(startX,startY); gyro_y->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("gyro_z"); rect = lineMatrix.mapRect(renderer->boundsOnElement("gyro_z")); startX = rect.x(); startY = rect.y()+ rect.height(); gyro_z = new QGraphicsSvgItem(); gyro_z->setSharedRenderer(renderer); gyro_z->setElementId("gyro_z"); m_ahrs->ahrsBargraph->scene()->addItem(gyro_z); gyro_z->setPos(startX,startY); gyro_z->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("mag_x"); rect = lineMatrix.mapRect(renderer->boundsOnElement("mag_x")); startX = rect.x(); startY = rect.y()+ rect.height(); mag_x = new QGraphicsSvgItem(); mag_x->setSharedRenderer(renderer); mag_x->setElementId("mag_x"); m_ahrs->ahrsBargraph->scene()->addItem(mag_x); mag_x->setPos(startX,startY); mag_x->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("mag_y"); rect = lineMatrix.mapRect(renderer->boundsOnElement("mag_y")); startX = rect.x(); startY = rect.y()+ rect.height(); mag_y = new QGraphicsSvgItem(); mag_y->setSharedRenderer(renderer); mag_y->setElementId("mag_y"); m_ahrs->ahrsBargraph->scene()->addItem(mag_y); mag_y->setPos(startX,startY); mag_y->setTransform(QTransform::fromScale(1,0),true); lineMatrix = renderer->matrixForElement("mag_z"); rect = lineMatrix.mapRect(renderer->boundsOnElement("mag_z")); startX = rect.x(); startY = rect.y()+ rect.height(); mag_z = new QGraphicsSvgItem(); mag_z->setSharedRenderer(renderer); mag_z->setElementId("mag_z"); m_ahrs->ahrsBargraph->scene()->addItem(mag_z); mag_z->setPos(startX,startY); mag_z->setTransform(QTransform::fromScale(1,0),true); position = -1; // Fill the dropdown menus: UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSSettings"))); UAVObjectField *field = obj->getField(QString("Algorithm")); m_ahrs->algorithm->addItems(field->getOptions()); // Register for Home Location state changes obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("HomeLocation"))); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this , SLOT(enableHomeLocSave(UAVObject*))); // Connect the signals connect(m_ahrs->ahrsCalibStart, SIGNAL(clicked()), this, SLOT(launchAHRSCalibration())); connect(m_ahrs->ahrsSettingsRequest, SIGNAL(clicked()), this, SLOT(ahrsSettingsRequest())); /* connect(m_ahrs->algorithm, SIGNAL(currentIndexChanged(int)), this, SLOT(ahrsSettingsSave())); connect(m_ahrs->indoorFlight, SIGNAL(stateChanged(int)), this, SLOT(homeLocationSave())); connect(m_ahrs->homeLocation, SIGNAL(clicked()), this, SLOT(homeLocationSaveSD())); */ connect(m_ahrs->ahrsSettingsSaveRAM, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveRAM())); connect(m_ahrs->ahrsSettingsSaveSD, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveSD())); connect(m_ahrs->sixPointsStart, SIGNAL(clicked()), this, SLOT(sixPointCalibrationMode())); connect(m_ahrs->sixPointsSave, SIGNAL(clicked()), this, SLOT(savePositionData())); connect(parent, SIGNAL(autopilotConnected()),this, SLOT(ahrsSettingsRequest())); }
/** * Updates the slider positions and min/max values * */ void ConfigServoWidget::updateChannels(UAVObject* controlCommand) { QString fieldName = QString("Connected"); UAVObjectField *field = controlCommand->getField(fieldName); if (field->getValue().toBool()) m_config->RCInputConnected->setText("RC Receiver Connected"); else m_config->RCInputConnected->setText("RC Receiver Not Connected"); if (m_config->doRCInputCalibration->isChecked()) { if (firstUpdate) { // Increase the data rate from the board so that the sliders // move faster UAVObject::Metadata mdata = controlCommand->getMetadata(); mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC; mccDataRate = mdata.flightTelemetryUpdatePeriod; mdata.flightTelemetryUpdatePeriod = 150; controlCommand->setMetadata(mdata); // Also protect the user by setting all values to zero // and making the ActuatorCommand object readonly UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand"))); mdata = obj->getMetadata(); mdata.flightAccess = UAVObject::ACCESS_READONLY; obj->setMetadata(mdata); UAVObjectField *field = obj->getField("Channel"); for (int i=0; i< field->getNumElements(); i++) { field->setValue(0,i); } obj->updated(); } field = controlCommand->getField(QString("Channel")); for (int i = 0; i < 8; i++) updateChannelInSlider(inSliders[i], inMinLabels[i], inMaxLabels[i], reversals[i], field->getValue(i).toInt()); firstUpdate = false; } else { if (!firstUpdate) { // Restore original data rate from the board: UAVObject::Metadata mdata = controlCommand->getMetadata(); mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC; mdata.flightTelemetryUpdatePeriod = mccDataRate; controlCommand->setMetadata(mdata); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand"))); mdata = obj->getMetadata(); mdata.flightAccess = UAVObject::ACCESS_READWRITE; obj->setMetadata(mdata); } firstUpdate = true; } //Update the Flight mode channel slider UAVObject* obj = getObjectManager()->getObject("ManualControlSettings"); // Find the channel currently assigned to flightmode field = obj->getField("FlightMode"); int chIndex = field->getOptions().indexOf(field->getValue().toString()); if (chIndex < field->getOptions().length() - 1) { float valueScaled; int chMin = inSliders[chIndex]->minimum(); int chMax = inSliders[chIndex]->maximum(); int chNeutral = inSliders[chIndex]->value(); int value = controlCommand->getField("Channel")->getValue(chIndex).toInt(); if ((chMax > chMin && value >= chNeutral) || (chMin > chMax && value <= chNeutral)) { if (chMax != chNeutral) valueScaled = (float)(value - chNeutral) / (float)(chMax - chNeutral); else valueScaled = 0; } else { if (chMin != chNeutral) valueScaled = (float)(value - chNeutral) / (float)(chNeutral - chMin); else valueScaled = 0; } // Bound if (valueScaled > 1.0) valueScaled = 1.0; else if (valueScaled < -1.0) valueScaled = -1.0; m_config->fmsSlider->setValue(valueScaled * 100); } }