mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
added new statistics (features extracted current image, local map size) shown in GUI for Odometry
git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@1719 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
@@ -53,7 +53,14 @@ public:
|
|||||||
|
|
||||||
bool init(int startIndex=0);
|
bool init(int startIndex=0);
|
||||||
void setFrameRate(float frameRate);
|
void setFrameRate(float frameRate);
|
||||||
void getNextImage(cv::Mat & image, cv::Mat & depth, cv::Mat & depth2d, float & fx, float & fy, float & cx, float & cy, Transform & localTransform, Transform & pose);
|
void getNextImage(cv::Mat & image,
|
||||||
|
cv::Mat & depth,
|
||||||
|
cv::Mat & depth2d,
|
||||||
|
float & fx, float & fy,
|
||||||
|
float & cx, float & cy,
|
||||||
|
Transform & localTransform,
|
||||||
|
Transform & pose,
|
||||||
|
int & seq);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void mainLoopBegin();
|
virtual void mainLoopBegin();
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class RTABMAP_EXP Odometry
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Odometry() {}
|
virtual ~Odometry() {}
|
||||||
Transform process(SensorData & data, int * quality = 0);
|
Transform process(SensorData & data, int * quality = 0, int * features = 0, int * localMapSize = 0);
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|
||||||
bool isLargeEnoughTransform(const Transform & transform);
|
bool isLargeEnoughTransform(const Transform & transform);
|
||||||
@@ -72,7 +72,7 @@ public:
|
|||||||
int getLocalHistory() const {return _localHistory;}
|
int getLocalHistory() const {return _localHistory;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual Transform computeTransform(const SensorData & image, int * quality = 0) = 0;
|
virtual Transform computeTransform(const SensorData & image, int * quality = 0, int * features = 0, int * localMapSize = 0) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _maxFeatures;
|
int _maxFeatures;
|
||||||
@@ -106,7 +106,7 @@ public:
|
|||||||
const Memory * getMemory() const {return _memory;}
|
const Memory * getMemory() const {return _memory;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual Transform computeTransform(const SensorData & image, int * quality = 0);
|
virtual Transform computeTransform(const SensorData & image, int * quality = 0, int * features = 0, int * localMapSize = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Memory * _memory;
|
Memory * _memory;
|
||||||
@@ -127,7 +127,7 @@ public:
|
|||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual Transform computeTransform(const SensorData & image, int * quality = 0);
|
virtual Transform computeTransform(const SensorData & image, int * quality = 0, int * features = 0, int * localMapSize = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _decimation;
|
int _decimation;
|
||||||
|
|||||||
@@ -37,10 +37,13 @@ class OdometryEvent : public UEvent
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OdometryEvent(
|
OdometryEvent(
|
||||||
const SensorData & data, int quality = -1, float time = 0.0f) :
|
const SensorData & data, int quality = -1, float time = 0.0f, int features = 0, int localMapSize = 0) :
|
||||||
_data(data),
|
_data(data),
|
||||||
_quality(quality),
|
_quality(quality),
|
||||||
_time(time){}
|
_time(time),
|
||||||
|
_features(features),
|
||||||
|
_localMapSize(localMapSize)
|
||||||
|
{}
|
||||||
virtual ~OdometryEvent() {}
|
virtual ~OdometryEvent() {}
|
||||||
virtual std::string getClassName() const {return "OdometryEvent";}
|
virtual std::string getClassName() const {return "OdometryEvent";}
|
||||||
|
|
||||||
@@ -48,11 +51,15 @@ public:
|
|||||||
const SensorData & data() const {return _data;}
|
const SensorData & data() const {return _data;}
|
||||||
int quality() const {return _quality;}
|
int quality() const {return _quality;}
|
||||||
float time() const {return _time;} // seconds
|
float time() const {return _time;} // seconds
|
||||||
|
int features() const {return _features;}
|
||||||
|
int localMapSize() const {return _localMapSize;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SensorData _data;
|
SensorData _data;
|
||||||
int _quality;
|
int _quality;
|
||||||
float _time; // seconds
|
float _time; // seconds
|
||||||
|
int _features;
|
||||||
|
int _localMapSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OdometryResetEvent : public UEvent
|
class OdometryResetEvent : public UEvent
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ private:
|
|||||||
// strategies for a type of signature or configuration.
|
// strategies for a type of signature or configuration.
|
||||||
EpipolarGeometry * _epipolarGeometry;
|
EpipolarGeometry * _epipolarGeometry;
|
||||||
BayesFilter * _bayesFilter;
|
BayesFilter * _bayesFilter;
|
||||||
|
ParametersMap _lastParameters;
|
||||||
|
|
||||||
Memory * _memory;
|
Memory * _memory;
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,8 @@ void DBReader::mainLoop()
|
|||||||
cv::Mat image, depth, depth2d;
|
cv::Mat image, depth, depth2d;
|
||||||
float fx,fy,cx,cy;
|
float fx,fy,cx,cy;
|
||||||
Transform localTransform, pose;
|
Transform localTransform, pose;
|
||||||
this->getNextImage(image, depth, depth2d, fx, fy, cx, cy, localTransform, pose);
|
int seq = 0;
|
||||||
|
this->getNextImage(image, depth, depth2d, fx, fy, cx, cy, localTransform, pose, seq);
|
||||||
if(!image.empty())
|
if(!image.empty())
|
||||||
{
|
{
|
||||||
if(depth.empty())
|
if(depth.empty())
|
||||||
@@ -145,7 +146,7 @@ void DBReader::mainLoop()
|
|||||||
{
|
{
|
||||||
if(!_odometryIgnored)
|
if(!_odometryIgnored)
|
||||||
{
|
{
|
||||||
SensorData data(image, depth, depth2d, fx, fy, cx, cy, pose, localTransform);
|
SensorData data(image, depth, depth2d, fx, fy, cx, cy, pose, localTransform, seq);
|
||||||
this->post(new OdometryEvent(data));
|
this->post(new OdometryEvent(data));
|
||||||
if(pose.isNull())
|
if(pose.isNull())
|
||||||
{
|
{
|
||||||
@@ -157,7 +158,7 @@ void DBReader::mainLoop()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// without odometry
|
// without odometry
|
||||||
this->post(new CameraEvent(image, depth, depth2d, fx, fy, cx, cy, localTransform));
|
this->post(new CameraEvent(image, depth, depth2d, fx, fy, cx, cy, localTransform, seq));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +180,8 @@ void DBReader::getNextImage(
|
|||||||
float & cx,
|
float & cx,
|
||||||
float & cy,
|
float & cy,
|
||||||
Transform & localTransform,
|
Transform & localTransform,
|
||||||
Transform & pose)
|
Transform & pose,
|
||||||
|
int & seq)
|
||||||
{
|
{
|
||||||
if(_dbDriver)
|
if(_dbDriver)
|
||||||
{
|
{
|
||||||
@@ -211,6 +213,7 @@ void DBReader::getNextImage(
|
|||||||
int mapId;
|
int mapId;
|
||||||
_dbDriver->getNodeData(*_currentId, imageBytes, depthBytes, depth2dBytes, fx, fy, cx, cy, localTransform);
|
_dbDriver->getNodeData(*_currentId, imageBytes, depthBytes, depth2dBytes, fx, fy, cx, cy, localTransform);
|
||||||
_dbDriver->getPose(*_currentId, pose, mapId);
|
_dbDriver->getPose(*_currentId, pose, mapId);
|
||||||
|
seq = *_currentId;
|
||||||
++_currentId;
|
++_currentId;
|
||||||
if(imageBytes.empty())
|
if(imageBytes.empty())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -99,9 +99,9 @@ bool Odometry::isLargeEnoughTransform(const Transform & transform)
|
|||||||
fabs(yaw) > _angularUpdate;
|
fabs(yaw) > _angularUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform Odometry::process(SensorData & data, int * quality)
|
Transform Odometry::process(SensorData & data, int * quality, int * features, int * localMapSize)
|
||||||
{
|
{
|
||||||
Transform t = this->computeTransform(data, quality);
|
Transform t = this->computeTransform(data, quality, features, localMapSize);
|
||||||
if(!t.isNull())
|
if(!t.isNull())
|
||||||
{
|
{
|
||||||
_resetCurrentCount = _resetCountdown;
|
_resetCurrentCount = _resetCountdown;
|
||||||
@@ -210,7 +210,7 @@ std::multimap<int,pcl::PointXYZ> OdometryBOW::getLocalMeansMap() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return not null transform if odometry is correctly computed
|
// return not null transform if odometry is correctly computed
|
||||||
Transform OdometryBOW::computeTransform(const SensorData & data, int * quality)
|
Transform OdometryBOW::computeTransform(const SensorData & data, int * quality, int * features, int * localMapSize)
|
||||||
{
|
{
|
||||||
UTimer timer;
|
UTimer timer;
|
||||||
Transform output;
|
Transform output;
|
||||||
@@ -388,6 +388,15 @@ Transform OdometryBOW::computeTransform(const SensorData & data, int * quality)
|
|||||||
_memory->emptyTrash();
|
_memory->emptyTrash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(features)
|
||||||
|
{
|
||||||
|
*features = nFeatures;
|
||||||
|
}
|
||||||
|
if(localMapSize)
|
||||||
|
{
|
||||||
|
*localMapSize = (int)localMap_.size();
|
||||||
|
}
|
||||||
|
|
||||||
UINFO("Odom update time = %fs features=%d inliers=%d/%d local_map=%d[%d] dict=%d nodes=%d",
|
UINFO("Odom update time = %fs features=%d inliers=%d/%d local_map=%d[%d] dict=%d nodes=%d",
|
||||||
timer.elapsed(),
|
timer.elapsed(),
|
||||||
nFeatures,
|
nFeatures,
|
||||||
@@ -430,7 +439,7 @@ void OdometryICP::reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return not null transform if odometry is correctly computed
|
// return not null transform if odometry is correctly computed
|
||||||
Transform OdometryICP::computeTransform(const SensorData & data, int * quality)
|
Transform OdometryICP::computeTransform(const SensorData & data, int * quality, int * features, int * localMapSize)
|
||||||
{
|
{
|
||||||
UTimer timer;
|
UTimer timer;
|
||||||
Transform output;
|
Transform output;
|
||||||
@@ -605,10 +614,12 @@ void OdometryThread::mainLoop()
|
|||||||
if(data.isValid())
|
if(data.isValid())
|
||||||
{
|
{
|
||||||
int quality = -1;
|
int quality = -1;
|
||||||
|
int features = -1;
|
||||||
|
int localMapSize = -1;
|
||||||
UTimer time;
|
UTimer time;
|
||||||
Transform pose = _odometry->process(data, &quality);
|
Transform pose = _odometry->process(data, &quality, &features, &localMapSize);
|
||||||
data.setPose(pose); // a null pose notify that odometry could not be computed
|
data.setPose(pose); // a null pose notify that odometry could not be computed
|
||||||
this->post(new OdometryEvent(data, quality, time.elapsed()));
|
this->post(new OdometryEvent(data, quality, time.elapsed(), features, localMapSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -422,6 +422,11 @@ void Rtabmap::parseParameters(const ParametersMap & parameters)
|
|||||||
{
|
{
|
||||||
_bayesFilter->parseParameters(parameters);
|
_bayesFilter->parseParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(ParametersMap::const_iterator iter = parameters.begin(); iter!=parameters.end(); ++iter)
|
||||||
|
{
|
||||||
|
uInsert(_lastParameters, ParametersPair(iter->first, iter->second));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Rtabmap::getDatabasePath() const
|
std::string Rtabmap::getDatabasePath() const
|
||||||
@@ -1274,19 +1279,20 @@ bool Rtabmap::process(const SensorData & data)
|
|||||||
std::string rejectedMsg;
|
std::string rejectedMsg;
|
||||||
if(_reextractLoopClosureFeatures)
|
if(_reextractLoopClosureFeatures)
|
||||||
{
|
{
|
||||||
ParametersMap customParameters;
|
ParametersMap customParameters = _lastParameters;
|
||||||
customParameters.insert(ParametersPair(Parameters::kLccBowInlierDistance(), uNumber2Str(_memory->getBowInlierDistance())));
|
// override some parameters
|
||||||
customParameters.insert(ParametersPair(Parameters::kLccBowIterations(), uNumber2Str(_memory->getBowIterations())));
|
uInsert(customParameters, ParametersPair(Parameters::kMemRehearsalSimilarity(), "1.0")); // desactivate rehearsal
|
||||||
customParameters.insert(ParametersPair(Parameters::kLccBowMinInliers(), uNumber2Str(_memory->getBowMinInliers())));
|
uInsert(customParameters, ParametersPair(Parameters::kMemImageKept(), "false"));
|
||||||
customParameters.insert(ParametersPair(Parameters::kKpMaxDepth(), uNumber2Str(_memory->getBowMaxDepth())));
|
uInsert(customParameters, ParametersPair(Parameters::kMemSTMSize(), "0"));
|
||||||
customParameters.insert(ParametersPair(Parameters::kLccBowForce2D(), uNumber2Str(_memory->getBowForce2D())));
|
uInsert(customParameters, ParametersPair(Parameters::kKpNNStrategy(), uNumber2Str(_reextractNNType))); // bruteforce
|
||||||
customParameters.insert(ParametersPair(Parameters::kMemRehearsalSimilarity(), "1.0")); // desactivate rehearsal
|
uInsert(customParameters, ParametersPair(Parameters::kKpNndrRatio(), uNumber2Str(_reextractNNDR)));
|
||||||
customParameters.insert(ParametersPair(Parameters::kMemImageKept(), "false"));
|
uInsert(customParameters, ParametersPair(Parameters::kKpDetectorStrategy(), uNumber2Str(_reextractFeatureType))); // FAST/BRIEF
|
||||||
customParameters.insert(ParametersPair(Parameters::kMemSTMSize(), "0"));
|
uInsert(customParameters, ParametersPair(Parameters::kKpWordsPerImage(), uNumber2Str(_reextractMaxWords)));
|
||||||
customParameters.insert(ParametersPair(Parameters::kKpNNStrategy(), uNumber2Str(_reextractNNType))); // bruteforce
|
|
||||||
customParameters.insert(ParametersPair(Parameters::kKpNndrRatio(), uNumber2Str(_reextractNNDR)));
|
for(ParametersMap::iterator iter = customParameters.begin(); iter!=customParameters.end(); ++iter)
|
||||||
customParameters.insert(ParametersPair(Parameters::kKpDetectorStrategy(), uNumber2Str(_reextractFeatureType))); // FAST/BRIEF
|
{
|
||||||
customParameters.insert(ParametersPair(Parameters::kKpWordsPerImage(), uNumber2Str(_reextractMaxWords)));
|
UINFO("%s=%s", iter->first.c_str(), iter->second.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
Memory memory(customParameters);
|
Memory memory(customParameters);
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ private slots:
|
|||||||
void selectScreenCaptureFormat(bool checked);
|
void selectScreenCaptureFormat(bool checked);
|
||||||
void takeScreenshot();
|
void takeScreenshot();
|
||||||
void updateElapsedTime();
|
void updateElapsedTime();
|
||||||
void processOdometry(const rtabmap::SensorData & data, int quality, float time);
|
void processOdometry(const rtabmap::SensorData & data, int quality, float time, int features, int localMapSize);
|
||||||
void applyAllPrefSettings();
|
void applyAllPrefSettings();
|
||||||
void applyPrefSettings(PreferencesDialog::PANEL_FLAGS flags);
|
void applyPrefSettings(PreferencesDialog::PANEL_FLAGS flags);
|
||||||
void applyPrefSettings(const rtabmap::ParametersMap & parameters);
|
void applyPrefSettings(const rtabmap::ParametersMap & parameters);
|
||||||
@@ -169,7 +169,7 @@ private slots:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void statsReceived(const rtabmap::Statistics &);
|
void statsReceived(const rtabmap::Statistics &);
|
||||||
void odometryReceived(const rtabmap::SensorData &, int, float);
|
void odometryReceived(const rtabmap::SensorData &, int, float, int, int);
|
||||||
void thresholdsChanged(int, int);
|
void thresholdsChanged(int, int);
|
||||||
void stateChanged(MainWindow::State);
|
void stateChanged(MainWindow::State);
|
||||||
void rtabmapEventInitReceived(int status, const QString & info);
|
void rtabmapEventInitReceived(int status, const QString & info);
|
||||||
|
|||||||
@@ -907,7 +907,10 @@ void DatabaseViewer::detectMoreLoopClosures()
|
|||||||
std::multimap<int, rtabmap::Link> links = updateLinksWithModifications(links_);
|
std::multimap<int, rtabmap::Link> links = updateLinksWithModifications(links_);
|
||||||
optimizedPoses = optimizeGraph(ids, poses_, links);
|
optimizedPoses = optimizeGraph(ids, poses_, links);
|
||||||
|
|
||||||
std::multimap<int, int> clusters = util3d::radiusPosesClustering(optimizedPoses, 0.1, 0.1);
|
std::multimap<int, int> clusters = util3d::radiusPosesClustering(
|
||||||
|
optimizedPoses,
|
||||||
|
ui_->doubleSpinBox_detectMore_radius->value(),
|
||||||
|
ui_->doubleSpinBox_detectMore_angle->value());
|
||||||
int added = 0;
|
int added = 0;
|
||||||
for(std::multimap<int, int>::iterator iter=clusters.begin(); iter!= clusters.end(); ++iter)
|
for(std::multimap<int, int>::iterator iter=clusters.begin(); iter!= clusters.end(); ++iter)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
|||||||
connect(this, SIGNAL(statsReceived(rtabmap::Statistics)), this, SLOT(processStats(rtabmap::Statistics)));
|
connect(this, SIGNAL(statsReceived(rtabmap::Statistics)), this, SLOT(processStats(rtabmap::Statistics)));
|
||||||
|
|
||||||
qRegisterMetaType<rtabmap::SensorData>("rtabmap::SensorData");
|
qRegisterMetaType<rtabmap::SensorData>("rtabmap::SensorData");
|
||||||
connect(this, SIGNAL(odometryReceived(rtabmap::SensorData, int, float)), this, SLOT(processOdometry(rtabmap::SensorData, int, float)));
|
connect(this, SIGNAL(odometryReceived(rtabmap::SensorData, int, float, int, int)), this, SLOT(processOdometry(rtabmap::SensorData, int, float, int, int)));
|
||||||
|
|
||||||
connect(this, SIGNAL(noMoreImagesReceived()), this, SLOT(stopDetection()));
|
connect(this, SIGNAL(noMoreImagesReceived()), this, SLOT(stopDetection()));
|
||||||
|
|
||||||
@@ -531,7 +531,7 @@ void MainWindow::handleEvent(UEvent* anEvent)
|
|||||||
!_processingStatistics)
|
!_processingStatistics)
|
||||||
{
|
{
|
||||||
_lastOdometryProcessed = false; // if we receive too many odometry events!
|
_lastOdometryProcessed = false; // if we receive too many odometry events!
|
||||||
emit odometryReceived(odomEvent->data(), odomEvent->quality(), odomEvent->time());
|
emit odometryReceived(odomEvent->data(), odomEvent->quality(), odomEvent->time(), odomEvent->features(), odomEvent->localMapSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(anEvent->getClassName().compare("ULogEvent") == 0)
|
else if(anEvent->getClassName().compare("ULogEvent") == 0)
|
||||||
@@ -554,7 +554,7 @@ void MainWindow::handleEvent(UEvent* anEvent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::processOdometry(const rtabmap::SensorData & data, int quality, float time)
|
void MainWindow::processOdometry(const rtabmap::SensorData & data, int quality, float time, int features, int localMapSize)
|
||||||
{
|
{
|
||||||
Transform pose = data.pose();
|
Transform pose = data.pose();
|
||||||
if(pose.isNull())
|
if(pose.isNull())
|
||||||
@@ -584,6 +584,14 @@ void MainWindow::processOdometry(const rtabmap::SensorData & data, int quality,
|
|||||||
{
|
{
|
||||||
_ui->statsToolBox->updateStat("Odometry/Time/ms", (float)data.id(), (float)time*1000.0f);
|
_ui->statsToolBox->updateStat("Odometry/Time/ms", (float)data.id(), (float)time*1000.0f);
|
||||||
}
|
}
|
||||||
|
if(features >=0)
|
||||||
|
{
|
||||||
|
_ui->statsToolBox->updateStat("Odometry/Features/", (float)data.id(), (float)features);
|
||||||
|
}
|
||||||
|
if(localMapSize >=0)
|
||||||
|
{
|
||||||
|
_ui->statsToolBox->updateStat("Odometry/LocalMapSize/", (float)data.id(), (float)localMapSize);
|
||||||
|
}
|
||||||
if(!pose.isNull())
|
if(!pose.isNull())
|
||||||
{
|
{
|
||||||
_lastOdomPose = pose;
|
_lastOdomPose = pose;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1076</width>
|
<width>1076</width>
|
||||||
<height>582</height>
|
<height>665</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -912,6 +912,58 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="8" column="0">
|
||||||
|
<widget class="QLabel" name="label_29">
|
||||||
|
<property name="text">
|
||||||
|
<string>Detect more LCs: radius</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="0">
|
||||||
|
<widget class="QLabel" name="label_30">
|
||||||
|
<property name="text">
|
||||||
|
<string>Detect more LCs: angle</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_detectMore_radius">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> m</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>10.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.300000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_detectMore_angle">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> rad</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>3.140000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.300000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|||||||
Reference in New Issue
Block a user