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

OP-220 1st attempt at "horizontal bias calibration" for the AHRS. Very basic calculation over 100 samples, be my guest to make it more sophisticated if necessary, all the basics are there, you just have to plug a better algo!

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2271 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
edouard 2010-12-22 15:31:37 +00:00 committed by edouard
parent 7715a6d6cd
commit fc27419cf6
3 changed files with 474 additions and 345 deletions

View File

@ -13,363 +13,387 @@
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QFrame" name="Position6">
<property name="geometry">
<rect>
<x>10</x>
<y>7</y>
<width>641</width>
<height>461</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QGraphicsView" name="ahrsBargraph">
<property name="geometry">
<rect>
<x>10</x>
<y>210</y>
<width>341</width>
<height>131</height>
</rect>
</property>
<property name="toolTip">
<string>These are the sensor variance values computed by the AHRS.
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="Position6">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="sixPointLayout" stretch="1,2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>#1: Six Point Calibration</string>
</property>
</widget>
</item>
<item>
<widget class="QGraphicsView" name="sixPointsHelp">
<property name="toolTip">
<string>Nice paper plane, eh?</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="horLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="sixPointsStart">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Launch a sensor range and bias calibration.</string>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="sixPointsSave">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Save settings (only enabled when calibration is running)</string>
</property>
<property name="text">
<string>Save Position</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTextEdit" name="sixPointCalibInstructions">
<property name="toolTip">
<string>Six Point Calibration instructions</string>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note:&lt;/span&gt; all &amp;quot;Start&amp;quot; buttons for the three calibration operations will remain disabled until telemetry is running.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="sensorNoiseLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>#2: Sensor noise calibration</string>
</property>
</widget>
</item>
<item>
<widget class="QGraphicsView" name="ahrsBargraph">
<property name="toolTip">
<string>These are the sensor variance values computed by the AHRS.
Tip: lower is better!</string>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
</widget>
<widget class="QLabel" name="calibInstructions">
<property name="geometry">
<rect>
<x>380</x>
<y>280</y>
<width>231</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Telemetry link not established.</string>
</property>
</widget>
<widget class="QPushButton" name="ahrsCalibStart">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>450</x>
<y>240</y>
<width>93</width>
<height>27</height>
</rect>
</property>
<property name="toolTip">
<string>Press to start a calibration procedure, about 15 seconds.
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="ahrsCalibStart">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Press to start a calibration procedure, about 15 seconds.
Hint: run this with engines at cruising speed.</string>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
<widget class="Line" name="line">
<property name="geometry">
<rect>
<x>220</x>
<y>180</y>
<width>411</width>
<height>20</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>380</y>
<width>111</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>AHRS Algorithm:</string>
</property>
</widget>
<widget class="QComboBox" name="algorithm">
<property name="geometry">
<rect>
<x>140</x>
<y>370</y>
<width>131</width>
<height>31</height>
</rect>
</property>
<property name="toolTip">
<string>Select the sensor integration algorithm here.
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="calibProgress">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>15</number>
</property>
<property name="value">
<number>0</number>
</property>
<property name="textVisible">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="calibInstructions">
<property name="text">
<string>Telemetry link not established.</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label_5">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>#3: Accelerometer Bias calibration</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="textEdit">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Place your airframe as horizontally as possible (use a spirit level if necessary), then press Start below and do not move your airframe at all until the end of the calibration.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="accelBiasStart">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="accelBiasProgress">
<property name="value">
<number>0</number>
</property>
<property name="textVisible">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="ahrsSettingsLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>AHRS Algorithm:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="algorithm">
<property name="toolTip">
<string>Select the sensor integration algorithm here.
&quot;Simple&quot; only uses accelerometer values
&quot;INSGPS&quot; the full featured algorithm integrating all sensors</string>
</property>
</widget>
<widget class="QGraphicsView" name="sixPointsHelp">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>191</width>
<height>151</height>
</rect>
</property>
<property name="toolTip">
<string>Nice paper plane, eh?</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>181</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>#1: Six Point Calibration</string>
</property>
</widget>
<widget class="QPushButton" name="sixPointsStart">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>250</x>
<y>10</y>
<width>111</width>
<height>27</height>
</rect>
</property>
<property name="toolTip">
<string>Launch a sensor range and bias calibration.</string>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
<widget class="QTextEdit" name="sixPointCalibInstructions">
<property name="geometry">
<rect>
<x>220</x>
<y>50</y>
<width>411</width>
<height>121</height>
</rect>
</property>
<property name="toolTip">
<string>Six Point Calibration instructions</string>
</property>
</widget>
<widget class="QRadioButton" name="homeLocationSet">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>480</x>
<y>361</y>
<width>51</width>
<height>31</height>
</rect>
</property>
<property name="toolTip">
<string>Saves the Home Location. This is only enabled
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Home Location:</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="homeLocationSet">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Saves the Home Location. This is only enabled
if the Home Location is set, i.e. if the GPS fix is
successful.
Disabled if there is no GPS fix.</string>
</property>
<property name="text">
<string>Set</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
<widget class="QPushButton" name="ahrsSettingsRequest">
<property name="geometry">
<rect>
<x>280</x>
<y>430</y>
<width>93</width>
<height>27</height>
</rect>
</property>
<property name="toolTip">
<string>Refresh this screen with current values from the board.</string>
</property>
<property name="text">
<string>Request</string>
</property>
</widget>
<widget class="Line" name="line_3">
<property name="geometry">
<rect>
<x>120</x>
<y>340</y>
<width>411</width>
<height>20</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>380</x>
<y>210</y>
<width>251</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>#2: Sensor noise calibration</string>
</property>
</widget>
<widget class="QProgressBar" name="calibProgress">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>390</x>
<y>310</y>
<width>201</width>
<height>23</height>
</rect>
</property>
<property name="maximum">
<number>15</number>
</property>
<property name="value">
<number>0</number>
</property>
<property name="textVisible">
<bool>false</bool>
</property>
</widget>
<widget class="QPushButton" name="sixPointsSave">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>380</x>
<y>10</y>
<width>111</width>
<height>27</height>
</rect>
</property>
<property name="toolTip">
<string>Save settings (only enabled when calibration is running)</string>
</property>
<property name="text">
<string>Save Position</string>
</property>
</widget>
<widget class="QPushButton" name="ahrsSettingsSaveRAM">
<property name="geometry">
<rect>
<x>390</x>
<y>430</y>
<width>111</width>
<height>27</height>
</rect>
</property>
<property name="toolTip">
<string>Save settings to the OP board (RAM only).
</property>
<property name="text">
<string>Set</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="homeLocationClear">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Clears the HomeLocation: only makes sense if you save
to SD. This will force the AHRS to use the next GPS fix as the
new home location unless it is in indoor mode.</string>
</property>
<property name="text">
<string>Clear</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="submitButtons">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="ahrsSettingsRequest">
<property name="toolTip">
<string>Refresh this screen with current values from the board.</string>
</property>
<property name="text">
<string>Request</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ahrsSettingsSaveRAM">
<property name="toolTip">
<string>Save settings to the OP board (RAM only).
This does not save the calibration settings, this is done using the
specific calibration button on top of the screen.</string>
</property>
<property name="text">
<string>Save to RAM</string>
</property>
</widget>
<widget class="QPushButton" name="ahrsSettingsSaveSD">
<property name="geometry">
<rect>
<x>520</x>
<y>430</y>
<width>101</width>
<height>27</height>
</rect>
</property>
<property name="toolTip">
<string>Send settings to OP board, and save to the microSD card.</string>
</property>
<property name="text">
<string>Save to SD</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
<widget class="QRadioButton" name="homeLocationClear">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>550</x>
<y>360</y>
<width>71</width>
<height>31</height>
</rect>
</property>
<property name="toolTip">
<string>Clears the HomeLocation: only makes sense if you save
to SD. This will force the AHRS to use the next GPS fix as the
new home location unless it is in indoor mode.</string>
</property>
<property name="text">
<string>Clear</string>
</property>
<attribute name="buttonGroup">
<string>buttonGroup</string>
</attribute>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>370</x>
<y>360</y>
<width>101</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Home Location:</string>
</property>
</widget>
</widget>
</property>
<property name="text">
<string>Save to RAM</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ahrsSettingsSaveSD">
<property name="toolTip">
<string>Send settings to OP board, and save to the microSD card.</string>
</property>
<property name="text">
<string>Save to SD</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>

View File

@ -203,6 +203,7 @@ ConfigAHRSWidget::ConfigAHRSWidget(QWidget *parent) : ConfigTaskWidget(parent)
// Connect the signals
connect(m_ahrs->ahrsCalibStart, SIGNAL(clicked()), this, SLOT(launchAHRSCalibration()));
connect(m_ahrs->accelBiasStart, SIGNAL(clicked()), this, SLOT(launchAccelBiasCalibration()));
connect(m_ahrs->ahrsSettingsRequest, SIGNAL(clicked()), this, SLOT(ahrsSettingsRequest()));
/*
connect(m_ahrs->algorithm, SIGNAL(currentIndexChanged(int)), this, SLOT(ahrsSettingsSave()));
@ -234,6 +235,106 @@ void ConfigAHRSWidget::showEvent(QShowEvent *event)
m_ahrs->sixPointsHelp->fitInView(paperplane,Qt::KeepAspectRatio);
}
void ConfigAHRSWidget::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event)
m_ahrs->ahrsBargraph->fitInView(ahrsbargraph, Qt::KeepAspectRatio);
m_ahrs->sixPointsHelp->fitInView(paperplane,Qt::KeepAspectRatio);
}
/**
Starts an accelerometer bias calibration.
*/
void ConfigAHRSWidget::launchAccelBiasCalibration()
{
m_ahrs->accelBiasStart->setEnabled(false);
// Setup the AHRS to give us the right data at the right rate:
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSSettings")));
UAVObjectField* field = obj->getField(QString("BiasCorrectedRaw"));
field->setValue("FALSE");
obj->updated();
accel_accum_x.clear();
accel_accum_y.clear();
accel_accum_z.clear();
UAVDataObject* ahrsCalib = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSCalibration")));
ahrsCalib->getField("accel_bias")->setDouble(0,0);
ahrsCalib->getField("accel_bias")->setDouble(0,1);
ahrsCalib->getField("accel_bias")->setDouble(0,2);
ahrsCalib->updated();
/* Need to get as many AttitudeRaw updates as possible */
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AttitudeRaw")));
initialMdata = obj->getMetadata();
UAVObject::Metadata mdata = initialMdata;
mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
mdata.flightTelemetryUpdatePeriod = 100;
obj->setMetadata(mdata);
// Now connect to the attituderaw updates, gather for 100 samples
collectingData = true;
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AttitudeRaw")));
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(accelBiasattitudeRawUpdated(UAVObject*)));
}
/**
Updates the accel bias raw values
*/
void ConfigAHRSWidget::accelBiasattitudeRawUpdated(UAVObject *obj)
{
UAVObjectField *accel_field = obj->getField(QString("accels_filtered"));
Q_ASSERT(accel_field != 0);
// This is necessary to prevent a race condition on disconnect signal and another update
if (collectingData == true) {
accel_accum_x.append(accel_field->getValue(0).toDouble());
accel_accum_y.append(accel_field->getValue(1).toDouble());
accel_accum_z.append(accel_field->getValue(2).toDouble());
}
m_ahrs->accelBiasProgress->setValue(m_ahrs->accelBiasProgress->value()+1);
if(accel_accum_x.size() >= 100 && collectingData == true) {
collectingData = false;
disconnect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(attitudeRawUpdated(UAVObject*)));
m_ahrs->accelBiasStart->setEnabled(true);
UAVDataObject* ahrsCalib = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSCalibration")));
/*
double xScale = ahrsCalib->getField("accel_scale")->getDouble(0);
double yScale = ahrsCalib->getField("accel_scale")->getDouble(1);
double zScale = ahrsCalib->getField("accel_scale")->getDouble(2);
*/
double xBias = - listMean(accel_accum_x);
double yBias = - listMean(accel_accum_y);
double zBias = -9.81 - listMean(accel_accum_z);
ahrsCalib->getField("accel_bias")->setDouble(xBias,0);
ahrsCalib->getField("accel_bias")->setDouble(yBias,1);
ahrsCalib->getField("accel_bias")->setDouble(zBias,2);
ahrsCalib->updated();
getObjectManager()->getObject(QString("AttitudeRaw"))->setMetadata(initialMdata);
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSSettings")));
UAVObjectField* field = obj->getField(QString("BiasCorrectedRaw"));
field->setValue("TRUE");
obj->updated();
saveAHRSCalibration();
}
}
/**
Launches the AHRS sensors calibration
*/
@ -702,6 +803,7 @@ void ConfigAHRSWidget::ahrsSettingsRequest()
m_ahrs->ahrsCalibStart->setEnabled(true);
m_ahrs->sixPointsStart->setEnabled(true);
m_ahrs->accelBiasStart->setEnabled(true);
m_ahrs->calibInstructions->setText(QString("Press \"Start\" above to calibrate."));
}

View File

@ -99,6 +99,7 @@ private slots:
void enableHomeLocSave(UAVObject *obj);
void launchAHRSCalibration();
void saveAHRSCalibration();
void launchAccelBiasCalibration();
void calibPhase2();
void incrementProgress();
void ahrsSettingsRequest();
@ -108,9 +109,11 @@ private slots:
void computeScaleBias();
void sixPointCalibrationMode();
void attitudeRawUpdated(UAVObject * obj);
void accelBiasattitudeRawUpdated(UAVObject*);
protected:
void showEvent(QShowEvent *event);
void resizeEvent(QResizeEvent *event);
};