BitmapToolkit Scol plugin
sSlam_ucoslam.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
25//#include "sService.h"
26
27#include "ArManager.h"
28#include "ArCameraParam.h"
29#include "sSlam.h"
30
31#include <vector>
32
33#ifdef WIN32
34#include <direct.h>
35#define GetCurrentDir _getcwd
36#else
37#include <unistd.h>
38#define GetCurrentDir getcwd
39#endif
40
41std::string GetCurrentWorkingDir(void)
42{
43 char buff[FILENAME_MAX];
44 GetCurrentDir(buff, FILENAME_MAX);
45 std::string current_working_dir(buff);
46
47 for (unsigned int i = 0; i < current_working_dir.length(); i++)
48 {
49 if (current_working_dir.substr(i, 1) == "\\")
50 current_working_dir.replace(i, 1, "/");
51 }
52 return current_working_dir;
53}
54
56{
57 mIsDirty = false;
58 needUpdate = false;
59 mScale = 1.0f;
60 mSlam = 0;
61 mFrameIdx = 0;
62
63 //mParams.runSequential = true;//avoid parallel processing
64 //mParams.global_optimizer = "g2o";//which global optimizer to use
65 //mParams.detectMarkers = false;//(dis/e)nables marker detection
66 //mParams.detectKeyPoints = true;//(dis/e)nables kp detection
67 //mParams.kpDescriptorType = ucoslam::DescriptorTypes::Type::DESC_ORB;//keypoint descriptor employed
68 //mParams.KPNonMaximaSuppresion = false;//activating it will create maps with less points (faster).
69 //mParams.KFMinConfidence = 0.65;//value that regulates when a keyframe is added. Range (0,inf). low values will include less keyframes. high value will include more keyframes
70 //mParams.maxFeatures = 1000;//number of features to be detected
71 //mParams.nOctaveLevels = 8;//number of octaves for keypoint detection
72 //mParams.scaleFactor = 1.2;//scale factor
73 //mParams.KFCulling = 0.8;// Value indicating how many redundant keypoints must be in a keyframe to remove it. Range [0,1]. If low, few keyframes will survive. If 1, no keyframe will be removed once added.
74 //mParams.aruco_markerSize = 0.08;//Size of markers in meters
75 //mParams.maxNewPoints = 350;//maximum number of new points created when a new keyframe is added
76 //mParams.forceInitializationFromMarkers = false;//If true, the system will not initialize until a good initialization from markers is obtained
77 //mParams.nthreads_feature_detector = 2;//number of threads employed in keypoint detection
78 //mParams.autoAdjustKpSensitivity = true;//enables/disables automatic keypoint detector sensitivity to adapt environement with low texture
79 //mParams.kptImageScaleFactor = 1.0;//[0,1] indicates the desired scale factor employed for keypoint detection. If 1 the original input image is used. Otherwise, the
80 //input image is resized with the specified scale factor. PLease notice that markers will be detected in the original input images anyway
81
82 //aruco::MarkerDetector::Params aruco_DetectorParams;//the internal parameters of Aruco Library for marker detection
83 //parameters of the aruco marker detector
84 mParams.aruco_Dictionary = "ARUCO";
85 mParams.aruco_DetectionMode = "DM_NORMAL";
86 mParams.aruco_CornerRefimentMethod = "CORNER_LINES";
87 mParams.aruco_minMarkerSize = 0;
88
89#ifdef ANDROID
90 mVocFile = CopyFileFromAssetToSD("btdata/orb_vocab.fbow", "orb_vocab.fbow", "btdata");
91#else
92 mVocFile = GetCurrentWorkingDir() + "/plugins/btdata/orb_vocab.fbow";
93#endif
94
95 mSlam = new ucoslam::UcoSlam();
96 mMap = std::make_shared<ucoslam::Map>();
97
98 try
99 {
100 mSlam->setParams(mMap, mParams, mVocFile);
101
102 // Run thread
103 StartThreading(boost::bind(&Sslam::GoThread, this));
104 }
105 catch (std::runtime_error)
106 {
107 //error
108 }
109}
110
112{
114
115 if (mSlam)
116 mSlam->waitForFinished();
117 SAFE_DELETE(mSlam);
118}
119
120void Sslam::SetDirty()
121{
122 mIsDirty = true;
123}
124
125void Sslam::BuildCameraParam(const aruco::CameraParameters &camparam)
126{
127 mScale = 1.0f;
128
129 /*int maxsize = std::max(camparam.CamSize.width, camparam.CamSize.height);
130 if (maxsize > 640)
131 mScale = 640.0f / (float)maxsize;*/
132
133 //construct camParam
134 mCamParams.CamSize = camparam.CamSize;
135 mCamParams.CameraMatrix = camparam.CameraMatrix;
136 mCamParams.Distorsion = camparam.Distorsion;
137 //mCamParams.resize(cv::Size((int)((float)camparam.CamSize.width * mScale), (int)((float)camparam.CamSize.height * mScale)));
138}
139
140void Sslam::InitDetector()
141{
142 boost::unique_lock<boost::recursive_mutex> ld(mUpdateMutex);
143
144 try
145 {
146 // build a SLAM system
147 mSlam->waitForFinished();
148 mSlam->clear();
149 mSlam->setParams(mMap, mParams, mVocFile);
150 }
151 catch (std::exception &)
152 {
153 SAFE_DELETE(mSlam);
154 }
155 mFrameIdx = 0;
156 ld.unlock();
157}
158
160{
161 return mLastCamPos;
162}
163
165{
166 return mLastCamQuat;
167}
168
169void Sslam::DrawLandmarks(cv::Mat image)
170{
171 if (mSlam && !image.empty())
172 {
173 //std::shared_ptr<openvslam::publish::frame_publisher> frame = mSlam->get_frame_publisher();
174 //frame->draw_frame(true).copyTo(image);
175 }
176}
177
178void Sslam::GoThread()
179{
180 while (IsRunning())
181 {
182 if (needUpdate)
183 {
185 manager->GetLastData(mLastData);
186
187 //cv::equalizeHist(mLastData.gray, mLastData.gray);
188
189 needUpdate = false;
190
191 //cv::blur(mLastData.gray, mLastData.gray, cv::Size(2, 2));
192 cv::Size nsize;
193 nsize.width = (int)((float)mLastData.gray.cols * mScale);
194 nsize.height = (int)((float)mLastData.gray.rows * mScale);
195 // Detect all markers seen on gray
196
197 // camera size changed
198 if (!mSlam || (((int)((float)mLastData.camParam.CamSize.width * mScale)) != mCamParams.CamSize.width || ((int)((float)mLastData.camParam.CamSize.height * mScale)) != mCamParams.CamSize.height))
199 mIsDirty = true;
200
201 // init detector
202 if (mIsDirty)
203 {
204 mIsDirty = false;
205 BuildCameraParam(mLastData.camParam);
206 InitDetector();
207 }
208
209 if (mScale != 1.0f)
210 cv::resize(mLastData.gray, mLastData.gray, mCamParams.CamSize, 0, 0, cv::INTER_LINEAR);
211
212 // thread to detect do it after mutex lock
213 if (!mLastData.image.empty() && mSlam)
214 {
215 cv::Mat mat = mSlam->process(mLastData.gray, mCamParams, mFrameIdx);
216 mFrameIdx += 1;
217
218 if (!mat.empty())
219 {
220 cv::Mat Rwc(3, 3, CV_32F);
221 cv::Mat twc(3, 1, CV_32F);
222 {
223 Rwc = mat.rowRange(0, 3).colRange(0, 3).t();
224 twc = -Rwc * mat.rowRange(0, 3).col(3);
225 }
226
227 double modelview_matrix[16];
228 modelview_matrix[0 + 0 * 4] = Rwc.at<float>(0, 0);
229 modelview_matrix[0 + 1 * 4] = Rwc.at<float>(1, 0);
230 modelview_matrix[0 + 2 * 4] = Rwc.at<float>(2, 0);
231 modelview_matrix[0 + 3 * 4] = 0.0;
232
233 modelview_matrix[1 + 0 * 4] = Rwc.at<float>(0, 1);
234 modelview_matrix[1 + 1 * 4] = Rwc.at<float>(1, 1);
235 modelview_matrix[1 + 2 * 4] = Rwc.at<float>(2, 1);
236 modelview_matrix[1 + 3 * 4] = 0.0;
237
238 modelview_matrix[2 + 0 * 4] = Rwc.at<float>(0, 2);
239 modelview_matrix[2 + 1 * 4] = Rwc.at<float>(1, 2);
240 modelview_matrix[2 + 2 * 4] = Rwc.at<float>(2, 2);
241 modelview_matrix[2 + 3 * 4] = 0.0;
242
243 modelview_matrix[3 + 0 * 4] = twc.at<float>(0);
244 modelview_matrix[3 + 1 * 4] = twc.at<float>(1);
245 modelview_matrix[3 + 2 * 4] = twc.at<float>(2);
246 modelview_matrix[3 + 3 * 4] = 1.0;
247
248 mLastCamPos = Vector3(twc.at<float>(0), twc.at<float>(1), twc.at<float>(2));
249
250 mLastCamQuat = Quaternion::FromRotationMatrix(modelview_matrix, mLastData.reversedBitmap);
251 }
252 }
253 }
254 else
255 {
256 //prevent cpu burn
257 boost::this_thread::sleep_for(boost::chrono::milliseconds(1)); //DO not burn too much CPU
258 }
259 }
260}
void GetLastData(LASTDATA &data)
static ArManager * GetInstance()
Definition ArManager.cpp:70
cv::Mat image
cv::Mat gray
bool reversedBitmap
void SetDirty()
Definition sSlam.cpp:583
bool needUpdate
Definition sSlam.h:128
Vector3 GetCameraPosition()
Definition sSlam.cpp:687
~Sslam()
Definition sSlam.cpp:412
Sslam()
Definition sSlam.cpp:328
void GoThread()
Definition sSlam.cpp:820
BtQuaternion GetCameraOrientation()
Definition sSlam.cpp:700
void DrawLandmarks(cv::Mat image)
Definition sSlam.cpp:739
Create a thread type. .
std::string GetCurrentWorkingDir(void)
#define GetCurrentDir