Project

General

Profile

BitmapToolkit Scol plugin
sSlam_vslam.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 "openvslam/publish/map_publisher.h"
32#include "openvslam/publish/frame_publisher.h"
33#include "openvslam/data/landmark.h"
34
35#include <vector>
36
37#ifdef WIN32
38#include <direct.h>
39#define GetCurrentDir _getcwd
40#else
41#include <unistd.h>
42#define GetCurrentDir getcwd
43#endif
44
45std::string GetCurrentWorkingDir(void)
46{
47 char buff[FILENAME_MAX];
48 GetCurrentDir(buff, FILENAME_MAX);
49 std::string current_working_dir(buff);
50
51 for (unsigned int i = 0; i < current_working_dir.length(); i++)
52 {
53 if (current_working_dir.substr(i, 1) == "\\")
54 current_working_dir.replace(i, 1, "/");
55 }
56 return current_working_dir;
57}
58
60{
61 mIsDirty = false;
62 needUpdate = false;
63 mScale = 1.0f;
64 mSlam = 0;
65 mTimestamp = 0.0;
66 mCfgNode = YAML::Load(
67"#==============#\n\
68# Camera Model #\n\
69#==============#\n\
70\n\
71Camera.name: \"Default monocular\"\n\
72Camera.setup : \"monocular\"\n\
73Camera.model : \"perspective\"\n\
74\n\
75Camera.fx : 640.0\n\
76Camera.fy : 640.0\n\
77Camera.cx : 480.0\n\
78Camera.cy : 480.0\n\
79\n\
80Camera.k1 : 0.0\n\
81Camera.k2 : 0.0\n\
82Camera.p1 : 0.0\n\
83Camera.p2 : 0.0\n\
84Camera.k3 : 0.0\n\
85\n\
86Camera.fps : 20.0\n\
87Camera.cols : 640\n\
88Camera.rows : 480\n\
89\n\
90Camera.color_order : \"Gray\"\n\
91\n\
92#================#\n\
93# ORB Parameters #\n\
94#================#\n\
95\n\
96Feature.max_num_keypoints: 1200\n\
97Feature.scale_factor : 1.2\n\
98Feature.num_levels : 8\n\
99Feature.ini_fast_threshold : 20\n\
100Feature.min_fast_threshold : 7\n\
101\n\
102#=====================#\n\
103# Tracking Parameters #\n\
104#=====================#\n\
105\n\
106depth_threshold: 35\n");
107
108 mCfg = std::make_shared<openvslam::config>(mCfgNode);
109
110 // Run thread
111 StartThreading(boost::bind(&Sslam::GoThread, this));
112}
113
115{
117
118 if (mSlam)
119 {
120 mSlam->abort_loop_BA();
121 while (mSlam->loop_BA_is_running())
122 boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
123
124 mSlam->shutdown();
125 SAFE_DELETE(mSlam);
126 }
127}
128
129void Sslam::SetDirty()
130{
131 mIsDirty = true;
132}
133
134void Sslam::BuildCameraParam(const aruco::CameraParameters &camparam)
135{
136 mScale = 1.0f;
137
138 int maxsize = std::max(camparam.CamSize.width, camparam.CamSize.height);
139 if (maxsize > 640)
140 mScale = 640 / (float)maxsize;
141
142 /*if (maxsize > 1600)
143 mScale = 0.4f;
144 else if (maxsize > 1200)
145 mScale = 0.53333f;
146 else if (maxsize > 750)
147 mScale = 0.85333f;
148 else if (maxsize > 640)
149 mScale = 0.9f;
150 else
151 mScale = 1.0f;
152
153#if defined(ANDROID) || defined(APPLE_IOS) || defined(RPI)
154 if (maxsize > 640)
155 mScale *= 0.75f;
156#endif
157 */
158
159 //construct camParam
160 mCfgNode["Camera.cols"] = (int)((float)camparam.CamSize.width * mScale);
161 mCfgNode["Camera.rows"] = (int)((float)camparam.CamSize.height * mScale);
162
163 float f = std::max(camparam.CamSize.width, camparam.CamSize.height);
164 mCfgNode["Camera.fx"] = f * mScale;
165 mCfgNode["Camera.fy"] = f * mScale;
166 mCfgNode["Camera.cx"] = static_cast<float>(camparam.CamSize.width) * mScale * 0.5f;
167 mCfgNode["Camera.cy"] = static_cast<float>(camparam.CamSize.height) * mScale * 0.5f;
168
169 mCfg = std::make_shared<openvslam::config>(mCfgNode);
170}
171
172void Sslam::InitDetector()
173{
174 boost::unique_lock<boost::recursive_mutex> ld(mUpdateMutex);
175
176 if (mSlam)
177 {
178 mSlam->abort_loop_BA();
179 while (mSlam->loop_BA_is_running())
180 boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
181
182 mSlam->shutdown();
183 SAFE_DELETE(mSlam);
184 }
185
186 try
187 {
188 std::string sdata;
189#ifdef ANDROID
190 sdata = CopyFileFromAssetToSD("btdata/orb_vocab.dbow2", "orb_vocab.dbow2", "btdata");
191#else
192 sdata = GetCurrentWorkingDir() + "/plugins/btdata/orb_vocab.dbow2";
193#endif
194
195 // build a SLAM system
196 mSlam = new openvslam::system(mCfg, sdata);
197 // startup the SLAM process
198 mSlam->startup();
199 mSlam->enable_mapping_module();
200 mSlam->disable_loop_detector();
201 }
202 catch (std::exception &)
203 {
204 SAFE_DELETE(mSlam);
205 }
206 mTimestamp = 0.0;
207 ld.unlock();
208}
209
211{
212 return mLastCamPos;
213}
214
216{
217 return mLastCamQuat;
218}
219
220void Sslam::DrawLandmarks(cv::Mat image)
221{
222 if (mSlam && !image.empty())
223 {
224 std::shared_ptr<openvslam::publish::frame_publisher> frame = mSlam->get_frame_publisher();
225 frame->draw_frame(true).copyTo(image);
226 }
227}
228
229void Sslam::GoThread()
230{
231 std::chrono::steady_clock::time_point lastTimeStamp = std::chrono::steady_clock::now();
232 while (IsRunning())
233 {
234 if (needUpdate)
235 {
237 manager->GetLastData(mLastData);
238
239 cv::Size nsize;
240 nsize.width = (int)((float)mLastData.gray.cols * mScale);
241 nsize.height = (int)((float)mLastData.gray.rows * mScale);
242
243 if (mScale != 1.0f)
244 cv::resize(mLastData.gray, mLastData.gray, nsize, 0, 0, cv::INTER_LINEAR);
245
246 //cv::equalizeHist(mLastData.gray, mLastData.gray);
247
248 needUpdate = false;
249
250 //cv::blur(mLastData.gray, mLastData.gray, cv::Size(2, 2));
251
252 // Detect all markers seen on gray
253
254 // camera size changed
255 if (!mSlam || (((int)((float)mLastData.camParam.CamSize.width * mScale)) != mCfg->camera_->cols_ || ((int)((float)mLastData.camParam.CamSize.height * mScale)) != mCfg->camera_->rows_))
256 mIsDirty = true;
257
258 // init detector
259 if (mIsDirty)
260 {
261 mIsDirty = false;
262 BuildCameraParam(mLastData.camParam);
263 InitDetector();
264 }
265
266 // thread to detect do it after mutex lock
267 if (!mLastData.image.empty() && mSlam)
268 {
269 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
270 double ttrack = std::chrono::duration_cast<std::chrono::duration<double>>(t1 - lastTimeStamp).count();
271 mTimestamp += ttrack;
272 lastTimeStamp = std::chrono::steady_clock::now();
273
274 mSlam->feed_monocular_frame(mLastData.gray, mTimestamp);
275
276 std::shared_ptr<openvslam::publish::map_publisher> map = mSlam->get_map_publisher();
277 openvslam::Mat44_t mat = map->get_current_cam_pose().inverse().eval();
278
279 //std::vector<openvslam::data::landmark*> all_landmarks;
280 //std::set<openvslam::data::landmark*> local_landmarks;
281 //map->get_landmarks(all_landmarks, local_landmarks);
282
283 if (!isnan(mat(0, 3)))
284 {
285 openvslam::Mat33_t rotation_matrix = mat.block<3, 3>(0, 0);
286 openvslam::Vec3_t translation_vector = mat.block<3, 1>(0, 3);
287
288 openvslam::Quat_t quat(rotation_matrix);
289 quat.normalize();
290
291 mLastCamPos = Vector3(translation_vector(0), -translation_vector(1), -translation_vector(2));
292 /*double modelview_matrix[16];
293
294 modelview_matrix[0 + 0 * 4] = rotation_matrix(0, 0);
295 modelview_matrix[0 + 1 * 4] = rotation_matrix(0, 1);
296 modelview_matrix[0 + 2 * 4] = rotation_matrix(0, 2);
297 modelview_matrix[0 + 3 * 4] = 0.0;
298 modelview_matrix[1 + 0 * 4] = -rotation_matrix(1, 0);
299 modelview_matrix[1 + 1 * 4] = -rotation_matrix(1, 1);
300 modelview_matrix[1 + 2 * 4] = -rotation_matrix(1, 2);
301 modelview_matrix[0 + 3 * 4] = 0.0;
302 modelview_matrix[2 + 0 * 4] = rotation_matrix(2, 0);
303 modelview_matrix[2 + 1 * 4] = rotation_matrix(2, 1);
304 modelview_matrix[2 + 2 * 4] = rotation_matrix(2, 2);
305 modelview_matrix[0 + 3 * 4] = 0.0;
306 modelview_matrix[3 + 0 * 4] = 0.0;
307 modelview_matrix[3 + 0 * 4] = 0.0;
308 modelview_matrix[3 + 0 * 4] = 0.0;
309 modelview_matrix[3 + 0 * 4] = 1.0;
310
311 mLastCamQuat = Quaternion::FromRotationMatrix(modelview_matrix, mLastData.reversedBitmap);// *Quaternion(sqrt(0.5f), 0.0, sqrt(0.5f), 0.0f);
312 */
313 mLastCamQuat = Quaternion(-quat.w(), (mLastData.reversedBitmap) ? quat.x() : -quat.x(), quat.y(), quat.z());
314 }
315 }
316 }
317 else
318 {
319 //prevent cpu burn
320 boost::this_thread::sleep_for(boost::chrono::milliseconds(1)); //DO not burn too much CPU
321 }
322 }
323}
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)
Definition sSlam_orb.cpp:43
std::string GetCurrentWorkingDir(void)
#define GetCurrentDir