Skip to content

Commit

Permalink
cleanup deleting IMU logic with zv-upt, should prevent buffers from g…
Browse files Browse the repository at this point in the history
…rowing large
  • Loading branch information
goldbattle committed Nov 22, 2022
1 parent 3861010 commit eba3500
Show file tree
Hide file tree
Showing 16 changed files with 130 additions and 83 deletions.
6 changes: 3 additions & 3 deletions config/euroc_mav/estimator_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ feat_rep_aruco: "ANCHORED_MSCKF_INVERSE_DEPTH"
try_zupt: false
zupt_chi2_multipler: 0 # set to 0 for only disp-based
zupt_max_velocity: 0.1
zupt_noise_multiplier: 50
zupt_max_disparity: 1.5 # set to 0 for only imu-based
zupt_only_at_beginning: true
zupt_noise_multiplier: 10
zupt_max_disparity: 0.5 # set to 0 for only imu-based
zupt_only_at_beginning: false

# ==================================================================
# ==================================================================
Expand Down
6 changes: 3 additions & 3 deletions config/kaist/estimator_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ calib_cam_extrinsics: false # degenerate motion
calib_cam_intrinsics: true
calib_cam_timeoffset: true # degenerate motion

max_clones: 8
max_clones: 11
max_slam: 50
max_slam_in_update: 25
max_msckf_in_update: 50
Expand All @@ -28,9 +28,9 @@ feat_rep_aruco: "ANCHORED_MSCKF_INVERSE_DEPTH"
# zero velocity update parameters we can use
# we support either IMU-based or disparity detection.
try_zupt: true
zupt_chi2_multipler: 0.25 # set to 0 for only disp-based
zupt_chi2_multipler: 0.5 # set to 0 for only disp-based
zupt_max_velocity: 0.1
zupt_noise_multiplier: 5
zupt_noise_multiplier: 1
zupt_max_disparity: 0.4 # set to 0 for only imu-based
zupt_only_at_beginning: false

Expand Down
7 changes: 4 additions & 3 deletions ov_core/src/track/TrackAruco.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,10 @@ void TrackAruco::perform_tracking(double timestamp, const cv::Mat &imgin, size_t
rT3 = boost::posix_time::microsec_clock::local_time();

// Timing information
// PRINT_DEBUG("[TIME-ARUCO]: %.4f seconds for detection\n",(rT2-rT1).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-ARUCO]: %.4f seconds for feature DB update (%d features)\n",(rT3-rT2).total_microseconds() * 1e-6,
// (int)good_left.size()); PRINT_DEBUG("[TIME-ARUCO]: %.4f seconds for total\n",(rT3-rT1).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-ARUCO]: %.4f seconds for detection\n", (rT2 - rT1).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-ARUCO]: %.4f seconds for feature DB update (%d features)\n", (rT3 - rT2).total_microseconds() * 1e-6,
(int)ids_new.size());
PRINT_ALL("[TIME-ARUCO]: %.4f seconds for total\n", (rT3 - rT1).total_microseconds() * 1e-6);
}

void TrackAruco::display_active(cv::Mat &img_out, int r1, int g1, int b1, int r2, int g2, int b2, std::string overlay) {
Expand Down
22 changes: 12 additions & 10 deletions ov_core/src/track/TrackDescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,12 @@ void TrackDescriptor::feed_monocular(const CameraData &message, size_t msg_id) {
rT5 = boost::posix_time::microsec_clock::local_time();

// Our timing information
// PRINT_DEBUG("[TIME-DESC]: %.4f seconds for detection\n",(rT2-rT1).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-DESC]: %.4f seconds for matching\n",(rT3-rT2).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-DESC]: %.4f seconds for merging\n",(rT4-rT3).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-DESC]: %.4f seconds for feature DB update (%d features)\n",(rT5-rT4).total_microseconds() * 1e-6,
// (int)good_left.size()); PRINT_DEBUG("[TIME-DESC]: %.4f seconds for total\n",(rT5-rT1).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-DESC]: %.4f seconds for detection\n", (rT2 - rT1).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-DESC]: %.4f seconds for matching\n", (rT3 - rT2).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-DESC]: %.4f seconds for merging\n", (rT4 - rT3).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-DESC]: %.4f seconds for feature DB update (%d features)\n", (rT5 - rT4).total_microseconds() * 1e-6,
(int)good_left.size());
PRINT_ALL("[TIME-DESC]: %.4f seconds for total\n", (rT5 - rT1).total_microseconds() * 1e-6);
}

void TrackDescriptor::feed_stereo(const CameraData &message, size_t msg_id_left, size_t msg_id_right) {
Expand Down Expand Up @@ -343,11 +344,12 @@ void TrackDescriptor::feed_stereo(const CameraData &message, size_t msg_id_left,
rT5 = boost::posix_time::microsec_clock::local_time();

// Our timing information
// PRINT_DEBUG("[TIME-DESC]: %.4f seconds for detection\n",(rT2-rT1).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-DESC]: %.4f seconds for matching\n",(rT3-rT2).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-DESC]: %.4f seconds for merging\n",(rT4-rT3).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-DESC]: %.4f seconds for feature DB update (%d features)\n",(rT5-rT4).total_microseconds() * 1e-6,
// (int)good_left.size()); PRINT_DEBUG("[TIME-DESC]: %.4f seconds for total\n",(rT5-rT1).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-DESC]: %.4f seconds for detection\n", (rT2 - rT1).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-DESC]: %.4f seconds for matching\n", (rT3 - rT2).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-DESC]: %.4f seconds for merging\n", (rT4 - rT3).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-DESC]: %.4f seconds for feature DB update (%d features)\n", (rT5 - rT4).total_microseconds() * 1e-6,
(int)good_left.size());
PRINT_ALL("[TIME-DESC]: %.4f seconds for total\n", (rT5 - rT1).total_microseconds() * 1e-6);
}

void TrackDescriptor::perform_detection_monocular(const cv::Mat &img0, const cv::Mat &mask0, std::vector<cv::KeyPoint> &pts0,
Expand Down
32 changes: 18 additions & 14 deletions ov_core/src/track/TrackKLT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ void TrackKLT::feed_monocular(const CameraData &message, size_t msg_id) {

// First we should make that the last images have enough features so we can do KLT
// This will "top-off" our number of tracks so always have a constant number
int pts_before_detect = (int)pts_last[cam_id].size();
auto pts_left_old = pts_last[cam_id];
auto ids_left_old = ids_last[cam_id];
perform_detection_monocular(img_pyramid_last[cam_id], img_mask_last[cam_id], pts_left_old, ids_left_old);
Expand Down Expand Up @@ -188,13 +189,14 @@ void TrackKLT::feed_monocular(const CameraData &message, size_t msg_id) {
}
rT5 = boost::posix_time::microsec_clock::local_time();

// // Timing information
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for pyramid\n", (rT2 - rT1).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for detection\n", (rT3 - rT2).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for temporal klt\n", (rT4 - rT3).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for feature DB update (%d features)\n", (rT5 - rT4).total_microseconds() * 1e-6,
// (int)good_left.size());
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for total\n", (rT5 - rT1).total_microseconds() * 1e-6);
// Timing information
PRINT_ALL("[TIME-KLT]: %.4f seconds for pyramid\n", (rT2 - rT1).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-KLT]: %.4f seconds for detection (%zu detected)\n", (rT3 - rT2).total_microseconds() * 1e-6,
(int)pts_last[cam_id].size() - pts_before_detect);
PRINT_ALL("[TIME-KLT]: %.4f seconds for temporal klt\n", (rT4 - rT3).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-KLT]: %.4f seconds for feature DB update (%d features)\n", (rT5 - rT4).total_microseconds() * 1e-6,
(int)good_left.size());
PRINT_ALL("[TIME-KLT]: %.4f seconds for total\n", (rT5 - rT1).total_microseconds() * 1e-6);
}

void TrackKLT::feed_stereo(const CameraData &message, size_t msg_id_left, size_t msg_id_right) {
Expand Down Expand Up @@ -239,6 +241,7 @@ void TrackKLT::feed_stereo(const CameraData &message, size_t msg_id_left, size_t

// First we should make that the last images have enough features so we can do KLT
// This will "top-off" our number of tracks so always have a constant number
int pts_before_detect = (int)pts_last[cam_id_left].size();
auto pts_left_old = pts_last[cam_id_left];
auto pts_right_old = pts_last[cam_id_right];
auto ids_left_old = ids_last[cam_id_left];
Expand Down Expand Up @@ -379,13 +382,14 @@ void TrackKLT::feed_stereo(const CameraData &message, size_t msg_id_left, size_t
rT6 = boost::posix_time::microsec_clock::local_time();

// // Timing information
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for pyramid\n", (rT2 - rT1).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for detection\n", (rT3 - rT2).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for temporal klt\n", (rT4 - rT3).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for stereo klt\n", (rT5 - rT4).total_microseconds() * 1e-6);
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for feature DB update (%d features)\n", (rT6 - rT5).total_microseconds() * 1e-6,
// (int)good_left.size());
// PRINT_DEBUG("[TIME-KLT]: %.4f seconds for total\n", (rT6 - rT1).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-KLT]: %.4f seconds for pyramid\n", (rT2 - rT1).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-KLT]: %.4f seconds for detection (%d detected)\n", (rT3 - rT2).total_microseconds() * 1e-6,
(int)pts_last[cam_id_left].size() - pts_before_detect);
PRINT_ALL("[TIME-KLT]: %.4f seconds for temporal klt\n", (rT4 - rT3).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-KLT]: %.4f seconds for stereo klt\n", (rT5 - rT4).total_microseconds() * 1e-6);
PRINT_ALL("[TIME-KLT]: %.4f seconds for feature DB update (%d features)\n", (rT6 - rT5).total_microseconds() * 1e-6,
(int)good_left.size());
PRINT_ALL("[TIME-KLT]: %.4f seconds for total\n", (rT6 - rT1).total_microseconds() * 1e-6);
}

void TrackKLT::perform_detection_monocular(const std::vector<cv::Mat> &img0pyr, const cv::Mat &mask0, std::vector<cv::KeyPoint> &pts0,
Expand Down
3 changes: 3 additions & 0 deletions ov_core/src/types/Landmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class Landmark : public Vec {
/// Boolean if this landmark should be marginalized out
bool should_marg = false;

/// Number of times the update has failed for this feature (we should remove if it fails a couple times!)
int update_fail_count = 0;

/// First normalized uv coordinate bearing of this measurement (used for single depth representation)
Eigen::Vector3d uv_norm_zero;

Expand Down
3 changes: 2 additions & 1 deletion ov_init/src/init/InertialInitializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void InertialInitializer::feed_imu(const ov_core::ImuData &message, double oldes
//});

// Loop through and delete imu messages that are older than our requested time
// std::cout << "INIT: imu_data.size() " << imu_data->size() << std::endl;
if (oldest_time != -1) {
auto it0 = imu_data->begin();
while (it0 != imu_data->end()) {
Expand All @@ -81,7 +82,7 @@ bool InertialInitializer::initialize(double &timestamp, Eigen::MatrixXd &covaria
}
}
}
double oldest_time = newest_cam_time - params.init_window_time - 0.01;
double oldest_time = newest_cam_time - params.init_window_time - 0.10;
if (newest_cam_time < 0 || oldest_time < 0) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion ov_msckf/launch/serial.launch
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<arg name="max_cameras" default="2" />
<arg name="use_stereo" default="true" />
<arg name="bag_start" default="0" /> <!-- v1-2: 0, mh1: 40, mh2: 35, mh3: 17.5, mh4-5: 15 -->
<arg name="dataset" default="V1_02_medium" /> <!-- V1_01_easy, V1_02_medium, V2_02_medium, dataset-room1_512_16 -->
<arg name="dataset" default="V1_02_medium" /> <!-- V1_01_easy, V1_02_medium, V1_03_difficult, V2_02_medium, dataset-room1_512_16 -->
<arg name="bag" default="/media/patrick/RPNG_DATA_6/$(arg config)/$(arg dataset).bag" />
<!-- <arg name="bag" default="/home/patrick/datasets/$(arg config)/$(arg dataset).bag" /> -->
<!-- <arg name="bag" default="/datasets/$(arg config)/$(arg dataset).bag" /> -->
Expand Down
28 changes: 21 additions & 7 deletions ov_msckf/src/core/VioManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,19 @@ void VioManager::feed_measurement_imu(const ov_core::ImuData &message) {
if (oldest_time > state->_timestamp) {
oldest_time = -1;
}
if (!is_initialized_vio) {
oldest_time = message.timestamp - params.init_options.init_window_time + state->_calib_dt_CAMtoIMU->value()(0) - 0.10;
}
propagator->feed_imu(message, oldest_time);

// Push back to our initializer
if (!is_initialized_vio) {
initializer->feed_imu(message, oldest_time);
}

// Push back to the zero velocity updater if we have it
if (is_initialized_vio && updaterZUPT != nullptr) {
// Push back to the zero velocity updater if it is enabled
// No need to push back if we are just doing the zv-update at the begining and we have moved
if (is_initialized_vio && updaterZUPT != nullptr && (!params.zupt_only_at_beginning || !has_moved_since_zupt)) {
updaterZUPT->feed_imu(message, oldest_time);
}
}
Expand Down Expand Up @@ -215,7 +219,10 @@ void VioManager::feed_measurement_simulation(double timestamp, const std::vector
did_zupt_update = updaterZUPT->try_update(state, timestamp);
}
if (did_zupt_update) {
assert_r(state->_timestamp == timestamp);
trackDATABASE->cleanup_measurements(timestamp);
propagator->clean_old_imu_measurements(timestamp + state->_calib_dt_CAMtoIMU->value()(0) - 0.10);
updaterZUPT->clean_old_imu_measurements(timestamp + state->_calib_dt_CAMtoIMU->value()(0) - 0.10);
return;
}
}
Expand Down Expand Up @@ -289,7 +296,10 @@ void VioManager::track_image_and_update(const ov_core::CameraData &message_const
did_zupt_update = updaterZUPT->try_update(state, message.timestamp);
}
if (did_zupt_update) {
assert_r(state->_timestamp == message.timestamp);
trackDATABASE->cleanup_measurements(message.timestamp);
propagator->clean_old_imu_measurements(message.timestamp + state->_calib_dt_CAMtoIMU->value()(0) - 0.10);
updaterZUPT->clean_old_imu_measurements(message.timestamp + state->_calib_dt_CAMtoIMU->value()(0) - 0.10);
return;
}
}
Expand Down Expand Up @@ -442,9 +452,10 @@ void VioManager::do_feature_propagate_update(const ov_core::CameraData &message)
}

// Loop through current SLAM features, we have tracks of them, grab them for this update!
// Note: if we have a slam feature that has lost tracking, then we should marginalize it out
// Note: we only enforce this if the current camera message is where the feature was seen from
// Note: if you do not use FEJ, these types of slam features *degrade* the estimator performance....
// NOTE: if we have a slam feature that has lost tracking, then we should marginalize it out
// NOTE: we only enforce this if the current camera message is where the feature was seen from
// NOTE: if you do not use FEJ, these types of slam features *degrade* the estimator performance....
// NOTE: we will also marginalize SLAM features if they have failed their update a couple times in a row
for (std::pair<const size_t, std::shared_ptr<Landmark>> &landmark : state->_features_SLAM) {
if (trackARUCO != nullptr) {
std::shared_ptr<Feature> feat1 = trackARUCO->get_feature_database()->get_feature(landmark.second->_featid);
Expand All @@ -459,6 +470,8 @@ void VioManager::do_feature_propagate_update(const ov_core::CameraData &message)
std::find(message.sensor_ids.begin(), message.sensor_ids.end(), landmark.second->_unique_camera_id) != message.sensor_ids.end();
if (feat2 == nullptr && current_unique_cam)
landmark.second->should_marg = true;
if (landmark.second->update_fail_count > 1)
landmark.second->should_marg = true;
}

// Lets marginalize out all old SLAM features here
Expand Down Expand Up @@ -492,15 +505,16 @@ void VioManager::do_feature_propagate_update(const ov_core::CameraData &message)
// Sort based on track length
// TODO: we should have better selection logic here (i.e. even feature distribution in the FOV etc..)
// TODO: right now features that are "lost" are at the front of this vector, while ones at the end are long-tracks
std::sort(featsup_MSCKF.begin(), featsup_MSCKF.end(), [](const std::shared_ptr<Feature> &a, const std::shared_ptr<Feature> &b) -> bool {
auto compare_feat = [](const std::shared_ptr<Feature> &a, const std::shared_ptr<Feature> &b) -> bool {
size_t asize = 0;
size_t bsize = 0;
for (const auto &pair : a->timestamps)
asize += pair.second.size();
for (const auto &pair : b->timestamps)
bsize += pair.second.size();
return asize < bsize;
});
};
std::sort(featsup_MSCKF.begin(), featsup_MSCKF.end(), compare_feat);

// Pass them to our MSCKF updater
// NOTE: if we have more then the max, we select the "best" ones (i.e. max tracks) for this update
Expand Down
7 changes: 4 additions & 3 deletions ov_msckf/src/ros/ROS1Visualizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ void ROS1Visualizer::setup_subscribers(std::shared_ptr<ov_core::YamlParser> pars
_nh->param<std::string>("topic_imu", topic_imu, "/imu0");
parser->parse_external("relative_config_imu", "imu0", "rostopic", topic_imu);
sub_imu = _nh->subscribe(topic_imu, 1000, &ROS1Visualizer::callback_inertial, this);
PRINT_INFO("subscribing to IMU: %s\n", topic_imu.c_str());

// Logic for sync stereo subscriber
// https://answers.ros.org/question/96346/subscribe-to-two-image_raws-with-one-function/?answer=96491#post-id-96491
Expand All @@ -174,8 +175,8 @@ void ROS1Visualizer::setup_subscribers(std::shared_ptr<ov_core::YamlParser> pars
sync_cam.push_back(sync);
sync_subs_cam.push_back(image_sub0);
sync_subs_cam.push_back(image_sub1);
PRINT_DEBUG("subscribing to cam (stereo): %s\n", cam_topic0.c_str());
PRINT_DEBUG("subscribing to cam (stereo): %s\n", cam_topic1.c_str());
PRINT_INFO("subscribing to cam (stereo): %s\n", cam_topic0.c_str());
PRINT_INFO("subscribing to cam (stereo): %s\n", cam_topic1.c_str());
} else {
// Now we should add any non-stereo callbacks here
for (int i = 0; i < _app->get_params().state_options.num_cameras; i++) {
Expand All @@ -185,7 +186,7 @@ void ROS1Visualizer::setup_subscribers(std::shared_ptr<ov_core::YamlParser> pars
parser->parse_external("relative_config_imucam", "cam" + std::to_string(i), "rostopic", cam_topic);
// create subscriber
subs_cam.push_back(_nh->subscribe<sensor_msgs::Image>(cam_topic, 10, boost::bind(&ROS1Visualizer::callback_monocular, this, _1, i)));
PRINT_DEBUG("subscribing to cam (mono): %s\n", cam_topic.c_str());
PRINT_INFO("subscribing to cam (mono): %s\n", cam_topic.c_str());
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions ov_msckf/src/ros/ROS2Visualizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ void ROS2Visualizer::setup_subscribers(std::shared_ptr<ov_core::YamlParser> pars
parser->parse_external("relative_config_imu", "imu0", "rostopic", topic_imu);
sub_imu = _node->create_subscription<sensor_msgs::msg::Imu>(topic_imu, rclcpp::SensorDataQoS(),
std::bind(&ROS2Visualizer::callback_inertial, this, std::placeholders::_1));
PRINT_INFO("subscribing to IMU: %s\n", topic_imu.c_str());

// Logic for sync stereo subscriber
// https://answers.ros.org/question/96346/subscribe-to-two-image_raws-with-one-function/?answer=96491#post-id-96491
Expand All @@ -193,8 +194,8 @@ void ROS2Visualizer::setup_subscribers(std::shared_ptr<ov_core::YamlParser> pars
sync_cam.push_back(sync);
sync_subs_cam.push_back(image_sub0);
sync_subs_cam.push_back(image_sub1);
PRINT_DEBUG("subscribing to cam (stereo): %s", cam_topic0.c_str());
PRINT_DEBUG("subscribing to cam (stereo): %s", cam_topic1.c_str());
PRINT_INFO("subscribing to cam (stereo): %s\n", cam_topic0.c_str());
PRINT_INFO("subscribing to cam (stereo): %s\n", cam_topic1.c_str());
} else {
// Now we should add any non-stereo callbacks here
for (int i = 0; i < _app->get_params().state_options.num_cameras; i++) {
Expand All @@ -209,7 +210,7 @@ void ROS2Visualizer::setup_subscribers(std::shared_ptr<ov_core::YamlParser> pars
auto sub = _node->create_subscription<sensor_msgs::msg::Image>(
cam_topic, 10, [this, i](const sensor_msgs::msg::Image::SharedPtr msg0) { callback_monocular(msg0, i); });
subs_cam.push_back(sub);
PRINT_DEBUG("subscribing to cam (mono): %s", cam_topic.c_str());
PRINT_INFO("subscribing to cam (mono): %s\n", cam_topic.c_str());
}
}
}
Expand Down
Loading

0 comments on commit eba3500

Please sign in to comment.