Browse Source

actuators: update output function parameter metadata

- remove the mixer functions that are unused with the current configration
  (e.g. if 4 motors -> remove motors 5-N)
- use the specific labels
QGC4.4
Beat Küng 3 years ago
parent
commit
d78b21cb5e
  1. 83
      src/Vehicle/Actuators/Actuators.cc
  2. 3
      src/Vehicle/Actuators/Actuators.h
  3. 33
      src/Vehicle/Actuators/Mixer.cc
  4. 4
      src/Vehicle/Actuators/Mixer.h

83
src/Vehicle/Actuators/Actuators.cc

@ -239,7 +239,7 @@ void Actuators::parametersChanged() @@ -239,7 +239,7 @@ void Actuators::parametersChanged()
_actuatorTest.updateFunctions(actuators);
// check if there are required functions, but not set on any output
QSet<int> requiredFunctions = _mixer.requiredFunctions();
QSet<int> requiredFunctions = _mixer.getFunctions(true);
_hasUnsetRequiredFunctions = false;
for (int requiredFunction : requiredFunctions) {
if (uniqueConfiguredFunctions.find(requiredFunction) == uniqueConfiguredFunctions.end()) {
@ -248,11 +248,92 @@ void Actuators::parametersChanged() @@ -248,11 +248,92 @@ void Actuators::parametersChanged()
}
emit hasUnsetRequiredFunctionsChanged();
updateFunctionMetadata();
updateActuatorActions();
updateGeometryImage();
}
void Actuators::updateFunctionMetadata()
{
// Update the function parameter metadata:
// - remove the mixer functions that are unused with the current configration (e.g. if 4 motors -> remove motors 5-N)
// - use the specific labels
QSet<int> usedMixerFunctions = _mixer.getFunctions(false);
QMap<int, QString> usedMixerLabels;
for (int usedMixerFunction : usedMixerFunctions) {
usedMixerLabels[usedMixerFunction] = _mixer.getSpecificLabelForFunction(usedMixerFunction);
}
if (_usedMixerLabels == usedMixerLabels) {
// no update required
return;
}
_usedMixerLabels = usedMixerLabels;
// Get the unused mixer functions
QSet<int> removedMixerFunctions;
for(Mixer::ActuatorTypes::const_iterator iter = _mixer.actuatorTypes().constBegin();
iter != _mixer.actuatorTypes().constEnd(); ++iter) {
if (iter.key() == "DEFAULT")
continue;
for (int i = iter.value().functionMin; i <= iter.value().functionMax; ++i) {
if (!usedMixerFunctions.contains(i)) {
removedMixerFunctions.insert(i);
}
}
}
// Now update all function facts (we need to treat them individually, as some might have extra functions)
for (int groupIdx = 0; groupIdx < _actuatorOutputs->count(); groupIdx++) {
ActuatorOutput* group = qobject_cast<ActuatorOutput*>(_actuatorOutputs->get(groupIdx));
group->forEachOutputFunction([&](ActuatorOutputSubgroup* subgroup, ChannelConfigInstance*, Fact* fact) {
QStringList enumStrings = fact->enumStrings();
if (!enumStrings.empty()) {
QVariantList enumValues = fact->enumValues();
// Replace or add
for (int usedMixerFunction : usedMixerFunctions) {
QString label = usedMixerLabels[usedMixerFunction];
int index = enumValues.indexOf(usedMixerFunction);
if (index == -1) {
// Insert at the right place
bool inserted = false;
for (index = 0; index < enumValues.count() && !inserted; ++index) {
if (enumValues[index].toInt() > usedMixerFunction) {
enumValues.insert(index, usedMixerFunction);
enumStrings.insert(index, label);
inserted = true;
}
}
if (!inserted) {
enumValues.append(usedMixerFunction);
enumStrings.append(label);
}
} else {
enumStrings[index] = label;
}
}
// Remove
for (int removedMixerFunction : removedMixerFunctions) {
int index = enumValues.indexOf(removedMixerFunction);
if (index != -1) {
enumValues.removeAt(index);
enumStrings.removeAt(index);
}
}
fact->setEnumInfo(enumStrings, enumValues);
}
});
}
}
void Actuators::updateActuatorActions()
{
_actuatorActions->clearAndDeleteContents();

3
src/Vehicle/Actuators/Actuators.h

@ -106,6 +106,8 @@ private: @@ -106,6 +106,8 @@ private:
void highlightActuators(bool highlight);
void updateFunctionMetadata();
QSet<Fact*> _subscribedFacts{};
QJsonDocument _jsonMetadata;
bool _init{false};
@ -120,5 +122,6 @@ private: @@ -120,5 +122,6 @@ private:
bool _imageRefreshFlag{false}; ///< indicator to QML to reload the image
int _selectedActuatorOutput{0};
Vehicle* _vehicle{nullptr};
QMap<int, QString> _usedMixerLabels;
};

33
src/Vehicle/Actuators/Mixer.cc

@ -317,7 +317,7 @@ void Mixers::update() @@ -317,7 +317,7 @@ void Mixers::update()
}
if (itemLabelPrefix != "") {
label = itemLabelPrefix + " (" + label + ")";
_functionsSpecificLabel[actuatorFunction] = label;
_functionsSpecificLabel[actuatorFunction] = itemLabelPrefix;
}
}
auto factAdded = [this](Function function, Fact* fact) {
@ -348,20 +348,37 @@ void Mixers::update() @@ -348,20 +348,37 @@ void Mixers::update()
QString Mixers::getSpecificLabelForFunction(int function) const
{
// Try to get it from the actuator type param
for (int mixerGroupIdx = 0; mixerGroupIdx < _groups->count(); ++mixerGroupIdx) {
Fact* typeFact = nullptr;
for (int mixerGroupIdx = 0; !typeFact && mixerGroupIdx < _groups->count(); ++mixerGroupIdx) {
Mixer::MixerConfigGroup* mixerGroup = _groups->value<Mixer::MixerConfigGroup*>(mixerGroupIdx);
for (int mixerChannelIdx = 0; mixerChannelIdx < mixerGroup->channels()->count(); ++mixerChannelIdx) {
for (int mixerChannelIdx = 0; !typeFact && mixerChannelIdx < mixerGroup->channels()->count(); ++mixerChannelIdx) {
Mixer::MixerChannel* mixerChannel = mixerGroup->channels()->value<Mixer::MixerChannel*>(mixerChannelIdx);
if (mixerChannel->actuatorFunction() != function) {
continue;
}
Fact* typeFact = mixerChannel->getFact(Function::Type);
if (typeFact) {
return typeFact->enumOrValueString() + " (" + _functions.value(function).label +")";
typeFact = mixerChannel->getFact(Function::Type);
}
}
if (typeFact) {
// Now check if we have multiple functions configured with the same type.
// If so, add the function label to disambiguate
for (int mixerGroupIdx = 0; mixerGroupIdx < _groups->count(); ++mixerGroupIdx) {
Mixer::MixerConfigGroup* mixerGroup = _groups->value<Mixer::MixerConfigGroup*>(mixerGroupIdx);
for (int mixerChannelIdx = 0; mixerChannelIdx < mixerGroup->channels()->count(); ++mixerChannelIdx) {
Mixer::MixerChannel* mixerChannel = mixerGroup->channels()->value<Mixer::MixerChannel*>(mixerChannelIdx);
if (mixerChannel->actuatorFunction() == function) {
continue;
}
Fact* typeFactOther = mixerChannel->getFact(Function::Type);
if (typeFactOther && typeFactOther->rawValue() == typeFact->rawValue()) {
return typeFact->enumOrValueString() + " (" + _functions.value(function).label +")";
}
}
}
return typeFact->enumOrValueString();
}
const auto iter = _functionsSpecificLabel.find(function);
@ -371,12 +388,12 @@ QString Mixers::getSpecificLabelForFunction(int function) const @@ -371,12 +388,12 @@ QString Mixers::getSpecificLabelForFunction(int function) const
return *iter;
}
QSet<int> Mixers::requiredFunctions() const
QSet<int> Mixers::getFunctions(bool requiredOnly) const
{
QSet<int> ret;
for (int mixerGroupIdx = 0; mixerGroupIdx < _groups->count(); ++mixerGroupIdx) {
Mixer::MixerConfigGroup* mixerGroup = _groups->value<Mixer::MixerConfigGroup*>(mixerGroupIdx);
if (mixerGroup->group().required) {
if (!requiredOnly || mixerGroup->group().required) {
for (int mixerChannelIdx = 0; mixerChannelIdx < mixerGroup->channels()->count(); ++mixerChannelIdx) {
const Mixer::MixerChannel* mixerChannel = mixerGroup->channels()->value<Mixer::MixerChannel*>(mixerChannelIdx);
if (mixerChannel->actuatorFunction() != 0) {

4
src/Vehicle/Actuators/Mixer.h

@ -321,9 +321,9 @@ public: @@ -321,9 +321,9 @@ public:
QString getSpecificLabelForFunction(int function) const;
/**
* Get the set of all required actuator functions
* Get the set of all (required) actuator functions
*/
QSet<int> requiredFunctions() const;
QSet<int> getFunctions(bool requiredOnly) const;
QString configuredType() const;

Loading…
Cancel
Save