Added assert when bad imu data is provided. Added checks when zed sdk is returning nan imu data.

This commit is contained in:
matlabbe
2026-07-02 21:46:33 -07:00
parent c9e354c67c
commit 1e25f5d4e1
5 changed files with 68 additions and 8 deletions
@@ -26,7 +26,7 @@ runs:
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: ${{ runner.workspace }}/vcpkg_installed path: ${{ runner.workspace }}/vcpkg_installed
key: ${{ runner.os }}-vcpkg-export-66c0373d-x64-vs2022-cuda130_v3 key: ${{ runner.os }}-vcpkg-export-66c0373d-x64-vs2022-cuda130_v4
- name: Download and Install vcpkg - name: Download and Install vcpkg
if: steps.cache-vcpkg.outputs.cache-hit != 'true' if: steps.cache-vcpkg.outputs.cache-hit != 'true'
+3 -1
View File
@@ -42,7 +42,9 @@ IF(APPLE AND BUILD_AS_BUNDLE)
MACOSX_BUNDLE_GUI_IDENTIFIER "com.introlab.rtabmap" MACOSX_BUNDLE_GUI_IDENTIFIER "com.introlab.rtabmap"
MACOSX_BUNDLE_BUNDLE_NAME "${CMAKE_BUNDLE_NAME}") MACOSX_BUNDLE_BUNDLE_NAME "${CMAKE_BUNDLE_NAME}")
ELSEIF(WIN32 AND BUILD_AS_BUNDLE) ELSEIF(WIN32 AND BUILD_AS_BUNDLE)
ADD_EXECUTABLE(rtabmap_app WIN32 ${SRC_FILES}) # not using WIN32 keyword to see fatal errors in the console
# (in particular when zed's neural dlls are not found)
ADD_EXECUTABLE(rtabmap_app ${SRC_FILES})
ELSE() ELSE()
ADD_EXECUTABLE(rtabmap_app ${SRC_FILES}) ADD_EXECUTABLE(rtabmap_app ${SRC_FILES})
ENDIF() ENDIF()
+1 -1
View File
@@ -344,7 +344,7 @@ public:
void setGPS(const GPS & gps) {gps_ = gps;} void setGPS(const GPS & gps) {gps_ = gps;}
const GPS & gps() const {return gps_;} const GPS & gps() const {return gps_;}
void setIMU(const IMU & imu) {imu_ = imu; } void setIMU(const IMU & imu);
const IMU & imu() const {return imu_;} const IMU & imu() const {return imu_;}
void setEnvSensors(const EnvSensors & sensors) {_envSensors = sensors;} void setEnvSensors(const EnvSensors & sensors) {_envSensors = sensors;}
+16
View File
@@ -952,6 +952,22 @@ void SensorData::setFeatures(const std::vector<cv::KeyPoint> & keypoints, const
_descriptors = descriptors; _descriptors = descriptors;
} }
void SensorData::setIMU(const IMU & imu)
{
UASSERT(
uIsFinite(imu.orientation()[0]) &&
uIsFinite(imu.orientation()[1]) &&
uIsFinite(imu.orientation()[2]) &&
uIsFinite(imu.orientation()[3]) &&
uIsFinite(imu.angularVelocity()[0]) &&
uIsFinite(imu.angularVelocity()[1]) &&
uIsFinite(imu.angularVelocity()[2]) &&
uIsFinite(imu.linearAcceleration()[0]) &&
uIsFinite(imu.linearAcceleration()[1]) &&
uIsFinite(imu.linearAcceleration()[2]));
imu_ = imu;
}
unsigned long SensorData::getMemoryUsed() const // Return memory usage in Bytes unsigned long SensorData::getMemoryUsed() const // Return memory usage in Bytes
{ {
return sizeof(SensorData) + return sizeof(SensorData) +
+47 -5
View File
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/utilite/UTimer.h> #include <rtabmap/utilite/UTimer.h>
#include <rtabmap/utilite/UThread.h> #include <rtabmap/utilite/UThread.h>
#include <rtabmap/utilite/UConversion.h> #include <rtabmap/utilite/UConversion.h>
#include <rtabmap/utilite/UMath.h>
#ifdef RTABMAP_ZED #ifdef RTABMAP_ZED
#include <sl/Camera.hpp> #include <sl/Camera.hpp>
@@ -161,6 +162,23 @@ IMU zedIMUtoIMU(const sl::SensorsData & sensorData, const Transform & imuLocalTr
accCov, accCov,
imuLocalTransform); imuLocalTransform);
} }
// sl::SensorsData::imu.is_available only means the camera has an IMU; a returned
// sample can still contain NaN pose/accel/gyro (e.g. before the IMU fusion has
// initialized, or in SVO/STREAM mode). Validate the actual measurements.
bool isImuValid(const sl::SensorsData & sensorData)
{
if(!sensorData.imu.is_available)
{
return false;
}
const sl::float3 & acc = sensorData.imu.linear_acceleration;
const sl::float3 & gyr = sensorData.imu.angular_velocity;
const sl::Orientation ori = sensorData.imu.pose.getOrientation();
return uIsFinite(acc.v[0]) && uIsFinite(acc.v[1]) && uIsFinite(acc.v[2]) &&
uIsFinite(gyr.v[0]) && uIsFinite(gyr.v[1]) && uIsFinite(gyr.v[2]) &&
uIsFinite(ori.ox) && uIsFinite(ori.oy) && uIsFinite(ori.oz) && uIsFinite(ori.ow);
}
#endif #endif
class ZedIMUThread: public UThread class ZedIMUThread: public UThread
@@ -217,7 +235,7 @@ private:
#else #else
sl::SensorsData sensordata; sl::SensorsData sensordata;
sl::ERROR_CODE res = zed_->getSensorsData(sensordata, sl::TIME_REFERENCE::CURRENT); sl::ERROR_CODE res = zed_->getSensorsData(sensordata, sl::TIME_REFERENCE::CURRENT);
if(res == sl::ERROR_CODE::SUCCESS && sensordata.imu.is_available) if(res == sl::ERROR_CODE::SUCCESS && isImuValid(sensordata))
{ {
camera_->postInterIMUPublic(zedIMUtoIMU(sensordata, imuLocalTransform_), double(sensordata.imu.timestamp.getNanoseconds())/10e8); camera_->postInterIMUPublic(zedIMUtoIMU(sensordata, imuLocalTransform_), double(sensordata.imu.timestamp.getNanoseconds())/10e8);
} }
@@ -463,6 +481,22 @@ bool CameraStereoZed::init(const std::string & calibrationFolder, const std::str
r = zed_->open(param); r = zed_->open(param);
} }
#if ZED_SDK_MAJOR_VERSION >= 3
// CORRUPTED_SDK_INSTALLATION on open() is typically a NEURAL depth mode whose optional
// neural/TensorRT runtime files aren't installed. Give a clear, actionable error.
if(r == sl::ERROR_CODE::CORRUPTED_SDK_INSTALLATION &&
param.depth_mode != sl::DEPTH_MODE::PERFORMANCE &&
param.depth_mode != sl::DEPTH_MODE::NONE)
{
UERROR("ZED open() returned \"%s\": the optional NEURAL/TensorRT runtime files are "
"likely missing. Install ZED SDK %d.%d, or select a non-NEURAL depth mode "
"(e.g. PERFORMANCE).", toString(r).c_str(), ZED_SDK_MAJOR_VERSION, ZED_SDK_MINOR_VERSION);
delete zed_;
zed_ = 0;
return false;
}
#endif
if(r!=sl::ERROR_CODE::SUCCESS) if(r!=sl::ERROR_CODE::SUCCESS)
{ {
UERROR("Camera initialization failed: \"%s\"", toString(r).c_str()); UERROR("Camera initialization failed: \"%s\"", toString(r).c_str());
@@ -731,16 +765,24 @@ SensorData CameraStereoZed::captureImage(SensorCaptureInfo * info)
res = zed_->grab(rparam); res = zed_->grab(rparam);
timestamp = zed_->getTimestamp(sl::TIME_REFERENCE::IMAGE); timestamp = zed_->getTimestamp(sl::TIME_REFERENCE::IMAGE);
// If the sensor supports IMU, wait IMU to be available before sending data. // If the sensor supports IMU, wait for IMU to be available before sending data.
if(imuPublishingThread_ == 0 && !imuLocalTransform_.isNull()) if(imuPublishingThread_ == 0 && !imuLocalTransform_.isNull())
{ {
sl::SensorsData imudatatmp; sl::SensorsData imudatatmp;
res = zed_->getSensorsData(imudatatmp, sl::TIME_REFERENCE::IMAGE); res = zed_->getSensorsData(imudatatmp, sl::TIME_REFERENCE::IMAGE);
imuReceived = res == sl::ERROR_CODE::SUCCESS && imudatatmp.imu.is_available && imudatatmp.imu.timestamp.getNanoseconds() != 0; imuReceived = res == sl::ERROR_CODE::SUCCESS && isImuValid(imudatatmp) && imudatatmp.imu.timestamp.getNanoseconds() != 0;
} }
} }
while(src_ == CameraVideo::kUsbDevice && (res!=sl::ERROR_CODE::SUCCESS || !imuReceived) && timer.elapsed() < 2.0); while(src_ == CameraVideo::kUsbDevice && (res!=sl::ERROR_CODE::SUCCESS || !imuReceived) && timer.elapsed() < 2.0);
// If no valid IMU arrived within the 2 sec startup window, null the IMU transform so
// we don't re-wait 2 sec on every subsequent frame (camera likely has no working IMU).
if(imuPublishingThread_ == 0 && !imuLocalTransform_.isNull() && !imuReceived)
{
UWARN("No valid IMU received within 2 sec; ignoring IMU for the rest of this session.");
imuLocalTransform_.setNull();
}
if(res==sl::ERROR_CODE::SUCCESS) if(res==sl::ERROR_CODE::SUCCESS)
#endif #endif
{ {
@@ -794,7 +836,7 @@ SensorData CameraStereoZed::captureImage(SensorCaptureInfo * info)
#endif #endif
} }
if(imuPublishingThread_ == 0) if(imuPublishingThread_ == 0 && !imuLocalTransform_.isNull())
{ {
#if ZED_SDK_MAJOR_VERSION < 3 #if ZED_SDK_MAJOR_VERSION < 3
sl::IMUData imudata; sl::IMUData imudata;
@@ -803,7 +845,7 @@ SensorData CameraStereoZed::captureImage(SensorCaptureInfo * info)
#else #else
sl::SensorsData imudata; sl::SensorsData imudata;
res = zed_->getSensorsData(imudata, sl::TIME_REFERENCE::IMAGE); res = zed_->getSensorsData(imudata, sl::TIME_REFERENCE::IMAGE);
if(res == sl::ERROR_CODE::SUCCESS && imudata.imu.is_available) if(res == sl::ERROR_CODE::SUCCESS && isImuValid(imudata))
#endif #endif
{ {
//ZED-Mini //ZED-Mini