Compare commits
No commits in common. "c138034db0c47fe0ea5a2abe516acae02190dbf5" and "0d2bc2ca5b834ddd03504454d0a43b9f67c20455" have entirely different histories.
c138034db0
...
0d2bc2ca5b
|
@ -22,6 +22,7 @@ cache:
|
||||||
- /home/travis/docker/
|
- /home/travis/docker/
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
- ROS_RELEASE=kinetic DOCKER_CACHE_FILE=/home/travis/docker/kinetic-cache.tar.gz
|
||||||
- ROS_RELEASE=melodic DOCKER_CACHE_FILE=/home/travis/docker/melodic-cache.tar.gz
|
- ROS_RELEASE=melodic DOCKER_CACHE_FILE=/home/travis/docker/melodic-cache.tar.gz
|
||||||
- ROS_RELEASE=noetic DOCKER_CACHE_FILE=/home/travis/docker/noetic-cache.tar.gz
|
- ROS_RELEASE=noetic DOCKER_CACHE_FILE=/home/travis/docker/noetic-cache.tar.gz
|
||||||
|
|
||||||
|
@ -33,5 +34,5 @@ before_install:
|
||||||
|
|
||||||
install: true
|
install: true
|
||||||
script:
|
script:
|
||||||
- scripts/build_docker.sh $GITHUB_TOKEN
|
- docker build ${TRAVIS_BUILD_DIR} -t cartographer_ros:${ROS_RELEASE} -f Dockerfile.${ROS_RELEASE} --build-arg github_token=${GITHUB_TOKEN}
|
||||||
- scripts/save_docker_cache.sh
|
- scripts/save_docker_cache.sh
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
# Copyright 2016 The Cartographer Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
FROM osrf/ros:kinetic-desktop
|
||||||
|
|
||||||
|
ARG CARTOGRAPHER_VERSION=master
|
||||||
|
|
||||||
|
# We require a GitHub access token to be passed.
|
||||||
|
ARG github_token
|
||||||
|
|
||||||
|
# Xenial's base image doesn't ship with sudo.
|
||||||
|
RUN apt-get update && apt-get install -y sudo
|
||||||
|
|
||||||
|
# First, we invalidate the entire cache if cartographer-project/cartographer has
|
||||||
|
# changed. This file's content changes whenever master changes. See:
|
||||||
|
# http://stackoverflow.com/questions/36996046/how-to-prevent-dockerfile-caching-git-clone
|
||||||
|
ADD https://api.github.com/repos/cartographer-project/cartographer/git/refs/heads/master?access_token=$github_token \
|
||||||
|
cartographer_ros/cartographer_version.json
|
||||||
|
|
||||||
|
# wstool needs the updated rosinstall file to clone the correct repos.
|
||||||
|
COPY cartographer_ros.rosinstall cartographer_ros/
|
||||||
|
COPY scripts/prepare_catkin_workspace.sh cartographer_ros/scripts/
|
||||||
|
RUN CARTOGRAPHER_VERSION=$CARTOGRAPHER_VERSION \
|
||||||
|
cartographer_ros/scripts/prepare_catkin_workspace.sh
|
||||||
|
|
||||||
|
# rosdep needs the updated package.xml files to install the correct debs.
|
||||||
|
COPY cartographer_ros/package.xml catkin_ws/src/cartographer_ros/cartographer_ros/
|
||||||
|
COPY cartographer_ros_msgs/package.xml catkin_ws/src/cartographer_ros/cartographer_ros_msgs/
|
||||||
|
COPY cartographer_rviz/package.xml catkin_ws/src/cartographer_ros/cartographer_rviz/
|
||||||
|
COPY scripts/install_debs.sh cartographer_ros/scripts/
|
||||||
|
RUN cartographer_ros/scripts/install_debs.sh
|
||||||
|
|
||||||
|
# Install Abseil and proto3.
|
||||||
|
RUN /catkin_ws/src/cartographer/scripts/install_abseil.sh
|
||||||
|
RUN /catkin_ws/src/cartographer/scripts/install_proto3.sh
|
||||||
|
|
||||||
|
# Build, install, and test all packages individually to allow caching. The
|
||||||
|
# ordering of these steps must match the topological package ordering as
|
||||||
|
# determined by Catkin.
|
||||||
|
COPY scripts/install.sh cartographer_ros/scripts/
|
||||||
|
COPY scripts/catkin_test_results.sh cartographer_ros/scripts/
|
||||||
|
|
||||||
|
RUN cartographer_ros/scripts/install.sh --pkg cartographer && \
|
||||||
|
cartographer_ros/scripts/install.sh --pkg cartographer --make-args test
|
||||||
|
|
||||||
|
COPY cartographer_ros_msgs catkin_ws/src/cartographer_ros/cartographer_ros_msgs/
|
||||||
|
RUN cartographer_ros/scripts/install.sh --pkg cartographer_ros_msgs && \
|
||||||
|
cartographer_ros/scripts/install.sh --pkg cartographer_ros_msgs \
|
||||||
|
--catkin-make-args run_tests && \
|
||||||
|
cartographer_ros/scripts/catkin_test_results.sh build_isolated/cartographer_ros_msgs
|
||||||
|
|
||||||
|
COPY cartographer_ros catkin_ws/src/cartographer_ros/cartographer_ros/
|
||||||
|
RUN cartographer_ros/scripts/install.sh --pkg cartographer_ros && \
|
||||||
|
cartographer_ros/scripts/install.sh --pkg cartographer_ros \
|
||||||
|
--catkin-make-args run_tests && \
|
||||||
|
cartographer_ros/scripts/catkin_test_results.sh build_isolated/cartographer_ros
|
||||||
|
|
||||||
|
COPY cartographer_rviz catkin_ws/src/cartographer_ros/cartographer_rviz/
|
||||||
|
RUN cartographer_ros/scripts/install.sh --pkg cartographer_rviz && \
|
||||||
|
cartographer_ros/scripts/install.sh --pkg cartographer_rviz \
|
||||||
|
--catkin-make-args run_tests && \
|
||||||
|
cartographer_ros/scripts/catkin_test_results.sh build_isolated/cartographer_rviz
|
||||||
|
|
||||||
|
COPY scripts/ros_entrypoint.sh /
|
||||||
|
|
||||||
|
RUN rm -rf /var/lib/apt/lists/*
|
||||||
|
# A BTRFS bug may prevent us from cleaning up these directories.
|
||||||
|
# https://btrfs.wiki.kernel.org/index.php/Problem_FAQ#I_cannot_delete_an_empty_directory
|
||||||
|
RUN rm -rf cartographer_ros catkin_ws || true
|
|
@ -15,22 +15,24 @@
|
||||||
FROM osrf/ros:melodic-desktop
|
FROM osrf/ros:melodic-desktop
|
||||||
|
|
||||||
ARG CARTOGRAPHER_VERSION=master
|
ARG CARTOGRAPHER_VERSION=master
|
||||||
ARG CARTOGRAPHER_SHA=LATEST
|
|
||||||
|
# We require a GitHub access token to be passed.
|
||||||
|
ARG github_token
|
||||||
|
|
||||||
# Bionic's base image doesn't ship with sudo.
|
# Bionic's base image doesn't ship with sudo.
|
||||||
RUN apt-get update && apt-get install -y sudo
|
RUN apt-get update && apt-get install -y sudo
|
||||||
|
|
||||||
|
# First, we invalidate the entire cache if cartographer-project/cartographer has
|
||||||
|
# changed. This file's content changes whenever master changes. See:
|
||||||
|
# http://stackoverflow.com/questions/36996046/how-to-prevent-dockerfile-caching-git-clone
|
||||||
|
ADD https://api.github.com/repos/cartographer-project/cartographer/git/refs/heads/master?access_token=$github_token \
|
||||||
|
cartographer_ros/cartographer_version.json
|
||||||
|
|
||||||
# wstool needs the updated rosinstall file to clone the correct repos.
|
# wstool needs the updated rosinstall file to clone the correct repos.
|
||||||
COPY cartographer_ros.rosinstall cartographer_ros/
|
COPY cartographer_ros.rosinstall cartographer_ros/
|
||||||
COPY scripts/prepare_catkin_workspace.sh cartographer_ros/scripts/
|
COPY scripts/prepare_catkin_workspace.sh cartographer_ros/scripts/
|
||||||
|
RUN CARTOGRAPHER_VERSION=$CARTOGRAPHER_VERSION \
|
||||||
# First, we invalidate the entire cache if cartographer-project/cartographer has
|
cartographer_ros/scripts/prepare_catkin_workspace.sh
|
||||||
# changed. CARTOGRAPHER_SHA ARG content changes whenever master changes. See:
|
|
||||||
# http://stackoverflow.com/questions/36996046/how-to-prevent-dockerfile-caching-git-clone
|
|
||||||
RUN CARTOGRAPHER_SHA=$CARTOGRAPHER_SHA \
|
|
||||||
CARTOGRAPHER_VERSION=$CARTOGRAPHER_VERSION \
|
|
||||||
cartographer_ros/scripts/prepare_catkin_workspace.sh && \
|
|
||||||
sed -i -e "s%<depend>libabsl-dev</depend>%<\!--<depend>libabsl-dev</depend>-->%g" catkin_ws/src/cartographer/package.xml
|
|
||||||
|
|
||||||
# rosdep needs the updated package.xml files to install the correct debs.
|
# rosdep needs the updated package.xml files to install the correct debs.
|
||||||
COPY cartographer_ros/package.xml catkin_ws/src/cartographer_ros/cartographer_ros/
|
COPY cartographer_ros/package.xml catkin_ws/src/cartographer_ros/cartographer_ros/
|
||||||
|
|
|
@ -15,7 +15,9 @@
|
||||||
FROM osrf/ros:noetic-desktop
|
FROM osrf/ros:noetic-desktop
|
||||||
|
|
||||||
ARG CARTOGRAPHER_VERSION=master
|
ARG CARTOGRAPHER_VERSION=master
|
||||||
ARG CARTOGRAPHER_SHA=LATEST
|
|
||||||
|
# We require a GitHub access token to be passed.
|
||||||
|
ARG github_token
|
||||||
|
|
||||||
# Prevent any interaction required by apt-get.
|
# Prevent any interaction required by apt-get.
|
||||||
# https://stackoverflow.com/questions/22466255
|
# https://stackoverflow.com/questions/22466255
|
||||||
|
@ -24,17 +26,17 @@ ARG DEBIAN_FRONTEND=noninteractive
|
||||||
# ROS Noetic's base image doesn't ship with sudo and git.
|
# ROS Noetic's base image doesn't ship with sudo and git.
|
||||||
RUN apt-get update && apt-get install -y sudo git
|
RUN apt-get update && apt-get install -y sudo git
|
||||||
|
|
||||||
|
# First, we invalidate the entire cache if cartographer-project/cartographer has
|
||||||
|
# changed. This file's content changes whenever master changes. See:
|
||||||
|
# http://stackoverflow.com/questions/36996046/how-to-prevent-dockerfile-caching-git-clone
|
||||||
|
ADD https://api.github.com/repos/cartographer-project/cartographer/git/refs/heads/master?access_token=$github_token \
|
||||||
|
cartographer_ros/cartographer_version.json
|
||||||
|
|
||||||
# wstool needs the updated rosinstall file to clone the correct repos.
|
# wstool needs the updated rosinstall file to clone the correct repos.
|
||||||
COPY cartographer_ros.rosinstall cartographer_ros/
|
COPY cartographer_ros.rosinstall cartographer_ros/
|
||||||
COPY scripts/prepare_catkin_workspace.sh cartographer_ros/scripts/
|
COPY scripts/prepare_catkin_workspace.sh cartographer_ros/scripts/
|
||||||
|
RUN CARTOGRAPHER_VERSION=$CARTOGRAPHER_VERSION \
|
||||||
# First, we invalidate the entire cache if cartographer-project/cartographer has
|
cartographer_ros/scripts/prepare_catkin_workspace.sh
|
||||||
# changed. CARTOGRAPHER_SHA ARG content changes whenever master changes. See:
|
|
||||||
# http://stackoverflow.com/questions/36996046/how-to-prevent-dockerfile-caching-git-clone
|
|
||||||
RUN CARTOGRAPHER_SHA=$CARTOGRAPHER_SHA \
|
|
||||||
CARTOGRAPHER_VERSION=$CARTOGRAPHER_VERSION \
|
|
||||||
cartographer_ros/scripts/prepare_catkin_workspace.sh && \
|
|
||||||
sed -i -e "s%<depend>libabsl-dev</depend>%<\!--<depend>libabsl-dev</depend>-->%g" catkin_ws/src/cartographer/package.xml
|
|
||||||
|
|
||||||
# rosdep needs the updated package.xml files to install the correct debs.
|
# rosdep needs the updated package.xml files to install the correct debs.
|
||||||
COPY cartographer_ros/package.xml catkin_ws/src/cartographer_ros/cartographer_ros/
|
COPY cartographer_ros/package.xml catkin_ws/src/cartographer_ros/cartographer_ros/
|
||||||
|
|
|
@ -45,10 +45,10 @@ at `our Contribution page`_.
|
||||||
|
|
||||||
.. _our Contribution page: https://github.com/cartographer-project/cartographer_ros/blob/master/CONTRIBUTING.md
|
.. _our Contribution page: https://github.com/cartographer-project/cartographer_ros/blob/master/CONTRIBUTING.md
|
||||||
|
|
||||||
.. |build| image:: https://app.travis-ci.com/cartographer-project/cartographer_ros.svg?branch=master
|
.. |build| image:: https://travis-ci.org/cartographer-project/cartographer_ros.svg?branch=master
|
||||||
:alt: Build Status
|
:alt: Build Status
|
||||||
:scale: 100%
|
:scale: 100%
|
||||||
:target: https://app.travis-ci.com/cartographer-project/cartographer_ros
|
:target: https://travis-ci.org/cartographer-project/cartographer_ros
|
||||||
.. |docs| image:: https://readthedocs.org/projects/google-cartographer-ros/badge/?version=latest
|
.. |docs| image:: https://readthedocs.org/projects/google-cartographer-ros/badge/?version=latest
|
||||||
:alt: Documentation Status
|
:alt: Documentation Status
|
||||||
:scale: 100%
|
:scale: 100%
|
||||||
|
|
|
@ -146,7 +146,7 @@ AssetsWriter::AssetsWriter(const std::string& pose_graph_filename,
|
||||||
<< "Pose graphs contains " << pose_graph_.trajectory_size()
|
<< "Pose graphs contains " << pose_graph_.trajectory_size()
|
||||||
<< " trajectories while " << bag_filenames_.size()
|
<< " trajectories while " << bag_filenames_.size()
|
||||||
<< " bags were provided. This tool requires one bag for each "
|
<< " bags were provided. This tool requires one bag for each "
|
||||||
"trajectory in the same order as the corresponding trajectories in the "
|
"trajectory in the same order as the correponding trajectories in the "
|
||||||
"pose graph proto.";
|
"pose graph proto.";
|
||||||
|
|
||||||
// This vector must outlive the pipeline.
|
// This vector must outlive the pipeline.
|
||||||
|
|
|
@ -138,7 +138,6 @@ int MapBuilderBridge::AddTrajectory(
|
||||||
CHECK_EQ(sensor_bridges_.count(trajectory_id), 0);
|
CHECK_EQ(sensor_bridges_.count(trajectory_id), 0);
|
||||||
sensor_bridges_[trajectory_id] = absl::make_unique<SensorBridge>(
|
sensor_bridges_[trajectory_id] = absl::make_unique<SensorBridge>(
|
||||||
trajectory_options.num_subdivisions_per_laser_scan,
|
trajectory_options.num_subdivisions_per_laser_scan,
|
||||||
trajectory_options.ignore_out_of_order_messages,
|
|
||||||
trajectory_options.tracking_frame,
|
trajectory_options.tracking_frame,
|
||||||
node_options_.lookup_transform_timeout_sec, tf_buffer_,
|
node_options_.lookup_transform_timeout_sec, tf_buffer_,
|
||||||
map_builder_->GetTrajectoryBuilder(trajectory_id));
|
map_builder_->GetTrajectoryBuilder(trajectory_id));
|
||||||
|
|
|
@ -771,8 +771,7 @@ void Node::HandleOdometryMessage(const int trajectory_id,
|
||||||
}
|
}
|
||||||
auto sensor_bridge_ptr = map_builder_bridge_.sensor_bridge(trajectory_id);
|
auto sensor_bridge_ptr = map_builder_bridge_.sensor_bridge(trajectory_id);
|
||||||
auto odometry_data_ptr = sensor_bridge_ptr->ToOdometryData(msg);
|
auto odometry_data_ptr = sensor_bridge_ptr->ToOdometryData(msg);
|
||||||
if (odometry_data_ptr != nullptr &&
|
if (odometry_data_ptr != nullptr) {
|
||||||
!sensor_bridge_ptr->IgnoreMessage(sensor_id, odometry_data_ptr->time)) {
|
|
||||||
extrapolators_.at(trajectory_id).AddOdometryData(*odometry_data_ptr);
|
extrapolators_.at(trajectory_id).AddOdometryData(*odometry_data_ptr);
|
||||||
}
|
}
|
||||||
sensor_bridge_ptr->HandleOdometryMessage(sensor_id, msg);
|
sensor_bridge_ptr->HandleOdometryMessage(sensor_id, msg);
|
||||||
|
@ -809,8 +808,7 @@ void Node::HandleImuMessage(const int trajectory_id,
|
||||||
}
|
}
|
||||||
auto sensor_bridge_ptr = map_builder_bridge_.sensor_bridge(trajectory_id);
|
auto sensor_bridge_ptr = map_builder_bridge_.sensor_bridge(trajectory_id);
|
||||||
auto imu_data_ptr = sensor_bridge_ptr->ToImuData(msg);
|
auto imu_data_ptr = sensor_bridge_ptr->ToImuData(msg);
|
||||||
if (imu_data_ptr != nullptr &&
|
if (imu_data_ptr != nullptr) {
|
||||||
!sensor_bridge_ptr->IgnoreMessage(sensor_id, imu_data_ptr->time)) {
|
|
||||||
extrapolators_.at(trajectory_id).AddImuData(*imu_data_ptr);
|
extrapolators_.at(trajectory_id).AddImuData(*imu_data_ptr);
|
||||||
}
|
}
|
||||||
sensor_bridge_ptr->HandleImuMessage(sensor_id, msg);
|
sensor_bridge_ptr->HandleImuMessage(sensor_id, msg);
|
||||||
|
|
|
@ -41,11 +41,10 @@ const std::string& CheckNoLeadingSlash(const std::string& frame_id) {
|
||||||
|
|
||||||
SensorBridge::SensorBridge(
|
SensorBridge::SensorBridge(
|
||||||
const int num_subdivisions_per_laser_scan,
|
const int num_subdivisions_per_laser_scan,
|
||||||
const bool ignore_out_of_order_messages, const std::string& tracking_frame,
|
const std::string& tracking_frame,
|
||||||
const double lookup_transform_timeout_sec, tf2_ros::Buffer* const tf_buffer,
|
const double lookup_transform_timeout_sec, tf2_ros::Buffer* const tf_buffer,
|
||||||
carto::mapping::TrajectoryBuilderInterface* const trajectory_builder)
|
carto::mapping::TrajectoryBuilderInterface* const trajectory_builder)
|
||||||
: num_subdivisions_per_laser_scan_(num_subdivisions_per_laser_scan),
|
: num_subdivisions_per_laser_scan_(num_subdivisions_per_laser_scan),
|
||||||
ignore_out_of_order_messages_(ignore_out_of_order_messages),
|
|
||||||
tf_bridge_(tracking_frame, lookup_transform_timeout_sec, tf_buffer),
|
tf_bridge_(tracking_frame, lookup_transform_timeout_sec, tf_buffer),
|
||||||
trajectory_builder_(trajectory_builder) {}
|
trajectory_builder_(trajectory_builder) {}
|
||||||
|
|
||||||
|
@ -62,31 +61,11 @@ std::unique_ptr<carto::sensor::OdometryData> SensorBridge::ToOdometryData(
|
||||||
time, ToRigid3d(msg->pose.pose) * sensor_to_tracking->inverse()});
|
time, ToRigid3d(msg->pose.pose) * sensor_to_tracking->inverse()});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SensorBridge::IgnoreMessage(const std::string& sensor_id,
|
|
||||||
cartographer::common::Time sensor_time) {
|
|
||||||
if (!ignore_out_of_order_messages_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto it = latest_sensor_time_.find(sensor_id);
|
|
||||||
if (it == latest_sensor_time_.end()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return sensor_time <= it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SensorBridge::HandleOdometryMessage(
|
void SensorBridge::HandleOdometryMessage(
|
||||||
const std::string& sensor_id, const nav_msgs::Odometry::ConstPtr& msg) {
|
const std::string& sensor_id, const nav_msgs::Odometry::ConstPtr& msg) {
|
||||||
std::unique_ptr<carto::sensor::OdometryData> odometry_data =
|
std::unique_ptr<carto::sensor::OdometryData> odometry_data =
|
||||||
ToOdometryData(msg);
|
ToOdometryData(msg);
|
||||||
if (odometry_data != nullptr) {
|
if (odometry_data != nullptr) {
|
||||||
if (IgnoreMessage(sensor_id, odometry_data->time)) {
|
|
||||||
LOG(WARNING) << "Ignored odometry message from sensor " << sensor_id
|
|
||||||
<< " because sensor time " << odometry_data->time
|
|
||||||
<< " is not before last odometry message time "
|
|
||||||
<< latest_sensor_time_[sensor_id];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
latest_sensor_time_[sensor_id] = odometry_data->time;
|
|
||||||
trajectory_builder_->AddSensorData(
|
trajectory_builder_->AddSensorData(
|
||||||
sensor_id,
|
sensor_id,
|
||||||
carto::sensor::OdometryData{odometry_data->time, odometry_data->pose});
|
carto::sensor::OdometryData{odometry_data->time, odometry_data->pose});
|
||||||
|
@ -167,14 +146,6 @@ void SensorBridge::HandleImuMessage(const std::string& sensor_id,
|
||||||
const sensor_msgs::Imu::ConstPtr& msg) {
|
const sensor_msgs::Imu::ConstPtr& msg) {
|
||||||
std::unique_ptr<carto::sensor::ImuData> imu_data = ToImuData(msg);
|
std::unique_ptr<carto::sensor::ImuData> imu_data = ToImuData(msg);
|
||||||
if (imu_data != nullptr) {
|
if (imu_data != nullptr) {
|
||||||
if (IgnoreMessage(sensor_id, imu_data->time)) {
|
|
||||||
LOG(WARNING) << "Ignored IMU message from sensor " << sensor_id
|
|
||||||
<< " because sensor time " << imu_data->time
|
|
||||||
<< " is not before last IMU message time "
|
|
||||||
<< latest_sensor_time_[sensor_id];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
latest_sensor_time_[sensor_id] = imu_data->time;
|
|
||||||
trajectory_builder_->AddSensorData(
|
trajectory_builder_->AddSensorData(
|
||||||
sensor_id,
|
sensor_id,
|
||||||
carto::sensor::ImuData{imu_data->time, imu_data->linear_acceleration,
|
carto::sensor::ImuData{imu_data->time, imu_data->linear_acceleration,
|
||||||
|
@ -261,14 +232,6 @@ void SensorBridge::HandleRangefinder(
|
||||||
const auto sensor_to_tracking =
|
const auto sensor_to_tracking =
|
||||||
tf_bridge_.LookupToTracking(time, CheckNoLeadingSlash(frame_id));
|
tf_bridge_.LookupToTracking(time, CheckNoLeadingSlash(frame_id));
|
||||||
if (sensor_to_tracking != nullptr) {
|
if (sensor_to_tracking != nullptr) {
|
||||||
if (IgnoreMessage(sensor_id, time)) {
|
|
||||||
LOG(WARNING) << "Ignored Rangefinder message from sensor " << sensor_id
|
|
||||||
<< " because sensor time " << time
|
|
||||||
<< " is not before last Rangefinder message time "
|
|
||||||
<< latest_sensor_time_[sensor_id];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
latest_sensor_time_[sensor_id] = time;
|
|
||||||
trajectory_builder_->AddSensorData(
|
trajectory_builder_->AddSensorData(
|
||||||
sensor_id, carto::sensor::TimedPointCloudData{
|
sensor_id, carto::sensor::TimedPointCloudData{
|
||||||
time, sensor_to_tracking->translation().cast<float>(),
|
time, sensor_to_tracking->translation().cast<float>(),
|
||||||
|
|
|
@ -43,9 +43,8 @@ namespace cartographer_ros {
|
||||||
class SensorBridge {
|
class SensorBridge {
|
||||||
public:
|
public:
|
||||||
explicit SensorBridge(
|
explicit SensorBridge(
|
||||||
int num_subdivisions_per_laser_scan, bool ignore_out_of_order_messages,
|
int num_subdivisions_per_laser_scan, const std::string& tracking_frame,
|
||||||
const std::string& tracking_frame, double lookup_transform_timeout_sec,
|
double lookup_transform_timeout_sec, tf2_ros::Buffer* tf_buffer,
|
||||||
tf2_ros::Buffer* tf_buffer,
|
|
||||||
::cartographer::mapping::TrajectoryBuilderInterface* trajectory_builder);
|
::cartographer::mapping::TrajectoryBuilderInterface* trajectory_builder);
|
||||||
|
|
||||||
SensorBridge(const SensorBridge&) = delete;
|
SensorBridge(const SensorBridge&) = delete;
|
||||||
|
@ -74,8 +73,6 @@ class SensorBridge {
|
||||||
const sensor_msgs::PointCloud2::ConstPtr& msg);
|
const sensor_msgs::PointCloud2::ConstPtr& msg);
|
||||||
|
|
||||||
const TfBridge& tf_bridge() const;
|
const TfBridge& tf_bridge() const;
|
||||||
bool IgnoreMessage(const std::string& sensor_id,
|
|
||||||
::cartographer::common::Time sensor_time);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void HandleLaserScan(
|
void HandleLaserScan(
|
||||||
|
@ -88,10 +85,8 @@ class SensorBridge {
|
||||||
const ::cartographer::sensor::TimedPointCloud& ranges);
|
const ::cartographer::sensor::TimedPointCloud& ranges);
|
||||||
|
|
||||||
const int num_subdivisions_per_laser_scan_;
|
const int num_subdivisions_per_laser_scan_;
|
||||||
const bool ignore_out_of_order_messages_;
|
|
||||||
std::map<std::string, cartographer::common::Time>
|
std::map<std::string, cartographer::common::Time>
|
||||||
sensor_to_previous_subdivision_time_;
|
sensor_to_previous_subdivision_time_;
|
||||||
std::map<std::string, cartographer::common::Time> latest_sensor_time_;
|
|
||||||
const TfBridge tf_bridge_;
|
const TfBridge tf_bridge_;
|
||||||
::cartographer::mapping::TrajectoryBuilderInterface* const
|
::cartographer::mapping::TrajectoryBuilderInterface* const
|
||||||
trajectory_builder_;
|
trajectory_builder_;
|
||||||
|
|
|
@ -76,12 +76,6 @@ TrajectoryOptions CreateTrajectoryOptions(
|
||||||
lua_parameter_dictionary->GetDouble("imu_sampling_ratio");
|
lua_parameter_dictionary->GetDouble("imu_sampling_ratio");
|
||||||
options.landmarks_sampling_ratio =
|
options.landmarks_sampling_ratio =
|
||||||
lua_parameter_dictionary->GetDouble("landmarks_sampling_ratio");
|
lua_parameter_dictionary->GetDouble("landmarks_sampling_ratio");
|
||||||
if (lua_parameter_dictionary->HasKey("ignore_out_of_order")) {
|
|
||||||
options.ignore_out_of_order_messages =
|
|
||||||
lua_parameter_dictionary->GetBool("ignore_out_of_order");
|
|
||||||
} else {
|
|
||||||
options.ignore_out_of_order_messages = false;
|
|
||||||
}
|
|
||||||
CheckTrajectoryOptions(options);
|
CheckTrajectoryOptions(options);
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ struct TrajectoryOptions {
|
||||||
bool use_nav_sat;
|
bool use_nav_sat;
|
||||||
bool use_landmarks;
|
bool use_landmarks;
|
||||||
bool publish_frame_projected_to_2d;
|
bool publish_frame_projected_to_2d;
|
||||||
bool ignore_out_of_order_messages;
|
|
||||||
int num_laser_scans;
|
int num_laser_scans;
|
||||||
int num_multi_echo_laser_scans;
|
int num_multi_echo_laser_scans;
|
||||||
int num_subdivisions_per_laser_scan;
|
int num_subdivisions_per_laser_scan;
|
||||||
|
|
|
@ -153,7 +153,7 @@ Sources of data include occupied space (points from the scan), translation and r
|
||||||
|
|
||||||
.. code-block:: lua
|
.. code-block:: lua
|
||||||
|
|
||||||
TRAJECTORY_BUILDER_2D.ceres_scan_matcher.occupied_space_weight
|
TRAJECTORY_BUILDER_3D.ceres_scan_matcher.occupied_space_weight
|
||||||
TRAJECTORY_BUILDER_3D.ceres_scan_matcher.occupied_space_weight_0
|
TRAJECTORY_BUILDER_3D.ceres_scan_matcher.occupied_space_weight_0
|
||||||
TRAJECTORY_BUILDER_3D.ceres_scan_matcher.occupied_space_weight_1
|
TRAJECTORY_BUILDER_3D.ceres_scan_matcher.occupied_space_weight_1
|
||||||
TRAJECTORY_BUILDER_nD.ceres_scan_matcher.translation_weight
|
TRAJECTORY_BUILDER_nD.ceres_scan_matcher.translation_weight
|
||||||
|
@ -253,7 +253,7 @@ Scan matching starts by aligning far points of the low resolution point cloud wi
|
||||||
Global SLAM
|
Global SLAM
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
While the local SLAM generates its succession of submaps, a global optimization (usually referred to as "*the optimization problem*" or "*sparse pose adjustment*") task runs in background.
|
While the local SLAM generates its succession of submaps, a global optimization (usually refered to as "*the optimization problem*" or "*sparse pose adjustment*") task runs in background.
|
||||||
Its role is to re-arrange submaps between each other so that they form a coherent global map.
|
Its role is to re-arrange submaps between each other so that they form a coherent global map.
|
||||||
For instance, this optimization is in charge of altering the currently built trajectory to properly align submaps with regards to loop closures.
|
For instance, this optimization is in charge of altering the currently built trajectory to properly align submaps with regards to loop closures.
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ The optimization is run in batches once a certain number of trajectory nodes was
|
||||||
|
|
||||||
The global SLAM is a kind of "*GraphSLAM*", it is essentially a pose graph optimization which works by building **constraints** between **nodes** and submaps and then optimizing the resulting constraints graph.
|
The global SLAM is a kind of "*GraphSLAM*", it is essentially a pose graph optimization which works by building **constraints** between **nodes** and submaps and then optimizing the resulting constraints graph.
|
||||||
Constraints can intuitively be thought of as little ropes tying all nodes together.
|
Constraints can intuitively be thought of as little ropes tying all nodes together.
|
||||||
The sparse pose adjustment fastens those ropes altogether.
|
The sparse pose adjustement fastens those ropes altogether.
|
||||||
The resulting net is called the "*pose graph*".
|
The resulting net is called the "*pose graph*".
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
@ -278,7 +278,7 @@ The resulting net is called the "*pose graph*".
|
||||||
|
|
||||||
- Non-global constraints (also known as intra submaps constraints) are built automatically between nodes that are closely following each other on a trajectory.
|
- Non-global constraints (also known as intra submaps constraints) are built automatically between nodes that are closely following each other on a trajectory.
|
||||||
Intuitively, those "*non-global ropes*" keep the local structure of the trajectory coherent.
|
Intuitively, those "*non-global ropes*" keep the local structure of the trajectory coherent.
|
||||||
- Global constraints (also referred to as loop closure constraints or inter submaps constraints) are regularly searched between a new submap and previous nodes that are considered "*close enough*" in space (part of a certain **search window**) and a strong fit (a good match when running scan matching).
|
- Global constraints (also referred to as loop closure constraints or inter submaps contraints) are regularly searched between a new submap and previous nodes that are considered "*close enough*" in space (part of a certain **search window**) and a strong fit (a good match when running scan matching).
|
||||||
Intuitively, those "*global ropes*" introduce knots in the structure and firmly bring two strands closer.
|
Intuitively, those "*global ropes*" introduce knots in the structure and firmly bring two strands closer.
|
||||||
|
|
||||||
.. code-block:: lua
|
.. code-block:: lua
|
||||||
|
@ -338,7 +338,7 @@ The weights and Ceres options can be configured as described in the :ref:`local-
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
One can find useful information about the residuals used in the optimization problem by toggling ``POSE_GRAPH.log_residual_histograms``
|
One can find useful information about the residuals used in the optimization problem by toggling ``POSE_GRAPH.max_num_final_iterations``
|
||||||
|
|
||||||
As part of its IMU residual, the optimization problem gives some flexibility to the IMU pose and, by default, Ceres is free to optimize the extrinsic calibration between your IMU and tracking frame.
|
As part of its IMU residual, the optimization problem gives some flexibility to the IMU pose and, by default, Ceres is free to optimize the extrinsic calibration between your IMU and tracking frame.
|
||||||
If you don't trust your IMU pose, the results of Ceres' global optimization can be logged and used to improve your extrinsic calibration.
|
If you don't trust your IMU pose, the results of Ceres' global optimization can be logged and used to improve your extrinsic calibration.
|
||||||
|
|
|
@ -23,6 +23,7 @@ The Cartographer ROS requirements are the same as `the ones from Cartographer`_.
|
||||||
|
|
||||||
The following `ROS distributions`_ are currently supported:
|
The following `ROS distributions`_ are currently supported:
|
||||||
|
|
||||||
|
* Kinetic
|
||||||
* Melodic
|
* Melodic
|
||||||
* Noetic
|
* Noetic
|
||||||
|
|
||||||
|
@ -70,6 +71,8 @@ The command 'sudo rosdep init' will print an error if you have already executed
|
||||||
rosdep update
|
rosdep update
|
||||||
rosdep install --from-paths src --ignore-src --rosdistro=${ROS_DISTRO} -y
|
rosdep install --from-paths src --ignore-src --rosdistro=${ROS_DISTRO} -y
|
||||||
|
|
||||||
|
# Only on Ubuntu 16 / ROS Kinetic: src/cartographer/scripts/install_proto3.sh
|
||||||
|
|
||||||
Cartographer uses the `abseil-cpp`_ library that needs to be manually installed using this script:
|
Cartographer uses the `abseil-cpp`_ library that needs to be manually installed using this script:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
|
@ -69,7 +69,7 @@ use_nav_sat
|
||||||
use_landmarks
|
use_landmarks
|
||||||
If enabled, subscribes to `cartographer_ros_msgs/LandmarkList`_ on the topic
|
If enabled, subscribes to `cartographer_ros_msgs/LandmarkList`_ on the topic
|
||||||
"landmarks". Landmarks must be provided, as `cartographer_ros_msgs/LandmarkEntry`_ within `cartographer_ros_msgs/LandmarkList`_. If `cartographer_ros_msgs/LandmarkEntry`_ data is provided the information
|
"landmarks". Landmarks must be provided, as `cartographer_ros_msgs/LandmarkEntry`_ within `cartographer_ros_msgs/LandmarkList`_. If `cartographer_ros_msgs/LandmarkEntry`_ data is provided the information
|
||||||
will be included in the SLAM according to the ID of the `cartographer_ros_msgs/LandmarkEntry`_. The `cartographer_ros_msgs/LandmarkList`_ should be provided at a sample rate comparable to the other sensors. The list can be empty but has to be provided because Cartographer strictly time orders sensor data in order to make the landmarks deterministic. However it is possible to set the trajectory builder option "collate_landmarks" to false and allow for a non-deterministic but also non-blocking approach.
|
will be included in the SLAM accoding to the ID of the `cartographer_ros_msgs/LandmarkEntry`_. The `cartographer_ros_msgs/LandmarkList`_ should be provided at a sample rate comparable to the other sensors. The list can be empty but has to be provided because Cartographer strictly time orders sensor data in order to make the landmarks deterministic. However it is possible to set the trajectory builder option "collate_landmarks" to false and allow for a non-deterministic but also non-blocking approach.
|
||||||
|
|
||||||
num_laser_scans
|
num_laser_scans
|
||||||
Number of laser scan topics to subscribe to. Subscribes to
|
Number of laser scan topics to subscribe to. Subscribes to
|
||||||
|
@ -106,7 +106,7 @@ pose_publish_period_sec
|
||||||
publish_to_tf
|
publish_to_tf
|
||||||
Enable or disable providing of TF transforms.
|
Enable or disable providing of TF transforms.
|
||||||
|
|
||||||
publish_tracked_pose
|
publish_tracked_pose_msg
|
||||||
Enable publishing of tracked pose as a `geometry_msgs/PoseStamped`_ to topic "tracked_pose".
|
Enable publishing of tracked pose as a `geometry_msgs/PoseStamped`_ to topic "tracked_pose".
|
||||||
|
|
||||||
trajectory_publish_period_sec
|
trajectory_publish_period_sec
|
||||||
|
|
|
@ -19,7 +19,11 @@ Getting involved
|
||||||
Cartographer is developed in the open and allows anyone to contribute to the project.
|
Cartographer is developed in the open and allows anyone to contribute to the project.
|
||||||
There are multiple ways to get involved!
|
There are multiple ways to get involved!
|
||||||
|
|
||||||
If you have question or think you've found an issue in Cartographer, you are welcome to open a `GitHub issue`_.
|
If you want to stay tuned with announcements (such as new major releases), you can join `the Cartographer mailing list`_ although you can not interact with this mailing list anymore.
|
||||||
|
|
||||||
|
.. _the Cartographer mailing list: https://groups.google.com/forum/#!forum/google-cartographer
|
||||||
|
|
||||||
|
If you think you've found an issue in Cartographer, you are welcome to open a `GitHub issue`_.
|
||||||
|
|
||||||
.. _GitHub issue: https://github.com/cartographer-project/cartographer/issues
|
.. _GitHub issue: https://github.com/cartographer-project/cartographer/issues
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ You can then use Cartographer as part of your calibration process to improve the
|
||||||
Multi-trajectories SLAM
|
Multi-trajectories SLAM
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
Cartographer can perform SLAM from multiple robots emitting data in parallel.
|
Cartographer can perform SLAM from multiple robots emiting data in parallel.
|
||||||
The global SLAM is able to detect shared paths and will merge the maps built by the different robots as soon as it becomes possible.
|
The global SLAM is able to detect shared paths and will merge the maps built by the different robots as soon as it becomes possible.
|
||||||
This is achieved through the usage of two ROS services ``start_trajectory`` and ``finish_trajectory``. (refer to the ROS API reference documentation for more details on their usage)
|
This is achieved through the usage of two ROS services ``start_trajectory`` and ``finish_trajectory``. (refer to the ROS API reference documentation for more details on their usage)
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ Start by copying one of the provided example:
|
||||||
- ``demo_my_robot.launch`` is meant to be used from a development machine and expects a ``bag_filename`` argument to replay data from a recording. This launch file also spawns a rviz window configured to visualize Cartographer's state.
|
- ``demo_my_robot.launch`` is meant to be used from a development machine and expects a ``bag_filename`` argument to replay data from a recording. This launch file also spawns a rviz window configured to visualize Cartographer's state.
|
||||||
- ``offline_my_robot.launch`` is very similar to ``demo_my_robot.launch`` but tries to execute SLAM as fast as possible. This can make map building significantly faster. This launch file can also use multiple bag files provided to the ``bag_filenames`` argument.
|
- ``offline_my_robot.launch`` is very similar to ``demo_my_robot.launch`` but tries to execute SLAM as fast as possible. This can make map building significantly faster. This launch file can also use multiple bag files provided to the ``bag_filenames`` argument.
|
||||||
- ``demo_my_robot_localization.launch`` is very similar to ``demo_my_robot.launch`` but expects a ``load_state_filename`` argument pointing to a ``.pbstream`` recording of a previous Cartographer execution. The previous recording will be used as a pre-computed map and Cartographer will only perform localization on this map.
|
- ``demo_my_robot_localization.launch`` is very similar to ``demo_my_robot.launch`` but expects a ``load_state_filename`` argument pointing to a ``.pbstream`` recording of a previous Cartographer execution. The previous recording will be used as a pre-computed map and Cartographer will only perform localization on this map.
|
||||||
- ``assets_writer_my_robot.launch`` is used to extract data out of a ``.pbstream`` recording of a previous Cartographer execution.
|
- ``assets_writer_my_robot.launch`` is used to extract data out of a ``.pstream`` recording of a previous Cartographer execution.
|
||||||
|
|
||||||
Again, a few adaptations need to be made to those files to suit your robot.
|
Again, a few adaptations need to be made to those files to suit your robot.
|
||||||
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Copyright 2016 The Cartographer Authors
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
# Cache intermediate Docker layers. For a description of how this works, see:
|
|
||||||
# https://giorgos.sealabs.net/docker-cache-on-travis-and-docker-112.html
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o verbose
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
if [ "$#" -ne 1 ]; then
|
|
||||||
echo "Please provide an access token to $0" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
token=$1
|
|
||||||
|
|
||||||
CARTOGRAPHER_SHA=$(curl -s -H 'Authorization: token ${token}' https://api.github.com/repos/cartographer-project/cartographer/git/refs/heads/master | jq -j '.object.sha')
|
|
||||||
|
|
||||||
docker build ${TRAVIS_BUILD_DIR} -t cartographer_ros:${ROS_RELEASE} -f Dockerfile.${ROS_RELEASE} --build-arg CARTOGRAPHER_SHA=${CARTOGRAPHER_SHA}
|
|
|
@ -34,3 +34,6 @@ cd catkin_ws
|
||||||
# Install rosdep dependencies.
|
# Install rosdep dependencies.
|
||||||
rosdep update
|
rosdep update
|
||||||
rosdep install --from-paths src --ignore-src --rosdistro=${ROS_DISTRO} -y
|
rosdep install --from-paths src --ignore-src --rosdistro=${ROS_DISTRO} -y
|
||||||
|
|
||||||
|
# Update rosconsole-bridge to fix build issue with Docker image for Kinetic
|
||||||
|
sudo apt-get install ros-${ROS_DISTRO}-rosconsole-bridge -y
|
||||||
|
|
Loading…
Reference in New Issue