40 #ifdef RTABMAP_DEPTHAI 48 const std::string & deviceSerial,
52 Camera(imageRate, localTransform)
53 #ifdef RTABMAP_DEPTHAI
55 deviceSerial_(deviceSerial),
57 depthConfidence_(200),
58 resolution_(resolution),
59 imuFirmwareUpdate_(
false),
63 #ifdef RTABMAP_DEPTHAI 64 UASSERT(resolution_>=(
int)dai::MonoCameraProperties::SensorResolution::THE_720_P && resolution_<=(
int)dai::MonoCameraProperties::SensorResolution::THE_1200_P);
70 #ifdef RTABMAP_DEPTHAI 80 #ifdef RTABMAP_DEPTHAI 81 outputDepth_ = enabled;
84 depthConfidence_ = confidence;
87 UERROR(
"CameraDepthAI: RTAB-Map is not built with depthai-core support!");
93 #ifdef RTABMAP_DEPTHAI 94 imuFirmwareUpdate_ = enabled;
96 UERROR(
"CameraDepthAI: RTAB-Map is not built with depthai-core support!");
102 #ifdef RTABMAP_DEPTHAI 103 imuPublished_ = published;
105 UERROR(
"CameraDepthAI: RTAB-Map is not built with depthai-core support!");
112 #ifdef RTABMAP_DEPTHAI 114 std::vector<dai::DeviceInfo> devices = dai::Device::getAllAvailableDevices();
127 dai::DeviceInfo deviceToUse;
128 if(deviceSerial_.empty())
129 deviceToUse = devices[0];
130 for(
size_t i=0; i<devices.size(); ++i)
132 UINFO(
"DepthAI device found: %s", devices[i].getMxId().c_str());
133 if(!deviceSerial_.empty() && deviceSerial_.compare(devices[i].getMxId()) == 0)
135 deviceToUse = devices[i];
139 if(deviceToUse.getMxId().empty())
141 UERROR(
"Could not find device with serial \"%s\", found devices:", deviceSerial_.c_str());
142 for(
size_t i=0; i<devices.size(); ++i)
144 UERROR(
"DepthAI device found: %s", devices[i].getMxId().c_str());
148 deviceSerial_ = deviceToUse.getMxId();
152 cv::Size targetSize(resolution_<2?1280:resolution_==4?1920:640, resolution_==0?720:resolution_==1?800:resolution_==2?400:resolution_==3?480:1200);
155 auto monoLeft = p.create<dai::node::MonoCamera>();
156 auto monoRight = p.create<dai::node::MonoCamera>();
157 auto stereo = p.create<dai::node::StereoDepth>();
158 std::shared_ptr<dai::node::IMU> imu;
160 imu = p.create<dai::node::IMU>();
162 auto xoutLeft = p.create<dai::node::XLinkOut>();
163 auto xoutDepthOrRight = p.create<dai::node::XLinkOut>();
164 std::shared_ptr<dai::node::XLinkOut> xoutIMU;
166 xoutIMU = p.create<dai::node::XLinkOut>();
169 xoutLeft->setStreamName(
"rectified_left");
170 xoutDepthOrRight->setStreamName(outputDepth_?
"depth":
"rectified_right");
172 xoutIMU->setStreamName(
"imu");
175 monoLeft->setResolution((dai::MonoCameraProperties::SensorResolution)resolution_);
176 monoLeft->setBoardSocket(dai::CameraBoardSocket::LEFT);
177 monoRight->setResolution((dai::MonoCameraProperties::SensorResolution)resolution_);
178 monoRight->setBoardSocket(dai::CameraBoardSocket::RIGHT);
186 stereo->initialConfig.setConfidenceThreshold(depthConfidence_);
187 stereo->initialConfig.setLeftRightCheckThreshold(5);
188 stereo->setRectifyEdgeFillColor(0);
189 stereo->setLeftRightCheck(
true);
190 stereo->setSubpixel(
false);
191 stereo->setExtendedDisparity(
false);
194 monoLeft->out.link(stereo->left);
195 monoRight->out.link(stereo->right);
201 stereo->rectifiedRight.link(xoutLeft->input);
203 stereo->rectifiedLeft.link(xoutLeft->input);
204 stereo->depth.link(xoutDepthOrRight->input);
208 stereo->rectifiedLeft.link(xoutLeft->input);
209 stereo->rectifiedRight.link(xoutDepthOrRight->input);
215 imu->enableIMUSensor({dai::IMUSensor::ACCELEROMETER_RAW, dai::IMUSensor::GYROSCOPE_RAW}, 200);
217 imu->setBatchReportThreshold(1);
221 imu->setMaxBatchReports(10);
224 imu->out.link(xoutIMU->input);
226 imu->enableFirmwareUpdate(imuFirmwareUpdate_);
229 device_.reset(
new dai::Device(p, deviceToUse));
231 UINFO(
"Loading eeprom calibration data");
232 dai::CalibrationHandler calibHandler = device_->readCalibration();
233 std::vector<std::vector<float> > matrix = calibHandler.getCameraIntrinsics(dai::CameraBoardSocket::LEFT, dai::Size2f(targetSize.width, targetSize.height));
234 double fx = matrix[0][0];
235 double fy = matrix[1][1];
236 double cx = matrix[0][2];
237 double cy = matrix[1][2];
238 matrix = calibHandler.getCameraExtrinsics(dai::CameraBoardSocket::RIGHT, dai::CameraBoardSocket::LEFT);
239 double baseline = matrix[0][3]/100.0;
240 UINFO(
"left: fx=%f fy=%f cx=%f cy=%f baseline=%f", fx, fy, cx, cy, baseline);
257 UINFO(
"IMU local transform = %s", imuLocalTransform_.prettyPrint().c_str());
261 UINFO(
"IMU disabled");
266 imuQueue_ = device_->getOutputQueue(
"imu", 50,
false);
268 leftQueue_ = device_->getOutputQueue(
"rectified_left", 1,
false);
269 rightOrDepthQueue_ = device_->getOutputQueue(outputDepth_?
"depth":
"rectified_right", 1,
false);
275 UERROR(
"CameraDepthAI: RTAB-Map is not built with depthai-core support!");
282 #ifdef RTABMAP_DEPTHAI 283 return stereoModel_.isValidForProjection();
291 #ifdef RTABMAP_DEPTHAI 292 return deviceSerial_;
300 #ifdef RTABMAP_DEPTHAI 302 cv::Mat left, depthOrRight;
303 auto rectifL = leftQueue_->get<dai::ImgFrame>();
304 auto rectifRightOrDepth = rightOrDepthQueue_->get<dai::ImgFrame>();
306 if(rectifL.get() && rectifRightOrDepth.get())
308 auto stampLeft = rectifL->getTimestamp().time_since_epoch().count();
309 auto stampRight = rectifRightOrDepth->getTimestamp().time_since_epoch().count();
310 double stamp = double(stampLeft)/10e8;
311 left = rectifL->getCvFrame();
312 depthOrRight = rectifRightOrDepth->getCvFrame();
314 if(!left.empty() && !depthOrRight.empty())
316 if(depthOrRight.type() == CV_8UC1)
318 if(stereoModel_.isValidForRectification())
320 left = stereoModel_.left().rectifyImage(left);
321 depthOrRight = stereoModel_.right().rectifyImage(depthOrRight);
330 if(fabs(
double(stampLeft)/10e8 -
double(stampRight)/10e8) >= 0.0001)
332 UWARN(
"Frames are not synchronized! %f vs %f",
double(stampLeft)/10e8,
double(stampRight)/10e8);
337 while(imuPublished_ && imuQueue_.get())
341 auto imuData = imuQueue_->get<dai::IMUData>();
343 auto imuPackets = imuData->packets;
344 double accStamp = 0.0;
345 double gyroStamp = 0.0;
346 for(
auto& imuPacket : imuPackets) {
347 auto& acceleroValues = imuPacket.acceleroMeter;
348 auto& gyroValues = imuPacket.gyroscope;
350 accStamp = double(acceleroValues.timestamp.get().time_since_epoch().count())/10e8;
351 gyroStamp = double(gyroValues.timestamp.get().time_since_epoch().count())/10e8;
352 accBuffer_.insert(accBuffer_.end(), std::make_pair(accStamp, cv::Vec3f(acceleroValues.x, acceleroValues.y, acceleroValues.z)));
353 gyroBuffer_.insert(gyroBuffer_.end(), std::make_pair(gyroStamp, cv::Vec3f(gyroValues.x, gyroValues.y, gyroValues.z)));
354 if(accBuffer_.size() > 1000)
356 accBuffer_.erase(accBuffer_.begin());
358 if(gyroBuffer_.size() > 1000)
360 gyroBuffer_.erase(gyroBuffer_.begin());
363 if(accStamp >= stamp && gyroStamp >= stamp)
370 UWARN(
"Could not received IMU after 10 ms! Disabling IMU!");
371 imuPublished_ =
false;
376 bool valid = !accBuffer_.empty() && !gyroBuffer_.empty();
378 if(!accBuffer_.empty())
380 std::map<double, cv::Vec3f>::const_iterator iterB = accBuffer_.lower_bound(stamp);
381 std::map<double, cv::Vec3f>::const_iterator iterA = iterB;
382 if(iterA != accBuffer_.begin())
386 if(iterB == accBuffer_.end())
390 if(iterA == iterB && stamp == iterA->first)
392 acc[0] = iterA->second[0];
393 acc[1] = iterA->second[1];
394 acc[2] = iterA->second[2];
396 else if(stamp >= iterA->first && stamp <= iterB->first)
398 float t = (stamp-iterA->first) / (iterB->first-iterA->first);
399 acc[0] = iterA->second[0] + t*(iterB->second[0] - iterA->second[0]);
400 acc[1] = iterA->second[1] + t*(iterB->second[1] - iterA->second[1]);
401 acc[2] = iterA->second[2] + t*(iterB->second[2] - iterA->second[2]);
406 if(stamp < iterA->first)
408 UWARN(
"Could not find acc data to interpolate at image time %f (earliest is %f). Are sensors synchronized?", stamp, iterA->first);
410 else if(stamp > iterB->first)
412 UWARN(
"Could not find acc data to interpolate at image time %f (latest is %f). Are sensors synchronized?", stamp, iterB->first);
416 UWARN(
"Could not find acc data to interpolate at image time %f (between %f and %f). Are sensors synchronized?", stamp, iterA->first, iterB->first);
421 if(!gyroBuffer_.empty())
423 std::map<double, cv::Vec3f>::const_iterator iterB = gyroBuffer_.lower_bound(stamp);
424 std::map<double, cv::Vec3f>::const_iterator iterA = iterB;
425 if(iterA != gyroBuffer_.begin())
429 if(iterB == gyroBuffer_.end())
433 if(iterA == iterB && stamp == iterA->first)
435 gyro[0] = iterA->second[0];
436 gyro[1] = iterA->second[1];
437 gyro[2] = iterA->second[2];
439 else if(stamp >= iterA->first && stamp <= iterB->first)
441 float t = (stamp-iterA->first) / (iterB->first-iterA->first);
442 gyro[0] = iterA->second[0] + t*(iterB->second[0] - iterA->second[0]);
443 gyro[1] = iterA->second[1] + t*(iterB->second[1] - iterA->second[1]);
444 gyro[2] = iterA->second[2] + t*(iterB->second[2] - iterA->second[2]);
449 if(stamp < iterA->first)
451 UWARN(
"Could not find gyro data to interpolate at image time %f (earliest is %f). Are sensors synchronized?", stamp, iterA->first);
453 else if(stamp > iterB->first)
455 UWARN(
"Could not find gyro data to interpolate at image time %f (latest is %f). Are sensors synchronized?", stamp, iterB->first);
459 UWARN(
"Could not find gyro data to interpolate at image time %f (between %f and %f). Are sensors synchronized?", stamp, iterA->first, iterB->first);
466 data.
setIMU(
IMU(gyro, cv::Mat::eye(3, 3, CV_64FC1), acc, cv::Mat::eye(3, 3, CV_64FC1), imuLocalTransform_));
472 UWARN(
"Null images received!?");
476 UERROR(
"CameraDepthAI: RTAB-Map is not built with depthai-core support!");
void setOutputDepth(bool enabled, int confidence=200)
Some conversion functions.
#define UASSERT(condition)
CameraDepthAI(const std::string &deviceSerial="", int resolution=1, float imageRate=0.0f, const Transform &localTransform=Transform::getIdentity())
virtual bool isCalibrated() const
void setIMUFirmwareUpdate(bool enabled)
virtual std::string getSerial() const
const Transform & getLocalTransform() const
void setIMUPublished(bool published)
float getImageRate() const
void uSleep(unsigned int ms)
virtual SensorData captureImage(CameraInfo *info=0)
void setIMU(const IMU &imu)
virtual bool init(const std::string &calibrationFolder=".", const std::string &cameraName="")