1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00

Preparatory commit before moving framework to a better location.

This commit is contained in:
zedamota 2012-02-05 14:41:23 +00:00
parent 427acee559
commit 32ebdb63a3
6 changed files with 837 additions and 406 deletions

View File

@ -43,12 +43,12 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa
QList<int> * rateGroup=new QList<int>(); QList<int> * rateGroup=new QList<int>();
rateGroup->append(0); rateGroup->append(0);
addApplySaveButtons(m_stabilization->saveStabilizationToRAM,m_stabilization->saveStabilizationToSD); addApplySaveButtons(m_stabilization->saveStabilizationToRAM,m_stabilization->saveStabilizationToSD);
addUAVObjectToWidgetRelation("StabilizationSettings","RollRatePID",m_stabilization->rateRollKp,"Kp",1,false,rateGroup); addUAVObjectToWidgetRelation("StabilizationSettings","RollRatePID",m_stabilization->rateRollKp,"Kp",1,true,rateGroup);
addDefaultButton(m_stabilization->defaultButton,0); addDefaultButton(m_stabilization->defaultButton,0);
addReloadButton(m_stabilization->reloadButton,0); addReloadButton(m_stabilization->reloadButton,0);
addWidgetToDefaultReloadGroups(m_stabilization->rateRollKp,rateGroup); addWidgetToDefaultReloadGroups(m_stabilization->rateRollKp,rateGroup);
addShadowWidget("StabilizationSettings","RollRatePID",m_stabilization->rateRollKi,0,1,false,rateGroup); addShadowWidget("StabilizationSettings","RollRatePID",m_stabilization->rateRollKi,0,1,true,rateGroup);
} }

View File

@ -29,7 +29,7 @@
#include "uavsettingsimportexport/uavsettingsimportexportfactory.h" #include "uavsettingsimportexport/uavsettingsimportexportfactory.h"
#include "configgadgetwidget.h" #include "configgadgetwidget.h"
ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent),isConnected(false),smartsave(NULL),dirty(false) ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent),isConnected(false),smartsave(NULL),dirty(false),outOfLimitsStyle("background-color: rgb(255, 0, 0);")
{ {
pm = ExtensionSystem::PluginManager::instance(); pm = ExtensionSystem::PluginManager::instance();
objManager = pm->getObject<UAVObjectManager>(); objManager = pm->getObject<UAVObjectManager>();
@ -89,6 +89,7 @@ void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString fiel
ow->widget=widget; ow->widget=widget;
ow->index=index; ow->index=index;
ow->scale=scale; ow->scale=scale;
ow->isLimited=isLimited;
objOfInterest.append(ow); objOfInterest.append(ow);
if(obj) if(obj)
{ {
@ -105,9 +106,10 @@ void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString fiel
else else
{ {
connectWidgetUpdatesToSlot(widget,SLOT(widgetsContentsChanged())); connectWidgetUpdatesToSlot(widget,SLOT(widgetsContentsChanged()));
if(defaultReloadGroups) if(defaultReloadGroups)
addWidgetToDefaultReloadGroups(widget,defaultReloadGroups); addWidgetToDefaultReloadGroups(widget,defaultReloadGroups);
shadowsList.insert(widget,ow); shadowsList.insert(widget,ow);
loadWidgetLimits(widget,_field,index,isLimited,scale);
} }
} }
@ -181,8 +183,8 @@ void ConfigTaskWidget::populateWidgets()
{ {
// do nothing // do nothing
} }
else else
setWidgetFromField(ow->widget,ow->field,ow->index,ow->scale); setWidgetFromField(ow->widget,ow->field,ow->index,ow->scale,ow->isLimited);
} }
setDirty(dirtyBack); setDirty(dirtyBack);
} }
@ -198,7 +200,7 @@ void ConfigTaskWidget::refreshWidgetsValues()
} }
else else
{ {
setWidgetFromField(ow->widget,ow->field,ow->index,ow->scale); setWidgetFromField(ow->widget,ow->field,ow->index,ow->scale,ow->isLimited);
} }
} }
@ -246,17 +248,21 @@ void ConfigTaskWidget::enableControls(bool enable)
void ConfigTaskWidget::widgetsContentsChanged() void ConfigTaskWidget::widgetsContentsChanged()
{ {
float scale; float scale;
objectToWidget * oTw= shadowsList.value((QWidget*)sender(),NULL);
/*
qDebug()<<"sender:"<<(quint32)sender(); qDebug()<<"sender:"<<(quint32)sender();
foreach(QWidget * w,shadowsList.keys()) foreach(QWidget * w,shadowsList.keys())
qDebug()<<"in list:"<<(quint32)w; qDebug()<<"in list:"<<(quint32)w;
objectToWidget * oTw= shadowsList.value((QWidget*)sender(),NULL);
if(oTw) if(oTw)
qDebug()<<"in oTw OK"<<(quint32)oTw->widget; qDebug()<<"in oTw OK"<<(quint32)oTw->widget;
*/
if(oTw) if(oTw)
{ {
if(oTw->widget==(QWidget*)sender()) if(oTw->widget==(QWidget*)sender())
{ {
scale=oTw->scale; scale=oTw->scale;
checkWidgetsLimits((QWidget*)sender(),oTw->field,oTw->index,oTw->isLimited,getVariantFromWidget((QWidget*)sender(),oTw->scale),oTw->scale);
qDebug()<<"sender was master"; qDebug()<<"sender was master";
} }
else else
@ -266,16 +272,23 @@ void ConfigTaskWidget::widgetsContentsChanged()
if(sh->widget==(QWidget*)sender()) if(sh->widget==(QWidget*)sender())
{ {
scale=sh->scale; scale=sh->scale;
checkWidgetsLimits((QWidget*)sender(),oTw->field,oTw->index,sh->isLimited,getVariantFromWidget((QWidget*)sender(),scale),scale);
qDebug()<<"sender was shadow"; qDebug()<<"sender was shadow";
} }
} }
} }
if(oTw->widget!=(QWidget *)sender()) if(oTw->widget!=(QWidget *)sender())
{
checkWidgetsLimits(oTw->widget,oTw->field,oTw->index,oTw->isLimited,getVariantFromWidget((QWidget*)sender(),scale),oTw->scale);
setWidgetFromVariant(oTw->widget,getVariantFromWidget((QWidget*)sender(),scale),oTw->scale); setWidgetFromVariant(oTw->widget,getVariantFromWidget((QWidget*)sender(),scale),oTw->scale);
}
foreach (shadow * sh, oTw->shadowsList) foreach (shadow * sh, oTw->shadowsList)
{ {
if(sh->widget!=(QWidget*)sender()) if(sh->widget!=(QWidget*)sender())
{
checkWidgetsLimits(sh->widget,oTw->field,oTw->index,sh->isLimited,getVariantFromWidget((QWidget*)sender(),scale),oTw->scale);
setWidgetFromVariant(sh->widget,getVariantFromWidget((QWidget*)sender(),scale),sh->scale); setWidgetFromVariant(sh->widget,getVariantFromWidget((QWidget*)sender(),scale),sh->scale);
}
} }
} }
setDirty(true); setDirty(true);
@ -540,7 +553,7 @@ void ConfigTaskWidget::defaultButtonClicked()
if(!oTw->object) if(!oTw->object)
continue; continue;
UAVDataObject * temp=((UAVDataObject*)oTw->object)->dirtyClone(); UAVDataObject * temp=((UAVDataObject*)oTw->object)->dirtyClone();
setWidgetFromField(oTw->widget,temp->getField(oTw->field->getName()),oTw->index,oTw->scale); setWidgetFromField(oTw->widget,temp->getField(oTw->field->getName()),oTw->index,oTw->scale,oTw->isLimited);
} }
} }
@ -568,7 +581,7 @@ void ConfigTaskWidget::reloadButtonClicked()
eventLoop->exec(); eventLoop->exec();
if(timeOut->isActive()) if(timeOut->isActive())
{ {
setWidgetFromField(oTw->widget,oTw->field,oTw->index,oTw->scale); setWidgetFromField(oTw->widget,oTw->field,oTw->index,oTw->scale,oTw->isLimited);
} }
timeOut->stop(); timeOut->stop();
} }
@ -614,7 +627,7 @@ void ConfigTaskWidget::connectWidgetUpdatesToSlot(QWidget * widget,const char* f
connect(cb,SIGNAL(clicked()),this,function); connect(cb,SIGNAL(clicked()),this,function);
} }
else else
qDebug()<<__FUNCTION__<<"widget to uavobject relation not implemented"<<widget->metaObject()->className(); qDebug()<<__FUNCTION__<<"widget to uavobject relation not implemented"<<widget->metaObject()->className();
} }
@ -667,8 +680,8 @@ bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, flo
{ {
if(QComboBox * cb=qobject_cast<QComboBox *>(widget)) if(QComboBox * cb=qobject_cast<QComboBox *>(widget))
{ {
cb->setCurrentIndex(cb->findText(value.toString())); cb->setCurrentIndex(cb->findText(value.toString()));
return true; return true;
} }
else if(QLabel * cb=qobject_cast<QLabel *>(widget)) else if(QLabel * cb=qobject_cast<QLabel *>(widget))
{ {
@ -699,16 +712,17 @@ bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, flo
return false; return false;
} }
bool ConfigTaskWidget::setWidgetFromField(QWidget * widget,UAVObjectField * field,int index,float scale) bool ConfigTaskWidget::setWidgetFromField(QWidget * widget,UAVObjectField * field,int index,float scale,bool hasLimits)
{ {
if(!widget || !field) if(!widget || !field)
return false; return false;
if(QComboBox * cb=qobject_cast<QComboBox *>(widget)) if(QComboBox * cb=qobject_cast<QComboBox *>(widget))
{ {
if(cb->count()==0) if(cb->count()==0)
cb->addItems(field->getOptions()); loadWidgetLimits(cb,field,index,hasLimits,scale);
} }
QVariant var=field->getValue(index); QVariant var=field->getValue(index);
checkWidgetsLimits(widget,field,index,hasLimits,var,scale);
bool ret=setWidgetFromVariant(widget,var,scale); bool ret=setWidgetFromVariant(widget,var,scale);
if(ret) if(ret)
return true; return true;
@ -718,6 +732,129 @@ bool ConfigTaskWidget::setWidgetFromField(QWidget * widget,UAVObjectField * fiel
return false; return false;
} }
} }
void ConfigTaskWidget::checkWidgetsLimits(QWidget * widget,UAVObjectField * field,int index,bool hasLimits, QVariant value, float scale)
{
if(!hasLimits)
return;
qDebug()<<"check widget"<<widget->accessibleName()<<"value"<<value.toString()<<"result"<<field->isWithinLimits(value,index);
if(!field->isWithinLimits(value,index))
{
if(!widget->property("styleBackup").isValid())
widget->setProperty("styleBackup",widget->styleSheet());
widget->setStyleSheet(outOfLimitsStyle);
widget->setProperty("wasOverLimits",(bool)true);
if(QComboBox * cb=qobject_cast<QComboBox *>(widget))
{
if(cb->findText(value.toString())==-1)
cb->addItem(value.toString());
}
else if(QDoubleSpinBox * cb=qobject_cast<QDoubleSpinBox *>(widget))
{
if(value.toDouble()/scale>cb->maximum())
{
cb->setMaximum(value.toDouble()/scale);
}
else if(value.toDouble()/scale<cb->minimum())
{
cb->setMinimum(value.toDouble()/scale);
}
}
else if(QSpinBox * cb=qobject_cast<QSpinBox *>(widget))
{
if(value.toInt()/scale>cb->maximum())
{
cb->setMaximum(value.toInt()/scale);
}
else if(value.toInt()/scale<cb->minimum())
{
cb->setMinimum(value.toInt()/scale);
}
}
else if(QSlider * cb=qobject_cast<QSlider *>(widget))
{
if(value.toInt()/scale>cb->maximum())
{
cb->setMaximum(value.toInt()/scale);
}
else if(value.toInt()/scale<cb->minimum())
{
cb->setMinimum(value.toInt()/scale);
}
}
}
else if(widget->property("wasOverLimits").isValid())
{
qDebug()<<"1wasOverLimits";
if(widget->property("wasOverLimits").toBool())
{
qDebug()<<"2";
widget->setProperty("wasOverLimits",(bool)false);
if(widget->property("styleBackup").isValid())
{
qDebug()<<"3";
QString style=widget->property("styleBackup").toString();
qDebug()<<"STYLE"<<style;
widget->setStyleSheet(style);
}
loadWidgetLimits(widget,field,index,hasLimits,scale);
}
}
}
void ConfigTaskWidget::loadWidgetLimits(QWidget * widget,UAVObjectField * field,int index,bool hasLimits,float scale)
{
if(QComboBox * cb=qobject_cast<QComboBox *>(widget))
{
cb->clear();
QStringList option=field->getOptions();
if(hasLimits)
{
foreach(QString str,option)
{
if(field->isWithinLimits(str,index))
cb->addItem(str);
}
}
else
cb->addItems(option);
}
if(!hasLimits)
return;
else if(QDoubleSpinBox * cb=qobject_cast<QDoubleSpinBox *>(widget))
{
if(field->getMaxLimit(index).isValid())
{
cb->setMaximum(field->getMaxLimit(index).toDouble()/scale);
}
if(field->getMinLimit(index).isValid())
{
cb->setMinimum(field->getMinLimit(index).toDouble()/scale);
}
}
else if(QSpinBox * cb=qobject_cast<QSpinBox *>(widget))
{
if(field->getMaxLimit(index).isValid())
{
cb->setMaximum((int)(field->getMaxLimit(index).toInt()/scale));
}
if(field->getMinLimit(index).isValid())
{
cb->setMinimum((int)(field->getMinLimit(index).toInt()/scale));
}
}
else if(QSlider * cb=qobject_cast<QSlider *>(widget))
{
if(field->getMaxLimit(index).isValid())
{
cb->setMaximum((int)(field->getMaxLimit(index).toInt()/scale));
}
if(field->getMinLimit(index).isValid())
{
cb->setMinimum((int)(field->getMinLimit(index).toInt()/scale));
}
}
}
/** /**
@} @}

View File

@ -111,7 +111,6 @@ void addUAVObjectToWidgetRelation(QString object, QString field, QWidget *widget
bool allObjectsUpdated(); bool allObjectsUpdated();
public slots: public slots:
void onAutopilotDisconnect(); void onAutopilotDisconnect();
void onAutopilotConnect(); void onAutopilotConnect();
@ -137,10 +136,12 @@ private:
QMap<QWidget *,objectToWidget*> shadowsList; QMap<QWidget *,objectToWidget*> shadowsList;
bool dirty; bool dirty;
bool setFieldFromWidget(QWidget *widget, UAVObjectField *field, int index, float scale); bool setFieldFromWidget(QWidget *widget, UAVObjectField *field, int index, float scale);
bool setWidgetFromField(QWidget *widget, UAVObjectField *field, int index, float scale); bool setWidgetFromField(QWidget *widget, UAVObjectField *field, int index, float scale, bool hasLimits);
QVariant getVariantFromWidget(QWidget *widget, float scale); QVariant getVariantFromWidget(QWidget *widget, float scale);
bool setWidgetFromVariant(QWidget *widget,QVariant value,float scale); bool setWidgetFromVariant(QWidget *widget,QVariant value,float scale);
void connectWidgetUpdatesToSlot(QWidget *widget, const char *function); void connectWidgetUpdatesToSlot(QWidget *widget, const char *function);
void loadWidgetLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, float sclale);
QString outOfLimitsStyle;
protected slots: protected slots:
virtual void disableObjUpdates(); virtual void disableObjUpdates();
virtual void enableObjUpdates(); virtual void enableObjUpdates();
@ -151,7 +152,7 @@ protected slots:
virtual void updateObjectsFromWidgets(); virtual void updateObjectsFromWidgets();
protected: protected:
virtual void enableControls(bool enable); virtual void enableControls(bool enable);
void checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, float scale);
}; };
#endif // CONFIGTASKWIDGET_H #endif // CONFIGTASKWIDGET_H

View File

@ -111,6 +111,12 @@
<string>Slowly raise Kp until you start seeing clear oscillations when you fly. <string>Slowly raise Kp until you start seeing clear oscillations when you fly.
Then lower the value by 20% or so.</string> Then lower the value by 20% or so.</string>
</property> </property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>

View File

@ -11,18 +11,18 @@
* @brief The UAVUObjects GCS plugin * @brief The UAVUObjects GCS plugin
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "uavobjectfield.h" #include "uavobjectfield.h"
@ -47,7 +47,7 @@ UAVObjectField::UAVObjectField(const QString& name, const QString& units, FieldT
constructorInitialize(name, units, type, elementNames, options,limits); constructorInitialize(name, units, type, elementNames, options,limits);
} }
void UAVObjectField::constructorInitialize(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options,QString &limits) void UAVObjectField::constructorInitialize(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options,const QString &limits)
{ {
// Copy params // Copy params
this->name = name; this->name = name;
@ -62,39 +62,40 @@ void UAVObjectField::constructorInitialize(const QString& name, const QString& u
// Set field size // Set field size
switch (type) switch (type)
{ {
case INT8: case INT8:
numBytesPerElement = sizeof(qint8); numBytesPerElement = sizeof(qint8);
break; break;
case INT16: case INT16:
numBytesPerElement = sizeof(qint16); numBytesPerElement = sizeof(qint16);
break; break;
case INT32: case INT32:
numBytesPerElement = sizeof(qint32); numBytesPerElement = sizeof(qint32);
break; break;
case UINT8: case UINT8:
numBytesPerElement = sizeof(quint8); numBytesPerElement = sizeof(quint8);
break; break;
case UINT16: case UINT16:
numBytesPerElement = sizeof(quint16); numBytesPerElement = sizeof(quint16);
break; break;
case UINT32: case UINT32:
numBytesPerElement = sizeof(quint32); numBytesPerElement = sizeof(quint32);
break; break;
case FLOAT32: case FLOAT32:
numBytesPerElement = sizeof(quint32); numBytesPerElement = sizeof(quint32);
break; break;
case ENUM: case ENUM:
numBytesPerElement = sizeof(quint8); numBytesPerElement = sizeof(quint8);
break; break;
case STRING: case STRING:
numBytesPerElement = sizeof(quint8); numBytesPerElement = sizeof(quint8);
break; break;
default: default:
numBytesPerElement = 0; numBytesPerElement = 0;
} }
limitsInitialize(limits);
} }
void UAVObjectField::limitsInitialize(QString &limits) void UAVObjectField::limitsInitialize(const QString &limits)
{ {
/// format /// format
/// (TY)->type (EQ-equal;NE-not equal;BE-between;BI-bigger;SM-smaller) /// (TY)->type (EQ-equal;NE-not equal;BE-between;BI-bigger;SM-smaller)
@ -102,6 +103,8 @@ void UAVObjectField::limitsInitialize(QString &limits)
/// %TY:VAL1:VAL2:VAL3,%TY,VAL1,VAL2,VAL3 /// %TY:VAL1:VAL2:VAL3,%TY,VAL1,VAL2,VAL3
/// example: first element bigger than 3 and second element inside [2.3,5] /// example: first element bigger than 3 and second element inside [2.3,5]
/// "%0BI:3,%1BE:2.3:5" /// "%0BI:3,%1BE:2.3:5"
if(limits.isEmpty())
return;
QStringList stringPerElement=limits.split(","); QStringList stringPerElement=limits.split(",");
foreach (QString str, stringPerElement) { foreach (QString str, stringPerElement) {
QStringList valuesPerElement=str.split(":"); QStringList valuesPerElement=str.split(":");
@ -124,13 +127,293 @@ void UAVObjectField::limitsInitialize(QString &limits)
valuesPerElement.removeAt(0); valuesPerElement.removeAt(0);
foreach(QString value,valuesPerElement) foreach(QString value,valuesPerElement)
{ {
lstruc.values.append(value); switch (type)
{
case INT8:
case INT16:
case INT32:
case UINT8:
lstruc.values.append((quint32)value.toULong());
break;
case UINT16:
case UINT32:
lstruc.values.append((qint32)value.toLong());
break;
case FLOAT32:
lstruc.values.append((float)value.toFloat());
break;
case ENUM:
lstruc.values.append((QString)value);
break;
case STRING:
lstruc.values.append((QString)value);
break;
default:
lstruc.values.append(QVariant());
}
} }
elementLimits.insert(index,lstruc); elementLimits.insert(index,lstruc);
} }
else
qDebug()<<"limits parsing failed on UAVObjectField"<<name;
} }
} }
bool UAVObjectField::isWithinLimits(QVariant var,quint32 index)
{
if(!elementLimits.keys().contains(index))
return true;
LimitStruct struc=elementLimits.value(index);
switch(struc.type)
{
case EQUAL:
switch (type)
{
case INT8:
case INT16:
case INT32:
foreach (QVariant vars, struc.values) {
if(var.toInt()==vars.toInt())
return true;
}
return false;
break;
case UINT8:
case UINT16:
case UINT32:
foreach (QVariant vars, struc.values) {
if(var.toUInt()==vars.toUInt())
return true;
}
return false;
break;
case ENUM:
case STRING:
foreach (QVariant vars, struc.values) {
if(var.toString()==vars.toString())
return true;
}
return false;
break;
case FLOAT32:
foreach (QVariant vars, struc.values) {
if(var.toFloat()==vars.toFloat())
return true;
}
return false;
break;
default:
return true;
}
break;
case NOT_EQUAL:
switch (type)
{
case INT8:
case INT16:
case INT32:
foreach (QVariant vars, struc.values) {
if(var.toInt()==vars.toInt())
return false;
}
return true;
break;
case UINT8:
case UINT16:
case UINT32:
foreach (QVariant vars, struc.values) {
if(var.toUInt()==vars.toUInt())
return false;
}
return true;
break;
case ENUM:
case STRING:
foreach (QVariant vars, struc.values) {
if(var.toString()==vars.toString())
return false;
}
return true;
break;
case FLOAT32:
foreach (QVariant vars, struc.values) {
if(var.toFloat()==vars.toFloat())
return false;
}
return true;
break;
default:
return true;
}
break;
case BETWEEN:
if(struc.values.length()<2)
{
qDebug()<<__FUNCTION__<<"between limit with less than 1 pair, aborting; field:"<<name;
return true;
}
if(struc.values.length()>2)
qDebug()<<__FUNCTION__<<"between limit with more than 1 pair, using first; field"<<name;
switch (type)
{
case INT8:
case INT16:
case INT32:
if(!(var.toInt()>=struc.values.at(0).toInt() && var.toInt()<=struc.values.at(1).toInt()))
return false;
return true;
break;
case UINT8:
case UINT16:
case UINT32:
if(!(var.toUInt()>=struc.values.at(0).toUInt() && var.toUInt()<=struc.values.at(1).toUInt()))
return false;
return true;
break;
case ENUM:
if(!(options.indexOf(var.toString())>=options.indexOf(struc.values.at(0).toString()) && options.indexOf(var.toString())<=options.indexOf(struc.values.at(1).toString())))
return false;
return true;
break;
case STRING:
return true;
break;
case FLOAT32:
if(!(var.toFloat()>=struc.values.at(0).toFloat() && var.toFloat()<=struc.values.at(1).toFloat()))
return false;
return true;
break;
default:
return true;
}
break;
case BIGGER:
if(struc.values.length()<1)
{
qDebug()<<__FUNCTION__<<"BIGGER limit with less than 1 value, aborting; field:"<<name;
return true;
}
if(struc.values.length()>1)
qDebug()<<__FUNCTION__<<"BIGGER limit with more than 1 value, using first; field"<<name;
switch (type)
{
case INT8:
case INT16:
case INT32:
if(!(var.toInt()>=struc.values.at(0).toInt()))
return false;
return true;
break;
case UINT8:
case UINT16:
case UINT32:
if(!(var.toUInt()>=struc.values.at(0).toUInt()))
return false;
return true;
break;
case ENUM:
if(!(options.indexOf(var.toString())>=options.indexOf(struc.values.at(0).toString())))
return false;
return true;
break;
case STRING:
return true;
break;
case FLOAT32:
if(!(var.toFloat()>=struc.values.at(0).toFloat()))
return false;
return true;
break;
default:
return true;
}
break;
case SMALLER:
switch (type)
{
case INT8:
case INT16:
case INT32:
if(!(var.toInt()<=struc.values.at(0).toInt()))
return false;
return true;
break;
case UINT8:
case UINT16:
case UINT32:
if(!(var.toUInt()<=struc.values.at(0).toUInt()))
return false;
return true;
break;
case ENUM:
if(!(options.indexOf(var.toString())<=options.indexOf(struc.values.at(0).toString())))
return false;
return true;
break;
case STRING:
return true;
break;
case FLOAT32:
if(!(var.toFloat()<=struc.values.at(0).toFloat()))
return false;
return true;
break;
default:
return true;
}
}
return true;
}
QVariant UAVObjectField::getMaxLimit(quint32 index)
{
if(!elementLimits.keys().contains(index))
return QVariant();
LimitStruct struc=elementLimits.value(index);
switch(struc.type)
{
case EQUAL:
case NOT_EQUAL:
case BIGGER:
return QVariant();
break;
break;
case BETWEEN:
return struc.values.at(1);
break;
case SMALLER:
return struc.values.at(0);
break;
default:
return QVariant();
break;
}
return QVariant();
}
QVariant UAVObjectField::getMinLimit(quint32 index)
{
if(!elementLimits.keys().contains(index))
return QVariant();
LimitStruct struc=elementLimits.value(index);
switch(struc.type)
{
case EQUAL:
case NOT_EQUAL:
case SMALLER:
return QVariant();
break;
break;
case BETWEEN:
return struc.values.at(0);
break;
case BIGGER:
return struc.values.at(0);
break;
default:
return QVariant();
break;
}
return QVariant();
}
void UAVObjectField::initialize(quint8* data, quint32 dataOffset, UAVObject* obj) void UAVObjectField::initialize(quint8* data, quint32 dataOffset, UAVObject* obj)
{ {
this->data = data; this->data = data;
@ -148,26 +431,26 @@ QString UAVObjectField::getTypeAsString()
{ {
switch (type) switch (type)
{ {
case UAVObjectField::INT8: case UAVObjectField::INT8:
return "int8"; return "int8";
case UAVObjectField::INT16: case UAVObjectField::INT16:
return "int16"; return "int16";
case UAVObjectField::INT32: case UAVObjectField::INT32:
return "int32"; return "int32";
case UAVObjectField::UINT8: case UAVObjectField::UINT8:
return "uint8"; return "uint8";
case UAVObjectField::UINT16: case UAVObjectField::UINT16:
return "uint16"; return "uint16";
case UAVObjectField::UINT32: case UAVObjectField::UINT32:
return "uint32"; return "uint32";
case UAVObjectField::FLOAT32: case UAVObjectField::FLOAT32:
return "float32"; return "float32";
case UAVObjectField::ENUM: case UAVObjectField::ENUM:
return "enum"; return "enum";
case UAVObjectField::STRING: case UAVObjectField::STRING:
return "string"; return "string";
default: default:
return ""; return "";
} }
} }
@ -236,64 +519,64 @@ qint32 UAVObjectField::pack(quint8* dataOut)
// Pack each element in output buffer // Pack each element in output buffer
switch (type) switch (type)
{ {
case INT8: case INT8:
memcpy(dataOut, &data[offset], numElements); memcpy(dataOut, &data[offset], numElements);
break; break;
case INT16: case INT16:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
qint16 value; qint16 value;
memcpy(&value, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&value, &data[offset + numBytesPerElement*index], numBytesPerElement);
qToLittleEndian<qint16>(value, &dataOut[numBytesPerElement*index]); qToLittleEndian<qint16>(value, &dataOut[numBytesPerElement*index]);
} }
break; break;
case INT32: case INT32:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
qint32 value; qint32 value;
memcpy(&value, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&value, &data[offset + numBytesPerElement*index], numBytesPerElement);
qToLittleEndian<qint32>(value, &dataOut[numBytesPerElement*index]); qToLittleEndian<qint32>(value, &dataOut[numBytesPerElement*index]);
} }
break; break;
case UINT8: case UINT8:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
dataOut[numBytesPerElement*index] = data[offset + numBytesPerElement*index]; dataOut[numBytesPerElement*index] = data[offset + numBytesPerElement*index];
} }
break; break;
case UINT16: case UINT16:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
quint16 value; quint16 value;
memcpy(&value, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&value, &data[offset + numBytesPerElement*index], numBytesPerElement);
qToLittleEndian<quint16>(value, &dataOut[numBytesPerElement*index]); qToLittleEndian<quint16>(value, &dataOut[numBytesPerElement*index]);
} }
break; break;
case UINT32: case UINT32:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
quint32 value; quint32 value;
memcpy(&value, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&value, &data[offset + numBytesPerElement*index], numBytesPerElement);
qToLittleEndian<quint32>(value, &dataOut[numBytesPerElement*index]); qToLittleEndian<quint32>(value, &dataOut[numBytesPerElement*index]);
} }
break; break;
case FLOAT32: case FLOAT32:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
quint32 value; quint32 value;
memcpy(&value, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&value, &data[offset + numBytesPerElement*index], numBytesPerElement);
qToLittleEndian<quint32>(value, &dataOut[numBytesPerElement*index]); qToLittleEndian<quint32>(value, &dataOut[numBytesPerElement*index]);
} }
break; break;
case ENUM: case ENUM:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
dataOut[numBytesPerElement*index] = data[offset + numBytesPerElement*index]; dataOut[numBytesPerElement*index] = data[offset + numBytesPerElement*index];
} }
break; break;
case STRING: case STRING:
memcpy(dataOut, &data[offset], numElements); memcpy(dataOut, &data[offset], numElements);
break; break;
} }
// Done // Done
return getNumBytes(); return getNumBytes();
@ -305,64 +588,64 @@ qint32 UAVObjectField::unpack(const quint8* dataIn)
// Unpack each element from input buffer // Unpack each element from input buffer
switch (type) switch (type)
{ {
case INT8: case INT8:
memcpy(&data[offset], dataIn, numElements); memcpy(&data[offset], dataIn, numElements);
break; break;
case INT16: case INT16:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
qint16 value; qint16 value;
value = qFromLittleEndian<qint16>(&dataIn[numBytesPerElement*index]); value = qFromLittleEndian<qint16>(&dataIn[numBytesPerElement*index]);
memcpy(&data[offset + numBytesPerElement*index], &value, numBytesPerElement); memcpy(&data[offset + numBytesPerElement*index], &value, numBytesPerElement);
} }
break; break;
case INT32: case INT32:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
qint32 value; qint32 value;
value = qFromLittleEndian<qint32>(&dataIn[numBytesPerElement*index]); value = qFromLittleEndian<qint32>(&dataIn[numBytesPerElement*index]);
memcpy(&data[offset + numBytesPerElement*index], &value, numBytesPerElement); memcpy(&data[offset + numBytesPerElement*index], &value, numBytesPerElement);
} }
break; break;
case UINT8: case UINT8:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
data[offset + numBytesPerElement*index] = dataIn[numBytesPerElement*index]; data[offset + numBytesPerElement*index] = dataIn[numBytesPerElement*index];
} }
break; break;
case UINT16: case UINT16:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
quint16 value; quint16 value;
value = qFromLittleEndian<quint16>(&dataIn[numBytesPerElement*index]); value = qFromLittleEndian<quint16>(&dataIn[numBytesPerElement*index]);
memcpy(&data[offset + numBytesPerElement*index], &value, numBytesPerElement); memcpy(&data[offset + numBytesPerElement*index], &value, numBytesPerElement);
} }
break; break;
case UINT32: case UINT32:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
quint32 value; quint32 value;
value = qFromLittleEndian<quint32>(&dataIn[numBytesPerElement*index]); value = qFromLittleEndian<quint32>(&dataIn[numBytesPerElement*index]);
memcpy(&data[offset + numBytesPerElement*index], &value, numBytesPerElement); memcpy(&data[offset + numBytesPerElement*index], &value, numBytesPerElement);
} }
break; break;
case FLOAT32: case FLOAT32:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
quint32 value; quint32 value;
value = qFromLittleEndian<quint32>(&dataIn[numBytesPerElement*index]); value = qFromLittleEndian<quint32>(&dataIn[numBytesPerElement*index]);
memcpy(&data[offset + numBytesPerElement*index], &value, numBytesPerElement); memcpy(&data[offset + numBytesPerElement*index], &value, numBytesPerElement);
} }
break; break;
case ENUM: case ENUM:
for (quint32 index = 0; index < numElements; ++index) for (quint32 index = 0; index < numElements; ++index)
{ {
data[offset + numBytesPerElement*index] = dataIn[numBytesPerElement*index]; data[offset + numBytesPerElement*index] = dataIn[numBytesPerElement*index];
} }
break; break;
case STRING: case STRING:
memcpy(&data[offset], dataIn, numElements); memcpy(&data[offset], dataIn, numElements);
break; break;
} }
// Done // Done
return getNumBytes(); return getNumBytes();
@ -377,35 +660,35 @@ bool UAVObjectField::isNumeric()
{ {
switch (type) switch (type)
{ {
case INT8: case INT8:
return true; return true;
break; break;
case INT16: case INT16:
return true; return true;
break; break;
case INT32: case INT32:
return true; return true;
break; break;
case UINT8: case UINT8:
return true; return true;
break; break;
case UINT16: case UINT16:
return true; return true;
break; break;
case UINT32: case UINT32:
return true; return true;
break; break;
case FLOAT32: case FLOAT32:
return true; return true;
break; break;
case ENUM: case ENUM:
return false; return false;
break; break;
case STRING: case STRING:
return false; return false;
break; break;
default: default:
return false; return false;
} }
} }
@ -413,35 +696,35 @@ bool UAVObjectField::isText()
{ {
switch (type) switch (type)
{ {
case INT8: case INT8:
return false; return false;
break; break;
case INT16: case INT16:
return false; return false;
break; break;
case INT32: case INT32:
return false; return false;
break; break;
case UINT8: case UINT8:
return false; return false;
break; break;
case UINT16: case UINT16:
return false; return false;
break; break;
case UINT32: case UINT32:
return false; return false;
break; break;
case FLOAT32: case FLOAT32:
return false; return false;
break; break;
case ENUM: case ENUM:
return true; return true;
break; break;
case STRING: case STRING:
return true; return true;
break; break;
default: default:
return false; return false;
} }
} }
@ -456,74 +739,74 @@ QVariant UAVObjectField::getValue(quint32 index)
// Get value // Get value
switch (type) switch (type)
{ {
case INT8: case INT8:
{ {
qint8 tmpint8; qint8 tmpint8;
memcpy(&tmpint8, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&tmpint8, &data[offset + numBytesPerElement*index], numBytesPerElement);
return QVariant(tmpint8); return QVariant(tmpint8);
break; break;
} }
case INT16: case INT16:
{ {
qint16 tmpint16; qint16 tmpint16;
memcpy(&tmpint16, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&tmpint16, &data[offset + numBytesPerElement*index], numBytesPerElement);
return QVariant(tmpint16); return QVariant(tmpint16);
break; break;
} }
case INT32: case INT32:
{ {
qint32 tmpint32; qint32 tmpint32;
memcpy(&tmpint32, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&tmpint32, &data[offset + numBytesPerElement*index], numBytesPerElement);
return QVariant(tmpint32); return QVariant(tmpint32);
break; break;
} }
case UINT8: case UINT8:
{ {
quint8 tmpuint8; quint8 tmpuint8;
memcpy(&tmpuint8, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&tmpuint8, &data[offset + numBytesPerElement*index], numBytesPerElement);
return QVariant(tmpuint8); return QVariant(tmpuint8);
break; break;
} }
case UINT16: case UINT16:
{ {
quint16 tmpuint16; quint16 tmpuint16;
memcpy(&tmpuint16, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&tmpuint16, &data[offset + numBytesPerElement*index], numBytesPerElement);
return QVariant(tmpuint16); return QVariant(tmpuint16);
break; break;
} }
case UINT32: case UINT32:
{ {
quint32 tmpuint32; quint32 tmpuint32;
memcpy(&tmpuint32, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&tmpuint32, &data[offset + numBytesPerElement*index], numBytesPerElement);
return QVariant(tmpuint32); return QVariant(tmpuint32);
break; break;
} }
case FLOAT32: case FLOAT32:
{ {
float tmpfloat; float tmpfloat;
memcpy(&tmpfloat, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&tmpfloat, &data[offset + numBytesPerElement*index], numBytesPerElement);
return QVariant(tmpfloat); return QVariant(tmpfloat);
break; break;
} }
case ENUM: case ENUM:
{ {
quint8 tmpenum; quint8 tmpenum;
memcpy(&tmpenum, &data[offset + numBytesPerElement*index], numBytesPerElement); memcpy(&tmpenum, &data[offset + numBytesPerElement*index], numBytesPerElement);
// Q_ASSERT((tmpenum < options.length()) && (tmpenum >= 0)); // catch bad enum settings // Q_ASSERT((tmpenum < options.length()) && (tmpenum >= 0)); // catch bad enum settings
if(tmpenum >= options.length()) { if(tmpenum >= options.length()) {
qDebug() << "Invalid value for" << name; qDebug() << "Invalid value for" << name;
return QVariant( QString("Bad Value") ); return QVariant( QString("Bad Value") );
}
return QVariant( options[tmpenum] );
break;
}
case STRING:
{
data[offset + numElements - 1] = '\0';
QString str((char*)&data[offset]);
return QVariant( str );
break;
} }
return QVariant( options[tmpenum] );
break;
}
case STRING:
{
data[offset + numElements - 1] = '\0';
QString str((char*)&data[offset]);
return QVariant( str );
break;
}
} }
// If this point is reached then we got an invalid type // If this point is reached then we got an invalid type
return QVariant(); return QVariant();
@ -536,7 +819,7 @@ bool UAVObjectField::checkValue(const QVariant& value, quint32 index)
if ( index >= numElements ) if ( index >= numElements )
{ {
return false; return false;
} }
// Get metadata // Get metadata
UAVObject::Metadata mdata = obj->getMetadata(); UAVObject::Metadata mdata = obj->getMetadata();
// Update value if the access mode permits // Update value if the access mode permits
@ -544,28 +827,29 @@ bool UAVObjectField::checkValue(const QVariant& value, quint32 index)
{ {
switch (type) switch (type)
{ {
case INT8: case INT8:
case INT16: case INT16:
case INT32: case INT32:
case UINT8: case UINT8:
case UINT16: case UINT16:
case UINT32: case UINT32:
case FLOAT32: case FLOAT32:
case STRING: case STRING:
return true; return true;
break; break;
case ENUM: case ENUM:
{ {
qint8 tmpenum = options.indexOf( value.toString() ); qint8 tmpenum = options.indexOf( value.toString() );
return ((tmpenum < 0) ? false : true); return ((tmpenum < 0) ? false : true);
break; break;
} }
default: default:
qDebug() << "checkValue: other types" << type; qDebug() << "checkValue: other types" << type;
Q_ASSERT(0); // To catch any programming errors where we tried to test invalid values Q_ASSERT(0); // To catch any programming errors where we tried to test invalid values
break; break;
} }
} }
return true;
} }
void UAVObjectField::setValue(const QVariant& value, quint32 index) void UAVObjectField::setValue(const QVariant& value, quint32 index)
@ -575,7 +859,7 @@ void UAVObjectField::setValue(const QVariant& value, quint32 index)
if ( index >= numElements ) if ( index >= numElements )
{ {
return; return;
} }
// Get metadata // Get metadata
UAVObject::Metadata mdata = obj->getMetadata(); UAVObject::Metadata mdata = obj->getMetadata();
// Update value if the access mode permits // Update value if the access mode permits
@ -583,67 +867,67 @@ void UAVObjectField::setValue(const QVariant& value, quint32 index)
{ {
switch (type) switch (type)
{ {
case INT8: case INT8:
{
qint8 tmpint8 = value.toInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpint8, numBytesPerElement);
break;
}
case INT16:
{
qint16 tmpint16 = value.toInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpint16, numBytesPerElement);
break;
}
case INT32:
{
qint32 tmpint32 = value.toInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpint32, numBytesPerElement);
break;
}
case UINT8:
{
quint8 tmpuint8 = value.toUInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpuint8, numBytesPerElement);
break;
}
case UINT16:
{
quint16 tmpuint16 = value.toUInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpuint16, numBytesPerElement);
break;
}
case UINT32:
{
quint32 tmpuint32 = value.toUInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpuint32, numBytesPerElement);
break;
}
case FLOAT32:
{
float tmpfloat = value.toFloat();
memcpy(&data[offset + numBytesPerElement*index], &tmpfloat, numBytesPerElement);
break;
}
case ENUM:
{
qint8 tmpenum = options.indexOf( value.toString() );
Q_ASSERT(tmpenum >= 0); // To catch any programming errors where we set invalid values
memcpy(&data[offset + numBytesPerElement*index], &tmpenum, numBytesPerElement);
break;
}
case STRING:
{
QString str = value.toString();
QByteArray barray = str.toAscii();
quint32 index;
for (index = 0; index < (quint32)barray.length() && index < (numElements-1); ++index)
{ {
qint8 tmpint8 = value.toInt(); data[offset+index] = barray[index];
memcpy(&data[offset + numBytesPerElement*index], &tmpint8, numBytesPerElement);
break;
}
case INT16:
{
qint16 tmpint16 = value.toInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpint16, numBytesPerElement);
break;
}
case INT32:
{
qint32 tmpint32 = value.toInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpint32, numBytesPerElement);
break;
}
case UINT8:
{
quint8 tmpuint8 = value.toUInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpuint8, numBytesPerElement);
break;
}
case UINT16:
{
quint16 tmpuint16 = value.toUInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpuint16, numBytesPerElement);
break;
}
case UINT32:
{
quint32 tmpuint32 = value.toUInt();
memcpy(&data[offset + numBytesPerElement*index], &tmpuint32, numBytesPerElement);
break;
}
case FLOAT32:
{
float tmpfloat = value.toFloat();
memcpy(&data[offset + numBytesPerElement*index], &tmpfloat, numBytesPerElement);
break;
}
case ENUM:
{
qint8 tmpenum = options.indexOf( value.toString() );
Q_ASSERT(tmpenum >= 0); // To catch any programming errors where we set invalid values
memcpy(&data[offset + numBytesPerElement*index], &tmpenum, numBytesPerElement);
break;
}
case STRING:
{
QString str = value.toString();
QByteArray barray = str.toAscii();
quint32 index;
for (index = 0; index < (quint32)barray.length() && index < (numElements-1); ++index)
{
data[offset+index] = barray[index];
}
barray[index] = '\0';
break;
} }
barray[index] = '\0';
break;
}
} }
} }
} }

View File

@ -75,6 +75,9 @@ public:
bool isText(); bool isText();
QString toString(); QString toString();
bool isWithinLimits(QVariant var, quint32 index);
QVariant getMaxLimit(quint32 index);
QVariant getMinLimit(quint32 index);
signals: signals:
void fieldUpdated(UAVObjectField* field); void fieldUpdated(UAVObjectField* field);
@ -91,8 +94,8 @@ protected:
UAVObject* obj; UAVObject* obj;
QMap<quint32,LimitStruct> elementLimits; QMap<quint32,LimitStruct> elementLimits;
void clear(); void clear();
void constructorInitialize(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options, QString &limits); void constructorInitialize(const QString& name, const QString& units, FieldType type, const QStringList& elementNames, const QStringList& options, const QString &limits);
void limitsInitialize(QString &limits); void limitsInitialize(const QString &limits);
}; };