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

Added support for objects value limits on the GCS to the GCS and generator.

This commit is contained in:
zedamota 2012-02-03 20:29:28 +00:00
parent 4c1e33b0b3
commit 427acee559
8 changed files with 253 additions and 100 deletions

View File

@ -48,6 +48,7 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa
addDefaultButton(m_stabilization->defaultButton,0);
addReloadButton(m_stabilization->reloadButton,0);
addWidgetToDefaultReloadGroups(m_stabilization->rateRollKp,rateGroup);
addShadowWidget("StabilizationSettings","RollRatePID",m_stabilization->rateRollKi,0,1,false,rateGroup);
}

View File

@ -68,6 +68,9 @@ void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString fiel
}
void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString field, QWidget * widget, int index,float scale,bool isLimited,QList<int>* defaultReloadGroups)
{
if(addShadowWidget(object,field,widget,index,scale,isLimited,defaultReloadGroups))
return;
UAVObject *obj=NULL;
UAVObjectField *_field=NULL;
if(!object.isEmpty())
@ -100,16 +103,28 @@ void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString fiel
// do nothing
}
else
{
connectWidgetUpdatesToSlot(widget,SLOT(widgetsContentsChanged()));
if(defaultReloadGroups)
addWidgetToDefaultReloadGroups(widget,defaultReloadGroups);
shadowsList.insert(widget,ow);
}
}
ConfigTaskWidget::~ConfigTaskWidget()
{
delete smartsave;
if(smartsave)
delete smartsave;
foreach(QList<objectToWidget*>* pointer,defaultReloadGroups.values())
delete pointer;
{
if(pointer)
delete pointer;
}
foreach (objectToWidget* oTw, objOfInterest)
{
if(oTw)
delete oTw;
}
}
void ConfigTaskWidget::saveObjectToSD(UAVObject *obj)
@ -230,6 +245,39 @@ void ConfigTaskWidget::enableControls(bool enable)
void ConfigTaskWidget::widgetsContentsChanged()
{
float scale;
qDebug()<<"sender:"<<(quint32)sender();
foreach(QWidget * w,shadowsList.keys())
qDebug()<<"in list:"<<(quint32)w;
objectToWidget * oTw= shadowsList.value((QWidget*)sender(),NULL);
if(oTw)
qDebug()<<"in oTw OK"<<(quint32)oTw->widget;
if(oTw)
{
if(oTw->widget==(QWidget*)sender())
{
scale=oTw->scale;
qDebug()<<"sender was master";
}
else
{
foreach (shadow * sh, oTw->shadowsList)
{
if(sh->widget==(QWidget*)sender())
{
scale=sh->scale;
qDebug()<<"sender was shadow";
}
}
}
if(oTw->widget!=(QWidget *)sender())
setWidgetFromVariant(oTw->widget,getVariantFromWidget((QWidget*)sender(),scale),oTw->scale);
foreach (shadow * sh, oTw->shadowsList)
{
if(sh->widget!=(QWidget*)sender())
setWidgetFromVariant(sh->widget,getVariantFromWidget((QWidget*)sender(),scale),sh->scale);
}
}
setDirty(true);
}
@ -249,10 +297,6 @@ bool ConfigTaskWidget::isDirty()
return false;
}
void ConfigTaskWidget::refreshValues()
{
}
void ConfigTaskWidget::disableObjUpdates()
{
foreach(objectToWidget * obj,objOfInterest)
@ -323,15 +367,27 @@ void ConfigTaskWidget::invalidateObjects()
}
}
bool ConfigTaskWidget::addShadowWidget(QString object, QString field, QWidget *widget, int index, float scale, bool isLimited)
bool ConfigTaskWidget::addShadowWidget(QString object, QString field, QWidget *widget, int index, float scale, bool isLimited,QList<int>* defaultReloadGroups)
{
foreach(objectToWidget * oTw, objOfInterest)
foreach(objectToWidget * oTw,objOfInterest)
{
if(!oTw->object || !oTw->widget)
continue;
if(oTw->object->getName()==object && oTw->field->getName()==field && oTw->index==index)
{
oTw->shadows.append(widget);
shadow * sh=new shadow;
sh->isLimited=isLimited;
sh->scale=scale;
sh->widget=widget;
oTw->shadowsList.append(sh);
shadowsList.insert(widget,oTw);
connectWidgetUpdatesToSlot(widget,SLOT(widgetsContentsChanged()));
if(defaultReloadGroups)
addWidgetToDefaultReloadGroups(widget,defaultReloadGroups);
return true;
}
}
return false;
}
void ConfigTaskWidget::autoLoadWidgets()
@ -442,9 +498,9 @@ void ConfigTaskWidget::addWidgetToDefaultReloadGroups(QWidget *widget, QList<int
addOTW=true;
else
{
foreach(QWidget * shadow, oTw->shadows)
foreach(shadow * sh, oTw->shadowsList)
{
if(shadow==widget)
if(sh->widget==widget)
addOTW=true;
}
}
@ -481,6 +537,8 @@ void ConfigTaskWidget::defaultButtonClicked()
QList<objectToWidget*> * list=defaultReloadGroups.value(group);
foreach(objectToWidget * oTw,*list)
{
if(!oTw->object)
continue;
UAVDataObject * temp=((UAVDataObject*)oTw->object)->dirtyClone();
setWidgetFromField(oTw->widget,temp->getField(oTw->field->getName()),oTw->index,oTw->scale);
}
@ -491,6 +549,10 @@ void ConfigTaskWidget::reloadButtonClicked()
int group=sender()->property("group").toInt();
QList<objectToWidget*> * list=defaultReloadGroups.value(group);
ObjectPersistence* objper = dynamic_cast<ObjectPersistence*>( getObjectManager()->getObject(ObjectPersistence::NAME) );
QTimer * timeOut=new QTimer(this);
QEventLoop * eventLoop=new QEventLoop(this);
connect(timeOut, SIGNAL(timeout()),eventLoop,SLOT(quit()));
connect(objper, SIGNAL(objectUpdated(UAVObject*)), eventLoop, SLOT(quit()));
foreach(objectToWidget * oTw,*list)
{
if (oTw->object != NULL)
@ -502,9 +564,19 @@ void ConfigTaskWidget::reloadButtonClicked()
data.InstanceID = oTw->object->getInstID();
objper->setData(data);
objper->updated();
timeOut->start(500);
eventLoop->exec();
if(timeOut->isActive())
{
setWidgetFromField(oTw->widget,oTw->field,oTw->index,oTw->scale);
}
timeOut->stop();
}
}
delete eventLoop;
delete timeOut;
}
void ConfigTaskWidget::connectWidgetUpdatesToSlot(QWidget * widget,const char* function)
{
if(!widget)
@ -545,46 +617,87 @@ void ConfigTaskWidget::connectWidgetUpdatesToSlot(QWidget * widget,const char* f
qDebug()<<__FUNCTION__<<"widget to uavobject relation not implemented"<<widget->metaObject()->className();
}
bool ConfigTaskWidget::setFieldFromWidget(QWidget * widget,UAVObjectField * field,int index,float scale)
{
if(!widget || !field)
return false;
if(QComboBox * cb=qobject_cast<QComboBox *>(widget))
QVariant ret=getVariantFromWidget(widget,scale);
if(ret.isValid())
{
field->setValue(cb->currentText(),index);
field->setValue(ret,index);
return true;
}
else if(QLabel * cb=qobject_cast<QLabel *>(widget))
{
field->setValue(cb->text(),index);
return true;
}
else if(QDoubleSpinBox * cb=qobject_cast<QDoubleSpinBox *>(widget))
{
field->setValue(cb->value()* scale,index);
return true;
}
else if(QSpinBox * cb=qobject_cast<QSpinBox *>(widget))
{
field->setValue(cb->value()* (int)scale,index);
return true;
}
else if(QSlider * cb=qobject_cast<QSlider *>(widget))
{
field->setValue(cb->value()* (int)scale,index);
return true;
}
else if(QCheckBox * cb=qobject_cast<QCheckBox *>(widget))
{
field->setValue((cb->isChecked()?"TRUE":"FALSE"),index);
return true;
}
else
{
qDebug()<<__FUNCTION__<<"widget to uavobject relation not implemented"<<widget->metaObject()->className();
return false;
}
}
QVariant ConfigTaskWidget::getVariantFromWidget(QWidget * widget,float scale)
{
if(QComboBox * cb=qobject_cast<QComboBox *>(widget))
{
return (QString)cb->currentText();
}
else if(QLabel * cb=qobject_cast<QLabel *>(widget))
{
return (QString)cb->text();
}
else if(QDoubleSpinBox * cb=qobject_cast<QDoubleSpinBox *>(widget))
{
return (double)(cb->value()* scale);
}
else if(QSpinBox * cb=qobject_cast<QSpinBox *>(widget))
{
return (int)(cb->value()* (int)scale);
}
else if(QSlider * cb=qobject_cast<QSlider *>(widget))
{
return(int)(cb->value()* (int)scale);
}
else if(QCheckBox * cb=qobject_cast<QCheckBox *>(widget))
{
return (bool)(cb->isChecked()?"TRUE":"FALSE");
}
else
return QVariant();
}
bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, float scale)
{
if(QComboBox * cb=qobject_cast<QComboBox *>(widget))
{
cb->setCurrentIndex(cb->findText(value.toString()));
return true;
}
else if(QLabel * cb=qobject_cast<QLabel *>(widget))
{
cb->setText(value.toString());
return true;
}
else if(QDoubleSpinBox * cb=qobject_cast<QDoubleSpinBox *>(widget))
{
cb->setValue(value.toDouble()/scale);
return true;
}
else if(QSpinBox * cb=qobject_cast<QSpinBox *>(widget))
{
cb->setValue(value.toInt()/(int)scale);
return true;
}
else if(QSlider * cb=qobject_cast<QSlider *>(widget))
{
cb->setValue(value.toInt()/(int)scale);
return true;
}
else if(QCheckBox * cb=qobject_cast<QCheckBox *>(widget))
{
cb->setChecked(value.toBool());
return true;
}
else
return false;
}
bool ConfigTaskWidget::setWidgetFromField(QWidget * widget,UAVObjectField * field,int index,float scale)
{
@ -594,34 +707,11 @@ bool ConfigTaskWidget::setWidgetFromField(QWidget * widget,UAVObjectField * fiel
{
if(cb->count()==0)
cb->addItems(field->getOptions());
cb->setCurrentIndex(cb->findText(field->getValue(index).toString()));
return true;
}
else if(QLabel * cb=qobject_cast<QLabel *>(widget))
{
cb->setText(field->getValue(index).toString());
QVariant var=field->getValue(index);
bool ret=setWidgetFromVariant(widget,var,scale);
if(ret)
return true;
}
else if(QDoubleSpinBox * cb=qobject_cast<QDoubleSpinBox *>(widget))
{
cb->setValue(field->getValue(index).toDouble()/scale);
return true;
}
else if(QSpinBox * cb=qobject_cast<QSpinBox *>(widget))
{
cb->setValue(field->getValue(index).toInt()/(int)scale);
return true;
}
else if(QSlider * cb=qobject_cast<QSlider *>(widget))
{
cb->setValue(field->getValue(index).toInt()/(int)scale);
return true;
}
else if(QCheckBox * cb=qobject_cast<QCheckBox *>(widget))
{
cb->setChecked(field->getValue(index).toBool());
return true;
}
else
{
qDebug()<<__FUNCTION__<<"widget to uavobject relation not implemented"<<widget->metaObject()->className();

View File

@ -49,6 +49,12 @@ class ConfigTaskWidget: public QWidget
Q_OBJECT
public:
struct shadow
{
QWidget * widget;
float scale;
bool isLimited;
};
struct objectToWidget
{
UAVObject * object;
@ -57,15 +63,7 @@ public:
int index;
float scale;
bool isLimited;
QList<QWidget *> shadows;
};
struct shadows
{
QWidget * widget;
float scale;
bool isLimited;
QWidget * parent;
QList<shadow *> shadowsList;
};
enum buttonTypeEnum {none,save_button,apply_button,reload_button,default_button};
@ -83,30 +81,37 @@ public:
ConfigTaskWidget(QWidget *parent = 0);
~ConfigTaskWidget();
void saveObjectToSD(UAVObject *obj);
UAVObjectManager* getObjectManager();
static double listMean(QList<double> list);
void addUAVObject(QString objectName);
void addWidget(QWidget * widget);
void addUAVObjectToWidgetRelation(QString object,QString field,QWidget * widget,int index=0,float scale=1,bool isLimited=false,QList<int>* defaultReloadGroups=0);
void addUAVObjectToWidgetRelation(QString object,QString field,QWidget * widget,QString element,float scale,bool isLimited=false,QList<int>* defaultReloadGroups=0);
void addUAVObjectToWidgetRelation(QString object, QString field, QWidget *widget, QString index);
//BUTTONS//
void addApplySaveButtons(QPushButton * update,QPushButton * save);
void addReloadButton(QPushButton * button,int buttonGroup);
void addDefaultButton(QPushButton * button,int buttonGroup);
//////////
void addWidgetToDefaultReloadGroups(QWidget * widget, QList<int> *groups);
bool addShadowWidget(QWidget * masterWidget, QWidget * shadowWidget,float shadowScale=1,bool shadowIsLimited=false);
bool addShadowWidget(QString object,QString field,QWidget * widget,int index=0,float scale=1,bool isLimited=false);
bool addShadowWidget(QString object,QString field,QWidget * widget,int index=0,float scale=1,bool isLimited=false, QList<int> *defaultReloadGroups=NULL);
void autoLoadWidgets();
bool isDirty();
void setDirty(bool value);
void addUAVObjectToWidgetRelation(QString object, QString field, QWidget *widget, QString index);
bool allObjectsUpdated();
public slots:
void onAutopilotDisconnect();
void onAutopilotConnect();
@ -117,8 +122,6 @@ signals:
void objectAdded(UAVObject*);
void objectRemoved(UAVObject*);
private slots:
virtual void refreshValues();
virtual void updateObjectsFromWidgets();
void objectUpdated(UAVObject*);
void defaultButtonClicked();
void reloadButtonClicked();
@ -131,10 +134,12 @@ private:
smartSaveButton *smartsave;
QMap<UAVObject *,bool> objectUpdates;
QMap<int,QList<objectToWidget*> *> defaultReloadGroups;
QList <shadows*> shadowsList;
QMap<QWidget *,objectToWidget*> shadowsList;
bool dirty;
bool setFieldFromWidget(QWidget *widget, UAVObjectField *field, int index, float scale);
bool setWidgetFromField(QWidget *widget, UAVObjectField *field, int index, float scale);
QVariant getVariantFromWidget(QWidget *widget, float scale);
bool setWidgetFromVariant(QWidget *widget,QVariant value,float scale);
void connectWidgetUpdatesToSlot(QWidget *widget, const char *function);
protected slots:
virtual void disableObjUpdates();
@ -143,6 +148,7 @@ protected slots:
virtual void widgetsContentsChanged();
virtual void populateWidgets();
virtual void refreshWidgetsValues();
virtual void updateObjectsFromWidgets();
protected:
virtual void enableControls(bool enable);

View File

@ -29,7 +29,7 @@
#include <QtEndian>
#include <QDebug>
UAVObjectField::UAVObjectField(const QString& name, const QString& units, FieldType type, quint32 numElements, const QStringList& options)
UAVObjectField::UAVObjectField(const QString& name, const QString& units, FieldType type, quint32 numElements, const QStringList& options, const QString &limits)
{
QStringList elementNames;
// Set element names
@ -38,16 +38,16 @@ UAVObjectField::UAVObjectField(const QString& name, const QString& units, FieldT
elementNames.append(QString("%1").arg(n));
}
// Initialize
constructorInitialize(name, units, type, elementNames, options);
constructorInitialize(name, units, type, elementNames, options,limits);
}
UAVObjectField::UAVObjectField(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options)
UAVObjectField::UAVObjectField(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options, const QString &limits)
{
constructorInitialize(name, units, type, elementNames, options);
constructorInitialize(name, units, type, elementNames, options,limits);
}
void UAVObjectField::constructorInitialize(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options)
void UAVObjectField::constructorInitialize(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options,QString &limits)
{
// Copy params
this->name = name;
@ -94,6 +94,43 @@ void UAVObjectField::constructorInitialize(const QString& name, const QString& u
}
}
void UAVObjectField::limitsInitialize(QString &limits)
{
/// format
/// (TY)->type (EQ-equal;NE-not equal;BE-between;BI-bigger;SM-smaller)
/// (VALX)->value
/// %TY:VAL1:VAL2:VAL3,%TY,VAL1,VAL2,VAL3
/// example: first element bigger than 3 and second element inside [2.3,5]
/// "%0BI:3,%1BE:2.3:5"
QStringList stringPerElement=limits.split(",");
foreach (QString str, stringPerElement) {
QStringList valuesPerElement=str.split(":");
LimitStruct lstruc;
quint32 index=valuesPerElement.at(0).mid(1,valuesPerElement.at(0).length()-3).toULong();
if(valuesPerElement.at(0).startsWith("%") && index<numElements)
{
if(valuesPerElement.at(0).right(2)=="EQ")
lstruc.type=EQUAL;
else if(valuesPerElement.at(0).right(2)=="NE")
lstruc.type=NOT_EQUAL;
else if(valuesPerElement.at(0).right(2)=="BE")
lstruc.type=BETWEEN;
else if(valuesPerElement.at(0).right(2)=="BI")
lstruc.type=BIGGER;
else if(valuesPerElement.at(0).right(2)=="SM")
lstruc.type=SMALLER;
else
qDebug()<<"limits parsing failed on UAVObjectField"<<name;
valuesPerElement.removeAt(0);
foreach(QString value,valuesPerElement)
{
lstruc.values.append(value);
}
elementLimits.insert(index,lstruc);
}
}
}
void UAVObjectField::initialize(quint8* data, quint32 dataOffset, UAVObject* obj)
{
this->data = data;

View File

@ -32,6 +32,8 @@
#include "uavobject.h"
#include <QStringList>
#include <QVariant>
#include <QList>
#include <QMap>
class UAVObject;
@ -41,9 +43,15 @@ class UAVOBJECTS_EXPORT UAVObjectField: public QObject
public:
typedef enum { INT8 = 0, INT16, INT32, UINT8, UINT16, UINT32, FLOAT32, ENUM, STRING } FieldType;
typedef enum { EQUAL,NOT_EQUAL,BETWEEN,BIGGER,SMALLER } LimitType;
typedef struct
{
LimitType type;
QList<QVariant> values;
} LimitStruct;
UAVObjectField(const QString& name, const QString& units, FieldType type, quint32 numElements, const QStringList& options);
UAVObjectField(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options);
UAVObjectField(const QString& name, const QString& units, FieldType type, quint32 numElements, const QStringList& options,const QString& limits=QString::QString());
UAVObjectField(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options,const QString& limits=QString::QString());
void initialize(quint8* data, quint32 dataOffset, UAVObject* obj);
UAVObject* getObject();
FieldType getType();
@ -81,9 +89,10 @@ protected:
quint32 offset;
quint8* data;
UAVObject* obj;
QMap<quint32,LimitStruct> elementLimits;
void clear();
void constructorInitialize(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options);
void constructorInitialize(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options, QString &limits);
void limitsInitialize(QString &limits);
};

View File

@ -131,19 +131,21 @@ bool UAVObjectGeneratorGCS::process_object(ObjectInfo* info)
.arg(varOptionName)
.arg(options[m]) );
}
finit.append( QString(" fields.append( new UAVObjectField(QString(\"%1\"), QString(\"%2\"), UAVObjectField::ENUM, %3, %4) );\n")
finit.append( QString(" fields.append( new UAVObjectField(QString(\"%1\"), QString(\"%2\"), UAVObjectField::ENUM, %3, %4, QString(\"%5\")));\n")
.arg(info->fields[n]->name)
.arg(info->fields[n]->units)
.arg(varElemName)
.arg(varOptionName) );
.arg(varOptionName)
.arg(info->fields[n]->limitValues));
}
// For all other types
else {
finit.append( QString(" fields.append( new UAVObjectField(QString(\"%1\"), QString(\"%2\"), UAVObjectField::%3, %4, QStringList()) );\n")
finit.append( QString(" fields.append( new UAVObjectField(QString(\"%1\"), QString(\"%2\"), UAVObjectField::%3, %4, QStringList(), QString(\"%5\")));\n")
.arg(info->fields[n]->name)
.arg(info->fields[n]->units)
.arg(fieldTypeStrCPPClass[info->fields[n]->type])
.arg(varElemName) );
.arg(varElemName)
.arg(info->fields[n]->limitValues));
}
}
outCode.replace(QString("$(FIELDSINIT)"), finit);

View File

@ -469,6 +469,13 @@ QString UAVObjectParser::processObjectFields(QDomNode& childNode, ObjectInfo* in
}
field->defaultValues = defaults;
}
elemAttr = elemAttributes.namedItem("limits");
if ( elemAttr.isNull() ) {
field->limitValues=QString();
}
else{
field->limitValues=elemAttr.nodeValue();
}
// Add field to object
info->fields.append(field);
// Done

View File

@ -52,11 +52,12 @@ typedef struct {
QString units;
FieldType type;
int numElements;
int numBytes;
int numBytes;
QStringList elementNames;
QStringList options; // for enums only
bool defaultElementNames;
QStringList defaultValues;
QString limitValues;
} FieldInfo;
/**
@ -69,13 +70,13 @@ typedef enum {
UPDATEMODE_NEVER /** Object is never updated */
} UpdateMode;
typedef enum {
ACCESS_READWRITE = 0,
ACCESS_READONLY = 1
} AccessMode;
typedef struct {
QString name;
QString namelc; /** name in lowercase */
@ -110,8 +111,8 @@ public:
quint32 getObjectID(int objIndex);
ObjectInfo* getObjectByIndex(int objIndex);
int getNumBytes(int objIndex);
QStringList all_units;
int getNumBytes(int objIndex);
QStringList all_units;
private:
QList<ObjectInfo*> objInfo;