From 76801f72ac1dbe24a2a8bc76a878fd4a7261c00a Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 16:39:58 +0100 Subject: [PATCH 001/215] first commit --- README.md | 137 ++ rqt_svo/CMakeLists.txt | 22 + rqt_svo/README.md | 10 + rqt_svo/package.xml | 25 + rqt_svo/plugin.xml | 12 + rqt_svo/resource/widget.ui | 101 + rqt_svo/scripts/rqt_svo | 10 + rqt_svo/setup.py | 12 + rqt_svo/src/rqt_svo/.gitignore | 1 + rqt_svo/src/rqt_svo/__init__.py | 0 rqt_svo/src/rqt_svo/svo.py | 66 + rqt_svo/src/rqt_svo/svo_widget.py | 126 ++ svo/CMakeLists.txt | 156 ++ svo/CMakeModules/FindG2O.cmake | 113 ++ svo/Doxyfile | 1782 +++++++++++++++++ svo/doc/.gitignore | 2 + svo/include/svo/bundle_adjustment.h | 103 + svo/include/svo/config.h | 159 ++ svo/include/svo/depth_filter.h | 163 ++ svo/include/svo/feature.h | 62 + svo/include/svo/feature_alignment.h | 63 + svo/include/svo/feature_detection.h | 76 + svo/include/svo/frame.h | 130 ++ svo/include/svo/frame_handler_base.h | 116 ++ svo/include/svo/frame_handler_mono.h | 75 + svo/include/svo/global.h | 95 + svo/include/svo/initialization.h | 83 + svo/include/svo/map.h | 134 ++ svo/include/svo/matcher.h | 105 + svo/include/svo/point.h | 83 + svo/include/svo/pose_optimizer.h | 77 + svo/include/svo/reprojection.h | 98 + svo/include/svo/sparse_img_align.h | 78 + svo/package.xml | 24 + svo/src/bundle_adjustment.cpp | 435 ++++ svo/src/config.cpp | 95 + svo/src/depth_filter.cpp | 362 ++++ svo/src/feature_alignment.cpp | 601 ++++++ svo/src/feature_detection.cpp | 77 + svo/src/frame.cpp | 197 ++ svo/src/frame_handler_base.cpp | 200 ++ svo/src/frame_handler_mono.cpp | 254 +++ svo/src/initialization.cpp | 205 ++ svo/src/map.cpp | 357 ++++ svo/src/matcher.cpp | 343 ++++ svo/src/point.cpp | 170 ++ svo/src/pose_optimizer.cpp | 164 ++ svo/src/reprojection.cpp | 214 ++ svo/src/sparse_img_align.cpp | 296 +++ svo/test/README.md | 11 + svo/test/benchmark.csv | 307 +++ svo/test/data/.gitignore | 2 + svo/test/results/.gitignore | 2 + svo/test/test_depth_filter.cpp | 200 ++ svo/test/test_feature_alignment.cpp | 122 ++ svo/test/test_feature_detection.cpp | 80 + svo/test/test_matcher.cpp | 195 ++ svo/test/test_pipeline.cpp | 94 + svo/test/test_pose_optimizer.cpp | 119 ++ svo/test/test_sparse_img_align.cpp | 165 ++ svo_analysis/benchmark.py | 67 + svo_analysis/evaluate.py | 47 + svo_analysis/experiments/asl2_acc.yaml | 2 + svo_analysis/experiments/asl2_fast.yaml | 2 + svo_analysis/results/.gitignore | 2 + svo_analysis/scripts/__init__.py | 2 + svo_analysis/scripts/analyse_dataset.py | 42 + svo_analysis/scripts/analyse_logs.py | 132 ++ svo_analysis/scripts/analyse_timing.py | 97 + svo_analysis/scripts/analyse_trajectory.py | 187 ++ svo_analysis/scripts/associate.py | 67 + svo_analysis/scripts/evaluate_rpe.py | 355 ++++ .../scripts/filter_groundtruth_smooth.py | 60 + svo_analysis/scripts/hand_eye_calib.py | 287 +++ svo_analysis/scripts/rotation_utils.py | 143 ++ svo_analysis/scripts/trajectory_comparison.py | 166 ++ svo_analysis/scripts/transformations.py | 1705 ++++++++++++++++ svo_msgs/CMakeLists.txt | 35 + svo_msgs/msg/DenseInput.msg | 6 + svo_msgs/msg/Feature.msg | 5 + svo_msgs/msg/Info.msg | 6 + svo_msgs/msg/NbvTrajectory.msg | 2 + svo_msgs/package.xml | 19 + svo_ros/CMakeLists.txt | 62 + svo_ros/include/svo_ros/dataset_img.h | 62 + svo_ros/include/svo_ros/dataset_imu.h | 70 + svo_ros/include/svo_ros/visualizer.h | 75 + svo_ros/launch/live.launch | 25 + svo_ros/launch/test_rig3.launch | 16 + svo_ros/package.xml | 42 + svo_ros/param/vo_accurate.yaml | 4 + svo_ros/param/vo_fast.yaml | 3 + svo_ros/rqt.perspective | 293 +++ svo_ros/rviz_config.rviz | 153 ++ svo_ros/src/benchmark_node.cpp | 155 ++ svo_ros/src/remote_node.cpp | 169 ++ svo_ros/src/visualizer.cpp | 268 +++ svo_ros/src/vo_node.cpp | 181 ++ 98 files changed, 14580 insertions(+) create mode 100644 README.md create mode 100644 rqt_svo/CMakeLists.txt create mode 100644 rqt_svo/README.md create mode 100644 rqt_svo/package.xml create mode 100644 rqt_svo/plugin.xml create mode 100644 rqt_svo/resource/widget.ui create mode 100755 rqt_svo/scripts/rqt_svo create mode 100644 rqt_svo/setup.py create mode 100644 rqt_svo/src/rqt_svo/.gitignore create mode 100644 rqt_svo/src/rqt_svo/__init__.py create mode 100644 rqt_svo/src/rqt_svo/svo.py create mode 100644 rqt_svo/src/rqt_svo/svo_widget.py create mode 100644 svo/CMakeLists.txt create mode 100644 svo/CMakeModules/FindG2O.cmake create mode 100644 svo/Doxyfile create mode 100644 svo/doc/.gitignore create mode 100644 svo/include/svo/bundle_adjustment.h create mode 100644 svo/include/svo/config.h create mode 100644 svo/include/svo/depth_filter.h create mode 100644 svo/include/svo/feature.h create mode 100644 svo/include/svo/feature_alignment.h create mode 100644 svo/include/svo/feature_detection.h create mode 100644 svo/include/svo/frame.h create mode 100644 svo/include/svo/frame_handler_base.h create mode 100644 svo/include/svo/frame_handler_mono.h create mode 100644 svo/include/svo/global.h create mode 100644 svo/include/svo/initialization.h create mode 100644 svo/include/svo/map.h create mode 100644 svo/include/svo/matcher.h create mode 100644 svo/include/svo/point.h create mode 100644 svo/include/svo/pose_optimizer.h create mode 100644 svo/include/svo/reprojection.h create mode 100644 svo/include/svo/sparse_img_align.h create mode 100644 svo/package.xml create mode 100644 svo/src/bundle_adjustment.cpp create mode 100644 svo/src/config.cpp create mode 100644 svo/src/depth_filter.cpp create mode 100644 svo/src/feature_alignment.cpp create mode 100644 svo/src/feature_detection.cpp create mode 100644 svo/src/frame.cpp create mode 100644 svo/src/frame_handler_base.cpp create mode 100644 svo/src/frame_handler_mono.cpp create mode 100644 svo/src/initialization.cpp create mode 100644 svo/src/map.cpp create mode 100644 svo/src/matcher.cpp create mode 100644 svo/src/point.cpp create mode 100644 svo/src/pose_optimizer.cpp create mode 100644 svo/src/reprojection.cpp create mode 100644 svo/src/sparse_img_align.cpp create mode 100644 svo/test/README.md create mode 100644 svo/test/benchmark.csv create mode 100644 svo/test/data/.gitignore create mode 100644 svo/test/results/.gitignore create mode 100644 svo/test/test_depth_filter.cpp create mode 100644 svo/test/test_feature_alignment.cpp create mode 100644 svo/test/test_feature_detection.cpp create mode 100644 svo/test/test_matcher.cpp create mode 100644 svo/test/test_pipeline.cpp create mode 100644 svo/test/test_pose_optimizer.cpp create mode 100644 svo/test/test_sparse_img_align.cpp create mode 100755 svo_analysis/benchmark.py create mode 100755 svo_analysis/evaluate.py create mode 100644 svo_analysis/experiments/asl2_acc.yaml create mode 100644 svo_analysis/experiments/asl2_fast.yaml create mode 100644 svo_analysis/results/.gitignore create mode 100644 svo_analysis/scripts/__init__.py create mode 100644 svo_analysis/scripts/analyse_dataset.py create mode 100755 svo_analysis/scripts/analyse_logs.py create mode 100755 svo_analysis/scripts/analyse_timing.py create mode 100644 svo_analysis/scripts/analyse_trajectory.py create mode 100644 svo_analysis/scripts/associate.py create mode 100755 svo_analysis/scripts/evaluate_rpe.py create mode 100644 svo_analysis/scripts/filter_groundtruth_smooth.py create mode 100644 svo_analysis/scripts/hand_eye_calib.py create mode 100644 svo_analysis/scripts/rotation_utils.py create mode 100644 svo_analysis/scripts/trajectory_comparison.py create mode 100644 svo_analysis/scripts/transformations.py create mode 100644 svo_msgs/CMakeLists.txt create mode 100644 svo_msgs/msg/DenseInput.msg create mode 100644 svo_msgs/msg/Feature.msg create mode 100644 svo_msgs/msg/Info.msg create mode 100644 svo_msgs/msg/NbvTrajectory.msg create mode 100644 svo_msgs/package.xml create mode 100644 svo_ros/CMakeLists.txt create mode 100644 svo_ros/include/svo_ros/dataset_img.h create mode 100644 svo_ros/include/svo_ros/dataset_imu.h create mode 100644 svo_ros/include/svo_ros/visualizer.h create mode 100644 svo_ros/launch/live.launch create mode 100644 svo_ros/launch/test_rig3.launch create mode 100644 svo_ros/package.xml create mode 100644 svo_ros/param/vo_accurate.yaml create mode 100644 svo_ros/param/vo_fast.yaml create mode 100644 svo_ros/rqt.perspective create mode 100644 svo_ros/rviz_config.rviz create mode 100644 svo_ros/src/benchmark_node.cpp create mode 100644 svo_ros/src/remote_node.cpp create mode 100644 svo_ros/src/visualizer.cpp create mode 100644 svo_ros/src/vo_node.cpp diff --git a/README.md b/README.md new file mode 100644 index 0000000..c3bc469 --- /dev/null +++ b/README.md @@ -0,0 +1,137 @@ +SVO +=== + +Disclaimer +---------- + +SVO has been tested under ROS Groovy and Hydro and Ubuntu 12.04 and 13.04. This is research code, expect that it changes often and any fitness for a particular purpose is disclaimed. + +Installation Instructions +------------------------- + +#### OPTIONAL: g2o - General Graph Optimization + +Only required if you want to run bundle adjustment. It is not necessary for visual odometry. +g2o requires the following system dependencies: `cmake, libeigen3-dev, libsuitesparse-dev, libqt4-dev, qt4-qmake, libqglviewer-qt4-dev`, install them with `apt-get` + +I suggest an out-of-source build of g2o: + + cd workspace + git clone https://github.com/RainerKuemmerle/g2o.git + cd g2o + mkdir build + cd build + cmake .. + make + sudo make install + +If you don't want to make a system install, then you can replace the cmake command with `cmake .. -DCMAKE_INSTALL_PREFIX:PATH=$HOME/installdir` + +#### Sophus - Lie groups + +Sophus by Hauke Strasdat implements Lie groups that we need to describe rigid body transformations. + + cd workspace + git clone https://github.com/strasdat/Sophus.git + cd Sophus + git checkout a621ff + mkdir build + cd build + cmake .. + make + +You don't need to install the library since `cmake ..` writes the package location to `~.cmake/packages/` where CMake can later find it. + +#### Fast Detector + +The Fast detector by Edward Rosten is used to detect corners. +To simplify installation we provide a CMake package that contains the fast detector from the libCVD library (http://www.edwardrosten.com/cvd/). + + cd workspace + git clone https://github.com/uzh-rpg/fast.git + cd fast + mkdir build + cd build + cmake .. + make + +#### ViKit - Some useful tools that we need + +ViKit for instance contains camera models, some math and interpolation functions that SVO needs. +ViKit is a catkin project, therefore, download it into your catkin workspace source folder. + + cd catkin_ws/src + git clone https://github.com/uzh-rpg/rpg_vikit.git + +#### SVO + +Now we are ready to build SVO. +Clone it into your catkin workspace + + cd catkin_ws/src + git clone https://github.com/uzh-rpg/rpg_slam.git + +If you installed g2o then set `HAVE_G2O` in `svo/CMakeLists.txt` to TRUE. +Then build + + catkin_make + + +Run SVO on a Dataset +------------------------- + +Download this example dataset: [rpg.ifi.uzh.ch/datasets/airground_rig_s3_2013-03-18_21-38-48.bag](http://rpg.ifi.uzh.ch/datasets/airground_rig_s3_2013-03-18_21-38-48.bag) + +Open a new console and start SVO with the prepared launchfile: + + roslaunch svo_ros test_rig3.launch + +Open a new console and start RViz + + rosrun rviz rviz + +In RViz, load the configuration file (File > Open Config) which is stored in `svo_ros/rviz_config.rviz`. + +Now you are ready to start the rosbag. Open a new console and change to the directory where you have downloaded the example dataset. Then type: + + rosbag play airground_rig_s3_2013-03-18_21-38-48.bag + +Now you should see the video with tracked features (green) and in RViz how the camera moves. + +SVO GUI +------- + +Type `rosrun rqt_svo rqt_svo` to run the SVO widget that displays the number of tracked features, the frame rate and provides some interface buttons. + +Keyboard Shortcuts +------------------ + +Make sure to active the console window when pressing the keys. + +* `s` Start/Restart +* `q` Quit +* `r` Reset + +Parameter Settings +------------------ + +A description of all parameters which can be set via the launchfile is provided in `svo/include/config.h`. The default parameters can be viewed in `svo/src/config.cpp`. Moreover, some additional parameters (mainly rostopic names etc.) are read from the ros parameter server in `svo_ros/slam_node.cpp`. + +Generating Code Documentation +----------------------------- + +You can generate a Doxygen documentation as follows + + cd svo + doxygen Doxyfile + +Contributing +------------ + +You are very welcome to contribute by opening a pull request via Github. +I try to follow the ROS C++ style guide. + +Licence +------- + +The source code is released under GPLv3 licence. A professional edition license for closed-source projects is also available. Please contact `forster at ifi dot uzh dot ch` for further information. diff --git a/rqt_svo/CMakeLists.txt b/rqt_svo/CMakeLists.txt new file mode 100644 index 0000000..b199493 --- /dev/null +++ b/rqt_svo/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 2.8.3) +project(rqt_svo) + +find_package(catkin REQUIRED COMPONENTS + rospy + rqt_gui + rqt_gui_py +) +catkin_package() +catkin_python_setup() + +install(FILES plugin.xml + DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +) + +install(DIRECTORY resource + DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +) + +install(PROGRAMS scripts/rqt_svo + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) \ No newline at end of file diff --git a/rqt_svo/README.md b/rqt_svo/README.md new file mode 100644 index 0000000..574a497 --- /dev/null +++ b/rqt_svo/README.md @@ -0,0 +1,10 @@ +run with: + + rosrun rqt_svo rqt_svo + +or start `rqt` and display the widget. + +If it does not work, try this: + + rm ~/.config/ros.org/rqt_gui.ini + rqt \ No newline at end of file diff --git a/rqt_svo/package.xml b/rqt_svo/package.xml new file mode 100644 index 0000000..862112a --- /dev/null +++ b/rqt_svo/package.xml @@ -0,0 +1,25 @@ + + + rqt_svo + 0.0.0 + The rqt_svo package + + cforster + + + TODO + + catkin + rospy + rqt_gui + rqt_gui_py + rospy + rqt_gui + rqt_gui_py + + + + + + + \ No newline at end of file diff --git a/rqt_svo/plugin.xml b/rqt_svo/plugin.xml new file mode 100644 index 0000000..fd6b605 --- /dev/null +++ b/rqt_svo/plugin.xml @@ -0,0 +1,12 @@ + + + + Plugin for SVO - Semi-Direct Visual Odometry + + + + system-help + Great user interface to provide real value. + + + \ No newline at end of file diff --git a/rqt_svo/resource/widget.ui b/rqt_svo/resource/widget.ui new file mode 100644 index 0000000..7808e37 --- /dev/null +++ b/rqt_svo/resource/widget.ui @@ -0,0 +1,101 @@ + + + SvoWidget + + + + 0 + 0 + 467 + 140 + + + + SVO + + + + + + + + SVO Namespace: + + + + + + + Topic to send Twist message to + + + + + + + + + + + + + + Current angular velocity + + + Status Message + + + + + + + + + + + 100 + + + 100 + + + %p% + + + + + + + + + + + Start + + + + + + + Reset velocities to zero + + + Reset + + + + + + + Quit + + + + + + + + + + diff --git a/rqt_svo/scripts/rqt_svo b/rqt_svo/scripts/rqt_svo new file mode 100755 index 0000000..753dcb5 --- /dev/null +++ b/rqt_svo/scripts/rqt_svo @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +import sys + +from rqt_svo.svo import Svo +from rqt_gui.main import Main + +plugin = 'rqt_svo' +main = Main(filename=plugin) +sys.exit(main.main(sys.argv, standalone=plugin)) # , plugin_argument_provider=Svo.add_arguments \ No newline at end of file diff --git a/rqt_svo/setup.py b/rqt_svo/setup.py new file mode 100644 index 0000000..e07a5df --- /dev/null +++ b/rqt_svo/setup.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +from distutils.core import setup +from catkin_pkg.python_setup import generate_distutils_setup + +d = generate_distutils_setup( + packages=['rqt_svo'], + package_dir={'': 'src'}, + scripts=['scripts/rqt_svo'] +) + +setup(**d) \ No newline at end of file diff --git a/rqt_svo/src/rqt_svo/.gitignore b/rqt_svo/src/rqt_svo/.gitignore new file mode 100644 index 0000000..7e99e36 --- /dev/null +++ b/rqt_svo/src/rqt_svo/.gitignore @@ -0,0 +1 @@ +*.pyc \ No newline at end of file diff --git a/rqt_svo/src/rqt_svo/__init__.py b/rqt_svo/src/rqt_svo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rqt_svo/src/rqt_svo/svo.py b/rqt_svo/src/rqt_svo/svo.py new file mode 100644 index 0000000..88acaf7 --- /dev/null +++ b/rqt_svo/src/rqt_svo/svo.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +import os +import rospy +import argparse +from qt_gui.plugin import Plugin +from .svo_widget import SvoWidget + +class Svo(Plugin): + """ + Subclass of Plugin to display SVO status + """ + def __init__(self, context): + + # Init Plugin + super(Svo, self).__init__(context) + self.setObjectName('SvoPlugin') + + # Load arguments + # TODO load topic name from args + args = self._parse_args(context.argv()) + + # Create QWidget + self._widget = SvoWidget() + + # Show _widget.windowTitle on left-top of each plugin (when + # it's set in _widget). This is useful when you open multiple + # plugins at once. Also if you open multiple instances of your + # plugin at once, these lines add number to make it easy to + # tell from pane to pane. + if context.serial_number() > 1: + self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number())) + + # Add widget to the user interface + context.add_widget(self._widget) + + def _parse_args(self, argv): + parser = argparse.ArgumentParser(prog='rqt_svo', add_help=False) + group = parser.add_argument_group('Options for rqt_svo plugin') + group.add_argument('topic', type=argparse.FileType('r'), nargs='*', default=[], help='Svo Info Topic to display') + return parser.parse_args(argv) + +# def shutdown_plugin(self): +# # self._unregister_publisher() +# pass +# +# def save_settings(self, plugin_settings, instance_settings): +# # TODO save intrinsic configuration, usually using: +# # instance_settings.set_value(k, v) +# pass +# +# def restore_settings(self, plugin_settings, instance_settings): +# # TODO restore intrinsic configuration, usually using: +# # v = instance_settings.value(k) +# pass + + +# def _unregister_publisher(self): +# if self._publisher is not None: +# self._publisher.unregister() +# self._publisher = None + + + #def trigger_configuration(self): + # Comment in to signal that the plugin has a way to configure + # This will enable a setting button (gear icon) in each dock widget title bar + # Usually used to open a modal configuration dialog diff --git a/rqt_svo/src/rqt_svo/svo_widget.py b/rqt_svo/src/rqt_svo/svo_widget.py new file mode 100644 index 0000000..fd8303b --- /dev/null +++ b/rqt_svo/src/rqt_svo/svo_widget.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +import os +import rospy +import rospkg +import numpy as np +from python_qt_binding import loadUi +from python_qt_binding.QtGui import QWidget +from python_qt_binding.QtCore import QTimer, Slot +from svo_msgs.msg import Info +from std_msgs.msg import String + +class SvoWidget(QWidget): + _last_info_msg = Info() + _publisher = None + _subscriber = None + _num_received_msgs = 0 + + def __init__(self, svo_namespace='svo'): + + # Init QWidget + super(SvoWidget, self).__init__() + self.setObjectName('SvoWidget') + + # load UI + ui_file = os.path.join(rospkg.RosPack().get_path('rqt_svo'), 'resource', 'widget.ui') + loadUi(ui_file, self) + + # init and start update timer for data, the timer calls the function update_info all 40ms + self._update_info_timer = QTimer(self) + self._update_info_timer.timeout.connect(self.update_info) + self._update_info_timer.start(40) + + # set the functions that are called when a button is pressed + self.button_start.pressed.connect(self.on_start_button_pressed) + self.button_reset.pressed.connect(self.on_reset_button_pressed) + self.button_quit.pressed.connect(self.on_quit_button_pressed) + + # set callback for changed topic + self.topic_line_edit.setText(svo_namespace) + self.register(svo_namespace) + self.topic_line_edit.textChanged.connect(self._on_topic_changed) + + # TODO: set a timer when the last message was received and give a warning if it is too long ago! + + @Slot(str) + def _on_topic_changed(self, topic): + topic = str(topic) + self.unregister() + self.register(topic) + + def register(self, svo_namespace): + # Load parameters + max_num_features = rospy.get_param(svo_namespace+'/max_fts', 120) + + # Feature bar + self.num_tracked_bar.setMaximum(max_num_features) + print('set maximum number of features to '+str(max_num_features)) + + # Subscribe to ROS Info topic and register callback + self._subscriber = rospy.Subscriber(svo_namespace+'/info', Info, self.info_cb) + + # Initialize Publisher + self._publisher = rospy.Publisher(svo_namespace+'/remote_key', String) + + def unregister(self): + if self._publisher is not None: + self._publisher.unregister() + self._publisher = None + + if self._subscriber is not None: + self._subscriber.unregister() + self._subscriber = None + + + def info_cb(self, msg): + self._last_info_msg = msg + self._num_received_msgs += 1 + + def update_info(self): + info_text = 'Not Connected' + if self._num_received_msgs > 0: + fps = 0 + if self._last_info_msg.processing_time > 0: + fps = 1.0/self._last_info_msg.processing_time + info_text = 'fps = %.2f' % fps + info_text += '\t #Features = ' + str(self._last_info_msg.num_matches) + info_text += '\t' + if self._last_info_msg.stage == 0: + info_text += '\t PAUSED' + elif self._last_info_msg.stage == 1: + info_text += '\t FIRST_FRAME' + elif self._last_info_msg.stage == 2: + info_text += '\t SECOND_FRAME' + elif self._last_info_msg.stage == 3: + info_text += '\t RUNNING' + if self._last_info_msg.tracking_quality == 0: + info_text += '\t CRITICAL' + elif self._last_info_msg.tracking_quality == 1: + info_text += '\t BAD TRACKING' + elif self._last_info_msg.tracking_quality == 2: + info_text += '\t GOOD TRACKING' + + # set info text + self.svo_info_label.setText(info_text) + + # set progress bar + self.num_tracked_bar.setValue(self._last_info_msg.num_matches) + + def on_start_button_pressed(self): + print('START SLAM') + self.send_command('s') + + def on_reset_button_pressed(self): + print('RESET SLAM') + self.send_command('r') + + def on_quit_button_pressed(self): + print('QUIT SLAM') + self.send_command('q') + + def send_command(self, cmd): + if self._publisher is None: + return + self._publisher.publish(String(cmd)) + + diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt new file mode 100644 index 0000000..7612a94 --- /dev/null +++ b/svo/CMakeLists.txt @@ -0,0 +1,156 @@ +################################################################################ +# user build settings + +SET(DEBUG FALSE) +SET(TRACE TRUE) +SET(HAVE_G2O FALSE) + +################################################################################ + +SET(PROJECT_NAME svo) +PROJECT(${PROJECT_NAME}) +CMAKE_MINIMUM_REQUIRED (VERSION 2.8.3) +SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo +SET(CMAKE_VERBOSE_MAKEFILE OFF) +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") + +# Set ARM_ARCHITECTURE environment variable on Odroid +IF(DEFINED ENV{ARM_ARCHITECTURE}) + SET(IS_ARM TRUE) +# ADD_DEFINITIONS(-DHAVE_FAST_NEON) +ELSE() + SET(IS_ARM FALSE) +ENDIF() + +# Set definitions +IF(DEBUG) + ADD_DEFINITIONS(-DSVO_DEBUG) +ENDIF() +IF(TRACE) + ADD_DEFINITIONS(-DSVO_TRACE) +ENDIF() +IF(HAVE_G2O) + ADD_DEFINITIONS(-DUSE_BUNDLE_ADJUSTMENT) +ENDIF() +ADD_DEFINITIONS(-DUSE_ROS) + +# Set build flags +SET(CMAKE_CXX_FLAGS "-Wall -Werror -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -g") +IF(IS_ARM) + SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -mfpu=neon -march=armv7-a -fomit-frame-pointer -fsee -funsafe-loop-optimizations -fno-signed-zeros -fno-math-errno -funroll-loops") +ELSE() + SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -mmmx -msse -msse -msse2 -msse3 -mssse3 -fomit-frame-pointer -fsee -funsafe-loop-optimizations -fno-signed-zeros -fno-math-errno -funroll-loops") +ENDIF() +IF(CMAKE_COMPILER_IS_GNUCC) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +ELSE() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +ENDIF() + +# Add catkin and required ROS packages +FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp vikit_common vikit_ros) + +# Add plain cmake packages +FIND_PACKAGE(G2O REQUIRED) +FIND_PACKAGE(OpenCV REQUIRED) +FIND_PACKAGE(Eigen REQUIRED) +FIND_PACKAGE(Sophus REQUIRED) +FIND_PACKAGE(fast REQUIRED) +FIND_PACKAGE(Boost REQUIRED COMPONENTS system thread signals) + +# Describe catkin Project +catkin_package( + DEPENDS Eigen OpenCV Sophus Boost fast + CATKIN_DEPENDS roscpp vikit_common vikit_ros + INCLUDE_DIRS include + LIBRARIES svo +) + +# Include dirs +INCLUDE_DIRECTORIES( + include + ${Eigen_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${Sophus_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${catkin_INCLUDE_DIRS} + ${fast_INCLUDE_DIRS} +) +IF(HAVE_G2O) + INCLUDE_DIRECTORIES( + ${G2O_ROOT}/include + /usr/include/suitesparse # for cholmod + ) +ENDIF() + +# Set link libraries +LIST(APPEND LINK_LIBS + ${OpenCV_LIBRARIES} + ${Sophus_LIBRARIES} + ${Boost_LIBRARIES} + ${catkin_LIBRARIES} + ${fast_LIBRARIES} +) +IF(HAVE_G2O) + LIST(APPEND LINK_LIBS + g2o_core g2o_stuff g2o_solver_cholmod g2o_solver_csparse g2o_solver_dense g2o_solver_pcg g2o_types_sba + cholmod cxsparse + ) +ENDIF() + +# Set sourcefiles +LIST(APPEND SOURCEFILES + src/frame_handler_mono.cpp + src/frame_handler_base.cpp + src/frame.cpp + src/point.cpp + src/map.cpp + src/pose_optimizer.cpp + src/initialization.cpp + src/matcher.cpp + src/reprojection.cpp + src/feature_alignment.cpp + src/feature_detection.cpp + src/depth_filter.cpp + src/config.cpp + src/sparse_img_align.cpp) +IF(HAVE_G2O) + LIST(APPEND SOURCEFILES src/bundle_adjustment.cpp) +ENDIF(HAVE_G2O) + +# Create svo library +ADD_LIBRARY(svo SHARED ${SOURCEFILES}) +TARGET_LINK_LIBRARIES(svo ${LINK_LIBS}) + + +################################################################################ +# TESTS + +IF(DEFINED ENV{SVO_DATASET_DIR}) + ADD_DEFINITIONS(-DTEST_DATA_DIR=\"$ENV{SVO_DATASET_DIR}\") +ELSE() + ADD_DEFINITIONS(-DTEST_DATA_DIR=\"${PROJECT_SOURCE_DIR}/test/data\") +ENDIF() +ADD_DEFINITIONS(-DTEST_TRACE_DIR=\"${PROJECT_SOURCE_DIR}/test/results\") + +ADD_EXECUTABLE(test_feature_align test/test_feature_alignment.cpp) +TARGET_LINK_LIBRARIES(test_feature_align svo) + +ADD_EXECUTABLE(test_pipeline test/test_pipeline.cpp) +TARGET_LINK_LIBRARIES(test_pipeline svo) + +ADD_EXECUTABLE(test_matcher test/test_matcher.cpp) +TARGET_LINK_LIBRARIES(test_matcher svo) + +ADD_EXECUTABLE(test_feature_detection test/test_feature_detection.cpp) +TARGET_LINK_LIBRARIES(test_feature_detection svo) + +ADD_EXECUTABLE(test_depth_filter test/test_depth_filter.cpp) +TARGET_LINK_LIBRARIES(test_depth_filter svo) + +ADD_EXECUTABLE(test_sparse_img_align test/test_sparse_img_align.cpp) +TARGET_LINK_LIBRARIES(test_sparse_img_align svo) + +ADD_EXECUTABLE(test_pose_optimizer test/test_pose_optimizer.cpp) +TARGET_LINK_LIBRARIES(test_pose_optimizer svo) diff --git a/svo/CMakeModules/FindG2O.cmake b/svo/CMakeModules/FindG2O.cmake new file mode 100644 index 0000000..655600f --- /dev/null +++ b/svo/CMakeModules/FindG2O.cmake @@ -0,0 +1,113 @@ +# Find the header files + +FIND_PATH(G2O_INCLUDE_DIR g2o/core/base_vertex.h + ${G2O_ROOT}/include + $ENV{G2O_ROOT}/include + $ENV{G2O_ROOT} + /usr/local/include + /usr/include + /opt/local/include + /sw/local/include + /sw/include + NO_DEFAULT_PATH + ) + +# Macro to unify finding both the debug and release versions of the +# libraries; this is adapted from the OpenSceneGraph FIND_LIBRARY +# macro. + +MACRO(FIND_G2O_LIBRARY MYLIBRARY MYLIBRARYNAME) + + FIND_LIBRARY("${MYLIBRARY}_DEBUG" + NAMES "g2o_${MYLIBRARYNAME}_d" + PATHS + ${G2O_ROOT}/lib/Debug + ${G2O_ROOT}/lib + $ENV{G2O_ROOT}/lib/Debug + $ENV{G2O_ROOT}/lib + NO_DEFAULT_PATH + ) + + FIND_LIBRARY("${MYLIBRARY}_DEBUG" + NAMES "g2o_${MYLIBRARYNAME}_d" + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/lib + /usr/local/lib64 + /usr/lib + /usr/lib64 + /opt/local/lib + /sw/local/lib + /sw/lib + ) + + FIND_LIBRARY(${MYLIBRARY} + NAMES "g2o_${MYLIBRARYNAME}" + PATHS + ${G2O_ROOT}/lib/Release + ${G2O_ROOT}/lib + $ENV{G2O_ROOT}/lib/Release + $ENV{G2O_ROOT}/lib + NO_DEFAULT_PATH + ) + + FIND_LIBRARY(${MYLIBRARY} + NAMES "g2o_${MYLIBRARYNAME}" + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/lib + /usr/local/lib64 + /usr/lib + /usr/lib64 + /opt/local/lib + /sw/local/lib + /sw/lib + ) + + IF(NOT ${MYLIBRARY}_DEBUG) + IF(MYLIBRARY) + SET(${MYLIBRARY}_DEBUG ${MYLIBRARY}) + ENDIF(MYLIBRARY) + ENDIF( NOT ${MYLIBRARY}_DEBUG) + +ENDMACRO(FIND_G2O_LIBRARY LIBRARY LIBRARYNAME) + +# Find the core elements +FIND_G2O_LIBRARY(G2O_STUFF_LIBRARY stuff) +FIND_G2O_LIBRARY(G2O_CORE_LIBRARY core) + +# Find the CLI library +FIND_G2O_LIBRARY(G2O_CLI_LIBRARY cli) + +# Find the pluggable solvers +FIND_G2O_LIBRARY(G2O_SOLVER_CHOLMOD solver_cholmod) +FIND_G2O_LIBRARY(G2O_SOLVER_CSPARSE solver_csparse) +FIND_G2O_LIBRARY(G2O_SOLVER_CSPARSE_EXTENSION csparse_extension) +FIND_G2O_LIBRARY(G2O_SOLVER_DENSE solver_dense) +FIND_G2O_LIBRARY(G2O_SOLVER_PCG solver_pcg) +FIND_G2O_LIBRARY(G2O_SOLVER_SLAM2D_LINEAR solver_slam2d_linear) +FIND_G2O_LIBRARY(G2O_SOLVER_STRUCTURE_ONLY solver_structure_only) +FIND_G2O_LIBRARY(G2O_SOLVER_EIGEN solver_eigen) + +# Find the predefined types +FIND_G2O_LIBRARY(G2O_TYPES_DATA types_data) +FIND_G2O_LIBRARY(G2O_TYPES_ICP types_icp) +FIND_G2O_LIBRARY(G2O_TYPES_SBA types_sba) +FIND_G2O_LIBRARY(G2O_TYPES_SCLAM2D types_sclam2d) +FIND_G2O_LIBRARY(G2O_TYPES_SIM3 types_sim3) +FIND_G2O_LIBRARY(G2O_TYPES_SLAM2D types_slam2d) +FIND_G2O_LIBRARY(G2O_TYPES_SLAM3D types_slam3d) + +# G2O solvers declared found if we found at least one solver +SET(G2O_SOLVERS_FOUND "NO") +IF(G2O_SOLVER_CHOLMOD OR G2O_SOLVER_CSPARSE OR G2O_SOLVER_DENSE OR G2O_SOLVER_PCG OR G2O_SOLVER_SLAM2D_LINEAR OR G2O_SOLVER_STRUCTURE_ONLY OR G2O_SOLVER_EIGEN) + SET(G2O_SOLVERS_FOUND "YES") +ENDIF(G2O_SOLVER_CHOLMOD OR G2O_SOLVER_CSPARSE OR G2O_SOLVER_DENSE OR G2O_SOLVER_PCG OR G2O_SOLVER_SLAM2D_LINEAR OR G2O_SOLVER_STRUCTURE_ONLY OR G2O_SOLVER_EIGEN) + +# G2O itself declared found if we found the core libraries and at least one solver +SET(G2O_FOUND "NO") +IF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_SOLVERS_FOUND) + SET(G2O_FOUND "YES") +ENDIF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_SOLVERS_FOUND) diff --git a/svo/Doxyfile b/svo/Doxyfile new file mode 100644 index 0000000..fb60d29 --- /dev/null +++ b/svo/Doxyfile @@ -0,0 +1,1782 @@ +# Doxyfile 1.7.6.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "svo" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Semi-Direct Visual Odometry" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = "doc" + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = "src", "include/nano_slam" + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = g2o +EXCLUDE_SYMBOLS += vk + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/svo/doc/.gitignore b/svo/doc/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/svo/doc/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/svo/include/svo/bundle_adjustment.h b/svo/include/svo/bundle_adjustment.h new file mode 100644 index 0000000..215d563 --- /dev/null +++ b/svo/include/svo/bundle_adjustment.h @@ -0,0 +1,103 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_BUNDLE_ADJUSTMENT_H_ +#define SVO_BUNDLE_ADJUSTMENT_H_ + +#include + +namespace g2o { +class EdgeProjectXYZ2UV; +class SparseOptimizer; +} +typedef g2o::EdgeProjectXYZ2UV g2oEdgeSE3; + +namespace svo { + +class Point; +class Feature; +class Map; + +/// Local, global and 2-view bundle adjustment with g2o. +namespace ba { + +/// Temporary container to hold the g2o edge with reference to frame and point. +struct EdgeContainerSE3 +{ + g2oEdgeSE3* edge; + Frame* frame; + Feature* feature; + bool is_deleted; + EdgeContainerSE3(g2oEdgeSE3* e, Frame* frame, Feature* feature) : + edge(e), frame(frame), feature(feature), is_deleted(false) + {} +}; + +/// Optimize two camera frames and their observed 3D points. +/// Is used after initialization. +void twoViewBA(Frame* frame1, Frame* frame2, double reproj_thresh, Map* map); + +/// Local bundle adjustment. +/// Optimizes core_kfs and their observed map points while keeping the +/// neighbourhood fixed. +void localBA( + Frame* center_kf, + set* core_kfs, + Map* map, + size_t& n_incorrect_edges_1, + size_t& n_incorrect_edges_2, + double& init_error, + double& final_error); + +/// Global bundle adjustment. +/// Optimizes the whole map. Is currently not used in SVO. +void globalBA(Map* map); + +/// Initialize g2o with solver type, optimization strategy and camera model. +void setupG2o(g2o::SparseOptimizer * optimizer); + +/// Run the optimization on the provided graph. +void runSparseBAOptimizer( + g2o::SparseOptimizer* optimizer, + unsigned int num_iter, + double& init_error, + double& final_error); + +/// Create a g2o vertice from a keyframe object. +g2oFrameSE3* createG2oFrameSE3( + Frame* kf, + size_t id, + bool fixed); + +/// Creates a g2o vertice from a mappoint object. +g2oPoint* createG2oPoint( + Vector3d pos, + size_t id, + bool fixed); + +/// Creates a g2o edge between a g2o keyframe and mappoint vertice with the provided measurement. +g2oEdgeSE3* createG2oEdgeSE3( + g2oFrameSE3* v_kf, + g2oPoint* v_mp, + const Vector2d& f_up, + bool robust_kernel, + double huber_width, + double weight = 1); + +} // namespace ba +} // namespace svo + +#endif // SVO_BUNDLE_ADJUSTMENT_H_ diff --git a/svo/include/svo/config.h b/svo/include/svo/config.h new file mode 100644 index 0000000..3ad547b --- /dev/null +++ b/svo/include/svo/config.h @@ -0,0 +1,159 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef NSLAM_CONFIG_H_ +#define NSLAM_CONFIG_H_ + +#include +#include +#include + +namespace svo { + +using namespace std; + +/// Global configuration file of SVO. +/// Implements the Singleton design pattern to allow global access and to ensure +/// that only one instance exists. +class Config +{ +public: + static Config& getInstance(); + + /// Base-name of the tracefiles. + static string& traceName() { return getInstance().trace_name; } + + /// Directory where the tracefiles are saved. + static string& traceDir() { return getInstance().trace_dir; } + + /// Number of pyramid levels used for features. + static size_t& nPyrLevels() { return getInstance().n_pyr_levels; } + + /// Use the IMU to get relative rotations. + static bool& useImu() { return getInstance().use_imu; } + + /// Number of keyframes in the core. The core-kfs are optimized through bundle adjustment. + static size_t& coreNKfs() { return getInstance().core_n_kfs; } + + /// Initial scale of the map. Depends on the distance the camera is moved for the initialization. + static double& mapScale() { return getInstance().map_scale; } + + /// Feature grid size of a cell in [px]. + static size_t& gridSize() { return getInstance().grid_size; } + + /// Initialization: Minimum required disparity between the first two frames. + static double& initMinDisparity() { return getInstance().init_min_disparity; } + + /// Initialization: Minimum number of tracked features. + static size_t& initMinTracked() { return getInstance().init_min_tracked; } + + /// Initialization: Minimum number of inliers after RANSAC. + static size_t& initMinInliers() { return getInstance().init_min_inliers; } + + /// Maximum level of the Lucas Kanade tracker. + static size_t& kltMaxLevel() { return getInstance().klt_max_level; } + + /// Minimum level of the Lucas Kanade tracker. + static size_t& kltMinLevel() { return getInstance().klt_min_level; } + + /// Reprojection threshold [px]. + static double& reprojThresh() { return getInstance().reproj_thresh; } + + /// Reprojection threshold after pose optimization. + static double& poseOptimThresh() { return getInstance().poseoptim_thresh; } + + /// Number of iterations in local bundle adjustment. + static size_t& poseOptimNumIter() { return getInstance().poseoptim_num_iter; } + + /// Maximum number of points to optimize at every iteration. + static size_t& structureOptimMaxPts() { return getInstance().structureoptim_max_pts; } + + /// Number of iterations in structure optimization. + static size_t& structureOptimNumIter() { return getInstance().structureoptim_num_iter; } + + /// Reprojection threshold after bundle adjustment. + static double& lobaThresh() { return getInstance().loba_thresh; } + + /// Threshold for the robust Huber kernel of the local bundle adjustment. + static double& lobaRobustHuberWidth() { return getInstance().loba_robust_huber_width; } + + /// Number of iterations in the local bundle adjustment. + static size_t& lobaNumIter() { return getInstance().loba_num_iter; } + + /// Minimum distance between two keyframes. Relative to the average height in the map. + static double& kfSelectMinDist() { return getInstance().kfselect_mindist; } + + /// Select only features with a minimum Harris corner score for triangulation. + static double& triangMinCornerScore() { return getInstance().triang_min_corner_score; } + + /// Subpixel refinement of reprojection and triangulation. Set to 0 if no subpix refinement required! + static size_t& subpixNIter() { return getInstance().subpix_n_iter; } + + /// Limit the number of keyframes in the map. This makes nslam essentially. + /// a Visual Odometry. Set to 0 if unlimited number of keyframes are allowed. + /// Minimum number of keyframes is 3. + static size_t& maxNKfs() { return getInstance().max_n_kfs; } + + /// How much (in milliseconds) is the camera delayed with respect to the imu. + static double& imgImuDelay() { return getInstance().img_imu_delay; } + + /// Maximum number of features that should be tracked. + static size_t& maxFts() { return getInstance().max_fts; } + + /// If the number of tracked features drops below this threshold. Tracking quality is bad. + static size_t& qualityMinFts() { return getInstance().quality_min_fts; } + + /// If within one frame, this amount of features are dropped. Tracking quality is bad. + static int& qualityMaxFtsDrop() { return getInstance().quality_max_drop_fts; } + +private: + Config(); + Config(Config const&); + void operator=(Config const&); + string trace_name; + string trace_dir; + size_t n_pyr_levels; + bool use_imu; + size_t core_n_kfs; + double map_scale; + size_t grid_size; + double init_min_disparity; + size_t init_min_tracked; + size_t init_min_inliers; + size_t klt_max_level; + size_t klt_min_level; + double reproj_thresh; + double poseoptim_thresh; + size_t poseoptim_num_iter; + size_t structureoptim_max_pts; + size_t structureoptim_num_iter; + double loba_thresh; + double loba_robust_huber_width; + size_t loba_num_iter; + double kfselect_mindist; + double triang_min_corner_score; + size_t triang_half_patch_size; + size_t subpix_n_iter; + size_t max_n_kfs; + double img_imu_delay; + size_t max_fts; + size_t quality_min_fts; + int quality_max_drop_fts; +}; + +} // namespace nslam + +#endif // NSLAM_CONFIG_H_ diff --git a/svo/include/svo/depth_filter.h b/svo/include/svo/depth_filter.h new file mode 100644 index 0000000..d943764 --- /dev/null +++ b/svo/include/svo/depth_filter.h @@ -0,0 +1,163 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_DEPTH_FILTER_H_ +#define SVO_DEPTH_FILTER_H_ + +#include +#include +#include +#include +#include +#include + +namespace svo { + +class Frame; +class Feature; +class Point; + +/// A seed is a probabilistic depth estimate for a single pixel. +struct Seed +{ + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + static int batch_counter; + static int seed_counter; + int batch_id; //!< Batch id is the id of the keyframe for which the seed was created. + int id; //!< Seed ID, only used for visualization. + Feature* ftr; //!< Feature in the keyframe for which the depth should be computed. + float a; //!< a of Beta distribution: When high, probability of inlier is large. + float b; //!< b of Beta distribution: When high, probability of outlier is large. + float mu; //!< Mean of normal distribution. + float z_range; //!< Max range of the possible depth. + float sigma2; //!< Variance of normal distribution. + Matrix2d patch_cov; //!< Patch covariance in reference image. + Seed(Feature* ftr, float angle, float depth_mean, float depth_min); +}; + +/// Depth filter implements the Bayesian Update proposed in: +/// "Video-based, Real-Time Multi View Stereo" by G. Vogiatzis and C. Hernández. +/// In Image and Vision Computing, 29(7):434-441, 2011. +/// +/// The class uses a callback mechanism such that it can be used also by other +/// algorithms than nslam and for simplified testing. +class DepthFilter +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + typedef boost::unique_lock lock_t; + typedef boost::function callback_t; + + /// Depth-filter config parameters + struct Options { + bool check_ftr_angle; //!< gradient features are only updated if the epipolar line is orthogonal to the gradient. + bool epi_search_1d; //!< restrict Gauss Newton in the epipolar search to the epipolar line. + bool verbose; //!< display output. + bool use_photometric_disparity_error; //!< use photometric disparity error instead of 1px error in tau computation. + int max_n_kfs; //!< maximum number of keyframes for which we maintain seeds. + double sigma_i_sq; //!< image noise. + double seed_convergence_sigma2_thresh; //!< threshold on depth uncertainty for convergence. + Options() + : check_ftr_angle(false), + epi_search_1d(false), + verbose(false), + use_photometric_disparity_error(false), + max_n_kfs(3), + sigma_i_sq(5e-4), + seed_convergence_sigma2_thresh(200.0) + {} + } options_; + + DepthFilter(feature_detection::DetectorPtr feature_detector, callback_t seed_converged_cb); + ~DepthFilter(); + + /// Start this thread when seed updating should be in a parallel thread. + void startThread(); + + /// Stop the parallel thread that is running. + void stopThread(); + + /// Add frame to the queue to be processed. + void addFrame(FramePtr frame); + + /// Add new keyframe to the queue + void addKeyframe(FramePtr frame, double depth_mean, double depth_min); + + /// Remove all seeds which are initialized from the specified keyframe. This + /// function is used to make sure that no seeds points to a non-existent frame + /// when a frame is removed from the map. + void removeKeyframe(FramePtr frame); + + /// If the map is reset, call this function such that we don't have pointers + /// to old frames. + void reset(); + + /// Returns a copy of the seeds belonging to frame. Thread-safe. + /// Can be used to compute the Next-Best-View in parallel. + /// IMPORTANT! Make sure you hold a valid reference counting pointer to frame + /// so it is not being deleted while you use it. + void getSeedsCopy(const FramePtr& frame, std::list& seeds); + + /// Return a reference to the seeds. This is NOT THREAD SAFE! + std::list >& getSeeds() { return seeds_; } + + /// Bayes update of the seed, x is the measurement, tau2 the measurement uncertainty + static void updateSeed( + const float x, + const float tau2, + Seed* seed); + + /// Compute the uncertainty of the measurement. + static double computeTau( + const SE3& T_ref_cur, + const Vector3d& f, + const double z, + const double px_error_angle); + +private: + feature_detection::DetectorPtr feature_detector_; + callback_t seed_converged_cb_; + std::list > seeds_; + boost::mutex seeds_mut_; + bool seeds_updating_halt_; //!< Set this value to true when seeds updating should be interrupted. + boost::thread* thread_; + std::queue frame_queue_; + boost::mutex frame_queue_mut_; + boost::condition_variable frame_queue_cond_; + FramePtr new_keyframe_; //!< Next keyframe to extract new seeds. + bool new_keyframe_set_; //!< Do we have a new keyframe to process?. + double new_keyframe_min_depth_; //!< Minimum depth in the new keyframe. Used for range in new seeds. + double new_keyframe_mean_depth_; //!< Maximum depth in the new keyframe. Used for range in new seeds. + vk::PerformanceMonitor permon_; //!< Separate performance monitor since the DepthFilter runs in a parallel thread. + + /// Initialize new seeds from a frame. + void initializeSeeds(FramePtr frame); + + /// Update all seeds with a new measurement frame. + void updateSeeds(FramePtr frame); + + /// When a new keyframe arrives, the frame queue should be cleared. + void clearFrameQueue(); + + /// A thread that is continuously updating the seeds. + void updateSeedsLoop(); +}; + +} // namespace svo + +#endif // SVO_DEPTH_FILTER_H_ diff --git a/svo/include/svo/feature.h b/svo/include/svo/feature.h new file mode 100644 index 0000000..a0a30f4 --- /dev/null +++ b/svo/include/svo/feature.h @@ -0,0 +1,62 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FEATURE_H_ +#define SVO_FEATURE_H_ + +#include + +namespace svo { + +/// A salient image region that is tracked across frames. +struct Feature +{ + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + Frame* frame; //!< Pointer to frame in which the feature was detected. + Vector2d px; //!< Coordinates in pixels on pyramid level 0. + Vector3d f; //!< Unit-bearing vector of the feature. + int level; //!< Image pyramid level where feature was extracted. + Point* point; //!< Pointer to 3D point which corresponds to the feature. + + Feature(Frame* _frame, const Vector2d& _px, int _level) + : frame(_frame), + px(_px), + f(frame->cam_->cam2world(px)), + level(_level), + point(NULL) + {} + + Feature(Frame* _frame, const Vector2d& _px, const Vector3d& _f, int _level) + : frame(_frame), + px(_px), + f(_f), + level(_level), + point(NULL) + {} + + Feature(Frame* _frame, Point* _point, const Vector2d& _px, const Vector3d& _f, int _level) + : frame(_frame), + px(_px), + f(_f), + level(_level), + point(_point) + {} +}; + +} // namespace svo + +#endif // SVO_FEATURE_H_ diff --git a/svo/include/svo/feature_alignment.h b/svo/include/svo/feature_alignment.h new file mode 100644 index 0000000..12523e3 --- /dev/null +++ b/svo/include/svo/feature_alignment.h @@ -0,0 +1,63 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FEATURE_ALIGNMENT_H_ +#define SVO_FEATURE_ALIGNMENT_H_ + +#include + +namespace svo { + +/// Subpixel refinement of a reference feature patch with the current image. +/// Implements the inverse-compositional approach (see "Lucas-Kanade 20 Years on" +/// paper by Baker. +namespace feature_alignment { + +bool align1D( + const cv::Mat& cur_img, + const Vector2f& dir, // direction in which the patch is allowed to move + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate, + double& h_inv); + +bool align2D( + const cv::Mat& cur_img, + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate, + bool no_simd = false); + +bool align2D_SSE2( + const cv::Mat& cur_img, + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate); + +bool align2D_NEON( + const cv::Mat& cur_img, + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate); + +} // namespace feature_alignment +} // namespace svo + +#endif // SVO_FEATURE_ALIGNMENT_H_ diff --git a/svo/include/svo/feature_detection.h b/svo/include/svo/feature_detection.h new file mode 100644 index 0000000..a84586a --- /dev/null +++ b/svo/include/svo/feature_detection.h @@ -0,0 +1,76 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FEATURE_DETECTION_H_ +#define SVO_FEATURE_DETECTION_H_ + +#include +#include + +namespace svo { + +/// Implementation of various feature detectors. +namespace feature_detection { + +/// Temporary container used for corner detection. Features are initialized from these. +// TODO: why not use feature struct? +struct Corner +{ + int x; //!< x-coordinate of corner in the image. + int y; //!< y-coordinate of corner in the image. + int level; //!< pyramid level of the corner. + float score; //!< shi-tomasi score of the corner. + float angle; //!< for gradient-features: dominant gradient angle. + Corner(int x, int y, float score, int level, float angle) : + x(x), y(y), level(level), score(score), angle(angle) + {} +}; +typedef vector Corners; + +/// All detectors should derive from this abstract class. +class AbstractDetector +{ +public: + virtual ~AbstractDetector() {}; + virtual void detect( + const ImgPyr& img_pyr, + const Features& fts, + const int cell_size, + const int n_levels, + const double detection_threshold, + Corners* corners) const = 0; +}; +typedef boost::shared_ptr DetectorPtr; + +/// FAST detector by Edward Rosten. +class FastDetector : public AbstractDetector +{ +public: + FastDetector() {} + virtual ~FastDetector() {} + virtual void detect( + const ImgPyr& img_pyr, + const Features& fts, + const int cell_size, + const int n_levels, + const double detection_threshold, + Corners* corners) const; +}; + +} // namespace feature_detection +} // namespace svo + +#endif // SVO_FEATURE_DETECTION_H_ diff --git a/svo/include/svo/frame.h b/svo/include/svo/frame.h new file mode 100644 index 0000000..68aa548 --- /dev/null +++ b/svo/include/svo/frame.h @@ -0,0 +1,130 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FRAME_H_ +#define SVO_FRAME_H_ + +#include +#include +#include +#include +#include +#include + +namespace g2o { +class VertexSE3Expmap; +} +typedef g2o::VertexSE3Expmap g2oFrameSE3; + +namespace svo { + +class Point; +class Frame; +struct Feature; + +typedef list Features; +typedef vector ImgPyr; + +/// A frame saves the image, the associated features and the estimated pose. +class Frame : boost::noncopyable +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + static int frame_counter_; //!< Counts the number of created frames. Used to set the unique id. + int id_; //!< Unique id of the frame. + double timestamp_; //!< Timestamp of when the image was recorded. + vk::AbstractCamera* cam_; //!< Camera model. + Sophus::SE3 T_f_w_; //!< Transform (f)rame from (w)orld. + Matrix Cov_; //!< Covariance. + ImgPyr img_pyr_; //!< Image Pyramid. + Features fts_; //!< List of features in the image. + vector key_pts_; //!< Five features and associated 3D points which are used to detect if two frames have overlapping field of view. + bool is_keyframe_; //!< Was this frames selected as keyframe? + g2oFrameSE3* v_kf_; //!< Temporary pointer to the g2o node object of the keyframe. + int last_published_ts_; //!< Timestamp of last publishing. + + Frame(vk::AbstractCamera* cam, const cv::Mat& img, double timestamp=0.0); + ~Frame(); + + /// Initialize new frame and create image pyramid. + void initFrame(const cv::Mat& img); + + /// Select this frame as keyframe. + void setKeyframe(); + + /// Add a feature to the image + void addFeature(Feature* ftr); + + /// The KeyPoints are those five features which are closest to the 4 image corners + /// and to the center and which have a 3D point assigned. These points are used + /// to quickly check whether two frames have overlapping field of view. + void setKeyPoints(); + + /// Check if we can select five better key-points. + void checkKeyPoints(Feature* ftr); + + /// If a point is deleted, we must remove the corresponding key-point. + void removeKeyPoint(Feature* ftr); + + /// Return number of point observations. + size_t nObs() const; + + /// Check if a point in (w)orld coordinate frame is visible in the image. + bool isVisible(const Vector3d& xyz_w) const; + + /// Full resolution image stored in the frame. + inline const cv::Mat& img() const { return img_pyr_[0]; } + + /// Was this frame selected as keyframe? + inline bool isKeyframe() const { return is_keyframe_; } + + /// Transforms point coordinates in world-frame (w) to camera pixel coordinates (c). + inline Vector2d w2c(const Vector3d& xyz_w) const { return cam_->world2cam( T_f_w_ * xyz_w ); } + + /// Transforms pixel coordinates (c) to frame unit sphere coordinates (f). + inline Vector3d c2f(const Vector2d& px) const { return cam_->cam2world(px[0], px[1]); } + + /// Transforms pixel coordinates (c) to frame unit sphere coordinates (f). + inline Vector3d c2f(const double x, const double y) const { return cam_->cam2world(x, y); } + + /// Transforms point coordinates in world-frame (w) to camera-frams (f). + inline Vector3d w2f(const Vector3d& xyz_w) const { return T_f_w_ * xyz_w; } + + /// Transforms point from frame unit sphere (f) frame to world coordinate frame (w). + inline Vector3d f2w(const Vector3d& f) const { return T_f_w_.inverse() * f; } + + /// Projects Point from unit sphere (f) in camera pixels (c). + inline Vector2d f2c(const Vector3d& f) const { return cam_->world2cam( f ); } + + /// Return the pose of the frame in the (w)orld coordinate frame. + inline Vector3d pos() const { return T_f_w_.inverse().translation(); } +}; + + +/// Some helper functions for the frame object. +namespace frame_utils { + +/// Creates an image pyramid of half-sampled images. +void createImgPyramid(const cv::Mat& img_level_0, int n_levels, ImgPyr& pyr); + +/// Get the average depth of the features in the image. +bool getSceneDepth(const Frame& frame, double& depth_mean, double& depth_min); + +} // namespace frame_utils +} // namespace svo + +#endif // SVO_FRAME_H_ diff --git a/svo/include/svo/frame_handler_base.h b/svo/include/svo/frame_handler_base.h new file mode 100644 index 0000000..51286c7 --- /dev/null +++ b/svo/include/svo/frame_handler_base.h @@ -0,0 +1,116 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FRAME_HANDLER_BASE_H_ +#define SVO_FRAME_HANDLER_BASE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vk { + class AbstractCamera; + class PerformanceMonitor; +} + +namespace svo { + +class Point; +class Matcher; +class DepthFilter; + +/// Base class for various VO pipelines. Manages the map and the state machine. +class FrameHandlerBase : boost::noncopyable +{ +public: + enum Stage { PAUSED, FIRST_FRAME, SECOND_FRAME, DEFAULT_FRAME }; + enum TrackingQuality { INSUFFICIENT, BAD, GOOD }; + enum UpdateResult { NO_KEYFRAME, IS_KEYFRAME, FAILURE }; + + FrameHandlerBase(); + + virtual ~FrameHandlerBase(); + + /// Set initial pose of the camera. + void setInitialPose(const SE3& T_frame_from_world) { T_f_w_init_ = T_frame_from_world; } + + /// Get the current map. + const Map& map() const { return map_; } + + /// Will reset the map as soon as the current frame is finished processing. + void reset() { set_reset_ = true; } + + /// Start processing. + void start() { set_start_ = true; } + + /// Get the current stage of the algorithm. + Stage stage() const { return stage_; } + + /// Get tracking quality. + TrackingQuality trackingQuality() const { return tracking_quality_; } + + /// Get the processing time of the previous iteration. + double lastProcessingTime() const { return timer_.getTime(); } + + /// Get the number of feature observations of the last frame. + size_t lastNumObservations() const { return num_obs_last_; } + + /// Access the depth filter. + DepthFilter* depthFilter() const { return depth_filter_; } + +protected: + Stage stage_; //!< Current stage of the algorithm. + bool set_reset_; //!< Flag that the user can set. Will reset the system before the next iteration. + bool set_start_; //!< Flag the user can set to start the system when the next image is received. + Map map_; //!< Map of keyframes created by the slam system. + SE3 T_f_w_init_; //!< Initial pose of the camera. + vk::Timer timer_; //!< Stopwatch to measure time to process frame. + vk::RingBuffer acc_frame_timings_; //!< Total processing time of the last 10 frames, used to give some user feedback on the performance. + vk::RingBuffer acc_num_obs_; //!< Number of observed features of the last 10 frames, used to give some user feedback on the tracking performance. + size_t num_obs_last_; //!< Number of observations in the previous frame. + TrackingQuality tracking_quality_; //!< An estimate of the tracking quality based on the number of tracked features. + DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. + + /// Before a frame is processed, this function is called. + bool startFrameProcessingCommon(); + + /// When a frame is finished processing, this function is called. + int finishFrameProcessingCommon( + size_t update_id, + UpdateResult dropout, + size_t num_observations); + + /// Reset the map and frame handler to start from scratch. + void resetCommon(); + + /// Reset the frame handler. Implement in derived class. + virtual void resetAll() { resetCommon(); } + + /// Set the tracking quality based on the number of tracked features. + void setTrackingQuality(const size_t num_observations); + + /// Optimize some of the observed 3D points. + void optimizeStructure(FramePtr frame, size_t max_n_pts, int max_iter); +}; + +} // namespace nslam + +#endif // SVO_FRAME_HANDLER_BASE_H_ diff --git a/svo/include/svo/frame_handler_mono.h b/svo/include/svo/frame_handler_mono.h new file mode 100644 index 0000000..3dc80ab --- /dev/null +++ b/svo/include/svo/frame_handler_mono.h @@ -0,0 +1,75 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FRAME_HANDLER_H_ +#define SVO_FRAME_HANDLER_H_ + +#include +#include +#include +#include + +namespace svo { + +/// Monocular Visual Odometry Pipeline as described in the SVO paper. +class FrameHandlerMono : public FrameHandlerBase +{ +public: + FrameHandlerMono(vk::AbstractCamera* cam); + ~FrameHandlerMono(); + + /// Provide an image. + void addImage(const cv::Mat& img, double timestamp); + + /// Get the last frame that has been processed. + FramePtr lastFrame() { return last_frame_; } + + /// Get the set of spatially closest keyframes of the last frame. + const set& coreKeyframes() { return core_kfs_; } + + /// Return the feature track to visualize the KLT tracking during initialization. + const vector& initFeatureTrackRefPx() const { return klt_homography_init_.px_ref_; } + const vector& initFeatureTrackCurPx() const { return klt_homography_init_.px_cur_; } + +protected: + vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit). + reprojection::Grid reprojection_grid_; //!< Grid used for reprojection to make sure we have evenly distributed features. + FramePtr new_frame_; //!< Current frame. + FramePtr last_frame_; //!< Last frame, not necessarily a keyframe. + set core_kfs_; //!< Keyframes in the closer neighbourhood. + vector< pair > overlap_kfs_; //!< All keyframes with overlapping field of view. the paired number specifies how many common mappoints are observed TODO: why vector!? + initialization::KltHomographyInit klt_homography_init_; //!< Used to estimate pose of the first two keyframes by estimating a homography. + + /// Processes the first frame and sets it as a keyframe. + UpdateResult processFirstFrame(); + + /// Processes all frames after the first frame until a keyframe is selected. + UpdateResult processSecondFrame(); + + /// Processes all frames after the first two keyframes. + UpdateResult processFrame(); + + /// Reset the frame handler. Implement in derived class. + virtual void resetAll(); + + void setCoreKfs(size_t n_closest); + + bool needNewKf(double scene_depth_mean); +}; + +} // namespace svo + +#endif // SVO_FRAME_HANDLER_H_ diff --git a/svo/include/svo/global.h b/svo/include/svo/global.h new file mode 100644 index 0000000..01d8d52 --- /dev/null +++ b/svo/include/svo/global.h @@ -0,0 +1,95 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_GLOBAL_H_ +#define SVO_GLOBAL_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef USE_ROS + #include + #define SVO_DEBUG_STREAM(x) ROS_DEBUG_STREAM(x) + #define SVO_INFO_STREAM(x) ROS_INFO_STREAM(x) + #define SVO_WARN_STREAM(x) ROS_WARN_STREAM(x) + #define SVO_WARN_STREAM_THROTTLE(rate, x) ROS_WARN_STREAM_THROTTLE(rate, x) + #define SVO_ERROR_STREAM(x) ROS_ERROR_STREAM(x) +#else + #define SVO_INFO_STREAM(x) std::cerr<<"\033[0;0m[INFO] "< // Adapted from rosconsole. Copyright (c) 2008, Willow Garage, Inc. + #define SVO_WARN_STREAM_THROTTLE(rate, x) \ + do { \ + static double __log_stream_throttle__last_hit__ = 0.0; \ + std::chrono::time_point __log_stream_throttle__now__ = \ + std::chrono::system_clock::now(); \ + if (__log_stream_throttle__last_hit__ + rate <= \ + std::chrono::duration_cast( \ + __log_stream_throttle__now__.time_since_epoch()).count()) { \ + __log_stream_throttle__last_hit__ = \ + std::chrono::duration_cast( \ + __log_stream_throttle__now__.time_since_epoch()).count(); \ + SVO_WARN_STREAM(x); \ + } \ + } while(0) +#endif + +namespace svo +{ + using namespace Eigen; + using namespace Sophus; + + const double EPS = 0.0000000001; + const double PI = 3.14159265; + +#ifdef SVO_TRACE + extern vk::PerformanceMonitor* g_permon; + #define SVO_LOG(value) g_permon->log(std::string((#value)),(value)) + #define SVO_LOG2(value1, value2) SVO_LOG(value1); SVO_LOG(value2) + #define SVO_LOG3(value1, value2, value3) SVO_LOG2(value1, value2); SVO_LOG(value3) + #define SVO_LOG4(value1, value2, value3, value4) SVO_LOG2(value1, value2); SVO_LOG2(value3, value4) + #define SVO_START_TIMER(name) g_permon->startTimer((name)) + #define SVO_STOP_TIMER(name) g_permon->stopTimer((name)) +#else + #define SVO_LOG(v) + #define SVO_LOG2(v1, v2) + #define SVO_LOG3(v1, v2, v3) + #define SVO_LOG4(v1, v2, v3, v4) + #define SVO_START_TIMER(name) + #define SVO_STOP_TIMER(name) +#endif + + class Frame; + typedef boost::shared_ptr FramePtr; +} // namespace svo + +#endif // SVO_GLOBAL_H_ diff --git a/svo/include/svo/initialization.h b/svo/include/svo/initialization.h new file mode 100644 index 0000000..4513086 --- /dev/null +++ b/svo/include/svo/initialization.h @@ -0,0 +1,83 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_INITIALIZATION_H +#define SVO_INITIALIZATION_H + +#include + +namespace svo { + +class FrameHandlerMono; + +/// Bootstrapping the map from the first two views. +namespace initialization { + +enum InitResult { FAILURE, NO_KEYFRAME, SUCCESS }; + +/// Tracks features using Lucas-Kanade tracker and then estimates a homography. +class KltHomographyInit { + friend class svo::FrameHandlerMono; +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + FramePtr frame_ref_; + KltHomographyInit() {}; + ~KltHomographyInit() {}; + InitResult addFirstFrame(FramePtr frame_ref); + InitResult addSecondFrame(FramePtr frame_ref); + void reset(); + +protected: + vector px_ref_; //!< keypoints to be tracked in reference frame. + vector px_cur_; //!< tracked keypoints in current frame. + vector f_ref_; //!< bearing vectors corresponding to the keypoints in the reference image. + vector f_cur_; //!< bearing vectors corresponding to the keypoints in the current image. + vector disparities_; //!< disparity between first and second frame. + vector inliers_; //!< inliers after the geometric check (e.g., Homography). + vector xyz_in_cur_; //!< 3D points computed during the geometric check. + SE3 T_cur_from_ref_; //!< computed transformation between the first two frames. +}; + +/// Detect Fast corners in the image. +void detectFeatures( + FramePtr frame, + vector& px_vec, + vector& f_vec); + +/// Compute optical flow (Lucas Kanade) for selected keypoints. +void trackKlt( + FramePtr frame_ref, + FramePtr frame_cur, + vector& px_ref, + vector& px_cur, + vector& f_ref, + vector& f_cur, + vector& disparities); + +void computeHomography( + const vector& f_ref, + const vector& f_cur, + double focal_length, + double reprojection_threshold, + vector& inliers, + vector& xyz_in_cur, + SE3& T_cur_from_ref); + +} // namespace initialization +} // namespace nslam + +#endif // NSLAM_INITIALIZATION_H diff --git a/svo/include/svo/map.h b/svo/include/svo/map.h new file mode 100644 index 0000000..076ee01 --- /dev/null +++ b/svo/include/svo/map.h @@ -0,0 +1,134 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_MAP_H_ +#define SVO_MAP_H_ + +#include +#include +#include +#include + +namespace svo { + +class Point; +class Feature; +class Seed; + +/// Container for converged 3D points that are not already assigned to two keyframes. +class MapPointCandidates +{ +public: + typedef pair PointCandidate; + typedef list PointCandidateList; + + /// The depth-filter is running in a parallel thread and fills the canidate list. + /// This mutex controls concurrent access to point_candidates. + boost::mutex mut_; + + /// Candidate points are created from converged seeds. + /// Until the next keyframe, these points can be used for reprojection and pose optimization. + PointCandidateList candidates_; + list< Point* > trash_points_; + + MapPointCandidates(); + ~MapPointCandidates(); + + /// Add a candidate point. + void newCandidatePoint(const Seed& seed, const Vector3d& xyz_world); + + /// Adds the feature to the frame and deletes candidate from list. + void addCandidatePointToFrame(FramePtr frame); + + /// Remove a candidate point from the list of candidates. + bool deleteCandidatePoint(Point* point); + + /// Remove all candidates that belong to a frame. + void removeFrameCandidates(FramePtr frame); + + /// Reset the candidate list, remove and delete all points. + void reset(); + + void deleteCandidate(PointCandidate& c); + + void emptyTrash(); +}; + +/// Map object which saves all keyframes which are in a map. +class Map : boost::noncopyable +{ +public: + list< FramePtr > keyframes_; //!< List of keyframes in the map. + list< Point* > trash_points_; //!< A deleted point is moved to the trash bin. Now and then this is cleaned. One reason is that the visualizer must remove the points also. + MapPointCandidates point_candidates_; + + Map(); + ~Map(); + + /// Reset the map. Delete all keyframes and reset the frame and point counters. + void reset(); + + /// Delete a point in the map and remove all references in keyframes to it. + void safeDeletePoint(Point* pt); + + /// Moves the point to the trash queue which is cleaned now and then. + void deletePoint(Point* pt); + + /// Moves the frame to the trash queue which is cleaned now and then. + bool safeDeleteFrame(FramePtr frame); + + /// Remove the references between a point and a frame. + void removePtFrameRef(Frame* frame, Feature* ftr); + + /// Add a new keyframe to the map. + void addKeyframe(FramePtr new_keyframe); + + /// Given a frame, return all keyframes which have an overlapping field of view. + void getCloseKeyframes(const FramePtr& frame, list< pair >& close_kfs) const; + + /// Return the keyframe which is spatially closest and has overlapping field of view. + FramePtr getClosestKeyframe(const FramePtr& frame) const; + + /// Return the keyframe which is furthest apart from pos. + FramePtr getFurthestKeyframe(const Vector3d& pos) const; + + /// Transform the whole map with rotation R, translation t and scale s. + void transform(const Matrix3d& R, const Vector3d& t, const double& s); + + /// Empty trash bin of deleted keyframes and map points. We don't delete the + /// points immediately to ensure proper cleanup and to provide the visualizer + /// a list of objects which must be removed. + void emptyTrash(); + + /// Return the keyframe which was last inserted in the map. + inline FramePtr lastKeyframe() { return keyframes_.back(); } + + /// Return the number of keyframes in the map + inline size_t size() const { return keyframes_.size(); } +}; + +/// A collection of debug functions to check the data consistency. +namespace map_debug { + +void mapStatistics(Map* map); +void mapValidation(Map* map, int id); +void frameValidation(Frame* frame, int id); +void pointValidation(Point* point, int id); + +} // namespace map_debug +} // namespace svo + +#endif // SVO_MAP_H_ diff --git a/svo/include/svo/matcher.h b/svo/include/svo/matcher.h new file mode 100644 index 0000000..b79340b --- /dev/null +++ b/svo/include/svo/matcher.h @@ -0,0 +1,105 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_MATCHER_H_ +#define SVO_MATCHER_H_ + +#include + +namespace vk { + class AbstractCamera; +} + +namespace svo { + +class Point; +class Frame; +class Feature; + +/// Patch-matcher for reprojection-matching and epipolar search in triangulation. +namespace matcher { + +const int g_halfpatch_size = 4; // do not change, because of sse instructions alignment. +const int g_patch_size = 8; // do not change, because of sse instructions alignment. + +/// Manages the aligned memory of a patch. Aligned for SIMD instructions. +struct PatchData +{ + const int patch_size; + uint8_t* patch; + uint8_t* patch_with_border; + PatchData(int patch_size); + ~PatchData(); +}; + +/// Warp a patch from the reference view to the current view. +namespace warp { + +void getWarpMatrixAffine( + const vk::AbstractCamera& cam_ref, + const vk::AbstractCamera& cam_cur, + const Vector2d& px_ref, + const Vector3d& f_ref, + const double depth_ref, + const SE3& T_cur_ref, + const int level_ref, + Matrix2d& A_cur_ref); + +int getBestSearchLevel( + const Matrix2d& A_cur_ref, + const int max_level); + +void warpAffine( + const Matrix2d& A_cur_ref, + const cv::Mat& img_ref, + const Vector2d& px_ref, + const int level_ref, + const int level_cur, + PatchData& ref_patch); + +} // namespace warp + +// TODO take function from vikit +bool depthFromTriangulation( + const SE3& T_cur_ref, + const Vector3d& f_ref, + const Vector3d& f_cur, + double& depth); + +/// Find a match by directly applying subpix refinement. +/// IMPORTANT! This function assumes that px_cur is already set to an estimate that is within ~2-3 pixel of the final result! +bool findMatchDirect( + const Point& pt, + const Frame& frame, + Vector2d& px_cur, + int& level_cur); + +/// Find a match by searching along the epipolar line without using any features. +bool findEpipolarMatchDirect( + const Frame& ref_frame, + const Frame& cur_frame, + const Feature& ref_ftr, + const double d_estimate, + const double d_min, + const double d_max, + const bool align_1d, + double& depth, + double& h_inv); + +} // namespace matcher +} // namespace svo + +#endif // SVO_MATCHER_H_ diff --git a/svo/include/svo/point.h b/svo/include/svo/point.h new file mode 100644 index 0000000..1fa26f0 --- /dev/null +++ b/svo/include/svo/point.h @@ -0,0 +1,83 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_POINT_H_ +#define SVO_POINT_H_ + +#include +#include + +namespace g2o { + class VertexSBAPointXYZ; +} +typedef g2o::VertexSBAPointXYZ g2oPoint; + +namespace svo { + +class Feature; + +typedef Matrix Matrix23d; + +/// A 3D point that was triangulated from at least two corresponding image features. +class Point : boost::noncopyable +{ +public: + + enum PointType {DELETED, CANDIDATE, UNKNOWN_QUALITY, GOOD_QUALITY }; + enum PointOrigin { TRIANGULATION, DEPTH, VOGIATZIS, IDFILTER }; + + static int point_counter_; //!< Counts the number of created points. Used to set the unique id. + int id_; //!< Unique ID of the point. + Vector3d pos_; //!< 3d pos of the point in the world coordinate frame. + list obs_; //!< References to keyframes which observe the point. + size_t n_obs_; //!< Number of obervations, not only keyframes. + g2oPoint* v_pt_; //!< Temporary pointer to the point-vertex in g2o during bundle adjustment. + int last_published_ts_; //!< Timestamp of last publishing. + int last_projected_kf_id_; //!< Flag for the reprojection: don't reproject a pt twice. + PointType type_; //!< Quality of the point. + PointOrigin origin_; //!< What is the source of the point, i.e. DEPTH if a kinect is used. + int n_failed_reproj_; //!< Number of failed reprojections. Used to assess the quality of the point. + int n_succeeded_reproj_; //!< Number of succeeded reprojections. Used to assess the quality of the point. + int last_structure_optim_; + + Point(Vector3d pos, PointOrigin origin); + ~Point(); + + /// Add a reference to a frame. + void addFrameRef(Feature* ftr); + + /// Remove reference to a frame. + bool deleteFrameRef(Frame* frame); + + /// Check whether mappoint has reference to a frame. + Feature* findFrameRef(Frame* frame); + + /// Get Frame with similar viewpoint. + bool getCloseViewObs(const Vector3d& pos, Feature*& obs) const; + + /// Get number of observations. + inline size_t nRefs() const { return obs_.size(); } + + /// Point jacobian w.r.t frame f. + void pointJacobian(const Vector3d& p_in_f, const Matrix3d& R_f_w, Matrix23d& point_jac) const; + + /// Optimize point position through minimizing the reprojection error. + void optimize(const size_t n_iter); +}; + +} // namespace svo + +#endif // SVO_POINT_H_ diff --git a/svo/include/svo/pose_optimizer.h b/svo/include/svo/pose_optimizer.h new file mode 100644 index 0000000..575da32 --- /dev/null +++ b/svo/include/svo/pose_optimizer.h @@ -0,0 +1,77 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_POSE_OPTIMIZER_H_ +#define SVO_POSE_OPTIMIZER_H_ + +#include + +namespace svo { + +using namespace Eigen; +using namespace Sophus; +using namespace std; + +typedef Matrix Matrix6d; +typedef Matrix Matrix26d; +typedef Matrix Vector6d; + +class Point; + +/// Motion-only bundle adjustment. Minimize the reprojection error of a single frame. +namespace pose_optimizer { + +inline Matrix26d +frameJac(const SE3 & T, + const Vector3d & xyz, + const Vector2d & focal_length) +{ + const Vector3d & xyz_trans = T*xyz; + double x = xyz_trans[0]; + double y = xyz_trans[1]; + double z = xyz_trans[2]; + double z_2 = z*z; + Matrix26d frame_jac; + frame_jac(0,0) = -1./z *focal_length[0]; + frame_jac(0,1) = 0; + frame_jac(0,2) = x/z_2 *focal_length[0]; + frame_jac(0,3) = x*y/z_2 * focal_length[0]; + frame_jac(0,4) = -(1+(x*x/z_2)) *focal_length[0]; + frame_jac(0,5) = y/z *focal_length[0]; + + frame_jac(1,0) = 0; + frame_jac(1,1) = -1./z *focal_length[1]; + frame_jac(1,2) = y/z_2 *focal_length[1]; + frame_jac(1,3) = (1+y*y/z_2) *focal_length[1]; + frame_jac(1,4) = -x*y/z_2 *focal_length[1]; + frame_jac(1,5) = -x/z *focal_length[1]; + return frame_jac; +} + +void optimizeGaussNewton( + const double reproj_thresh, + const size_t n_iter, + const bool verbose, + FramePtr& frame, + double& estimated_scale, + double& error_init, + double& error_final, + size_t& num_obs); + +} // namespace pose_optimizer +} // namespace svo + +#endif // SVO_POSE_OPTIMIZER_H_ diff --git a/svo/include/svo/reprojection.h b/svo/include/svo/reprojection.h new file mode 100644 index 0000000..a6ce153 --- /dev/null +++ b/svo/include/svo/reprojection.h @@ -0,0 +1,98 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_REPROJECTION_H_ +#define SVO_REPROJECTION_H_ + +#include +#include + +namespace vk { + class AbstractCamera; +} + +namespace svo { + +class Map; +class Point; +class MapPointCandidates; + +/// Project points from the map into the image and find the corresponding +/// feature (corner). We don't search a match for every point but only for one +/// point per cell. Thereby, we achieve a homogeneously distributed set of +/// matched features and at the same time we can save processing time by not +/// projecting all points. +namespace reprojection { + +/// A candidate is a point that projects into the image plane and for which we +/// will search a maching feature in the image. +struct Candidate { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + Point* pt; //!< 3D point. + Vector2d px; //!< projected 2D pixel location. + Candidate(Point* pt, Vector2d& px) + : pt(pt), + px(px) + {} +}; + +typedef std::list > Cell; +typedef std::vector CandidateGrid; + +/// The grid stores a set of candidate matches. For every grid cell we try to find one match. +struct Grid +{ + CandidateGrid cells; + vector cell_order; + int cell_size; + int grid_n_cols; + int grid_n_rows; + Grid(); + void initialize(vk::AbstractCamera* cam); + ~Grid(); +}; + +/// Reset the grid +void resetGrid(Grid& grid); + +/// Project points from the map into the image. First finds keyframes with +/// overlapping field of view and projects only those map-points. +void reprojectMap( + Map& map, + FramePtr frame, + Grid& grid, + MapPointCandidates& candidate_points, + std::vector< std::pair >& overlap_kfs, + size_t& n_matches, + size_t& n_trials); + +bool reprojectCell( + Cell& cell, + FramePtr frame, + Map& map, + MapPointCandidates& candidate_points, + size_t& n_trials); + +bool reprojectPoint( + Grid& grid, + FramePtr frame, + Point* point); + +} // namespace reprojection +} // namespace svo + +#endif // SVO_REPROJECTION_H_ diff --git a/svo/include/svo/sparse_img_align.h b/svo/include/svo/sparse_img_align.h new file mode 100644 index 0000000..7df0456 --- /dev/null +++ b/svo/include/svo/sparse_img_align.h @@ -0,0 +1,78 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_SPARSE_IMG_ALIGN_H_ +#define SVO_SPARSE_IMG_ALIGN_H_ + +#include +#include +#include + +namespace vk { +class AbstractCamera; +} + +namespace svo { + +class Feature; + +/// Optimize the pose of the frame by minimizing the photometric error of feature patches. +class SparseImgAlign : public vk::NLLSSolver<6, SE3> +{ + static const int patch_halfsize_ = 2; + static const int patch_size_ = 2*patch_halfsize_; + static const int patch_area_ = patch_size_*patch_size_; +public: + + cv::Mat resimg_; + + SparseImgAlign( + int n_levels, + int min_level, + int n_iter, + Method method, + bool display, + bool verbose); + + size_t run( + FramePtr ref_frame, + FramePtr cur_frame); + +protected: + FramePtr ref_frame_; //!< reference frame, has depth for gradient pixels. + FramePtr cur_frame_; //!< only the image is known! + int level_; //!< current pyramid level on which the optimization runs. + bool display_; //!< display residual image. + int max_level_; //!< coarsest pyramid level for the alignment. + int min_level_; //!< finest pyramid level for the alignment. + + // cache: + Matrix jacobian_cache_; //!< the first row is a flag whether the jacobian has been computed. + bool have_ref_patch_cache_; + cv::Mat ref_patch_cache_; + std::vector visible_fts_; + + void precomputeReferencePatches(); + virtual double computeResiduals(const SE3& model, bool linearize_system, bool compute_weight_scale = false); + virtual int solve(); + virtual void update (const ModelType& old_model, ModelType& new_model); + virtual void startIteration(); + virtual void finishIteration(); +}; + +} // namespace svo + +#endif // SVO_SPARSE_IMG_ALIGN_H_ diff --git a/svo/package.xml b/svo/package.xml new file mode 100644 index 0000000..c2997c2 --- /dev/null +++ b/svo/package.xml @@ -0,0 +1,24 @@ + + + svo + 0.1.0 + + Monocular Visual Odometry + + Christian Forster + Christian Forster + GPLv3 + + + catkin + + + roscpp + vikit_common + vikit_ros + + + roscpp + vikit_common + vikit_ros + \ No newline at end of file diff --git a/svo/src/bundle_adjustment.cpp b/svo/src/bundle_adjustment.cpp new file mode 100644 index 0000000..a2075f4 --- /dev/null +++ b/svo/src/bundle_adjustment.cpp @@ -0,0 +1,435 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SCHUR_TRICK 1 + +namespace svo { +namespace ba { + +void +twoViewBA(Frame* frame1, Frame* frame2, + double reproj_thresh, + Map* map) +{ + // scale reprojection threshold in pixels to unit plane + reproj_thresh /= frame1->cam_->errorMultiplier2(); + + // init g2o + g2o::SparseOptimizer optimizer; + setupG2o(&optimizer); + + list edges; + size_t v_id = 0; + + // New Keyframe Vertex 1: This Keyframe is set to fixed! + g2oFrameSE3* v_frame1 = createG2oFrameSE3(frame1, v_id++, true); + optimizer.addVertex(v_frame1); + + // New Keyframe Vertex 2 + g2oFrameSE3* v_frame2 = createG2oFrameSE3(frame2, v_id++, false); + optimizer.addVertex(v_frame2); + + // Create Point Vertices + for(Features::iterator it_ftr=frame1->fts_.begin(); it_ftr!=frame1->fts_.end(); ++it_ftr) + { + Point* pt = (*it_ftr)->point; + if(pt == NULL) + continue; + g2oPoint* v_pt = createG2oPoint(pt->pos_, v_id++, false); + optimizer.addVertex(v_pt); + pt->v_pt_ = v_pt; + g2oEdgeSE3* e = createG2oEdgeSE3(v_frame1, v_pt, vk::project2d((*it_ftr)->f), true, reproj_thresh*Config::lobaRobustHuberWidth()); + optimizer.addEdge(e); + edges.push_back(EdgeContainerSE3(e, frame1, *it_ftr)); // TODO feature now links to frame, so we can simplify edge container! + + // find at which index the second frame observes the point + Feature* ftr_frame2 = pt->findFrameRef(frame2); + e = createG2oEdgeSE3(v_frame2, v_pt, vk::project2d(ftr_frame2->f), true, reproj_thresh*Config::lobaRobustHuberWidth()); + optimizer.addEdge(e); + edges.push_back(EdgeContainerSE3(e, frame2, ftr_frame2)); + } + + // Optimization + double init_error, final_error; + runSparseBAOptimizer(&optimizer, Config::lobaNumIter(), init_error, final_error); + printf("2-View BA: Error before/after = %f / %f\n", init_error, final_error); + + // Update Keyframe Positions + frame1->T_f_w_.rotation_matrix() = v_frame1->estimate().rotation().toRotationMatrix(); + frame1->T_f_w_.translation() = v_frame1->estimate().translation(); + frame2->T_f_w_.rotation_matrix() = v_frame2->estimate().rotation().toRotationMatrix(); + frame2->T_f_w_.translation() = v_frame2->estimate().translation(); + + // Update Mappoint Positions + for(Features::iterator it=frame1->fts_.begin(); it!=frame1->fts_.end(); ++it) + { + if((*it)->point == NULL) + continue; + (*it)->point->pos_ = (*it)->point->v_pt_->estimate(); + (*it)->point->v_pt_ = NULL; + } + + // Find Mappoints with too large reprojection error + const double reproj_thresh_squared = reproj_thresh*reproj_thresh; + size_t n_incorrect_edges = 0; + for(list::iterator it_e = edges.begin(); it_e != edges.end(); ++it_e) + if(it_e->edge_->chi2() > reproj_thresh_squared) + { + if(it_e->feature_->point != NULL) + { + map->safeDeletePoint(it_e->feature_->point); + it_e->feature_->point = NULL; + } + ++n_incorrect_edges; + } + + printf("2-View BA: Wrong edges = %zu\n", n_incorrect_edges); +} + +void +localBA(Frame* center_kf, + set* core_kfs, + Map* map, + size_t& n_incorrect_edges_1, + size_t& n_incorrect_edges_2, + double& init_error, + double& final_error) +{ + + // init g2o + g2o::SparseOptimizer optimizer; + setupG2o(&optimizer); + + list edges; + set mps; + list neib_kfs; + size_t v_id = 0; + size_t n_mps = 0; + size_t n_fix_kfs = 0; + size_t n_var_kfs = 1; + size_t n_edges = 0; + n_incorrect_edges_1 = 0; + n_incorrect_edges_2 = 0; + + // Add all core keyframes + for(set::iterator it_kf = core_kfs->begin(); it_kf != core_kfs->end(); ++it_kf) + { + g2oFrameSE3* v_kf = createG2oFrameSE3(it_kf->get(), v_id++, false); + (*it_kf)->v_kf_ = v_kf; + ++n_var_kfs; + assert(optimizer.addVertex(v_kf)); + + // all points that the core keyframes observe are also optimized: + for(Features::iterator it_pt=(*it_kf)->fts_.begin(); it_pt!=(*it_kf)->fts_.end(); ++it_pt) + if((*it_pt)->point != NULL) + mps.insert((*it_pt)->point); + } + + // Now go throug all the points and add a measurement. Add a fixed neighbour + // Keyframe if it is not in the set of core kfs + double reproj_thresh_2 = Config::lobaThresh() / center_kf->cam_->errorMultiplier2(); + double reproj_thresh_1 = Config::poseOptimThresh() / center_kf->cam_->errorMultiplier2(); + double reproj_thresh_1_squared = reproj_thresh_1*reproj_thresh_1; + for(set::iterator it_pt = mps.begin(); it_pt!=mps.end(); ++it_pt) + { + // Create point vertex + g2oPoint* v_pt = createG2oPoint((*it_pt)->pos_, v_id++, false); + (*it_pt)->v_pt_ = v_pt; + assert(optimizer.addVertex(v_pt)); + ++n_mps; + + // Add edges + Observations::iterator it_obs=(*it_pt)->obs_.begin(); + while(it_obs!=(*it_pt)->obs_.end()) + { + Vector2d error = vk::project2d((*it_obs)->f) - vk::project2d((*it_obs)->frame->w2f((*it_pt)->pos_)); + + if((*it_obs)->frame->v_kf_ == NULL) + { + // frame does not have a vertex yet -> it belongs to the neib kfs and + // is fixed. create one: + g2oFrameSE3* v_kf = createG2oFrameSE3((*it_obs)->frame, v_id++, true); + (*it_obs)->frame->v_kf_ = v_kf; + ++n_fix_kfs; + assert(optimizer.addVertex(v_kf)); + neib_kfs.push_back((*it_obs)->frame); + } + + // create edge + g2oEdgeSE3* e = createG2oEdgeSE3((*it_obs)->frame->v_kf_, v_pt, + vk::project2d((*it_obs)->f), + true, + reproj_thresh_2*Config::lobaRobustHuberWidth(), + 1.0 / (1<<(*it_obs)->level)); + assert(optimizer.addEdge(e)); + edges.push_back(EdgeContainerSE3(e, (*it_obs)->frame, *it_obs)); + ++n_edges; + ++it_obs; + } + } + + // structure only + g2o::StructureOnlySolver<3> structure_only_ba; + g2o::OptimizableGraph::VertexContainer points; + for (g2o::OptimizableGraph::VertexIDMap::const_iterator it = optimizer.vertices().begin(); it != optimizer.vertices().end(); ++it) + { + g2o::OptimizableGraph::Vertex* v = static_cast(it->second); + if (v->dimension() == 3 && v->edges().size() >= 2) + points.push_back(v); + } + structure_only_ba.calc(points, 10); + + // Optimization + if(Config::lobaNumIter() > 0) + runSparseBAOptimizer(&optimizer, Config::lobaNumIter(), init_error, final_error); + + // Update Keyframes + for(set::iterator it = core_kfs->begin(); it != core_kfs->end(); ++it) + { + (*it)->T_f_w_ = SE3( (*it)->v_kf_->estimate().rotation(), + (*it)->v_kf_->estimate().translation()); + (*it)->v_kf_ = NULL; + } + + for(list::iterator it = neib_kfs.begin(); it != neib_kfs.end(); ++it) + (*it)->v_kf_ = NULL; + + // Update Mappoints + for(set::iterator it = mps.begin(); it != mps.end(); ++it) + { + (*it)->pos_ = (*it)->v_pt_->estimate(); + (*it)->v_pt_ = NULL; + } + + // Remove Measurements with too large reprojection error + double reproj_thresh_2_squared = reproj_thresh_2*reproj_thresh_2; + for(list::iterator it = edges.begin(); it != edges.end(); ++it) + { + if(it->edge_->chi2() > reproj_thresh_2_squared) //*(1<feature_->level)) + { + map->removePtFrameRef(it->frame_, it->feature_); + ++n_incorrect_edges_2; + } + } + + // TODO: delete points and edges! + init_error = sqrt(init_error)*center_kf->cam_->errorMultiplier2(); + final_error = sqrt(final_error)*center_kf->cam_->errorMultiplier2(); +} + +void +globalBA(Map* map) +{ + // init g2o + g2o::SparseOptimizer optimizer; + setupG2o(&optimizer); + + list edges; + list< pair > incorrect_edges; + + // Go through all Keyframes + size_t v_id = 0; + double reproj_thresh_2 = Config::lobaThresh() / map->lastKeyframe()->cam_->errorMultiplier2(); + double reproj_thresh_1_squared = Config::poseOptimThresh() / map->lastKeyframe()->cam_->errorMultiplier2(); + reproj_thresh_1_squared *= reproj_thresh_1_squared; + for(list::iterator it_kf = map->keyframes_.begin(); + it_kf != map->keyframes_.end(); ++it_kf) + { + // New Keyframe Vertex + g2oFrameSE3* v_kf = createG2oFrameSE3(it_kf->get(), v_id++, false); + (*it_kf)->v_kf_ = v_kf; + optimizer.addVertex(v_kf); + for(Features::iterator it_ftr=(*it_kf)->fts_.begin(); it_ftr!=(*it_kf)->fts_.end(); ++it_ftr) + { + // for each keyframe add edges to all observed mapoints + Point* mp = (*it_ftr)->point; + if(mp == NULL) + continue; + g2oPoint* v_mp = mp->v_pt_; + if(v_mp == NULL) + { + // mappoint-vertex doesn't exist yet. create a new one: + v_mp = createG2oPoint(mp->pos_, v_id++, false); + mp->v_pt_ = v_mp; + optimizer.addVertex(v_mp); + } + + // Due to merging of mappoints it is possible that references in kfs suddenly + // have a very large reprojection error which may result in distorted results. + Vector2d error = vk::project2d((*it_ftr)->f) - vk::project2d((*it_kf)->w2f(mp->pos_)); + if(error.squaredNorm() > reproj_thresh_1_squared) + incorrect_edges.push_back(pair(*it_kf, *it_ftr)); + else + { + g2oEdgeSE3* e = createG2oEdgeSE3(v_kf, v_mp, vk::project2d((*it_ftr)->f), + true, + reproj_thresh_2*Config::lobaRobustHuberWidth()); + + edges.push_back(EdgeContainerSE3(e, it_kf->get(), *it_ftr)); + optimizer.addEdge(e); + } + } + } + + // Optimization + double init_error=0.0, final_error=0.0; + if(Config::lobaNumIter() > 0) + runSparseBAOptimizer(&optimizer, Config::lobaNumIter(), init_error, final_error); + + // Update Keyframe and MapPoint Positions + for(list::iterator it_kf = map->keyframes_.begin(); + it_kf != map->keyframes_.end(); ++it_kf) + { + (*it_kf)->T_f_w_ = SE3( (*it_kf)->v_kf_->estimate().rotation(), + (*it_kf)->v_kf_->estimate().translation()); + (*it_kf)->v_kf_ = NULL; + for(Features::iterator it_ftr=(*it_kf)->fts_.begin(); it_ftr!=(*it_kf)->fts_.end(); ++it_ftr) + { + Point* mp = (*it_ftr)->point; + if(mp == NULL) + continue; + if(mp->v_pt_ == NULL) + continue; // mp was updated before + mp->pos_ = mp->v_pt_->estimate(); + mp->v_pt_ = NULL; + } + } + + // Remove Measurements with too large reprojection error + for(list< pair >::iterator it=incorrect_edges.begin(); + it!=incorrect_edges.end(); ++it) + map->removePtFrameRef(it->first.get(), it->second); + + double reproj_thresh_2_squared = reproj_thresh_2*reproj_thresh_2; + for(list::iterator it = edges.begin(); it != edges.end(); ++it) + { + if(it->edge_->chi2() > reproj_thresh_2_squared) + { + map->removePtFrameRef(it->frame_, it->feature_); + } + } +} + +void +setupG2o(g2o::SparseOptimizer * optimizer) +{ + // TODO: What's happening with all this HEAP stuff? Memory Leak? + optimizer->setVerbose(false); + +#if SCHUR_TRICK + // solver + g2o::BlockSolver_6_3::LinearSolverType* linearSolver; + linearSolver = new g2o::LinearSolverCholmod(); + //linearSolver = new g2o::LinearSolverCSparse(); + + g2o::BlockSolver_6_3 * solver_ptr = new g2o::BlockSolver_6_3(linearSolver); + g2o::OptimizationAlgorithmLevenberg * solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr); +#else + g2o::BlockSolverX::LinearSolverType * linearSolver; + linearSolver = new g2o::LinearSolverCholmod(); + //linearSolver = new g2o::LinearSolverCSparse(); + g2o::BlockSolverX * solver_ptr = new g2o::BlockSolverX(linearSolver); + g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr); +#endif + + solver->setMaxTrialsAfterFailure(5); + optimizer->setAlgorithm(solver); + + // setup camera + g2o::CameraParameters * cam_params = new g2o::CameraParameters(1.0, Vector2d(0.,0.), 0.); + cam_params->setId(0); + if (!optimizer->addParameter(cam_params)) { + assert(false); + } +} + +void +runSparseBAOptimizer(g2o::SparseOptimizer* optimizer, + unsigned int num_iter, + double& init_error, double& final_error) +{ + optimizer->initializeOptimization(); + optimizer->computeActiveErrors(); + init_error = optimizer->activeChi2(); + optimizer->optimize(num_iter); + final_error = optimizer->activeChi2(); +} + +g2oFrameSE3* +createG2oFrameSE3(Frame* frame, size_t id, bool fixed) +{ + g2oFrameSE3* v = new g2oFrameSE3(); + v->setId(id); + v->setFixed(fixed); + v->setEstimate(g2o::SE3Quat(frame->T_f_w_.unit_quaternion(), frame->T_f_w_.translation())); + return v; +} + +g2oPoint* +createG2oPoint(Vector3d pos, + size_t id, + bool fixed) +{ + g2oPoint* v = new g2oPoint(); + v->setId(id); +#if SCHUR_TRICK + v->setMarginalized(true); +#endif + v->setFixed(fixed); + v->setEstimate(pos); + return v; +} + +g2oEdgeSE3* +createG2oEdgeSE3( g2oFrameSE3* v_frame, + g2oPoint* v_point, + const Vector2d& f_up, + bool robust_kernel, + double huber_width, + double weight) +{ + g2oEdgeSE3* e = new g2oEdgeSE3(); + e->setVertex(0, dynamic_cast(v_point)); + e->setVertex(1, dynamic_cast(v_frame)); + e->setMeasurement(f_up); + e->information() = weight * Eigen::Matrix2d::Identity(2,2); + g2o::RobustKernelHuber* rk = new g2o::RobustKernelHuber(); // TODO: memory leak + rk->setDelta(huber_width); + e->setRobustKernel(rk); + e->setParameterId(0, 0); //old: e->setId(v_point->id()); + return e; +} + +} // namespace ba +} // namespace svo diff --git a/svo/src/config.cpp b/svo/src/config.cpp new file mode 100644 index 0000000..c8593c4 --- /dev/null +++ b/svo/src/config.cpp @@ -0,0 +1,95 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifdef USE_ROS +#include +#endif +#include + +namespace svo { + +Config::Config() : +#ifdef USE_ROS + trace_name(vk::getParam("svo/trace_name", "svo")), + trace_dir(vk::getParam("svo/trace_dir", "/tmp")), + n_pyr_levels(vk::getParam("svo/n_pyr_levels", 3)), + use_imu(vk::getParam("svo/use_imu", false)), + core_n_kfs(vk::getParam("svo/core_n_kfs", 3)), + map_scale(vk::getParam("svo/map_scale", 1.0)), + grid_size(vk::getParam("svo/grid_size", 30)), + init_min_disparity(vk::getParam("svo/init_min_disparity", 50.0)), + init_min_tracked(vk::getParam("svo/init_min_tracked", 50)), + init_min_inliers(vk::getParam("svo/init_min_inliers", 40)), + klt_max_level(vk::getParam("svo/klt_max_level", 4)), + klt_min_level(vk::getParam("svo/klt_min_level", 2)), + reproj_thresh(vk::getParam("svo/reproj_thresh", 2.0)), + poseoptim_thresh(vk::getParam("svo/poseoptim_thresh", 2.0)), + poseoptim_num_iter(vk::getParam("svo/poseoptim_num_iter", 10)), + structureoptim_max_pts(vk::getParam("svo/structureoptim_max_pts", 20)), + structureoptim_num_iter(vk::getParam("svo/structureoptim_num_iter", 5)), + loba_thresh(vk::getParam("svo/loba_thresh", 2.0)), + loba_robust_huber_width(vk::getParam("svo/loba_robust_huber_width", 1.0)), + loba_num_iter(vk::getParam("svo/loba_num_iter", 0)), + kfselect_mindist(vk::getParam("svo/kfselect_mindist", 0.12)), + triang_min_corner_score(vk::getParam("svo/triang_min_corner_score", 20.0)), + triang_half_patch_size(vk::getParam("svo/triang_half_patch_size", 4)), + subpix_n_iter(vk::getParam("svo/subpix_n_iter", 10)), + max_n_kfs(vk::getParam("svo/max_n_kfs", 10)), + img_imu_delay(vk::getParam("svo/img_imu_delay", 0.0)), + max_fts(vk::getParam("svo/max_fts", 120)), + quality_min_fts(vk::getParam("svo/quality_min_fts", 50)), + quality_max_drop_fts(vk::getParam("svo/quality_max_drop_fts", 40)) +#else + trace_name("svo"), + trace_dir("/tmp"), + n_pyr_levels(3), + use_imu(false), + core_n_kfs(3), + map_scale(1.0), + grid_size(25), + init_min_disparity(50.0), + init_min_tracked(50), + init_min_inliers(40), + klt_max_level(4), + klt_min_level(2), + reproj_thresh(2.0), + poseoptim_thresh(2.0), + poseoptim_num_iter(10), + structureoptim_max_pts(20), + structureoptim_num_iter(5), + loba_thresh(2.0), + loba_robust_huber_width(1.0), + loba_num_iter(0), + kfselect_mindist(0.12), + triang_min_corner_score(20.0), + triang_half_patch_size(4), + subpix_n_iter(10), + max_n_kfs(0), + img_imu_delay(0.0), + max_fts(120), + quality_min_fts(50), + quality_max_drop_fts(40) +#endif +{} + +Config& Config::getInstance() +{ + static Config instance; // Instantiated on first use and guaranteed to be destroyed + return instance; +} + +} // namespace svo + diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp new file mode 100644 index 0000000..8acd71d --- /dev/null +++ b/svo/src/depth_filter.cpp @@ -0,0 +1,362 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +int Seed::batch_counter = 0; +int Seed::seed_counter = 0; + +Seed::Seed(Feature* ftr, float angle, float depth_mean, float depth_min) : + batch_id(batch_counter), + id(seed_counter++), + ftr(ftr), + a(10), + b(10), + mu(1.0/depth_mean), + z_range(1.0/depth_min), + sigma2(z_range*z_range/36) +{} + +DepthFilter::DepthFilter(feature_detection::DetectorPtr feature_detector, callback_t seed_converged_cb) : + feature_detector_(feature_detector), + seed_converged_cb_(seed_converged_cb), + seeds_updating_halt_(false), + thread_(NULL), + new_keyframe_set_(false), + new_keyframe_min_depth_(0.0), + new_keyframe_mean_depth_(0.0) +{} + +DepthFilter::~DepthFilter() +{ + stopThread(); + SVO_INFO_STREAM("DepthFilter destructed."); +} + +void DepthFilter::startThread() +{ + thread_ = new boost::thread(&DepthFilter::updateSeedsLoop, this); +} + +void DepthFilter::stopThread() +{ + SVO_INFO_STREAM("DepthFilter stop thread invoked."); + if(thread_ != NULL) + { + SVO_INFO_STREAM("DepthFilter interrupt and join thread... "); + seeds_updating_halt_ = true; + thread_->interrupt(); + thread_->join(); + thread_ = NULL; + } +} + +void DepthFilter::addFrame(FramePtr frame) +{ + if(thread_ != NULL) + { + { + lock_t lock(frame_queue_mut_); + if(frame_queue_.size() > 2) + frame_queue_.pop(); + frame_queue_.push(frame); + } + seeds_updating_halt_ = false; + frame_queue_cond_.notify_one(); + } + else + updateSeeds(frame); +} + +void DepthFilter::addKeyframe(FramePtr frame, double depth_mean, double depth_min) +{ + new_keyframe_min_depth_ = depth_min; + new_keyframe_mean_depth_ = depth_mean; + if(thread_ != NULL) + { + new_keyframe_ = frame; + new_keyframe_set_ = true; + seeds_updating_halt_ = true; + frame_queue_cond_.notify_one(); + } + else + initializeSeeds(frame); +} + +void DepthFilter::initializeSeeds(FramePtr frame) +{ + feature_detection::Corners corners; + feature_detector_->detect(frame->img_pyr_, frame->fts_, svo::Config::gridSize(), + svo::Config::nPyrLevels(), Config::triangMinCornerScore(), + &corners); + + seeds_updating_halt_ = true; + lock_t lock(seeds_mut_); // by locking the updateSeeds function stops + size_t new_seeds = 0; + ++Seed::batch_counter; + + // now for all maximum corners, initialize a new seed + for(feature_detection::Corners::iterator it=corners.begin(); it!=corners.end(); ++it) + { + // we must check again if the score is above the threshold because the Corners + // vector is initialized with dummy corners + if(it->score > Config::triangMinCornerScore()) + { + Feature* new_feature(new Feature(frame.get(), Vector2d(it->x, it->y), it->level)); + seeds_.push_back(Seed(new_feature, it->angle, new_keyframe_mean_depth_, new_keyframe_min_depth_)); + ++new_seeds; + } + } + + if(options_.verbose) + SVO_INFO_STREAM("DepthFilter: Initialized "<::iterator it=seeds_.begin(); + size_t n_removed = 0; + while(it!=seeds_.end()) + { + if(it->ftr->frame == frame.get()) + { + it = seeds_.erase(it); + ++n_removed; + } + else + ++it; + } + seeds_updating_halt_ = false; + //printf("Vogiatzis: removed %zu seeds belonging to old keyframe\n", n_removed); +} + +void DepthFilter::reset() +{ + seeds_updating_halt_ = true; + { + lock_t lock(seeds_mut_); + seeds_.clear(); + } + lock_t lock(); + while(!frame_queue_.empty()) + frame_queue_.pop(); + seeds_updating_halt_ = false; + + if(options_.verbose) + SVO_INFO_STREAM("DepthFilter: RESET."); +} + +void DepthFilter::updateSeedsLoop() +{ + while(!boost::this_thread::interruption_requested()) + { + FramePtr frame; + { + lock_t lock(frame_queue_mut_); + while(frame_queue_.empty() && new_keyframe_set_ == false) + frame_queue_cond_.wait(lock); + if(new_keyframe_set_) + { + new_keyframe_set_ = false; + clearFrameQueue(); + initializeSeeds(new_keyframe_); + continue; + } + frame = frame_queue_.front(); + frame_queue_.pop(); + } + updateSeeds(frame); + } +} + +void DepthFilter::updateSeeds(FramePtr frame) +{ + // update only a limited number of seeds, because we don't have time to do it + // for all the seeds in every frame! + size_t n_updates=0, n_failed_matches=0, n_seeds = seeds_.size(); + double reproj_thresh = Config::lobaThresh() / frame->cam_->errorMultiplier2(); + lock_t lock(seeds_mut_); + list::iterator it=seeds_.begin(); + + const double focal_length = frame->cam_->errorMultiplier2(); + double px_noise = 1.0; + double px_error_angle = atan(px_noise/(2.0*focal_length))*2.0; // law of chord (sehnensatz) + + while( it!=seeds_.end()) + { + // set this value true when seeds updating should be interrupted + if(seeds_updating_halt_) + return; + + // check if seed is not already too old + if((Seed::batch_counter - it->batch_id) > options_.max_n_kfs) { + it = seeds_.erase(it); + continue; + } + + SE3 T_ref_cur = it->ftr->frame->T_f_w_ * frame->T_f_w_.inverse(); + + // check if point is visible in the current image + const Vector3d xyz_f(T_ref_cur.inverse()*(1.0/it->mu * it->ftr->f) ); + if(xyz_f.z() < 0.0) { + ++it; // behind the camera + continue; + } + const Vector2d px(it->ftr->frame->f2c(xyz_f)); + if(!it->ftr->frame->cam_->isInFrame(px.cast())) { + ++it; + if(options_.verbose) + SVO_INFO_STREAM("not visible"); + continue; + } + + // we are using inverse depth coordinates + float z_inv_min = it->mu + sqrt(it->sigma2); + float z_inv_max = max(it->mu - sqrt(it->sigma2), 0.00000001f); + double z, h_inv = -1.0; + if(!matcher::findEpipolarMatchDirect( + *it->ftr->frame, *frame, *it->ftr, 1.0/it->mu, 1.0/z_inv_min, 1.0/z_inv_max, + options_.epi_search_1d, z, h_inv)) + { + if(options_.verbose) + SVO_INFO_STREAM("no match found"); + it->b++; // increase outlier probability when no match was found + ++it; + ++n_failed_matches; + continue; + } + + if(options_.use_photometric_disparity_error && h_inv > 0) + { + px_noise = fmax(2.0*options_.sigma_i_sq*h_inv, 1.0); + px_error_angle = atan(px_noise/(2.0*focal_length))*2.0; // law of chord (sehnensatz) + if(options_.verbose) + SVO_INFO_STREAM("Photometric disparity error "<ftr->f, z, px_error_angle); + double tau_inverse = 0.5 * (1.0/max(0.0000001, z-tau) - 1.0/(z+tau)); + + // update the estimate + updateSeed(1./z, tau_inverse*tau_inverse, &*it); + ++n_updates; + + // if the seed has converged, we initialize a new candidate point and remove the seed + if(sqrt(it->sigma2) < it->z_range/options_.seed_convergence_sigma2_thresh) + { + if(it->ftr->point == NULL) + { + Vector3d xyz_world(it->ftr->frame->T_f_w_.inverse() * (it->ftr->f * (1.0/it->mu))); + seed_converged_cb_(*it, xyz_world); + if(options_.verbose) + SVO_INFO_STREAM("seed converged"); + } + it = seeds_.erase(it); + } + else if(isnan(z_inv_min)) + { + SVO_WARN_STREAM("z_min is NaN"); + it = seeds_.erase(it); + } + else + ++it; + } +} + +void DepthFilter:: +clearFrameQueue() +{ + while(!frame_queue_.empty()) + frame_queue_.pop(); +} + +void DepthFilter::getSeedsCopy(const FramePtr& frame, std::list& seeds) +{ + lock_t lock(seeds_mut_); + for(std::list::iterator it=seeds_.begin(); it!=seeds_.end(); ++it) + { + if (it->ftr->frame == frame.get()) + seeds.push_back(*it); + } +} + +void DepthFilter::updateSeed(const float x, const float tau2, Seed* seed) +{ + float norm_scale = sqrt(seed->sigma2 + tau2); + if(isnanf(norm_scale)) + return; + boost::math::normal_distribution nd(seed->mu, norm_scale); + float s2 = 1./(1./seed->sigma2 + 1./tau2); + float m = s2*(seed->mu/seed->sigma2 + x/tau2); + float C1 = seed->a/(seed->a+seed->b) * boost::math::pdf(nd, x); + float C2 = seed->b/(seed->a+seed->b) * 1./seed->z_range; + float normalization_constant = C1 + C2; + C1 /= normalization_constant; + C2 /= normalization_constant; + float f = C1*(seed->a+1.)/(seed->a+seed->b+1.) + C2*seed->a/(seed->a+seed->b+1.); + float e = C1*(seed->a+1.)*(seed->a+2.)/((seed->a+seed->b+1.)*(seed->a+seed->b+2.)) + + C2*seed->a*(seed->a+1.0f)/((seed->a+seed->b+1.0f)*(seed->a+seed->b+2.0f)); + + // update parameters + float mu_new = C1*m+C2*seed->mu; + seed->sigma2 = C1*(s2 + m*m) + C2*(seed->sigma2 + seed->mu*seed->mu) - mu_new*mu_new; + seed->mu = mu_new; + seed->a = (e-f)/(f-e/f); + seed->b = seed->a*(1.0f-f)/f; +} + +double DepthFilter::computeTau( + const SE3& T_ref_cur, + const Vector3d& f, + const double z, + const double px_error_angle) +{ + Vector3d t(T_ref_cur.translation()); + Vector3d a = f*z-t; + double t_norm = t.norm(); + double a_norm = a.norm(); + double alpha = acos(f.dot(t)/t_norm); // dot product + double beta = acos(a.dot(-t)/(t_norm*a_norm)); // dot product + double beta_plus = beta + px_error_angle; + double gamma_plus = PI-alpha-beta_plus; // triangle angles sum to PI + double z_plus = t_norm*sin(beta_plus)/sin(gamma_plus); // law of sines + return (z_plus - z); // tau +} + +} // namespace svo diff --git a/svo/src/feature_alignment.cpp b/svo/src/feature_alignment.cpp new file mode 100644 index 0000000..15dcee3 --- /dev/null +++ b/svo/src/feature_alignment.cpp @@ -0,0 +1,601 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifdef __SSE2__ +#include +#endif +#ifdef __ARM_NEON__ +#include +#endif +#include + +namespace svo { +namespace feature_alignment { + +#define SUBPIX_VERBOSE 0 + +bool align1D( + const cv::Mat& cur_img, + const Vector2f& dir, // direction in which the patch is allowed to move + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate, + double& h_inv) +{ + const int halfpatch_size_ = 4; + const int patch_size = 8; + const int patch_area = 64; + bool converged=false; + + // compute derivative of template and prepare inverse compositional + float __attribute__((__aligned__(16))) ref_patch_dv[patch_area]; + Matrix2f H; H.setZero(); + + // compute gradient and hessian + const int ref_step = patch_size+2; + float* it_dv = ref_patch_dv; + for(int y=0; y= cur_img.cols-halfpatch_size_ || v_r >= cur_img.rows-halfpatch_size_) + break; + + if(isnan(u) || isnan(v)) // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check + return false; + + // compute interpolation weights + float subpix_x = u-u_r; + float subpix_y = v-v_r; + float wTL = (1.0-subpix_x)*(1.0-subpix_y); + float wTR = subpix_x * (1.0-subpix_y); + float wBL = (1.0-subpix_x)*subpix_y; + float wBR = subpix_x * subpix_y; + + // loop through search_patch, interpolate + uint8_t* it_ref = ref_patch; + float* it_ref_dv = ref_patch_dv; + float new_chi2 = 0.0; + Vector2f Jres; Jres.setZero(); + for(int y=0; y 0 && new_chi2 > chi2) + { +#if SUBPIX_VERBOSE + cout << "error increased." << endl; +#endif + u -= update[0]; + v -= update[1]; + break; + } + + chi2 = new_chi2; + update = Hinv * Jres; + u += update[0]*dir[0]; + v += update[0]*dir[1]; + mean_diff += update[1]; + +#if SUBPIX_VERBOSE + cout << "Iter " << iter << ":" + << "\t u=" << u << ", v=" << v + << "\t update = " << update[0] << ", " << update[1] + << "\t new chi2 = " << new_chi2 << endl; +#endif + + if(update[0]*update[0]+update[1]*update[1] < min_update_squared) + { +#if SUBPIX_VERBOSE + cout << "converged." << endl; +#endif + converged=true; + break; + } + } + + cur_px_estimate << u, v; + return converged; +} + +bool align2D( + const cv::Mat& cur_img, + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate, + bool no_simd) +{ +#ifdef __ARM_NEON__ + if(!no_simd) + return align2D_NEON(cur_img, ref_patch_with_border, ref_patch, n_iter, cur_px_estimate); +#endif + + const int halfpatch_size_ = 4; + const int patch_size_ = 8; + const int patch_area_ = 64; + bool converged=false; + + // compute derivative of template and prepare inverse compositional + float __attribute__((__aligned__(16))) ref_patch_dx[patch_area_]; + float __attribute__((__aligned__(16))) ref_patch_dy[patch_area_]; + Matrix3f H; H.setZero(); + + // compute gradient and hessian + const int ref_step = patch_size_+2; + float* it_dx = ref_patch_dx; + float* it_dy = ref_patch_dy; + for(int y=0; y= cur_img.cols-halfpatch_size_ || v_r >= cur_img.rows-halfpatch_size_) + break; + + if(isnan(u) || isnan(v)) // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check + return false; + + // compute interpolation weights + float subpix_x = u-u_r; + float subpix_y = v-v_r; + float wTL = (1.0-subpix_x)*(1.0-subpix_y); + float wTR = subpix_x * (1.0-subpix_y); + float wBL = (1.0-subpix_x)*subpix_y; + float wBR = subpix_x * subpix_y; + + // loop through search_patch, interpolate + uint8_t* it_ref = ref_patch; + float* it_ref_dx = ref_patch_dx; + float* it_ref_dy = ref_patch_dy; + float new_chi2 = 0.0; + Vector3f Jres; Jres.setZero(); + for(int y=0; y 0 && new_chi2 > chi2) + { +#if SUBPIX_VERBOSE + cout << "error increased." << endl; +#endif + u -= update[0]; + v -= update[1]; + break; + } + + chi2 = new_chi2; + update = Hinv * Jres; + u += update[0]; + v += update[1]; + mean_diff += update[2]; + +#if SUBPIX_VERBOSE + cout << "Iter " << iter << ":" + << "\t u=" << u << ", v=" << v + << "\t update = " << update[0] << ", " << update[1] + << "\t new chi2 = " << new_chi2 << endl; +#endif + + if(update[0]*update[0]+update[1]*update[1] < min_update_squared) + { +#if SUBPIX_VERBOSE + cout << "converged." << endl; +#endif + converged=true; + break; + } + } + + cur_px_estimate << u, v; + return converged; +} + +#define DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n)) // rounds to closest integer and descales + +bool align2D_SSE2( + const cv::Mat& cur_img, + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate) +{ + // TODO: This function should not be used as the alignment is not robust to illumination changes! + const int halfpatch_size = 4; + const int patch_size = 8; + const int patch_area = 64; + bool converged=false; + const int W_BITS = 14; + + // compute derivative of template and prepare inverse compositional + int16_t __attribute__((__aligned__(16))) ref_patch_dx[patch_area]; + int16_t __attribute__((__aligned__(16))) ref_patch_dy[patch_area]; + + // compute gradient and hessian + const int ref_step = patch_size+2; + int16_t* it_dx = ref_patch_dx; + int16_t* it_dy = ref_patch_dy; + float A11=0, A12=0, A22=0; + for(int y=0; y(it[1]) - it[-1]; + int16_t dy = static_cast(it[ref_step]) - it[-ref_step]; + *it_dx = dx; + *it_dy = dy; // we are missing a factor 1/2 + A11 += static_cast(dx*dx); // we are missing a factor 1/4 + A12 += static_cast(dx*dy); + A22 += static_cast(dy*dy); + } + } + + // Compute pixel location in new image: + float u = cur_px_estimate.x(); + float v = cur_px_estimate.y(); + + // termination condition + const float min_update_squared = 0.03*0.03; + const int cur_step = cur_img.step.p[0]; + const float Dinv = 1.0f/(A11*A22 - A12*A12); // we are missing an extra factor 16 + float chi2 = 0; + float update_u = 0, update_v = 0; + + for(int iter = 0; iter= cur_img.cols-halfpatch_size || v_r >= cur_img.rows-halfpatch_size) + break; + + if(isnan(u) || isnan(v)) // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check + return false; + + float subpix_x = u-u_r; + float subpix_y = v-v_r; + float b1=0, b2=0; + float new_chi2 = 0.0; + +#ifdef __SSE2__ + // compute bilinear interpolation weights + int wTL = static_cast((1.0f-subpix_x)*(1.0f-subpix_y)*(1 << W_BITS)); + int wTR = static_cast(subpix_x * (1.0f-subpix_y)*(1 << W_BITS)); + int wBL = static_cast((1.0f-subpix_x)*subpix_y*(1 << W_BITS)); + int wBR = (1 << W_BITS) - wTL - wTR - wBL; + + __m128i qw0 = _mm_set1_epi32(wTL + (wTR << 16)); // Sets the 4 signed 32-bit integer values to [wTL, wTR]. + __m128i qw1 = _mm_set1_epi32(wBL + (wBR << 16)); + __m128i z = _mm_setzero_si128(); + __m128 qb0 = _mm_setzero_ps(); // 4 floats + __m128 qb1 = _mm_setzero_ps(); // 4 floats + __m128i qdelta = _mm_set1_epi32(1 << (W_BITS-1)); + for(int y=0; y(it[1] - it[-1]); + *it_dy = static_cast(it[ref_step] - it[-ref_step]); // divide by 2 missing + Vector3f J(*it_dx, *it_dy, 1.0f); + H += J*J.transpose(); + } + } + Matrix3f Hinv = H.inverse(); + float mean_diff = 0.0; + + // Compute pixel location in new image: + float u = cur_px_estimate.x(); + float v = cur_px_estimate.y(); + + // termination condition + const float min_update_squared = 0.03*0.03; + const int cur_step = cur_img.step.p[0]; + Vector3f update; + Vector3f Jres; + for(int iter = 0; iter= cur_img.cols-halfpatch_size || v_r >= cur_img.rows-halfpatch_size) + break; + + if(isnan(u) || isnan(v)) // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check + return false; + + float subpix_x = u-u_r; + float subpix_y = v-v_r; + float b1=0, b2=0; + +#ifdef __ARM_NEON__ + const int SHIFT_BITS = 7; + const uint16_t wTL = static_cast((1.0f-subpix_x)*(1.0f-subpix_y)*(1<(subpix_x*(1.0f-subpix_y)*(1<((1.0f-subpix_x)*subpix_y*(1<((1 << SHIFT_BITS) - wTL - wTR - wBL); + + // initialize result to zero + int32x4_t vb1 = vdupq_n_s32(0); + int32x4_t vb2 = vdupq_n_s32(0); + int16x8_t vmean_diff = vdupq_n_s16( (int16_t) (mean_diff+0.5) ); + int16x8_t vres_sum = vdupq_n_s16(0); + for(int y=0; y Vr[i] := Va[i] + Vb[i] * Vc[i] + // int32x4_t vmlal_s16(int32x4_t a, int16x4_t b, int16x4_t c); // VMLAL.S16 q0,d0,d0 + int16x8_t grad = vld1q_s16(ref_patch_dx + y*patch_size); + vb1 = vmlal_s16(vb1, vget_low_s16(grad), vget_low_s16(res)); + vb1 = vmlal_s16(vb1, vget_high_s16(grad), vget_high_s16(res)); + + grad = vld1q_s16(ref_patch_dy + y*patch_size); + vb2 = vmlal_s16(vb2, vget_low_s16(grad), vget_low_s16(res)); + vb2 = vmlal_s16(vb2, vget_high_s16(grad), vget_high_s16(res)); + } + + // finally, sum results of vb1, vb2 and vres_sum + int32x2_t tmp; + tmp = vpadd_s32(vget_low_s32(vb1), vget_high_s32(vb1)); + Jres[0] = -vget_lane_s32(tmp, 0) - vget_lane_s32(tmp, 1); + + tmp = vpadd_s32(vget_low_s32(vb2), vget_high_s32(vb2)); + Jres[1] = -vget_lane_s32(tmp, 0) - vget_lane_s32(tmp, 1); + + int32x4_t vres_sum1 = vpaddlq_s16(vres_sum); + tmp = vpadd_s32(vget_low_s32(vres_sum1), vget_high_s32(vres_sum1)); + Jres[2] = -vget_lane_s32(tmp, 0) - vget_lane_s32(tmp, 1); +#endif + + update = Hinv * Jres * 2; // * 2 to compensate because above, we did not compute the derivative correctly + u += update[0]; + v += update[1]; + mean_diff += update[2]; + +#if SUBPIX_VERBOSE + cout << "Iter " << iter << ":" + << "\t u=" << u << ", v=" << v + << "\t update = " << update[0] << ", " << update[1] << endl; +#endif + + if(update[0]*update[0]+update[1]*update[1] < min_update_squared) + { +#if SUBPIX_VERBOSE + cout << "converged." << endl; +#endif + converged=true; + break; + } + } + + cur_px_estimate << u, v; + return converged; +} + +} // namespace feature_alignment +} // namespace svo diff --git a/svo/src/feature_detection.cpp b/svo/src/feature_detection.cpp new file mode 100644 index 0000000..be0ca02 --- /dev/null +++ b/svo/src/feature_detection.cpp @@ -0,0 +1,77 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include + +namespace svo { +namespace feature_detection { + +void FastDetector::detect( + const ImgPyr& img_pyr, + const Features& existing_fts, + const int cell_size, + const int n_levels, + const double detection_threshold, + Corners* corners) const +{ + // first, find which parts of the image already have a matched feature + const int grid_n_cols = ceil(static_cast(img_pyr[0].cols)/cell_size); + const int grid_n_rows = ceil(static_cast(img_pyr[0].rows)/cell_size); + vector occupancy(grid_n_cols*grid_n_rows, false); + for(Features::const_iterator it=existing_fts.begin(); it!=existing_fts.end(); ++it) + { + if((*it)->point == false) + continue; + const int k = static_cast((*it)->px[1]/cell_size)*grid_n_cols + static_cast((*it)->px[0]/cell_size); + occupancy.at(k) = true; + } + + // now, detect features and perform nonmax suppression + corners->resize(grid_n_cols*grid_n_rows, Corner(0,0,detection_threshold,0,0.0f)); + for(int L=0; L fast_corners; +#if __SSE2__ + fast::fast_corner_detect_10_sse2((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); +#elif HAVE_FAST_NEON + fast::fast_corner_detect_9_neon((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); +#else + fast::fast_corner_detect_10((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); +#endif + vector scores, nm_corners; + fast::fast_corner_score_10((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, fast_corners, 20, scores); + fast::fast_nonmax_3x3(fast_corners, scores, nm_corners); + + for(vector::iterator it=nm_corners.begin(); it!=nm_corners.end(); ++it) + { + fast::fast_xy& xy = fast_corners.at(*it); + const int k = static_cast((xy.y*scale)/cell_size)*grid_n_cols + static_cast((xy.x*scale)/cell_size); + if(occupancy[k]) + continue; + const float score = vk::shiTomasiScore(img_pyr[L], xy.x, xy.y); + if(score > corners->at(k).score) + corners->at(k) = Corner(xy.x*scale, xy.y*scale, score, L, 0.0f); + } + } +} + +} // namespace feature_detection +} // namespace svo + diff --git a/svo/src/frame.cpp b/svo/src/frame.cpp new file mode 100644 index 0000000..e5f4501 --- /dev/null +++ b/svo/src/frame.cpp @@ -0,0 +1,197 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +int Frame::frame_counter_ = 0; + +Frame::Frame(vk::AbstractCamera* cam, const cv::Mat& img, double timestamp) : + id_(frame_counter_++), + timestamp_(timestamp), + cam_(cam), + key_pts_(5), + is_keyframe_(false), + v_kf_(NULL) +{ + initFrame(img); +} + +Frame::~Frame() +{ + std::for_each(fts_.begin(), fts_.end(), [&](Feature* i){delete i;}); +} + +void Frame::initFrame(const cv::Mat& img) +{ + // check image + if(img.empty() || img.type() != CV_8UC1 || img.cols != cam_->width() || img.rows != cam_->height()) + throw std::runtime_error("Frame: provided image has not the same size as the camera model"); + + // Set keypoints to NULL + std::for_each(key_pts_.begin(), key_pts_.end(), [&](Feature* ftr){ ftr=NULL; }); + + // Build Image Pyramid + frame_utils::createImgPyramid(img, max(Config::nPyrLevels(), Config::kltMaxLevel()+1), img_pyr_); +} + +void Frame::setKeyframe() +{ + is_keyframe_ = true; + setKeyPoints(); +} + +void Frame::addFeature(Feature* ftr) +{ + fts_.push_back(ftr); +} + +void Frame::setKeyPoints() +{ + for(size_t i = 0; i < 5; ++i) + if(key_pts_[i] != NULL) + if(key_pts_[i]->point == NULL) + key_pts_[i] = NULL; + + std::for_each(fts_.begin(), fts_.end(), [&](Feature* ftr){ if(ftr->point != NULL) checkKeyPoints(ftr); }); +} + +void Frame::checkKeyPoints(Feature* ftr) +{ + const int cu = cam_->width()/2; + const int cv = cam_->height()/2; + + // center pixel + if(key_pts_[0] == NULL) + key_pts_[0] = ftr; + else if(max(abs(ftr->px[0]-cu), abs(ftr->px[1]-cv)) + < max(abs(key_pts_[0]->px[0]-cu), abs(key_pts_[0]->px[1]-cv))) + key_pts_[0] = ftr; + + if(ftr->px[0] >= cu && ftr->px[1] >= cv) + { + if(key_pts_[1] == NULL) + key_pts_[1] = ftr; + else if((ftr->px[0]-cu) * (ftr->px[1]-cv) + > (key_pts_[1]->px[0]-cu) * (key_pts_[1]->px[0]-cv)) + key_pts_[1] = ftr; + } + if(ftr->px[0] >= cu && ftr->px[1] < cv) + { + if(key_pts_[2] == NULL) + key_pts_[2] = ftr; + else if((ftr->px[0]-cu) * (ftr->px[1]-cv) + < (key_pts_[2]->px[0]-cu) * (key_pts_[2]->px[0]-cv)) + key_pts_[2] = ftr; + } + if(ftr->px[0] < cv && ftr->px[1] < cv) + { + if(key_pts_[3] == NULL) + key_pts_[3] = ftr; + else if((ftr->px[0]-cu) * (ftr->px[1]-cv) + > (key_pts_[3]->px[0]-cu) * (key_pts_[3]->px[0]-cv)) + key_pts_[3] = ftr; + } + if(ftr->px[0] < cv && ftr->px[1] >= cv) + { + if(key_pts_[4] == NULL) + key_pts_[4] = ftr; + else if((ftr->px[0]-cu) * (ftr->px[1]-cv) + < (key_pts_[4]->px[0]-cu) * (key_pts_[4]->px[0]-cv)) + key_pts_[4] = ftr; + } +} + +void Frame::removeKeyPoint(Feature* ftr) +{ + bool found = false; + std::for_each(key_pts_.begin(), key_pts_.end(), [&](Feature*& i){ + if(i == ftr) { + i = NULL; + found = true; + } + }); + if(found) + setKeyPoints(); +} + +size_t Frame::nObs() const +{ + size_t n=0; + std::for_each(fts_.begin(), fts_.end(), [&](Feature* i){if(i->point != NULL) ++n; }); + return n; +} + +bool Frame::isVisible(const Vector3d& xyz_w) const +{ + Vector3d xyz_f = T_f_w_*xyz_w; + if(xyz_f.z() < 0.0) + return false; // point is behind the camera + Vector2d px = f2c(xyz_f); + if(px[0] >= 0.0 && px[1] >= 0.0 && px[0] < cam_->width() && px[1] < cam_->height()) + return true; + return false; +} + + +/// Utility functions for the Frame class +namespace frame_utils { + +void createImgPyramid(const cv::Mat& img_level_0, int n_levels, ImgPyr& pyr) +{ + pyr.resize(n_levels); + pyr[0] = img_level_0; + for(int i=1; i depth_vec; + depth_vec.reserve(frame.fts_.size()); + depth_min = std::numeric_limits::max(); + for(auto it=frame.fts_.begin(), ite=frame.fts_.end(); it!=ite; ++it) + { + if((*it)->point != NULL) + { + const double z = frame.w2f((*it)->point->pos_).z(); + depth_vec.push_back(z); + depth_min = fmin(z, depth_min); + } + } + if(depth_vec.empty()) + { + SVO_WARN_STREAM("Cannot set scene depth. Frame has no point-observations!"); + return false; + } + depth_mean = vk::getMedian(depth_vec); + return true; +} + +} // namespace frame_utils +} // namespace svo diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp new file mode 100644 index 0000000..3d530f7 --- /dev/null +++ b/svo/src/frame_handler_base.cpp @@ -0,0 +1,200 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +// definition of global and static variables which were declared in the header +#ifdef SVO_TRACE +vk::PerformanceMonitor* g_permon = NULL; +#endif + +FrameHandlerBase:: +FrameHandlerBase() : + stage_(PAUSED), + set_reset_(false), + set_start_(false), + acc_frame_timings_(10), + acc_num_obs_(10), + num_obs_last_(0), + tracking_quality_(BAD), + depth_filter_(NULL) +{ +#ifdef SVO_TRACE + // Initialize Performance Monitor + g_permon = new vk::PerformanceMonitor(); + g_permon->addTimer("pyramid_creation"); + g_permon->addTimer("sparse_img_align"); + g_permon->addTimer("reproject"); + g_permon->addTimer("pose_optimizer"); + g_permon->addTimer("point_optimizer"); + g_permon->addTimer("local_ba"); + g_permon->addTimer("tot_time"); + g_permon->addLog("img_align_n_tracked"); + g_permon->addLog("repr_n_mps"); + g_permon->addLog("repr_n_new_references"); + g_permon->addLog("sfba_thresh"); + g_permon->addLog("sfba_error_init"); + g_permon->addLog("sfba_error_final"); + g_permon->addLog("sfba_n_edges_final"); + g_permon->addLog("loba_n_erredges_init"); + g_permon->addLog("loba_n_erredges_fin"); + g_permon->addLog("loba_err_init"); + g_permon->addLog("loba_err_fin"); + g_permon->addLog("n_candidates"); + g_permon->addLog("dropout"); + g_permon->init(Config::traceName(), Config::traceDir()); +#endif + + // create depth filter and set callback + feature_detection::DetectorPtr feature_detector(new feature_detection::FastDetector()); + DepthFilter::callback_t depth_filter_cb = boost::bind(&MapPointCandidates::newCandidatePoint, &map_.point_candidates_, _1, _2); + depth_filter_ = new DepthFilter(feature_detector, depth_filter_cb); + depth_filter_->startThread(); + + SVO_INFO_STREAM("NanoSlam initialized"); +} + +FrameHandlerBase:: +~FrameHandlerBase() +{ + SVO_INFO_STREAM("SVO destructor invoked."); + delete depth_filter_; + SVO_INFO_STREAM("SVO destructed."); +} + +bool FrameHandlerBase:: +startFrameProcessingCommon() +{ + if(set_start_) + { + resetAll(); + stage_ = FIRST_FRAME; + set_start_ = false; + } + + if(stage_ == PAUSED) + return false; + + SVO_DEBUG_STREAM("New Frame"); + SVO_START_TIMER("tot_time"); + timer_.start(); + + // some cleanup from last iteration, can't do before because of visualization + map_.emptyTrash(); + return true; +} + +int FrameHandlerBase:: +finishFrameProcessingCommon(size_t update_id, UpdateResult dropout, size_t num_observations) +{ + SVO_DEBUG_STREAM("Frame: "<writeToFile(); + { + boost::unique_lock lock(map_.point_candidates_.mut_); + size_t n_candidates = map_.point_candidates_.candidates_.size(); + SVO_LOG(n_candidates); + } + #endif + + // reset if failure or requested + if(dropout == FAILURE || set_reset_) + resetAll(); + return 0; +} + +void FrameHandlerBase:: +resetCommon() +{ + map_.reset(); + stage_ = PAUSED; + set_reset_ = false; + tracking_quality_ = BAD; + depth_filter_->reset(); + num_obs_last_ = 0; + SVO_INFO_STREAM("RESET"); +} + +void FrameHandlerBase:: +setTrackingQuality(const size_t num_observations) +{ + tracking_quality_ = GOOD; + if(num_observations < Config::qualityMinFts()) + { + ROS_WARN_STREAM_THROTTLE(0.5, "Tracking less than "<< Config::qualityMinFts() <<" features!"); + tracking_quality_ = BAD; + } + const int feature_drop = static_cast(num_obs_last_) - num_observations; + if(feature_drop > Config::qualityMaxFtsDrop()) + { + ROS_WARN_STREAM("Lost "<< feature_drop <<" features!"); + tracking_quality_ = BAD; + } + if(num_observations < 20) + { + ROS_ERROR_STREAM("Tracking less than 20 features!"); + tracking_quality_ = INSUFFICIENT; + } +} + +bool ptLastOptimComparator(Point* lhs, Point* rhs) +{ + return (lhs->last_structure_optim_ < rhs->last_structure_optim_); +} + +void FrameHandlerBase:: +optimizeStructure(FramePtr frame, size_t max_n_pts, int max_iter) +{ + deque pts; + for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point != NULL) + pts.push_back((*it)->point); + } + max_n_pts = min(max_n_pts, pts.size()); + nth_element(pts.begin(), pts.begin() + max_n_pts, pts.end(), ptLastOptimComparator); + for(deque::iterator it=pts.begin(); it!=pts.begin()+max_n_pts; ++it) + { + (*it)->optimize(max_iter); + (*it)->last_structure_optim_ = frame->id_; + } +} + + +} // namespace svo diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp new file mode 100644 index 0000000..95a9787 --- /dev/null +++ b/svo/src/frame_handler_mono.cpp @@ -0,0 +1,254 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef USE_BUNDLE_ADJUSTMENT +#include +#endif + +namespace svo { + +FrameHandlerMono:: +FrameHandlerMono(vk::AbstractCamera* cam) : + FrameHandlerBase(), + cam_(cam) +{ + reprojection_grid_.initialize(cam_); +} + +FrameHandlerMono:: +~FrameHandlerMono() +{} + +void FrameHandlerMono:: +addImage(const cv::Mat& img, double timestamp) +{ + if(!startFrameProcessingCommon()) + return; + + // some cleanup from last iteration, can't do before because of visualization + core_kfs_.clear(); + overlap_kfs_.clear(); + + // create new frame + SVO_START_TIMER("pyramid_creation"); + new_frame_.reset(new Frame(cam_, img.clone(), timestamp)); + SVO_STOP_TIMER("pyramid_creation"); + + // process frame + UpdateResult res = FAILURE; + if(stage_ == DEFAULT_FRAME) + res = processFrame(); + else if(stage_ == SECOND_FRAME) + res = processSecondFrame(); + else if(stage_ == FIRST_FRAME) + res = processFirstFrame(); + + // set last frame + last_frame_ = new_frame_; + new_frame_.reset(); + + // finish processing + finishFrameProcessingCommon(last_frame_->id_, res, last_frame_->nObs()); +} + +FrameHandlerMono::UpdateResult FrameHandlerMono:: +processFirstFrame() +{ + new_frame_->T_f_w_ = T_f_w_init_; + if(klt_homography_init_.addFirstFrame(new_frame_) == initialization::FAILURE) + return NO_KEYFRAME; + new_frame_->setKeyframe(); + map_.addKeyframe(new_frame_); + stage_ = SECOND_FRAME; + SVO_INFO_STREAM("Init: Selected first frame."); + return IS_KEYFRAME; +} + +FrameHandlerMono::UpdateResult FrameHandlerMono:: +processSecondFrame() +{ + initialization::InitResult res = klt_homography_init_.addSecondFrame(new_frame_); + if(res == initialization::FAILURE) + return FAILURE; + else if(res == initialization::NO_KEYFRAME) + return NO_KEYFRAME; + + // two-frame bundle adjustment +#ifdef USE_BUNDLE_ADJUSTMENT + ba::twoViewBA(new_frame_.get(), map_.lastKeyframe().get(), Config::lobaThresh(), map_); +#endif + + double depth_mean, depth_min; + frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); + depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min); + + // add frame to map + new_frame_->setKeyframe(); + map_.addKeyframe(new_frame_); + stage_ = DEFAULT_FRAME; + klt_homography_init_.reset(); + SVO_INFO_STREAM("Init: Selected second frame, triangulated initial map."); + return IS_KEYFRAME; +} + +FrameHandlerMono::UpdateResult FrameHandlerMono:: +processFrame() +{ + // Set initial pose TODO use prior + new_frame_->T_f_w_ = last_frame_->T_f_w_; + + // sparse image align + SVO_START_TIMER("sparse_img_align"); + SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), + 30, SparseImgAlign::GaussNewton, false, false); + size_t img_align_n_tracked = img_align.run(last_frame_, new_frame_); + SVO_STOP_TIMER("sparse_img_align"); + SVO_LOG(img_align_n_tracked); + SVO_DEBUG_STREAM("Img Align:\t Tracked = " << img_align_n_tracked); + + // map reprojection & feature alignment + SVO_START_TIMER("reproject"); + size_t repr_n_new_references, repr_n_mps; + reprojection::reprojectMap( + map_, new_frame_, reprojection_grid_, map_.point_candidates_, + overlap_kfs_, repr_n_new_references, repr_n_mps); + SVO_STOP_TIMER("reproject"); + SVO_LOG2(repr_n_mps, repr_n_new_references); + SVO_DEBUG_STREAM("Reprojection:\t nPoints = "<addFrame(new_frame_); + return NO_KEYFRAME; + } + + // new keyframe selected + for(Features::iterator it=new_frame_->fts_.begin(); it!=new_frame_->fts_.end(); ++it) + if((*it)->point != NULL) + (*it)->point->addFrameRef(*it); + map_.point_candidates_.addCandidatePointToFrame(new_frame_); + + // optional bundle adjustment + core_kfs_.insert(new_frame_); +#ifdef USE_BUNDLE_ADJUSTMENT + if(Config::lobaNumIter() > 0) + { + SVO_START_TIMER("local_ba"); + setCoreKfs(Config::coreNKfs()); + size_t loba_n_erredges_init, loba_n_erredges_fin; + double loba_err_init, ba_final_error; + ba::localBA(new_frame_.get(), &core_kfs_, &map_, + loba_n_erredges_init, ba_incorrect_edges_2, + ba_init_error, loba_err_fin); + SVO_STOP_TIMER("local_ba"); + SVO_LOG4(loba_n_erredges_init, loba_n_erredges_fin, loba_err_init, loba_err_fin); + SVO_DEBUG_STREAM("Local BA:\t RemovedEdges {"<addKeyframe(new_frame_, depth_mean, 0.5*depth_min); + + // if limited number of keyframes, remove the one furthest apart + if(Config::maxNKfs() > 2 && map_.size() >= Config::maxNKfs()) + { + FramePtr furthest_frame = map_.getFurthestKeyframe(new_frame_->pos()); + depth_filter_->removeKeyframe(furthest_frame); // TODO this interrupts the mapper thread, maybe we can solve this better + map_.safeDeleteFrame(furthest_frame); + } + + // add keyframe to map + new_frame_->setKeyframe(); + map_.addKeyframe(new_frame_); + + return IS_KEYFRAME; +} + +void FrameHandlerMono:: +resetAll() +{ + resetCommon(); + last_frame_.reset(); + new_frame_.reset(); + core_kfs_.clear(); + overlap_kfs_.clear(); +} + +bool FrameHandlerMono:: +needNewKf(double scene_depth_mean) +{ + for(auto it=overlap_kfs_.begin(), ite=overlap_kfs_.end(); it!=ite; ++it) + { + Vector3d relpos = new_frame_->w2f(it->first->pos()); + if(abs(relpos.x())/scene_depth_mean < Config::kfSelectMinDist() && + abs(relpos.y())/scene_depth_mean < Config::kfSelectMinDist()*0.8 && + abs(relpos.z())/scene_depth_mean < Config::kfSelectMinDist()*1.3) + return false; + } + return true; +} + +void FrameHandlerMono:: +setCoreKfs(size_t n_closest) +{ + size_t n = min(n_closest, overlap_kfs_.size()-1); + std::partial_sort(overlap_kfs_.begin(), overlap_kfs_.begin()+n, overlap_kfs_.end(), + boost::bind(&pair::second, _1) > + boost::bind(&pair::second, _2)); + std::for_each(overlap_kfs_.begin(), overlap_kfs_.end(), [&](pair& i){ core_kfs_.insert(i.first); }); +} + +} // namespace svo diff --git a/svo/src/initialization.cpp b/svo/src/initialization.cpp new file mode 100644 index 0000000..1087e61 --- /dev/null +++ b/svo/src/initialization.cpp @@ -0,0 +1,205 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { +namespace initialization { + +InitResult KltHomographyInit::addFirstFrame(FramePtr frame_ref) +{ + reset(); + detectFeatures(frame_ref, px_ref_, f_ref_); + if(px_ref_.size() < 100) + { + SVO_WARN_STREAM_THROTTLE(2.0, "First image has less than 100 features. Retry in more textured environment."); + return FAILURE; + } + frame_ref_ = frame_ref; + px_cur_.insert(px_cur_.begin(), px_ref_.begin(), px_ref_.end()); + return SUCCESS; +} + +InitResult KltHomographyInit::addSecondFrame(FramePtr frame_cur) +{ + trackKlt(frame_ref_, frame_cur, px_ref_, px_cur_, f_ref_, f_cur_, disparities_); + SVO_INFO_STREAM("Init: KLT tracked "<< disparities_.size() <<" features"); + + if(disparities_.size() < Config::initMinTracked()) + return FAILURE; + + double disparity = vk::getMedian(disparities_); + SVO_INFO_STREAM("Init: KLT "<cam_->errorMultiplier2(), Config::poseOptimThresh(), + inliers_, xyz_in_cur_, T_cur_from_ref_); + SVO_INFO_STREAM("Init: Homography RANSAC "< depth_vec; + for(size_t i=0; iT_f_w_ = T_cur_from_ref_ * frame_ref_->T_f_w_; + frame_cur->T_f_w_.translation() = + -frame_cur->T_f_w_.rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); + + // For each inlier create 3D point and add feature in both frames + SE3 T_world_cur = frame_cur->T_f_w_.inverse(); + for(vector::iterator it=inliers_.begin(); it!=inliers_.end(); ++it) + { + Vector2d px_cur(px_cur_[*it].x, px_cur_[*it].y); + Vector2d px_ref(px_ref_[*it].x, px_ref_[*it].y); + if(frame_ref_->cam_->isInFrame(px_cur.cast(), 10) && frame_ref_->cam_->isInFrame(px_ref.cast(), 10) && xyz_in_cur_[*it].z() > 0) + { + Vector3d pos = T_world_cur * (xyz_in_cur_[*it]*scale); + Point* new_point = new Point(pos, Point::TRIANGULATION); + + Feature* ftr_cur(new Feature(frame_cur.get(), new_point, px_cur, f_cur_[*it], 0)); + frame_cur->addFeature(ftr_cur); + new_point->addFrameRef(ftr_cur); + + Feature* ftr_ref(new Feature(frame_ref_.get(), new_point, px_ref, f_ref_[*it], 0)); + frame_ref_->addFeature(ftr_ref); + new_point->addFrameRef(ftr_ref); + } + } + return SUCCESS; +} + +void KltHomographyInit::reset() +{ + px_cur_.clear(); + frame_ref_.reset(); +} + +void detectFeatures( + FramePtr frame, + vector& px_vec, + vector& f_vec) +{ + feature_detection::Corners corners; + feature_detection::FastDetector detector; + detector.detect(frame->img_pyr_, frame->fts_, Config::gridSize(), + Config::nPyrLevels(), Config::triangMinCornerScore(), + &corners); + + // now for all maximum corners, initialize a new seed + px_vec.clear(); px_vec.reserve(corners.size()); + f_vec.clear(); f_vec.reserve(corners.size()); + for(feature_detection::Corners::iterator it=corners.begin(); it!=corners.end(); ++it) + { + // we must check again if the score is above the threshold because the Corners + // vector is initialized with dummy corners + if(it->score > Config::triangMinCornerScore()) + { + px_vec.push_back(cv::Point2f(it->x, it->y)); + f_vec.push_back(frame->c2f(it->x, it->y)); + } + } +} + +void trackKlt( + FramePtr frame_ref, + FramePtr frame_cur, + vector& px_ref, + vector& px_cur, + vector& f_ref, + vector& f_cur, + vector& disparities) +{ + const double klt_win_size = 30.0; + const int klt_max_iter = 30; + const double klt_eps = 0.001; + vector status; + vector error; + vector min_eig_vec; + cv::TermCriteria termcrit(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, klt_max_iter, klt_eps); + cv::calcOpticalFlowPyrLK(frame_ref->img_pyr_[0], frame_cur->img_pyr_[0], + px_ref, px_cur, + status, error, + cv::Size2i(klt_win_size, klt_win_size), + 4, termcrit); + + vector::iterator px_ref_it = px_ref.begin(); + vector::iterator px_cur_it = px_cur.begin(); + vector::iterator f_ref_it = f_ref.begin(); + f_cur.clear(); f_cur.reserve(px_cur.size()); + disparities.clear(); disparities.reserve(px_cur.size()); + for(size_t i=0; px_ref_it != px_ref.end(); ++i) + { + if(!status[i]) + { + px_ref_it = px_ref.erase(px_ref_it); + px_cur_it = px_cur.erase(px_cur_it); + f_ref_it = f_ref.erase(f_ref_it); + continue; + } + f_cur.push_back(frame_cur->c2f(px_cur_it->x, px_cur_it->y)); + disparities.push_back(Vector2d(px_ref_it->x - px_cur_it->x, px_ref_it->y - px_cur_it->y).norm()); + ++px_ref_it; + ++px_cur_it; + ++f_ref_it; + } +} + +void computeHomography( + const vector& f_ref, + const vector& f_cur, + double focal_length, + double reprojection_threshold, + vector& inliers, + vector& xyz_in_cur, + SE3& T_cur_from_ref) +{ + vector > uv_ref(f_ref.size()); + vector > uv_cur(f_cur.size()); + for(size_t i=0, i_max=f_ref.size(); i outliers; + vk::computeInliers(f_cur, f_ref, + Homography.T_c2_from_c1.rotation_matrix(), Homography.T_c2_from_c1.translation(), + reprojection_threshold, focal_length, + xyz_in_cur, inliers, outliers); + T_cur_from_ref = Homography.T_c2_from_c1; +} + + +} // namespace initialization +} // namespace svo diff --git a/svo/src/map.cpp b/svo/src/map.cpp new file mode 100644 index 0000000..808917c --- /dev/null +++ b/svo/src/map.cpp @@ -0,0 +1,357 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include + +namespace svo { + +Map::Map() {} + +Map::~Map() +{ + reset(); + SVO_INFO_STREAM("Map destructed"); +} + +void Map::reset() +{ + keyframes_.clear(); + point_candidates_.reset(); + emptyTrash(); +} + +bool Map::safeDeleteFrame(FramePtr frame) +{ + bool found = false; + for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) + { + if(*it == frame) + { + std::for_each((*it)->fts_.begin(), (*it)->fts_.end(), [&](Feature* ftr){ + removePtFrameRef(it->get(), ftr); + }); + keyframes_.erase(it); + found = true; + break; + } + } + + point_candidates_.removeFrameCandidates(frame); + + if(found) + return true; + + SVO_ERROR_STREAM("Tried to delete Keyframe in map which was not there."); + return false; +} + +void Map::removePtFrameRef(Frame* frame, Feature* ftr) +{ + if(ftr->point == NULL) + return; // mappoint may have been deleted in a previous ref. removal + Point* pt = ftr->point; + ftr->point = NULL; + if(pt->obs_.size() <= 2) + { + // If the references list of mappoint has only size=2, delete mappoint + safeDeletePoint(pt); + return; + } + pt->deleteFrameRef(frame); // Remove reference from map_point + frame->removeKeyPoint(ftr); // Check if mp was keyMp in keyframe +} + +void Map::safeDeletePoint(Point* pt) +{ + // Delete references to mappoints in all keyframes + std::for_each(pt->obs_.begin(), pt->obs_.end(), [&](Feature* ftr){ + ftr->point=NULL; + ftr->frame->removeKeyPoint(ftr); + }); + pt->obs_.clear(); + + // Delete mappoint + deletePoint(pt); +} + +void Map::deletePoint(Point* pt) +{ + pt->type_ = Point::DELETED; + trash_points_.push_back(pt); +} + +void Map::addKeyframe(FramePtr new_keyframe) +{ + keyframes_.push_back(new_keyframe); +} + +void Map::getCloseKeyframes(const FramePtr& frame, list< pair >& close_kfs) const +{ + const Vector3d frame_pos(frame->pos()); + for(auto it_kf=keyframes_.begin(), ite_kf=keyframes_.end(); it_kf!=ite_kf; ++it_kf) + { + // check first if Point is visible in the Keyframe, use therefore KeyPoints + for(auto it=(*it_kf)->key_pts_.begin(), ite=(*it_kf)->key_pts_.end(); it!=ite; ++it) + { + if(*it == NULL) + continue; + + assert((*it)->point != NULL); + + if((*it_kf)->isVisible((*it)->point->pos_)) + { + close_kfs.push_back(pair(*it_kf, + (frame->T_f_w_.translation()-(*it_kf)->T_f_w_.translation()).norm())); + break; // this keyframe has an overlapping field of view -> add to close_kfs + } + } + } +} + +FramePtr Map::getClosestKeyframe(const FramePtr& frame) const +{ + list< pair > close_kfs; + getCloseKeyframes(frame, close_kfs); + + // Sort KFs with overlap according to their closeness + close_kfs.sort(boost::bind(&std::pair::second, _1) < + boost::bind(&std::pair::second, _2)); + + if(close_kfs.front().first != frame) + return close_kfs.front().first; + close_kfs.pop_front(); + return close_kfs.front().first; +} + +FramePtr Map::getFurthestKeyframe(const Vector3d& pos) const +{ + FramePtr furthest_kf; + double maxdist = 0.0; + for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) + { + double dist = ((*it)->pos()-pos).norm(); + if(dist > maxdist) { + maxdist = dist; + furthest_kf = *it; + } + } + return furthest_kf; +} + +void Map::transform(const Matrix3d& R, const Vector3d& t, const double& s) +{ + for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) + { + Vector3d pos = s*R*(*it)->pos() + t; + Matrix3d rot = R*(*it)->T_f_w_.rotation_matrix().inverse(); + (*it)->T_f_w_ = SE3(rot, pos).inverse(); + for(auto ftr=(*it)->fts_.begin(); ftr!=(*it)->fts_.end(); ++ftr) + { + if((*ftr)->point == NULL) + continue; + if((*ftr)->point->last_published_ts_ == -1000) + continue; + (*ftr)->point->last_published_ts_ = -1000; + (*ftr)->point->pos_ = s*R*(*ftr)->point->pos_ + t; + } + } +} + +void Map::emptyTrash() +{ + std::for_each(trash_points_.begin(), trash_points_.end(), [&](Point*& pt){ + delete pt; + pt=NULL; + }); + trash_points_.clear(); + point_candidates_.emptyTrash(); +} + +MapPointCandidates::MapPointCandidates() +{} + +MapPointCandidates::~MapPointCandidates() +{ + reset(); +} + +void MapPointCandidates::newCandidatePoint(const Seed& seed, const Vector3d& xyz_world) +{ + // initalize a new point + Point* point = new Point(xyz_world, Point::VOGIATZIS); + point->addFrameRef(seed.ftr); + point->type_ = Point::CANDIDATE; + seed.ftr->point = point; + + // add candidate to list + boost::unique_lock lock(mut_); + candidates_.push_back(PointCandidate(point, seed.ftr)); +} + +void MapPointCandidates::addCandidatePointToFrame(FramePtr frame) +{ + boost::unique_lock lock(mut_); + PointCandidateList::iterator it=candidates_.begin(); + while(it != candidates_.end()) + { + if(it->first->obs_.front()->frame == frame.get()) + { + // insert feature in the frame + it->first->type_ = Point::UNKNOWN_QUALITY; + it->first->n_failed_reproj_ = 0; + it->second->frame->addFeature(it->second); + it = candidates_.erase(it); + } + else + ++it; + } +} + +bool MapPointCandidates::deleteCandidatePoint(Point* point) +{ + boost::unique_lock lock(mut_); + for(auto it=candidates_.begin(), ite=candidates_.end(); it!=ite; ++it) + { + if(it->first == point) + { + deleteCandidate(*it); + candidates_.erase(it); + return true; + } + } + return false; +} + +void MapPointCandidates::removeFrameCandidates(FramePtr frame) +{ + boost::unique_lock lock(mut_); + auto it=candidates_.begin(); + while(it!=candidates_.end()) + { + if(it->second->frame == frame.get()) + { + deleteCandidate(*it); + it = candidates_.erase(it); + } + else + ++it; + } +} + +void MapPointCandidates::reset() +{ + boost::unique_lock lock(mut_); + std::for_each(candidates_.begin(), candidates_.end(), [&](PointCandidate& c){ + delete c.first; + delete c.second; + }); + candidates_.clear(); +} + +void MapPointCandidates::deleteCandidate(PointCandidate& c) +{ + // camera-rig: another frame might still be pointing to the candidate point + // therefore, we can't delete it right now. + delete c.second; c.second=NULL; + c.first->type_ = Point::DELETED; + trash_points_.push_back(c.first); +} + +void MapPointCandidates::emptyTrash() +{ + std::for_each(trash_points_.begin(), trash_points_.end(), [&](Point*& p){ + delete p; p=NULL; + }); + trash_points_.clear(); +} + +namespace map_debug { + +void mapValidation(Map* map, int id) +{ + for(auto it=map->keyframes_.begin(); it!=map->keyframes_.end(); ++it) + frameValidation(it->get(), id); +} + +void frameValidation(Frame* frame, int id) +{ + for(auto it = frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point==NULL) + continue; + + if((*it)->point->type_ == Point::DELETED) + printf("ERROR DataValidation %i: Referenced point was deleted.\n", id); + + if(!(*it)->point->findFrameRef(frame)) + printf("ERROR DataValidation %i: Frame has reference but point does not have a reference back.\n", id); + + pointValidation((*it)->point, id); + } + for(auto it=frame->key_pts_.begin(); it!=frame->key_pts_.end(); ++it) + if(*it != NULL) + if((*it)->point == NULL) + printf("ERROR DataValidation %i: KeyPoints not correct!\n", id); +} + +void pointValidation(Point* point, int id) +{ + for(auto it=point->obs_.begin(); it!=point->obs_.end(); ++it) + { + bool found=false; + for(auto it_ftr=(*it)->frame->fts_.begin(); it_ftr!=(*it)->frame->fts_.end(); ++it_ftr) + if((*it_ftr)->point == point) { + found=true; break; + } + if(!found) + printf("ERROR DataValidation %i: Point %i has inconsistent reference in frame %i, is candidate = %i\n", id, point->id_, (*it)->frame->id_, (int) point->type_); + } +} + +void mapStatistics(Map* map) +{ + // compute average number of features which each frame observes + size_t n_pt_obs(0); + for(auto it=map->keyframes_.begin(); it!=map->keyframes_.end(); ++it) + n_pt_obs += (*it)->nObs(); + printf("\n\nMap Statistics: Frame avg. point obs = %f\n", (float) n_pt_obs/map->size()); + + // compute average number of observations that each point has + size_t n_frame_obs(0); + size_t n_pts(0); + set points; + for(auto it=map->keyframes_.begin(); it!=map->keyframes_.end(); ++it) + { + for(auto ftr=(*it)->fts_.begin(); ftr!=(*it)->fts_.end(); ++ftr) + { + if((*ftr)->point == NULL) + continue; + if(points.insert((*ftr)->point).second) { + ++n_pts; + n_frame_obs += (*ftr)->point->nRefs(); + } + } + } + printf("Map Statistics: Point avg. frame obs = %f\n\n", (float) n_frame_obs/n_pts); +} + +} // namespace map_debug +} // namespace svo diff --git a/svo/src/matcher.cpp b/svo/src/matcher.cpp new file mode 100644 index 0000000..9587608 --- /dev/null +++ b/svo/src/matcher.cpp @@ -0,0 +1,343 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { +namespace matcher { + +PatchData::PatchData(int patch_size) : + patch_size(patch_size) +{ + patch = vk::aligned_mem::aligned_alloc(patch_size*patch_size, 16); + patch_with_border = vk::aligned_mem::aligned_alloc((patch_size+2)*(patch_size+2), 16); +} + +PatchData::~PatchData() +{ + free(patch); + free(patch_with_border); +} + +namespace warp { + +void getWarpMatrixAffine( + const vk::AbstractCamera& cam_ref, + const vk::AbstractCamera& cam_cur, + const Vector2d& px_ref, + const Vector3d& f_ref, + const double depth_ref, + const SE3& T_cur_ref, + const int level_ref, + Matrix2d& A_cur_ref) +{ + // Compute affine warp matrix A_ref_cur + const int halfpatch_size = 5; + const Vector3d xyz_ref(f_ref*depth_ref); + Vector3d xyz_du_ref(cam_ref.cam2world(px_ref + Vector2d(halfpatch_size,0)*(1< 3.0 && level_cur < max_level) + { + level_cur += 1; + D *= 0.25; + } + return level_cur; +} + +void warpAffine( + const Matrix2d& A_cur_ref, + const cv::Mat& img_ref, + const Vector2d& px_ref, + const int level_ref, + const int level_cur, + PatchData& ref_patch) +{ + const int halfpatch_size = ref_patch.patch_size/2+1; + const int patch_size = halfpatch_size*2 ; + Matrix2f A_ref_cur = A_cur_ref.inverse().cast(); + if(isnan(A_ref_cur(0,0))) + { + printf("Affine warp is NaN, probably camera has no translation\n"); // TODO + return; + } + + // Perform the Warp on a larger patch + uint8_t* ref_patch_ptr = ref_patch.patch_with_border; + const Vector2f px_ref_pyr = px_ref.cast() / (1<=img_ref.cols-1 || px[1]>=img_ref.rows-1) + *ref_patch_ptr = 0; + else + *ref_patch_ptr = (uint8_t) vk::interpolateMat_8u(img_ref, px[0], px[1]); + } + } + + ref_patch_ptr = ref_patch.patch; + for(int y=1; yframe->cam_->isInFrame( + ref_ftr->px.cast()/(1<level), g_halfpatch_size+2, ref_ftr->level)) + return false; + + // warp affine + PatchData ref_patch(g_patch_size); + Matrix2d A_cur_ref; + warp::getWarpMatrixAffine( + *ref_ftr->frame->cam_, *cur_frame.cam_, ref_ftr->px, ref_ftr->f, + (ref_ftr->frame->pos() - pt.pos_).norm(), cur_frame.T_f_w_ * ref_ftr->frame->T_f_w_.inverse(), ref_ftr->level, A_cur_ref); + level_cur = warp::getBestSearchLevel(A_cur_ref, Config::nPyrLevels()-1); + warp::warpAffine( + A_cur_ref, ref_ftr->frame->img_pyr_[ref_ftr->level], ref_ftr->px, ref_ftr->level, level_cur, ref_patch); + + // px_cur should be set + Vector2d px_scaled(px_cur/(1< A; A << T_search_ref.rotation_matrix() * f_ref, f_cur; + const Matrix2d AtA = A.transpose()*A; + if(AtA.determinant() < 0.000001) + return false; + const Vector2d depth2 = - AtA.inverse()*A.transpose()*T_search_ref.translation(); + depth = fabs(depth2[0]); + return true; +} + +bool +findEpipolarMatchDirect( + const Frame& ref_frame, + const Frame& cur_frame, + const Feature& ref_ftr, + const double d_estimate, + const double d_min, + const double d_max, + const bool align_1d, + double& depth, + double& h_inv) +{ + typedef vk::patch_score::ZMSSD PatchScore; + + PatchData ref_patch(g_patch_size); + SE3 T_cur_ref = cur_frame.T_f_w_ * ref_frame.T_f_w_.inverse(); + int zmssd_best = PatchScore::threshold(); + Vector2d uv_best; + + // Compute start and end of epipolar line in old_kf for match search, on unit plane! + Vector2d A = vk::project2d(T_cur_ref * (ref_ftr.f*d_min)); + Vector2d B = vk::project2d(T_cur_ref * (ref_ftr.f*d_max)); + Vector2d epi_dir = A - B; + + // Compute affine warp matrix + Matrix2d A_cur_ref; + warp::getWarpMatrixAffine( + *ref_frame.cam_, *cur_frame.cam_, ref_ftr.px, ref_ftr.f, + d_estimate, T_cur_ref, ref_ftr.level, A_cur_ref); + int level_cur = warp::getBestSearchLevel(A_cur_ref, Config::nPyrLevels()-1); + + // Find length of search range on epipolar line + Vector2d px_A(cur_frame.cam_->world2cam(A)); + Vector2d px_B(cur_frame.cam_->world2cam(B)); + double px_length = (px_A-px_B).norm() / (1<().normalized(), + ref_patch.patch_with_border, ref_patch.patch, 10, px_scaled, h_inv); + else + res = feature_alignment::align2D( + cur_frame.img_pyr_[level_cur], ref_patch.patch_with_border, + ref_patch.patch, 10, px_scaled); + if(res) + { + px = px_scaled*(1<cam2world(px), depth)) + return true; + } + return false; + } + + size_t n_steps = px_length/0.7; // one step per pixel + Vector2d step = epi_dir/n_steps; + + if(n_steps > 1000) + { + printf("WARNING: skip epipolar search: %zu evaluations, px_lenght=%f, d_min=%f, d_max=%f.\n", + n_steps, px_length, d_min, d_max); + return false; + } + + // for matching, precompute sum and sum2 of warped reference patch + int pixel_sum = 0; + int pixel_sum_square = 0; + PatchScore patch_score(ref_patch.patch); + + // now we sample along the epipolar line + Vector2d uv = B-step; + Vector2i last_checked_pxi(0,0); + ++n_steps; + for(size_t i=0; iworld2cam(uv)); + Vector2i pxi(px[0]/(1<isInFrame(pxi, g_patch_size, level_cur)) + continue; + + // TODO interpolation would probably be a good idea + uint8_t* cur_patch_ptr = cur_frame.img_pyr_[level_cur].data + (pxi[1]-g_halfpatch_size)*cur_frame.img_pyr_[level_cur].cols + (pxi[0]-g_halfpatch_size); + int zmssd = patch_score.computeScore(cur_patch_ptr, cur_frame.img_pyr_[level_cur].cols); + + if(zmssd < zmssd_best) { + zmssd_best = zmssd; + uv_best = uv; + } + } + +#ifdef DEBUG_MATCHER_EPISEARCH + if(zmssd_best < g_zmssd_thresh) { + Vector2d px(cur_frame.cam_->world2cam(uv_best)); + Vector2i pxi(px[0]/(1<world2cam(uv_best)); + Vector2d px_scaled(px/(1<().normalized(), + ref_patch.patch_with_border, ref_patch.patch, 10, px_scaled, h_inv); + else + res = feature_alignment::align2D( + cur_frame.img_pyr_[level_cur], ref_patch.patch_with_border, + ref_patch.patch, 10, px_scaled); + if(res) + { + px = px_scaled*(1<cam2world(px), depth)) + return true; + } + return false; + } + + if(depthFromTriangulation(T_cur_ref, ref_ftr.f, vk::unproject2d(uv_best).normalized(), depth)) + return true; + } + return false; +} + +} // namespace matcher +} // namespace svo diff --git a/svo/src/point.cpp b/svo/src/point.cpp new file mode 100644 index 0000000..40aced9 --- /dev/null +++ b/svo/src/point.cpp @@ -0,0 +1,170 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include + +namespace svo { + +int Point::point_counter_ = 0; + +Point::Point(Vector3d pos, PointOrigin origin) : + id_(point_counter_++), + pos_(pos), + n_obs_(0), + v_pt_(NULL), + last_published_ts_(0), + last_projected_kf_id_(-1), + type_(UNKNOWN_QUALITY), + origin_(origin), + n_failed_reproj_(0), + n_succeeded_reproj_(0), + last_structure_optim_(0) +{} + +Point::~Point() +{} + +void Point::addFrameRef(Feature* ftr) +{ + obs_.push_front(ftr); + ++n_obs_; +} + +Feature* Point::findFrameRef(Frame* frame) +{ + for(auto it=obs_.begin(), ite=obs_.end(); it!=ite; ++it) + if((*it)->frame == frame) + return *it; + return NULL; // no keyframe found +} + +bool Point::deleteFrameRef(Frame* frame) +{ + for(auto it=obs_.begin(), ite=obs_.end(); it!=ite; ++it) + { + if((*it)->frame == frame) + { + obs_.erase(it); + return true; + } + } + return false; +} + +bool Point::getCloseViewObs(const Vector3d& framepos, Feature*& ftr) const +{ + // TODO: get frame with same point of view AND same pyramid level! + Vector3d obs_dir(framepos - pos_); obs_dir.normalize(); + auto min_it=obs_.begin(); + double min_cos_angle = 0; + for(auto it=obs_.begin(), ite=obs_.end(); it!=ite; ++it) + { + Vector3d dir((*it)->frame->pos() - pos_); dir.normalize(); + double cos_angle = obs_dir.dot(dir); + if(cos_angle > min_cos_angle) + { + min_cos_angle = cos_angle; + min_it = it; + } + } + ftr = *min_it; + if(min_cos_angle < 0.5) // assume that observations larger than 60° are useless + return false; + return true; +} + +void Point::pointJacobian( + const Vector3d& p_in_f, + const Matrix3d& R_f_w, + Matrix23d& point_jac) const +{ + // we work on the unit plane, therefore focal lenght = 1 + const double z_inv = 1.0/p_in_f[2]; + const double z_inv_sq = z_inv*z_inv; + point_jac(0, 0) = z_inv; + point_jac(0, 1) = 0.0; + point_jac(0, 2) = -p_in_f[0] * z_inv_sq; + point_jac(1, 0) = 0.0; + point_jac(1, 1) = z_inv; + point_jac(1, 2) = -p_in_f[1] * z_inv_sq; + point_jac = - point_jac * R_f_w; +} + +void Point::optimize(const size_t n_iter) +{ + Vector3d old_point = pos_; + double chi2 = 0.0; + Matrix3d A; + Vector3d b; + + for(size_t i=0; iframe->T_f_w_ * pos_); + pointJacobian(p_in_f, (*it)->frame->T_f_w_.rotation_matrix(), J); + const Vector2d e(vk::project2d((*it)->f) - vk::project2d(p_in_f)); + new_chi2 += e.squaredNorm(); + A.noalias() += J.transpose() * J; + b.noalias() -= J.transpose() * e; + } + + // solve linear system + const Vector3d dp(A.ldlt().solve(b)); + + // check if error increased + if((i > 0 && new_chi2 > chi2) || (bool) std::isnan((double)dp[0])) + { +#ifdef POINT_OPTIMIZER_DEBUG + cout << "it " << i + << "\t FAILURE \t new_chi2 = " << new_chi2 << endl; +#endif + pos_ = old_point; // roll-back + break; + } + + // update the model + Vector3d new_point = pos_ + dp; + old_point = pos_; + pos_ = new_point; + chi2 = new_chi2; +#ifdef POINT_OPTIMIZER_DEBUG + cout << "it " << i + << "\t Success \t new_chi2 = " << new_chi2 + << "\t norm(b) = " << vk::norm_max(b) + << endl; +#endif + + // stop when converged + if(vk::norm_max(dp) <= EPS) + break; + } +#ifdef POINT_OPTIMIZER_DEBUG + cout << endl; +#endif +} + +} // namespace svo diff --git a/svo/src/pose_optimizer.cpp b/svo/src/pose_optimizer.cpp new file mode 100644 index 0000000..180bb1c --- /dev/null +++ b/svo/src/pose_optimizer.cpp @@ -0,0 +1,164 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include + +namespace svo { +namespace pose_optimizer { + +void optimizeGaussNewton( + const double reproj_thresh, + const size_t n_iter, + const bool verbose, + FramePtr& frame, + double& estimated_scale, + double& error_init, + double& error_final, + size_t& num_obs) +{ + // init + double chi2(0.0); + Vector2d focal_length(1,1); + vector chi2_vec_init, chi2_vec_final; + vk::robust_cost::TukeyWeightFunction weight_function; + SE3 T_old(frame->T_f_w_); + Matrix6d A; + Vector6d b; + + // compute the scale of the error for robust estimation + std::vector errors; errors.reserve(frame->fts_.size()); + for(auto it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point == NULL) + continue; + Vector2d e = vk::project2d((*it)->f) + - vk::project2d(frame->T_f_w_ * (*it)->point->pos_); + e *= 1.0 / (1<<(*it)->level); + errors.push_back(e.norm()); + } + if(errors.empty()) + return; + vk::robust_cost::MADScaleEstimator scale_estimator; + estimated_scale = scale_estimator.compute(errors); + + num_obs = errors.size(); + chi2_vec_init.reserve(num_obs); + chi2_vec_final.reserve(num_obs); + double scale = estimated_scale; + for(size_t iter=0; itercam_->errorMultiplier2(); + + b.setZero(); + A.setZero(); + double new_chi2(0.0); + + // compute residual + for(auto it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point == NULL) + continue; + Matrix26d J = frameJac(frame->T_f_w_, (*it)->point->pos_, focal_length); + Vector2d e = vk::project2d((*it)->f) + - vk::project2d(frame->T_f_w_ * (*it)->point->pos_); + double sqrt_inv_cov = 1.0 / (1<<(*it)->level); + e *= sqrt_inv_cov; + if(iter == 0) + chi2_vec_init.push_back(e.squaredNorm()); // just for debug + J *= sqrt_inv_cov; + double weight = weight_function.value(e.norm()/scale); + A.noalias() += J.transpose()*J*weight; + b.noalias() -= J.transpose()*e*weight; + new_chi2 += e.squaredNorm()*weight; + } + + // solve linear system + const Vector6d dT(A.ldlt().solve(b)); + + // check if error increased + if((iter > 0 && new_chi2 > chi2) || (bool) std::isnan((double)dT[0])) + { + if(verbose) + std::cout << "it " << iter + << "\t FAILURE \t new_chi2 = " << new_chi2 << std::endl; + frame->T_f_w_ = T_old; // roll-back + break; + } + + // update the model + SE3 T_new = SE3::exp(dT)*frame->T_f_w_; + T_old = frame->T_f_w_; + frame->T_f_w_ = T_new; + chi2 = new_chi2; + if(verbose) + std::cout << "it " << iter + << "\t Success \t new_chi2 = " << new_chi2 + << "\t norm(dT) = " << vk::norm_max(dT) << std::endl; + + // stop when converged + if(vk::norm_max(dT) <= EPS) + break; + } + + // Set covariance as inverse information matrix. Optimistic estimator! + const double pixel_variance=1.0; + frame->Cov_ = pixel_variance*(A*std::pow(frame->cam_->errorMultiplier2(),2)).inverse(); + + // Remove Measurements with too large reprojection error + double reproj_thresh_scaled = reproj_thresh / frame->cam_->errorMultiplier2(); + size_t n_deleted_refs = 0; + for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point == NULL) + continue; + Vector2d e = vk::project2d((*it)->f) - vk::project2d(frame->T_f_w_ * (*it)->point->pos_); + double sqrt_inv_cov = 1.0 / (1<<(*it)->level); + e *= sqrt_inv_cov; + chi2_vec_final.push_back(e.squaredNorm()); + if(e.norm() > reproj_thresh_scaled) + { + // (*it)->point->deleteFrameRef(frame); + (*it)->point = NULL; + ++n_deleted_refs; + } + } + + error_init=0.0; + error_final=0.0; + if(!chi2_vec_init.empty()) + error_init = sqrt(vk::getMedian(chi2_vec_init))*frame->cam_->errorMultiplier2(); + if(!chi2_vec_final.empty()) + error_final = sqrt(vk::getMedian(chi2_vec_final))*frame->cam_->errorMultiplier2(); + + estimated_scale *= frame->cam_->errorMultiplier2(); + if(verbose) + std::cout << "n deleted obs = " << n_deleted_refs + << "\t scale = " << estimated_scale + << "\t error init = " << error_init + << "\t error end = " << error_final << std::endl; + num_obs -= n_deleted_refs; +} + +} // namespace pose_optimizer +} // namespace svo diff --git a/svo/src/reprojection.cpp b/svo/src/reprojection.cpp new file mode 100644 index 0000000..26de82c --- /dev/null +++ b/svo/src/reprojection.cpp @@ -0,0 +1,214 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { +namespace reprojection { + +Grid::Grid() +{} + +void Grid::initialize(vk::AbstractCamera* cam) +{ + cell_size = Config::gridSize(); + grid_n_cols = ceil(static_cast(cam->width())/cell_size); + grid_n_rows = ceil(static_cast(cam->height())/cell_size); + cells.resize(grid_n_cols*grid_n_rows); + std::for_each(cells.begin(), cells.end(), [&](Cell*& c){ c = new Cell; }); + cell_order.resize(cells.size()); + for(size_t i=0; iclear(); }); +} + +void reprojectMap( + Map& map, + FramePtr frame, + Grid& grid, + MapPointCandidates& candidate_points, + std::vector< std::pair >& overlap_kfs, + size_t& n_matches, + size_t& n_trials) +{ + resetGrid(grid); + + // Identify those Keyframes which share a common field of view. + list< pair > close_kfs; + map.getCloseKeyframes(frame, close_kfs); + + // Sort KFs with overlap according to their closeness // TODO is this still necessary? + close_kfs.sort(boost::bind(&std::pair::second, _1) < + boost::bind(&std::pair::second, _2)); + + // Reproject all mappoints of the closest N kfs with overlap. We only store + // in which grid cell the points fall. + size_t n = 0, max_n = 10; + overlap_kfs.reserve(max_n); + for(auto it_frame=close_kfs.begin(), ite_frame=close_kfs.end(); + it_frame!=ite_frame && nfirst; + overlap_kfs.push_back(pair(ref_frame,0)); + + // Try to reproject each mappoint that the other KF observes + for(auto it_ftr=ref_frame->fts_.begin(), ite_ftr=ref_frame->fts_.end(); + it_ftr!=ite_ftr; ++it_ftr) + { + // check if the feature has a mappoint assigned + if((*it_ftr)->point == NULL) + continue; + + // make sure we project a point only once + if((*it_ftr)->point->last_projected_kf_id_ == frame->id_) + continue; + (*it_ftr)->point->last_projected_kf_id_ = frame->id_; + if(reprojectPoint(grid, frame, (*it_ftr)->point)) + overlap_kfs.back().second++; + } + } + + // Now project all point candidates + { + boost::unique_lock lock(candidate_points.mut_); + auto it=candidate_points.candidates_.begin(); + while(it!=candidate_points.candidates_.end()) + { + if(!reprojectPoint(grid, frame, it->first)) + { + it->first->n_failed_reproj_ += 3; + if(it->first->n_failed_reproj_ > 30) + { + candidate_points.deleteCandidate(*it); + it = candidate_points.candidates_.erase(it); + continue; + } + } + ++it; + } + } + + // Now we go through each grid cell and select one point to match. + // At the end, we should have at maximum one reprojected point per cell. + n_matches=0; n_trials=0; + for(size_t i=0; i (size_t) Config::maxFts()) + break; + } +} + +bool pointQualityComparator(Candidate& lhs, Candidate& rhs) +{ + if(lhs.pt->type_ > rhs.pt->type_) + return true; + return false; +} + +bool reprojectCell( + Cell& cell, + FramePtr frame, + Map& map, + MapPointCandidates& candidate_points, + size_t& n_trials) +{ + cell.sort(boost::bind(&pointQualityComparator, _1, _2)); + Cell::iterator it=cell.begin(); + while(it!=cell.end()) + { + ++n_trials; + + if(it->pt->type_ == Point::DELETED) + { + it = cell.erase(it); + continue; + } + + int feature_level; + bool found_match = matcher::findMatchDirect(*it->pt, *frame, it->px, feature_level); + if(!found_match) + { + it->pt->n_failed_reproj_++; + if(it->pt->type_ == Point::UNKNOWN_QUALITY && it->pt->n_failed_reproj_ > 15) + map.safeDeletePoint(it->pt); + if(it->pt->type_ == Point::CANDIDATE && it->pt->n_failed_reproj_ > 30) + candidate_points.deleteCandidatePoint(it->pt); + it = cell.erase(it); + continue; + } + it->pt->n_succeeded_reproj_++; + if(it->pt->type_ == Point::UNKNOWN_QUALITY && it->pt->n_succeeded_reproj_ > 10) + it->pt->type_ = Point::GOOD_QUALITY; + + Feature* new_feature = new Feature(frame.get(), it->px, feature_level); + frame->addFeature(new_feature); + new_feature->point = it->pt; + // note, we add a reference to the point only if the frame is selected as a keyframe + + // If the keyframe is selected and we reproject the rest, we don't have to + // check this point anymore. + it = cell.erase(it); + + // Maximum one point per cell. + return true; + } + return false; +} + +bool reprojectPoint( + Grid& grid, + FramePtr frame, + Point* point) +{ + Vector2d px(frame->w2c(point->pos_)); + if(frame->cam_->isInFrame(px.cast(), 8)) // 8px is the patch size in the matcher + { + const int k = static_cast(px[1]/grid.cell_size)*grid.grid_n_cols + static_cast(px[0]/grid.cell_size); + grid.cells.at(k)->push_back(Candidate(point, px)); + return true; + } + return false; +} + +} // namespace reprojection +} // namespace svo diff --git a/svo/src/sparse_img_align.cpp b/svo/src/sparse_img_align.cpp new file mode 100644 index 0000000..c4a2afd --- /dev/null +++ b/svo/src/sparse_img_align.cpp @@ -0,0 +1,296 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +SparseImgAlign:: +SparseImgAlign(int max_level, int min_level, int n_iter, + Method method, bool display, bool verbose) : + display_(display), + max_level_(max_level), + min_level_(min_level) +{ + n_iter_ = n_iter; + n_iter_init_ = n_iter_; + method_ = method; + verbose_ = verbose; + eps_ = 0.000001; +} + +size_t SparseImgAlign:: +run(FramePtr ref_frame, FramePtr cur_frame) +{ + reset(); + + if(ref_frame->fts_.empty()) + { + SVO_WARN_STREAM("SparseImgAlign: no features to track!"); + return 0; + } + + ref_frame_ = ref_frame; + cur_frame_ = cur_frame; + ref_patch_cache_ = cv::Mat(ref_frame_->fts_.size(), patch_area_, CV_32F); + jacobian_cache_.resize(Eigen::NoChange, ref_patch_cache_.rows*patch_area_); + visible_fts_.resize(ref_patch_cache_.rows, false); + + SE3 T_cur_from_ref(cur_frame_->T_f_w_ * ref_frame_->T_f_w_.inverse()); + + for(level_=max_level_; level_>=min_level_; --level_) + { + setInitialChi2(1.0); + mu_ = 0.1; + jacobian_cache_.setZero(); + have_ref_patch_cache_ = false; + if(verbose_) + printf("\nPYRAMID LEVEL %i\n---------------\n", level_); + optimize(T_cur_from_ref); + } + cur_frame_->T_f_w_ = T_cur_from_ref * ref_frame_->T_f_w_; + return n_meas_/patch_area_; +} + +// TODO take jacobian from Frame Class! +void +frameJac(const Vector3d & xyz, + Matrix & J) +{ + const double x = xyz[0]; + const double y = xyz[1]; + const double z_inv = 1./xyz[2]; + const double z_inv_2 = z_inv*z_inv; + + J(0,0) = z_inv; // 1/z + J(0,1) = 0.0; // 0 + J(0,2) = -x*z_inv_2; // -x/z^2 + J(0,3) = J(0,2)*y; // -x*y/z^2 + J(0,4) = 1.0 - J(0,2)*x; // 1.0 + x^2/z^2 + J(0,5) = -y*z_inv; // -y/z + + J(1,0) = 0.0; // 0 + J(1,1) = z_inv; // 1/z + J(1,2) = -y*z_inv_2; // -y/z^2 + J(1,3) = -1.0 + J(1,2)*y; // -1.0 - y^2/z^2 + J(1,4) = -J(0,3); // x*y/^2 + J(1,5) = x*z_inv; // x/z +} + +void SparseImgAlign:: +precomputeReferencePatches() +{ + const int border = patch_halfsize_+1; + const cv::Mat& ref_img = ref_frame_->img_pyr_.at(level_); + const int stride = ref_img.cols; + const float scale = 1.0f/(1<pos(); + const double focal_length = ref_frame_->cam_->errorMultiplier2(); + size_t feature_counter = 0; + std::vector::iterator visiblity_it = visible_fts_.begin(); + for(auto it=ref_frame_->fts_.begin(), ite=ref_frame_->fts_.end(); + it!=ite; ++it, ++feature_counter, ++visiblity_it) + { + // check if reference with patch size is within image + const float u_ref = (*it)->px[0]*scale; + const float v_ref = (*it)->px[1]*scale; + const int u_ref_i = floorf(u_ref); + const int v_ref_i = floorf(v_ref); + if((*it)->point == NULL || u_ref_i-border < 0 || v_ref_i-border < 0 || u_ref_i+border >= ref_img.cols || v_ref_i+border >= ref_img.rows) + continue; + *visiblity_it = true; + + // cannot just take the 3d points coordinate because of the reprojection errors in the reference image!!! + const double depth(((*it)->point->pos_ - ref_pos).norm()); + const Vector3d xyz_ref((*it)->f*depth); + + // compute bilateral interpolation weights for reference image + const float subpix_u_ref = u_ref-u_ref_i; + const float subpix_v_ref = v_ref-v_ref_i; + const float w_ref_tl = (1.0-subpix_u_ref) * (1.0-subpix_v_ref); + const float w_ref_tr = subpix_u_ref * (1.0-subpix_v_ref); + const float w_ref_bl = (1.0-subpix_u_ref) * subpix_v_ref; + const float w_ref_br = subpix_u_ref * subpix_v_ref; + size_t pixel_counter = 0; + float* cache_ptr = reinterpret_cast(ref_patch_cache_.data) + patch_area_*feature_counter; + for(int y=0; y frame_jac; + frameJac(xyz_ref, frame_jac); + + // cache the jacobian + jacobian_cache_.col(feature_counter*patch_area_ + pixel_counter) = + (dx*frame_jac.row(0) + dy*frame_jac.row(1))*(focal_length / (1<img_pyr_.at(level_); + const cv::Mat& cur_img = cur_frame_->img_pyr_.at(level_); + + if(linearize_system && display_) + resimg_ = cv::Mat(ref_img.size(), CV_32F, cv::Scalar(0)); + + if(have_ref_patch_cache_ == false) + precomputeReferencePatches(); + + // compute the weights on the first iteration + std::vector errors; + if(compute_weight_scale) + errors.reserve(visible_fts_.size()); + const int stride = ref_img.cols; + const int border = patch_halfsize_+1; + const float scale = 1.0f/(1<pos()); + float chi2 = 0.0; + size_t feature_counter = 0; // is used to compute the index of the cached jacobian + std::vector::iterator visiblity_it = visible_fts_.begin(); + for(auto it=ref_frame_->fts_.begin(); it!=ref_frame_->fts_.end(); + ++it, ++feature_counter, ++visiblity_it) + { + // check if feature is within image + if(!*visiblity_it) + continue; + + // compute pixel location in cur img + const double depth = ((*it)->point->pos_ - ref_pos).norm(); + const Vector3d xyz_ref((*it)->f*depth); + const Vector3d xyz_cur(T_cur_from_ref * xyz_ref); + const Vector2f uv_cur_pyr(cur_frame_->cam_->world2cam(xyz_cur).cast() * scale); + const float u_cur = uv_cur_pyr[0]; + const float v_cur = uv_cur_pyr[1]; + const int u_cur_i = floorf(u_cur); + const int v_cur_i = floorf(v_cur); + + // check if projection is within the image + if(u_cur_i < 0 || v_cur_i < 0 || u_cur_i-border < 0 || v_cur_i-border < 0 || u_cur_i+border >= cur_img.cols || v_cur_i+border >= cur_img.rows) + continue; + + // compute bilateral interpolation weights for the current image + const float subpix_u_cur = u_cur-u_cur_i; + const float subpix_v_cur = v_cur-v_cur_i; + const float w_cur_tl = (1.0-subpix_u_cur) * (1.0-subpix_v_cur); + const float w_cur_tr = subpix_u_cur * (1.0-subpix_v_cur); + const float w_cur_bl = (1.0-subpix_u_cur) * subpix_v_cur; + const float w_cur_br = subpix_u_cur * subpix_v_cur; + float* ref_patch_cache_ptr = reinterpret_cast(ref_patch_cache_.data) + patch_area_*feature_counter; + size_t pixel_counter = 0; // is used to compute the index of the cached jacobian + for(int y=0; yvalue(res/scale_); + } + + chi2 += res*res*weight; + n_meas_++; + + if(linearize_system) + { + // compute Jacobian, weighted Hessian and weighted "steepest descend images" (times error) + const Vector6d J(jacobian_cache_.col(feature_counter*patch_area_ + pixel_counter)); + H_ += J*J.transpose()*weight; + Jres_ -= J*res*weight; + if(display_) + resimg_.at((int) v_cur+y-patch_halfsize_, (int) u_cur+x-patch_halfsize_) = res/255.0; + } + } + } + } + + // compute the weights on the first iteration + if(compute_weight_scale && iter_ == 0) + scale_ = scale_estimator_->compute(errors); + + return chi2/n_meas_; +} + +int SparseImgAlign:: +solve() +{ + x_ = H_.ldlt().solve(Jres_); + if((bool) std::isnan((double) x_[0])) + return 0; + return 1; +} + +void SparseImgAlign:: +update(const ModelType& T_curold_from_ref, ModelType& T_curnew_from_ref) +{ + // the jacobian is computed in the coordinate frame of the reference image + // T_ref_from_curnew = T_ref_from_curold * SE3::exp(x_).inverse(); + // but our state is in the reference frame of the new image, thus using (AB)^-1 = B^-1*A^-1 + T_curnew_from_ref = SE3::exp(x_) * T_curold_from_ref; +} + +void SparseImgAlign:: +startIteration() +{} + +void SparseImgAlign:: +finishIteration() +{ + if(display_) + { + cv::namedWindow("residuals", CV_WINDOW_AUTOSIZE); + cv::imshow("residuals", resimg_*4); + cv::waitKey(0); + } +} + +} // namespace svo + diff --git a/svo/test/README.md b/svo/test/README.md new file mode 100644 index 0000000..ce9f1fd --- /dev/null +++ b/svo/test/README.md @@ -0,0 +1,11 @@ +Download Synthetic Test Data: +----------------------------- + +Downloads and extracts the test data in the folder `data`: + + cd rpg_slam/svo/test/data + wget http://rpg.ifi.uzh.ch/datasets/flying_room_1_rig_1.tar.gz -O - | tar -xz + +If you want to store the data in another location (for instance, if you maintain a special folder with all datasets), then you can move the dataset there and set the environment variable `TEST_DATA_DIR` in your `.bashrc` like this: + + export SVO_DATASET_DIR=${HOME}/Datasets diff --git a/svo/test/benchmark.csv b/svo/test/benchmark.csv new file mode 100644 index 0000000..e6f88a3 --- /dev/null +++ b/svo/test/benchmark.csv @@ -0,0 +1,307 @@ +local_ba,point_optimizer,pose_optimizer,pyramid_creation,reproject,sparse_img_align,tot_time,dropout,img_align_n_tracked,loba_err_fin,loba_err_init,loba_n_erredges_fin,loba_n_erredges_init,n_candidates,repr_n_mps,repr_n_new_references,sfba_error_final,sfba_error_init,sfba_n_edges_final,sfba_thresh +0.000000000000000,0.000000000000000,0.000000000000000,0.000203000000000,0.000000000000000,0.000000000000000,0.006850000000000,1.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000109000000000,0.000000000000000,0.000000000000000,0.015619000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000085000000000,0.000000000000000,0.000000000000000,0.015440000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000096000000000,0.000000000000000,0.000000000000000,0.016054000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000104000000000,0.000000000000000,0.000000000000000,0.022404000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000086000000000,0.000000000000000,0.000000000000000,0.027997000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000120000000000,0.000000000000000,0.000000000000000,0.031598000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000085000000000,0.000000000000000,0.000000000000000,0.030167000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000115000000000,0.000000000000000,0.000000000000000,0.029319000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000085000000000,0.000000000000000,0.000000000000000,0.030061000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000118000000000,0.000000000000000,0.000000000000000,0.034386000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000086000000000,0.000000000000000,0.000000000000000,0.089886000000000,1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000031000000000,0.000123000000000,0.000083000000000,0.000787000000000,0.001478000000000,0.002580000000000,0.000000000000000,279.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,148.000000000000000,121.000000000000000,0.170175036288459,0.209622100274688,121.000000000000000,0.310240723182540 +0.000000000000000,0.000021000000000,0.000169000000000,0.000094000000000,0.000742000000000,0.000759000000000,0.001820000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,151.000000000000000,121.000000000000000,0.200086249073657,0.226929968841294,119.000000000000000,0.335856340084193 +0.000000000000000,0.000025000000000,0.000161000000000,0.000087000000000,0.000786000000000,0.000849000000000,0.001929000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,150.000000000000000,121.000000000000000,0.220021652685224,0.250579787227198,120.000000000000000,0.370858080741496 +0.000000000000000,0.000022000000000,0.000154000000000,0.000080000000000,0.000833000000000,0.000799000000000,0.001908000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,153.000000000000000,121.000000000000000,0.241933925519325,0.315090765827434,119.000000000000000,0.466334367626374 +0.000000000000000,0.000022000000000,0.000147000000000,0.000078000000000,0.000733000000000,0.000857000000000,0.001878000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,145.000000000000000,121.000000000000000,0.272951477661557,0.278442109473506,118.000000000000000,0.412094340922640 +0.000000000000000,0.000028000000000,0.000163000000000,0.000105000000000,0.000998000000000,0.000769000000000,0.002090000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,176.000000000000000,121.000000000000000,0.295685270342958,0.345204254144622,120.000000000000000,0.510902319377397 +0.000000000000000,0.000026000000000,0.000096000000000,0.000108000000000,0.000884000000000,0.000849000000000,0.001987000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,154.000000000000000,121.000000000000000,0.280726298758396,0.351937246615374,119.000000000000000,0.520867118388044 +0.000000000000000,0.000027000000000,0.000145000000000,0.000077000000000,0.000795000000000,0.000757000000000,0.001822000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,160.000000000000000,121.000000000000000,0.299712701755874,0.325868377142253,119.000000000000000,0.482285213145440 +0.000000000000000,0.000017000000000,0.000088000000000,0.000082000000000,0.000819000000000,0.000723000000000,0.001753000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,157.000000000000000,121.000000000000000,0.266414412346027,0.325724036228748,121.000000000000000,0.482071564765419 +0.000000000000000,0.000018000000000,0.000117000000000,0.000090000000000,0.000805000000000,0.000748000000000,0.001799000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,53.000000000000000,146.000000000000000,121.000000000000000,0.268513468986649,0.275002624188711,120.000000000000000,0.407003878905728 +0.000000000000000,0.000017000000000,0.000084000000000,0.000077000000000,0.000701000000000,0.000777000000000,0.001677000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,76.000000000000000,141.000000000000000,121.000000000000000,0.291779187140528,0.283057832886000,119.000000000000000,0.418925579815900 +0.000000000000000,0.000019000000000,0.000215000000000,0.000093000000000,0.000797000000000,0.000821000000000,0.001970000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,96.000000000000000,146.000000000000000,121.000000000000000,0.284752636918227,0.313033086538782,118.000000000000000,0.463288955787851 +0.000000000000000,0.000018000000000,0.000115000000000,0.000087000000000,0.000928000000000,0.000752000000000,0.001937000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,108.000000000000000,164.000000000000000,121.000000000000000,0.266984542077384,0.310809089011309,117.000000000000000,0.459997446489587 +0.000000000000000,0.000018000000000,0.000145000000000,0.000076000000000,0.000879000000000,0.000667000000000,0.001797000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,82.000000000000000,172.000000000000000,121.000000000000000,0.281472783188953,0.318106490866299,118.000000000000000,0.470797632399925 +0.000000000000000,0.000025000000000,0.000097000000000,0.000092000000000,0.001059000000000,0.001001000000000,0.002299000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,82.000000000000000,169.000000000000000,121.000000000000000,0.259578545621370,0.296051217193402,118.000000000000000,0.438155829408007 +0.000000000000000,0.000023000000000,0.000152000000000,0.000090000000000,0.000987000000000,0.000683000000000,0.001956000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,88.000000000000000,169.000000000000000,121.000000000000000,0.260854021729684,0.463271425215932,119.000000000000000,0.685641725628487 +0.000000000000000,0.000012000000000,0.000147000000000,0.000078000000000,0.000828000000000,0.000628000000000,0.001713000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,100.000000000000000,162.000000000000000,121.000000000000000,0.224857463762793,0.241819177256775,120.000000000000000,0.357892398925400 +0.000000000000000,0.000015000000000,0.000176000000000,0.000082000000000,0.000976000000000,0.000761000000000,0.002033000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,175.000000000000000,163.000000000000000,121.000000000000000,0.232802573731276,0.307670936583970,121.000000000000000,0.455352982415734 +0.000000000000000,0.000015000000000,0.000150000000000,0.000089000000000,0.000914000000000,0.000700000000000,0.001890000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,215.000000000000000,163.000000000000000,121.000000000000000,0.223503209746196,0.245376568533207,121.000000000000000,0.363157337925476 +0.000000000000000,0.000014000000000,0.000085000000000,0.000085000000000,0.000830000000000,0.000688000000000,0.001724000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,236.000000000000000,160.000000000000000,121.000000000000000,0.238679764456232,0.260245227551971,121.000000000000000,0.385162944164610 +0.000000000000000,0.000017000000000,0.000094000000000,0.000082000000000,0.001027000000000,0.000661000000000,0.001919000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,253.000000000000000,156.000000000000000,121.000000000000000,0.240028080500584,0.347317487309391,119.000000000000000,0.514029864789977 +0.000000000000000,0.000017000000000,0.000107000000000,0.000086000000000,0.001095000000000,0.000731000000000,0.002049000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,225.000000000000000,203.000000000000000,121.000000000000000,0.237050681546672,0.342187692298344,118.000000000000000,0.506437791010399 +0.000000000000000,0.000027000000000,0.000087000000000,0.000082000000000,0.001031000000000,0.000707000000000,0.001956000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,224.000000000000000,192.000000000000000,121.000000000000000,0.228256268353354,0.255917210772511,118.000000000000000,0.378757460447388 +0.000000000000000,0.000028000000000,0.000163000000000,0.000113000000000,0.001066000000000,0.000688000000000,0.002083000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,237.000000000000000,174.000000000000000,121.000000000000000,0.253024524781435,0.270830951731115,117.000000000000000,0.400829834964262 +0.000000000000000,0.000024000000000,0.000148000000000,0.000082000000000,0.000924000000000,0.000665000000000,0.001864000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,243.000000000000000,168.000000000000000,121.000000000000000,0.255837794475283,0.309767339197390,117.000000000000000,0.458455660309276 +0.000000000000000,0.000024000000000,0.000086000000000,0.000079000000000,0.000949000000000,0.000709000000000,0.001867000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,247.000000000000000,176.000000000000000,121.000000000000000,0.242039138156127,0.295753126320285,120.000000000000000,0.437714633120047 +0.000000000000000,0.000017000000000,0.000162000000000,0.000105000000000,0.001033000000000,0.000869000000000,0.002208000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,284.000000000000000,173.000000000000000,121.000000000000000,0.234035640036960,0.262962619721412,120.000000000000000,0.389184684115904 +0.000000000000000,0.000017000000000,0.000148000000000,0.000084000000000,0.000934000000000,0.000632000000000,0.001837000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,323.000000000000000,168.000000000000000,121.000000000000000,0.243963350316049,0.254676670136256,118.000000000000000,0.376921484440742 +0.000000000000000,0.000020000000000,0.000115000000000,0.000080000000000,0.000954000000000,0.000883000000000,0.002074000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,346.000000000000000,164.000000000000000,121.000000000000000,0.237498578056768,0.242318556788754,120.000000000000000,0.358631474732560 +0.000000000000000,0.000026000000000,0.000160000000000,0.000084000000000,0.001068000000000,0.000705000000000,0.002067000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,360.000000000000000,174.000000000000000,121.000000000000000,0.231204379503806,0.310626553544348,119.000000000000000,0.459727290210615 +0.000000000000000,0.000025000000000,0.000107000000000,0.000082000000000,0.000854000000000,0.000734000000000,0.001826000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,371.000000000000000,154.000000000000000,121.000000000000000,0.226372225769396,0.240389889691023,118.000000000000000,0.355777042407619 +0.000000000000000,0.000018000000000,0.000109000000000,0.000077000000000,0.000903000000000,0.000645000000000,0.001789000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,383.000000000000000,163.000000000000000,121.000000000000000,0.243430388985134,0.289702067134667,116.000000000000000,0.428759091467402 +0.000000000000000,0.000023000000000,0.000162000000000,0.000088000000000,0.001172000000000,0.000728000000000,0.002190000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,351.000000000000000,189.000000000000000,121.000000000000000,0.238491169554930,0.289513420723387,119.000000000000000,0.428479887859349 +0.000000000000000,0.000021000000000,0.000095000000000,0.000089000000000,0.001107000000000,0.000638000000000,0.001974000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,351.000000000000000,187.000000000000000,121.000000000000000,0.253535525839367,0.299150984189304,119.000000000000000,0.442743431776745 +0.000000000000000,0.000012000000000,0.000107000000000,0.000073000000000,0.001079000000000,0.000677000000000,0.001968000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,360.000000000000000,182.000000000000000,121.000000000000000,0.242747319355396,0.331002407056278,119.000000000000000,0.489883554348514 +0.000000000000000,0.000022000000000,0.000152000000000,0.000092000000000,0.001093000000000,0.000806000000000,0.002196000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,420.000000000000000,166.000000000000000,121.000000000000000,0.214060131146887,0.291831223233246,120.000000000000000,0.431910240805571 +0.000000000000000,0.000013000000000,0.000086000000000,0.000086000000000,0.001065000000000,0.000781000000000,0.002051000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,467.000000000000000,189.000000000000000,121.000000000000000,0.191542689678233,0.219467905989458,120.000000000000000,0.324812508085401 +0.000000000000000,0.000017000000000,0.000087000000000,0.000076000000000,0.001000000000000,0.000696000000000,0.001897000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,491.000000000000000,176.000000000000000,121.000000000000000,0.237287862315746,0.290385534097234,119.000000000000000,0.429770572749869 +0.000000000000000,0.000015000000000,0.000098000000000,0.000115000000000,0.001209000000000,0.000852000000000,0.002312000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,503.000000000000000,195.000000000000000,121.000000000000000,0.255419259577233,0.271365864372703,119.000000000000000,0.401621476258818 +0.000000000000000,0.000014000000000,0.000106000000000,0.000102000000000,0.001070000000000,0.000640000000000,0.001952000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,519.000000000000000,192.000000000000000,121.000000000000000,0.243354924512186,0.322133979720464,118.000000000000000,0.476758255408191 +0.000000000000000,0.000015000000000,0.000087000000000,0.000074000000000,0.001024000000000,0.000658000000000,0.001878000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,537.000000000000000,182.000000000000000,121.000000000000000,0.256839605640840,0.290001626967172,120.000000000000000,0.429202410592353 +0.000000000000000,0.000019000000000,0.000171000000000,0.000101000000000,0.001223000000000,0.000747000000000,0.002282000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,551.000000000000000,186.000000000000000,121.000000000000000,0.234920975451741,0.278307444024956,121.000000000000000,0.411895021692308 +0.000000000000000,0.000020000000000,0.000085000000000,0.000077000000000,0.001001000000000,0.000765000000000,0.001993000000000,1.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,566.000000000000000,182.000000000000000,121.000000000000000,0.236213272390075,0.243545153610833,120.000000000000000,0.360446828894150 +0.000000000000000,0.000019000000000,0.000102000000000,0.000073000000000,0.001140000000000,0.000640000000000,0.001988000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,523.000000000000000,194.000000000000000,121.000000000000000,0.256770484355549,0.281629623166612,120.000000000000000,0.416811865969600 +0.000000000000000,0.000018000000000,0.000099000000000,0.000139000000000,0.001286000000000,0.000761000000000,0.002328000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,523.000000000000000,193.000000000000000,121.000000000000000,0.238587016371888,0.245006436065432,120.000000000000000,0.362609544894325 +0.000000000000000,0.000020000000000,0.000152000000000,0.000079000000000,0.001167000000000,0.000673000000000,0.002111000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,525.000000000000000,207.000000000000000,121.000000000000000,0.272520106859475,0.292688892408874,120.000000000000000,0.433179596238706 +0.000000000000000,0.000022000000000,0.000132000000000,0.000074000000000,0.001159000000000,0.000620000000000,0.002036000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,532.000000000000000,193.000000000000000,121.000000000000000,0.300157301652565,0.352279034698071,121.000000000000000,0.521372960116753 +0.000000000000000,0.000025000000000,0.000088000000000,0.000085000000000,0.001215000000000,0.000771000000000,0.002209000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,541.000000000000000,192.000000000000000,121.000000000000000,0.262925275260352,0.296134704229152,121.000000000000000,0.438279358303388 +0.000000000000000,0.000018000000000,0.000115000000000,0.000090000000000,0.001041000000000,0.000632000000000,0.001918000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,565.000000000000000,171.000000000000000,121.000000000000000,0.281978346961253,0.308467305071063,121.000000000000000,0.456531611839373 +0.000000000000000,0.000024000000000,0.000152000000000,0.000078000000000,0.001256000000000,0.000758000000000,0.002299000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,608.000000000000000,201.000000000000000,121.000000000000000,0.262127606608173,0.344179498178872,120.000000000000000,0.509385653434813 +0.000000000000000,0.000015000000000,0.000150000000000,0.000084000000000,0.001197000000000,0.000656000000000,0.002124000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,636.000000000000000,196.000000000000000,121.000000000000000,0.243118892914018,0.307363483400101,120.000000000000000,0.454897987687333 +0.000000000000000,0.000021000000000,0.000153000000000,0.000080000000000,0.001146000000000,0.000654000000000,0.002075000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,663.000000000000000,198.000000000000000,121.000000000000000,0.308232628226545,0.324201861364523,120.000000000000000,0.479818779824340 +0.000000000000000,0.000014000000000,0.000090000000000,0.000080000000000,0.001210000000000,0.000638000000000,0.002083000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,687.000000000000000,198.000000000000000,121.000000000000000,0.262176220963531,0.309537239684066,120.000000000000000,0.458115096603436 +0.000000000000000,0.000016000000000,0.000088000000000,0.000083000000000,0.001372000000000,0.000608000000000,0.002184000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,661.000000000000000,229.000000000000000,121.000000000000000,0.297772564345863,0.357204547667525,120.000000000000000,0.528662731800066 +0.000000000000000,0.000019000000000,0.000117000000000,0.000170000000000,0.001186000000000,0.000723000000000,0.002237000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,661.000000000000000,195.000000000000000,121.000000000000000,0.273843523747758,0.292259687716359,119.000000000000000,0.432544362541022 +0.000000000000000,0.000024000000000,0.000153000000000,0.000084000000000,0.001302000000000,0.000641000000000,0.002227000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,668.000000000000000,208.000000000000000,121.000000000000000,0.290286911670839,0.351299244972216,120.000000000000000,0.519922910820696 +0.000000000000000,0.000016000000000,0.000088000000000,0.000087000000000,0.001312000000000,0.000624000000000,0.002148000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,681.000000000000000,211.000000000000000,121.000000000000000,0.258959269785308,0.286064925174815,120.000000000000000,0.423376082295636 +0.000000000000000,0.000032000000000,0.000153000000000,0.000075000000000,0.001269000000000,0.000651000000000,0.002202000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,695.000000000000000,219.000000000000000,121.000000000000000,0.299842600943275,0.306289515328744,118.000000000000000,0.453308488218462 +0.000000000000000,0.000019000000000,0.000193000000000,0.000085000000000,0.001467000000000,0.000596000000000,0.002394000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,704.000000000000000,201.000000000000000,121.000000000000000,0.274895790792161,0.339772965508454,119.000000000000000,0.502863994936072 +0.000000000000000,0.000017000000000,0.000154000000000,0.000080000000000,0.001269000000000,0.000617000000000,0.002161000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,712.000000000000000,205.000000000000000,121.000000000000000,0.276261362669988,0.281418870291626,120.000000000000000,0.416499935291270 +0.000000000000000,0.000016000000000,0.000086000000000,0.000075000000000,0.001135000000000,0.000709000000000,0.002044000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,743.000000000000000,194.000000000000000,121.000000000000000,0.308428304394499,0.293336201315787,118.000000000000000,0.434137551702758 +0.000000000000000,0.000018000000000,0.000171000000000,0.000082000000000,0.001466000000000,0.000783000000000,0.002546000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,769.000000000000000,216.000000000000000,121.000000000000000,0.273449756649530,0.322902720385252,119.000000000000000,0.477896045491622 +0.000000000000000,0.000016000000000,0.000087000000000,0.000083000000000,0.001273000000000,0.000696000000000,0.002177000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,791.000000000000000,204.000000000000000,121.000000000000000,0.288082179726881,0.251959464844591,120.000000000000000,0.372900022480006 +0.000000000000000,0.000016000000000,0.000085000000000,0.000074000000000,0.001110000000000,0.000812000000000,0.002149000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,803.000000000000000,190.000000000000000,121.000000000000000,0.282457893847037,0.276453430621912,117.000000000000000,0.409151077978374 +0.000000000000000,0.000013000000000,0.000172000000000,0.000092000000000,0.001460000000000,0.000864000000000,0.002617000000000,0.000000000000000,111.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,781.000000000000000,208.000000000000000,121.000000000000000,0.294189238611744,0.317837647902468,121.000000000000000,0.470399701551591 +0.000000000000000,0.000011000000000,0.000108000000000,0.000167000000000,0.001206000000000,0.000875000000000,0.002390000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,781.000000000000000,194.000000000000000,121.000000000000000,0.243742619771063,0.304182365871834,119.000000000000000,0.450189939591226 +0.000000000000000,0.000012000000000,0.000101000000000,0.000079000000000,0.001300000000000,0.000731000000000,0.002246000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,803.000000000000000,220.000000000000000,121.000000000000000,0.265019461457802,0.270352874765002,119.000000000000000,0.400122247905802 +0.000000000000000,0.000020000000000,0.000165000000000,0.000097000000000,0.001379000000000,0.000946000000000,0.002634000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,811.000000000000000,196.000000000000000,121.000000000000000,0.253755606620435,0.269982081521535,119.000000000000000,0.399573494543632 +0.000000000000000,0.000016000000000,0.000164000000000,0.000085000000000,0.001383000000000,0.000747000000000,0.002418000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,821.000000000000000,217.000000000000000,121.000000000000000,0.242158681319397,0.277544822144716,118.000000000000000,0.410766329481695 +0.000000000000000,0.000019000000000,0.000149000000000,0.000078000000000,0.001258000000000,0.000689000000000,0.002215000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,826.000000000000000,208.000000000000000,121.000000000000000,0.247027054438406,0.299934280502362,119.000000000000000,0.443902753492513 +0.000000000000000,0.000021000000000,0.000089000000000,0.000096000000000,0.001356000000000,0.000776000000000,0.002363000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,835.000000000000000,206.000000000000000,121.000000000000000,0.251693428883974,0.262689374323986,119.000000000000000,0.388780283669121 +0.000000000000000,0.000014000000000,0.000148000000000,0.000100000000000,0.001257000000000,0.000655000000000,0.002196000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,858.000000000000000,208.000000000000000,121.000000000000000,0.204260997947582,0.239470873759942,121.000000000000000,0.354416885149381 +0.000000000000000,0.000023000000000,0.000162000000000,0.000076000000000,0.001146000000000,0.000648000000000,0.002087000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,887.000000000000000,182.000000000000000,121.000000000000000,0.288689598171738,0.321106098890548,121.000000000000000,0.475237040529197 +0.000000000000000,0.000024000000000,0.000153000000000,0.000091000000000,0.001220000000000,0.000643000000000,0.002186000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,895.000000000000000,169.000000000000000,121.000000000000000,0.226469268954673,0.283662212895001,120.000000000000000,0.419820102888912 +0.000000000000000,0.000024000000000,0.000085000000000,0.000080000000000,0.001237000000000,0.000635000000000,0.002077000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,887.000000000000000,201.000000000000000,121.000000000000000,0.248977774242743,0.301416583242808,121.000000000000000,0.446096553891485 +0.000000000000000,0.000021000000000,0.000171000000000,0.000164000000000,0.001414000000000,0.000769000000000,0.002569000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,881.000000000000000,197.000000000000000,121.000000000000000,0.197091396735570,0.215309872281506,121.000000000000000,0.318658631095349 +0.000000000000000,0.000020000000000,0.000151000000000,0.000085000000000,0.001385000000000,0.000841000000000,0.002509000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,888.000000000000000,208.000000000000000,121.000000000000000,0.211961816387840,0.217745091845774,121.000000000000000,0.322262753412405 +0.000000000000000,0.000018000000000,0.000150000000000,0.000078000000000,0.001242000000000,0.000841000000000,0.002356000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,913.000000000000000,191.000000000000000,121.000000000000000,0.223779838328298,0.264533102759499,119.000000000000000,0.391509013717953 +0.000000000000000,0.000022000000000,0.000097000000000,0.000097000000000,0.001450000000000,0.000723000000000,0.002416000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,960.000000000000000,191.000000000000000,121.000000000000000,0.192480719814296,0.242812842123578,120.000000000000000,0.359363019522775 +0.000000000000000,0.000020000000000,0.000090000000000,0.000082000000000,0.001223000000000,0.000684000000000,0.002125000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1010.000000000000000,186.000000000000000,121.000000000000000,0.226246256927728,0.246572316756408,121.000000000000000,0.364927025819891 +0.000000000000000,0.000018000000000,0.000107000000000,0.000079000000000,0.001240000000000,0.000867000000000,0.002334000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1043.000000000000000,191.000000000000000,121.000000000000000,0.213017300445347,0.226962316320547,121.000000000000000,0.335904230275835 +0.000000000000000,0.000016000000000,0.000187000000000,0.000091000000000,0.001459000000000,0.000724000000000,0.002629000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1066.000000000000000,197.000000000000000,121.000000000000000,0.236488382783212,0.308296711179547,118.000000000000000,0.456279145868659 +0.000000000000000,0.000016000000000,0.000147000000000,0.000085000000000,0.001434000000000,0.000889000000000,0.002595000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1045.000000000000000,222.000000000000000,121.000000000000000,0.203395568382791,0.322649411912471,119.000000000000000,0.477521162587761 +0.000000000000000,0.000019000000000,0.000093000000000,0.000103000000000,0.001526000000000,0.000764000000000,0.002542000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1041.000000000000000,208.000000000000000,121.000000000000000,0.217461375876614,0.242876047600301,119.000000000000000,0.359456575981592 +0.000000000000000,0.000012000000000,0.000089000000000,0.000085000000000,0.001381000000000,0.000699000000000,0.002299000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,202.000000000000000,121.000000000000000,0.237082694302344,0.363703604736602,120.000000000000000,0.538281356749968 +0.000000000000000,0.000013000000000,0.000106000000000,0.000083000000000,0.001290000000000,0.000760000000000,0.002283000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1051.000000000000000,204.000000000000000,121.000000000000000,0.204040454954466,0.217778632970223,121.000000000000000,0.322312387363004 +0.000000000000000,0.000021000000000,0.000089000000000,0.000095000000000,0.001523000000000,0.000740000000000,0.002518000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1092.000000000000000,216.000000000000000,121.000000000000000,0.189496933340522,0.218462243311750,119.000000000000000,0.323324121364161 +0.000000000000000,0.000016000000000,0.000114000000000,0.000088000000000,0.001265000000000,0.000870000000000,0.002384000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1150.000000000000000,195.000000000000000,121.000000000000000,0.234911952172899,0.229829985444704,121.000000000000000,0.340148387945673 +0.000000000000000,0.000022000000000,0.000165000000000,0.000090000000000,0.001383000000000,0.000870000000000,0.002564000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1188.000000000000000,188.000000000000000,121.000000000000000,0.238956119978159,0.242241004289434,119.000000000000000,0.358516689903833 +0.000000000000000,0.000024000000000,0.000125000000000,0.000088000000000,0.001295000000000,0.000732000000000,0.002498000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1209.000000000000000,181.000000000000000,121.000000000000000,0.231068618034561,0.351821584870681,121.000000000000000,0.520695977291580 +0.000000000000000,0.000009000000000,0.000086000000000,0.000086000000000,0.001377000000000,0.000690000000000,0.002304000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1131.000000000000000,223.000000000000000,121.000000000000000,0.232053202367997,0.243086811406556,121.000000000000000,0.359768506659923 +0.000000000000000,0.000015000000000,0.000156000000000,0.000090000000000,0.001467000000000,0.000758000000000,0.002521000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1126.000000000000000,205.000000000000000,121.000000000000000,0.217720599422460,0.232179181942645,120.000000000000000,0.343625190587007 +0.000000000000000,0.000022000000000,0.000088000000000,0.000083000000000,0.001420000000000,0.000856000000000,0.002503000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1122.000000000000000,225.000000000000000,121.000000000000000,0.210873068435952,0.231191074937355,120.000000000000000,0.342162783347037 +0.000000000000000,0.000010000000000,0.000096000000000,0.000092000000000,0.001468000000000,0.000882000000000,0.002583000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1124.000000000000000,218.000000000000000,121.000000000000000,0.199078575841603,0.231934072485734,121.000000000000000,0.343262412908369 +0.000000000000000,0.000014000000000,0.000090000000000,0.000084000000000,0.001429000000000,0.000750000000000,0.002400000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1131.000000000000000,217.000000000000000,121.000000000000000,0.199480471035799,0.201976563717399,121.000000000000000,0.298925319680116 +0.000000000000000,0.000016000000000,0.000086000000000,0.000082000000000,0.001377000000000,0.000677000000000,0.002270000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1170.000000000000000,216.000000000000000,121.000000000000000,0.220678346305332,0.284081275414871,121.000000000000000,0.420440299824576 +0.000000000000000,0.000027000000000,0.000102000000000,0.000086000000000,0.001575000000000,0.000893000000000,0.002726000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1207.000000000000000,220.000000000000000,121.000000000000000,0.211162657455426,0.207040156377078,121.000000000000000,0.306419439695680 +0.000000000000000,0.000016000000000,0.000108000000000,0.000083000000000,0.001461000000000,0.000764000000000,0.002474000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1249.000000000000000,230.000000000000000,121.000000000000000,0.227293453622315,0.273472763274248,121.000000000000000,0.404739696351758 +0.000000000000000,0.000016000000000,0.000088000000000,0.000078000000000,0.001528000000000,0.000670000000000,0.002548000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,235.000000000000000,121.000000000000000,0.230650938262149,0.341719334696620,121.000000000000000,0.505744634189104 +0.000000000000000,0.000014000000000,0.000157000000000,0.000097000000000,0.001482000000000,0.000903000000000,0.002719000000000,0.000000000000000,106.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1118.000000000000000,225.000000000000000,121.000000000000000,0.192289115182234,0.284781239296802,121.000000000000000,0.421476244276178 +0.000000000000000,0.000009000000000,0.000107000000000,0.000085000000000,0.001393000000000,0.000822000000000,0.002450000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1112.000000000000000,223.000000000000000,121.000000000000000,0.206644050900703,0.414842370987539,120.000000000000000,0.613966712358429 +0.000000000000000,0.000013000000000,0.000119000000000,0.000087000000000,0.001684000000000,0.000696000000000,0.002637000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1116.000000000000000,248.000000000000000,121.000000000000000,0.217279659889557,0.386405943424662,121.000000000000000,0.571880811943511 +0.000000000000000,0.000013000000000,0.000107000000000,0.000086000000000,0.001569000000000,0.000810000000000,0.002621000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1115.000000000000000,245.000000000000000,121.000000000000000,0.205227319768628,0.260415513728504,121.000000000000000,0.385414955241683 +0.000000000000000,0.000017000000000,0.000090000000000,0.000082000000000,0.001607000000000,0.000835000000000,0.002666000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1141.000000000000000,234.000000000000000,121.000000000000000,0.215577332340184,0.253414375214643,120.000000000000000,0.375053286801197 +0.000000000000000,0.000018000000000,0.000118000000000,0.000089000000000,0.001476000000000,0.000855000000000,0.002594000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1162.000000000000000,189.000000000000000,121.000000000000000,0.263380285246488,0.344156012084719,121.000000000000000,0.509350879343151 +0.000000000000000,0.000019000000000,0.000107000000000,0.000079000000000,0.001350000000000,0.000913000000000,0.002498000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1191.000000000000000,211.000000000000000,121.000000000000000,0.211941539220644,0.302129709054244,121.000000000000000,0.447152008225909 +0.000000000000000,0.000017000000000,0.000113000000000,0.000084000000000,0.001500000000000,0.000792000000000,0.002540000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1216.000000000000000,227.000000000000000,121.000000000000000,0.202379365741516,0.390009847847033,120.000000000000000,0.577214540970843 +0.000000000000000,0.000011000000000,0.000089000000000,0.000087000000000,0.001487000000000,0.000793000000000,0.002500000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1231.000000000000000,213.000000000000000,121.000000000000000,0.214175551012714,0.216953676956891,120.000000000000000,0.321091452830759 +0.000000000000000,0.000015000000000,0.000086000000000,0.000080000000000,0.001432000000000,0.000687000000000,0.002331000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,223.000000000000000,121.000000000000000,0.199434039847726,0.257284849007253,121.000000000000000,0.380781610790163 +0.000000000000000,0.000014000000000,0.000093000000000,0.000084000000000,0.001629000000000,0.000756000000000,0.002612000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,237.000000000000000,121.000000000000000,0.197980635555219,0.261749609075989,121.000000000000000,0.387389446361990 +0.000000000000000,0.000017000000000,0.000088000000000,0.000087000000000,0.001493000000000,0.000846000000000,0.002566000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1233.000000000000000,228.000000000000000,121.000000000000000,0.236508484356981,0.240200224772688,121.000000000000000,0.355496322487429 +0.000000000000000,0.000014000000000,0.000164000000000,0.000088000000000,0.001671000000000,0.000811000000000,0.002926000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,248.000000000000000,121.000000000000000,0.184315305243839,0.201680214668134,121.000000000000000,0.298486726394656 +0.000000000000000,0.000013000000000,0.000164000000000,0.000099000000000,0.001590000000000,0.000831000000000,0.002766000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1105.000000000000000,230.000000000000000,121.000000000000000,0.190613955848338,0.200507971284196,120.000000000000000,0.296751787320034 +0.000000000000000,0.000016000000000,0.000087000000000,0.000085000000000,0.001377000000000,0.000850000000000,0.002444000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1104.000000000000000,218.000000000000000,121.000000000000000,0.200535674470726,0.209035608733197,120.000000000000000,0.309372710300047 +0.000000000000000,0.000013000000000,0.000091000000000,0.000089000000000,0.001407000000000,0.000797000000000,0.002429000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1144.000000000000000,201.000000000000000,121.000000000000000,0.227018445721033,0.269171979187375,121.000000000000000,0.398374546537365 +0.000000000000000,0.000024000000000,0.000159000000000,0.000086000000000,0.001427000000000,0.000852000000000,0.002589000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1182.000000000000000,206.000000000000000,121.000000000000000,0.206458268024795,0.213071493736729,121.000000000000000,0.315345817611568 +0.000000000000000,0.000023000000000,0.000096000000000,0.000084000000000,0.001443000000000,0.000848000000000,0.002527000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1214.000000000000000,197.000000000000000,121.000000000000000,0.195773117170614,0.235723820191720,120.000000000000000,0.348871251500985 +0.000000000000000,0.000018000000000,0.000166000000000,0.000097000000000,0.001547000000000,0.000786000000000,0.002646000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,206.000000000000000,121.000000000000000,0.202449512908354,0.259327833750046,121.000000000000000,0.383805213005791 +0.000000000000000,0.000015000000000,0.000089000000000,0.000085000000000,0.001354000000000,0.000899000000000,0.002473000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1255.000000000000000,195.000000000000000,121.000000000000000,0.234803205654552,0.251609191002594,120.000000000000000,0.372381595360564 +0.000000000000000,0.000015000000000,0.000148000000000,0.000079000000000,0.001434000000000,0.000759000000000,0.002612000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1267.000000000000000,221.000000000000000,121.000000000000000,0.207185371940379,0.272198837560189,121.000000000000000,0.402854263297596 +0.000000000000000,0.000014000000000,0.000110000000000,0.000089000000000,0.001471000000000,0.000697000000000,0.002442000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1147.000000000000000,216.000000000000000,121.000000000000000,0.170542136055104,0.199853580496046,121.000000000000000,0.295783293486634 +0.000000000000000,0.000011000000000,0.000140000000000,0.000086000000000,0.001577000000000,0.000769000000000,0.002617000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1147.000000000000000,234.000000000000000,121.000000000000000,0.189245949418993,0.197736413403659,121.000000000000000,0.292649910272330 +0.000000000000000,0.000018000000000,0.000166000000000,0.000094000000000,0.001662000000000,0.000699000000000,0.002677000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1177.000000000000000,225.000000000000000,121.000000000000000,0.198921843902340,0.245387061075502,119.000000000000000,0.363172854853005 +0.000000000000000,0.000010000000000,0.000149000000000,0.000107000000000,0.001458000000000,0.000785000000000,0.002541000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1221.000000000000000,222.000000000000000,121.000000000000000,0.196061687568370,0.262447572567731,121.000000000000000,0.388422408733057 +0.000000000000000,0.000013000000000,0.000150000000000,0.000086000000000,0.001461000000000,0.000690000000000,0.002431000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1264.000000000000000,222.000000000000000,121.000000000000000,0.188165247064654,0.226893158617754,120.000000000000000,0.335801879206626 +0.000000000000000,0.000011000000000,0.000087000000000,0.000090000000000,0.001543000000000,0.000884000000000,0.002648000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1280.000000000000000,221.000000000000000,121.000000000000000,0.195179134679885,0.208025099223027,119.000000000000000,0.307877146368027 +0.000000000000000,0.000014000000000,0.000208000000000,0.000082000000000,0.001576000000000,0.000716000000000,0.002630000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1295.000000000000000,262.000000000000000,121.000000000000000,0.204969117934416,0.216857241486732,119.000000000000000,0.320948742586853 +0.000000000000000,0.000024000000000,0.000169000000000,0.000098000000000,0.001343000000000,0.000853000000000,0.002520000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1303.000000000000000,192.000000000000000,121.000000000000000,0.227441413063451,0.257511508846672,120.000000000000000,0.381117019034739 +0.000000000000000,0.000009000000000,0.000087000000000,0.000083000000000,0.001482000000000,0.000867000000000,0.002560000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1303.000000000000000,234.000000000000000,121.000000000000000,0.206543419238523,0.240601524255942,121.000000000000000,0.356090287223134 +0.000000000000000,0.000017000000000,0.000085000000000,0.000090000000000,0.001430000000000,0.000831000000000,0.002586000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1312.000000000000000,207.000000000000000,121.000000000000000,0.208575675835164,0.214150033311086,121.000000000000000,0.316942039397577 +0.000000000000000,0.000015000000000,0.000164000000000,0.000102000000000,0.001530000000000,0.000841000000000,0.002712000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1139.000000000000000,223.000000000000000,121.000000000000000,0.209522023711657,0.213144284667314,121.000000000000000,0.315453551588861 +0.000000000000000,0.000015000000000,0.000105000000000,0.000078000000000,0.001301000000000,0.000820000000000,0.002350000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1137.000000000000000,212.000000000000000,121.000000000000000,0.214867803164927,0.261245240464500,120.000000000000000,0.386642965897231 +0.000000000000000,0.000016000000000,0.000101000000000,0.000080000000000,0.001381000000000,0.000813000000000,0.002424000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1182.000000000000000,188.000000000000000,121.000000000000000,0.205519375020890,0.194082271824269,121.000000000000000,0.287241755590969 +0.000000000000000,0.000013000000000,0.000149000000000,0.000084000000000,0.001317000000000,0.000634000000000,0.002230000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,190.000000000000000,121.000000000000000,0.193630790736426,0.209509974832839,121.000000000000000,0.310074762819209 +0.000000000000000,0.000020000000000,0.000095000000000,0.000087000000000,0.001465000000000,0.000730000000000,0.002432000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1251.000000000000000,218.000000000000000,121.000000000000000,0.192820932489665,0.213663301525895,121.000000000000000,0.316221664773433 +0.000000000000000,0.000019000000000,0.000163000000000,0.000085000000000,0.001400000000000,0.000794000000000,0.002498000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1258.000000000000000,187.000000000000000,121.000000000000000,0.178472893331951,0.196146108608914,120.000000000000000,0.290296240030441 +0.000000000000000,0.000012000000000,0.000108000000000,0.000091000000000,0.001293000000000,0.000751000000000,0.002285000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1274.000000000000000,203.000000000000000,121.000000000000000,0.204380791067604,0.211515445058425,119.000000000000000,0.313042868010643 +0.000000000000000,0.000017000000000,0.000161000000000,0.000078000000000,0.001276000000000,0.000745000000000,0.002316000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1284.000000000000000,207.000000000000000,121.000000000000000,0.187808408411530,0.214316116353771,121.000000000000000,0.317187858866760 +0.000000000000000,0.000015000000000,0.000093000000000,0.000089000000000,0.001466000000000,0.000749000000000,0.002445000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1286.000000000000000,207.000000000000000,121.000000000000000,0.199989980411572,0.230213140472726,121.000000000000000,0.340715438140956 +0.000000000000000,0.000016000000000,0.000150000000000,0.000081000000000,0.001405000000000,0.000699000000000,0.002385000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,213.000000000000000,121.000000000000000,0.206268660764417,0.237247311670881,121.000000000000000,0.351126007647841 +0.000000000000000,0.000020000000000,0.000155000000000,0.000079000000000,0.001337000000000,0.000555000000000,0.002180000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1279.000000000000000,203.000000000000000,121.000000000000000,0.183003834372267,0.219788084820077,121.000000000000000,0.325286355628032 +0.000000000000000,0.000024000000000,0.000162000000000,0.000089000000000,0.001394000000000,0.000718000000000,0.002565000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1272.000000000000000,191.000000000000000,121.000000000000000,0.186553971804931,0.182751341988290,121.000000000000000,0.270472000430761 +0.000000000000000,0.000016000000000,0.000109000000000,0.000097000000000,0.001309000000000,0.000793000000000,0.002379000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1148.000000000000000,206.000000000000000,121.000000000000000,0.182081620850879,0.190648173777097,119.000000000000000,0.282159304756511 +0.000000000000000,0.000018000000000,0.000165000000000,0.000085000000000,0.001434000000000,0.001000000000000,0.002736000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1146.000000000000000,198.000000000000000,121.000000000000000,0.161190220960006,0.185797469108689,121.000000000000000,0.274980249131025 +0.000000000000000,0.000017000000000,0.000065000000000,0.000084000000000,0.001165000000000,0.000868000000000,0.002227000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1202.000000000000000,183.000000000000000,121.000000000000000,0.182593650165736,0.182593650165736,120.000000000000000,0.270238614721097 +0.000000000000000,0.000013000000000,0.000106000000000,0.000081000000000,0.001303000000000,0.000768000000000,0.002301000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1222.000000000000000,185.000000000000000,121.000000000000000,0.166736786826383,0.199418227406995,120.000000000000000,0.295138987188000 +0.000000000000000,0.000015000000000,0.000109000000000,0.000095000000000,0.001360000000000,0.000938000000000,0.002546000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1249.000000000000000,189.000000000000000,121.000000000000000,0.191808443828625,0.226302606500564,121.000000000000000,0.334927876891194 +0.000000000000000,0.000019000000000,0.000163000000000,0.000087000000000,0.001234000000000,0.000928000000000,0.002463000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,165.000000000000000,121.000000000000000,0.166580449599247,0.180745814173528,121.000000000000000,0.267503794151850 +0.000000000000000,0.000023000000000,0.000090000000000,0.000087000000000,0.001327000000000,0.000948000000000,0.002508000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1289.000000000000000,189.000000000000000,121.000000000000000,0.204446978142314,0.213236190122245,120.000000000000000,0.315589564787498 +0.000000000000000,0.000012000000000,0.000089000000000,0.000086000000000,0.001424000000000,0.000752000000000,0.002394000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1303.000000000000000,207.000000000000000,121.000000000000000,0.189969084150173,0.239096854811035,121.000000000000000,0.353863330132112 +0.000000000000000,0.000018000000000,0.000151000000000,0.000084000000000,0.001303000000000,0.000702000000000,0.002297000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1309.000000000000000,198.000000000000000,121.000000000000000,0.203248106998635,0.283179509252321,120.000000000000000,0.419105667153969 +0.000000000000000,0.000018000000000,0.000121000000000,0.000114000000000,0.001451000000000,0.000873000000000,0.002610000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1309.000000000000000,186.000000000000000,121.000000000000000,0.193450874101625,0.200224929073400,120.000000000000000,0.296332880820479 +0.000000000000000,0.000016000000000,0.000099000000000,0.000085000000000,0.001266000000000,0.000850000000000,0.002346000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1307.000000000000000,182.000000000000000,121.000000000000000,0.190247303390951,0.176735411055755,120.000000000000000,0.261568417740656 +0.000000000000000,0.000017000000000,0.000148000000000,0.000080000000000,0.001332000000000,0.000666000000000,0.002391000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1339.000000000000000,203.000000000000000,121.000000000000000,0.200414786051663,0.221307330406924,119.000000000000000,0.327534844351391 +0.000000000000000,0.000016000000000,0.000157000000000,0.000094000000000,0.001205000000000,0.000724000000000,0.002264000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1203.000000000000000,168.000000000000000,121.000000000000000,0.199743231584850,0.225956586080112,121.000000000000000,0.334415767738987 +0.000000000000000,0.000011000000000,0.000087000000000,0.000092000000000,0.001277000000000,0.000769000000000,0.002270000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1198.000000000000000,184.000000000000000,121.000000000000000,0.148096017248236,0.229791243682201,121.000000000000000,0.340091046075047 +0.000000000000000,0.000015000000000,0.000098000000000,0.000084000000000,0.001401000000000,0.000839000000000,0.002470000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,207.000000000000000,121.000000000000000,0.171701277226300,0.189474819161897,121.000000000000000,0.280422723010407 +0.000000000000000,0.000015000000000,0.000157000000000,0.000086000000000,0.001295000000000,0.000747000000000,0.002332000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1272.000000000000000,197.000000000000000,121.000000000000000,0.154842494097145,0.164895074486922,120.000000000000000,0.244044726914351 +0.000000000000000,0.000013000000000,0.000151000000000,0.000078000000000,0.001295000000000,0.000656000000000,0.002225000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1288.000000000000000,190.000000000000000,121.000000000000000,0.171037240946432,0.274189059551541,121.000000000000000,0.405799825981935 +0.000000000000000,0.000012000000000,0.000163000000000,0.000096000000000,0.001404000000000,0.000731000000000,0.002442000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1300.000000000000000,186.000000000000000,121.000000000000000,0.183021843966101,0.234105160743232,121.000000000000000,0.346475629956656 +0.000000000000000,0.000015000000000,0.000096000000000,0.000083000000000,0.001337000000000,0.000726000000000,0.002288000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1307.000000000000000,185.000000000000000,121.000000000000000,0.183461220328528,0.207991417189789,121.000000000000000,0.307827284970608 +0.000000000000000,0.000016000000000,0.000149000000000,0.000080000000000,0.001274000000000,0.000606000000000,0.002156000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1313.000000000000000,200.000000000000000,121.000000000000000,0.203158950593758,0.241305735673881,121.000000000000000,0.357132499098233 +0.000000000000000,0.000012000000000,0.000152000000000,0.000083000000000,0.001408000000000,0.000621000000000,0.002310000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1319.000000000000000,207.000000000000000,121.000000000000000,0.172769464465069,0.242423202061487,121.000000000000000,0.358786340745426 +0.000000000000000,0.000017000000000,0.000155000000000,0.000087000000000,0.001210000000000,0.000693000000000,0.002332000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1314.000000000000000,179.000000000000000,121.000000000000000,0.189900236210407,0.248224778263959,121.000000000000000,0.367372660392853 +0.000000000000000,0.000013000000000,0.000157000000000,0.000092000000000,0.001368000000000,0.000607000000000,0.002301000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1110.000000000000000,204.000000000000000,121.000000000000000,0.167414207784906,0.238891530166090,121.000000000000000,0.353559486451843 +0.000000000000000,0.000017000000000,0.000092000000000,0.000082000000000,0.001333000000000,0.000748000000000,0.002306000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1103.000000000000000,197.000000000000000,121.000000000000000,0.164998017179115,0.188230341089860,121.000000000000000,0.278580909202036 +0.000000000000000,0.000011000000000,0.000150000000000,0.000082000000000,0.001388000000000,0.000755000000000,0.002418000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1146.000000000000000,219.000000000000000,121.000000000000000,0.173088299071632,0.182167160144569,121.000000000000000,0.269607399250574 +0.000000000000000,0.000014000000000,0.000095000000000,0.000091000000000,0.001460000000000,0.000843000000000,0.002540000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1188.000000000000000,199.000000000000000,121.000000000000000,0.159193450711399,0.194342796414950,121.000000000000000,0.287627328495391 +0.000000000000000,0.000023000000000,0.000162000000000,0.000084000000000,0.001428000000000,0.000661000000000,0.002402000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1213.000000000000000,213.000000000000000,121.000000000000000,0.163604775275874,0.178874584867471,121.000000000000000,0.264734376394025 +0.000000000000000,0.000015000000000,0.000091000000000,0.000079000000000,0.001243000000000,0.000704000000000,0.002165000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1240.000000000000000,184.000000000000000,121.000000000000000,0.179908260850595,0.207929795609648,121.000000000000000,0.307736104067471 +0.000000000000000,0.000014000000000,0.000152000000000,0.000086000000000,0.001314000000000,0.000826000000000,0.002424000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1263.000000000000000,189.000000000000000,121.000000000000000,0.159876479501220,0.178421775752828,121.000000000000000,0.264064216973465 +0.000000000000000,0.000013000000000,0.000087000000000,0.000080000000000,0.001408000000000,0.000757000000000,0.002377000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,210.000000000000000,121.000000000000000,0.180877939732212,0.181463986212420,121.000000000000000,0.268566703687611 +0.000000000000000,0.000011000000000,0.000088000000000,0.000086000000000,0.001449000000000,0.000746000000000,0.002414000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1279.000000000000000,209.000000000000000,121.000000000000000,0.194139433375495,0.249420140021997,121.000000000000000,0.369141792306152 +0.000000000000000,0.000013000000000,0.000095000000000,0.000083000000000,0.001315000000000,0.000730000000000,0.002270000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1277.000000000000000,178.000000000000000,121.000000000000000,0.156793757882320,0.178864440219203,120.000000000000000,0.264719390175743 +0.000000000000000,0.000012000000000,0.000127000000000,0.000079000000000,0.001313000000000,0.000701000000000,0.002265000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,185.000000000000000,121.000000000000000,0.164883000136156,0.240733177667065,121.000000000000000,0.356285108060795 +0.000000000000000,0.000014000000000,0.000166000000000,0.000100000000000,0.001393000000000,0.000725000000000,0.002432000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1318.000000000000000,183.000000000000000,121.000000000000000,0.135728889598211,0.162060045311901,119.000000000000000,0.239848863786058 +0.000000000000000,0.000015000000000,0.000155000000000,0.000089000000000,0.001343000000000,0.000750000000000,0.002387000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1356.000000000000000,191.000000000000000,121.000000000000000,0.173788063146282,0.195529217779223,121.000000000000000,0.289383243221234 +0.000000000000000,0.000016000000000,0.000150000000000,0.000078000000000,0.001258000000000,0.000644000000000,0.002300000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1395.000000000000000,185.000000000000000,121.000000000000000,0.151475576157850,0.175539257809215,121.000000000000000,0.259798098049517 +0.000000000000000,0.000011000000000,0.000151000000000,0.000096000000000,0.001555000000000,0.000651000000000,0.002540000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1235.000000000000000,239.000000000000000,121.000000000000000,0.155311911245058,0.179651409086422,121.000000000000000,0.265884094799596 +0.000000000000000,0.000013000000000,0.000088000000000,0.000084000000000,0.001324000000000,0.000729000000000,0.002270000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,203.000000000000000,121.000000000000000,0.164537143262273,0.221612984534127,121.000000000000000,0.327987236077292 +0.000000000000000,0.000013000000000,0.000098000000000,0.000087000000000,0.001493000000000,0.000702000000000,0.002430000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1240.000000000000000,208.000000000000000,121.000000000000000,0.175143219815607,0.215695284047881,121.000000000000000,0.319229017177332 +0.000000000000000,0.000023000000000,0.000119000000000,0.000088000000000,0.001527000000000,0.000683000000000,0.002476000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,213.000000000000000,121.000000000000000,0.153675591056653,0.182664252108742,121.000000000000000,0.270343088627296 +0.000000000000000,0.000014000000000,0.000151000000000,0.000078000000000,0.001233000000000,0.000696000000000,0.002204000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1239.000000000000000,203.000000000000000,121.000000000000000,0.153229115354477,0.193081832581164,121.000000000000000,0.285761102061624 +0.000000000000000,0.000021000000000,0.000143000000000,0.000123000000000,0.001403000000000,0.000694000000000,0.002424000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1238.000000000000000,184.000000000000000,121.000000000000000,0.139965152794629,0.227002185063016,120.000000000000000,0.335963240089810 +0.000000000000000,0.000015000000000,0.000110000000000,0.000088000000000,0.001404000000000,0.000704000000000,0.002355000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,209.000000000000000,121.000000000000000,0.137197338848433,0.208531405635090,121.000000000000000,0.308626482553977 +0.000000000000000,0.000018000000000,0.000088000000000,0.000079000000000,0.001190000000000,0.000700000000000,0.002107000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,188.000000000000000,121.000000000000000,0.130941105653028,0.146060909721641,121.000000000000000,0.216170158735599 +0.000000000000000,0.000021000000000,0.000118000000000,0.000089000000000,0.001415000000000,0.000816000000000,0.002492000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,184.000000000000000,121.000000000000000,0.153353796799625,0.199263806316360,121.000000000000000,0.294910453677173 +0.000000000000000,0.000017000000000,0.000151000000000,0.000082000000000,0.001223000000000,0.000698000000000,0.002202000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1228.000000000000000,179.000000000000000,121.000000000000000,0.140213553319483,0.175196026122660,121.000000000000000,0.259290133483817 +0.000000000000000,0.000019000000000,0.000155000000000,0.000078000000000,0.001255000000000,0.000811000000000,0.002351000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1229.000000000000000,190.000000000000000,121.000000000000000,0.130014281845411,0.153376137782893,120.000000000000000,0.226996677933372 +0.000000000000000,0.000017000000000,0.000119000000000,0.000089000000000,0.001341000000000,0.000705000000000,0.002417000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1228.000000000000000,181.000000000000000,121.000000000000000,0.153048040967559,0.195396547391727,121.000000000000000,0.289186880799568 +0.000000000000000,0.000034000000000,0.000168000000000,0.000085000000000,0.001355000000000,0.000876000000000,0.002565000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1098.000000000000000,224.000000000000000,121.000000000000000,0.139772469128747,0.173322524076028,121.000000000000000,0.256517354567422 +0.000000000000000,0.000017000000000,0.000164000000000,0.000090000000000,0.001416000000000,0.000893000000000,0.002614000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1096.000000000000000,199.000000000000000,121.000000000000000,0.153304734612976,0.183642468789981,120.000000000000000,0.271790863455149 +0.000000000000000,0.000016000000000,0.000151000000000,0.000085000000000,0.001314000000000,0.000712000000000,0.002309000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1169.000000000000000,206.000000000000000,121.000000000000000,0.142897294139319,0.181555340311233,120.000000000000000,0.268701908186442 +0.000000000000000,0.000015000000000,0.000117000000000,0.000085000000000,0.001376000000000,0.000780000000000,0.002405000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1216.000000000000000,222.000000000000000,121.000000000000000,0.126799378274116,0.146656265445468,120.000000000000000,0.217051287718072 +0.000000000000000,0.000016000000000,0.000165000000000,0.000106000000000,0.001478000000000,0.000760000000000,0.002565000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1236.000000000000000,202.000000000000000,121.000000000000000,0.140084421158853,0.204486312942259,121.000000000000000,0.302639753705096 +0.000000000000000,0.000011000000000,0.000107000000000,0.000080000000000,0.001194000000000,0.000749000000000,0.002169000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1246.000000000000000,201.000000000000000,121.000000000000000,0.139419993339841,0.168128905916729,121.000000000000000,0.248830789269877 +0.000000000000000,0.000014000000000,0.000152000000000,0.000092000000000,0.001362000000000,0.000736000000000,0.002390000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1247.000000000000000,196.000000000000000,121.000000000000000,0.145258293429478,0.175683893358186,121.000000000000000,0.260012150779442 +0.000000000000000,0.000017000000000,0.000165000000000,0.000083000000000,0.001281000000000,0.000789000000000,0.002367000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1243.000000000000000,182.000000000000000,121.000000000000000,0.130776175712068,0.189705854296339,121.000000000000000,0.280764651397170 +0.000000000000000,0.000014000000000,0.000148000000000,0.000080000000000,0.001146000000000,0.000646000000000,0.002066000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1231.000000000000000,185.000000000000000,121.000000000000000,0.160961980060978,0.209744716515705,121.000000000000000,0.310422175201532 +0.000000000000000,0.000017000000000,0.000165000000000,0.000099000000000,0.001434000000000,0.000756000000000,0.002649000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1229.000000000000000,192.000000000000000,121.000000000000000,0.148237727429110,0.178425698740388,121.000000000000000,0.264070029503321 +0.000000000000000,0.000009000000000,0.000152000000000,0.000088000000000,0.001271000000000,0.000627000000000,0.002203000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1070.000000000000000,202.000000000000000,121.000000000000000,0.145517296057557,0.194221829742895,121.000000000000000,0.287448302575818 +0.000000000000000,0.000013000000000,0.000171000000000,0.000110000000000,0.001292000000000,0.000667000000000,0.002296000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1062.000000000000000,207.000000000000000,121.000000000000000,0.144870620749843,0.185268776731061,120.000000000000000,0.274197806796764 +0.000000000000000,0.000012000000000,0.000167000000000,0.000090000000000,0.001672000000000,0.000784000000000,0.002761000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1051.000000000000000,240.000000000000000,121.000000000000000,0.147451415472805,0.239110494103313,121.000000000000000,0.353883547627265 +0.000000000000000,0.000023000000000,0.000169000000000,0.000084000000000,0.001225000000000,0.000708000000000,0.002240000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1058.000000000000000,193.000000000000000,121.000000000000000,0.139221728219021,0.208258123486744,121.000000000000000,0.308222006291587 +0.000000000000000,0.000018000000000,0.000114000000000,0.000095000000000,0.001441000000000,0.000867000000000,0.002569000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1122.000000000000000,195.000000000000000,121.000000000000000,0.144798866574318,0.161179631549979,121.000000000000000,0.238545871495364 +0.000000000000000,0.000015000000000,0.000087000000000,0.000084000000000,0.001190000000000,0.000950000000000,0.002357000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1161.000000000000000,181.000000000000000,121.000000000000000,0.156951809426305,0.174642571732918,121.000000000000000,0.258471021667723 +0.000000000000000,0.000025000000000,0.000109000000000,0.000081000000000,0.001177000000000,0.000732000000000,0.002154000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1178.000000000000000,188.000000000000000,121.000000000000000,0.143966687089071,0.148286357619255,121.000000000000000,0.219463816142722 +0.000000000000000,0.000016000000000,0.000167000000000,0.000091000000000,0.001397000000000,0.000699000000000,0.002561000000000,1.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1185.000000000000000,186.000000000000000,121.000000000000000,0.141904983877111,0.215844079586902,120.000000000000000,0.319449236243278 +0.000000000000000,0.000013000000000,0.000107000000000,0.000086000000000,0.001203000000000,0.000597000000000,0.002056000000000,0.000000000000000,109.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1024.000000000000000,198.000000000000000,121.000000000000000,0.158784086059447,0.201694183533691,121.000000000000000,0.298507398783450 +0.000000000000000,0.000011000000000,0.000112000000000,0.000087000000000,0.001357000000000,0.000625000000000,0.002227000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1012.000000000000000,200.000000000000000,121.000000000000000,0.142538196203460,0.192228508218454,121.000000000000000,0.284498190955069 +0.000000000000000,0.000011000000000,0.000111000000000,0.000090000000000,0.001358000000000,0.000662000000000,0.002264000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1012.000000000000000,207.000000000000000,121.000000000000000,0.168549877781207,0.187821262175372,121.000000000000000,0.277975471037833 +0.000000000000000,0.000012000000000,0.000149000000000,0.000117000000000,0.001286000000000,0.000829000000000,0.002423000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1008.000000000000000,214.000000000000000,121.000000000000000,0.143759909717310,0.192182987333624,121.000000000000000,0.284430816152474 +0.000000000000000,0.000015000000000,0.000167000000000,0.000090000000000,0.001493000000000,0.000810000000000,0.002612000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1001.000000000000000,212.000000000000000,121.000000000000000,0.174890959675259,0.213312437262072,121.000000000000000,0.315702428954185 +0.000000000000000,0.000019000000000,0.000151000000000,0.000086000000000,0.001409000000000,0.000712000000000,0.002407000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1001.000000000000000,207.000000000000000,121.000000000000000,0.152789140763855,0.164105200132453,121.000000000000000,0.242875700800910 +0.000000000000000,0.000016000000000,0.000087000000000,0.000081000000000,0.001205000000000,0.000602000000000,0.002152000000000,1.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1043.000000000000000,199.000000000000000,121.000000000000000,0.163939125281343,0.202213714394798,120.000000000000000,0.299276295395959 +0.000000000000000,0.000011000000000,0.000111000000000,0.000101000000000,0.001485000000000,0.000606000000000,0.002388000000000,0.000000000000000,105.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,933.000000000000000,228.000000000000000,121.000000000000000,0.162381916777401,0.199296542527132,121.000000000000000,0.294958899849931 +0.000000000000000,0.000012000000000,0.000086000000000,0.000086000000000,0.001214000000000,0.000711000000000,0.002139000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,930.000000000000000,188.000000000000000,121.000000000000000,0.126548973306942,0.138574150155498,120.000000000000000,0.205089745706516 +0.000000000000000,0.000012000000000,0.000167000000000,0.000087000000000,0.001455000000000,0.000638000000000,0.002392000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,959.000000000000000,226.000000000000000,121.000000000000000,0.166801187642930,0.183010323861591,120.000000000000000,0.270855273595110 +0.000000000000000,0.000014000000000,0.000088000000000,0.000087000000000,0.001409000000000,0.000740000000000,0.002371000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,966.000000000000000,208.000000000000000,121.000000000000000,0.151605751950910,0.214754024488413,120.000000000000000,0.317835955945735 +0.000000000000000,0.000017000000000,0.000112000000000,0.000085000000000,0.001310000000000,0.000658000000000,0.002217000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,966.000000000000000,202.000000000000000,121.000000000000000,0.149723343863280,0.232974269786109,121.000000000000000,0.344801899348607 +0.000000000000000,0.000014000000000,0.000143000000000,0.000095000000000,0.001352000000000,0.001073000000000,0.002710000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,980.000000000000000,184.000000000000000,121.000000000000000,0.155861567427539,0.183956647347986,120.000000000000000,0.272255840571782 +0.000000000000000,0.000014000000000,0.000149000000000,0.000084000000000,0.001120000000000,0.000720000000000,0.002120000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,984.000000000000000,177.000000000000000,121.000000000000000,0.150101106525736,0.181285553460186,121.000000000000000,0.268302612657185 +0.000000000000000,0.000011000000000,0.000154000000000,0.000077000000000,0.001135000000000,0.000704000000000,0.002114000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1009.000000000000000,162.000000000000000,121.000000000000000,0.164203457795522,0.166918334037277,121.000000000000000,0.247039140121353 +0.000000000000000,0.000014000000000,0.000153000000000,0.000087000000000,0.001265000000000,0.000661000000000,0.002212000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1044.000000000000000,184.000000000000000,121.000000000000000,0.166079753752638,0.235937082097295,121.000000000000000,0.349186897144050 +0.000000000000000,0.000016000000000,0.000087000000000,0.000079000000000,0.001083000000000,0.000776000000000,0.002071000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1065.000000000000000,179.000000000000000,121.000000000000000,0.140784932440615,0.174109634177219,121.000000000000000,0.257682261366227 +0.000000000000000,0.000017000000000,0.000177000000000,0.000085000000000,0.001217000000000,0.000893000000000,0.002614000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1085.000000000000000,173.000000000000000,121.000000000000000,0.136693367503916,0.164873100634404,121.000000000000000,0.244012202019025 +0.000000000000000,0.000010000000000,0.000111000000000,0.000098000000000,0.001335000000000,0.000674000000000,0.002290000000000,0.000000000000000,108.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,940.000000000000000,210.000000000000000,121.000000000000000,0.152064884062461,0.157064948938113,121.000000000000000,0.232456109236813 +0.000000000000000,0.000009000000000,0.000148000000000,0.000085000000000,0.001199000000000,0.000682000000000,0.002153000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,937.000000000000000,196.000000000000000,121.000000000000000,0.149276999735119,0.172780031999726,121.000000000000000,0.255714442019319 +0.000000000000000,0.000016000000000,0.000157000000000,0.000094000000000,0.001300000000000,0.000821000000000,0.002420000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,948.000000000000000,187.000000000000000,121.000000000000000,0.151768200456098,0.155713508180996,121.000000000000000,0.230455992441400 +0.000000000000000,0.000019000000000,0.000116000000000,0.000085000000000,0.001196000000000,0.000791000000000,0.002239000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,950.000000000000000,186.000000000000000,121.000000000000000,0.144000321191294,0.179229516503960,121.000000000000000,0.265259702733687 +0.000000000000000,0.000013000000000,0.000154000000000,0.000083000000000,0.001139000000000,0.000808000000000,0.002231000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,960.000000000000000,170.000000000000000,121.000000000000000,0.152250251263816,0.176190168633417,121.000000000000000,0.260761436421654 +0.000000000000000,0.000015000000000,0.000087000000000,0.000085000000000,0.001127000000000,0.000768000000000,0.002115000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,983.000000000000000,164.000000000000000,121.000000000000000,0.129302901903334,0.143871781002835,121.000000000000000,0.212930229321842 +0.000000000000000,0.000013000000000,0.000110000000000,0.000120000000000,0.001152000000000,0.000761000000000,0.002188000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1013.000000000000000,181.000000000000000,121.000000000000000,0.137216294671414,0.165518456926789,121.000000000000000,0.244967327033756 +0.000000000000000,0.000022000000000,0.000167000000000,0.000085000000000,0.001236000000000,0.000710000000000,0.002252000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,170.000000000000000,121.000000000000000,0.162107693844438,0.225222383429965,121.000000000000000,0.333329153190160 +0.000000000000000,0.000014000000000,0.000108000000000,0.000083000000000,0.001153000000000,0.000703000000000,0.002206000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1073.000000000000000,176.000000000000000,121.000000000000000,0.142487698690500,0.215619270887844,121.000000000000000,0.319116532088679 +0.000000000000000,0.000016000000000,0.000149000000000,0.000080000000000,0.001141000000000,0.000754000000000,0.002190000000000,0.000000000000000,109.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,919.000000000000000,194.000000000000000,121.000000000000000,0.144721479076393,0.144784816827571,121.000000000000000,0.214281516154081 +0.000000000000000,0.000013000000000,0.000152000000000,0.000093000000000,0.001294000000000,0.000832000000000,0.002420000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,915.000000000000000,177.000000000000000,121.000000000000000,0.149099082449318,0.191998203412644,121.000000000000000,0.284157323986802 +0.000000000000000,0.000018000000000,0.000087000000000,0.000081000000000,0.001097000000000,0.000702000000000,0.002015000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,933.000000000000000,176.000000000000000,121.000000000000000,0.155861769273800,0.170207046079660,121.000000000000000,0.251906426263653 +0.000000000000000,0.000014000000000,0.000089000000000,0.000078000000000,0.001146000000000,0.000908000000000,0.002268000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,942.000000000000000,168.000000000000000,121.000000000000000,0.138592736529167,0.162826237027208,121.000000000000000,0.240982837817279 +0.000000000000000,0.000020000000000,0.000091000000000,0.000094000000000,0.001136000000000,0.000619000000000,0.001992000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,952.000000000000000,158.000000000000000,121.000000000000000,0.145657951253513,0.188004859202689,121.000000000000000,0.278247194172679 +0.000000000000000,0.000020000000000,0.000125000000000,0.000078000000000,0.001053000000000,0.000766000000000,0.002073000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,981.000000000000000,173.000000000000000,121.000000000000000,0.128806331282994,0.198803320775784,121.000000000000000,0.294228921915590 +0.000000000000000,0.000019000000000,0.000167000000000,0.000089000000000,0.001255000000000,0.000878000000000,0.002445000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1004.000000000000000,174.000000000000000,121.000000000000000,0.118066645939065,0.158172695543332,121.000000000000000,0.234095596462448 +0.000000000000000,0.000014000000000,0.000107000000000,0.000083000000000,0.001134000000000,0.000719000000000,0.002090000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1033.000000000000000,174.000000000000000,121.000000000000000,0.120270585655071,0.185382011446256,121.000000000000000,0.274365384559707 +0.000000000000000,0.000023000000000,0.000149000000000,0.000076000000000,0.001048000000000,0.000778000000000,0.002104000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1055.000000000000000,177.000000000000000,121.000000000000000,0.111655902944065,0.127479790231990,121.000000000000000,0.188670081746738 +0.000000000000000,0.000024000000000,0.000165000000000,0.000093000000000,0.001273000000000,0.000666000000000,0.002422000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1068.000000000000000,161.000000000000000,121.000000000000000,0.137252105053442,0.201665031989628,121.000000000000000,0.298464234431299 +0.000000000000000,0.000016000000000,0.000151000000000,0.000085000000000,0.001226000000000,0.000594000000000,0.002131000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,917.000000000000000,199.000000000000000,121.000000000000000,0.109849180876551,0.169849754533253,121.000000000000000,0.251377637677945 +0.000000000000000,0.000019000000000,0.000166000000000,0.000083000000000,0.001090000000000,0.000732000000000,0.002128000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,914.000000000000000,161.000000000000000,121.000000000000000,0.094619378225366,0.127736587063336,121.000000000000000,0.189050145383732 +0.000000000000000,0.000019000000000,0.000109000000000,0.000094000000000,0.001174000000000,0.000652000000000,0.002081000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,924.000000000000000,172.000000000000000,121.000000000000000,0.095987819870883,0.183985249071388,121.000000000000000,0.272298170952257 +0.000000000000000,0.000013000000000,0.000151000000000,0.000081000000000,0.001173000000000,0.000806000000000,0.002255000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,931.000000000000000,188.000000000000000,121.000000000000000,0.103214005987484,0.160102278671277,121.000000000000000,0.236951368196443 +0.000000000000000,0.000016000000000,0.000166000000000,0.000090000000000,0.001244000000000,0.000853000000000,0.002405000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,933.000000000000000,176.000000000000000,121.000000000000000,0.107624598314130,0.132136716401229,121.000000000000000,0.195562352203489 +0.000000000000000,0.000019000000000,0.000160000000000,0.000083000000000,0.001074000000000,0.000663000000000,0.002029000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,968.000000000000000,161.000000000000000,121.000000000000000,0.105311906661098,0.145668800777700,121.000000000000000,0.215589815537253 +0.000000000000000,0.000016000000000,0.000109000000000,0.000079000000000,0.001079000000000,0.000825000000000,0.002137000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,999.000000000000000,164.000000000000000,121.000000000000000,0.115404334777576,0.144024386113689,121.000000000000000,0.213156084014562 +0.000000000000000,0.000016000000000,0.000093000000000,0.000099000000000,0.001239000000000,0.000811000000000,0.002291000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1014.000000000000000,171.000000000000000,121.000000000000000,0.102620214117170,0.192238051746968,120.000000000000000,0.284512317929807 +0.000000000000000,0.000019000000000,0.000086000000000,0.000082000000000,0.001037000000000,0.000718000000000,0.001972000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1040.000000000000000,170.000000000000000,121.000000000000000,0.105335250265535,0.144890464932436,121.000000000000000,0.214437873207215 +0.000000000000000,0.000017000000000,0.000109000000000,0.000079000000000,0.001050000000000,0.000705000000000,0.001992000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1061.000000000000000,160.000000000000000,121.000000000000000,0.102004773526380,0.101331023468228,121.000000000000000,0.149969916793428 +0.000000000000000,0.000019000000000,0.000120000000000,0.000096000000000,0.001236000000000,0.000783000000000,0.002289000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1076.000000000000000,160.000000000000000,121.000000000000000,0.101321819984142,0.125092002453206,121.000000000000000,0.185136164681599 +0.000000000000000,0.000017000000000,0.000151000000000,0.000083000000000,0.001093000000000,0.000805000000000,0.002181000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1087.000000000000000,166.000000000000000,121.000000000000000,0.100949350996349,0.133208193438679,121.000000000000000,0.197148136707625 +0.000000000000000,0.000016000000000,0.000166000000000,0.000086000000000,0.001225000000000,0.000614000000000,0.002142000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1094.000000000000000,173.000000000000000,121.000000000000000,0.113902102274736,0.263501176586062,121.000000000000000,0.389981758862282 +0.000000000000000,0.000017000000000,0.000110000000000,0.000085000000000,0.001057000000000,0.000701000000000,0.002002000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1103.000000000000000,147.000000000000000,121.000000000000000,0.112950870334457,0.159164000744430,121.000000000000000,0.235562729541910 +0.000000000000000,0.000015000000000,0.000148000000000,0.000081000000000,0.001005000000000,0.000710000000000,0.002002000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1107.000000000000000,160.000000000000000,121.000000000000000,0.096261721291800,0.169941815822129,121.000000000000000,0.251513903595272 +0.000000000000000,0.000014000000000,0.000111000000000,0.000087000000000,0.001226000000000,0.000704000000000,0.002175000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1134.000000000000000,179.000000000000000,121.000000000000000,0.100695432310273,0.149404926005425,121.000000000000000,0.221119300461396 +0.000000000000000,0.000017000000000,0.000159000000000,0.000084000000000,0.001069000000000,0.000609000000000,0.001969000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1163.000000000000000,157.000000000000000,121.000000000000000,0.104264909242810,0.168733357468614,121.000000000000000,0.249725362886627 +0.000000000000000,0.000016000000000,0.000084000000000,0.000079000000000,0.000994000000000,0.000786000000000,0.001989000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1186.000000000000000,161.000000000000000,121.000000000000000,0.098764835183793,0.142076743187060,121.000000000000000,0.210273574643228 +0.000000000000000,0.000014000000000,0.000113000000000,0.000090000000000,0.001119000000000,0.000653000000000,0.002020000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1204.000000000000000,154.000000000000000,121.000000000000000,0.099700583140545,0.115489183389192,121.000000000000000,0.170923985837824 +0.000000000000000,0.000015000000000,0.000088000000000,0.000083000000000,0.001096000000000,0.000758000000000,0.002070000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1224.000000000000000,165.000000000000000,121.000000000000000,0.113531975395493,0.159479019440782,121.000000000000000,0.236028944980121 +0.000000000000000,0.000016000000000,0.000106000000000,0.000080000000000,0.000950000000000,0.000689000000000,0.001870000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1236.000000000000000,152.000000000000000,121.000000000000000,0.101278477365169,0.121853029810147,121.000000000000000,0.180342482857587 +0.000000000000000,0.000026000000000,0.000157000000000,0.000086000000000,0.001250000000000,0.000748000000000,0.002309000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1243.000000000000000,177.000000000000000,121.000000000000000,0.113386397852020,0.206475855003173,121.000000000000000,0.305584280242809 +0.000000000000000,0.000018000000000,0.000087000000000,0.000081000000000,0.001080000000000,0.000613000000000,0.001908000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1252.000000000000000,162.000000000000000,121.000000000000000,0.103012888489708,0.192649617277085,121.000000000000000,0.285121445786875 +0.000000000000000,0.000014000000000,0.000084000000000,0.000078000000000,0.001104000000000,0.000752000000000,0.002063000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1267.000000000000000,181.000000000000000,121.000000000000000,0.119108801565499,0.146565581346541,121.000000000000000,0.216917068822130 +0.000000000000000,0.000017000000000,0.000169000000000,0.000087000000000,0.001262000000000,0.000745000000000,0.002313000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1272.000000000000000,162.000000000000000,121.000000000000000,0.113261864886997,0.130198323725397,121.000000000000000,0.192693514913252 +0.000000000000000,0.000013000000000,0.000147000000000,0.000081000000000,0.001101000000000,0.000691000000000,0.002065000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1269.000000000000000,173.000000000000000,121.000000000000000,0.115292532476552,0.143763553384774,121.000000000000000,0.212770056216498 +0.000000000000000,0.000017000000000,0.000089000000000,0.000077000000000,0.001052000000000,0.000711000000000,0.001978000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1264.000000000000000,159.000000000000000,121.000000000000000,0.101382577834875,0.107355247718934,121.000000000000000,0.158885781611837 +0.000000000000000,0.000016000000000,0.000118000000000,0.000092000000000,0.001316000000000,0.000678000000000,0.002256000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1260.000000000000000,177.000000000000000,121.000000000000000,0.124156248079858,0.184101498216806,121.000000000000000,0.272470221836003 +0.000000000000000,0.000018000000000,0.000151000000000,0.000083000000000,0.001038000000000,0.000700000000000,0.002018000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1259.000000000000000,160.000000000000000,121.000000000000000,0.124874729225317,0.136317718156052,121.000000000000000,0.201750219857265 +0.000000000000000,0.000019000000000,0.000118000000000,0.000088000000000,0.001213000000000,0.000732000000000,0.002204000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1256.000000000000000,175.000000000000000,121.000000000000000,0.137395115258524,0.272990416298521,121.000000000000000,0.404025816597931 +0.000000000000000,0.000033000000000,0.000166000000000,0.000098000000000,0.001332000000000,0.000676000000000,0.002341000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1256.000000000000000,175.000000000000000,121.000000000000000,0.125440559596022,0.192594450198696,121.000000000000000,0.285039792378329 +0.000000000000000,0.000011000000000,0.000147000000000,0.000080000000000,0.001052000000000,0.000650000000000,0.001970000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1254.000000000000000,161.000000000000000,121.000000000000000,0.135853494715468,0.174263471494220,121.000000000000000,0.257909935633510 +0.000000000000000,0.000016000000000,0.000118000000000,0.000078000000000,0.001158000000000,0.000816000000000,0.002217000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1253.000000000000000,167.000000000000000,121.000000000000000,0.122720689566236,0.207186929273245,121.000000000000000,0.306636651409222 +0.000000000000000,0.000015000000000,0.000117000000000,0.000091000000000,0.001177000000000,0.000833000000000,0.002267000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1249.000000000000000,162.000000000000000,121.000000000000000,0.131197397185608,0.147375515585527,121.000000000000000,0.218115764109708 +0.000000000000000,0.000011000000000,0.000150000000000,0.000081000000000,0.001038000000000,0.000708000000000,0.002171000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1238.000000000000000,166.000000000000000,121.000000000000000,0.137378655081558,0.217187593785681,121.000000000000000,0.321437652163372 +0.000000000000000,0.000014000000000,0.000152000000000,0.000092000000000,0.001138000000000,0.000700000000000,0.002154000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1068.000000000000000,186.000000000000000,121.000000000000000,0.145478356636836,0.211190875078835,121.000000000000000,0.312562500325826 +0.000000000000000,0.000014000000000,0.000151000000000,0.000087000000000,0.001380000000000,0.000695000000000,0.002361000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1066.000000000000000,208.000000000000000,121.000000000000000,0.145910261187635,0.270725437624101,121.000000000000000,0.400673629542342 +0.000000000000000,0.000010000000000,0.000106000000000,0.000080000000000,0.001226000000000,0.000670000000000,0.002123000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1063.000000000000000,202.000000000000000,121.000000000000000,0.142580547861068,0.222707058106822,121.000000000000000,0.329606455264036 +0.000000000000000,0.000016000000000,0.000091000000000,0.000082000000000,0.001339000000000,0.000780000000000,0.002343000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1056.000000000000000,206.000000000000000,121.000000000000000,0.127026409458953,0.138078812827686,121.000000000000000,0.204356634060426 +0.000000000000000,0.000015000000000,0.000112000000000,0.000084000000000,0.001327000000000,0.000760000000000,0.002333000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1046.000000000000000,203.000000000000000,121.000000000000000,0.143390011522010,0.189299220864586,121.000000000000000,0.280162852382094 +0.000000000000000,0.000012000000000,0.000153000000000,0.000080000000000,0.001259000000000,0.000815000000000,0.002350000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1041.000000000000000,190.000000000000000,121.000000000000000,0.146470888134392,0.170045702350971,121.000000000000000,0.251667632374036 +0.000000000000000,0.000016000000000,0.000109000000000,0.000082000000000,0.001303000000000,0.000864000000000,0.002410000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1035.000000000000000,192.000000000000000,121.000000000000000,0.145288024491270,0.152085543829851,120.000000000000000,0.225086604806994 +0.000000000000000,0.000015000000000,0.000130000000000,0.000082000000000,0.001210000000000,0.000564000000000,0.002031000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1033.000000000000000,195.000000000000000,121.000000000000000,0.150132403510209,0.284875350032339,121.000000000000000,0.421615517545908 +0.000000000000000,0.000017000000000,0.000142000000000,0.000087000000000,0.001179000000000,0.000822000000000,0.002279000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1032.000000000000000,177.000000000000000,121.000000000000000,0.150560599418679,0.158144787063228,121.000000000000000,0.234054276956730 +0.000000000000000,0.000014000000000,0.000166000000000,0.000090000000000,0.001346000000000,0.000786000000000,0.002438000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1025.000000000000000,195.000000000000000,121.000000000000000,0.143981650642650,0.191284534828251,121.000000000000000,0.283101111496310 +0.000000000000000,0.000011000000000,0.000086000000000,0.000079000000000,0.001157000000000,0.000713000000000,0.002195000000000,1.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1022.000000000000000,190.000000000000000,121.000000000000000,0.154353905338326,0.194713119296172,121.000000000000000,0.288175424788969 +0.000000000000000,0.000015000000000,0.000156000000000,0.000097000000000,0.001181000000000,0.000713000000000,0.002220000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,838.000000000000000,198.000000000000000,121.000000000000000,0.139070972107019,0.141121163279108,121.000000000000000,0.208859322949524 +0.000000000000000,0.000015000000000,0.000151000000000,0.000089000000000,0.001225000000000,0.000800000000000,0.002315000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,835.000000000000000,186.000000000000000,121.000000000000000,0.138520459895391,0.192364562878898,121.000000000000000,0.284699557206785 +0.000000000000000,0.000016000000000,0.000166000000000,0.000083000000000,0.001375000000000,0.000800000000000,0.002476000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,831.000000000000000 \ No newline at end of file diff --git a/svo/test/data/.gitignore b/svo/test/data/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/svo/test/data/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/svo/test/results/.gitignore b/svo/test/results/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/svo/test/results/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/svo/test/test_depth_filter.cpp b/svo/test/test_depth_filter.cpp new file mode 100644 index 0000000..09d0034 --- /dev/null +++ b/svo/test/test_depth_filter.cpp @@ -0,0 +1,200 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +struct ConvergedSeed { + int x_, y_; + double depth_, error_; + ConvergedSeed(int x, int y, double depth, double error) : + x_(x), y_(y), depth_(depth), error_(error) + {} +}; + +/// DepthFilter Test-Fixture +class DepthFilterTest { + public: + DepthFilterTest(); + virtual ~DepthFilterTest(); + void depthFilterCb(const svo::Seed& seed, const Eigen::Vector3d& xyz_world); + void testReconstruction(std::string dataset_dir, std::string experiment_name); + + std::list results_; + std::vector errors_; + double error_sum_; + size_t n_converged_seeds_; + vk::PinholeCamera* cam_; + svo::DepthFilter* depth_filter_; + svo::FramePtr frame_ref_; + svo::FramePtr frame_cur_; + cv::Mat depth_ref_; +}; + +DepthFilterTest::DepthFilterTest() : + n_converged_seeds_(0), + cam_(new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240)), + depth_filter_(NULL) +{ + errors_.reserve(1000); +} + +DepthFilterTest::~DepthFilterTest() +{ + delete cam_; +} + +void DepthFilterTest::depthFilterCb( + const svo::Seed& seed, + const Eigen::Vector3d& xyz_world) +{ + double depth = (frame_ref_->pos() - xyz_world).norm(); + double error = fabs(depth - depth_ref_.at(seed.ftr->px[1], seed.ftr->px[0])); + results_.push_back(ConvergedSeed(seed.ftr->px[0], seed.ftr->px[1], depth, error)); + errors_.push_back(error); + delete seed.ftr; + ++n_converged_seeds_; +} + +void DepthFilterTest::testReconstruction( + std::string dataset_dir, + std::string experiment_name) +{ + vk::FileReader sequence_file_reader(dataset_dir+"/trajectory.txt"); + std::vector sequence; + sequence_file_reader.skipComments(); + if(!sequence_file_reader.next()) + std::runtime_error("Failed to open sequence file"); + sequence_file_reader.readAllEntries(sequence); + std::cout << "RUN EXPERIMENT: read " << sequence.size() << " dataset entries." << std::endl; + std::vector::iterator it = sequence.begin(); + vk::Timer t; + std::list n_converged_per_iteration; + + svo::feature_detection::DetectorPtr feature_detector(new svo::feature_detection::FastDetector()); + svo::DepthFilter::callback_t depth_filter_cb = boost::bind(&DepthFilterTest::depthFilterCb, this, _1, _2); + depth_filter_ = new svo::DepthFilter(feature_detector, depth_filter_cb); + + for(int i=0; it != sequence.end() && i<50; ++it, ++i) + { + std::string img_name(dataset_dir+"/img/" + (*it).image_name_ + "_0.png"); + if(i==0) + printf("reading image: '%s'\n", img_name.c_str()); + cv::Mat img(cv::imread(img_name, 0)); + assert(!img.empty()); + + Sophus::SE3 T_w_f = Sophus::SE3(it->q_.toRotationMatrix(), it->t_); + if(i == 0) + { + // create reference frame and load ground truth depthmap + frame_ref_.reset(new svo::Frame(cam_, img)); + frame_ref_->T_f_w_ = T_w_f.inverse(); + depth_filter_->addKeyframe(frame_ref_, 3, 1); + vk::blender_utils::loadBlenderDepthmap(dataset_dir+"/depth/" + (*it).image_name_ + "_0.depth", *cam_, depth_ref_); + continue; + } + + n_converged_seeds_=0; + frame_cur_ = svo::FramePtr(new svo::Frame(cam_, img)); + frame_cur_->T_f_w_ = T_w_f.inverse(); + depth_filter_->addFrame(frame_cur_); + n_converged_per_iteration.push_back(n_converged_seeds_); + } + printf("Experiment '%s' took %f ms\n", experiment_name.c_str(), t.stop()*1000); + + // compute mean, median and variance of error in converged area + { + printf("# converged: \t %zu (ref: 349)\n", errors_.size()); + double sum_error = 0; + std::for_each(errors_.begin(), errors_.end(), [&](double& e){sum_error+=e;}); + printf("mean error: \t %f cm (ref: 1.510507)\n", sum_error*100/errors_.size()); + std::vector::iterator it = errors_.begin()+0.5*errors_.size(); + std::nth_element(errors_.begin(), it, errors_.end()); + printf("50-percentile: \t %f cm (ref: 0.809308)\n", *it*100); + it = errors_.begin()+0.8*errors_.size(); + std::nth_element(errors_.begin(), it, errors_.end()); + printf("80-percentile: \t %f cm (ref: 1.580725)\n", *it*100); + it = errors_.begin()+0.95*errors_.size(); + std::nth_element(errors_.begin(), it, errors_.end()); + printf("95-percentile: \t %f cm (ref: 2.557531)\n", *it*100); + } + + // trace error + std::string trace_name(std::string(TEST_TRACE_DIR) + "/depth_filter_" + experiment_name + ".txt"); + std::ofstream ofs(trace_name.c_str()); + for(std::list::iterator i=results_.begin(); i!=results_.end(); ++i) + ofs << i->x_ << ", " << i->y_ << ", " << fabs(i->error_) << std::endl; + ofs.close(); + + // trace convergence rate + trace_name = std::string(TEST_TRACE_DIR) + "/depth_filter_" + experiment_name + "_convergence.txt"; + ofs.open(trace_name.c_str()); + for(std::list::iterator it=n_converged_per_iteration.begin(); + it!=n_converged_per_iteration.end(); ++it) + ofs << *it << std::endl; + ofs.close(); + + // write ply file for pointcloud visualization in Meshlab + trace_name = std::string(TEST_TRACE_DIR) + "/depth_filter_" + experiment_name + ".ply"; + ofs.open(trace_name.c_str()); + ofs << "ply" << std::endl + << "format ascii 1.0" << std::endl + << "element vertex " << results_.size() << std::endl + << "property float x" << std::endl + << "property float y" << std::endl + << "property float z" << std::endl + << "property uchar blue" << std::endl + << "property uchar green" << std::endl + << "property uchar red" << std::endl + << "end_header" << std::endl; + + for(std::list::iterator i=results_.begin(); i!=results_.end(); ++i) + { + cv::Vec3b c = frame_ref_->img_pyr_[0].at(i->y_, i->x_); + Eigen::Vector3d p = cam_->cam2world(i->x_, i->y_)*i->depth_; + ofs << p[0] << " " << p[1] << " " << p[2] << " " + << (int) c[0] << " " << (int) c[1] << " " << (int) c[2] << std::endl; + } +} + +} // namespace + +int main(int argc, char** argv) +{ + DepthFilterTest test; + std::string dataset_dir(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1"); + std::string experiment_name("synth_fast_2d"); + test.testReconstruction(dataset_dir, experiment_name); + return 0; +} diff --git a/svo/test/test_feature_alignment.cpp b/svo/test/test_feature_alignment.cpp new file mode 100644 index 0000000..04bddf7 --- /dev/null +++ b/svo/test/test_feature_alignment.cpp @@ -0,0 +1,122 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#if __ARM_NEON__ +#include +#endif + +using namespace Eigen; + +void generateRefPatchNoWarpInterpolate(const cv::Mat& img, const Vector2d& px, + cv::Mat& ref_patch_with_border) +{ + // compute interpolation weights + const int u_r = floor(px[0]); + const int v_r = floor(px[1]); + const float subpix_u = px[0]-u_r; + const float subpix_v = px[1]-v_r; + const float wTL = (1.0-subpix_u)*(1.0-subpix_v); + const float wTR = subpix_u * (1.0-subpix_v); + const float wBL = (1.0-subpix_u)*subpix_v; + const float wBR = subpix_u * subpix_v; + + // loop through search_patch, interpolate + ref_patch_with_border = cv::Mat(10, 10, CV_8UC1); + uint8_t* patch_ptr = ref_patch_with_border.data; + const int stride = img.step.p[0]; + for(int y=0; y<10; ++y) + { + uint8_t* img_ptr = (uint8_t*) img.data + (v_r+y-4-1)*stride + u_r-4-1; + for(int x=0; x<10; ++x, ++patch_ptr, ++img_ptr) + *patch_ptr = wTL*img_ptr[0] + wTR*img_ptr[1] + wBL*img_ptr[stride] + wBR*img_ptr[stride+1]; + } +} + +int main(int argc, char **argv) +{ + std::string img_name(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1/img/frame_000001_0.png"); + printf("Loading image '%s'\n", img_name.c_str()); + cv::Mat img(cv::imread(img_name, 0)); + assert(img.type() == CV_8UC1); + + // TODO: test on corner/gradient features! + Vector2d px_true(130.2,120.3); + + // create reference patch with border + cv::Mat ref_patch_with_border; + generateRefPatchNoWarpInterpolate(img, px_true, ref_patch_with_border); + + // create reference patch, aligned + uint8_t* ref_patch = vk::aligned_mem::aligned_alloc(64, 16); + uint8_t* ref_patch_ptr = ref_patch; + for(int y=1; y<9; ++y) + { + uint8_t* ref_patch_border_ptr = ref_patch_with_border.data + y*10 + 1; + for(int x=0; x<8; ++x, ++ref_patch_border_ptr, ++ref_patch_ptr) + *ref_patch_ptr = *ref_patch_border_ptr; + } + + Vector2d px_est, px_error(-1.1, -0.8); + double h_inv; + vk::Timer t; + for(int i=0; i<1000; ++i) + { + px_est = px_true-px_error; + Vector2f dir = px_error.normalized().cast(); + svo::feature_alignment::align1D(img, dir, ref_patch_with_border.data, ref_patch, 3, px_est, h_inv); + } + Vector2d e = px_est-px_true; + printf("1000Xalign 1D took %fms, error = %fpx \t (ref i7-W520: 1.637000ms, Odroid-U2: ?, 0.008788px) \n", t.stop()*1000, e.norm()); + + t.start(); + for(int i=0; i<1000; ++i) + { + px_est = px_true-px_error; + svo::feature_alignment::align2D(img, ref_patch_with_border.data, ref_patch, 3, px_est, true); + } + e = px_est-px_true; + printf("1000Xalign 2D took %fms, error = %fpx \t (ref i7-W520: 2.147000ms, Odroid-U2: ?, 0.009632px)\n", t.stop()*1000, e.norm()); + +#ifdef __SSE2__ + // Note, this KLT implementation is not invariant to illuminatino changes! + t.start(); + for(int i=0; i<1000; ++i) + { + px_est = px_true-px_error; + svo::feature_alignment::align2D_SSE2(img, ref_patch_with_border.data, ref_patch, 3, px_est); + } + e = px_est-px_true; + printf("1000Xalign 2D SSE2 %fms, error = %fpx \t (ref i7-W520: 0.548000ms, 0.023032px)\n", t.stop()*1000, e.norm()); +#endif + +#ifdef __ARM_NEON__ + t.start(); + for(int i=0; i<1000; ++i) + { + px_est = px_true-px_error; + svo::feature_alignment::align2D_NEON(img, ref_patch_with_border.data, ref_patch, 3, px_est); + } + e = px_est-px_true; + printf("1000Xalign 2D NEON %fms, error = %fpx \t (ref Odroid-U2: ?, ?)\n", t.stop()*1000, e.norm()); +#endif + + return 0; +} diff --git a/svo/test/test_feature_detection.cpp b/svo/test/test_feature_detection.cpp new file mode 100644 index 0000000..00e21a2 --- /dev/null +++ b/svo/test/test_feature_detection.cpp @@ -0,0 +1,80 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +using namespace Eigen; +using namespace std; + +void testCornerDetector() +{ + std::string img_name(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1/img/frame_000001_0.png"); + printf("Loading image '%s'\n", img_name.c_str()); + cv::Mat img(cv::imread(img_name, 0)); + assert(img.type() == CV_8UC1 && !img.empty()); + + svo::ImgPyr img_pyr; + svo::frame_utils::createImgPyramid( + img, max(svo::Config::nPyrLevels(), svo::Config::kltMaxLevel()+1), img_pyr); + svo::Features fts; + + // Corner detection + vk::Timer t; + svo::feature_detection::Corners corners; + svo::feature_detection::FastDetector fast_detector; + for(int i=0; i<100; ++i) + { + fast_detector.detect(img_pyr, fts, svo::Config::gridSize(), svo::Config::nPyrLevels(), + svo::Config::triangMinCornerScore(), &corners); + } + printf("Fast corner detection took %f ms, %zu corners detected (ref i7-W520: 8.06878ms, 416)\n", t.stop()*10, corners.size()); + + if(false) + { + cv::Mat img_rgb = cv::Mat(img.size(), CV_8UC3); + cv::cvtColor(img, img_rgb, CV_GRAY2RGB); + for(svo::feature_detection::Corners::iterator it=corners.begin(); it!=corners.end(); ++it) + { + // we must check again if the score is above the threshold because the Corners + // vector is initialized with dummy corners + if(it->score > svo::Config::triangMinCornerScore()) + { + cv::circle(img_rgb, cv::Point2f(it->x, it->y), 4*(it->level+1), cv::Scalar(0,255,0), 1); + } + } + cv::imshow("ref_img", img_rgb); + cv::waitKey(0); + } +} + +} // namespace + + +int main(int argc, char **argv) +{ + testCornerDetector(); + return 0; +} diff --git a/svo/test/test_matcher.cpp b/svo/test/test_matcher.cpp new file mode 100644 index 0000000..3138d48 --- /dev/null +++ b/svo/test/test_matcher.cpp @@ -0,0 +1,195 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +/// Matcher Test-Fixture +class MatcherTest { + public: + MatcherTest() + { + cam_ = new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240); + + // load images + std::string dataset_dir(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1"); + std::string img_name(dataset_dir+"/img/frame_000071_0.png"); + printf("Loading image '%s'\n", img_name.c_str()); + cv::Mat img_ref(cv::imread(img_name, 0)); + img_name = std::string(dataset_dir+"/img/frame_000097_0.png"); + printf("Loading image '%s'\n", img_name.c_str()); + cv::Mat img_cur(cv::imread(img_name, 0)); + assert(!img_ref.empty() && !img_cur.empty()); + + // create frame + frame_ref_ = new svo::Frame(cam_, img_ref, 1.0); + frame_cur_ = new svo::Frame(cam_, img_cur, 2.0); + ref_ftr_ = new svo::Feature(frame_ref_, Eigen::Vector2d(300, 260), 0); + + // set poses + Eigen::Vector3d t_w_ref(1.0054399967193604, 1.75655996799469, 4.610799789428711); + Eigen::Vector3d t_w_cur(-0.046640001237392426, 2.163439989089966, 4.6279802322387695); + Eigen::Quaterniond q_w_ref(0.015279541723430157, 0.7095794081687927, 0.7044594287872314, 0.0006494877743534744); + Eigen::Quaterniond q_w_cur(0.004395846277475357, -0.7776520252227783, -0.6286740899085999, -0.0026246386114507914); + frame_ref_->T_f_w_ = Sophus::SE3(q_w_ref.toRotationMatrix(), t_w_ref).inverse(); + frame_cur_->T_f_w_ = Sophus::SE3(q_w_cur.toRotationMatrix(), t_w_cur).inverse(); + + // load ground-truth depth + vk::blender_utils::loadBlenderDepthmap(dataset_dir+"/depth/frame_000071_0.depth", *cam_, depth_ref_); + } + + virtual ~MatcherTest() + { + delete cam_; + delete frame_ref_; + delete frame_cur_; + delete ref_ftr_; + } + + // Individual tests + void testEpipolarSearchFullImg(); + void testWarpAffine(); + + // Objects declared here can be used by all tests + vk::PinholeCamera* cam_; + svo::Frame* frame_ref_; + svo::Frame* frame_cur_; + svo::Feature* ref_ftr_; + cv::Mat depth_ref_; +}; + +void MatcherTest::testEpipolarSearchFullImg() +{ + cv::Mat depthmap(frame_ref_->cam_->height(), frame_ref_->cam_->width(), CV_32FC1, cv::Scalar(0)); + cv::Mat error_map(depthmap.rows, depthmap.cols, CV_32FC1, cv::Scalar(0)); + cv::Mat mask(depthmap.rows, depthmap.cols, CV_8UC1, cv::Scalar(1)); + double depth_range = 0.8; + size_t n_converged = 0; + double sum_error = 0; + std::vector errors; errors.reserve(depthmap.cols*depthmap.rows); + for(int y=4; y(y, x); + double depth_estimate, h_inv; + int res = svo::matcher::findEpipolarMatchDirect( + *frame_ref_, *frame_cur_, ftr, + depth_gt, fmax(depth_gt-depth_range,0.0), depth_gt+depth_range, false, depth_estimate, h_inv); + if(res) + { + depthmap.at(y,x) = depth_estimate; + error_map.at(y,x) = fabsf(depth_estimate-depth_gt); + ++n_converged; + sum_error += error_map.at(y,x); + errors.push_back(error_map.at(y,x)); + } + else + mask.at(y,x) = 0; + } + } + + // compute mean, median and variance of error in converged area + printf("n converged: \t %zu (ref: 194472)\n", n_converged); + printf("mean error: \t %f (ref: 1.0848)\n", sum_error*100/n_converged); + std::vector::iterator it = errors.begin()+0.5*errors.size(); + std::nth_element(errors.begin(), it, errors.end()); + printf("50-percentile: \t %f (ref: 0.1343)\n", *it*100); + it = errors.begin()+0.8*errors.size(); + std::nth_element(errors.begin(), it, errors.end()); + printf("80-percentile: \t %f (ref: 0.3151)\n", *it*100); + it = errors.begin()+0.95*errors.size(); + std::nth_element(errors.begin(), it, errors.end()); + printf("95-percentile: \t %f (ref: 1.3753)\n", *it*100); + + // save results to file + std::ofstream output_stream; + std::string output_filename(std::string(TEST_TRACE_DIR) + "/depthmap.bin"); + output_stream.open(output_filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + output_stream.write((const char *)depthmap.data, depthmap.rows*depthmap.cols*sizeof(float)); + output_stream.close(); + + output_filename.assign(std::string(TEST_TRACE_DIR) + "/depthmap_error.bin"); + output_stream.open(output_filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + output_stream.write((const char *)error_map.data, error_map.rows*error_map.cols*sizeof(float)); + output_stream.close(); + + output_filename.assign(std::string(TEST_TRACE_DIR) + "/depthmap_mask.bin"); + output_stream.open(output_filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + output_stream.write((const char *)mask.data, mask.rows*mask.cols*sizeof(uint8_t)); + output_stream.close(); +} + +void MatcherTest::testWarpAffine() +{ + const int halfpatch_size = 15; + const int patch_size=halfpatch_size*2; + svo::matcher::PatchData md(patch_size); + double depth = 1.0; + + Sophus::SE3 T_cur_ref(frame_cur_->T_f_w_*frame_ref_->T_f_w_.inverse()); + Eigen::Vector2d px_cur(frame_cur_->cam_->world2cam(T_cur_ref*(ref_ftr_->f*depth))); + + // compute reference patch + cv::Mat ref_patch(patch_size, patch_size, CV_8U, md.patch_with_border); + + Eigen::Matrix2d A_cur_ref; + svo::matcher::warp::getWarpMatrixAffine( + *cam_, *cam_, ref_ftr_->px, ref_ftr_->f, 1.0, T_cur_ref, ref_ftr_->level, A_cur_ref); + int level_cur = svo::matcher::warp::getBestSearchLevel(A_cur_ref, svo::Config::nPyrLevels()-1); + svo::matcher::warp::warpAffine( + A_cur_ref, ref_ftr_->frame->img_pyr_[ref_ftr_->level], ref_ftr_->px, ref_ftr_->level, level_cur, md); + + // copy current patch + Eigen::Vector2i pxi(px_cur[0]/(1<img_pyr_.at(level_cur)(cv::Range(pxi[1]-halfpatch_size, + pxi[1]+halfpatch_size), + cv::Range(pxi[0]-halfpatch_size, + pxi[0]+halfpatch_size)).copyTo(cur_patch); + + // display results + cv::circle(frame_cur_->img_pyr_[level_cur], + cv::Point2f(pxi[0], pxi[1]), + patch_size, cv::Scalar(255), 2); + cv::circle(frame_ref_->img_pyr_[ref_ftr_->level], + cv::Point2f(ref_ftr_->px[0]/(1<level), ref_ftr_->px[1]/(1<level)), + patch_size, cv::Scalar(255), 2); + cv::imshow("cur_patch", cur_patch); + cv::imshow("ref_patch", ref_patch); + cv::imshow("ref_img", frame_ref_->img_pyr_[ref_ftr_->level]); + cv::imshow("cur_img", frame_cur_->img_pyr_[level_cur]); + cv::waitKey(0); +} + +} // namespace + +int main(int argc, char** argv) +{ + MatcherTest test; + test.testEpipolarSearchFullImg(); +// test.testWarpAffine(); + return 0; +} diff --git a/svo/test/test_pipeline.cpp b/svo/test/test_pipeline.cpp new file mode 100644 index 0000000..d328bf1 --- /dev/null +++ b/svo/test/test_pipeline.cpp @@ -0,0 +1,94 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +class BenchmarkNode +{ + vk::AbstractCamera* cam_; + svo::FrameHandlerMono* vo_; + +public: + BenchmarkNode(); + ~BenchmarkNode(); + void runFromFolder(); +}; + +BenchmarkNode::BenchmarkNode() +{ + Config::traceName() = "benchmark"; + Config::traceDir() = std::string(TEST_TRACE_DIR)+"/.."; + cam_ = new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240); + vo_ = new svo::FrameHandlerMono(cam_); + vo_->start(); +} + +BenchmarkNode::~BenchmarkNode() +{ + delete vo_; + delete cam_; +} + +void BenchmarkNode::runFromFolder() +{ + for(int img_id = 1; img_id < 310; ++img_id) + { + // load image + std::stringstream ss; + ss << std::string(TEST_DATA_DIR) << "/flying_room_1_rig_1/img/frame_" << std::setw( 6 ) << std::setfill( '0' ) << img_id << "_0.png"; + if(img_id == 1) + std::cout << "reading image " << ss.str() << std::endl; + cv::Mat img(cv::imread(ss.str().c_str(), 0)); + assert(!img.empty()); + + // process frame + vo_->addImage(img, 0.01*img_id); + + // display tracking quality + if(vo_->lastFrame() != NULL) + std::cout << "Frame-Id: " << vo_->lastFrame()->id_ << " \t" + << "#Features: " << vo_->lastNumObservations() << " \t" + << "Proc. Time: " << vo_->lastProcessingTime()*1000 << "ms \n"; + } +} + +} // namespace svo + +int main(int argc, char** argv) +{ + { + svo::BenchmarkNode benchmark; + benchmark.runFromFolder(); + } + printf("BenchmarkNode finished.\n"); + return 0; +} + diff --git a/svo/test/test_pose_optimizer.cpp b/svo/test/test_pose_optimizer.cpp new file mode 100644 index 0000000..0c9a63f --- /dev/null +++ b/svo/test/test_pose_optimizer.cpp @@ -0,0 +1,119 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +using namespace svo; +using namespace Eigen; + +/// Pose Optimizer Test-Fixture +class PoseOptimizerTest { + public: + PoseOptimizerTest() + { + cam_ = new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240); + + // load image + std::string dataset_dir(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1"); + std::string img_name(dataset_dir+"/img/frame_000001_0.png"); + printf("Loading image '%s'\n", img_name.c_str()); + cv::Mat img(cv::imread(img_name, 0)); + assert(!img.empty()); + + // create frame + frame_.reset(new svo::Frame(cam_, img, 1.0)); + + // set pose + Eigen::Vector3d t_w_ref(2.139359951019287, -1.9544399976730347, 2.8595199584960938 ); + Eigen::Quaterniond q_w_ref(0.0027939670253545046, 0.8382523059844971, 0.5443645715713501, -0.03150530532002449); + frame_->T_f_w_ = Sophus::SE3(q_w_ref.toRotationMatrix(), t_w_ref).inverse(); + + // load ground-truth depth + vk::blender_utils::loadBlenderDepthmap(dataset_dir + "/depth/frame_000001_0.depth", *cam_, depthmap_); + + // detect features + feature_detection::Corners corners; + feature_detection::FastDetector detector; + detector.detect(frame_->img_pyr_, frame_->fts_, Config::gridSize(), + Config::nPyrLevels(), Config::triangMinCornerScore(), &corners); + size_t n_fts = 0; + for(feature_detection::Corners::iterator it=corners.begin(); it!=corners.end(); ++it) + { + // we must check again if the score is above the threshold because the Corners + // vector is initialized with dummy corners + if(it->score > Config::triangMinCornerScore()) + { + Feature* ftr(new Feature(frame_.get(), Vector2d(it->x, it->y), it->level)); + Point* point(new Point(frame_->f2w(ftr->f*depthmap_.at(it->y, it->x)), Point::DEPTH)); + ftr->point = point; + ftr->frame = frame_.get(); + frame_->addFeature(ftr); + ++n_fts; + } + } + printf("Added %zu features to frame.\n", n_fts); + } + + virtual ~PoseOptimizerTest() + { + delete cam_; + } + + // Individual tests + void test(const Vector3d& pose_disturbance, double pixel_sigma2); + + // Objects declared here can be used by all tests + vk::PinholeCamera* cam_; + FramePtr frame_; + cv::Mat depthmap_; +}; + +void PoseOptimizerTest::test(const Vector3d& pose_disturbance, double pixel_sigma2) +{ + printf("Add %f px noise to each observation\n", pixel_sigma2); + for(Features::iterator it=frame_->fts_.begin(); it!=frame_->fts_.end(); ++it) + { + (*it)->px += Vector2d(vk::Sample::gaussian(pixel_sigma2), vk::Sample::gaussian(pixel_sigma2)); + (*it)->f = frame_->c2f((*it)->px); + } + frame_->T_f_w_ = frame_->T_f_w_*SE3(Matrix3d::Identity(), pose_disturbance); + double estimated_scale, error_init, error_final; + size_t num_obs; + pose_optimizer::optimizeGaussNewton( + Config::reprojThresh(), 10, true, frame_, + estimated_scale, error_init, error_final, num_obs); +} + +} // namespace + +int main(int argc, char** argv) +{ + PoseOptimizerTest test; + test.test(Eigen::Vector3d(0.2, 0.2, 0.2), 1.0); + return 0; +} diff --git a/svo/test/test_sparse_img_align.cpp b/svo/test/test_sparse_img_align.cpp new file mode 100644 index 0000000..1c4437c --- /dev/null +++ b/svo/test/test_sparse_img_align.cpp @@ -0,0 +1,165 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +/// SparseImgAlign Test-Fixture +class SparseImgAlignTest { + public: + + SparseImgAlignTest(); + virtual ~SparseImgAlignTest(); + void testSequence( + const std::string& dataset_dir, + const std::string& experiment_name, + svo::feature_detection::AbstractDetector* feature_detector); + + vk::PinholeCamera* cam_; + svo::FramePtr frame_ref_; + svo::FramePtr frame_cur_; +}; + +SparseImgAlignTest::SparseImgAlignTest() : + cam_(new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240)) +{} + +SparseImgAlignTest::~SparseImgAlignTest() +{} + +void SparseImgAlignTest::testSequence( + const std::string& dataset_dir, + const std::string& experiment_name, + svo::feature_detection::AbstractDetector* feature_detector) +{ + vk::FileReader sequence_file_reader(dataset_dir+"/trajectory.txt"); + std::vector sequence; + sequence_file_reader.skipComments(); + if(!sequence_file_reader.next()) + std::runtime_error("Failed to open sequence file"); + sequence_file_reader.readAllEntries(sequence); + printf("RUN EXPERIMENT: read %zu dataset entries.\n", sequence.size()); + std::vector::iterator iter = sequence.begin(); + std::list translation_error; + + Sophus::SE3 T_prev_w, T_prevgt_w; + std::string trace_name(std::string(TEST_TRACE_DIR) + "/sparse_img_align_" + experiment_name + "_trans_estimate.txt"); + std::ofstream ofs(trace_name.c_str()); + for(int i=0; iter != sequence.end() && i<30; ++iter, ++i) + { + // load img + // IMPORTANT: We need to flip the image because the Povray dataset has a + // negative focal length in y direction which we didn't set. + std::string img_name(dataset_dir+"/img/" + iter->image_name_ + "_0.png"); + cv::Mat img(cv::imread(img_name, 0)); + assert(!img.empty()); + + // load pose + Sophus::SE3 T_w_gt = Sophus::SE3(iter->q_.toRotationMatrix(), iter->t_); + Sophus::SE3 T_gt_w = T_w_gt.inverse(); // ground-truth + + if(i==0) + { + // set reference frame + frame_ref_.reset(new svo::Frame(cam_, img)); + frame_ref_->T_f_w_ = T_gt_w; + + // load ground-truth depth + cv::Mat depthmap; + vk::blender_utils::loadBlenderDepthmap( + dataset_dir+"/depth/"+iter->image_name_+"_0.depth", *cam_, depthmap); + + // extract features, generate features with 3D points + svo::feature_detection::Corners corners; + feature_detector->detect( + frame_ref_->img_pyr_, frame_ref_->fts_, svo::Config::gridSize(), + svo::Config::nPyrLevels(), svo::Config::triangMinCornerScore(), &corners); + for(svo::feature_detection::Corners::iterator corner=corners.begin(); corner!=corners.end(); ++corner) + { + svo::Feature* ftr = new svo::Feature(frame_ref_.get(), Eigen::Vector2d(corner->x, corner->y), corner->level); + Eigen::Vector3d pt_pos_cur = ftr->f*depthmap.at(corner->y, corner->x); + Eigen::Vector3d pt_pos_w = frame_ref_->T_f_w_.inverse()*pt_pos_cur; + svo::Point* pt = new svo::Point(pt_pos_w, svo::Point::DEPTH); + ftr->point = pt; + frame_ref_->addFeature(ftr); + } + + printf("Added %zu 3d pts to the reference frame.\n", corners.size()); + T_prev_w = frame_ref_->T_f_w_; + T_prevgt_w = T_gt_w; + continue; + } + + frame_cur_.reset(new svo::Frame(cam_, img)); + //frame_cur_->T_f_w_ = frame_ref_->T_f_w_; // start at reference frame + frame_cur_->T_f_w_ = T_prev_w; // start at last frame + + // run image align + vk::Timer t; + svo::SparseImgAlign img_align(svo::Config::kltMaxLevel(), svo::Config::kltMinLevel(), + 30, svo::SparseImgAlign::GaussNewton, false, false); + img_align.run(frame_ref_, frame_cur_); + + // compute error + Sophus::SE3 T_f_gt = frame_cur_->T_f_w_ * T_gt_w.inverse(); + translation_error.push_back(T_f_gt.translation().norm()); + printf("[%3.i] time = %f ms \t |t| = %f \t translation error = %f\n", + i, t.stop()*1000, (frame_ref_->T_f_w_*T_gt_w.inverse()).translation().norm(), + translation_error.back()); + + // save old pose for next iteration + T_prev_w = frame_cur_->T_f_w_; + T_prevgt_w = T_gt_w; + + ofs << frame_cur_->T_f_w_.inverse().translation().transpose() << " " + << T_gt_w.inverse().translation().transpose() << std::endl; + } + ofs.close(); + + // trace error + trace_name = std::string(TEST_TRACE_DIR) + "/sparse_img_align_" + experiment_name + "_trans_error.txt"; + ofs.open(trace_name.c_str()); + for(std::list::iterator it=translation_error.begin(); it!=translation_error.end(); ++it) + ofs << *it << std::endl; + ofs.close(); +} + +} // namespace + + +int main(int argc, char** argv) +{ + std::string experiment_name("flying_room_1_rig_1_fast_minlev0"); + std::string dataset_dir(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1"); + svo::feature_detection::FastDetector detector; + svo::Config::triangMinCornerScore() = 20; + svo::Config::kltMinLevel() = 0; + SparseImgAlignTest test; + test.testSequence(dataset_dir, experiment_name, &detector); + return 0; +} diff --git a/svo_analysis/benchmark.py b/svo_analysis/benchmark.py new file mode 100755 index 0000000..da32e70 --- /dev/null +++ b/svo_analysis/benchmark.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +""" +Created on Sat Aug 10 18:21:47 2013 + +@author: Christian Forster +""" + +import os +import yaml +import time + +class RosNode: + def __init__(self, package, executable): + self.package = package + self.executable = executable + + def run(self, parameter_dictionary): + parameter_string = '' + for key in parameter_dictionary.keys(): + parameter_string = parameter_string + ' _' + key + ':=' + str(parameter_dictionary[key]) + os.system('rosrun ' + self.package + ' ' + self.executable + ' ' + parameter_string) + +if __name__=="__main__": + + # config: + home_dir = os.getenv("HOME") + dataset_dir = home_dir+'/Datasets/SlamBenchmark/' + algo_dir = home_dir+'/workspace/rpg_slam/svo_ros' + trace_dir = home_dir+'/workspace/rpg_slam/svo_analysis/results' + platform = 'i7' + + # load parameters + experiment_name = 'asl2_fast' + experiment_file = 'experiments/'+experiment_name+'.yaml' + experiment_file_stream = open(experiment_file,'r') + experiment_dict = yaml.load(experiment_file_stream) + + dataset_param_file = dataset_dir+experiment_dict['dataset']+'/dataset_params.yaml' + dataset_param_file_stream = open(dataset_param_file,'r') + dataset_param_dict = yaml.load(dataset_param_file_stream) + + algo_param_file = algo_dir+'/param/'+experiment_dict['param_settings']+'.param' + algo_param_file_stream = open(algo_param_file,'r') + algo_param_dict = yaml.load(algo_param_file_stream) + + params = dict(dataset_param_dict.items() + algo_param_dict.items() + experiment_dict.items()) + localtime = time.localtime() + params['trace_name'] = time.strftime("%Y%m%d_%H%M", localtime)+'_nslam_'+platform+'_'+experiment_name + params['trace_dir'] = trace_dir+'/'+params['trace_name'] + params['run_id'] = 0 + + # create folder for experiment results + if not os.path.exists(params['trace_dir']): + os.makedirs(params['trace_dir']) + + # dump experiment params to file: + params_dump_file = params['trace_dir']+'/params.yaml' + with open(params_dump_file,'w') as outfile: + outfile.write( yaml.dump(params, default_flow_style=False) ) + + # start ros node + print 'starting ros node' + node = RosNode('svo_ros','benchmark') + node.run(params) + print 'ros node finished processing' + + diff --git a/svo_analysis/evaluate.py b/svo_analysis/evaluate.py new file mode 100755 index 0000000..05af1ee --- /dev/null +++ b/svo_analysis/evaluate.py @@ -0,0 +1,47 @@ +#!/usr/bin/python +""" +Created on Sat Aug 10 18:21:47 2013 + +@author: Christian Forster +""" + +import argparse +import csv +import numpy as np +from matplotlib import rc +import scripts.analyse_logs as analyse_logs +import scripts.analyse_timing as analyse_timing + +if __name__=="__main__": + + # parse command line + parser = argparse.ArgumentParser() + parser.add_argument('--trace_name', help='svo tracefile with timings and logs', default='20131121_0930_px7') + args = parser.parse_args() + + # config + results_dir = 'results/'+args.trace_name + trace_file = results_dir+'/'+args.trace_name+'.csv' + + # tracefile + data = csv.reader(open(trace_file)) + fields = data.next() + D = dict() + for field in fields: + D[field] = list() + + # fill dictionary with column values + for row in data: + for (field, value) in zip(fields, row): + D[field].append(float(value)) + + # change dictionary values from list to numpy array for easier manipulation + for field, value in D.items(): + D[field] = np.array(D[field]) + + # tell matplotlib to use latex font + rc('font',**{'family':'serif','serif':['Cardo']}) + rc('text', usetex=True) + + analyse_logs.analyse_logs(D, results_dir+'/'+args.trace_name) + analyse_timing.analyse_timing(D, results_dir+'/'+args.trace_name) \ No newline at end of file diff --git a/svo_analysis/experiments/asl2_acc.yaml b/svo_analysis/experiments/asl2_acc.yaml new file mode 100644 index 0000000..0b5bf3b --- /dev/null +++ b/svo_analysis/experiments/asl2_acc.yaml @@ -0,0 +1,2 @@ +dataset: asl_vicon_d2 +param_settings: vo_accurate \ No newline at end of file diff --git a/svo_analysis/experiments/asl2_fast.yaml b/svo_analysis/experiments/asl2_fast.yaml new file mode 100644 index 0000000..34285b5 --- /dev/null +++ b/svo_analysis/experiments/asl2_fast.yaml @@ -0,0 +1,2 @@ +dataset: asl_vicon_d2 +param_settings: vo_fast \ No newline at end of file diff --git a/svo_analysis/results/.gitignore b/svo_analysis/results/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/svo_analysis/results/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/svo_analysis/scripts/__init__.py b/svo_analysis/scripts/__init__.py new file mode 100644 index 0000000..633f866 --- /dev/null +++ b/svo_analysis/scripts/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- + diff --git a/svo_analysis/scripts/analyse_dataset.py b/svo_analysis/scripts/analyse_dataset.py new file mode 100644 index 0000000..fa257b8 --- /dev/null +++ b/svo_analysis/scripts/analyse_dataset.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +import associate +import numpy as np +import matplotlib.pyplot as plt +import yaml +import transformations + +def loadDataset(filename): + file = open(filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + D = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) + return D + +dataset_dir = '/home/cforster/Datasets/SlamBenchmark/px4_r2' +trajectory_data = dataset_dir+'/groundtruth.txt' +stepsize = 10 + +# load dataset +data = loadDataset(trajectory_data) +n = data.shape[0] +steps = np.arange(0,n,stepsize) + +# compute trajectory length +last_pos = data[0,1:4] +trajectory_length = 0 + +for i in steps[1:]: + new_pos = data[i,1:4] + trajectory_length += np.linalg.norm(new_pos-last_pos) + last_pos = new_pos + + +print 'trajectory lenght = ' + str(trajectory_length) + 'm' +print 'height mean = ' + str(np.mean(data[:,3])) + 'm' +print 'height median = ' + str(np.median(data[:,3])) + 'm' +print 'height std = ' + str(np.std(data[:,3])) + 'm' +print 'duration = ' + str(data[-1,0]-data[0,0]) + 's' +print 'speed = ' + str(trajectory_length/(data[-1,0]-data[0,0])) + 'm/s' + + diff --git a/svo_analysis/scripts/analyse_logs.py b/svo_analysis/scripts/analyse_logs.py new file mode 100755 index 0000000..be14feb --- /dev/null +++ b/svo_analysis/scripts/analyse_logs.py @@ -0,0 +1,132 @@ +#!/usr/bin/python + +import argparse +import csv +import numpy as np +import matplotlib.pyplot as plt +from matplotlib import rc + +def analyse_logs(D, trace_name): + + # identify measurements which result from normal frames and which from keyframes + is_kf = np.argwhere( (D['dropout'] == 1) & (D['repr_n_mps'] >= 0)) + is_frame = np.argwhere(D['repr_n_mps'] >= 0) + is_nokf = np.argwhere( (D['dropout'] == 0) & (D['repr_n_mps'] >= 0)) + n_frames = len(is_frame) + n_kfs = len(is_kf) + n_nokf = len(is_nokf) + fps = 25.0 + + # plot number of reprojected points + mean_n_reproj_points = np.mean(D['repr_n_mps'][is_frame]); + mean_n_reproj_matches = np.mean(D['repr_n_new_references'][is_frame]); + + plt.figure() + plt.plot(np.arange(n_frames), D['repr_n_mps'][is_frame], 'r-', label='reprojected points, avg = %(i).2f'%{'i':mean_n_reproj_points}) + plt.plot(np.arange(n_frames), D['repr_n_new_references'][is_frame], 'b-', label='reprojected matches, avg = %(i).2f'%{'i':mean_n_reproj_matches}) + plt.legend() + plt.tight_layout() + plt.title('Reprojected points asdf') + plt.savefig(trace_name+'_reprojection.pdf', bbox_inches="tight") + + # plot number of triangulations +# plt.figure(3) +# plt.plot(np.arange(n_kfs), D['triang_n_points'][is_kf], 'g-', label='triangulated points, avg %0.2f'%np.mean(D['triang_n_points'][is_kf])) +# plt.plot(np.arange(n_kfs), D['triang_n_refs'][is_kf], 'b-', label='new references, avg %0.2f'%np.mean(D['triang_n_refs'][is_kf])) +# plt.plot(np.arange(n_kfs), D['triang_n_fails'][is_kf], 'r-', label='failures, avg %0.2f'%np.mean(D['triang_n_fails'][is_kf])) +# plt.plot(np.arange(n_kfs), D['triang_n_add_refs'][is_kf], 'm-', label='additional refs, avg %0.2f'%np.mean(D['triang_n_add_refs'][is_kf])) +# plt.legend() +# plt.title('Triangulation') +# plt.savefig(trace_name+'_img_triangulation.png', bbox_inches="tight") + + # plot number of klt tracked and matched points + fig = plt.figure(figsize=(8,2)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='no. features') + ax.plot(np.arange(n_frames)/fps, D['repr_n_new_references'][is_frame], 'b-', label='number of successful matches') + fig.tight_layout() + fig.savefig(trace_name+'number_of_features.pdf', bbox_inches="tight") + + # plot median error before and after pose-optimzation and bundle adjustment + init_error_avg = np.mean(D['sfba_error_init'][is_frame]) + opt1_avg = np.mean(D['sfba_error_final'][is_frame]) + + fig = plt.figure(figsize=(8,2)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='error [px]') + t_max = n_frames + ax.plot(np.arange(n_frames)[0:t_max]/fps, D['sfba_error_init'][is_frame][0:t_max], 'r-', label='Initial error') + ax.plot(np.arange(n_frames)[0:t_max]/fps, D['sfba_error_final'][is_frame][0:t_max], 'b-', label='Final error') + ax.legend(ncol=2) + ax.set_xlim([0, t_max/fps+4]) + #ax.set_ylim([0, 0.8]) + fig.tight_layout() + fig.savefig(trace_name+'reprojection_error.pdf', bbox_inches="tight") + print 'average reprojection error improvement: ' + str(init_error_avg - opt1_avg) + + # plot number of references + plt.figure() + plt.fill(np.arange(n_frames+1), np.append(D['repr_n_new_references'][is_frame]+D['klt_n_matches'][is_frame],0), 'g-', label='Reprojection') + plt.fill(np.arange(n_frames+1), np.append(D['klt_n_tracked'][is_frame],0), 'b-', label='KLT Matches') + plt.plot(np.arange(n_frames), D['sfba_n_edges_final'][is_frame], 'r-', label='References after Optimization', linewidth=2.0) + plt.legend() + plt.tight_layout() + plt.title('Pose Optimization') + plt.savefig(trace_name+'_img_n_references.pdf', bbox_inches="tight") + + # plot number of seeds + plt.figure() + has_seed = np.argwhere(D['seeds_n_tot'] >= 0) + plt.fill(np.arange(len(has_seed)+1), np.append(D['seeds_n_tot'][has_seed],0), label='nSeeds', edgecolor='none') + plt.fill(np.arange(len(has_seed)+1), np.append(D['seeds_n_updates'][has_seed]+D['seeds_n_failed_matches'][has_seed],0), label='nFailedMatches', edgecolor='none') + plt.fill(np.arange(len(has_seed)+1), np.append(D['seeds_n_updates'][has_seed],0), label='nUpdates', edgecolor='none') + plt.legend() + plt.tight_layout() + plt.title('Seeds') + plt.savefig(trace_name+'_seeds.pdf', bbox_inches="tight") + + + plt.figure() + plt.plot(D['n_candidates']) + plt.title('Candidates') + plt.show() + +# plt.figure() +# plt.plot()) + +if __name__=="__main__": + + dataset='20131003_1937_nslam_i7_asl2_fast' + n_align_frames = 10 + save = True + results_dir = '../results/'+dataset + logfile = results_dir+'/'+dataset+'_0.csv' + + # parse command line + parser = argparse.ArgumentParser(description=''' + This script computes the absolute trajectory error from the ground truth trajectory and the estimated trajectory. + ''') + parser.add_argument('--trace_file', help='nanoslam tracefile with timings and logs', default=logfile) + parser.add_argument('--trace_name', help='name of the tracefile, used for saving figures etc.', default=results_dir+'/') + args = parser.parse_args() + + # tracefile + data = csv.reader(open(args.trace_file)) + fields = data.next() + D = dict() + for field in fields: + D[field] = list() + + # fill dictionary with column values + for row in data: + for (field, value) in zip(fields, row): + D[field].append(float(value)) + + # change dictionary values from list to numpy array for easier manipulation + for field, value in D.items(): + D[field] = np.array(D[field]) + + # tell matplotlib to use latex font + rc('font',**{'family':'serif','serif':['Cardo']}) + rc('text', usetex=True) + + analyse_logs(D, args.trace_name) + diff --git a/svo_analysis/scripts/analyse_timing.py b/svo_analysis/scripts/analyse_timing.py new file mode 100755 index 0000000..b0d2199 --- /dev/null +++ b/svo_analysis/scripts/analyse_timing.py @@ -0,0 +1,97 @@ +#!/usr/bin/python + +import argparse +import csv +import numpy as np +import matplotlib.pyplot as plt +from matplotlib import rc + +def analyse_timing(D, trace_name): + + # identify measurements which result from normal frames and which from keyframes + is_frame = np.argwhere(D['repr_n_mps'] >= 0) + n_frames = len(is_frame) + + # plot total time for frame processing + avg_time = np.mean(D['t_tot_time'][is_frame])*1000; + + fig = plt.figure(figsize=(8, 3)) + ax = fig.add_subplot(111, ylabel='processing time [ms]', xlabel='time [s]') + ax.plot(np.arange(n_frames), D['t_tot_time'][is_frame]*1000, 'g-', label='total time [ms]') + ax.plot(np.arange(n_frames), np.ones(n_frames)*avg_time, 'b--', label=str('%(time).1fms mean time' % {'time': avg_time})) + ax.legend() + fig.tight_layout() + fig.savefig(trace_name+'_img_tot_processing_time.pdf', bbox_inches="tight") + + fig = plt.figure(figsize=(6,2)) + ax = fig.add_subplot(111, xlabel='Processing time [ms]') + ax.boxplot([ + D['t_tot_time'][is_frame]*1000, +# D['t_local_ba'][is_kf]*1000, + D['t_pose_optimizer'][is_frame]*1000 + D['t_point_optimizer'][is_frame]*1000, + D['t_reproject'][is_frame]*1000, + D['t_sparse_img_align'][is_frame]*1000, + D['t_pyramid_creation'][is_frame]*1000 + ], 0,'', vert=0) # + + boxplot_labels = [ + r'\textbf{Total Motion Estimation: %2.2fms}' % np.median(D['t_tot_time'][is_frame]*1000), +# 'Local BA (KF only): %.2fms ' % np.median(D['t_local_ba'][is_kf]*1000), + 'Refinement: %2.2fms' % np.median(D['t_pose_optimizer'][is_frame]*1000 + D['t_point_optimizer'][is_frame]*1000), + 'Feature Alignment: %2.2fms' % np.median(D['t_reproject'][is_frame]*1000), + 'Sparse Image Alignment: %2.2fms' % np.median(D['t_sparse_img_align'][is_frame]*1000), + 'Pyramid Creation: %2.2fms' % np.median(D['t_pyramid_creation'][is_frame]*1000) ] + + ax.set_yticks(np.arange(len(boxplot_labels))+1) + ax.set_yticklabels(boxplot_labels) + fig.tight_layout() + fig.savefig(trace_name+'_timing_boxplot.pdf', bbox_inches="tight") + + fig = plt.figure(figsize=(8, 5)) + ax = fig.add_subplot(111, ylabel='time [ms]') + ax.plot(D['t_reproject']*1000, 'r', label='reproject') + ax.plot(D['t_reproject_find_pts']*1000, 'g', label='reproject find pts') # ok! + ax.plot(D['t_reproject_best']*1000, 'm', label='reproject best') + ax.plot(D['t_reproject_candidates']*1000, 'b', label='reproject candidates') + ax.legend() + fig.tight_layout() + fig.savefig(trace_name+'_reprojection.pdf', bbox_inches="tight") + + +if __name__=="__main__": + + # config + dataset='20131003_1937_nslam_i7_asl2_fast' + results_dir = '../results/'+dataset + tracefile = results_dir + '/'+dataset+'_0.csv' + + # parse command line + parser = argparse.ArgumentParser(description=''' + This script computes the absolute trajectory error from the ground truth trajectory and the estimated trajectory. + ''') + parser.add_argument('--trace_file', help='nanoslam tracefile with timings and logs', default=tracefile) + parser.add_argument('--trace_name', help='name of the tracefile, used for saving figures etc.', default=results_dir) + args = parser.parse_args() + results_dir = args.trace_name + + # tracefile + data = csv.reader(open(args.trace_file)) + fields = data.next() + D = dict() + for field in fields: + D[field] = list() + + # fill dictionary with column values + for row in data: + for (field, value) in zip(fields, row): + D[field].append(float(value)) + + # change dictionary values from list to numpy array for easier manipulation + for field, value in D.items(): + D[field] = np.array(D[field]) + + # tell matplotlib to use latex font + rc('font',**{'family':'serif','serif':['Cardo']}) + rc('text', usetex=True) + + \ No newline at end of file diff --git a/svo_analysis/scripts/analyse_trajectory.py b/svo_analysis/scripts/analyse_trajectory.py new file mode 100644 index 0000000..f70cd62 --- /dev/null +++ b/svo_analysis/scripts/analyse_trajectory.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- + +import associate +import numpy as np +import matplotlib.pyplot as plt +import yaml +import transformations +from matplotlib import rc + +def alignSim3(model, data, n): + + # select the first n datapoints and remove its mean so their center is zero + M = model[0:n,:] + D = data[0:n,:] + + # substract mean + mu_M = M.mean(0) + mu_D = D.mean(0) + M_zerocentered = M - mu_M + D_zerocentered = D - mu_D + + # correlation + C = 1.0/n*np.dot(M_zerocentered.transpose(), D_zerocentered) + sigma2 = 1.0/n*np.multiply(D_zerocentered,D_zerocentered).sum() + U_svd,D_svd,V_svd = np.linalg.linalg.svd(C) + D_svd = np.diag(D_svd) + V_svd = np.transpose(V_svd) + S = np.eye(3) + + if(np.linalg.det(U_svd)*np.linalg.det(V_svd) < 0): + S[2,2] = -1 + + R = np.dot(U_svd, np.dot(S, np.transpose(V_svd))) + s = 1.0/sigma2*np.trace(np.dot(D_svd, S)) + t = mu_M-s*np.dot(R,mu_D) + + return s, R, t + + +def getRigidBodyTrafo(quat,trans): + T = transformations.quaternion_matrix(quat) + T[0:3,3] = trans + return T + +if __name__ == '__main__': + + # config + dataset='20131003_1937_nslam_i7_asl2_fast' + n_align_frames = 100 + save = True + results_dir = '../results/'+dataset + + # plot options + rc('font',**{'family':'serif','serif':['Cardo']}) + rc('text', usetex=True) + + # load dataset parameters + params_stream = open(results_dir+'/params.yaml') + params = yaml.load(params_stream) + + # set trajectory groundtruth and estimate file + traj_groundtruth = params['dataset_directory']+'/groundtruth_filtered.txt' + traj_estimate = results_dir+'/traj_estimate.txt' + traj_estimate_rotated_filename = results_dir+'/traj_estimate_rotated.txt' + translation_error_filename = results_dir+'/translation_error.txt' + orientation_error_filename = results_dir+'/orientation_error.txt' + scale_drift_filename = results_dir+'/scale_drift.txt' + + # load hand-eye calib: trafo between (m)arker and (c)amera. + dataset_param_file = params['dataset_directory']+'/dataset_params.yaml' + dataset_param_file_stream = open(dataset_param_file,'r') + P = yaml.load(dataset_param_file_stream) + T_cm_quat = np.array([P['calib_Tcm_qx'], P['calib_Tcm_qy'], P['calib_Tcm_qz'], P['calib_Tcm_qw']]) + T_cm_tran = np.array([P['calib_Tcm_tx'], P['calib_Tcm_ty'], P['calib_Tcm_tz']]) + T_cm = getRigidBodyTrafo(T_cm_quat, T_cm_tran) + T_mc = transformations.inverse_matrix(T_cm) + + # load data + data_gt = associate.read_file_list(traj_groundtruth) + data_es = associate.read_file_list(traj_estimate) + + # find matches + matches = associate.associate(data_gt, data_es, -P['cam_delay'], 0.02) + p_gt = np.array([[float(value) for value in data_gt[a][0:3]] for a,b in matches]) + q_gt = np.array([[float(value) for value in data_gt[a][3:7]] for a,b in matches]) + p_es = np.array([[float(value) for value in data_es[b][0:3]] for a,b in matches]) + q_es = np.array([[float(value) for value in data_es[b][3:7]] for a,b in matches]) + t_gt = np.array([float(a) for a,b in matches]) + t_es = np.array([float(b) for a,b in matches]) + start_time = min(t_es[0], t_gt[0]) + t_es -= start_time + t_gt -= start_time + + # align Sim3 to get scale + if(n_align_frames > np.shape(matches)[0]): + raise NameError('n_matches_for_scale is too large') + scale,rot,trans = alignSim3(p_gt, p_es, n_align_frames) + print 'scale = '+str(scale) + + # get trafo between (v)ision and (o)ptitrack frame + T_om = getRigidBodyTrafo(q_gt[0,:], p_gt[0,:]) + T_vc = getRigidBodyTrafo(q_es[0,:], scale*p_es[0,:]) + T_cv = transformations.inverse_matrix(T_vc) + T_ov = np.dot(T_om, np.dot(T_mc, T_cv)) + print 'T_ov = ' + str(T_ov) + + p_es_aligned = np.zeros(np.shape(p_es)) + q_es_aligned = np.zeros(np.shape(q_es)) + rpy_es_aligned = np.zeros(np.shape(p_es)) + rpy_gt = np.zeros(np.shape(p_es)) + + # rotate trajectory + for i in range(np.shape(matches)[0]): + T_vc = getRigidBodyTrafo(q_es[i,:],p_es[i,:]) + T_vc[0:3,3] *= scale + T_om = np.dot(T_ov, np.dot(T_vc, T_cm)) + p_es_aligned[i,:] = T_om[0:3,3] + q_es_aligned[i,:] = transformations.quaternion_from_matrix(T_om) + rpy_es_aligned[i,:] = transformations.euler_from_quaternion(q_es_aligned[i,:], 'rzyx') + rpy_gt[i,:] = transformations.euler_from_quaternion(q_gt[i,:], 'rzyx') + + if save: + f = open(traj_estimate_rotated_filename,'w') + for i in range(np.shape(p_es_aligned)[0]): + f.write('%.7f %.5f %.5f %.5f %.5f %.5f %.5f %.5f\n' % (matches[i][1]-P['cam_delay'], p_es_aligned[i,0], p_es_aligned[i,1], p_es_aligned[i,2], q_es_aligned[i,0], q_es_aligned[i,1], q_es_aligned[i,2], q_es_aligned[i,3])) + f.close() + + # plot trajectory + fig = plt.figure() + ax = fig.add_subplot(111, title='trajectory', aspect='equal', xlabel='x [m]', ylabel='Y [m]') + ax.plot(p_es_aligned[:,0], p_es_aligned[:,1], 'b-', label='estimate') + ax.plot(p_gt[:,0], p_gt[:,1], 'r-', label='groundtruth') + ax.plot(p_es_aligned[0:n_align_frames,0], p_es_aligned[0:n_align_frames,1], 'g-', linewidth=2, label='aligned') + fig.tight_layout() + fig.savefig(results_dir+'/trajectory.pdf') + + # plot position error (drift) + translation_error = (p_gt-p_es_aligned) + fig = plt.figure(figsize=(8, 2.5)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='position drift [m]', xlim=[0,t_es[-1]+4]) + ax.plot(t_es, translation_error[:,0], 'r-', label='x') + ax.plot(t_es, translation_error[:,1], 'g-', label='y') + ax.plot(t_es, translation_error[:,2], 'b-', label='z') + fig.tight_layout() + + if save: + fig.savefig(results_dir+'/translation_error.pdf') + f = open(translation_error_filename,'w') + for i in range(translation_error.shape[0]): + f.write('%.7f %.5f %.5f %.5f\n'%(t_es[i], translation_error[i,0], translation_error[i,1], translation_error[i,2])) + f.close() + + # plot orientation error (drift) + orientation_error = (rpy_gt - rpy_es_aligned) + fig = plt.figure(figsize=(8, 2.5)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='orientation drift [rad]', xlim=[0,t_es[-1]+4]) + ax.plot(t_es, orientation_error[:,0], 'r--', label='yaw') + ax.plot(t_es, orientation_error[:,1], 'g--', label='pitch') + ax.plot(t_es, orientation_error[:,2], 'b--', label='roll') + ax.legend() + fig.tight_layout() + + if save: + fig.savefig(results_dir+'/orientation_error.pdf') + f = open(orientation_error_filename,'w') + for i in range(orientation_error.shape[0]): + f.write('%.7f %.5f %.5f %.5f\n'%(t_es[i], orientation_error[i,0], orientation_error[i,1], orientation_error[i,2])) + f.close() + + # plot scale drift + motion_gt = np.diff(p_gt, 0) + motion_es = np.diff(p_es_aligned, 0) + dist_gt = np.sqrt(np.sum(np.multiply(motion_gt,motion_gt),1)) + dist_es = np.sqrt(np.sum(np.multiply(motion_es,motion_es),1)) + fig = plt.figure(figsize=(8,2.5)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='scale change [\%]', xlim=[0,t_es[-1]+4]) + scale_drift = np.divide(dist_es,dist_gt)*100-100 + ax.plot(t_es, scale_drift, 'b-') + fig.tight_layout() + + if save: + fig.savefig(results_dir+'/scale_drift.pdf') + f = open(scale_drift_filename,'w') + for i in range(orientation_error.shape[0]): + f.write('%.7f %.5f\n'%(t_es[i], scale_drift[i])) + f.close() + diff --git a/svo_analysis/scripts/associate.py b/svo_analysis/scripts/associate.py new file mode 100644 index 0000000..8a7438c --- /dev/null +++ b/svo_analysis/scripts/associate.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +# +# Requirements: +# sudo apt-get install python-argparse + +import argparse +import sys +import os +import numpy + + +def read_file_list(filename): + file = open(filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + list = [[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"] + list = [(float(l[0]),l[1:]) for l in list if len(l)>1] + return dict(list) + +def associate(first_list, second_list,offset,max_difference): + # first_list = groundtruth + # second_list = estimate + first_keys = first_list.keys() + second_keys = second_list.keys() + potential_matches = [(abs(a - (b + offset)), a, b) + for a in first_keys + for b in second_keys + if abs(a - (b + offset)) < max_difference] + + potential_matches.sort() + matches = [] + for diff, a, b in potential_matches: + if a in first_keys and b in second_keys: + first_keys.remove(a) + second_keys.remove(b) + matches.append((a, b)) + + matches.sort() + + return matches + +if __name__ == '__main__': + + # parse command line + parser = argparse.ArgumentParser(description=''' + This script takes two data files with timestamps and associates them + ''') + parser.add_argument('first_file', help='first text file (format: timestamp data)') + parser.add_argument('second_file', help='second text file (format: timestamp data)') + parser.add_argument('--first_only', help='only output associated lines from first file', action='store_true') + parser.add_argument('--offset', help='time offset added to the timestamps of the second file (default: 0.0)',default=0.0) + parser.add_argument('--max_difference', help='maximally allowed time difference for matching entries (default: 0.02)',default=0.02) + args = parser.parse_args() + + first_list = read_file_list(args.first_file) + second_list = read_file_list(args.second_file) + + matches = associate(first_list, second_list,float(args.offset),float(args.max_difference)) + + if args.first_only: + for a,b in matches: + print("%f %s"%(a," ".join(first_list[a]))) + else: + for a,b in matches: + print("%f %s %f %s"%(a," ".join(first_list[a]),b-float(args.offset)," ".join(second_list[b]))) + + diff --git a/svo_analysis/scripts/evaluate_rpe.py b/svo_analysis/scripts/evaluate_rpe.py new file mode 100755 index 0000000..1ba24a7 --- /dev/null +++ b/svo_analysis/scripts/evaluate_rpe.py @@ -0,0 +1,355 @@ +#!/usr/bin/python + +import yaml +import argparse +import random +import numpy +import sys +import transformations +import matplotlib +import matplotlib.pyplot as plt +import matplotlib.pylab as pylab +from matplotlib import rc + +def transform44(l): + t = l[1:4] + q = l[4:8] + return numpy.dot(transformations.translation_matrix(t),transformations.quaternion_matrix(q)) + +def read_trajectory(filename, matrix=True): + file = open(filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + list = [[float(v.strip()) for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"] + list_ok = [] + for i,l in enumerate(list): + if l[4:8]==[0,0,0,0]: + continue + isnan = False + for v in l: + if numpy.isnan(v): + isnan = True + break + if isnan: + sys.stderr.write("Warning: line %d of file '%s' has NaNs, skipping line\n"%(i,filename)) + continue + list_ok.append(l) + if matrix : + traj = dict([(l[0],transform44(l[0:])) for l in list_ok]) + else: + traj = dict([(l[0],l[1:8]) for l in list_ok]) + return traj + +def find_closest_index(L,t): + beginning = 0 + difference = abs(L[0] - t) + best = 0 + end = len(L) + while beginning < end: + middle = int((end+beginning)/2) + if abs(L[middle] - t) < difference: + difference = abs(L[middle] - t) + best = middle + if t == L[middle]: + return middle + elif L[middle] > t: + end = middle + else: + beginning = middle + 1 + return best + +def ominus(a,b): + return numpy.dot(numpy.linalg.inv(a),b) + +def scale(a,scalar): + return numpy.array( + [[a[0,0], a[0,1], a[0,2], a[0,3]*scalar], + [a[1,0], a[1,1], a[1,2], a[1,3]*scalar], + [a[2,0], a[2,1], a[2,2], a[2,3]*scalar], + [a[3,0], a[3,1], a[3,2], a[3,3]]] + ) + +def compute_distance(transform): + return numpy.linalg.norm(transform[0:3,3]) + +def compute_angle(transform): + # an invitation to 3-d vision, p 27 + return numpy.arccos( min(1,max(-1, (numpy.trace(transform[0:3,0:3]) - 1)/2) )) + +def distances_along_trajectory(traj): + keys = traj.keys() + keys.sort() + motion = [ominus(traj[keys[i+1]],traj[keys[i]]) for i in range(len(keys)-1)] + distances = [0] + sum = 0 + for t in motion: + sum += compute_distance(t) + distances.append(sum) + return distances + +def rotations_along_trajectory(traj,scale): + keys = traj.keys() + keys.sort() + motion = [ominus(traj[keys[i+1]],traj[keys[i]]) for i in range(len(keys)-1)] + distances = [0] + sum = 0 + for t in motion: + sum += compute_angle(t)*scale + distances.append(sum) + return distances + +def interpolate_transformation(alpha,a,b): + qa,ta = transformations.quaternion_from_matrix(a),transformations.translation_from_matrix(a) + qb,tb = transformations.quaternion_from_matrix(b),transformations.translation_from_matrix(b) + qr = transformations.quaternion_slerp(qa,qb,alpha) + tr = (1-alpha) * ta + (alpha) * tb + r = numpy.dot(transformations.translation_matrix(tr),transformations.quaternion_matrix(qr)) + return r + +def interpolate_and_resample(traj_gt,stamps_est,param_offset,gt_max_time_difference): + traj_new = {} + + stamps_gt = list(traj_gt.keys()) + stamps_gt.sort() + + for t_est in stamps_est: + t_new = t_est + param_offset + i_nearest = find_closest_index(stamps_gt,t_est + param_offset) + if stamps_gt[i_nearest] >= t_new and i_nearest>0: + i_low = i_nearest-1 + i_high = i_nearest + else: + i_low = i_nearest + i_high = i_nearest+1 + if i_low<0 or i_high>=len(stamps_gt): + continue + + t_low = stamps_gt[i_low] + t_high = stamps_gt[i_high] + + if(abs( t_new - (t_low + param_offset) ) > gt_max_time_difference or + abs( t_new - (t_high + param_offset) ) > gt_max_time_difference): + continue + + alpha = (t_new - (t_low + param_offset)) / (t_high - t_low) + transform = interpolate_transformation(alpha,traj_gt[t_low],traj_gt[t_high]) + traj_new[t_new] = transform + return traj_new + + +def evaluate_trajectory(traj_gt,traj_est,param_max_pairs=10000,param_fixed_delta=False,param_delta=1.00,param_delta_unit="s",param_offset=0.00,param_scale=1.00,param_interpolation=True): + stamps_est = list(traj_est.keys()) + stamps_est.sort() + stamps_gt = list(traj_gt.keys()) + stamps_gt.sort() + + gt_interval = numpy.median([s-t for s,t in zip(stamps_gt[1:],stamps_gt[:-1])]) + gt_max_time_difference = 2*gt_interval + + if param_interpolation: + traj_gt = interpolate_and_resample(traj_gt,stamps_est,param_offset,gt_max_time_difference) + stamps_gt = list(traj_gt.keys()) + stamps_gt.sort() + + stamps_est_return = [] + for t_est in stamps_est: + t_gt = stamps_gt[find_closest_index(stamps_gt,t_est + param_offset)] + t_est_return = stamps_est[find_closest_index(stamps_est,t_gt - param_offset)] + t_gt_return = stamps_gt[find_closest_index(stamps_gt,t_est_return + param_offset)] + if not t_est_return in stamps_est_return: + stamps_est_return.append(t_est_return) + if(len(stamps_est_return)<2): + raise Exception("Number of overlap in the timestamps is too small. Did you run the evaluation on the right files?") + + if param_delta_unit=="s": + index_est = list(traj_est.keys()) + index_est.sort() + elif param_delta_unit=="m": + index_est = distances_along_trajectory(traj_est) + elif param_delta_unit=="rad": + index_est = rotations_along_trajectory(traj_est,1) + elif param_delta_unit=="deg": + index_est = rotations_along_trajectory(traj_est,180/numpy.pi) + elif param_delta_unit=="f": + index_est = range(len(traj_est)) + else: + raise Exception("Unknown unit for delta: '%s'"%param_delta_unit) + + if not param_fixed_delta: + if(param_max_pairs==0 or len(traj_est)param_max_pairs): + pairs = random.sample(pairs,param_max_pairs) + + result = [] + for i,j in pairs: + stamp_est_0 = stamps_est[i] + stamp_est_1 = stamps_est[j] + + stamp_gt_0 = stamps_gt[ find_closest_index(stamps_gt,stamp_est_0 + param_offset) ] + stamp_gt_1 = stamps_gt[ find_closest_index(stamps_gt,stamp_est_1 + param_offset) ] + + if(abs(stamp_gt_0 - (stamp_est_0 + param_offset)) > gt_max_time_difference or + abs(stamp_gt_1 - (stamp_est_1 + param_offset)) > gt_max_time_difference): + continue + + error44 = ominus( scale( + ominus( traj_est[stamp_est_1], traj_est[stamp_est_0] ),param_scale), + ominus( traj_gt[stamp_gt_1], traj_gt[stamp_gt_0] ) ) + + + trans = compute_distance(error44) + rot = compute_angle(error44) + + motion_gt = ominus( traj_gt[stamp_gt_1], traj_gt[stamp_gt_0] ) + trans_gt = compute_distance(motion_gt) + rot_gt = compute_angle(motion_gt) + + if(rot < 0.07): + result.append([stamp_est_0,stamp_est_1,stamp_gt_0,stamp_gt_1,trans,rot,trans_gt,rot_gt]) + + if len(result)<2: + raise Exception("Couldn't find matching timestamp pairs between groundtruth and estimated trajectory!") + + return result + +def percentile(seq,q): + seq_sorted = list(seq) + seq_sorted.sort() + return seq_sorted[int((len(seq_sorted)-1)*q)] + +if __name__ == '__main__': + random.seed(0) + + # config ------------------------------------------------------------------------- + + dataset='20131003_1937_nslam_i7_asl2_fast' + dataset_dir = '../results/'+dataset + + #--------------------------------------------------------------------------------- + + # load dataset parameters + params_stream = open(dataset_dir+'/params.yaml') + params = yaml.load(params_stream) + + # set trajectory groundtruth and estimate file + traj_groundtruth = params['dataset_directory']+'/groundtruth_filtered.txt' + traj_estimate_rotated = dataset_dir+'/traj_estimate_rotated.txt' + + parser = argparse.ArgumentParser(description=''' + This script computes the relative pose error from the ground truth trajectory and the estimated trajectory. + ''') + parser.add_argument('--groundtruth_file', help='ground-truth trajectory file (format: "timestamp tx ty tz qx qy qz qw")', default=traj_groundtruth) + parser.add_argument('--estimated_file', help='estimated trajectory file (format: "timestamp tx ty tz qx qy qz qw")', default=traj_estimate_rotated) + parser.add_argument('--interpolate', help='interpolate and resample the ground truth trajectory', default=True) + parser.add_argument('--max_pairs', help='maximum number of pose comparisons (default: 10000, set to zero to disable downsampling)', default=10000) + parser.add_argument('--fixed_delta', help='only consider pose pairs that have a distance of delta delta_unit (e.g., for evaluating the drift per second/meter/radian)', default=True) + parser.add_argument('--delta', help='delta for evaluation (default: 1.0)',default=1.0) + parser.add_argument('--delta_unit', help='unit of delta (options: \'s\' for seconds, \'m\' for meters, \'rad\' for radians, \'f\' for frames; default: \'s\')',default='s') + parser.add_argument('--offset', help='time offset between ground-truth and estimated trajectory (default: 0.0)',default=0.0) + parser.add_argument('--scale', help='scaling factor for the estimated trajectory (default: 1.0)',default=1.0) + parser.add_argument('--save', help='text file to which the evaluation will be saved (format: stamp_est0 stamp_est1 stamp_gt0 stamp_gt1 trans_error rot_error)') + parser.add_argument('--plot', help='plot the result to a file (requires --fixed_delta, output format: png)', default=True) + parser.add_argument('--plotname', help='plot the result to a file (requires --fixed_delta, output format: png)', default='rpe.png') + parser.add_argument('--verbose', help='print all evaluation data (otherwise, only the mean translational error measured in meters will be printed)', default=True) + args = parser.parse_args() + + if args.plot and not args.fixed_delta: + sys.exit("The '--plot' option can only be used in combination with '--fixed_delta'") + + traj_gt = read_trajectory(args.groundtruth_file) + traj_est = read_trajectory(args.estimated_file) + + result = evaluate_trajectory(traj_gt, + traj_est, + int(args.max_pairs), + args.fixed_delta, + float(args.delta), + args.delta_unit, + float(args.offset), + float(args.scale), + args.interpolate) + + stamps = numpy.array(result)[:,0] + trans_error = numpy.array(result)[:,4] + rot_error = numpy.array(result)[:,5] + + + results = dict() + results['trans_rmse'] = float(numpy.sqrt(numpy.dot(trans_error,trans_error) / len(trans_error))) + results['trans_mean'] = float(numpy.mean(trans_error)) + results['trans_median'] = float(numpy.median(trans_error)) + results['trans_std'] = float(numpy.std(trans_error)) + results['trans_min'] = float(numpy.min(trans_error)) + results['trans_max'] = float(numpy.max(trans_error)) + results['rot_rmse'] = float((numpy.sqrt(numpy.dot(rot_error,rot_error) / len(rot_error)) * 180.0 / numpy.pi)) + results['rot_mean'] = float((numpy.mean(rot_error) * 180.0 / numpy.pi)) + results['rot_median'] = float(numpy.median(rot_error) * 180.0 / numpy.pi) + results['rot_std'] = float((numpy.std(rot_error) * 180.0 / numpy.pi)) + results['rot_min'] = float((numpy.min(rot_error) * 180.0 / numpy.pi)) + results['rot_max'] = float((numpy.max(rot_error) * 180.0 / numpy.pi)) + + # dump experiment results to file: + results_file = params['trace_dir']+'/rpe_results.yaml' + with open(results_file,'w') as outfile: + outfile.write( yaml.dump(results, default_flow_style=False) ) + + if args.save: + f = open(args.save,"w") + f.write("\n".join([" ".join(["%f"%v for v in line]) for line in result])) + f.close() + + if args.verbose: + print "compared_pose_pairs %d pairs"%(len(trans_error)) + + print "translational_error.rmse %f m"%results['trans_rmse'] + print "translational_error.mean %f m"%results['trans_mean'] + print "translational_error.median %f m"%results['trans_median'] + print "translational_error.std %f m"%results['trans_std'] + print "translational_error.min %f m"%results['trans_min'] + print "translational_error.max %f m"%results['trans_max'] + + print "rotational_error.rmse %f deg"%results['rot_rmse'] + print "rotational_error.mean %f deg"%results['rot_mean'] + print "rotational_error.median %f deg"%results['rot_median'] + print "rotational_error.std %f deg"%results['rot_std'] + print "rotational_error.min %f deg"%results['rot_min'] + print "rotational_error.max %f deg"%results['rot_max'] + else: + print numpy.mean(trans_error) + + if args.plot: + + # tell matplotlib to use latex font + rc('font',**{'family':'serif','serif':['Cardo']}) + rc('text', usetex=True) + + #matplotlib.use('Agg') # no window should appear? + + fig = plt.figure(figsize=(8, 3)) + ax = fig.add_subplot(111) + ax.plot(stamps - stamps[0],trans_error,'-',color="blue") + #ax.plot([t for t,e in err_rot],[e for t,e in err_rot],'-',color="red") + ax.set_xlabel('time [s]') + ax.set_ylabel('translational error [m]') + plt.tight_layout() + plt.savefig(dataset_dir+'/rpe_trans_error.pdf') + plt.show() + + fig = plt.figure(figsize=(8, 3)) + ax = fig.add_subplot(111) + ax.plot(stamps - stamps[0],rot_error* 180.0 / numpy.pi,'-',color="blue") + #ax.plot([t for t,e in err_rot],[e for t,e in err_rot],'-',color="red") + ax.set_xlabel('time [s]') + ax.set_ylabel('rot error [deg]') + plt.tight_layout() + plt.savefig(dataset_dir+'/rpe_rot_error.pdf') + plt.show() \ No newline at end of file diff --git a/svo_analysis/scripts/filter_groundtruth_smooth.py b/svo_analysis/scripts/filter_groundtruth_smooth.py new file mode 100644 index 0000000..d0cc240 --- /dev/null +++ b/svo_analysis/scripts/filter_groundtruth_smooth.py @@ -0,0 +1,60 @@ +#!/usr/bin/python + + +import numpy as np +import matplotlib.pyplot as plt +import transformations +from scipy import signal + +save = True +data_filename = '/home/cforster/Datasets/SlamBenchmark/asl_vicon_d2/groundtruth.txt' +filtered_data_filename = '/home/cforster/Datasets/SlamBenchmark/asl_vicon_d2/groundtruth_filtered.txt' +file = open(data_filename) +data = file.read() +lines = data.replace(","," ").replace("\t"," ").split("\n") +D = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) + +n = np.shape(D)[0] +rpy = np.empty([n,3]) +for i in range(n): + quat = D[i,4:8] + rpy[i,:] = transformations.euler_from_quaternion(quat, axes='sxyz') + +# filter rpy +f_sensor = 200.0; # sampling frequency in hz +f_cut = 15.0; # cutoff frequency in hz +b,a = signal.butter(5,f_cut/(f_sensor/2)); +print a +print b + +rpy_filt = np.empty([n,3]) +rpy_filt[:,0] = signal.filtfilt(b, a, rpy[:,0]) +rpy_filt[:,1] = signal.filtfilt(b, a, rpy[:,1]) +rpy_filt[:,2] = signal.filtfilt(b, a, rpy[:,2]) + +fig = plt.figure() +ax = fig.add_subplot(111, title='orientation filtered') +ax.plot(rpy[:,0], 'r-') +ax.plot(rpy[:,1], 'g-') +ax.plot(rpy[:,2], 'b-') +ax.plot(rpy_filt[:,0], 'k-', linewidth=2) +ax.plot(rpy_filt[:,1], 'k-', linewidth=2) +ax.plot(rpy_filt[:,2], 'k-', linewidth=2) + +fig = plt.figure() +ax = fig.add_subplot(111, title='position') +ax.plot(D[:,1], 'r') +ax.plot(D[:,2], 'g') +ax.plot(D[:,3], 'b') + +fig = plt.figure() +ax = fig.add_subplot(111, title='trajectory from top') +ax.plot(D[:,1], D[:,2]) + +if save: + f = open(filtered_data_filename,'w') + for i in range(np.shape(D)[0]): + quat = transformations.quaternion_from_euler(rpy_filt[i,0], rpy_filt[i,1], rpy_filt[i,2], axes='sxyz') + f.write('%.7f %.5f %.5f %.5f %.5f %.5f %.5f %.5f\n' % (D[i,0], D[i,1], D[i,2], D[i,3], quat[0], quat[1], quat[2], quat[3])) + + f.close() diff --git a/svo_analysis/scripts/hand_eye_calib.py b/svo_analysis/scripts/hand_eye_calib.py new file mode 100644 index 0000000..7a7bb1b --- /dev/null +++ b/svo_analysis/scripts/hand_eye_calib.py @@ -0,0 +1,287 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Aug 4 15:47:55 2013 + +@author: cforster +""" + +import yaml +import numpy as np +import associate +import rotation_utils as ru +import matplotlib.pyplot as plt + +def alignSim3(model, data, n): + + # select the first n datapoints and remove its mean so their center is zero + M = model[0:n,:] + D = data[0:n,:] + + # substract mean + mu_M = M.mean(0) + mu_D = D.mean(0) + M_zerocentered = M - mu_M + D_zerocentered = D - mu_D + + # correlation + C = 1.0/n*np.dot(M_zerocentered.transpose(), D_zerocentered) + sigma2 = 1.0/n*np.multiply(D_zerocentered,D_zerocentered).sum() + U_svd,D_svd,V_svd = np.linalg.linalg.svd(C) + D_svd = np.diag(D_svd) + V_svd = np.transpose(V_svd) + S = np.eye(3) + + if(np.linalg.det(U_svd)*np.linalg.det(V_svd) < 0): + S[2,2] = -1 + + R = np.dot(U_svd, np.dot(S, np.transpose(V_svd))) + s = 1.0/sigma2*np.trace(np.dot(D_svd, S)) + t = mu_M-s*np.dot(R,mu_D) + + return s, R, t + +def matrixLog(A): + theta = np.arccos((np.trace(A)-1.0)/2.0) + log_theta = 0.5*theta/np.sin(theta) * (A - A.transpose()) + x = np.array([log_theta[2,1], log_theta[0,2], log_theta[1,0]]) + return x + +def handEyeCalib(q_gt, q_es, p_gt, p_es, I, delta=10, verbose=True): + ''' Implementation of the least squares solution described in the paper: + Robot Sensor Calibration: Solving AX=XB on the Euclidean Group + by Frank C. Park and Bryan J. Martin + ''' + n = np.shape(I)[0] + M = np.zeros([3,3]) + C = np.zeros([3*n, 3]) + b_A = np.zeros([3*n,1]) + b_B = np.zeros([3*n,1]) + for ix, i in enumerate(I): + A1 = ru.quat2dcm(q_es[i,:]) + A2 = ru.quat2dcm(q_es[i+delta,:]) + A = np.dot(A1.transpose(), A2) + B1 = ru.quat2dcm(q_gt[i,:]) + B2 = ru.quat2dcm(q_gt[i+delta,:]) + B = np.dot(B1.transpose(), B2) + alpha = matrixLog(A) + beta = matrixLog(B) + M = M + np.dot(np.matrix(beta).transpose(), np.matrix(alpha)) + C[3*ix:3*ix+3,:] = np.eye(3) - A + b_A[3*ix:3*ix+3,0] = np.dot(np.transpose(A1), p_es[i+delta,:]-p_es[i,:]) + b_B[3*ix:3*ix+3,0] = np.dot(np.transpose(B1), p_gt[i+delta,:]-p_gt[i,:]) + + # compute rotation + D,V = np.linalg.linalg.eig(np.dot(M.transpose(), M)) + Lambda = np.diag([np.sqrt(1.0/D[0]), np.sqrt(1.0/D[1]), np.sqrt(1.0/D[2])]) + Vinv = np.linalg.linalg.inv(V) + X = np.dot(V, np.dot(Lambda, np.dot(Vinv, M.transpose()))) + + # compute translation + d = np.zeros([3*n,1]) + for i in range(n): + d[3*i:3*i+3,:] = b_A[3*i:3*i+3,:] - np.dot(X, b_B[3*i:3*i+3,:]) + + b = np.dot(np.linalg.inv(np.dot(np.transpose(C),C)), np.dot(np.transpose(C),d)) + + return np.array(X),b + + +# user config +display = True +dataset = '20130906_2149_ptam_i7_asl2' +n_measurements = 1000 +delta = 20 + +# load dataset parameters +dataset_dir = '../results/'+dataset +params_stream = open(dataset_dir+'/params.yaml') +params = yaml.load(params_stream) + +# set trajectory groundtruth and estimate file +traj_groundtruth = params['dataset_directory']+'/groundtruth_filtered.txt' +traj_estimate = dataset_dir+'/traj_estimate.txt' + +# load dataset params +dataset_param_file_stream = open(params['dataset_directory']+'/dataset_params.yaml','r') +dataset_param = yaml.load(dataset_param_file_stream) + +# load data +data_gt = associate.read_file_list(traj_groundtruth) +data_es = associate.read_file_list(traj_estimate) + +# select matches +#offset = -dataset_param['cam_delay'] +offset = -0.03 +matches = associate.associate(data_gt, data_es, offset, 0.02) +#matches = matches[0:470] +p_gt = np.array([[float(value) for value in data_gt[a][0:3]] for a,b in matches]) +q_gt = np.array([[float(value) for value in data_gt[a][3:7]] for a,b in matches]) +p_es = np.array([[float(value) for value in data_es[b][0:3]] for a,b in matches]) +q_es = np.array([[float(value) for value in data_es[b][3:7]] for a,b in matches]) + +# -------------------------------------------------------------------------------- +# align Sim3 to get scale +scale,rot,trans = alignSim3(p_gt, p_es, np.shape(matches)[0]) +p_es = scale*p_es +#p_es = np.transpose(scale*np.dot(rot,np.transpose(p_es)))+trans + +print 's='+str(scale) +#print 't='+str(trans) +#print 'R='+str(rot) + +# plot sim3 aligned trajectory +if display: + fig = plt.figure() + ax = fig.add_subplot(111, aspect='equal') + ax.plot(p_es[:,0], p_es[:,1], 'r-', label='estimate') + ax.plot(p_gt[:,0], p_gt[:,1], 'b-', label='groundtruth') + ax.legend() + +# -------------------------------------------------------------------------------- +# hand-eye-calib + +# select random measurements +I = np.array(rand(n_measurements,1)*(np.shape(matches)[0]-delta), dtype=int)[:,0] +R,b = handEyeCalib(q_gt, q_es, p_gt, p_es, I, delta, True) + +print 'quat = ' + str(ru.dcm2quat(R)) +print 'b = ' + str(b) + +rpy_es = np.zeros([q_es.shape[0]-1, 3]) +rpy_gt = np.zeros([q_gt.shape[0]-1, 3]) +t_gt = np.zeros([q_es.shape[0]-1,3]) +t_es = np.zeros([q_es.shape[0]-1,3]) + +for i in range(delta,np.shape(q_es)[0]): + A1 = ru.quat2dcm(q_es[i-delta,:]) + A2 = ru.quat2dcm(q_es[i,:]) + A = np.dot(A1.transpose(), A2) + B1 = ru.quat2dcm(q_gt[i-delta,:]) + B2 = ru.quat2dcm(q_gt[i,:]) + B = np.dot(B1.transpose(), B2) + B_es = np.dot(np.transpose(R), np.dot(A, R)) + rpy_gt[i-delta,:] = ru.dcm2rpy(B) + rpy_es[i-delta,:] = ru.dcm2rpy(B_es) + t_B = np.dot(np.transpose(B1),(p_gt[i,:]-p_gt[i-delta,:])) + t_A = np.dot(np.transpose(A1),(p_es[i,:]-p_es[i-delta,:])) + t_gt[i-delta,:] = t_B + t_es[i-delta,:] = np.dot(np.transpose(R), np.dot(A,b[:,0]) + t_A - b[:,0]) + +alignment_error = (t_gt-t_es) +error = np.sqrt(np.sum(np.multiply(alignment_error,alignment_error),1)) +I_accurate = np.argwhere(error < np.percentile(error, 90))[:,0] + +if display: + plt.figure() + plt.plot(rpy_es[:,0], 'r-', label='es roll') + plt.plot(rpy_es[:,1], 'g-', label='es pitch') + plt.plot(rpy_es[:,2], 'b-', label='es yaw') + plt.plot(rpy_gt[:,0], 'r--', label='gt roll') + plt.plot(rpy_gt[:,1], 'g--', label='gt pitch') + plt.plot(rpy_gt[:,2], 'b--', label='gt yaw') + plt.legend() + plt.figure() + plt.plot(t_gt[:,0], 'r-', label='gt x') + plt.plot(t_gt[:,1], 'g-', label='gt y') + plt.plot(t_gt[:,2], 'b-', label='gt z') + plt.plot(t_es[:,0], 'r--', label='es x') + plt.plot(t_es[:,1], 'g--', label='es y') + plt.plot(t_es[:,2], 'b--', label='es z') + plt.legend() + plt.figure() + plt.plot(error,'-g') + + +print 'e_rms = ' + str(np.sqrt(np.dot(error,error) / len(error))) +print 'e_mean = ' + str(np.mean(error)) +print 'e_median = ' + str(np.median(error)) +print 'e_std = ' + str(np.std(error)) + + +# now sample again from the filtered list: +N = 10 +display = False +n_acc_meas = I_accurate.size +n_measurements = 500 + +#for i in range(5): +# print '-------------------------------------' +# i0 = np.array(rand(n_measurements,1)*np.shape(I_accurate)[0], dtype=int)[:,0] +# i1 = np.minimum(i0+N, n_acc_meas-1) +# I = np.empty(i0.size*2, dtype=int) +# I[0::2] = I_accurate[i0] +# I[1::2] = I_accurate[i1] +# R,b = handEyeCalib(q_gt[I,:], q_es[I,:], p_gt[I,:], p_es[I,:], True) +# print 'quat = ' + str(ru.dcm2quat(R)) +# print 'b = ' + str(b) +# rpy_es = np.zeros([q_es.shape[0]-1, 3]) +# rpy_gt = np.zeros([q_gt.shape[0]-1, 3]) +# t_gt = np.zeros([q_es.shape[0]-1,3]) +# t_es = np.zeros([q_es.shape[0]-1,3]) +# +# delta = 10 +# for i in range(delta,np.shape(q_es)[0]): +# A1 = ru.quat2dcm(q_es[i-delta,:]) +# A2 = ru.quat2dcm(q_es[i,:]) +# A = np.dot(A1.transpose(), A2) +# B1 = ru.quat2dcm(q_gt[i-delta,:]) +# B2 = ru.quat2dcm(q_gt[i,:]) +# B = np.dot(B1.transpose(), B2) +# B_es = np.dot(np.transpose(R), np.dot(A, R)) +# rpy_gt[i-delta,:] = ru.dcm2rpy(B) +# rpy_es[i-delta,:] = ru.dcm2rpy(B_es) +# t_B = np.dot(np.transpose(B1),(p_gt[i,:]-p_gt[i-delta,:])) +# t_A = np.dot(np.transpose(A1),(p_es[i,:]-p_es[i-delta,:])) +# t_gt[i-delta,:] = t_B +# t_es[i-delta,:] = np.dot(np.transpose(R), np.dot(A,b[:,0]) + t_A - b[:,0]) +# alignment_error = (t_gt-t_es) +# error = np.sqrt(np.sum(np.multiply(alignment_error,alignment_error),1)) +# +# if display: +# plt.figure() +# plt.plot(rpy_es[:,0], 'r-', label='es roll') +# plt.plot(rpy_es[:,1], 'g-', label='es pitch') +# plt.plot(rpy_es[:,2], 'b-', label='es yaw') +# plt.plot(rpy_gt[:,0], 'r--', label='gt roll') +# plt.plot(rpy_gt[:,1], 'g--', label='gt pitch') +# plt.plot(rpy_gt[:,2], 'b--', label='gt yaw') +# plt.legend() +# plt.figure() +# plt.plot(t_gt[:,0], 'r-', label='es x') +# plt.plot(t_gt[:,1], 'g-', label='es y') +# plt.plot(t_gt[:,2], 'b-', label='es z') +# plt.plot(t_es[:,0], 'r--', label='gt x') +# plt.plot(t_es[:,1], 'g--', label='gt y') +# plt.plot(t_es[:,2], 'b--', label='gt z') +# plt.legend() +# plt.figure() +# plt.plot(error,'-g') +# +# print 'e_rms = ' + str(np.sqrt(np.dot(error,error) / len(error))) +# print 'e_mean = ' + str(np.mean(error)) +# print 'e_median = ' + str(np.median(error)) +# print 'e_std = ' + str(np.std(error)) + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/svo_analysis/scripts/rotation_utils.py b/svo_analysis/scripts/rotation_utils.py new file mode 100644 index 0000000..4c7b711 --- /dev/null +++ b/svo_analysis/scripts/rotation_utils.py @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jun 28 10:42:37 2013 + +@author: cforster +""" + +import math +import numpy as np + +# epsilon for testing whether a number is close to zero +_EPS = np.finfo(float).eps * 4.0 + +# axis sequences for Euler angles +_NEXT_AXIS = [1, 2, 0, 1] + +# map axes strings to/from tuples of inner axis, parity, repetition, frame +_AXES2TUPLE = { + 'sxyz': (0, 0, 0, 0), 'sxyx': (0, 0, 1, 0), 'sxzy': (0, 1, 0, 0), + 'sxzx': (0, 1, 1, 0), 'syzx': (1, 0, 0, 0), 'syzy': (1, 0, 1, 0), + 'syxz': (1, 1, 0, 0), 'syxy': (1, 1, 1, 0), 'szxy': (2, 0, 0, 0), + 'szxz': (2, 0, 1, 0), 'szyx': (2, 1, 0, 0), 'szyz': (2, 1, 1, 0), + 'rzyx': (0, 0, 0, 1), 'rxyx': (0, 0, 1, 1), 'ryzx': (0, 1, 0, 1), + 'rxzx': (0, 1, 1, 1), 'rxzy': (1, 0, 0, 1), 'ryzy': (1, 0, 1, 1), + 'rzxy': (1, 1, 0, 1), 'ryxy': (1, 1, 1, 1), 'ryxz': (2, 0, 0, 1), + 'rzxz': (2, 0, 1, 1), 'rxyz': (2, 1, 0, 1), 'rzyz': (2, 1, 1, 1)} + +_TUPLE2AXES = dict((v, k) for k, v in _AXES2TUPLE.items()) + + +def quat2dcm(quaternion): + """Convert Quaternion [x y z w] to Direct Cosine Matrix representation """ + q = np.array(quaternion[:4], dtype=np.float64, copy=True) + nq = np.dot(q, q) + if nq < _EPS: + return np.identity(4) + q *= math.sqrt(2.0 / nq) + q = np.outer(q, q) + return np.array([ [1.0-q[1, 1]-q[2, 2], q[0, 1]-q[2, 3], q[0, 2]+q[1, 3]], + [ q[0, 1]+q[2, 3], 1.0-q[0, 0]-q[2, 2], q[1, 2]-q[0, 3]], + [ q[0, 2]-q[1, 3], q[1, 2]+q[0, 3], 1.0-q[0, 0]-q[1, 1]]], + dtype=np.float64) + +def dcm2quat(matrix): + """Convert Direct Cosine Matrix to Quaternion + + This algorithm comes from "Quaternion Calculus and Fast Animation", + Ken Shoemake, 1987 SIGGRAPH course notes + """ + q = np.empty((4, ), dtype=np.float64) + M = np.array(matrix, dtype=np.float64, copy=False)[:3, :3] + t = np.trace(M) + if (t > 0): + t = math.sqrt(t + 1.0); + q[3] = 0.5*t; + t = 0.5/t; + q[0] = (M[2,1] - M[1,2]) * t; + q[1] = (M[0,2] - M[2,0]) * t; + q[2] = (M[1,0] - M[0,1]) * t; + else: + i = 0; + if (M[1,1] > M[0,0]): + i = 1; + if (M[2,2] > M[i,i]): + i = 2; + j = (i+1)%3; + k = (j+1)%3; + + t = math.sqrt(M[i,i]-M[j,j]-M[k,k] + 1.0); + q[i] = 0.5 * t; + t = 0.5/t; + q[3] = (M[k,j]-M[j,k])*t; + q[j] = (M[j,i]+M[i,j])*t; + q[k] = (M[k,i]+M[i,k])*t; + return q + +def dcm2rpy(matrix, axes='sxyz'): + """Return Euler angles from rotation matrix for specified axis sequence. + + axes : One of 24 axis sequences as string or encoded tuple + + Note that many Euler angle triplets can describe one matrix. + + >>> R0 = euler_matrix(1, 2, 3, 'syxz') + >>> al, be, ga = euler_from_matrix(R0, 'syxz') + >>> R1 = euler_matrix(al, be, ga, 'syxz') + >>> numpy.allclose(R0, R1) + True + >>> angles = (4.0*math.pi) * (numpy.random.random(3) - 0.5) + >>> for axes in _AXES2TUPLE.keys(): + ... R0 = euler_matrix(axes=axes, *angles) + ... R1 = euler_matrix(axes=axes, *euler_from_matrix(R0, axes)) + ... if not numpy.allclose(R0, R1): print axes, "failed" + + """ + try: + firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()] + except (AttributeError, KeyError): + _ = _TUPLE2AXES[axes] + firstaxis, parity, repetition, frame = axes + + i = firstaxis + j = _NEXT_AXIS[i+parity] + k = _NEXT_AXIS[i-parity+1] + + M = np.array(matrix, dtype=np.float64, copy=False)[:3, :3] + if repetition: + sy = math.sqrt(M[i, j]*M[i, j] + M[i, k]*M[i, k]) + if sy > _EPS: + ax = math.atan2( M[i, j], M[i, k]) + ay = math.atan2( sy, M[i, i]) + az = math.atan2( M[j, i], -M[k, i]) + else: + ax = math.atan2(-M[j, k], M[j, j]) + ay = math.atan2( sy, M[i, i]) + az = 0.0 + else: + cy = math.sqrt(M[i, i]*M[i, i] + M[j, i]*M[j, i]) + if cy > _EPS: + ax = math.atan2( M[k, j], M[k, k]) + ay = math.atan2(-M[k, i], cy) + az = math.atan2( M[j, i], M[i, i]) + else: + ax = math.atan2(-M[j, k], M[j, j]) + ay = math.atan2(-M[k, i], cy) + az = 0.0 + + if parity: + ax, ay, az = -ax, -ay, -az + if frame: + ax, az = az, ax + return ax, ay, az + +def quat2rpy(quaternion, axes='sxyz'): + """Return Euler angles from quaternion for specified axis sequence. + + >>> angles = euler_from_quaternion([0.06146124, 0, 0, 0.99810947]) + >>> numpy.allclose(angles, [0.123, 0, 0]) + True + + """ + return dcm2rpy(quat2dcm(quaternion), axes) + diff --git a/svo_analysis/scripts/trajectory_comparison.py b/svo_analysis/scripts/trajectory_comparison.py new file mode 100644 index 0000000..1bc219e --- /dev/null +++ b/svo_analysis/scripts/trajectory_comparison.py @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- + +import numpy as np +import matplotlib.pyplot as plt +import yaml +from matplotlib import rc +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset + + +def plotTrajectory(ax, filename, label, color, linewidth): + file = open(filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + trajectory = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) + ax.plot(trajectory[:,1], trajectory[:,2], label=label, color=color, linewidth=linewidth) + + +if __name__ == '__main__': + + results_dir = '../results' + experiments = ['20130911_2113_nslam_i7_asl2_acc', + '20130911_2229_nslam_i7_asl2_fast', + '20130906_2149_ptam_i7_asl2'] + + # tell matplotlib to use latex font + rc('font',**{'family':'serif','serif':['Cardo']}) + rc('text', usetex=True) + + # ------------------------------------------------------------------------------ + # position error + fig_poserr = plt.figure(figsize=(8,6)) + ax_poserr_x = fig_poserr.add_subplot(311, ylabel='x-error [m]') + ax_poserr_y = fig_poserr.add_subplot(312, ylabel='y-error [m]') + ax_poserr_z = fig_poserr.add_subplot(313, ylabel='z-error [m]', xlabel='time [s]') + + for exp in experiments: + + # load dataset parameters + params_stream = open(results_dir+'/'+exp+'/params.yaml') + params = yaml.load(params_stream) + + # plot translation error + trans_error_filename = results_dir+'/'+exp+'/translation_error.txt' + file = open(trans_error_filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + trans_error = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) + ax_poserr_x.plot(trans_error[:,0], trans_error[:,1], label=params['experiment_label']) + ax_poserr_y.plot(trans_error[:,0], trans_error[:,2]) + ax_poserr_z.plot(trans_error[:,0], trans_error[:,3]) + + ax_poserr_x.set_xlim([0, trans_error[-1,0]+4]) + ax_poserr_y.set_xlim([0, trans_error[-1,0]+4]) + ax_poserr_z.set_xlim([0, trans_error[-1,0]+4]) + ax_poserr_x.legend(bbox_to_anchor=[0, 0], loc='lower left', ncol=3) + ax_poserr_x.grid() + ax_poserr_y.grid() + ax_poserr_z.grid() + fig_poserr.tight_layout() + fig_poserr.savefig('../results/translation_error.pdf') + + # ------------------------------------------------------------------------------ + # orientation error + fig_roterr = plt.figure(figsize=(8,6)) + ax_roterr_r = fig_roterr.add_subplot(311, ylabel='roll-error [rad]') + ax_roterr_p = fig_roterr.add_subplot(312, ylabel='pitch-error [rad]') + ax_roterr_y = fig_roterr.add_subplot(313, ylabel='yaw-error [rad]', xlabel='time [s]') + + for exp in experiments: + + # load dataset parameters + params_stream = open(results_dir+'/'+exp+'/params.yaml') + params = yaml.load(params_stream) + + # plot translation error + rot_error_filename = results_dir+'/'+exp+'/orientation_error.txt' + file = open(rot_error_filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + rot_error = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) + ax_roterr_r.plot(rot_error[:,0], rot_error[:,3], label=params['experiment_label']) + ax_roterr_p.plot(rot_error[:,0], rot_error[:,2]) + ax_roterr_y.plot(rot_error[:,0], rot_error[:,1]) + + ax_roterr_r.set_xlim([0, rot_error[-1,0]+4]) + ax_roterr_p.set_xlim([0, rot_error[-1,0]+4]) + ax_roterr_y.set_xlim([0, rot_error[-1,0]+4]) + ax_roterr_r.legend(bbox_to_anchor=[0, 1], loc='upper left', ncol=3) + ax_roterr_r.grid() + ax_roterr_p.grid() + ax_roterr_y.grid() + fig_roterr.tight_layout() + fig_roterr.savefig('../results/orientation_error.pdf') + + # ------------------------------------------------------------------------------ + # scale error + fig_scale = plt.figure(figsize=(8,2.5)) + ax_scale = fig_scale.add_subplot(111, xlabel='time [s]', ylabel='scale change [\%]') + + for exp in experiments: + + # load dataset parameters + params_stream = open(results_dir+'/'+exp+'/params.yaml') + params = yaml.load(params_stream) + + # plot translation error + scale_drift_filename = results_dir+'/'+exp+'/scale_drift.txt' + file = open(scale_drift_filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + scale_drift = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) + ax_scale.plot(scale_drift[:,0], scale_drift[:,1], label=params['experiment_label']) + + ax_scale.set_xlim([0, rot_error[-1,0]+4]) + ax_scale.legend(bbox_to_anchor=[0, 1], loc='upper left', ncol=3) + ax_scale.grid() + fig_scale.tight_layout() + fig_scale.savefig('../results/scale_drift.pdf') + + # ------------------------------------------------------------------------------ + # trajectory + + + fig_traj = plt.figure(figsize=(8,4.8)) + ax_traj = fig_traj.add_subplot(111, xlabel='x [m]', ylabel='y [m]', aspect='equal', xlim=[-3.1, 4], ylim=[-1.5, 2.6]) + + plotTrajectory(ax_traj, '/home/cforster/Datasets/asl_vicon_d2/groundtruth_filtered.txt', 'Groundtruth', 'k', 1.5) + plotTrajectory(ax_traj, results_dir+'/20130911_2229_nslam_i7_asl2_fast/traj_estimate_rotated.txt', 'Fast', 'g', 1) + plotTrajectory(ax_traj, results_dir+'/20130906_2149_ptam_i7_asl2/traj_estimate_rotated.txt', 'PTAM', 'r', 1) + + # show detail: + axins = zoomed_inset_axes(ax_traj, 5.0, loc=1) # zoom = 6 + plotTrajectory(axins, '/home/cforster/Datasets/asl_vicon_d2/groundtruth_filtered.txt', 'Groundtruth', 'k', 1.5) + plotTrajectory(axins, results_dir+'/20130911_2229_nslam_i7_asl2_fast/traj_estimate_rotated.txt', 'Fast', 'g', 1) + plotTrajectory(axins, results_dir+'/20130906_2149_ptam_i7_asl2/traj_estimate_rotated.txt', 'PTAM', 'r', 1) + axins.set_xlim(1.2, 1.70) + axins.set_ylim(-0.8, -0.3) + axins.patch.set_facecolor('0.9') + plt.xticks(visible=False) + plt.yticks(visible=False) + + mark_inset(ax_traj, axins, loc1=2, loc2=4, fc="none", ec='b') + plt.draw() + plt.show() + ax_traj.legend(bbox_to_anchor=[1, 0], loc='lower right', ncol=3) + ax_traj.grid() + fig_traj.tight_layout() + fig_traj.savefig('../results/trajectory_asl.pdf') + + + # ------------------------------------------------------------------------------ + # number of matches + + # plot number of klt tracked and matched points +# fig = plt.figure(figsize=(8,2)) +# ax = fig.add_subplot(111, xlabel='time [s]', ylabel='no. features', ylim=[0,220]) +# ax.plot(np.arange(len(n_fts_1))/25.0, n_fts_1, 'b-', label='Accurate') +# ax.plot(np.arange(len(n_fts_2))/25.0, n_fts_2, 'g-', label='Fast') +# ax.legend(bbox_to_anchor=[1, 0], loc='lower right', ncol=2) +# fig.tight_layout() +# fig.savefig('../results/number_of_features2.pdf', bbox_inches="tight") +# + + + \ No newline at end of file diff --git a/svo_analysis/scripts/transformations.py b/svo_analysis/scripts/transformations.py new file mode 100644 index 0000000..6d6f19e --- /dev/null +++ b/svo_analysis/scripts/transformations.py @@ -0,0 +1,1705 @@ +# -*- coding: utf-8 -*- +# transformations.py + +# Copyright (c) 2006, Christoph Gohlke +# Copyright (c) 2006-2009, The Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the copyright holders nor the names of any +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +"""Homogeneous Transformation Matrices and Quaternions. + +A library for calculating 4x4 matrices for translating, rotating, reflecting, +scaling, shearing, projecting, orthogonalizing, and superimposing arrays of +3D homogeneous coordinates as well as for converting between rotation matrices, +Euler angles, and quaternions. Also includes an Arcball control object and +functions to decompose transformation matrices. + +:Authors: + `Christoph Gohlke `__, + Laboratory for Fluorescence Dynamics, University of California, Irvine + +:Version: 20090418 + +Requirements +------------ + +* `Python 2.6 `__ +* `Numpy 1.3 `__ +* `transformations.c 20090418 `__ + (optional implementation of some functions in C) + +Notes +----- + +Matrices (M) can be inverted using numpy.linalg.inv(M), concatenated using +numpy.dot(M0, M1), or used to transform homogeneous coordinates (v) using +numpy.dot(M, v) for shape (4, \*) "point of arrays", respectively +numpy.dot(v, M.T) for shape (\*, 4) "array of points". + +Calculations are carried out with numpy.float64 precision. + +This Python implementation is not optimized for speed. + +Vector, point, quaternion, and matrix function arguments are expected to be +"array like", i.e. tuple, list, or numpy arrays. + +Return types are numpy arrays unless specified otherwise. + +Angles are in radians unless specified otherwise. + +Quaternions ix+jy+kz+w are represented as [x, y, z, w]. + +Use the transpose of transformation matrices for OpenGL glMultMatrixd(). + +A triple of Euler angles can be applied/interpreted in 24 ways, which can +be specified using a 4 character string or encoded 4-tuple: + + *Axes 4-string*: e.g. 'sxyz' or 'ryxy' + + - first character : rotations are applied to 's'tatic or 'r'otating frame + - remaining characters : successive rotation axis 'x', 'y', or 'z' + + *Axes 4-tuple*: e.g. (0, 0, 0, 0) or (1, 1, 1, 1) + + - inner axis: code of axis ('x':0, 'y':1, 'z':2) of rightmost matrix. + - parity : even (0) if inner axis 'x' is followed by 'y', 'y' is followed + by 'z', or 'z' is followed by 'x'. Otherwise odd (1). + - repetition : first and last axis are same (1) or different (0). + - frame : rotations are applied to static (0) or rotating (1) frame. + +References +---------- + +(1) Matrices and transformations. Ronald Goldman. + In "Graphics Gems I", pp 472-475. Morgan Kaufmann, 1990. +(2) More matrices and transformations: shear and pseudo-perspective. + Ronald Goldman. In "Graphics Gems II", pp 320-323. Morgan Kaufmann, 1991. +(3) Decomposing a matrix into simple transformations. Spencer Thomas. + In "Graphics Gems II", pp 320-323. Morgan Kaufmann, 1991. +(4) Recovering the data from the transformation matrix. Ronald Goldman. + In "Graphics Gems II", pp 324-331. Morgan Kaufmann, 1991. +(5) Euler angle conversion. Ken Shoemake. + In "Graphics Gems IV", pp 222-229. Morgan Kaufmann, 1994. +(6) Arcball rotation control. Ken Shoemake. + In "Graphics Gems IV", pp 175-192. Morgan Kaufmann, 1994. +(7) Representing attitude: Euler angles, unit quaternions, and rotation + vectors. James Diebel. 2006. +(8) A discussion of the solution for the best rotation to relate two sets + of vectors. W Kabsch. Acta Cryst. 1978. A34, 827-828. +(9) Closed-form solution of absolute orientation using unit quaternions. + BKP Horn. J Opt Soc Am A. 1987. 4(4), 629-642. +(10) Quaternions. Ken Shoemake. + http://www.sfu.ca/~jwa3/cmpt461/files/quatut.pdf +(11) From quaternion to matrix and back. JMP van Waveren. 2005. + http://www.intel.com/cd/ids/developer/asmo-na/eng/293748.htm +(12) Uniform random rotations. Ken Shoemake. + In "Graphics Gems III", pp 124-132. Morgan Kaufmann, 1992. + + +Examples +-------- + +>>> alpha, beta, gamma = 0.123, -1.234, 2.345 +>>> origin, xaxis, yaxis, zaxis = (0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1) +>>> I = identity_matrix() +>>> Rx = rotation_matrix(alpha, xaxis) +>>> Ry = rotation_matrix(beta, yaxis) +>>> Rz = rotation_matrix(gamma, zaxis) +>>> R = concatenate_matrices(Rx, Ry, Rz) +>>> euler = euler_from_matrix(R, 'rxyz') +>>> numpy.allclose([alpha, beta, gamma], euler) +True +>>> Re = euler_matrix(alpha, beta, gamma, 'rxyz') +>>> is_same_transform(R, Re) +True +>>> al, be, ga = euler_from_matrix(Re, 'rxyz') +>>> is_same_transform(Re, euler_matrix(al, be, ga, 'rxyz')) +True +>>> qx = quaternion_about_axis(alpha, xaxis) +>>> qy = quaternion_about_axis(beta, yaxis) +>>> qz = quaternion_about_axis(gamma, zaxis) +>>> q = quaternion_multiply(qx, qy) +>>> q = quaternion_multiply(q, qz) +>>> Rq = quaternion_matrix(q) +>>> is_same_transform(R, Rq) +True +>>> S = scale_matrix(1.23, origin) +>>> T = translation_matrix((1, 2, 3)) +>>> Z = shear_matrix(beta, xaxis, origin, zaxis) +>>> R = random_rotation_matrix(numpy.random.rand(3)) +>>> M = concatenate_matrices(T, R, Z, S) +>>> scale, shear, angles, trans, persp = decompose_matrix(M) +>>> numpy.allclose(scale, 1.23) +True +>>> numpy.allclose(trans, (1, 2, 3)) +True +>>> numpy.allclose(shear, (0, math.tan(beta), 0)) +True +>>> is_same_transform(R, euler_matrix(axes='sxyz', *angles)) +True +>>> M1 = compose_matrix(scale, shear, angles, trans, persp) +>>> is_same_transform(M, M1) +True + +""" + +from __future__ import division + +import warnings +import math + +import numpy + +# Documentation in HTML format can be generated with Epydoc +__docformat__ = "restructuredtext en" + + +def identity_matrix(): + """Return 4x4 identity/unit matrix. + + >>> I = identity_matrix() + >>> numpy.allclose(I, numpy.dot(I, I)) + True + >>> numpy.sum(I), numpy.trace(I) + (4.0, 4.0) + >>> numpy.allclose(I, numpy.identity(4, dtype=numpy.float64)) + True + + """ + return numpy.identity(4, dtype=numpy.float64) + + +def translation_matrix(direction): + """Return matrix to translate by direction vector. + + >>> v = numpy.random.random(3) - 0.5 + >>> numpy.allclose(v, translation_matrix(v)[:3, 3]) + True + + """ + M = numpy.identity(4) + M[:3, 3] = direction[:3] + return M + + +def translation_from_matrix(matrix): + """Return translation vector from translation matrix. + + >>> v0 = numpy.random.random(3) - 0.5 + >>> v1 = translation_from_matrix(translation_matrix(v0)) + >>> numpy.allclose(v0, v1) + True + + """ + return numpy.array(matrix, copy=False)[:3, 3].copy() + + +def reflection_matrix(point, normal): + """Return matrix to mirror at plane defined by point and normal vector. + + >>> v0 = numpy.random.random(4) - 0.5 + >>> v0[3] = 1.0 + >>> v1 = numpy.random.random(3) - 0.5 + >>> R = reflection_matrix(v0, v1) + >>> numpy.allclose(2., numpy.trace(R)) + True + >>> numpy.allclose(v0, numpy.dot(R, v0)) + True + >>> v2 = v0.copy() + >>> v2[:3] += v1 + >>> v3 = v0.copy() + >>> v2[:3] -= v1 + >>> numpy.allclose(v2, numpy.dot(R, v3)) + True + + """ + normal = unit_vector(normal[:3]) + M = numpy.identity(4) + M[:3, :3] -= 2.0 * numpy.outer(normal, normal) + M[:3, 3] = (2.0 * numpy.dot(point[:3], normal)) * normal + return M + + +def reflection_from_matrix(matrix): + """Return mirror plane point and normal vector from reflection matrix. + + >>> v0 = numpy.random.random(3) - 0.5 + >>> v1 = numpy.random.random(3) - 0.5 + >>> M0 = reflection_matrix(v0, v1) + >>> point, normal = reflection_from_matrix(M0) + >>> M1 = reflection_matrix(point, normal) + >>> is_same_transform(M0, M1) + True + + """ + M = numpy.array(matrix, dtype=numpy.float64, copy=False) + # normal: unit eigenvector corresponding to eigenvalue -1 + l, V = numpy.linalg.eig(M[:3, :3]) + i = numpy.where(abs(numpy.real(l) + 1.0) < 1e-8)[0] + if not len(i): + raise ValueError("no unit eigenvector corresponding to eigenvalue -1") + normal = numpy.real(V[:, i[0]]).squeeze() + # point: any unit eigenvector corresponding to eigenvalue 1 + l, V = numpy.linalg.eig(M) + i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] + if not len(i): + raise ValueError("no unit eigenvector corresponding to eigenvalue 1") + point = numpy.real(V[:, i[-1]]).squeeze() + point /= point[3] + return point, normal + + +def rotation_matrix(angle, direction, point=None): + """Return matrix to rotate about axis defined by point and direction. + + >>> angle = (random.random() - 0.5) * (2*math.pi) + >>> direc = numpy.random.random(3) - 0.5 + >>> point = numpy.random.random(3) - 0.5 + >>> R0 = rotation_matrix(angle, direc, point) + >>> R1 = rotation_matrix(angle-2*math.pi, direc, point) + >>> is_same_transform(R0, R1) + True + >>> R0 = rotation_matrix(angle, direc, point) + >>> R1 = rotation_matrix(-angle, -direc, point) + >>> is_same_transform(R0, R1) + True + >>> I = numpy.identity(4, numpy.float64) + >>> numpy.allclose(I, rotation_matrix(math.pi*2, direc)) + True + >>> numpy.allclose(2., numpy.trace(rotation_matrix(math.pi/2, + ... direc, point))) + True + + """ + sina = math.sin(angle) + cosa = math.cos(angle) + direction = unit_vector(direction[:3]) + # rotation matrix around unit vector + R = numpy.array(((cosa, 0.0, 0.0), + (0.0, cosa, 0.0), + (0.0, 0.0, cosa)), dtype=numpy.float64) + R += numpy.outer(direction, direction) * (1.0 - cosa) + direction *= sina + R += numpy.array((( 0.0, -direction[2], direction[1]), + ( direction[2], 0.0, -direction[0]), + (-direction[1], direction[0], 0.0)), + dtype=numpy.float64) + M = numpy.identity(4) + M[:3, :3] = R + if point is not None: + # rotation not around origin + point = numpy.array(point[:3], dtype=numpy.float64, copy=False) + M[:3, 3] = point - numpy.dot(R, point) + return M + + +def rotation_from_matrix(matrix): + """Return rotation angle and axis from rotation matrix. + + >>> angle = (random.random() - 0.5) * (2*math.pi) + >>> direc = numpy.random.random(3) - 0.5 + >>> point = numpy.random.random(3) - 0.5 + >>> R0 = rotation_matrix(angle, direc, point) + >>> angle, direc, point = rotation_from_matrix(R0) + >>> R1 = rotation_matrix(angle, direc, point) + >>> is_same_transform(R0, R1) + True + + """ + R = numpy.array(matrix, dtype=numpy.float64, copy=False) + R33 = R[:3, :3] + # direction: unit eigenvector of R33 corresponding to eigenvalue of 1 + l, W = numpy.linalg.eig(R33.T) + i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] + if not len(i): + raise ValueError("no unit eigenvector corresponding to eigenvalue 1") + direction = numpy.real(W[:, i[-1]]).squeeze() + # point: unit eigenvector of R33 corresponding to eigenvalue of 1 + l, Q = numpy.linalg.eig(R) + i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] + if not len(i): + raise ValueError("no unit eigenvector corresponding to eigenvalue 1") + point = numpy.real(Q[:, i[-1]]).squeeze() + point /= point[3] + # rotation angle depending on direction + cosa = (numpy.trace(R33) - 1.0) / 2.0 + if abs(direction[2]) > 1e-8: + sina = (R[1, 0] + (cosa-1.0)*direction[0]*direction[1]) / direction[2] + elif abs(direction[1]) > 1e-8: + sina = (R[0, 2] + (cosa-1.0)*direction[0]*direction[2]) / direction[1] + else: + sina = (R[2, 1] + (cosa-1.0)*direction[1]*direction[2]) / direction[0] + angle = math.atan2(sina, cosa) + return angle, direction, point + + +def scale_matrix(factor, origin=None, direction=None): + """Return matrix to scale by factor around origin in direction. + + Use factor -1 for point symmetry. + + >>> v = (numpy.random.rand(4, 5) - 0.5) * 20.0 + >>> v[3] = 1.0 + >>> S = scale_matrix(-1.234) + >>> numpy.allclose(numpy.dot(S, v)[:3], -1.234*v[:3]) + True + >>> factor = random.random() * 10 - 5 + >>> origin = numpy.random.random(3) - 0.5 + >>> direct = numpy.random.random(3) - 0.5 + >>> S = scale_matrix(factor, origin) + >>> S = scale_matrix(factor, origin, direct) + + """ + if direction is None: + # uniform scaling + M = numpy.array(((factor, 0.0, 0.0, 0.0), + (0.0, factor, 0.0, 0.0), + (0.0, 0.0, factor, 0.0), + (0.0, 0.0, 0.0, 1.0)), dtype=numpy.float64) + if origin is not None: + M[:3, 3] = origin[:3] + M[:3, 3] *= 1.0 - factor + else: + # nonuniform scaling + direction = unit_vector(direction[:3]) + factor = 1.0 - factor + M = numpy.identity(4) + M[:3, :3] -= factor * numpy.outer(direction, direction) + if origin is not None: + M[:3, 3] = (factor * numpy.dot(origin[:3], direction)) * direction + return M + + +def scale_from_matrix(matrix): + """Return scaling factor, origin and direction from scaling matrix. + + >>> factor = random.random() * 10 - 5 + >>> origin = numpy.random.random(3) - 0.5 + >>> direct = numpy.random.random(3) - 0.5 + >>> S0 = scale_matrix(factor, origin) + >>> factor, origin, direction = scale_from_matrix(S0) + >>> S1 = scale_matrix(factor, origin, direction) + >>> is_same_transform(S0, S1) + True + >>> S0 = scale_matrix(factor, origin, direct) + >>> factor, origin, direction = scale_from_matrix(S0) + >>> S1 = scale_matrix(factor, origin, direction) + >>> is_same_transform(S0, S1) + True + + """ + M = numpy.array(matrix, dtype=numpy.float64, copy=False) + M33 = M[:3, :3] + factor = numpy.trace(M33) - 2.0 + try: + # direction: unit eigenvector corresponding to eigenvalue factor + l, V = numpy.linalg.eig(M33) + i = numpy.where(abs(numpy.real(l) - factor) < 1e-8)[0][0] + direction = numpy.real(V[:, i]).squeeze() + direction /= vector_norm(direction) + except IndexError: + # uniform scaling + factor = (factor + 2.0) / 3.0 + direction = None + # origin: any eigenvector corresponding to eigenvalue 1 + l, V = numpy.linalg.eig(M) + i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] + if not len(i): + raise ValueError("no eigenvector corresponding to eigenvalue 1") + origin = numpy.real(V[:, i[-1]]).squeeze() + origin /= origin[3] + return factor, origin, direction + + +def projection_matrix(point, normal, direction=None, + perspective=None, pseudo=False): + """Return matrix to project onto plane defined by point and normal. + + Using either perspective point, projection direction, or none of both. + + If pseudo is True, perspective projections will preserve relative depth + such that Perspective = dot(Orthogonal, PseudoPerspective). + + >>> P = projection_matrix((0, 0, 0), (1, 0, 0)) + >>> numpy.allclose(P[1:, 1:], numpy.identity(4)[1:, 1:]) + True + >>> point = numpy.random.random(3) - 0.5 + >>> normal = numpy.random.random(3) - 0.5 + >>> direct = numpy.random.random(3) - 0.5 + >>> persp = numpy.random.random(3) - 0.5 + >>> P0 = projection_matrix(point, normal) + >>> P1 = projection_matrix(point, normal, direction=direct) + >>> P2 = projection_matrix(point, normal, perspective=persp) + >>> P3 = projection_matrix(point, normal, perspective=persp, pseudo=True) + >>> is_same_transform(P2, numpy.dot(P0, P3)) + True + >>> P = projection_matrix((3, 0, 0), (1, 1, 0), (1, 0, 0)) + >>> v0 = (numpy.random.rand(4, 5) - 0.5) * 20.0 + >>> v0[3] = 1.0 + >>> v1 = numpy.dot(P, v0) + >>> numpy.allclose(v1[1], v0[1]) + True + >>> numpy.allclose(v1[0], 3.0-v1[1]) + True + + """ + M = numpy.identity(4) + point = numpy.array(point[:3], dtype=numpy.float64, copy=False) + normal = unit_vector(normal[:3]) + if perspective is not None: + # perspective projection + perspective = numpy.array(perspective[:3], dtype=numpy.float64, + copy=False) + M[0, 0] = M[1, 1] = M[2, 2] = numpy.dot(perspective-point, normal) + M[:3, :3] -= numpy.outer(perspective, normal) + if pseudo: + # preserve relative depth + M[:3, :3] -= numpy.outer(normal, normal) + M[:3, 3] = numpy.dot(point, normal) * (perspective+normal) + else: + M[:3, 3] = numpy.dot(point, normal) * perspective + M[3, :3] = -normal + M[3, 3] = numpy.dot(perspective, normal) + elif direction is not None: + # parallel projection + direction = numpy.array(direction[:3], dtype=numpy.float64, copy=False) + scale = numpy.dot(direction, normal) + M[:3, :3] -= numpy.outer(direction, normal) / scale + M[:3, 3] = direction * (numpy.dot(point, normal) / scale) + else: + # orthogonal projection + M[:3, :3] -= numpy.outer(normal, normal) + M[:3, 3] = numpy.dot(point, normal) * normal + return M + + +def projection_from_matrix(matrix, pseudo=False): + """Return projection plane and perspective point from projection matrix. + + Return values are same as arguments for projection_matrix function: + point, normal, direction, perspective, and pseudo. + + >>> point = numpy.random.random(3) - 0.5 + >>> normal = numpy.random.random(3) - 0.5 + >>> direct = numpy.random.random(3) - 0.5 + >>> persp = numpy.random.random(3) - 0.5 + >>> P0 = projection_matrix(point, normal) + >>> result = projection_from_matrix(P0) + >>> P1 = projection_matrix(*result) + >>> is_same_transform(P0, P1) + True + >>> P0 = projection_matrix(point, normal, direct) + >>> result = projection_from_matrix(P0) + >>> P1 = projection_matrix(*result) + >>> is_same_transform(P0, P1) + True + >>> P0 = projection_matrix(point, normal, perspective=persp, pseudo=False) + >>> result = projection_from_matrix(P0, pseudo=False) + >>> P1 = projection_matrix(*result) + >>> is_same_transform(P0, P1) + True + >>> P0 = projection_matrix(point, normal, perspective=persp, pseudo=True) + >>> result = projection_from_matrix(P0, pseudo=True) + >>> P1 = projection_matrix(*result) + >>> is_same_transform(P0, P1) + True + + """ + M = numpy.array(matrix, dtype=numpy.float64, copy=False) + M33 = M[:3, :3] + l, V = numpy.linalg.eig(M) + i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] + if not pseudo and len(i): + # point: any eigenvector corresponding to eigenvalue 1 + point = numpy.real(V[:, i[-1]]).squeeze() + point /= point[3] + # direction: unit eigenvector corresponding to eigenvalue 0 + l, V = numpy.linalg.eig(M33) + i = numpy.where(abs(numpy.real(l)) < 1e-8)[0] + if not len(i): + raise ValueError("no eigenvector corresponding to eigenvalue 0") + direction = numpy.real(V[:, i[0]]).squeeze() + direction /= vector_norm(direction) + # normal: unit eigenvector of M33.T corresponding to eigenvalue 0 + l, V = numpy.linalg.eig(M33.T) + i = numpy.where(abs(numpy.real(l)) < 1e-8)[0] + if len(i): + # parallel projection + normal = numpy.real(V[:, i[0]]).squeeze() + normal /= vector_norm(normal) + return point, normal, direction, None, False + else: + # orthogonal projection, where normal equals direction vector + return point, direction, None, None, False + else: + # perspective projection + i = numpy.where(abs(numpy.real(l)) > 1e-8)[0] + if not len(i): + raise ValueError( + "no eigenvector not corresponding to eigenvalue 0") + point = numpy.real(V[:, i[-1]]).squeeze() + point /= point[3] + normal = - M[3, :3] + perspective = M[:3, 3] / numpy.dot(point[:3], normal) + if pseudo: + perspective -= normal + return point, normal, None, perspective, pseudo + + +def clip_matrix(left, right, bottom, top, near, far, perspective=False): + """Return matrix to obtain normalized device coordinates from frustrum. + + The frustrum bounds are axis-aligned along x (left, right), + y (bottom, top) and z (near, far). + + Normalized device coordinates are in range [-1, 1] if coordinates are + inside the frustrum. + + If perspective is True the frustrum is a truncated pyramid with the + perspective point at origin and direction along z axis, otherwise an + orthographic canonical view volume (a box). + + Homogeneous coordinates transformed by the perspective clip matrix + need to be dehomogenized (devided by w coordinate). + + >>> frustrum = numpy.random.rand(6) + >>> frustrum[1] += frustrum[0] + >>> frustrum[3] += frustrum[2] + >>> frustrum[5] += frustrum[4] + >>> M = clip_matrix(*frustrum, perspective=False) + >>> numpy.dot(M, [frustrum[0], frustrum[2], frustrum[4], 1.0]) + array([-1., -1., -1., 1.]) + >>> numpy.dot(M, [frustrum[1], frustrum[3], frustrum[5], 1.0]) + array([ 1., 1., 1., 1.]) + >>> M = clip_matrix(*frustrum, perspective=True) + >>> v = numpy.dot(M, [frustrum[0], frustrum[2], frustrum[4], 1.0]) + >>> v / v[3] + array([-1., -1., -1., 1.]) + >>> v = numpy.dot(M, [frustrum[1], frustrum[3], frustrum[4], 1.0]) + >>> v / v[3] + array([ 1., 1., -1., 1.]) + + """ + if left >= right or bottom >= top or near >= far: + raise ValueError("invalid frustrum") + if perspective: + if near <= _EPS: + raise ValueError("invalid frustrum: near <= 0") + t = 2.0 * near + M = ((-t/(right-left), 0.0, (right+left)/(right-left), 0.0), + (0.0, -t/(top-bottom), (top+bottom)/(top-bottom), 0.0), + (0.0, 0.0, -(far+near)/(far-near), t*far/(far-near)), + (0.0, 0.0, -1.0, 0.0)) + else: + M = ((2.0/(right-left), 0.0, 0.0, (right+left)/(left-right)), + (0.0, 2.0/(top-bottom), 0.0, (top+bottom)/(bottom-top)), + (0.0, 0.0, 2.0/(far-near), (far+near)/(near-far)), + (0.0, 0.0, 0.0, 1.0)) + return numpy.array(M, dtype=numpy.float64) + + +def shear_matrix(angle, direction, point, normal): + """Return matrix to shear by angle along direction vector on shear plane. + + The shear plane is defined by a point and normal vector. The direction + vector must be orthogonal to the plane's normal vector. + + A point P is transformed by the shear matrix into P" such that + the vector P-P" is parallel to the direction vector and its extent is + given by the angle of P-P'-P", where P' is the orthogonal projection + of P onto the shear plane. + + >>> angle = (random.random() - 0.5) * 4*math.pi + >>> direct = numpy.random.random(3) - 0.5 + >>> point = numpy.random.random(3) - 0.5 + >>> normal = numpy.cross(direct, numpy.random.random(3)) + >>> S = shear_matrix(angle, direct, point, normal) + >>> numpy.allclose(1.0, numpy.linalg.det(S)) + True + + """ + normal = unit_vector(normal[:3]) + direction = unit_vector(direction[:3]) + if abs(numpy.dot(normal, direction)) > 1e-6: + raise ValueError("direction and normal vectors are not orthogonal") + angle = math.tan(angle) + M = numpy.identity(4) + M[:3, :3] += angle * numpy.outer(direction, normal) + M[:3, 3] = -angle * numpy.dot(point[:3], normal) * direction + return M + + +def shear_from_matrix(matrix): + """Return shear angle, direction and plane from shear matrix. + + >>> angle = (random.random() - 0.5) * 4*math.pi + >>> direct = numpy.random.random(3) - 0.5 + >>> point = numpy.random.random(3) - 0.5 + >>> normal = numpy.cross(direct, numpy.random.random(3)) + >>> S0 = shear_matrix(angle, direct, point, normal) + >>> angle, direct, point, normal = shear_from_matrix(S0) + >>> S1 = shear_matrix(angle, direct, point, normal) + >>> is_same_transform(S0, S1) + True + + """ + M = numpy.array(matrix, dtype=numpy.float64, copy=False) + M33 = M[:3, :3] + # normal: cross independent eigenvectors corresponding to the eigenvalue 1 + l, V = numpy.linalg.eig(M33) + i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-4)[0] + if len(i) < 2: + raise ValueError("No two linear independent eigenvectors found %s" % l) + V = numpy.real(V[:, i]).squeeze().T + lenorm = -1.0 + for i0, i1 in ((0, 1), (0, 2), (1, 2)): + n = numpy.cross(V[i0], V[i1]) + l = vector_norm(n) + if l > lenorm: + lenorm = l + normal = n + normal /= lenorm + # direction and angle + direction = numpy.dot(M33 - numpy.identity(3), normal) + angle = vector_norm(direction) + direction /= angle + angle = math.atan(angle) + # point: eigenvector corresponding to eigenvalue 1 + l, V = numpy.linalg.eig(M) + i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] + if not len(i): + raise ValueError("no eigenvector corresponding to eigenvalue 1") + point = numpy.real(V[:, i[-1]]).squeeze() + point /= point[3] + return angle, direction, point, normal + + +def decompose_matrix(matrix): + """Return sequence of transformations from transformation matrix. + + matrix : array_like + Non-degenerative homogeneous transformation matrix + + Return tuple of: + scale : vector of 3 scaling factors + shear : list of shear factors for x-y, x-z, y-z axes + angles : list of Euler angles about static x, y, z axes + translate : translation vector along x, y, z axes + perspective : perspective partition of matrix + + Raise ValueError if matrix is of wrong type or degenerative. + + >>> T0 = translation_matrix((1, 2, 3)) + >>> scale, shear, angles, trans, persp = decompose_matrix(T0) + >>> T1 = translation_matrix(trans) + >>> numpy.allclose(T0, T1) + True + >>> S = scale_matrix(0.123) + >>> scale, shear, angles, trans, persp = decompose_matrix(S) + >>> scale[0] + 0.123 + >>> R0 = euler_matrix(1, 2, 3) + >>> scale, shear, angles, trans, persp = decompose_matrix(R0) + >>> R1 = euler_matrix(*angles) + >>> numpy.allclose(R0, R1) + True + + """ + M = numpy.array(matrix, dtype=numpy.float64, copy=True).T + if abs(M[3, 3]) < _EPS: + raise ValueError("M[3, 3] is zero") + M /= M[3, 3] + P = M.copy() + P[:, 3] = 0, 0, 0, 1 + if not numpy.linalg.det(P): + raise ValueError("Matrix is singular") + + scale = numpy.zeros((3, ), dtype=numpy.float64) + shear = [0, 0, 0] + angles = [0, 0, 0] + + if any(abs(M[:3, 3]) > _EPS): + perspective = numpy.dot(M[:, 3], numpy.linalg.inv(P.T)) + M[:, 3] = 0, 0, 0, 1 + else: + perspective = numpy.array((0, 0, 0, 1), dtype=numpy.float64) + + translate = M[3, :3].copy() + M[3, :3] = 0 + + row = M[:3, :3].copy() + scale[0] = vector_norm(row[0]) + row[0] /= scale[0] + shear[0] = numpy.dot(row[0], row[1]) + row[1] -= row[0] * shear[0] + scale[1] = vector_norm(row[1]) + row[1] /= scale[1] + shear[0] /= scale[1] + shear[1] = numpy.dot(row[0], row[2]) + row[2] -= row[0] * shear[1] + shear[2] = numpy.dot(row[1], row[2]) + row[2] -= row[1] * shear[2] + scale[2] = vector_norm(row[2]) + row[2] /= scale[2] + shear[1:] /= scale[2] + + if numpy.dot(row[0], numpy.cross(row[1], row[2])) < 0: + scale *= -1 + row *= -1 + + angles[1] = math.asin(-row[0, 2]) + if math.cos(angles[1]): + angles[0] = math.atan2(row[1, 2], row[2, 2]) + angles[2] = math.atan2(row[0, 1], row[0, 0]) + else: + #angles[0] = math.atan2(row[1, 0], row[1, 1]) + angles[0] = math.atan2(-row[2, 1], row[1, 1]) + angles[2] = 0.0 + + return scale, shear, angles, translate, perspective + + +def compose_matrix(scale=None, shear=None, angles=None, translate=None, + perspective=None): + """Return transformation matrix from sequence of transformations. + + This is the inverse of the decompose_matrix function. + + Sequence of transformations: + scale : vector of 3 scaling factors + shear : list of shear factors for x-y, x-z, y-z axes + angles : list of Euler angles about static x, y, z axes + translate : translation vector along x, y, z axes + perspective : perspective partition of matrix + + >>> scale = numpy.random.random(3) - 0.5 + >>> shear = numpy.random.random(3) - 0.5 + >>> angles = (numpy.random.random(3) - 0.5) * (2*math.pi) + >>> trans = numpy.random.random(3) - 0.5 + >>> persp = numpy.random.random(4) - 0.5 + >>> M0 = compose_matrix(scale, shear, angles, trans, persp) + >>> result = decompose_matrix(M0) + >>> M1 = compose_matrix(*result) + >>> is_same_transform(M0, M1) + True + + """ + M = numpy.identity(4) + if perspective is not None: + P = numpy.identity(4) + P[3, :] = perspective[:4] + M = numpy.dot(M, P) + if translate is not None: + T = numpy.identity(4) + T[:3, 3] = translate[:3] + M = numpy.dot(M, T) + if angles is not None: + R = euler_matrix(angles[0], angles[1], angles[2], 'sxyz') + M = numpy.dot(M, R) + if shear is not None: + Z = numpy.identity(4) + Z[1, 2] = shear[2] + Z[0, 2] = shear[1] + Z[0, 1] = shear[0] + M = numpy.dot(M, Z) + if scale is not None: + S = numpy.identity(4) + S[0, 0] = scale[0] + S[1, 1] = scale[1] + S[2, 2] = scale[2] + M = numpy.dot(M, S) + M /= M[3, 3] + return M + + +def orthogonalization_matrix(lengths, angles): + """Return orthogonalization matrix for crystallographic cell coordinates. + + Angles are expected in degrees. + + The de-orthogonalization matrix is the inverse. + + >>> O = orthogonalization_matrix((10., 10., 10.), (90., 90., 90.)) + >>> numpy.allclose(O[:3, :3], numpy.identity(3, float) * 10) + True + >>> O = orthogonalization_matrix([9.8, 12.0, 15.5], [87.2, 80.7, 69.7]) + >>> numpy.allclose(numpy.sum(O), 43.063229) + True + + """ + a, b, c = lengths + angles = numpy.radians(angles) + sina, sinb, _ = numpy.sin(angles) + cosa, cosb, cosg = numpy.cos(angles) + co = (cosa * cosb - cosg) / (sina * sinb) + return numpy.array(( + ( a*sinb*math.sqrt(1.0-co*co), 0.0, 0.0, 0.0), + (-a*sinb*co, b*sina, 0.0, 0.0), + ( a*cosb, b*cosa, c, 0.0), + ( 0.0, 0.0, 0.0, 1.0)), + dtype=numpy.float64) + + +def superimposition_matrix(v0, v1, scaling=False, usesvd=True): + """Return matrix to transform given vector set into second vector set. + + v0 and v1 are shape (3, \*) or (4, \*) arrays of at least 3 vectors. + + If usesvd is True, the weighted sum of squared deviations (RMSD) is + minimized according to the algorithm by W. Kabsch [8]. Otherwise the + quaternion based algorithm by B. Horn [9] is used (slower when using + this Python implementation). + + The returned matrix performs rotation, translation and uniform scaling + (if specified). + + >>> v0 = numpy.random.rand(3, 10) + >>> M = superimposition_matrix(v0, v0) + >>> numpy.allclose(M, numpy.identity(4)) + True + >>> R = random_rotation_matrix(numpy.random.random(3)) + >>> v0 = ((1,0,0), (0,1,0), (0,0,1), (1,1,1)) + >>> v1 = numpy.dot(R, v0) + >>> M = superimposition_matrix(v0, v1) + >>> numpy.allclose(v1, numpy.dot(M, v0)) + True + >>> v0 = (numpy.random.rand(4, 100) - 0.5) * 20.0 + >>> v0[3] = 1.0 + >>> v1 = numpy.dot(R, v0) + >>> M = superimposition_matrix(v0, v1) + >>> numpy.allclose(v1, numpy.dot(M, v0)) + True + >>> S = scale_matrix(random.random()) + >>> T = translation_matrix(numpy.random.random(3)-0.5) + >>> M = concatenate_matrices(T, R, S) + >>> v1 = numpy.dot(M, v0) + >>> v0[:3] += numpy.random.normal(0.0, 1e-9, 300).reshape(3, -1) + >>> M = superimposition_matrix(v0, v1, scaling=True) + >>> numpy.allclose(v1, numpy.dot(M, v0)) + True + >>> M = superimposition_matrix(v0, v1, scaling=True, usesvd=False) + >>> numpy.allclose(v1, numpy.dot(M, v0)) + True + >>> v = numpy.empty((4, 100, 3), dtype=numpy.float64) + >>> v[:, :, 0] = v0 + >>> M = superimposition_matrix(v0, v1, scaling=True, usesvd=False) + >>> numpy.allclose(v1, numpy.dot(M, v[:, :, 0])) + True + + """ + v0 = numpy.array(v0, dtype=numpy.float64, copy=False)[:3] + v1 = numpy.array(v1, dtype=numpy.float64, copy=False)[:3] + + if v0.shape != v1.shape or v0.shape[1] < 3: + raise ValueError("Vector sets are of wrong shape or type.") + + # move centroids to origin + t0 = numpy.mean(v0, axis=1) + t1 = numpy.mean(v1, axis=1) + v0 = v0 - t0.reshape(3, 1) + v1 = v1 - t1.reshape(3, 1) + + if usesvd: + # Singular Value Decomposition of covariance matrix + u, s, vh = numpy.linalg.svd(numpy.dot(v1, v0.T)) + # rotation matrix from SVD orthonormal bases + R = numpy.dot(u, vh) + if numpy.linalg.det(R) < 0.0: + # R does not constitute right handed system + R -= numpy.outer(u[:, 2], vh[2, :]*2.0) + s[-1] *= -1.0 + # homogeneous transformation matrix + M = numpy.identity(4) + M[:3, :3] = R + else: + # compute symmetric matrix N + xx, yy, zz = numpy.sum(v0 * v1, axis=1) + xy, yz, zx = numpy.sum(v0 * numpy.roll(v1, -1, axis=0), axis=1) + xz, yx, zy = numpy.sum(v0 * numpy.roll(v1, -2, axis=0), axis=1) + N = ((xx+yy+zz, yz-zy, zx-xz, xy-yx), + (yz-zy, xx-yy-zz, xy+yx, zx+xz), + (zx-xz, xy+yx, -xx+yy-zz, yz+zy), + (xy-yx, zx+xz, yz+zy, -xx-yy+zz)) + # quaternion: eigenvector corresponding to most positive eigenvalue + l, V = numpy.linalg.eig(N) + q = V[:, numpy.argmax(l)] + q /= vector_norm(q) # unit quaternion + q = numpy.roll(q, -1) # move w component to end + # homogeneous transformation matrix + M = quaternion_matrix(q) + + # scale: ratio of rms deviations from centroid + if scaling: + v0 *= v0 + v1 *= v1 + M[:3, :3] *= math.sqrt(numpy.sum(v1) / numpy.sum(v0)) + + # translation + M[:3, 3] = t1 + T = numpy.identity(4) + T[:3, 3] = -t0 + M = numpy.dot(M, T) + return M + + +def euler_matrix(ai, aj, ak, axes='sxyz'): + """Return homogeneous rotation matrix from Euler angles and axis sequence. + + ai, aj, ak : Euler's roll, pitch and yaw angles + axes : One of 24 axis sequences as string or encoded tuple + + >>> R = euler_matrix(1, 2, 3, 'syxz') + >>> numpy.allclose(numpy.sum(R[0]), -1.34786452) + True + >>> R = euler_matrix(1, 2, 3, (0, 1, 0, 1)) + >>> numpy.allclose(numpy.sum(R[0]), -0.383436184) + True + >>> ai, aj, ak = (4.0*math.pi) * (numpy.random.random(3) - 0.5) + >>> for axes in _AXES2TUPLE.keys(): + ... R = euler_matrix(ai, aj, ak, axes) + >>> for axes in _TUPLE2AXES.keys(): + ... R = euler_matrix(ai, aj, ak, axes) + + """ + try: + firstaxis, parity, repetition, frame = _AXES2TUPLE[axes] + except (AttributeError, KeyError): + _ = _TUPLE2AXES[axes] + firstaxis, parity, repetition, frame = axes + + i = firstaxis + j = _NEXT_AXIS[i+parity] + k = _NEXT_AXIS[i-parity+1] + + if frame: + ai, ak = ak, ai + if parity: + ai, aj, ak = -ai, -aj, -ak + + si, sj, sk = math.sin(ai), math.sin(aj), math.sin(ak) + ci, cj, ck = math.cos(ai), math.cos(aj), math.cos(ak) + cc, cs = ci*ck, ci*sk + sc, ss = si*ck, si*sk + + M = numpy.identity(4) + if repetition: + M[i, i] = cj + M[i, j] = sj*si + M[i, k] = sj*ci + M[j, i] = sj*sk + M[j, j] = -cj*ss+cc + M[j, k] = -cj*cs-sc + M[k, i] = -sj*ck + M[k, j] = cj*sc+cs + M[k, k] = cj*cc-ss + else: + M[i, i] = cj*ck + M[i, j] = sj*sc-cs + M[i, k] = sj*cc+ss + M[j, i] = cj*sk + M[j, j] = sj*ss+cc + M[j, k] = sj*cs-sc + M[k, i] = -sj + M[k, j] = cj*si + M[k, k] = cj*ci + return M + + +def euler_from_matrix(matrix, axes='sxyz'): + """Return Euler angles from rotation matrix for specified axis sequence. + + axes : One of 24 axis sequences as string or encoded tuple + + Note that many Euler angle triplets can describe one matrix. + + >>> R0 = euler_matrix(1, 2, 3, 'syxz') + >>> al, be, ga = euler_from_matrix(R0, 'syxz') + >>> R1 = euler_matrix(al, be, ga, 'syxz') + >>> numpy.allclose(R0, R1) + True + >>> angles = (4.0*math.pi) * (numpy.random.random(3) - 0.5) + >>> for axes in _AXES2TUPLE.keys(): + ... R0 = euler_matrix(axes=axes, *angles) + ... R1 = euler_matrix(axes=axes, *euler_from_matrix(R0, axes)) + ... if not numpy.allclose(R0, R1): print axes, "failed" + + """ + try: + firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()] + except (AttributeError, KeyError): + _ = _TUPLE2AXES[axes] + firstaxis, parity, repetition, frame = axes + + i = firstaxis + j = _NEXT_AXIS[i+parity] + k = _NEXT_AXIS[i-parity+1] + + M = numpy.array(matrix, dtype=numpy.float64, copy=False)[:3, :3] + if repetition: + sy = math.sqrt(M[i, j]*M[i, j] + M[i, k]*M[i, k]) + if sy > _EPS: + ax = math.atan2( M[i, j], M[i, k]) + ay = math.atan2( sy, M[i, i]) + az = math.atan2( M[j, i], -M[k, i]) + else: + ax = math.atan2(-M[j, k], M[j, j]) + ay = math.atan2( sy, M[i, i]) + az = 0.0 + else: + cy = math.sqrt(M[i, i]*M[i, i] + M[j, i]*M[j, i]) + if cy > _EPS: + ax = math.atan2( M[k, j], M[k, k]) + ay = math.atan2(-M[k, i], cy) + az = math.atan2( M[j, i], M[i, i]) + else: + ax = math.atan2(-M[j, k], M[j, j]) + ay = math.atan2(-M[k, i], cy) + az = 0.0 + + if parity: + ax, ay, az = -ax, -ay, -az + if frame: + ax, az = az, ax + return ax, ay, az + + +def euler_from_quaternion(quaternion, axes='sxyz'): + """Return Euler angles from quaternion for specified axis sequence. + + >>> angles = euler_from_quaternion([0.06146124, 0, 0, 0.99810947]) + >>> numpy.allclose(angles, [0.123, 0, 0]) + True + + """ + return euler_from_matrix(quaternion_matrix(quaternion), axes) + + +def quaternion_from_euler(ai, aj, ak, axes='sxyz'): + """Return quaternion from Euler angles and axis sequence. + + ai, aj, ak : Euler's roll, pitch and yaw angles + axes : One of 24 axis sequences as string or encoded tuple + + >>> q = quaternion_from_euler(1, 2, 3, 'ryxz') + >>> numpy.allclose(q, [0.310622, -0.718287, 0.444435, 0.435953]) + True + + """ + try: + firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()] + except (AttributeError, KeyError): + _ = _TUPLE2AXES[axes] + firstaxis, parity, repetition, frame = axes + + i = firstaxis + j = _NEXT_AXIS[i+parity] + k = _NEXT_AXIS[i-parity+1] + + if frame: + ai, ak = ak, ai + if parity: + aj = -aj + + ai /= 2.0 + aj /= 2.0 + ak /= 2.0 + ci = math.cos(ai) + si = math.sin(ai) + cj = math.cos(aj) + sj = math.sin(aj) + ck = math.cos(ak) + sk = math.sin(ak) + cc = ci*ck + cs = ci*sk + sc = si*ck + ss = si*sk + + quaternion = numpy.empty((4, ), dtype=numpy.float64) + if repetition: + quaternion[i] = cj*(cs + sc) + quaternion[j] = sj*(cc + ss) + quaternion[k] = sj*(cs - sc) + quaternion[3] = cj*(cc - ss) + else: + quaternion[i] = cj*sc - sj*cs + quaternion[j] = cj*ss + sj*cc + quaternion[k] = cj*cs - sj*sc + quaternion[3] = cj*cc + sj*ss + if parity: + quaternion[j] *= -1 + + return quaternion + + +def quaternion_about_axis(angle, axis): + """Return quaternion for rotation about axis. + + >>> q = quaternion_about_axis(0.123, (1, 0, 0)) + >>> numpy.allclose(q, [0.06146124, 0, 0, 0.99810947]) + True + + """ + quaternion = numpy.zeros((4, ), dtype=numpy.float64) + quaternion[:3] = axis[:3] + qlen = vector_norm(quaternion) + if qlen > _EPS: + quaternion *= math.sin(angle/2.0) / qlen + quaternion[3] = math.cos(angle/2.0) + return quaternion + + +def quaternion_matrix(quaternion): + """Return homogeneous rotation matrix from quaternion. + + >>> R = quaternion_matrix([0.06146124, 0, 0, 0.99810947]) + >>> numpy.allclose(R, rotation_matrix(0.123, (1, 0, 0))) + True + + """ + q = numpy.array(quaternion[:4], dtype=numpy.float64, copy=True) + nq = numpy.dot(q, q) + if nq < _EPS: + return numpy.identity(4) + q *= math.sqrt(2.0 / nq) + q = numpy.outer(q, q) + return numpy.array(( + (1.0-q[1, 1]-q[2, 2], q[0, 1]-q[2, 3], q[0, 2]+q[1, 3], 0.0), + ( q[0, 1]+q[2, 3], 1.0-q[0, 0]-q[2, 2], q[1, 2]-q[0, 3], 0.0), + ( q[0, 2]-q[1, 3], q[1, 2]+q[0, 3], 1.0-q[0, 0]-q[1, 1], 0.0), + ( 0.0, 0.0, 0.0, 1.0) + ), dtype=numpy.float64) + + +def quaternion_from_matrix(matrix): + """Return quaternion from rotation matrix. + + >>> R = rotation_matrix(0.123, (1, 2, 3)) + >>> q = quaternion_from_matrix(R) + >>> numpy.allclose(q, [0.0164262, 0.0328524, 0.0492786, 0.9981095]) + True + + """ + q = numpy.empty((4, ), dtype=numpy.float64) + M = numpy.array(matrix, dtype=numpy.float64, copy=False)[:4, :4] + t = numpy.trace(M) + if t > M[3, 3]: + q[3] = t + q[2] = M[1, 0] - M[0, 1] + q[1] = M[0, 2] - M[2, 0] + q[0] = M[2, 1] - M[1, 2] + else: + i, j, k = 0, 1, 2 + if M[1, 1] > M[0, 0]: + i, j, k = 1, 2, 0 + if M[2, 2] > M[i, i]: + i, j, k = 2, 0, 1 + t = M[i, i] - (M[j, j] + M[k, k]) + M[3, 3] + q[i] = t + q[j] = M[i, j] + M[j, i] + q[k] = M[k, i] + M[i, k] + q[3] = M[k, j] - M[j, k] + q *= 0.5 / math.sqrt(t * M[3, 3]) + return q + + +def quaternion_multiply(quaternion1, quaternion0): + """Return multiplication of two quaternions. + + >>> q = quaternion_multiply([1, -2, 3, 4], [-5, 6, 7, 8]) + >>> numpy.allclose(q, [-44, -14, 48, 28]) + True + + """ + x0, y0, z0, w0 = quaternion0 + x1, y1, z1, w1 = quaternion1 + return numpy.array(( + x1*w0 + y1*z0 - z1*y0 + w1*x0, + -x1*z0 + y1*w0 + z1*x0 + w1*y0, + x1*y0 - y1*x0 + z1*w0 + w1*z0, + -x1*x0 - y1*y0 - z1*z0 + w1*w0), dtype=numpy.float64) + + +def quaternion_conjugate(quaternion): + """Return conjugate of quaternion. + + >>> q0 = random_quaternion() + >>> q1 = quaternion_conjugate(q0) + >>> q1[3] == q0[3] and all(q1[:3] == -q0[:3]) + True + + """ + return numpy.array((-quaternion[0], -quaternion[1], + -quaternion[2], quaternion[3]), dtype=numpy.float64) + + +def quaternion_inverse(quaternion): + """Return inverse of quaternion. + + >>> q0 = random_quaternion() + >>> q1 = quaternion_inverse(q0) + >>> numpy.allclose(quaternion_multiply(q0, q1), [0, 0, 0, 1]) + True + + """ + return quaternion_conjugate(quaternion) / numpy.dot(quaternion, quaternion) + + +def quaternion_slerp(quat0, quat1, fraction, spin=0, shortestpath=True): + """Return spherical linear interpolation between two quaternions. + + >>> q0 = random_quaternion() + >>> q1 = random_quaternion() + >>> q = quaternion_slerp(q0, q1, 0.0) + >>> numpy.allclose(q, q0) + True + >>> q = quaternion_slerp(q0, q1, 1.0, 1) + >>> numpy.allclose(q, q1) + True + >>> q = quaternion_slerp(q0, q1, 0.5) + >>> angle = math.acos(numpy.dot(q0, q)) + >>> numpy.allclose(2.0, math.acos(numpy.dot(q0, q1)) / angle) or \ + numpy.allclose(2.0, math.acos(-numpy.dot(q0, q1)) / angle) + True + + """ + q0 = unit_vector(quat0[:4]) + q1 = unit_vector(quat1[:4]) + if fraction == 0.0: + return q0 + elif fraction == 1.0: + return q1 + d = numpy.dot(q0, q1) + if abs(abs(d) - 1.0) < _EPS: + return q0 + if shortestpath and d < 0.0: + # invert rotation + d = -d + q1 *= -1.0 + angle = math.acos(d) + spin * math.pi + if abs(angle) < _EPS: + return q0 + isin = 1.0 / math.sin(angle) + q0 *= math.sin((1.0 - fraction) * angle) * isin + q1 *= math.sin(fraction * angle) * isin + q0 += q1 + return q0 + + +def random_quaternion(rand=None): + """Return uniform random unit quaternion. + + rand: array like or None + Three independent random variables that are uniformly distributed + between 0 and 1. + + >>> q = random_quaternion() + >>> numpy.allclose(1.0, vector_norm(q)) + True + >>> q = random_quaternion(numpy.random.random(3)) + >>> q.shape + (4,) + + """ + if rand is None: + rand = numpy.random.rand(3) + else: + assert len(rand) == 3 + r1 = numpy.sqrt(1.0 - rand[0]) + r2 = numpy.sqrt(rand[0]) + pi2 = math.pi * 2.0 + t1 = pi2 * rand[1] + t2 = pi2 * rand[2] + return numpy.array((numpy.sin(t1)*r1, + numpy.cos(t1)*r1, + numpy.sin(t2)*r2, + numpy.cos(t2)*r2), dtype=numpy.float64) + + +def random_rotation_matrix(rand=None): + """Return uniform random rotation matrix. + + rnd: array like + Three independent random variables that are uniformly distributed + between 0 and 1 for each returned quaternion. + + >>> R = random_rotation_matrix() + >>> numpy.allclose(numpy.dot(R.T, R), numpy.identity(4)) + True + + """ + return quaternion_matrix(random_quaternion(rand)) + + +class Arcball(object): + """Virtual Trackball Control. + + >>> ball = Arcball() + >>> ball = Arcball(initial=numpy.identity(4)) + >>> ball.place([320, 320], 320) + >>> ball.down([500, 250]) + >>> ball.drag([475, 275]) + >>> R = ball.matrix() + >>> numpy.allclose(numpy.sum(R), 3.90583455) + True + >>> ball = Arcball(initial=[0, 0, 0, 1]) + >>> ball.place([320, 320], 320) + >>> ball.setaxes([1,1,0], [-1, 1, 0]) + >>> ball.setconstrain(True) + >>> ball.down([400, 200]) + >>> ball.drag([200, 400]) + >>> R = ball.matrix() + >>> numpy.allclose(numpy.sum(R), 0.2055924) + True + >>> ball.next() + + """ + + def __init__(self, initial=None): + """Initialize virtual trackball control. + + initial : quaternion or rotation matrix + + """ + self._axis = None + self._axes = None + self._radius = 1.0 + self._center = [0.0, 0.0] + self._vdown = numpy.array([0, 0, 1], dtype=numpy.float64) + self._constrain = False + + if initial is None: + self._qdown = numpy.array([0, 0, 0, 1], dtype=numpy.float64) + else: + initial = numpy.array(initial, dtype=numpy.float64) + if initial.shape == (4, 4): + self._qdown = quaternion_from_matrix(initial) + elif initial.shape == (4, ): + initial /= vector_norm(initial) + self._qdown = initial + else: + raise ValueError("initial not a quaternion or matrix.") + + self._qnow = self._qpre = self._qdown + + def place(self, center, radius): + """Place Arcball, e.g. when window size changes. + + center : sequence[2] + Window coordinates of trackball center. + radius : float + Radius of trackball in window coordinates. + + """ + self._radius = float(radius) + self._center[0] = center[0] + self._center[1] = center[1] + + def setaxes(self, *axes): + """Set axes to constrain rotations.""" + if axes is None: + self._axes = None + else: + self._axes = [unit_vector(axis) for axis in axes] + + def setconstrain(self, constrain): + """Set state of constrain to axis mode.""" + self._constrain = constrain == True + + def getconstrain(self): + """Return state of constrain to axis mode.""" + return self._constrain + + def down(self, point): + """Set initial cursor window coordinates and pick constrain-axis.""" + self._vdown = arcball_map_to_sphere(point, self._center, self._radius) + self._qdown = self._qpre = self._qnow + + if self._constrain and self._axes is not None: + self._axis = arcball_nearest_axis(self._vdown, self._axes) + self._vdown = arcball_constrain_to_axis(self._vdown, self._axis) + else: + self._axis = None + + def drag(self, point): + """Update current cursor window coordinates.""" + vnow = arcball_map_to_sphere(point, self._center, self._radius) + + if self._axis is not None: + vnow = arcball_constrain_to_axis(vnow, self._axis) + + self._qpre = self._qnow + + t = numpy.cross(self._vdown, vnow) + if numpy.dot(t, t) < _EPS: + self._qnow = self._qdown + else: + q = [t[0], t[1], t[2], numpy.dot(self._vdown, vnow)] + self._qnow = quaternion_multiply(q, self._qdown) + + def next(self, acceleration=0.0): + """Continue rotation in direction of last drag.""" + q = quaternion_slerp(self._qpre, self._qnow, 2.0+acceleration, False) + self._qpre, self._qnow = self._qnow, q + + def matrix(self): + """Return homogeneous rotation matrix.""" + return quaternion_matrix(self._qnow) + + +def arcball_map_to_sphere(point, center, radius): + """Return unit sphere coordinates from window coordinates.""" + v = numpy.array(((point[0] - center[0]) / radius, + (center[1] - point[1]) / radius, + 0.0), dtype=numpy.float64) + n = v[0]*v[0] + v[1]*v[1] + if n > 1.0: + v /= math.sqrt(n) # position outside of sphere + else: + v[2] = math.sqrt(1.0 - n) + return v + + +def arcball_constrain_to_axis(point, axis): + """Return sphere point perpendicular to axis.""" + v = numpy.array(point, dtype=numpy.float64, copy=True) + a = numpy.array(axis, dtype=numpy.float64, copy=True) + v -= a * numpy.dot(a, v) # on plane + n = vector_norm(v) + if n > _EPS: + if v[2] < 0.0: + v *= -1.0 + v /= n + return v + if a[2] == 1.0: + return numpy.array([1, 0, 0], dtype=numpy.float64) + return unit_vector([-a[1], a[0], 0]) + + +def arcball_nearest_axis(point, axes): + """Return axis, which arc is nearest to point.""" + point = numpy.array(point, dtype=numpy.float64, copy=False) + nearest = None + mx = -1.0 + for axis in axes: + t = numpy.dot(arcball_constrain_to_axis(point, axis), point) + if t > mx: + nearest = axis + mx = t + return nearest + + +# epsilon for testing whether a number is close to zero +_EPS = numpy.finfo(float).eps * 4.0 + +# axis sequences for Euler angles +_NEXT_AXIS = [1, 2, 0, 1] + +# map axes strings to/from tuples of inner axis, parity, repetition, frame +_AXES2TUPLE = { + 'sxyz': (0, 0, 0, 0), 'sxyx': (0, 0, 1, 0), 'sxzy': (0, 1, 0, 0), + 'sxzx': (0, 1, 1, 0), 'syzx': (1, 0, 0, 0), 'syzy': (1, 0, 1, 0), + 'syxz': (1, 1, 0, 0), 'syxy': (1, 1, 1, 0), 'szxy': (2, 0, 0, 0), + 'szxz': (2, 0, 1, 0), 'szyx': (2, 1, 0, 0), 'szyz': (2, 1, 1, 0), + 'rzyx': (0, 0, 0, 1), 'rxyx': (0, 0, 1, 1), 'ryzx': (0, 1, 0, 1), + 'rxzx': (0, 1, 1, 1), 'rxzy': (1, 0, 0, 1), 'ryzy': (1, 0, 1, 1), + 'rzxy': (1, 1, 0, 1), 'ryxy': (1, 1, 1, 1), 'ryxz': (2, 0, 0, 1), + 'rzxz': (2, 0, 1, 1), 'rxyz': (2, 1, 0, 1), 'rzyz': (2, 1, 1, 1)} + +_TUPLE2AXES = dict((v, k) for k, v in _AXES2TUPLE.items()) + +# helper functions + +def vector_norm(data, axis=None, out=None): + """Return length, i.e. eucledian norm, of ndarray along axis. + + >>> v = numpy.random.random(3) + >>> n = vector_norm(v) + >>> numpy.allclose(n, numpy.linalg.norm(v)) + True + >>> v = numpy.random.rand(6, 5, 3) + >>> n = vector_norm(v, axis=-1) + >>> numpy.allclose(n, numpy.sqrt(numpy.sum(v*v, axis=2))) + True + >>> n = vector_norm(v, axis=1) + >>> numpy.allclose(n, numpy.sqrt(numpy.sum(v*v, axis=1))) + True + >>> v = numpy.random.rand(5, 4, 3) + >>> n = numpy.empty((5, 3), dtype=numpy.float64) + >>> vector_norm(v, axis=1, out=n) + >>> numpy.allclose(n, numpy.sqrt(numpy.sum(v*v, axis=1))) + True + >>> vector_norm([]) + 0.0 + >>> vector_norm([1.0]) + 1.0 + + """ + data = numpy.array(data, dtype=numpy.float64, copy=True) + if out is None: + if data.ndim == 1: + return math.sqrt(numpy.dot(data, data)) + data *= data + out = numpy.atleast_1d(numpy.sum(data, axis=axis)) + numpy.sqrt(out, out) + return out + else: + data *= data + numpy.sum(data, axis=axis, out=out) + numpy.sqrt(out, out) + + +def unit_vector(data, axis=None, out=None): + """Return ndarray normalized by length, i.e. eucledian norm, along axis. + + >>> v0 = numpy.random.random(3) + >>> v1 = unit_vector(v0) + >>> numpy.allclose(v1, v0 / numpy.linalg.norm(v0)) + True + >>> v0 = numpy.random.rand(5, 4, 3) + >>> v1 = unit_vector(v0, axis=-1) + >>> v2 = v0 / numpy.expand_dims(numpy.sqrt(numpy.sum(v0*v0, axis=2)), 2) + >>> numpy.allclose(v1, v2) + True + >>> v1 = unit_vector(v0, axis=1) + >>> v2 = v0 / numpy.expand_dims(numpy.sqrt(numpy.sum(v0*v0, axis=1)), 1) + >>> numpy.allclose(v1, v2) + True + >>> v1 = numpy.empty((5, 4, 3), dtype=numpy.float64) + >>> unit_vector(v0, axis=1, out=v1) + >>> numpy.allclose(v1, v2) + True + >>> list(unit_vector([])) + [] + >>> list(unit_vector([1.0])) + [1.0] + + """ + if out is None: + data = numpy.array(data, dtype=numpy.float64, copy=True) + if data.ndim == 1: + data /= math.sqrt(numpy.dot(data, data)) + return data + else: + if out is not data: + out[:] = numpy.array(data, copy=False) + data = out + length = numpy.atleast_1d(numpy.sum(data*data, axis)) + numpy.sqrt(length, length) + if axis is not None: + length = numpy.expand_dims(length, axis) + data /= length + if out is None: + return data + + +def random_vector(size): + """Return array of random doubles in the half-open interval [0.0, 1.0). + + >>> v = random_vector(10000) + >>> numpy.all(v >= 0.0) and numpy.all(v < 1.0) + True + >>> v0 = random_vector(10) + >>> v1 = random_vector(10) + >>> numpy.any(v0 == v1) + False + + """ + return numpy.random.random(size) + + +def inverse_matrix(matrix): + """Return inverse of square transformation matrix. + + >>> M0 = random_rotation_matrix() + >>> M1 = inverse_matrix(M0.T) + >>> numpy.allclose(M1, numpy.linalg.inv(M0.T)) + True + >>> for size in range(1, 7): + ... M0 = numpy.random.rand(size, size) + ... M1 = inverse_matrix(M0) + ... if not numpy.allclose(M1, numpy.linalg.inv(M0)): print size + + """ + return numpy.linalg.inv(matrix) + + +def concatenate_matrices(*matrices): + """Return concatenation of series of transformation matrices. + + >>> M = numpy.random.rand(16).reshape((4, 4)) - 0.5 + >>> numpy.allclose(M, concatenate_matrices(M)) + True + >>> numpy.allclose(numpy.dot(M, M.T), concatenate_matrices(M, M.T)) + True + + """ + M = numpy.identity(4) + for i in matrices: + M = numpy.dot(M, i) + return M + + +def is_same_transform(matrix0, matrix1): + """Return True if two matrices perform same transformation. + + >>> is_same_transform(numpy.identity(4), numpy.identity(4)) + True + >>> is_same_transform(numpy.identity(4), random_rotation_matrix()) + False + + """ + matrix0 = numpy.array(matrix0, dtype=numpy.float64, copy=True) + matrix0 /= matrix0[3, 3] + matrix1 = numpy.array(matrix1, dtype=numpy.float64, copy=True) + matrix1 /= matrix1[3, 3] + return numpy.allclose(matrix0, matrix1) + + +def _import_module(module_name, warn=True, prefix='_py_', ignore='_'): + """Try import all public attributes from module into global namespace. + + Existing attributes with name clashes are renamed with prefix. + Attributes starting with underscore are ignored by default. + + Return True on successful import. + + """ + try: + module = __import__(module_name) + except ImportError: + if warn: + warnings.warn("Failed to import module " + module_name) + else: + for attr in dir(module): + if ignore and attr.startswith(ignore): + continue + if prefix: + if attr in globals(): + globals()[prefix + attr] = globals()[attr] + elif warn: + warnings.warn("No Python implementation of " + attr) + globals()[attr] = getattr(module, attr) + return True diff --git a/svo_msgs/CMakeLists.txt b/svo_msgs/CMakeLists.txt new file mode 100644 index 0000000..23d4e3b --- /dev/null +++ b/svo_msgs/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 2.8.3) +project(svo_msgs) + +# search for everything we need to build the messages, dont forget the message_generation +find_package(catkin REQUIRED COMPONENTS + message_generation + geometry_msgs + sensor_msgs +) + +# search for all msg files +FILE(GLOB messages_to_build RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/msg" + "${CMAKE_CURRENT_SOURCE_DIR}/msg/*.msg") + +# notify catkin to look at the previously found msg files +add_message_files( + FILES + ${messages_to_build} +) + +# build the header files from the msg files, and notify catkin about the dependencies +generate_messages( + DEPENDENCIES + geometry_msgs + sensor_msgs +) + +# export the dependencis of this package for who ever depends on us +catkin_package( + CATKIN_DEPENDS message_runtime geometry_msgs +) + +include_directories( + ${catkin_INCLUDE_DIRS} +) \ No newline at end of file diff --git a/svo_msgs/msg/DenseInput.msg b/svo_msgs/msg/DenseInput.msg new file mode 100644 index 0000000..d36dee8 --- /dev/null +++ b/svo_msgs/msg/DenseInput.msg @@ -0,0 +1,6 @@ +Header header +uint32 frame_id +geometry_msgs/Pose pose +sensor_msgs/Image image +float32 min_depth +float32 max_depth \ No newline at end of file diff --git a/svo_msgs/msg/Feature.msg b/svo_msgs/msg/Feature.msg new file mode 100644 index 0000000..2972c32 --- /dev/null +++ b/svo_msgs/msg/Feature.msg @@ -0,0 +1,5 @@ +float32 u +float32 v +float32 x +float32 y +float32 z \ No newline at end of file diff --git a/svo_msgs/msg/Info.msg b/svo_msgs/msg/Info.msg new file mode 100644 index 0000000..b962e1b --- /dev/null +++ b/svo_msgs/msg/Info.msg @@ -0,0 +1,6 @@ +Header header +float32 processing_time +int32[] keyframes +int32 num_matches +int32 tracking_quality +int32 stage \ No newline at end of file diff --git a/svo_msgs/msg/NbvTrajectory.msg b/svo_msgs/msg/NbvTrajectory.msg new file mode 100644 index 0000000..03f0792 --- /dev/null +++ b/svo_msgs/msg/NbvTrajectory.msg @@ -0,0 +1,2 @@ +Header header +geometry_msgs/Pose[] trajectory \ No newline at end of file diff --git a/svo_msgs/package.xml b/svo_msgs/package.xml new file mode 100644 index 0000000..b122e2d --- /dev/null +++ b/svo_msgs/package.xml @@ -0,0 +1,19 @@ + + + svo_msgs + 0.0.0 + Custom messages for svo + Christian Forster + BSD + catkin + + message_generation + geometry_msgs + sensor_msgs + + message_runtime + geometry_msgs + sensor_msgs + + + \ No newline at end of file diff --git a/svo_ros/CMakeLists.txt b/svo_ros/CMakeLists.txt new file mode 100644 index 0000000..8fcd739 --- /dev/null +++ b/svo_ros/CMakeLists.txt @@ -0,0 +1,62 @@ +SET(PROJECT_NAME svo_ros) +PROJECT(${PROJECT_NAME}) +CMAKE_MINIMUM_REQUIRED (VERSION 2.8.3) +SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo +SET(CMAKE_VERBOSE_MAKEFILE OFF) +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") + +IF(CMAKE_COMPILER_IS_GNUCC) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +ELSE() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +ENDIF() + + +# Add catkin and required ROS packages +FIND_PACKAGE(catkin REQUIRED COMPONENTS + roscpp nav_msgs std_msgs visualization_msgs sensor_msgs image_transport cv_bridge tf svo svo_msgs vikit_common vikit_ros +) + +# Add plain cmake packages +FIND_PACKAGE(OpenCV REQUIRED) +FIND_PACKAGE(Eigen REQUIRED) +FIND_PACKAGE(Sophus REQUIRED) +FIND_PACKAGE(Boost REQUIRED COMPONENTS thread signals) + +# Describe catkin Project +catkin_package( + DEPENDS Eigen OpenCV Sophus Boost + CATKIN_DEPENDS roscpp nav_msgs std_msgs visualization_msgs sensor_msgs image_transport cv_bridge tf svo svo_msgs vikit_common vikit_ros + INCLUDE_DIRS include + LIBRARIES svo_visualizer +) + +# Include dirs +INCLUDE_DIRECTORIES( + include + ${Eigen_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${Sophus_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${catkin_INCLUDE_DIRS} +) + +# Set link libraries +LIST(APPEND LINK_LIBS + ${OpenCV_LIBRARIES} + ${Sophus_LIBRARIES} + ${Boost_LIBRARIES} + ${catkin_LIBRARIES} +) + +# Create visualizer library +ADD_LIBRARY(svo_visualizer src/visualizer.cpp) +TARGET_LINK_LIBRARIES(svo_visualizer ${LINK_LIBS}) + +# Create Executables +ADD_EXECUTABLE(vo src/vo_node.cpp) +TARGET_LINK_LIBRARIES(vo svo_visualizer) +ADD_EXECUTABLE(benchmark src/benchmark_node.cpp) +TARGET_LINK_LIBRARIES(benchmark svo_visualizer) +ADD_EXECUTABLE(remote src/remote_node.cpp) +TARGET_LINK_LIBRARIES(remote svo_visualizer) \ No newline at end of file diff --git a/svo_ros/include/svo_ros/dataset_img.h b/svo_ros/include/svo_ros/dataset_img.h new file mode 100644 index 0000000..2d78ef7 --- /dev/null +++ b/svo_ros/include/svo_ros/dataset_img.h @@ -0,0 +1,62 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef DATASET_IMG_H +#define DATASET_IMG_H + +namespace FileType { + +#include +#include +#include + +using ::Eigen::Quaterniond; +using ::Eigen::Vector3d; + +/// Specification of Dataset which contains: Camera Image, Gyroscope Rotation +class DatasetImg +{ +public: + DatasetImg() {} + virtual ~DatasetImg() {} + + double stamp_; + std::string imgname_; + + friend std::ostream& operator <<(std::ostream& out, const DatasetImg& pair); + friend std::istream& operator >>(std::istream& in, DatasetImg& pair); +}; + +std::ostream& operator <<(std::ostream& out, const DatasetImg& gt) +{ + out + << gt.stamp_ << " " + << gt.imgname_ << " " + << std::endl; + return out; +} + +std::istream& operator >>(std::istream& in, DatasetImg& gt) +{ + in >> gt.stamp_; + in >> gt.imgname_; + return in; +} + +} // end namespace FileType + + +#endif /* DATASET_IMG_H */ diff --git a/svo_ros/include/svo_ros/dataset_imu.h b/svo_ros/include/svo_ros/dataset_imu.h new file mode 100644 index 0000000..9ee5e66 --- /dev/null +++ b/svo_ros/include/svo_ros/dataset_imu.h @@ -0,0 +1,70 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef DATASET_IMU_H_ +#define DATASET_IMU_H_ + +namespace FileType { + +#include +#include +#include + +using ::Eigen::Quaterniond; +using ::Eigen::Vector3d; + +/// Specification of Dataset which contains: Camera Image, Gyroscope Rotation +class DatasetImu +{ +public: + DatasetImu() {} + virtual ~DatasetImu() {} + + double stamp_; + Quaterniond q_imu_; + + friend std::ostream& operator <<(std::ostream& out, const DatasetImu& pair); + friend std::istream& operator >>(std::istream& in, DatasetImu& pair); +}; + +std::ostream& operator <<(std::ostream& out, const DatasetImu& gt) +{ + out + << gt.stamp_ << " " + << gt.q_imu_.x() << " " + << gt.q_imu_.y() << " " + << gt.q_imu_.z() << " " + << gt.q_imu_.w() << " " + << std::endl; + return out; +} + +std::istream& operator >>(std::istream& in, DatasetImu& gt) +{ + in >> gt.stamp_; + double x,y,z,w; + in >> x; + in >> y; + in >> z; + in >> w; + gt.q_imu_ = Quaterniond(w, x, y, z); + return in; +} + +} // end namespace FileType + + +#endif /* DATASET_IMU_H_ */ diff --git a/svo_ros/include/svo_ros/visualizer.h b/svo_ros/include/svo_ros/visualizer.h new file mode 100644 index 0000000..1a7df1f --- /dev/null +++ b/svo_ros/include/svo_ros/visualizer.h @@ -0,0 +1,75 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_VISUALIZER_H_ +#define SVO_VISUALIZER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +class Frame; +class Point; +class Map; +class FrameHandlerMono; + +typedef boost::shared_ptr FramePtr; + +/// This class bundles all functions to publish visualisation messages, +/// trace data and output debugging information. +class Visualizer +{ +public: + ros::NodeHandle pnh_; + size_t trace_id_; + size_t img_pub_level_; + size_t img_pub_nth_; + size_t dense_pub_nth_; + ros::Publisher pub_frames_; + ros::Publisher pub_points_; + ros::Publisher pub_pose_; + ros::Publisher pub_info_; + ros::Publisher pub_dense_; + image_transport::Publisher pub_images_; + tf::TransformBroadcaster br_; + + Visualizer(); + ~Visualizer() {}; + void visualizeMarkers(const FramePtr& frame, const set& core_kfs, const Map& map); + void publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono& slam, const double timestamp); + void publishMapRegion(set frames); + void removeDeletedPts(const Map& map); + void displayKeyframeWithMps(const FramePtr& frame, int ts); + void exportToDense(const FramePtr& frame); +}; + +} // end namespace svo + +#endif /* SVO_VISUALIZER_H_ */ diff --git a/svo_ros/launch/live.launch b/svo_ros/launch/live.launch new file mode 100644 index 0000000..738d97a --- /dev/null +++ b/svo_ros/launch/live.launch @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/svo_ros/launch/test_rig3.launch b/svo_ros/launch/test_rig3.launch new file mode 100644 index 0000000..d03359f --- /dev/null +++ b/svo_ros/launch/test_rig3.launch @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/svo_ros/package.xml b/svo_ros/package.xml new file mode 100644 index 0000000..efc72e0 --- /dev/null +++ b/svo_ros/package.xml @@ -0,0 +1,42 @@ + + + svo_ros + 0.1.0 + + Monocular Visual Odometry - ROS Nodes + + Christian Forster + Christian Forster + GPLv3 + + + catkin + + + roscpp + nav_msgs + std_msgs + visualization_msgs + sensor_msgs + image_transport + cv_bridge + tf + svo + svo_msgs + vikit_common + vikit_ros + + + roscpp + nav_msgs + std_msgs + visualization_msgs + sensor_msgs + image_transport + cv_bridge + tf + svo + svo_msgs + vikit_common + vikit_ros + \ No newline at end of file diff --git a/svo_ros/param/vo_accurate.yaml b/svo_ros/param/vo_accurate.yaml new file mode 100644 index 0000000..8446875 --- /dev/null +++ b/svo_ros/param/vo_accurate.yaml @@ -0,0 +1,4 @@ +grid_size: 20 +max_n_kfs: 50 +loba_num_iter: 10 +max_fts: 200 \ No newline at end of file diff --git a/svo_ros/param/vo_fast.yaml b/svo_ros/param/vo_fast.yaml new file mode 100644 index 0000000..3df87dd --- /dev/null +++ b/svo_ros/param/vo_fast.yaml @@ -0,0 +1,3 @@ +grid_size: 30 +max_n_kfs: 10 +loba_num_iter: 0 \ No newline at end of file diff --git a/svo_ros/rqt.perspective b/svo_ros/rqt.perspective new file mode 100644 index 0000000..66dd7ef --- /dev/null +++ b/svo_ros/rqt.perspective @@ -0,0 +1,293 @@ +{ + "keys": {}, + "groups": { + "pluginmanager": { + "keys": { + "running-plugins": { + "type": "repr", + "repr": "{u'rqt_rviz/RViz': [1], u'rqt_reconfigure/Param': [1], u'rqt_image_view/ImageView': [1], u'svo_rqt/Svo': [1]}" + } + }, + "groups": { + "plugin__rqt_rviz__RViz__1": { + "keys": {}, + "groups": { + "dock_widget__": { + "keys": { + "dockable": { + "type": "repr", + "repr": "True" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + } + } + }, + "plugin__rqt_robot_steering__RobotSteering__1": { + "keys": {}, + "groups": { + "dock_widget__RobotSteeringUi": { + "keys": { + "dockable": { + "type": "repr", + "repr": "u'true'" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + }, + "plugin": { + "keys": { + "topic": { + "type": "repr", + "repr": "u'/cmd_vel'" + }, + "vx_min": { + "type": "repr", + "repr": "u'-1'" + }, + "vw_min": { + "type": "repr", + "repr": "u'-3'" + }, + "vw_max": { + "type": "repr", + "repr": "u'3'" + }, + "vx_max": { + "type": "repr", + "repr": "u'1'" + } + }, + "groups": {} + } + } + }, + "plugin__rqt_reconfigure__Param__1": { + "keys": {}, + "groups": { + "dock_widget___plugincontainer_top_widget": { + "keys": { + "dockable": { + "type": "repr", + "repr": "True" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + }, + "plugin": { + "keys": { + "splitter": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff0000000000000002000000c00000006401000000060100000001')", + "pretty-print": " d " + }, + "_splitter": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff00000000000000020000013e0000006401000000090100000002')", + "pretty-print": " > d " + } + }, + "groups": {} + } + } + }, + "plugin__rqt_image_view__ImageView__1": { + "keys": {}, + "groups": { + "dock_widget__ImageViewWidget": { + "keys": { + "dockable": { + "type": "repr", + "repr": "True" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + }, + "plugin": { + "keys": { + "dynamic_range": { + "type": "repr", + "repr": "False" + }, + "max_range": { + "type": "repr", + "repr": "10.0" + }, + "topic": { + "type": "repr", + "repr": "u'/svo/image'" + }, + "zoom1": { + "type": "repr", + "repr": "False" + } + }, + "groups": {} + } + } + }, + "plugin__svo_rqt__Svo__1": { + "keys": {}, + "groups": { + "dock_widget__SvoWidget": { + "keys": { + "dockable": { + "type": "repr", + "repr": "True" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + }, + "dock_widget__SvoUi": { + "keys": { + "dockable": { + "type": "repr", + "repr": "u'true'" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + } + } + }, + "plugin__rqt_shell__Shell__1": { + "keys": {}, + "groups": { + "plugin": { + "keys": { + "shell_type": { + "type": "repr", + "repr": "u'0'" + } + }, + "groups": {} + } + } + }, + "plugin__rqt_console__Console__1": { + "keys": {}, + "groups": { + "plugin": { + "keys": { + "show_highlighted_only": { + "type": "repr", + "repr": "u'false'" + }, + "message_limit": { + "type": "repr", + "repr": "u'20000'" + }, + "exclude_filters": { + "type": "repr", + "repr": "u'severity'" + }, + "table_splitter": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff00000000000000020000004e000000ed01000000090100000002')", + "pretty-print": " N " + }, + "highlight_filters": { + "type": "repr", + "repr": "u'message'" + }, + "paused": { + "type": "repr", + "repr": "u'false'" + }, + "settings_exist": { + "type": "repr", + "repr": "u'true'" + }, + "filter_splitter": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff0000000000000002000000720000007201000000090100000002')", + "pretty-print": " r r " + } + }, + "groups": { + "exclude_filter_0": { + "keys": { + "enabled": { + "type": "repr", + "repr": "u'true'" + }, + "itemlist": { + "type": "repr", + "repr": "u''" + } + }, + "groups": {} + }, + "highlight_filter_0": { + "keys": { + "regex": { + "type": "repr", + "repr": "u'false'" + }, + "text": { + "type": "repr", + "repr": "u''" + }, + "enabled": { + "type": "repr", + "repr": "u'true'" + } + }, + "groups": {} + } + } + } + } + } + } + }, + "mainwindow": { + "keys": { + "geometry": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('01d9d0cb00010000000007a9fffffffc00001187000005a7000007b1000000180000117f0000059f000000000000')", + "pretty-print": " " + }, + "state": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff00000000fd0000000100000003000009cf00000559fc0100000005fb0000002c00730076006f005f007200710074005f005f00530076006f005f005f0031005f005f00530076006f005500690100000000000003890000000000000000fb0000006a007200710074005f0072006f0062006f0074005f007300740065006500720069006e0067005f005f0052006f0062006f0074005300740065006500720069006e0067005f005f0031005f005f0052006f0062006f0074005300740065006500720069006e00670055006901000000000000020b0000000000000000fc00000000000003530000022e00fffffffc0200000004fb0000003400730076006f005f007200710074005f005f00530076006f005f005f0031005f005f00530076006f0057006900640067006500740100000019000000a30000009900fffffffb0000004c007200710074005f0063006f006e0073006f006c0065005f005f0043006f006e0073006f006c0065005f005f0031005f005f0043006f006e0073006f006c006500570069006400670065007401000000c3000003b50000000000000000fb0000005a007200710074005f0069006d006100670065005f0076006900650077005f005f0049006d0061006700650056006900650077005f005f0031005f005f0049006d006100670065005600690065007700570069006400670065007401000000c2000002700000005100fffffffb0000006c007200710074005f007200650063006f006e006600690067007500720065005f005f0050006100720061006d005f005f0031005f005f005f0070006c007500670069006e0063006f006e007400610069006e00650072005f0074006f0070005f00770069006400670065007401000003380000023a0000010f00fffffffb00000026007200710074005f007200760069007a005f005f005200560069007a005f005f0031005f005f010000035900000676000000a700fffffffb00000040007200710074005f007300680065006c006c005f005f005300680065006c006c005f005f0031005f005f0058005400650072006d005700690064006700650074010000091c000000b30000000000000000000009cf0000000000000004000000040000000800000008fc00000001000000030000000100000036004d0069006e0069006d0069007a006500640044006f0063006b00570069006400670065007400730054006f006f006c0062006100720000000000ffffffff0000000000000000')", + "pretty-print": " ,svo_rqt__Svo__1__SvoUi jrqt_robot_steering__RobotSteering__1__RobotSteeringUi S . p Q 8 : Y v " + } + }, + "groups": { + "toolbar_areas": { + "keys": { + "MinimizedDockWidgetsToolbar": { + "type": "repr", + "repr": "8" + } + }, + "groups": {} + } + } + } + } +} \ No newline at end of file diff --git a/svo_ros/rviz_config.rviz b/svo_ros/rviz_config.rviz new file mode 100644 index 0000000..95d7c0e --- /dev/null +++ b/svo_ros/rviz_config.rviz @@ -0,0 +1,153 @@ +Panels: + - Class: rviz/Displays + Help Height: 108 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + - /Status1 + - /TF1 + - /Marker1 + - /Marker2 + - /Marker2/Namespaces1 + - /Image1 + Splitter Ratio: 0.5 + Tree Height: 680 + - Class: rviz/Selection + Name: Selection + - Class: rviz/Tool Properties + Expanded: + - /2D Pose Estimate1 + - /2D Nav Goal1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.588679 + - Class: rviz/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: Image +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.03 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Class: rviz/TF + Enabled: false + Frame Timeout: 15 + Frames: + All Enabled: true + Marker Scale: 1 + Name: TF + Show Arrows: true + Show Axes: true + Show Names: true + Tree: + {} + Update Interval: 0 + Value: false + - Class: rviz/Marker + Enabled: true + Marker Topic: /svo/keyframes + Name: Marker + Namespaces: + cams: true + kfs: true + Queue Size: 100 + Value: true + - Class: rviz/Marker + Enabled: true + Marker Topic: /svo/points + Name: Marker + Namespaces: + pts: true + trajectory: true + Queue Size: 100 + Value: true + - Class: rviz/Image + Enabled: true + Image Topic: /svo/image + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Value: true + Enabled: true + Global Options: + Background Color: 255; 255; 255 + Fixed Frame: /world + Name: root + Tools: + - Class: rviz/Interact + Hide Inactive Objects: true + - Class: rviz/MoveCamera + - Class: rviz/Select + - Class: rviz/FocusCamera + - Class: rviz/Measure + - Class: rviz/SetInitialPose + Topic: /initialpose + - Class: rviz/SetGoal + Topic: /move_base_simple/goal + - Class: rviz/PublishPoint + Single click: true + Topic: /clicked_point + Value: true + Views: + Current: + Class: rviz/Orbit + Distance: 5.48911 + Focal Point: + X: 0.777511 + Y: 0.689927 + Z: -0.445833 + Name: Current View + Near Clip Distance: 0.01 + Pitch: 0.125204 + Target Frame: + Value: Orbit (rviz) + Yaw: 4.45215 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1416 + Hide Left Dock: false + Hide Right Dock: true + Image: + collapsed: false + QMainWindow State: 000000ff00000000fd0000000400000000000002cc00000542fc0200000009fb0000001200530065006c0065006300740069006f006e00000000280000009b0000006400fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000002800000355000000dd00fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d0061006700650100000383000001e70000001600ffffff000000010000010f000003dafc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a005600690065007700730000000028000003da000000b000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000003ce0000003efc0100000002fb0000000800540069006d00650000000000000003ce000002f600fffffffb0000000800540069006d00650100000000000004500000000000000000000006fd0000054200000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: true + Width: 2511 + X: 1962 + Y: 24 diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp new file mode 100644 index 0000000..2d0ff6e --- /dev/null +++ b/svo_ros/src/benchmark_node.cpp @@ -0,0 +1,155 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +class BenchmarkNode +{ + svo::FrameHandlerMono* vo_; + svo::Visualizer visualizer_; + vk::UserInputThread user_input_thread_; + int frame_count_; + std::ofstream trace_est_pose_; + vk::AbstractCamera* cam_; + bool quit_; + +public: + BenchmarkNode(ros::NodeHandle& nh); + ~BenchmarkNode(); + void runCamImuBenchmark(); + void processUserActions(); +}; + +BenchmarkNode::BenchmarkNode(ros::NodeHandle& nh) : + vo_(NULL), + frame_count_(0), + quit_(false) +{ + // Create Camera + if(!vk::camera_loader::loadFromRosNs("svo", cam_)) + throw std::runtime_error("Camera model not correctly specified."); + + // Initialize VO + vo_ = new svo::FrameHandlerMono(cam_); + vo_->start(); +} + +BenchmarkNode::~BenchmarkNode() +{ + delete vo_; + delete cam_; +} + +void BenchmarkNode::runCamImuBenchmark() +{ + // create image reader and load dataset + std::string benchmark_dir(vk::getParam("svo/dataset_directory")); + std::string filename_benchmark(benchmark_dir + "/images.txt"); + vk::FileReader dataset_reader(filename_benchmark); + dataset_reader.skipComments(); + if(!dataset_reader.next()) + std::runtime_error("Failed to open images file"); + std::vector dataset; + dataset_reader.readAllEntries(dataset); + + // create pose tracefile + std::string trace_est_name(Config::traceDir() + "/traj_estimate.txt"); + trace_est_pose_.open(trace_est_name.c_str()); + if(trace_est_pose_.fail()) + throw std::runtime_error("ERROR:frame_count_ could not create tracefile. probably the specified folder does not exist."); + + // process dataset + for(vk::vector::iterator it = dataset.begin(); + it != dataset.end(); ++it, ++frame_count_) + { + // Read image + std::string img_filename(benchmark_dir + "/" + it->imgname_); + cv::Mat img(cv::imread(img_filename, 0)); + if(frame_count_ == 0) + SVO_INFO_STREAM("Reading image "<addImage(img, it->stamp_); + + // Visualize + visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->stamp_); + if(vo_->stage() != svo::FrameHandlerMono::PAUSED) + visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); + + // write pose to tracefile + if(vo_->stage() == svo::FrameHandlerMono::DEFAULT_FRAME) + { + Quaterniond q(vo_->lastFrame()->T_f_w_.inverse().unit_quaternion()); + Vector3d p(vo_->lastFrame()->T_f_w_.inverse().translation()); + trace_est_pose_.precision(15); + trace_est_pose_.setf(std::ios::fixed, std::ios::floatfield ); + trace_est_pose_ << it->stamp_<< " "; + trace_est_pose_.precision(6); + trace_est_pose_ << p.x() << " " << p.y() << " " << p.z() << " " + << q.x() << " " << q.y() << " " << q.z() << " " << q.w() << endl; + } + if (!ros::ok() || quit_) + break; + } +} + +void BenchmarkNode::processUserActions() +{ + char input = user_input_thread_.getInput(); + switch(input) + { + case 'q': quit_ = true; break; + case 'r': vo_->reset(); break; + case 's': vo_->start(); break; + default: ; + } +} + +} // namespace svo + +int main(int argc, char** argv) +{ + ros::init(argc, argv, "svo"); + ros::NodeHandle nh; + { + svo::BenchmarkNode benchmark(nh); + benchmark.runCamImuBenchmark(); + } + printf("BenchmarkNode finished.\n"); + return 0; +} diff --git a/svo_ros/src/remote_node.cpp b/svo_ros/src/remote_node.cpp new file mode 100644 index 0000000..8952b21 --- /dev/null +++ b/svo_ros/src/remote_node.cpp @@ -0,0 +1,169 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class RemoteHandler +{ +public: + ros::NodeHandle& nh_; + vk::UserInputThread input_thread_; + + ros::Publisher pub_key_; + ros::Publisher pub_frames_; + tf::TransformBroadcaster br_; + + vk::RingBuffer acc_timing_; + vk::RingBuffer acc_obs_; + typedef std::map > pose_map_t; + pose_map_t poses_; + std::set published_kfs_; + std::set current_kfs_; + + RemoteHandler(ros::NodeHandle& nh); + ~RemoteHandler(); + void handleUserInput(); + void poseCb(const geometry_msgs::PoseWithCovarianceStampedConstPtr msg); + void infoCb(const svo_msgs::InfoConstPtr msg); +}; + +RemoteHandler::RemoteHandler(ros::NodeHandle& nh) : + nh_(nh), + pub_key_(nh_.advertise ("/svo/remote_key", 10)), + pub_frames_(nh_.advertise("/svo/vis/frame", 100)), + acc_timing_(50), + acc_obs_(50) +{} + +RemoteHandler::~RemoteHandler() +{} + +void RemoteHandler::handleUserInput() +{ + char key = input_thread_.getInput(); + std_msgs::StringPtr msg(new std_msgs::String); + switch(key) + { + case 'q': msg->data = 'q'; pub_key_.publish(msg); break; // quit + case 'r': msg->data = 'r'; pub_key_.publish(msg); break; // reset + case 'p': msg->data = 'p'; pub_key_.publish(msg); break; // pause + case 's': msg->data = 's'; pub_key_.publish(msg); break; // start + default: ; + } +} + +void RemoteHandler::poseCb(const geometry_msgs::PoseWithCovarianceStampedConstPtr msg) +{ + Eigen::Vector3d p(msg->pose.pose.position.x, msg->pose.pose.position.y, msg->pose.pose.position.z); + Eigen::Quaterniond q(msg->pose.pose.orientation.w, msg->pose.pose.orientation.x, msg->pose.pose.orientation.y, msg->pose.pose.orientation.z); + Eigen::Matrix3d R_world_from_frame(q.inverse()); + Eigen::Vector3d p_frame_in_world(-R_world_from_frame*p); + + poses_.insert(std::pair >( + msg->header.seq, + std::pair(p_frame_in_world, R_world_from_frame))); + + // publish trajectory + vk::output_helper::publishPointMarker(pub_frames_, p_frame_in_world, "trajectory_points", + msg->header.stamp, msg->header.seq, 0, 0.006, Eigen::Vector3d(0.,0.,0.5)); + + // publish camera pose tf + tf::StampedTransform transform_msg; + transform_msg.frame_id_ = "cam"; + transform_msg.child_frame_id_ = "world"; + transform_msg.stamp_ = msg->header.stamp; + transform_msg.setOrigin(tf::Vector3(p.x(), p.y(), p.z())); + transform_msg.setRotation(tf::Quaternion(q.x(), q.y(), q.z(), q.w())); + br_.sendTransform(transform_msg); + + // publish keyframes + std::set deleted_kfs; + std::set_difference(published_kfs_.begin(), published_kfs_.end(), current_kfs_.begin(), current_kfs_.end(), std::inserter(deleted_kfs, deleted_kfs.end())); + for(std::set::iterator it=deleted_kfs.begin(); it!=deleted_kfs.end(); ++it) + { + pose_map_t::iterator kf = poses_.find(*it); + if(kf != poses_.end()) + vk::output_helper::publishFrameMarker(pub_frames_, kf->second.second, kf->second.first, "kfs", ros::Time::now(), (*it)*10, 2, 0.015); + } + + std::set unpublished_kfs; + std::set_difference(current_kfs_.begin(), current_kfs_.end(), published_kfs_.begin(), published_kfs_.end(), std::inserter(unpublished_kfs, unpublished_kfs.end())); + for(std::set::iterator it=unpublished_kfs.begin(); it!=unpublished_kfs.end(); ++it) + { + pose_map_t::iterator kf = poses_.find(*it); + if(kf != poses_.end()) + vk::output_helper::publishFrameMarker(pub_frames_, kf->second.second, kf->second.first, "kfs", ros::Time::now(), (*it)*10, 0, 0.015); + } + published_kfs_.swap(current_kfs_); + + + // publish hexacopter + vk::output_helper::publishHexacopterMarker(pub_frames_, "cam", "hexacopter", msg->header.stamp, 1, 0, 0.3, Eigen::Vector3d(0.,0.,1.)); +} + +void RemoteHandler::infoCb(const svo_msgs::InfoConstPtr msg) +{ + std::string kfmsg(""); + current_kfs_.clear(); + for(std::vector::const_iterator it=msg->keyframes.begin(); it!=msg->keyframes.end(); ++it) { + current_kfs_.insert(static_cast(*it)); + if(*it == static_cast(msg->header.seq)) { + kfmsg = "Keyframe!"; + break; + } + } + acc_timing_.push_back(msg->processing_time); + acc_obs_.push_back(msg->num_matches); + + printf("[%i] t=%.2fhz (mean=%.2f) \t n_obs=%i (mean=%i) \t %s\n", + msg->header.seq, 1./msg->processing_time, 1./acc_timing_.getMean(), + msg->num_matches, acc_obs_.getMean(), kfmsg.c_str()); +} + +int main(int argc, char **argv) +{ + ros::init(argc, argv, "svo_remote"); + ros::NodeHandle nh; + RemoteHandler node(nh); + + printf("Listening to User-Input...\n"); + + ros::Subscriber sub_pose = nh.subscribe("/svo/pose", 10, &RemoteHandler::poseCb, &node); + ros::Subscriber sub_info = nh.subscribe("/svo/info", 10, &RemoteHandler::infoCb, &node); + ros::Rate r(100); + while (ros::ok()) + { + node.handleUserInput(); + ros::spinOnce(); + r.sleep(); + } + return 0; +} diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp new file mode 100644 index 0000000..d8aa72f --- /dev/null +++ b/svo_ros/src/visualizer.cpp @@ -0,0 +1,268 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +Visualizer:: +Visualizer() : + pnh_("~"), + trace_id_(0), + img_pub_level_(vk::getParam("svo/image_publishing_level", 0)), + img_pub_nth_(vk::getParam("svo/publish_every_nth_img", 1)), + dense_pub_nth_(vk::getParam("svo/publish_every_nth_dense_input", 1)) +{ + // Init ROS Marker Publishers + pub_frames_ = pnh_.advertise("keyframes", 10); + pub_points_ = pnh_.advertise("points", 1000); + pub_pose_ = pnh_.advertise("pose",10); + pub_info_ = pnh_.advertise("info", 10); + pub_dense_ = pnh_.advertise("dense_input",10); + + // create video publisher + image_transport::ImageTransport it(pnh_); + pub_images_ = it.advertise("image", 10); +} + +void Visualizer:: +visualizeMarkers(const FramePtr& frame, const set& core_kfs, const Map& map) +{ + if(frame != NULL) + { + // publish camera pose tf + vk::output_helper::publishTfTransform(frame->T_f_w_, ros::Time(frame->timestamp_), "cam_pos", "world", br_); + if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) + { + vk::output_helper::publishHexacopterMarker(pub_frames_, "cam_pos", "cams", ros::Time(frame->timestamp_), 1, 0, 0.3, Vector3d(0.,0.,1.)); + vk::output_helper::publishPointMarker(pub_points_, frame->pos(), "trajectory", ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5)); + publishMapRegion(core_kfs); + removeDeletedPts(map); + } + } +} + +void Visualizer:: +publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono& slam, const double timestamp) +{ + ++trace_id_; + std_msgs::Header header_msg; + header_msg.frame_id = "/cam"; + header_msg.seq = trace_id_; + header_msg.stamp = ros::Time(timestamp); + + // publish svo info msgs + if(pub_info_.getNumSubscribers() > 0) + { + svo_msgs::Info msg_info; + msg_info.header = header_msg; + msg_info.processing_time = slam.lastProcessingTime(); + msg_info.keyframes.resize(slam.map().keyframes_.size()); + for(list::const_iterator it=slam.map().keyframes_.begin(); it!=slam.map().keyframes_.end(); ++it) + msg_info.keyframes.push_back((*it)->id_); + msg_info.stage = static_cast(slam.stage()); + msg_info.tracking_quality = static_cast(slam.trackingQuality()); + if(frame != NULL) + msg_info.num_matches = slam.lastNumObservations(); + else + msg_info.num_matches = 0; + pub_info_.publish(msg_info); + } + + // publish pyramid-image every nth-frame + if(frame != NULL && img_pub_nth_ > 0 + && trace_id_%img_pub_nth_ == 0 && pub_images_.getNumSubscribers() > 0) + { + const int scale = (1<img_pyr_[img_pub_level_].size(), CV_8UC3); + cv::cvtColor(frame->img_pyr_[img_pub_level_], img_rgb, CV_GRAY2RGB); + + // during initialization, draw lines + if(slam.stage() == FrameHandlerBase::SECOND_FRAME) + { + const vector& px_ref(slam.initFeatureTrackRefPx()); + const vector& px_cur(slam.initFeatureTrackCurPx()); + for(vector::const_iterator it_ref=px_ref.begin(), it_cur=px_cur.begin(); + it_ref != px_ref.end(); ++it_ref, ++it_cur) + cv::line(img_rgb, + cv::Point2f(it_cur->x/scale, it_cur->y/scale), + cv::Point2f(it_ref->x/scale, it_ref->y/scale), cv::Scalar(0,255,0), 2); + } + + // draw features on frame + if(img_pub_level_ == 0) + for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + cv::rectangle(img_rgb, + cv::Point2f((*it)->px[0]-2, (*it)->px[1]-2), + cv::Point2f((*it)->px[0]+2, (*it)->px[1]+2), + cv::Scalar(0,255,0), CV_FILLED); + if(img_pub_level_ == 1) + for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + cv::rectangle(img_rgb, + cv::Point2f((*it)->px[0]/scale-1, (*it)->px[1]/scale-1), + cv::Point2f((*it)->px[0]/scale+1, (*it)->px[1]/scale+1), + cv::Scalar(0,255,0), CV_FILLED); + else + for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + cv::rectangle(img_rgb, + cv::Point2f((*it)->px[0]/scale, (*it)->px[1]/scale), + cv::Point2f((*it)->px[0]/scale, (*it)->px[1]/scale), + cv::Scalar(0,255,0), CV_FILLED); + + // publish image + cv_bridge::CvImage img_msg; + img_msg.header = header_msg; + img_msg.image = img_rgb; + img_msg.encoding = sensor_msgs::image_encodings::BGR8; + pub_images_.publish(img_msg.toImageMsg()); + } + else if(frame == NULL && pub_images_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::PAUSED) + { + // display image when slam is not running + cv_bridge::CvImage img_msg; + img_msg.header.stamp = ros::Time::now(); + img_msg.header.frame_id = "/image"; + img_msg.image = img; + img_msg.encoding = sensor_msgs::image_encodings::MONO8; + pub_images_.publish(img_msg.toImageMsg()); + } + + // publish pose (world in camera frame) + if(pub_pose_.getNumSubscribers() > 0 && frame != NULL) + { + geometry_msgs::PoseWithCovarianceStampedPtr msg_pose(new geometry_msgs::PoseWithCovarianceStamped); + Quaterniond q(frame->T_f_w_.rotation_matrix()); + Vector3d p(frame->T_f_w_.translation()); + msg_pose->header = header_msg; + msg_pose->pose.pose.position.x = p[0]; + msg_pose->pose.pose.position.y = p[1]; + msg_pose->pose.pose.position.z = p[2]; + msg_pose->pose.pose.orientation.x = q.x(); + msg_pose->pose.pose.orientation.y = q.y(); + msg_pose->pose.pose.orientation.z = q.z(); + msg_pose->pose.pose.orientation.w = q.w(); + for(size_t i=0; i<36; ++i) + msg_pose->pose.covariance[i] = frame->Cov_(i%6, i/6); + pub_pose_.publish(msg_pose); + } +} + +void Visualizer:: +publishMapRegion(set frames) +{ + if(pub_points_.getNumSubscribers() > 0) + { + int ts = vk::Timer::getCurrentTime(); + for(set::iterator it=frames.begin(); it!=frames.end(); ++it) + displayKeyframeWithMps(*it, ts); + } +} + +void Visualizer:: +removeDeletedPts(const Map& map) +{ + if(pub_points_.getNumSubscribers() > 0) + { + for(list::const_iterator it=map.trash_points_.begin(); it!=map.trash_points_.end(); ++it) + vk::output_helper::publishPointMarker(pub_points_, Vector3d(), "pts", ros::Time::now(), (*it)->id_, 2, 0.006, Vector3d()); + } +} + +void Visualizer:: +displayKeyframeWithMps(const FramePtr& frame, int ts) +{ + // publish keyframe + vk::output_helper::publishFrameMarker(pub_frames_, frame->T_f_w_.inverse().rotation_matrix(), frame->pos(), "kfs", ros::Time::now(), frame->id_*10, 0, 0.015); + + // publish point cloud and links + for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point == NULL) + continue; + + if((*it)->point->last_published_ts_ == ts) + continue; + + vk::output_helper::publishPointMarker(pub_points_, (*it)->point->pos_, "pts", ros::Time::now(), (*it)->point->id_, 0, 0.005, Vector3d(1.0, 0., 1.0)); + (*it)->point->last_published_ts_ = ts; + } +} + +void Visualizer:: +exportToDense(const FramePtr& frame) +{ + // publish air_ground_msgs + if(frame != NULL && dense_pub_nth_ > 0 + && trace_id_%dense_pub_nth_ == 0 && pub_dense_.getNumSubscribers() > 0) + { + svo_msgs::DenseInput msg; + msg.header.stamp = ros::Time(frame->timestamp_); + msg.header.frame_id = "/world"; + msg.frame_id = frame->id_; + + cv_bridge::CvImage img_msg; + img_msg.header.stamp = msg.header.stamp; + img_msg.header.frame_id = "camera"; + img_msg.image = frame->img(); + img_msg.encoding = sensor_msgs::image_encodings::MONO8; + msg.image = *img_msg.toImageMsg(); + + double min_z = std::numeric_limits::max(); + double max_z = std::numeric_limits::min(); + for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point==NULL) + continue; + Vector3d pos = frame->T_f_w_*(*it)->point->pos_; + min_z = min(pos[2], min_z); + max_z = max(pos[2], max_z); + } + msg.min_depth = (float) min_z; + msg.max_depth = (float) max_z; + + Quaterniond q(frame->T_f_w_.inverse().rotation_matrix()); + Vector3d p(frame->T_f_w_.inverse().translation()); + msg.pose.position.x = p[0]; + msg.pose.position.y = p[1]; + msg.pose.position.z = p[2]; + msg.pose.orientation.w = q.w(); + msg.pose.orientation.x = q.x(); + msg.pose.orientation.y = q.y(); + msg.pose.orientation.z = q.z(); + pub_dense_.publish(msg); + } +} + +} // end namespace svo diff --git a/svo_ros/src/vo_node.cpp b/svo_ros/src/vo_node.cpp new file mode 100644 index 0000000..27b7ef0 --- /dev/null +++ b/svo_ros/src/vo_node.cpp @@ -0,0 +1,181 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +using namespace std; +using namespace vk; + +/// SVO Interface +class VoNode +{ +public: + svo::FrameHandlerMono* vo_; + svo::Visualizer visualizer_; + bool publish_markers_; //!< publish only the minimal amount of info (choice for embedded devices) + bool publish_dense_input_; + vk::UserInputThread* user_input_thread_; + ros::Subscriber sub_remote_key_; + string remote_input_; + vk::AbstractCamera* cam_; + bool quit_; + VoNode(); + ~VoNode(); + void imgCb(const sensor_msgs::ImageConstPtr& msg); + void processUserActions(); + void remoteKeyCb(const std_msgs::StringConstPtr& key_input); +}; + +VoNode:: +VoNode() : + vo_(NULL), + publish_markers_(vk::getParam("svo/publish_markers", true)), + publish_dense_input_(vk::getParam("svo/publish_dense_input", false)), + user_input_thread_(new vk::UserInputThread()), + remote_input_(""), + cam_(NULL), + quit_(false) +{ + // Create Camera + if(!vk::camera_loader::loadFromRosNs("svo", cam_)) + throw std::runtime_error("Camera model not correctly specified."); + + // Init camera + vo_ = new svo::FrameHandlerMono(cam_); + + // Set initial position and orientation + Sophus::SE3 T_cam_from_world( + vk::rpy2dcm(Vector3d(vk::getParam("svo/init_rx", 0.0), + vk::getParam("svo/init_ry", 0.0), + vk::getParam("svo/init_rz", 0.0))), + Eigen::Vector3d(vk::getParam("svo/init_tx", 0.0), + vk::getParam("svo/init_ty", 0.0), + vk::getParam("svo/init_tz", 0.0))); + vo_->setInitialPose(T_cam_from_world); + vo_->start(); +} + +VoNode:: +~VoNode() +{ + delete vo_; + delete user_input_thread_; + delete cam_; +} + +void VoNode:: +imgCb(const sensor_msgs::ImageConstPtr& msg) +{ + cv::Mat img; + try { + img = cv_bridge::toCvShare(msg, "mono8")->image; + } catch (cv_bridge::Exception& e) { + ROS_ERROR("cv_bridge exception: %s", e.what()); + } + processUserActions(); + vo_->addImage(img, msg->header.stamp.toSec()); + visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, msg->header.stamp.toSec()); + + if(publish_markers_ && vo_->stage() != FrameHandlerBase::PAUSED) + visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); + + if(publish_dense_input_) + visualizer_.exportToDense(vo_->lastFrame()); + + if(vo_->stage() == FrameHandlerMono::PAUSED) + usleep(100000); // avoid busy loop when paused +} + +void VoNode::processUserActions() +{ + char input = remote_input_.c_str()[0]; + remote_input_ = ""; + + char console_input = user_input_thread_->getInput(); + if(console_input != 0) + input = console_input; + + switch(input) + { + case 'q': + quit_ = true; + printf("Svo User Input: QUIT\n"); + break; + case 'r': + vo_->reset(); + printf("Svo User Input: RESET\n"); + break; + case 's': + vo_->start(); + printf("Svo User Input: START\n"); + break; + default: ; + } +} + +void VoNode::remoteKeyCb(const std_msgs::StringConstPtr& key_input) +{ + remote_input_ = key_input->data; +} + +} // namespace svo + +int main(int argc, char **argv) +{ + ros::init(argc, argv, "svo"); + ros::NodeHandle nh; + std::cout << "create vo_node" << std::endl; + svo::VoNode vo_node; + + // subscribe to cam msgs + std::string cam_topic(vk::getParam("svo/cam_topic", "camera/image_raw")); + image_transport::ImageTransport it(nh); + image_transport::Subscriber it_sub = it.subscribe(cam_topic, 5, &svo::VoNode::imgCb, &vo_node); + + // subscribe to remote input + vo_node.sub_remote_key_ = nh.subscribe("svo/remote_key", 5, &svo::VoNode::remoteKeyCb, &vo_node); + + // start processing callbacks + while(ros::ok() && !vo_node.quit_) + { + ros::spinOnce(); + // TODO check when last image was processed. when too long ago. publish warning that no msgs are received! + } + + printf("Svo terminated.\n"); + return 0; +} From 9220bea29d40305ea9f330620adb228e23ccf04f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 16:45:43 +0100 Subject: [PATCH 002/215] added licence --- LICENCE | 675 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 675 insertions(+) create mode 100644 LICENCE diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..70fc6da --- /dev/null +++ b/LICENCE @@ -0,0 +1,675 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. {http://fsf.org/} + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + PTAM-GPL Copyright (C) 2013 Oxford-PTAM + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +{http://www.gnu.org/licenses/}. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +{http://www.gnu.org/philosophy/why-not-lgpl.html}. + From 76c7c6841c928aa6709a995a5e23b1b4fce3fdc3 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 16:45:51 +0100 Subject: [PATCH 003/215] comment on citing this work --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index c3bc469..3362683 100644 --- a/README.md +++ b/README.md @@ -135,3 +135,15 @@ Licence ------- The source code is released under GPLv3 licence. A professional edition license for closed-source projects is also available. Please contact `forster at ifi dot uzh dot ch` for further information. + +Citing +------ + +If you use SVO in an academic context, please cite the following publication: + + @article{Pomerleau12comp, + author = {Forster, Christian and Pizzoli, Matia and Scaramuzza, Davide}, + title = {{SVO: Fast Semi-Direct Monocular Visual Odometry}}, + journal = {IEEE International Conference on Robotics and Automation (ICRA)}, + year = {2014} + } \ No newline at end of file From 35c2fee2bde7a55c9a3e356d3a2385e2876d8e1d Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 18:38:12 +0100 Subject: [PATCH 004/215] set trace flag to false --- svo/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 7612a94..16b1cba 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -2,7 +2,7 @@ # user build settings SET(DEBUG FALSE) -SET(TRACE TRUE) +SET(TRACE FALSE) SET(HAVE_G2O FALSE) ################################################################################ From 3c65f67676a25f5a7274cf2bc7e79cb0071ebd3f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 19:24:55 +0100 Subject: [PATCH 005/215] added info about camera model --- README.md | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 3362683..4504e49 100644 --- a/README.md +++ b/README.md @@ -4,32 +4,16 @@ SVO Disclaimer ---------- -SVO has been tested under ROS Groovy and Hydro and Ubuntu 12.04 and 13.04. This is research code, expect that it changes often and any fitness for a particular purpose is disclaimed. +SVO has been tested under ROS Groovy and Hydro and Ubuntu 12.04 and 13.04. This is research code, any fitness for a particular purpose is disclaimed. Installation Instructions ------------------------- -#### OPTIONAL: g2o - General Graph Optimization - -Only required if you want to run bundle adjustment. It is not necessary for visual odometry. -g2o requires the following system dependencies: `cmake, libeigen3-dev, libsuitesparse-dev, libqt4-dev, qt4-qmake, libqglviewer-qt4-dev`, install them with `apt-get` - -I suggest an out-of-source build of g2o: - - cd workspace - git clone https://github.com/RainerKuemmerle/g2o.git - cd g2o - mkdir build - cd build - cmake .. - make - sudo make install - -If you don't want to make a system install, then you can replace the cmake command with `cmake .. -DCMAKE_INSTALL_PREFIX:PATH=$HOME/installdir` +We use two workspaces, one for the plain CMake projects `Sophus`, `Fast` and optionally `g2o` and another workspace for the Catkin projects `rpg_vikit` and `rpg_svo`. Make sure to clone in the right folder. #### Sophus - Lie groups -Sophus by Hauke Strasdat implements Lie groups that we need to describe rigid body transformations. +Sophus by Hauke Strasdat implements Lie groups that we need to describe rigid body transformations. Checkout in your workspace for plain CMake projects. cd workspace git clone https://github.com/strasdat/Sophus.git @@ -55,6 +39,24 @@ To simplify installation we provide a CMake package that contains the fast detec cmake .. make +#### OPTIONAL: g2o - General Graph Optimization + +Only required if you want to run bundle adjustment. It is not necessary for visual odometry. In fact, we don't run it on our MAVs. +g2o requires the following system dependencies: `cmake, libeigen3-dev, libsuitesparse-dev, libqt4-dev, qt4-qmake, libqglviewer-qt4-dev`, install them with `apt-get` + +I suggest an out-of-source build of g2o: + + cd workspace + git clone https://github.com/RainerKuemmerle/g2o.git + cd g2o + mkdir build + cd build + cmake .. + make + sudo make install + +If you don't want to make a system install, then you can replace the cmake command with `cmake .. -DCMAKE_INSTALL_PREFIX:PATH=$HOME/installdir` + #### ViKit - Some useful tools that we need ViKit for instance contains camera models, some math and interpolation functions that SVO needs. @@ -96,7 +98,7 @@ Now you are ready to start the rosbag. Open a new console and change to the dire rosbag play airground_rig_s3_2013-03-18_21-38-48.bag -Now you should see the video with tracked features (green) and in RViz how the camera moves. +Now you should see the video with tracked features (green) and in RViz how the camera moves. SVO GUI ------- @@ -112,6 +114,17 @@ Make sure to active the console window when pressing the keys. * `q` Quit * `r` Reset +Camera Calibration +------------------ + +You need a calibrated camera to run SVO. We use the Matrix Vision Bluefox cameras in our lab, which have VGA resolution and global shutter. +SVO supports three camera models: + +1. The `ATAN` model --- our preference --- which is also used by `PTAM`. This model uses the _FOV_ distortion model of "Deverneay and Faugeras, Straight lines have to be straight, 2001". You can calibrate your camera with this model by using the calibration tool in this package: https://github.com/ethz-asl/ethzasl_ptam We prefer this model because the projection and unprojection can be computed faster than with the other models. Further, the industral cameras that we use have neglectable tangential distortion. +2. The `Pinhole` model with three radial and two tangential distortion parameters. This model is standard in OpenCV and ROS. You can use the ROS camera calibration tool: http://wiki.ros.org/camera_calibration +3. The `Ocam` model by Davide Scaramuzza which can be used to model Omnidirectional cameras. Use the OCamCalib toolbox to calibrate your camera: http://rpg.ifi.uzh.ch/software_datasets.html +Although SVO can be used with this camera model, the algorithm does not work yet (!) with omnidirectional cameras. + Parameter Settings ------------------ From 2d24e002f293c9d69472f168c49ca08c84fe7a18 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 19:25:08 +0100 Subject: [PATCH 006/215] added comments to launchfile --- svo_ros/launch/test_rig3.launch | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/svo_ros/launch/test_rig3.launch b/svo_ros/launch/test_rig3.launch index d03359f..31b85f4 100644 --- a/svo_ros/launch/test_rig3.launch +++ b/svo_ros/launch/test_rig3.launch @@ -1,16 +1,21 @@ - + + + + - - - - - - - - - + + + + + + + + + + + From 63bf963e8ad9904fca3a35153dc7b6cdd16b5128 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 19:25:27 +0100 Subject: [PATCH 007/215] added template calibration files --- svo_ros/param/camera_atan.yaml | 8 ++++++++ svo_ros/param/camera_pinhole.yaml | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 svo_ros/param/camera_atan.yaml create mode 100644 svo_ros/param/camera_pinhole.yaml diff --git a/svo_ros/param/camera_atan.yaml b/svo_ros/param/camera_atan.yaml new file mode 100644 index 0000000..e3c625c --- /dev/null +++ b/svo_ros/param/camera_atan.yaml @@ -0,0 +1,8 @@ +cam_model: ATAN +cam_width: 752 +cam_height: 480 +cam_fx: 0.509326 +cam_fy: 0.796651 +cam_cx: 0.45905 +cam_cy: 0.510056 +cam_d0: 0.9320 \ No newline at end of file diff --git a/svo_ros/param/camera_pinhole.yaml b/svo_ros/param/camera_pinhole.yaml new file mode 100644 index 0000000..4898bcd --- /dev/null +++ b/svo_ros/param/camera_pinhole.yaml @@ -0,0 +1,11 @@ +cam_model: Pinhole +cam_width: 752 +cam_height: 480 +cam_fx: 414.536145 +cam_fy: 414.284429 +cam_cx: 348.804988 +cam_cy: 240.076451 +cam_d0: -0.283076 +cam_d1: 0.066674 +cam_d2: 0.000896 +cam_d3: 0.000778 \ No newline at end of file From 6fdc04c883f4bda1f607845c61ef5dfc832ed5d2 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 19:28:52 +0100 Subject: [PATCH 008/215] update --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4504e49..f2605e6 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,12 @@ SVO GUI Type `rosrun rqt_svo rqt_svo` to run the SVO widget that displays the number of tracked features, the frame rate and provides some interface buttons. +If the widget is not found, try this: + + rm ~/.config/ros.org/rqt_gui.ini + rosrun rqt_svo rqt_svo + + Keyboard Shortcuts ------------------ @@ -120,10 +126,10 @@ Camera Calibration You need a calibrated camera to run SVO. We use the Matrix Vision Bluefox cameras in our lab, which have VGA resolution and global shutter. SVO supports three camera models: -1. The `ATAN` model --- our preference --- which is also used by `PTAM`. This model uses the _FOV_ distortion model of "Deverneay and Faugeras, Straight lines have to be straight, 2001". You can calibrate your camera with this model by using the calibration tool in this package: https://github.com/ethz-asl/ethzasl_ptam We prefer this model because the projection and unprojection can be computed faster than with the other models. Further, the industral cameras that we use have neglectable tangential distortion. +1. The `ATAN` model - our preference - which is also used by _PTAM_. This model uses the _FOV_ distortion model of "Deverneay and Faugeras, Straight lines have to be straight, 2001". You can calibrate your camera with this model by using the calibration tool in this package: https://github.com/ethz-asl/ethzasl_ptam We prefer this model because the projection and unprojection can be computed faster than with the other models. Further, the industral cameras that we use have neglectable tangential distortion. 2. The `Pinhole` model with three radial and two tangential distortion parameters. This model is standard in OpenCV and ROS. You can use the ROS camera calibration tool: http://wiki.ros.org/camera_calibration -3. The `Ocam` model by Davide Scaramuzza which can be used to model Omnidirectional cameras. Use the OCamCalib toolbox to calibrate your camera: http://rpg.ifi.uzh.ch/software_datasets.html -Although SVO can be used with this camera model, the algorithm does not work yet (!) with omnidirectional cameras. +3. The `Ocam` model by Davide Scaramuzza which can be used to model cameras with high field of view or even omnidirectional cameras. Use the OCamCalib toolbox to calibrate your camera: http://rpg.ifi.uzh.ch/software_datasets.html +Although SVO can be used with this camera model, the algorithm does not work yet with omnidirectional cameras. Parameter Settings ------------------ From 18a8fe5a6bcd54a50fd26487b9b19bc4c98f53eb Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 19:32:49 +0100 Subject: [PATCH 009/215] update --- README.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f2605e6..ad4d647 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,10 @@ I suggest an out-of-source build of g2o: If you don't want to make a system install, then you can replace the cmake command with `cmake .. -DCMAKE_INSTALL_PREFIX:PATH=$HOME/installdir` -#### ViKit - Some useful tools that we need +#### vikit - Some useful tools that we need -ViKit for instance contains camera models, some math and interpolation functions that SVO needs. -ViKit is a catkin project, therefore, download it into your catkin workspace source folder. +vikit for contains camera models, some math and interpolation functions that SVO needs. +vikit is a catkin project, therefore, download it into your catkin workspace source folder. cd catkin_ws/src git clone https://github.com/uzh-rpg/rpg_vikit.git @@ -88,17 +88,12 @@ Open a new console and start SVO with the prepared launchfile: roslaunch svo_ros test_rig3.launch -Open a new console and start RViz - - rosrun rviz rviz - -In RViz, load the configuration file (File > Open Config) which is stored in `svo_ros/rviz_config.rviz`. - Now you are ready to start the rosbag. Open a new console and change to the directory where you have downloaded the example dataset. Then type: rosbag play airground_rig_s3_2013-03-18_21-38-48.bag Now you should see the video with tracked features (green) and in RViz how the camera moves. +If you want to see the number of tracked features, fps and tracking quality, run the GUI. SVO GUI ------- @@ -109,7 +104,7 @@ If the widget is not found, try this: rm ~/.config/ros.org/rqt_gui.ini rosrun rqt_svo rqt_svo - + Keyboard Shortcuts ------------------ From 0782e271fb796565965ef7294af4818127c9354b Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 19:35:31 +0100 Subject: [PATCH 010/215] update --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ad4d647..5cb0757 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ Although SVO can be used with this camera model, the algorithm does not work yet Parameter Settings ------------------ -A description of all parameters which can be set via the launchfile is provided in `svo/include/config.h`. The default parameters can be viewed in `svo/src/config.cpp`. Moreover, some additional parameters (mainly rostopic names etc.) are read from the ros parameter server in `svo_ros/slam_node.cpp`. +A description of all parameters which can be set via the launchfile is provided in `svo/include/config.h`. The default parameters can be viewed in `svo/src/config.cpp`. Moreover, some additional parameters (mainly rostopic names etc.) are read from the ros parameter server in `svo_ros/vo_node.cpp`. Generating Code Documentation ----------------------------- @@ -142,8 +142,8 @@ You can generate a Doxygen documentation as follows Contributing ------------ -You are very welcome to contribute by opening a pull request via Github. -I try to follow the ROS C++ style guide. +You are very welcome to contribute to SVO by opening a pull request via Github. +I try to follow the ROS C++ style guide http://wiki.ros.org/CppStyleGuide Licence ------- @@ -155,7 +155,7 @@ Citing If you use SVO in an academic context, please cite the following publication: - @article{Pomerleau12comp, + @article{Forster2014ICRA, author = {Forster, Christian and Pizzoli, Matia and Scaramuzza, Davide}, title = {{SVO: Fast Semi-Direct Monocular Visual Odometry}}, journal = {IEEE International Conference on Robotics and Automation (ICRA)}, From 1b2f50614040e1528dd82a4a5c6d831b3d07629b Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 19:47:36 +0100 Subject: [PATCH 011/215] added paper --- Forster2014ICRA.pdf | Bin 0 -> 1469859 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Forster2014ICRA.pdf diff --git a/Forster2014ICRA.pdf b/Forster2014ICRA.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9567178028f06f0ec44135b5cca6f32241222f6b GIT binary patch literal 1469859 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

$Y#kbE)r+O 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�dq_33=;_VBQxjtfyO56_CA1f!!N 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

@n-nJ!yJuUVIu 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

5gpfilDPfeCsr#<1kNNVR24B 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

ujz+V^yTPam$YKVp>TJE^pN6d_>lMxPM*Tz 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%0AMW2 z8Cxlm?gI_^6;qjaS^x`Dd}&?DKOuA;M2w3YK|Q-?yTP`3gB{brc<1xe9{l-r->vsP^a?w;dTlE^; z7cEz_A4l=4$`|8JMh7Ck88kb~c2lal9TiZAC`f5MG)V7$wvny3`0=?{$GPIhZ(ral znXk)j_?GcMUkPuBt^X5B-?IBY)K7lM`ydZK%rTNi()+*Z5#%>(#aY!-MLifUm!Hke z%uu^qM%a$;z z=2dh}YDc0wORBP}-0-yBKR()Ih>dJIN*#I+2LI z3Rq*>jQrs#Z^0uJ;a6w6CVKBKYbG4dj{qs)=qOrz@D9yS>_s1vSEg*ubZISSCSv9O zAc9oQmcPbY<$AcVGuvn;~L1}JnURSjPi-U%*(G0EERa! z9}T$SUrT2oKj*EA7SN{>)_sD!Fd?I4)hOQt_zFH`>R$srv}|quNMb7*FoGf^^>Hl; zkk8SZLkjKP>NkvR1WMq6_h4+xHJ;r=TpWeHr2MH7CDX5C>tXb5PCVmb$11i2r;mgr7^Fn2o+`k*Nw0 z8Y_XMyNPf@YE7Y_q9Ew_gi+Z~!Clli3S`PqNIiEKzR|>@@i3>j`whK#U8Zp*?xsd3 z>5G3Mb`Erwj`Z%;4>CE5QZIH|Al^>z6=(H1HC7GYz-39G+Bw_$U^JZ%k7IlB4uHU} zTLq4;#sggg)CbV2R%bAcd~aK0ciN3c-NZ6Mi{tF0W;;m=XDp|HWwRH-lbU3=8UwM? z(dJD49#Zv5zQp~eu27c$w$}%l(rq&r_R2tKT2hT)l!;dX;*SrcF!WNnKPEFo2pM(0 zx01RDjM2W^`#onVWGz~r?Gr<7UwAN=1M=Rp@a^Jucg2A;)75W(*@{9`mGw1HdpR67 znk~Ii5Dpvw4it{hBF1T_du@J*O)@&bS{h1?aj4BzvK&|KQE}@-lP8i_+Mklhvvghi zs<@+&qF~F=cX|`WiJtO_Iqgg=INmi}xE(C(C3yIPmW@7)a#M$$t$HF_8j7mwu0rR` zjl?gMnQX67w(;dng9lAjxmcQ?F14`|^9?+W-1HO7V6&Yw*o0LotQI-hZ?#yH9H37k zH;H|+!*sFm-+0jMJnw=ssXEc!0S(AU`TPULq@lRJDbY?h4922$ku9qRGyPl}`6Lc# z1%r)jyII?Eubw%OdiO5}n|D<#*W44$x359x`I;zYXouw@!B_>doUf+Zl+|iOn$keK zB$G$i`l_eLCL9+j6!#D%986&gj7$_rW^?!C)6rspL_26&9s4%;11_xA$3wRq$+` z2s9t@!NnCTf3JTjKuXTMSJyP*OtV~5baD4KAAZ~E{+wmJq+@itEU9BfTYs}Xr^SUe zIHlEszF3hqbb5c8UsO~;%S0l~z|d$HkA4LA&mlB_+P$LWE>OEQGlMPB5Nn0AyB8!- zdR5QBUQqdQamNm3t~vXoj!b9SvyeM!#(uq;(>E z4v_ULQjb_`{;3p!u`O3bQVBfn%Z0@?!tKjZl`$8MOO1^D;yM z@8ask@YHRfzqC?Zacp+u?~m7YZP}i3t}O{_`+?CtT;r%peRKALR7_Ym~#P$vit|j0(vy+EVE90i#N>dMv z^UDO4KyIE`U{mJPQJPI!sOzm6>s@~89|bT)!56bOT0Y}6ju;?_odyCqG#;hIzr%iW z<)Cln1ZLD&UY(8Dw_(*(fSj=84a39uzCrV_?;0lR(LE zOA9dxPO!Ccstj#9paojzAI7$*-Y7ApCS1-TsS~!1zL7NW^#Y7g>*SsmlXv^XdqRjU z%rplc*?;y-20adKVKrr9ZlGF;G^7K?o8m+!oA>GgxiBkgbeIMu?>(69dLn+5^qHW{ zqkQaUgrgh_$)rmVdW&s1C-x)~bVX6@jtO zSRZSv=3s~}4E)$_4HCJfJTb|b4nA)qxmz+mo`0_v+(5~z5=^3YEG5QEvr1q~Ni7Sv}xbr^PE`3Zdv7HY=LW33HrUlqWH1!SGy!yT( z&NEn`5vGX7D9VfEL7$1Wl~$7^w#joHJ&QUih~{-s9Z{xXkklo8&bG#qg0^W>2I+U+ zybi#2r=P))eG2DBzIcmdH|~wijQ&QkYmFo``+E|O{*y6-i83L+Ir3Oy_L#VV*9&bp(&hb>y-fK+ z-jk3;#*I20A}jDj;JFF&51>0I0HU*vE$7k}w|VHUHH!jD_SJ#e#3p2@-$< z_nu|10kb&$45l}ypG8i3p#wTXmQ<{c7vyH!@{kgFm;&LGynIy`PvU2o^}Mz2ZX*f@V8ARqR<%>k*bL+Kb|uOu>}LUX^o*LG)Fdnq2Uy75Km|2A z7<(72kQ{D;qB;DhzdYh`Tks6_Lsr2Y`tPf>P>rMz{Q)Ks9T+)X3uE5sA7C?q?#Nd$ zKNp}p z@o2y6zF6UI(1Jcd! z^{BPemxFD;3+HdSea|(Y94-8VoDJROKAKOzDE%Kgw*Ne6!++ou2vqL_gN3}3GLc4g zcTOAjn3##B=>61qrE#KgB#U$Imk{C1wNr&C(VI{o;Lp;O=p|Lmv{Tm&enE9SYy8*kYg-5QHeV8F#trn83(Z_|Jk>mX z+4Hp4v!SRV2dkOH2dtzyy9SQb2Vv?sb^Nt($$7j}!1;}X>b!RQ8U;oez~~FB+j}Ac zj?<9B32PJmx;vyaQ7)O`O99KMAEy}1(x_M!0G=Fj8E>+zI7rLmKdbDKN!jV=WQTVX z2S{alZLBY^T_1O+580AT_D%_RfzIuA?Zt1&9kd3fkaiqSv{0_IhwwtK_&z=N?+KSh z-|MKvCOMEEdlr=cApAh-gQC3^{0gK{Fm}VhRYgwQo6gyWL(0(=r*EuB%3Dv7k|>|8v85J#tKh~S*OI4 zT9`Xt@<_yz5L^P*+kS9IVMt8LUrKGz;ND9!XE8G#P>=p*{{_jbMDb~BCZb@tuSNb*FMbQyCF*`ym&H`p>cRl?hC6haBEkVcXoWry=S%8wL_<2TfS z{kR83^x_CA-Y1UDn+)&0w2u6$ClQhJ7AaFV@1#`Ku3;8{}_f zxYEf`PcuwUo$r-xU+2XE+2a@v}& za#^df4I#}~xbs@?ly?b@{)WZGZ!?TzEn=FdzgqrmSf_k)bI~@7oz*-owIxq3^C^f7 zo>Um&qllp@X{&)0++8~J-DU;WBP3%7A&ZSG6_!$~T&Ns+@HyWLT0kkK}YbR*mb%H`bsC72<*}!Q^a=#K6ZZF>x&rMR-rN z@n{H#c}!r!wS5KyHm4!=&Lu8DnTZ_81=D?k4`g_=$`NY=qH3Tu8tAVyc+Th@-!q@UsXG2F zzVWQcTl08#v5(~AnYo7{Axpta2prwvkElbO~*(3fhS-+b*7sC?A(RTgb6qrRrW zh5jIaww~70Y*0iMM@ko6Nk_)pnJia!bXJA_zLT}^pOqYMbVxP9K8~EBR+fJ_lh;si zFIuiJ!;C7|S-Cm+^%v34Qja=l5hPrd-2~ZZ ztt+Z$EJ(&zG!$VG2;$t>CtN7}FJwqT4!xdo%8I%7DdTVC7j+dvqP$}Ug4Og)Lb{W~ zx1|h(vRFPd7V(dF6g#&HlwGzb#Qk=mFHq&a{Rj0*4?plOWDp1R6wFw*-ti=rhjYs( zz9~zpek1`*v}7MpnifxZeBm#eqpeO!@BLbfrZMp&C2KJ9Yv?CU2|e;@H!_OHVq0k! zc}&^UoOWXycHNXP_o0<=1a?WnE_xbL6lBS1oyOVAE%Y|ACu_AjJGF~|g`xfJJhG-T zojhSrw*HTJ>D^jStKX@jSxTv>Rv8b9GM8^R4NuwC6S}c$|WQCwp1Ev1l2A$(#=fwd1csqnOv+o6d2qvt_;akQ_zBJ?@3we zB9wSt?S<3ECSF)2eeN-a`(`oqMs13N8MFg_cYi}B=^G|M1?|jBVE@a7^I)IJU>_;8 z*_oyxdNEIRrx%S;7&NC$qol9mUJ^Tyng~);=;JQE)#2wpY^rqsxsRm%!~Sz0iCp{r z`E+q2ruxdHY{Fk2%@Zm9&1^{&?JX90!nNOB$cA@z^hIZfi`_flwk;qH?|SJ~!&lW? za44F7$g`Hw$$I#$!#ES!p6FNaVMJ^qYm#wtK(IL`+_vyr8@)V9=H0M}eF$GK%@qoF z=hE0NNdS#BAGE40w`zZ4Vy0|1Q-S(#)q^7!a|YeUmhyTV$v7Z2*JFm^rqufK&IhKa zC9N;KGO~Lj4u%01la6lkxp1r=Y=FaWa2n#uTqNd;R{!~CTXWA?E|;Hqi*ia|8`C#q z)Jf;NZNe^y35HMeZi^*+$7VW5U^E226c*qp2JKGid1OMBz4K+n3~-Ws5u31z;S|pI zMd7BwjfDO|0rW6{OAc7Qr@Y9)1JdF{uxz^IdcZt+P2Do!>~!(Ia6%~1N;qQF_G797 zt>TheH}`E*GtlWUcf&JtNFE&_$b=XgMv4TE9nf0lI1R)XAL9VWI^nKJLq78TA-b?; z`uMAx8=|QJ&%9r&-_T>~V!g{49vePi{qqlsX{>(6N^z_cx$y3!tI0rwpu;6ny1@DP z`|Mt6y7Ue{u55yS+dn9rZ0I}xyvNh8-l%GwF(DXWEMwb*R$$6@76$GknG;`l_>*Bj zLd&}#lt{}ZIb-sS|1=&BHrU%?_=NLXh0dz;fZ_<*bCc?(|{FAskq<&hA&((y`^z1 znK>Yb+q}m8;+pPNqkSLvKLNpVWURpEE)7*ASMh6U;$EjJZ(|{S2 zY(OS~bvF-Ecz!X>!Sn-#p^`J&=DEBk3|u9+o;0I3(e&Dw0m?U@$w$6|O#psX!VuO* z0kMS+f<`P2e31{YW7=Eb^^xi%fmwBlZ#{@0@DSq9%R z;X$0}2U_v1um1$U>#S${Q=P1}#s+y~ak73=)nX!EMvAxjC4~(5^W8&J^z;x6+t))= zdzv&In5ibtK&S>qmZfnx*!24j3NX72N4*duQhEnU)|lZmAy z4v>ihR<}xsC31-Tx~A_EpgQDsi^Q};tG`~i*>ZJx&8RMjsjLw zW~Snl=!r$}zEMIO^H)o*$-X#$DfDAm0n(ZONnvg@iGz5zrX-HSuY7n`%rkAdZUC)Q z+(`KsVNXy64ZtT9;dHge8KF&-e)zy5>9G+%ok&K3B--y{%4d zy-%z~sG(b0LwV?CxwlI zDpwUFoWXg}Na2NpoBB7hSPJrvj!AZmJigD%3ELWqUJXND?F^ysau}Xp$NhsEYcN|n zg*y(I47@5SPA2wr1^irgn-dL!6BWs6J#rU@mO5l1i^+4id8i#`l{e17d{l2 z|InbJ-%`upu~ms`Ft%dXV>hZiH79O(pEsMI;TIHHHbPcx^t-5xNrK_YqZ?bgWOY0! zPy89BBZonzQ3`?rR{3VVH6z_@c_ot{0fN-A_*?7EEV`Q%8t(7^r}FFz#?N?uZ;}-r z4FgJkiDW{D1p!q{o4r^WUScOPH0mE6Z*r(fx_eTzWa6M^R%5us27|y7kg+_FdSWGl zCx$UP${>g!b69rjMIXl_=4I%LKDS14TdWMtHM9IflVLbXpS8-=Apo^pohK6kBC00{`nm8(Y{3 z8kmRzDPRJHl95_GOm8XQA01+4$GUH-i6o{U;Gu1&Q1I<3H8R@5vvzfy@%E#NSa``4 zW22KZ^nRf1o>jzsnTE&Nq(27YT1Q5&p|4%nE)sc=x{^z6C3DJs@INzlu5$Pu~B~4 zqdXO1G}HR}j(U|vnkH#8u%|MEqK!qrgm0E^L*e0CyQ874ZF;+5QSNL;y>}v8ZBgD? zV83n3+=d26YsEx?uTg9=n%eXPNT-u!7C$oJEo=k!P;V;3RfkKiC!1c9DeTfVQee4TK$}>LZQZ5udI!lAN z4_UO$aB;afe}&)KeMiIRPrs(X9%`&PgfFlqu@lJj+A+MO&8b*kQ>rq=HyZFSO~E72 z4|VE(r6zs!v=0&-d7`S}aIeFf`8H)j#xq>049~19@x)%ZF6Zf#vQ5H*NW*7lX@j3P z!0X&EHB7AOmS0v^@(*IM=i5u`r_qZ$(%JKu^e1K0PfaLiO8o3?hAI1Ll9dbRV-S*G z|u9^v480Z2D_lNNYC*9#|#Fnb3g;8jO(Y|Heu;UQynu1`a?e2JpR(`z% z%zxD*tsxuk6<~!V4py-_N)w_670<0!L6UYsKi*>vNWtqS6%OLx!oiq331_c0qi1U- z`Jw9NAjD&3_v-G4XZ|*l0bbhUpPUQt1A`L`Ll(addoKbFq#%O4JS|IByLdOY-cb4n zl+ZVI%_^q4E+b@rI6eM+=Vr+j8MeDZB`MwOrdiSlCyM>ox~z_)BW1z~srcU%Nz zPK%vW;wONadm_HU`&{<2=P`&XXDjk5rvI)2+^;-WzGPfuKSZF#D06r!btMA`r+7ft zL63D3tc|wV#UgE#va}foVH{fryluv~!%X&`rUGP?w5dR3vES2+!mAS-c?WT? zRlvRo@{VmrS_=1`A_%k%6qWxz2ah&Ixk167N+Ad|Ba}t1U1~I|YYhmZChZllzzZ94 zEVtxW!b=fS4V!Y%Lh!6A7Y|D|28bX-QoNeNJ!iI&@DFJ;@`A%S2E!9TVV=k>Z86To z9ps?_JzRQa`vaiClyM^7kw{;Xr*S2Cpig-0CP`?sP&Z-h+Ge^%&mr+0mc?m|($fJa z#fKBk~1;Q|5Fu&!O{*T(4qGct ziNaKbiNH*>zl%H%V0h6CgIj6NwPPgYL0Zj?m9gOo`MY?Q!fgBSj~KSPt$8s%NnKBM zVm-gaiWdJq~LS6%Tbt8Vm%;fd)A1-G*GoCry86ast;mmYk0MlIOKnaJ_M^?bkKilkfQPTEsKucF|lGpxz7gNfh{-xv5eKBqi znRiX5Ob=cBlyCxW^hV3}@pWs~dY*ZwfJ+(k5=Q=j#v+Fn8nElN`8o*+(6?%O1Z`(` zVrF=Zh7&2tDfZ|Wbo6}H&#Na;Tow)M{fc1ViyZJXvB+QX9?|)xOr(3ZclO-hdvqVk zB?xkCe`8Rl2)F5r?4Aka*Bd*Y?!mUzV@@HTgGEK`-_=(WBG(OMhAi zP{7FRGP)}m4$({>^%`X2RXz(WMYrn|BO?|xd@QVvOKKNMJpe985m%o|{^~!YIMfFs zP^uVP;7tHEfPR=}^A5?r0G|3{=a>Aph{zI~)WXj|lBH`B&BB~Mld1vZO&bn$E6%<~ z9*7_dN%#BS!RUhWl<~=XF$|7`mBpArHV|9uTVtsdefv~d3?*N;$<7^*i|mS$PzdD) zC8)W*RtEnL401Zum?_5Zxkc?9dRD{G zO3tU9AP+~rmtJ&m-<=vr&gXDE8!`L=TNMh|Be3R4z`_B$FscU+R&>JHNRX_LR)egO z!sSsD)h_I425#}6C?Lto3?*ueHX0N@rtSnqDqfZUB!pmT>TF*kXDCmcL{PqMe5JA5 z^;~}!AWp8MYswlrg(Yr0gbvcv9MD=@DwTXatk*7*GGL9W7@^R^u&xJJV2@pV^j}`G{uT(fHN8`nZ!^yIfA9&dd87DwsI%(F zw!86qAJ$ljzZ5VHKFs$e0@`zR=P(3*@v4F=t5U$DkjzKl5LEnZEAD%y(m$vFQ+LSj zZ>u?M2P2D#2|WKp8=Va;KVob1b!ZD2_z8ApqHQ5_PQ+}H9b;=j3uOcCWoD zH_w3mXneBLe9{wMDX3u64iNf$blPdhw__hu^V@q4A`pxbTerr{ZO%|bOq4Cgg|Y}N zv)Xvo)R^V~k6elrOz;N>x%+vvXq)4Lz&Jx7JFQ@m2o$PawEa|P(*%-*QDLz!9ny`k zWl<3c+N=_fv)*!&swtlq25VzG5>_kl|Kqr z)$;dE)Zdi)jKiK8u!{Cs9ZNiA`}P1ZWs+m3>y1=v6OC`jN3T9wuT{Nq+#0Yl4%q!! zry+R~%vIhXOVhok@OA|K?U+PjHa|<$(frDt;kh1ZJ{d-rZyUkP4-kn=)SZN5`HF{d z_s?e|yT^MS#vwf(C3#TR`o$Wxo5s@DX;r9^Bh7yWm)Y~vV@JW)SyV$~z4GVYh13M} zx|Ny_ZAKrK2vw<4{`V_9_*=6IO~O5$V<#@{a>YOKUYuK%TW6J3W?6r5-zX?@5*sj7 z>3K;W$}Mw7Ub6UuVu<~sr#s#gUeJLK(osLPNQyH#JI7qLWAKn7#yPa}rY5kV;;+CT zQ#dF0(t96-YGgr{ag?uI97ieN&egORM!#p#x<3S*=E|JG_V12)toD%i}znA83UuelA?v&)EKo-S$YS ze7dd)(s@swOupn4YSsTPv)`qqTvCBG5)fmphyw<8qq&(o50HwYK<%k^LP$~VVVEDq z0IXg{E8*j5!8iCMX-%kj8=pVd?fU2f)-9rZD$NL70dWz6PE@HMQ{w+eWh&eq_~JmoshosX_lBiDHP_8ZlO z$eRo<3`S?gTRM2*w(=Xr$KLt#To2o`b7n7W+=PgnOkEsSnlc6Ry&nBJ+88mACm6Jc zX$lE=tK(zp7t8e9i#+s^^r4<@UnU_LPOjl{wk2fOZjbzO9${1aqUFMz~L6JxgMPoHcmdn zx|@6vuZf4a?^2SgCjUXX^m8wc33FEy42x7xB$31IqGxeIb7-c@=lB^eBukQ=AO`eL zOd3~ayy)IK^bJ9v+eH0YP^Sr-12{1AkLa=4#(69S7=Toh^v2FYNQ|DmD90CtWrWD0 zN*N?O4GViltUiNPJ-F3?!5&i5#=4$DDb<(OnI<;Y0RfPZrQ&m3`scB_bl6YEkff}{ zl2J@0;fBCFM3iL}oC?f4u>(` z^CQ5b4qAxMpDL4*>X7DpA`)OGquV0IyY?Vn&2`P6Y=o*Q(>zDO67l%Ga}jfaQ%ZXE zttn_usqnuHJbkt1zq}H7#USxfOE=Qj&P@;mv<46(6E+E+uKi=QA%xa=Vn ztSPcMtemhRU~s^;mYM`x9TYBwOOd-mSxW>Zj=%pw=?F3nmw3WeGWu5-#n-p& zh8>m%67qgd0~#_eUFI_RJ|BW=-uh&jGr6}M4vkWU_XiTBb zj{xUAd{z-Tz=n}5gCI~a+PRsYaDde}63JSUZ^S|2XPolywDZNDaiSGpZ2B2U*+;}d ziGG5XW}DYPQ5XgzzA|apSV-a)8@HZ7Y9~nL>}u>Cq&V~ltTbqB`TS~ervx-0xzNmf z%H0GqEja|S!FUzqSy=uh%&6skL_IbQy|z&PUn8h00c#Xw(!A+Vj7@)GGY#@b!?!O4 z3*y1VJ=<$wuk|z$iNY{U{gj^q+=!eQwwA;?UyziGBsg{$z)#V0w=JBU0)~&gdpb*> zQ$D;!-m`cxO4czY0T2i>T)uQ3`rbf%E|lC%66Z$>4DV0iH`NKRNqinBLZm!V+*Er% zQMkJpVci#!+8Awk_N|E-;efT0BsIK{bs7h$K)l9D0)ao@V)QUSx4Kq(xV3$`Y~)m% z(e~_p-QvxJJ(*7Lf)88g&*Qqqpwqkk9$eP^g^uG;%5Mz>l4@hMD#NTIPncuMuM_JF zN<&w5VY56X2Ua+%XbvV}UcJ=oA^qVvzdvczXtO+RRo?JS5k|j8)aCbkT=W|nMe1H1 zx%2o-YvK0e6UHR^>Rx@wI;&YV&16PuhxStb;Au&&arKeyi3~Hlc#}H(K+s{$ha{g;|hg^-4TRX^c zrRDZMdd@i!f0C%aqnd(Sd}F8%(LbnZB^n?3XvM-db3vrD=w;P>u0&~9yA=9JDHg-T zBr`UB=qGhNGFDckB0>aKFJju@z-~00W%$DD5%px?#&V9*6TAOSJ6K1I_pz6Q8D9p^ z{=O0_b!|uq5U*3cew-M0cipCHF0aJ88Q$Czy0`I~-jnObAcev#!4hZ?WTPbYpI4wC zx-U6B;R{iH@)e9doo2AR|39^R{@hEuh_t0_2=^ioKsdcJU_;Getk?iAhwe~~Cmamml0Q}LYxsGKx;ejeN*VeMwzDguP3w=n9aUEyn zKVSKRF`3`KsUJ>95VeKT!uAA(Kp3BH-y%vlk>wM6GbQTUPkh*1bC?hxRpG(t$wc50(oT_oKH+`Ju(XegZqhWbbLUW ze)y9v@X+Q-ja+_P{zSkrScfcaj zl0gukOUJO}u{snn>s+FPr43GAu)+%SK~g9u)Ya`8r9;PsO$`j$=hb3WG5sRt6@c>@ zn(r6{%8kiFOvrguB*^?$WR^>bo(mY^@e53h3SNA|%PH;Erh7zjx*9|!tK>_PN}@>V zk2Oh)GyI`2`1OdcE)DJ?ahb-CcEYs48n?u1Gy9)|0-W#XSIjdtdVX+-K(X*^U7Ry` zk6jPAxQ<0$Vm1z~uw9Z40SC%M2UmsUrLwTpEtimzIivtZ0~%-dERDDnNTD5qE6-=x zCJ|S@+0;uDi!GGJ(U!ItLe}3gFt8~mu5wA8q6kBkm2lAJf45r1LGR!667EKc;~=0_ zFk{y8NFA5wNnlwIMJ~%JF^T(Rx&;0 zTZ5d0s^8k!N><){8M7*07YzB2uq#jm{~+>!NH>~Un(hR8EEJKyY^rURg58J|@OwKA zZht_d>LL6CHdJM_d~-c>1*K%TlaPwto}IHz%eG#M1G=ec__`w>1F0ozmJ^hxq3A6B zX~g3zk`rMPT=K9wYRk)%`s!^nLlmnLfuJjVXw`FyFl1da`a{RFr*~y_ZUvcLMQphq zbqnXZ1GlE$rkc-2`M)-#moL-Q5qMi|(eyC9=Q*5Dt~L~UsBAEG)SbzTPfzQvt(cTG zqvgoyhqGyGpNG(yPwduyhroTTa$O89y=g1Np`p&j#&kdnelH|Q&tkAhmkw|<-7@8i z3K*`|z4=6*2#O!U#_WcCG=zUZ+9gUlNCiK6ooNVLyu{NeOJCs?FH;rgfe1m7R`O|U znLo+bd^E6z2vPIk`>T&P=6Q-BZW4Uh)jZy@!UWb^-pl#-5`}QaSsQvp2x+yAMtSes zccw(&_XWFm7;!mj=(~x%aP{*@L;Z3e=AhE^vY29^% zYEIDPjYYQ*r|T&c^2hDrY&WA*j$u5_X(ny?E2>2)d5CBAA9K-KS0j3_N;k_o$ilO> zq+%cTIs)eMqj%5F2E9tF<1R<9JV^CZg7xah0Bw7!qX)Rv`A4udZi{kdxE(A<&uXb| z#g*l{z$5KaF~jV6X;XZv0<&ASS`6N=s>t=Uv}2AZ%-KnD-aqz4D>q&8dLeCi5>n&F z8A&hK-x=)tG4qzdQgM?oly*Vx_}ff@5Gypq^2WthA{-#?qBZ0M9mP2&Ab)Hk*&3U#2e^rx%#VEX(Xe=9lOv9=#@ zr?$_swiA7uI@@j-5zK7RPOsv5FY!Qnh+Z&xz=lg@A@k}#VjflSD{bz z5F-=P+C3osibs8-R0Nf^=j8zT6D`qsBVTeu`A?Yg(NjDTWDQLBSTkMwkZd8j{$kXj zpP_G3H>CtA<={e__avD5*hdGTpY~2(fxJ%*qk#SyqgLnFjp{$h1Zr`ZEsaYUV66pu z^auT-i#E@DZ7!fyuw0XjfeSQOz2aQm^h04ZXC{!#&9UF){4D{vA&eOD*isjFGxQ?_ zp_^ZlFnNL~2sA2QY%yF!s+a2ZO67H zZbs{WMnz_dY`07FC&R)Hdc7#R=#zDF-VS@(30`Kk-B@0!Q8?Qt2&Rs!v!jqa(W8qq zSz2u!L2l!X)ls6uk^dy)S8a97nUJnG2fn!+9Si92UNS>JQrit$~IU%DfwR*CEuLuH8bv}wnum1w$goXx9 zAA>(^NLR$PXON7C6q6iMK3R1C=- zOM;G6B*PrdM$<|#e9&@m2(r0}uC=4jz}(b${p&S2resU&AA514O>kN#8j8~ZQBs~= zoJBg#Uw!C{qG!}2zE$mlh#BXRSx!X9=`%(ic-gb2DvpnJ&i>NwH2pq;zH5$;Ex;$X zxT6;e&zXB}=fB-o7B$8nxqp^=v|frC4nS3H1oYRyOS`P%f8*kXJbxzY9|vB`J(VS( z5;UJik7>xP&oPuB&iqsKboIUUVX9P`SI@bT?W4|LonF3W{^g)i6eHOAy2CYP6l;Do z%YT=K&YY$th%ot$el#mJ>vO&K6*=xA&e4?Muu6JHJ$TaToIC(9YDzJlN6eIA`D=kRM0{>H(*rx?h< zBkyFpHqAO@vywv0LD5s;nq;hru*w9qicG(Z)G0-e@jOxd6}^&%!AZ?9}JBmxo<=#H%iU-xIQJO01g?mbU4NZ)?eM56af;PPjb z1hmT$5d^&o1C1CPGpoLkF#mr#EpDvX-o!oD$CXTC#h=HQ+XJT6(KW(!xt6`72-=V0 zXy;By`C1lIri>aGbIQly8?qU#7LNXfvRHvSs)IZ~S(-kk8Dr4H9T7rb6~nrxA52KM zqvWlP`0 zq<%VENt&A&>qejsu8OE}UdLjTMa8%jH=fiyM7ae~zAbDT9 zt|<7_rob`;Hh}L?ZOCCp|MWsmbUm3_%MUTD=Hhy3L<*3bdH-AX0=D#12#ZkN- zcI!4CU)%Pk_YkDhyba0}wk$jQU`06LtypjpvhRAq|&&4%3=l8<~Z*9ZuEmz-(6r^W$lhqTPfjNt+_}@ z0vYl`YV_IT2V$c`N^dzG-z#2A9M$r^Y-AO!t}Y2DHgOZP&We8G_;%3SllNk5B+d(4 zYb>*xpc2F4Tv*tiQ@AA-MQB%F7}&NnO8$Q|y=7dKZQH$l4&5c)Fmy>tBLhlzcY}0y zI-sB+jdYFDf^>=qNOy=dNQZ<92m*rts{p3&iBxmi%zSi2-4~rB*6%<~vri-T@ zw_0_)Uz!ktfthwpFx5p!Ws8364T?y|RU9!kwrl9bUMG?Z)mK<3wEP;SJr;OqyM|wo~a%68{#coEP*BG_iSYiyUYB|ZZ$Nj3kP ziea{tinhiSnkIb7LZ&{;h@KI=MLkqGGRZsI^j>cN?ehgNC8O(-IVL{EKxuz~{huau z$c`VytIA-K+d$BW1g9OmC6$|~?C$P|#2gZ<6V{%n|AUAxH6e#pOJzJZoA7R%Uvn`P zROilX7Y?VSE%aFMdK6*aVO*1oi3+X4U1tT_ZYF1!&PL!HaG`gOi}{qDrK7qp$p0e8 z(+pc)_|G`zA4^0E%j^>cO{#zs1`| z&4@CqDx1I^`x=&^h2Tg>0|k^XSz@pB*jEMC%M*TS;C!^C|KN~$dC`$8sn1uQPYZ2l z6wj_{2_7#Y*{Ar)CVs6Q#BYH^B!69tYMCk4MY=TT-Eo?v`y4-}Y6zOQ*uK;ZoUv@9 zNr0+`zde=9kKq^^5^xziBy&frl%GPn8UX^0IQ&|NO5k9g(3d@jnoMc+MQbM&jb(A0 zA)`f}DWSlJm#rIBuXBI(-RctU9*m34>+rgX1yS0avZDZR+Qp3aCo(aeWYWcoJ(nRrLZc|LHB$QU^`7zk&hjIE(~x{t5C2JV(h9!-Sj2IV^~@0jMMV$ zZOetGh!~w-NQ&0&7{*bvCB4432$Xz9SF!YyEkP{3pFbspc=n0l@(|q4K>WRqNvXZJ zI$w{xollXPD$bYoD9!eiXxu%THz=hC{lh5(FONwXyj{?w7#?mIk+88Mf)B=Jd#9Qs zJX=YAzzK?Zt@I|mKYdyBbKCz14gGrB`ctj8-gkcbqRU=HlkJ5@!u-2rk4xr{8SCjI z0YjoVxdR*Qef*3*2r7qGN2nWBs|EIiMc*iZs^D1S-DY;`n6^=_zx1GX^6w;3Iq?RM zQ9yn`q*rrCd{xHbc<5l8X6v@hsg%Cgm=rF_g5mJ83NHUh@<(ShZi;7H68d0Cun;XU zr`(Og7nX524w?vyLI{g3)Y+QQpN$isaY$$Rbjv_o45Pu}ScFLIJ;V!bs(j)xVH{Ve zmWUEj{m@3`0CBHP=VLxljG8JxtXcI zcmA-V3#5a!sJE1u2;yF>v5rELDh)YA;l)pkQCYHztgHV3&#-8)&CDh%DOKl&a*QS1 zFHjgR86^p?uR_H^k~FPhDH94$90Zou_oesL>{BE4+6TK_A@)-<^1NV$+NPT+n0H;1 z@G^C;N}q5B=m)L?4{tM9CMgPXT|EUB(ZSOONCr)8Wbtd`l|8!mSazT3#|}xnrtU} z8rTO7Ar7=75aUS?9*I8DkCpKmhZG6iyEA${B-jAXFVNHD{@v7J8)uh3fO`fm<=0th zZYNZO24`~%Y14@YCByF3XU7K!{EOBnEo}xYuaA0AxX)Q-jn;fd#uh?lbxstYqVVvXni!~#I6Vx8DS*Y97!({OOd#n}SPz-OwiW0Zo9+xByN5RrGiRCj!M44%Df%~u-HX}t0zKgP$yiwTs z{n-Lysh6(RRBW-2&kTfb>{1B1=~f!hk;JS>ju1n8N5Xty29LGRRFcpg>W7rczjd(0 zO$2Wu=`D_+({>cjSij?Xp{(>2%nuH+BgBc?ejo_b^mnn@j^X(_=&DMA7Qey5nBZij zLK!__3XLa&412$~6Cyp5PjB5}P^5ciM7EP%wjclQ4ERMg{po1P9=G*UtWOCJ)AwHj z{|y!Yx{GaEcntF?7pzVKzy0N;Bp||5I3+#4ADu0M!pJnHJ|Tp(hSJS*aF=?)%;M^R zP=8j40$GW&;GG=H$SeBYm=y)K;PBzo^o1Gx6}HbU*rEec5((b|wB$h}($tdqa%NoF znB%?lgQ*mO65Avea` zaF_Wf+jb~G;8}Re?=)80cB8PWJ)ik_lrz9kgw!>foo!Ccfb76yp_2Z1toAGkxOH-N zj|xoVmOwcI+PL)a85;hZL56-v$G!2a$9^1AzE6WKqX&D5)tk9nFrZ+vm)?)YoH}p> zN&x6coM9~5QjP%64y_jUA8+cQgzbOeK^L`)31ID!d<_;_OHHs7|NpB>{_FHXB|NN( zwNK`=-RSilFsDT2ZnWG>L`^j@y!0UX6eu}phT*a>hC1>zUqgzPVwNNc>Yz`}YM$0a z_8F!>r#}v(tUXdpDzuK=#X$3k|0ziG51RMkNh|LvN{`60-|?N`yuM=h!GUYY)6QSAL(#Y$lm)zPqiuJOIpE;oo#FbDQRh zulZ8Xd)Bv~eDKcLiZ7{BcDf6c7Bp$IcOLjC7W9|lV+VzOU0c#ZyM%XeO?pLF8GA2x zVkt9N^qIGQsfn{gG3hzOvRd@{5LpoO4zOgGr1kiCvTD|^paY6H?y7*L0TnvKd?y-{ zu+VetiK&NPq1d+FkB8p1;V20KvUwsYno^{rY=p}K$zhmNYGVTTp$h(cFFp-DVMB5> zO-O7#`dKU|m^QwoX6}@%M&;WfMZ@QOH#HzBQUnFtX|JQNwvSr3am&Z6hE&P~dJ<(d zaoB~vXu3uv^@(z`AZ_Z0k$;dg8wWs+(i&aPm@NSSg01BC6lQZvqsN0H2dgl}H2FP= z+Lx6H{U6QaGYenUUyZv*%5LS8cYag3I2SyQ`P{>@_K`H@A2jo6QM#y@bY)dhf>h%3 zEq4^=$BV=489|F*00I^8lw6I)aI~(cAJX;WgNt^97ZYUpaCa*5!~_T9mwE-sN{$zM zDqN3Lg@+sYhkskU;E{4`B?|XMW@zi~v~G2rfKU!^K{0q-CZ4{WPG!PvWWv?3Jmz(! zY^3G9U;ifU?~3*9{SI}l)pFbe7vE)G;41Dw2&q=PxIj1#p1e`b=Q;yKHhEIEm0zZnl5Rbd89>A>SR$X%LU5{ z8uw51PC2#-Wju#j-#8hz+qHZ*5^UokghU>7B`r}Q2g;n>9lK(Y0*4>mRZ_B79xC}Q zi^7uf>RY|W3vV$Y*Ag^3UAS;l`6&u}p&0))tTp7tb8xJD`=y!Jyd`a9mx*Tsi<X9|JbCUZ5wofyP46K$~D4$ zY+)e6C&ubZzEgGjbUS1r{2OjuMWtTBH(*PJOMjlb4){KnwRi76bE~}Nt$V0Zgl3|X zX8kMeXcO^<_8xdX(uG+GObe@&O|AH}=_%uL*%Se8xTvTNPX<*u5cBoFY({%X2aJ&I zci;O4knZ#9MOqDy)tQaN(EU6n$HH_l7&%+iD;NmAecGx3KE^K(aH>6ykN=J@`=lQt z=(5t6o5Gy3Y;A!`X#WrT{O|#>fS1ITPs_t5n7%=_spZS#6iM9#T7wHg1 z89bZEoIc#mjvFr|P>OK!Q1@sj`t;LeeZ<74>7_lbu=dRbv3vp@>;hMDEafrY4z}%U z{kbK~xa0oI#m6MEgq$?h%er$~eQG5xf1i{++xT7gB=<G-{0yHFc$>yWycH|${FQ|nUIsa>qZKKI6tFI6iYUDT+}fVa%^@^$8ZFa zj^ukf&D0ZuGTD#6;-S{cUO3G(Y9)9(fE-2;J2TVEu2G|;Y8zcXgOnU7s1YywNty(N zA3mRmEN_HmJpiA(?X#LL#)l^alS8>j#tqs#l?0;+=-{pRUNkJvoVZEt#u2___yfcs zIx0Qyg(vM$T}@9px;UB^Je-)MgS~)vvY6M`+rC|qi45ovMcRw@u$DDrSUF3_fB5|- zN`?yeg8d9@&)N*C!fYOW>5v+b|IBhw>2m#^`OOx`4!I^ z9x!eD7EbK1pHO^RZ|DICrkIv-oR?I(7yMjK-AkwyGW7uH6`k%dcqy5 zJ7!4M#MgF8a9^NNd{;1i89?)jp@P=PUrMfQnN=Rp2^KmT3_x3cY@GSeT1dcT=OQK&FfNUykkbtZHq(z*K;1vg8C!xPa8^q3q8c6DlLCRDzS}ji- z6yV~(^RXn!Va^SnY{&>jNHRXe-Uc08P7O+8ra3DbK=P@O8gS}^dQ~&&6vqJ^u!!-H zkHXt_aH77R!tf=>@D9PCh1lqduY8h-4-t4>9|^L%^}&H&C4Pk5iTNqGUm|HGb?BqZ zfk}JosW1tQ=RXAzHwEK)!Y?K>Xk1Rxu6zgVA!#!es5evdc9&o!-SPqVM0hAxLT!H6 zn1#gPHZyuyr-S!YbfHsBaQ&9ID)(0F^y`$a7r`50J%t2p zE0-u`r%X=_)HcJ2Yz5lyw^z}c-NFstZ;?2Q`a^|^OUlFXP-XbDkz9(SBe9L!)GPDWijBxwy!yq+~&|I1UNx!P^oVy%OuRn;}hdy*4i7yX`u#$!M>C6@D+I z*Y8&XaB-oD8{DX9`Ks6s2m=aFp)g$ap^~2bZ&2oita1!&_>S9-7CR(!V?41Q9JhI> zOw1G5`MWDUA~|(5xco->9=%AZr`zFpM0%KMAivBB>03QRczBW8wK#d9KR{@ zNY%SJkn9U{Gurn~ajwjpA*;-L97TJBoGUs$NzVbiO{yvWz{{WgjP9fkkTVv3*wp39 z^H7oz%;&ut_x>a4YY+-jjzgzHS95eQcD#x4>#IQRcK(Fe4ZK)sl_9JSXTwAjzeo1d zpfDk>>|L+ZKZw92^={gkBGNcv{bsJL-_#R-rCZ?`N@xM&USp+#o_iW~3NCosiy5s> zwaH=Gp1WswKiF{(lD_`@V=+o0V^_-UvNQ^83Hdf>`2iZf#oRZaUNzrPYEBy^c7KkF zvi7k*_hD}r7J@09?6FN@+{0YKlE(;mdjWfElU(=HZ?IGJ1-JEMj?JJrto1?G7oKl* z8+ax8Np++GD|eBEsmhs&`99CIjYQ8WALw$d-*S;uFT8H!e5wa-d@7#Wv&Im62BCsk zn94Dkz}$p0Y(~^G5H+XC^7Eq}9?^B%7uBTKCBO28b@w}2)i#uUH`}F-zx$k5P;1lC zj3u*|tYQ2jYp<40KRxZ6^yR5#a^XmD){Rna!$o+P^to5Vk#TDPjiSVO1isP3H_uSDxzPeD4DMu>q?4{vNRlOe*9OHblQ4yTVvn^-4|#hdP*{r- zv3g~~#$ZaJ^>#`Vp<~7_bCz#Qg@-&(u=_aX>GlX$KrQ(UJYfTad%^Amw*|(vlcNn0 zgBl6%Grj$mIx6N2QDq+r3-G3EG4<$#Px7A3FB&p4nawUNK2yHAhn4Gy)BB$=Aa*KG zEyy(qPSRuCgF}%33>mXPqbi97ZdMgr#+9?nMg$Jso^#J04GL47F`_;3#VQI+%=7mq`v2&&K1mA@GTZjB*S|_9_k$Bvu{-@2I_n2_YMcc5_tko)WbTXm55L zZ8&Bg03<~ziL?;m!&py%8O_4kG10OH;d6kaaZ6y*7Ue$?hj#_?a zI+%(AB~s6TIG<`9hV0}1EefMpv6H0sG8zon6NM>{EvGI3vxb;NKco;sAArJG?ucFh zj@XC8Z(pw1Gt;9Zs804A>n-FY4-OEFgEs=hyW(*G*C3Q|espd`ydhw$xLEj+i3 zoY}H>0!Gg7cLqvi;_UQE2Q*w&DK_**>;B-?SMPXS%W3^+KMQs*$IX~eg6I8=c)xl{ zJSl#XX>23#uX{`B+iS{SuKfe_p0v7OKS9?g!T7V(h zCt>U_6#F)HqqvH?$=YY_2kU}vm_R-7KZS+0leXQ2d{$UFgA{jvWTqlcHl!4?7mv1epQZCd zxVgfQd-q=8`B;1vdhMc~>1CZWXfF6hDLg&UZT@c@^Gs>%t|Gqu*>Sk7+^#I>iE zlUHp!fa{sgg|5O@@XDMskPA(PC0>t6?Oma)rYPp0;wa|V??^k+Q@CN-$+ROg4qOrg z(o>k(d{)Dz(?fy%p5hk9{CzKM`-C0`N&~c@L|3lmeE)I5mOfQ^k?z* zTxtX`Uyxcu!-!YUWPurjCM8!fD#}f<9{wa1aKO$O8|zI{p+?~^SuUw0G_c0%&eP|r z5GD#=%q=>)Or3sYlqkcb_C$4@eU`)_0*?q)TwJx91C7`@pl|W>>UYe{x!A>^ofZc= zhhdJbs_U|UUCwckeE94@6}=uKvtgJkr?Dv^zT9S^VOVyvDJdrrn@;}CGKy9TeL`OO zl|MX9+ZExi?idh(Bc$BGCW%1=!cOBCdE|r_zO))!@b}OYGZTwp(Z;^0oJc2Ne4lFn zc+cgnq^VMGHv`y=Gss5|6H%o{hl~S1@`6ekcWYvPG&qF3`(lN&k+h}FEjzug^k?f7 zg=dyK*4pKgLn-M^2Vi=8Sd$}$|x{7>+g%N z_j?vS)lT11xBQ@gtgB3jnPRs<*03Zp3!jpL4nv=>m+8X5i+UWehpeFDdlSKbtB5 zGi*3FNSElOvkirNez-`gAx_POO(2qM!>870#gM18k@Rr}-Pp9LHFind#m<&&=b3${ zpx~DQGNm+LHew<%Oz3k)sbS z{0gG>Vb<>sJ&&%EI7Z!e$q#O*SF3(odaTwAlobb%)A~-*tipYbZ`0S>Ps3BEw`=uP zdGD&)N7KBw>lzb7uQjbF!)lV2>5p3qD2qQfmFk?OT5Fa19p#1P|2{@}$iI!t#$-eP z&gHsckNWwXv;ws5mY_&T#3c?7ttE>FI&?00ySxPUhJI-XktN=*y87lNu){=&Z`hHh zGHi_KP)OjeS;>6>k4`9V{dUo`5;W_l~A;8a*i(Sc#tDI-Qw5^ar#E!npvhALa3@!p{M+g5kN? zj*k$*zRwG2KD~e^?ennSxBm(e!{uokdWLoX{C6l|3h;72p+Q5!ux*&$`*{E5Rn%S% z3H)CVBEe&O{X_ibma`+bKY^!Q9-elp=#|!18Rs5uZ+@5aRxhOxbeKLX?5t=@Slp7c zUlUeY-+Tp=i@li8&`+!mb?SuNtjq_+uesPAlHY(GnZxoDOmE1d>_k68O?)1KF={D)W5js)6u>$Z|iC)nA&!&mr$n*H5aEsxLQtEbYdSNH! z3~bCsl8J@*z)t^ zPlehQW!zW3OFy-$s$buwms4jl{R$dr9u5at#?%`p?yNp*%e-})DOF!oly^^llE|)x zhwq>wK|dG!wr_p>rk{ZeHa$eP#rXz6ziA%22g+i?eAuWt=^u#J){#oPOUe}Ksvfk> zwDUxK)&^>(vTRR4r zF-%RKp_#0M<1{bnz~?~-5HHo6GFEb!69T{rzLz&skDOSeunERkDn<|IMAw)`k-M}0*0AOItH|LEcAk*j_+xjIs1i725GcTE2zQi8+ zS+hJJI@Iq|YAT9c1%iG!C!taCE5jXrSt_?6QQCDjpX{w(PLLxx{K46NN%g6^q4ECW zj9g|lg5V(VP65-E!pPxE+_!hRtLp_IWV^ZKC40y1rBd(xhyaHW6) z*gB@zMJzN+=-%B=)gbd{tXeVHC$n4N7`7^i%hWcs={A!Q^|7dW0Q z8@1U#epek@XXJvNva${O?6mKJg+Sl52)RbxA%J9KbS9a6HN_RmPx}uB_98B(X=uE; z4QPKXHqjtNi2s!2Tom?9cvJH25WA$|WS5!C0?zuEr%n80<8Unb1eg_veVQ@@ySQ|C zr_8+l-kE!}WPzfde)Gp#(4{T9uJY!FmwV-19$kVH#lc3!4UVtXUhVVV>IW36(#wBO zw7J#Idz*de5^`4#sMKO7!t!1U3@I9pkd)+K09%ki+^Ho)lu%m72ZuluLEK1_O{U~Q zKhAx-Hb=};wWPHsk2+Qynu1);9c7K*D77s%oRNhIH5{6Dc1o0=~qnHKm z6$$t!uFfWMcWJkG#Z|CE71^qZ!L2Q1e1YcLw-@OrAt7Z>1Rr<;q>lFhMnb52LMdeX z%-qK36%A4Fd%2Bq-=hJE>&ThhFLzACfh^K8zsfpN%G zksQJ33q=qxTlUJt#&#`Gip(W$^9d7TX0+P$H8=;dI2PZFF?7ztCg_T!PBJrzbsQ_qnihVGuc~8Co6-()e1D~4Hrit4(||hLQ0fCYBm$f zHAhj^^erca=xl6;?~Y}iNL0Fse$RBt56r9lS#MD;_1t{-TT{9cAF^kRHoG6R>c1%O zhVW%i0?S-3<%%{lL=0qfEfi5Xc0DNNYJ0Na@VT%=2g5vCnkQ{!MF-9FGtEV8FFHuR zoV?|y@fNuS{5r^^#EFaUIcH|=J;7o7#L9^sudMRiqwo{A-k)QxVX9i+?rT3-$k=+^ z#`7n5lIFmwhB2$Ytn!Eb(&s6YP_?w6)~npW<)$0?ZIU%xIK0{2pX9-GCKZuM8`uEZ z*taFY+kRLPIitN_L*EsK$lVDSYB_#ZtI%JLL(R-8tyqE5Dj*JuhHY$f)q~D>g~DQS zb{h6d$p^k(f(G$y;{-;4*%3AsX>Ol7tO$bK%wEVgrKSmLR8f@&+7pej z>W*~nuK-XYfmr3!D`sf$9t5y*>0(v#6jQ*i!7*DO`@Zd=Ob5E|xK=mpoEMNf+jdAU zRZ;iugam*QUwMLOK*2k|hQ#tMflUGNhhY0;(#s4g7rAD1Mr$ba1zGciojlo2F4(UO zi}c}sh)qcJjDP?F_`c2oUVGXW18_GVR-$)}2!e@lrOVMTeKYyyzaD~F*#Fl;aR0A$ zAzDv6}3Oivy9g4v@bCxph_SCYq*Pzp6;un^&vG8-aHsG||fj$?#bwS@iQ(0L_}nPloBE#~OV9ufX@}(-w0qXN({MUK2K7>9@!c*3_I( z$Aj1+NA4|AbY`kbH8NsC9{WGxgFC`$y%oT^`&*Y@|4LZQen98|F>*2Iz1%SL50Y^Y zCdX+HF8v&Xmqz?Sw(`BnmlJmvWA9}%WrDuS?ewKj`Xa;MH-8bm4Gr(OFS038$W)uy zuhztv8+eozu;3M!JB@VH7JDogG|Tw={QT{Precw!8c{wufm_Jj>{XVo2WL5h>$r)< zs&YtRLq8Lqa6|>ktypk*`|6O+H!(2w%+KHFb8N)Ncq;r0+%xHzjrEE_H@C7C=tj;2 z1TE`TVj}rdXxYcdHpDXhrJf4+_Lf`vySS6u?`0b^cvt6${J?>INi&&QagKDJVr3uyImR0HQK)C4cupMk*ktUETqA} zkWSIo8jI^k&8V|6=%8++PXK57U1d>z`HOdpG-5i)=KwuJS-vac!5{_5~o(HFlc=p+gI8K6#j zU2VLpHlCH^bI})moVu;8@t4Acz4Um-6r;PFtNb%u#gejqa|Qi&xW7dcA`0|f3pLRR z#dS$XFM$@#TRvzpo^-Fhw<&Yd1NtrAY<6mzh9|S}GI!gAf|cX0=yFS=iDS}G#_2n)`dp6suptdONMU6|=L2#Mg8)M|!tl2f}4MA=KB_3r6A*5=2%fbH8ZD-z^NbxO-v%k0*Yf%XEtMhY&sqYDvJ(NDslI zT@oAxSzd+!NtPl9m7w(etx{fsv@p{jC%7RG^|}JHN&7ci+X^2jSrDOep&XVR&mG+; z+I%vuL+=MN?e6?L`2&uYAJJ!$T8Twycdy+Bmwr9h%!g@qL{WF8jZAPohIkmwWpW?2 z&;D^!eW7pEAvD;O1kz_@uCx|rnjfgg6sc3&oeylx=!qK1?taJd`6az3?0D@@vm3j! zz~bETYbJ^zFwxJ!3oeeVU`z4oK@oKws!@}r8(?qZo86pTFqkgKcMPj#GB^g#|u&Q3@tk&-yeCxCYXWZtML#nLq0+QSEWv3{JFpt*`n zK8Tk0%H)%$w~x26nDM{}ETfsFvOP17DttoWt;RU~BXX60_2J&wFAg_zfkbh||NHyS z{`qpS$HzY}&sZe!!sego#~1Pvy)y^}XDz2d<;2Rw&jar*|3edhFt4X9$FG)iTNko` zS>+s2&k0&sp;Rx5VMxH}n)uWjEa%;Kat!i=kJOD?+ib;%Br!l(!-Gwv8~u%>%qEg9 zqTI>N{B{a>Z<@)E*&84C5iNkOd25ZBw`B0=nMj_}5^p71{f?lu?y`dH<2U8yhb@7b zE}nK-+(jR-B-yU#hj()*ER1*pQ0IZi)9fG_yY+&1%crqVe*bv+t@?)tO@x|GaYoJy zNyQI->l&#t`H;_mYiO}j*@LI8p--cu@haRt;L5^QyOa`LS`Qb!{d5^R`+*>C&ETW%#a1wFlm)M49bi8q6Jt5_fK-ipa_F<;Z3`DJSb ztA2hRaV#eqBKg;Ku3L*dAhVz=Cy2`TC$?m*_>2AdlJ8*wo$p(V><2b1I9Q*(I~@2% z*lZQ?@^pWF@7dC)*EeWk%7KA^H8#(Y4jXMReJV66gcbX@2XDx}$LhJC<^?`+3m-Z6 z&^Tm~aQEXfe_IDl>!YXsY3c_glN(QnJM}s`uqQd7DMEYTA+G0JcHqP$0#kjH-{XYU zpOLSj!?rZsM+2s@pc9UltrBBj*DpP}6w;*8IY~TCS=>e5hd(}2BNCbHBrrR9crjJ! zg3IDSJrG>!7eD=K>G2a2MNjw!Z29*CZH1OV`@13iV0W~{6qgnE7o$R|tWmQL^p_

n+1X}Y99lsD{ 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[eN=UG%t#FF^i)aib$3~RZ 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

qVr6#}_z z4@FHUnoOs=cSD^PnnciC1A*Qkt5}Nxqxc@%e0CgD2zI;g#fY}`>`FIvJr*Y z0r5LE84=`5%XH%Pb48@lRzK2D7J_!z+Ugqcre@J5`{is|-VE#4!P~bm*AG|xt86GK zbwOE4F3tm;Fw!U84h4B-hSi}Ps;WSPvm>3R8ORqX%p^t(h;CA=WRB=pmK_8gPc|zT z5$UT0_oD9~nBeh@08UNHYW-Bo7i=JTicXPrb@4jNZ?I}e_hMDltKY^^U|=H5H5JP}9fSph z@W1Qy)PI@4Dk@AEF<*ZLtrqW79jC{ABUz~P3HBR*>bFV>C_z#bjg0?m^<@`@ztq{u zjKHf2c&dMudlikc5Idz}PolpQLcc2dPp)gozFcO)E0 zBg(sRkI1>1(oF!28;^pjY_~m)$HPt4P6NZ&MaT{+w&A2mAx$I9?Rn zZNkjim0bcgxVoDgFAt+6rmZkFacP)I{l-ow1x=QprsbN6P1MuspD#m&rx*2bjrBX{@vQp*#30fj@oIk<34xKMEm)KtDin`smvt_+AR^V_lYsHLxT+`+q6A|1JXjXF}Y+Mpqx=yiH95zHN@2 zypQ|rdLa9bl$XPmedEcs|5iZTaJjW{-((|fXvl@pOByLzFFm}?%YVjoBS~{c`%|bZ znW0BD-S~cU0lgU1=+ZKHiPOv`Plg!zd z0y3PS*%a`p5-R4YR88B!)~U<0CSqTvt(P^O!ttWdt&_X5QosRhA&#(h3$Mht-J>XA zBM2W>*6cj`6A$~x4@CiN@B0M0QYn2oyoBOA&201M$}{C1S*UjzwfIKPbA$BQMBdI) z*zDijRVv4~T47`J!_)iSxv(w@h_)Dy?z5;pUba%;C3C~N>(+>v<8Ih-Jv zka=pnJU84tHcEXf=xm*Wdn4|hkVZN6PFIy4O)sK~l?I(*o67exk^uNZWju8zV9-3q^J{@3cfQW*)tYp>IEQeo>(%{1G} z>zP+KvnJBP5x<>O%N_GPk)>z7h&4p|!k3Vv%T(@(jiSN!L^v}$xZ4SIROug|c)xea z)~o1Djw@%ZIPS!`k_}Gb-G%HO_HvtZ3w$c^dV|vOTaG%^PY$neBjtVPO)dQz9q%0N z)aP90+)4Z-sX|T`to~#;Dr^%JJJWqxg1{X5d z6?&|C072#iZvC_zBl9|oleEzFdiHBHnh4@ErEUPrjzpout9{xWJnh>#bDP^J*V2 zZ_Aw8u&K%KPtns%jZ6WW+Me0^dslO!JZ$z03w6q@i7TLf5LC2kygoAb^?WeUD%#R7 zM`$ua9AB7S^p?MJ;m}ZM$f_9L21yv-+^|WYfP4&N#N|r|9OkRNrtv{d$*s1LTZP=~ zOK0gq=eDg$+EkiWG#k@0DRL-1#)DD&5A%&fUDtmS2(w=IPHSEg{rJQ(Z_^D4l%|=; z6ndlIcX%l>dM7bbs@vZD%a&xm`{6_ zcP-9naO>^MM#P!U)DroMMPW2z^hLtH02{IO(~FrIaa^ z4eTz=D@V*+sJxqzU3k^Yk`mU@>{z8_Yp;kX_5nDyh7Kgw^7om%vqHPjSw?5o>A=wU z3sEsdkVgaPo5{?5ho>w4pDF?Wx}j2={*`g`II+Mq{lk*xZ^hoiH9grA!I3;Kf<&Xm zUT`)Z*SO=CH6%0}?Y<6sPs2u&=K+4<04bUl`TNl>@CVxKEVUEQ$FCr!3comu8K0QO z&n9|qZz#vmvosfO5aZbyB!K*H7W+Za;-k>)Wkg{&Bu|^-t#Q9_M3w&$N`6)+eP%|kJJYDcg z^AXdta9T3fouz$&n~;?2_cEUIE8N!au07)iJYg~4oLyEnm4#g8f4NOW|M3rC)ziI+ zEBeBUEaq_+IGb4Pd8Ce;FR|m?IH5|sL|qKQ%jy*4Q4!*3dP{2q?5IjDw$vDnNv#f5 zQ2MRwFq3PHJ-1cITi)$go#MAH5|rGP^d>JD<+do>V8PjZgxZjjdXOk5$|{8gu-gv! zV(goMV>J)LjAj-@@P2?5C2k#6jzoI7MHb%hzs7sTysa8A?et(cx?6i zE^Ak&z!xzcx4xg&B*HM4{HX+sqQ%JB?oxpwHsWnF8=yS)61^e+HVb0TLjQ3k8;&RB z@Vb;9dTy9%yG2v0M%BXScGgHJRdGJjs?#X6pw+Ev3&BoPZtrXhGxl(FH25~az6XWq z9{4dY(Likfd^t6o_Oacm_hTQ?oJ@x5BQmGmaB@mj>}IuG6nL#!%Si?HkqY3)$5Y6T zt%A3*lrhquk|ypK?yKYW36oekJv@gEC9UnK_=!TM_;SFv<%KC|sGoA3L~d>C2$k>(C$KG}NN zEF3huFj?mg72;4Sji7*Y#|@6;?-V*t9z>24*jD?CxmJu-ou);*toh&Fd(Y?CAo*Pw zPi)R+&3{b%>L2qgw|bCih17P=+=Lk?xE%?}*@8IG-cRwYi3so?S5OHw=KWNqTwNcX zv&)9AFZGmjRrj-3?eGr; z2SzJ+-eP{H)8@|-iuDB23{lgEDaFuz_;tePiPeC^AOaZ z_1er?^_0{OvT%QLl+r_-HKawjy{*;God=!{KE*nd6X#aaYGt&|t^=^8HVZC;o0Z54 z^Wmw9OC`5R!yjr5lVS+(_-iZh*><1_#hvu8twNT<Y4QVH({zmN(Yta^Ah?q{3qqI5)ptx2C!CPfR>MaSNKnkvNYc;SGZT;VRbN*dq z&|Tu6P`6R*oWCVacUBE&qo>{pF`?mjmc8VHMYv~CLQZ=!_d355-h46&zez{lx zW7*KAe5=^ET&$}l7Vn)q-Bou5#i-@c;EfmKxS0ZZm<998aEO4a zIDripcC4m>>OuCxO+Csp_7!u}_)`jZj4ika z?mi!Kc(6eUOT55aOIYNqNbe`D$d?PC=@Z2XvyxmP&g}NZ;97_I%mte^+>sK+L2X2T zSeKxl)5ac<#P0B?vrrgQ$#USx;Ft)K!Nn{OB4ozg&x|sbZlWI(uc7|{)N)?tkIEtU zCaXlX#aQ>^Iwu3p6p^9lXqKIcFD`s+#<)+o&SmHVLNxI9=!%D?$a8QNd0Tj|5Qh>* zeyZ)4VKfubxDEOg=8ds_7N`nGhK|eovQ3f#>Yn+YykSho0ZB|WmRgg8lm$7{Pktct z+{TeJ_?W)#hQ$x=xz^<|w-`iKH!BbV7-mZhRA%WU{7i44{TI!XFq z8mq;2E>F_+wyq+bA)QL9Qe$whjn|K`g*1Z)@Ide4v|(pKSplSy{1~hL3eL%+Iiw&#~22DUTi-XFC@3EkeH9(I7SW z?8}4BzJJF;oy^Jm0O2PczZJqLHUyrWU=UmHm&i*J>KC@QfepxSL+!{p;;cZyiWklD zUc9*M*62zd{$0Po&CVLt${&3x>HST~hu18dz34uvz7n5_Vtvga5AzJ?kfl3e9TvTF z&~+n|mz{-hxwF&AVhk=O#J9YF0}-=LQAI_qOo;>uA?$^X;8RI-M03k4|5s&S*;Ir- zLb}?Wo+fzBkUt4QbG>1eCJLN>3cMSC_1c%KQ{>-=kF`o2my@{9YbT}+XTv@$(%Txez}P8NdOH1teW z?kOoiGIwAWxe*mrL*m?85=gU&^cp^Q7(`sSezM!yIPYTfr!;hlX&MDp^ziAfXfmyc z{qum<{6w=%8|H?@ituWz*l#nt#C^S@^u0e4k@-=s;+&XS}f5+I9g?n>zaM@FS zX{dd@_safNOfyP|n7!YjHyJ=(1wo@pq)Ed=vDx^B6G4OVksaS1__=v!@Ha!d=3sKZ zQ@Z}t(6uAc@P)2*49clmihj{ORgEw~{y=ICf7E>`arn7d8|yl!FpU!@2~E!YfdPW_ zPI?hZt)v!VuwxLQ1qvuSe?k>0w#j5FvYqi+Fm7 zT<*!QnEHXq%r-34j% zvd?tJZJXQPs)VR)09^!DQXOlNY0>~Or7QCab)EH?89bsNiY|@86!Xh_LAsC}KQ=L! zk5{|XQC;677(siGO;F}&Z-fTn=Xv?P@}Ftj2DJ>L-;_ejp7Aq~KeNX;#T*PP4d1xpo7>payT@a$Q(#)Mr`o9s7%4{a7a3HA|AkLtl?9D3$S>3pjU1WvPqWCL-j z+riRDbnM-=zFnIB$CUhHp)HB7;DhB6q~3*rGK_|8LWt2^imq&Yw5mbXFH%A# z%#co`e7Jl+YQ@;ev!?Mn9d`?Y%@MoS@&oHT{I}_?FzSwZKT}POM>l!@D|%dpDPME_ zmMvFdNBT`&3koZB1AkYsA zbMi5{w0{7m{H>Md&J&lD;{2d(ZKA9e?sN!WcXNvpF;x-HnQ2&s^|M$JB^hi?q$;Lw zEmoA%zT3%K!R*?A&hQfIMc{Ggmu>0a8Be!-UpZJASMA>kHz%gjZkB}Aotj$}_h$wJ zxepX))sexU3!=MkR#Hsr<=H-HXzX8yJuGePBl>ES0z@ zWPH%U5TI{lQ-SoXU~+VBIFBPhZ5I&c8p&nX zUOcSP{#1wwZ(2`RBCh8A#wh(#Ds0ih983Zw@)Ik-7(lYn6hxF$$3Fln5bYNWz^*bb z%p2vd=tvqQ^*M&}ydQO~Y@`9JJI3OFW(xLS0Jmu7FIwG{j>8+7Un!gFLWF0J$BxCU z1-RB{d}L}}c)j`4d8m5JU$>3)HdMbue(^0V<6;YK95$f1b`;}DFL0Sq3(2kb6i4l* z4s(sLS1C@>hNUbUHPpGQa~q3TjE#-;18csiWS!J>%rr-J#T5O(O%Fel+U!-Qj@_`1 zmp^(u%zMiJo+0-=34k)5uli4u2Qq9!$Mwr6aAxS9bR(!Jr-9$XIXRRTqiYw*FH52k z+oWef@}}~3V_HS&SefEOfZ-%^!qB>WDywqSGmlHwadw?`aGAsJ?RoQk;d&?hpxBhE zY*8secHy!iutw~+p|5)(c_?Ip*(j`F=WTE8<*Z>S^I6MMAhoNIs%i`qCCEHn$yCK%_`{RkaGsPpjzqVrtvF(|TY~#++_vKM z{m9D&sxY=kA1pYv4ucW(Vs_d%5_FP0^J>0+!Epd%JpyV!F-q7~OY)h*xxPyuNx-$=L{Al1~x zom(r2wk53?oKSJ(Zn!9MuJ}X_97);}m7oRud0_KDfVw2It;*_>7fe+-gKFw>{{Z4l zZ#k=HoFZvUG|IHgpq5k{n2!-ATLt(Xs(gD@0j9L89`0{2STL=VbGlU&GW|uT;YiO6 zN#}qFp5?~dA@_2A@e^9YRmk*Dv+tGrm$0RwI@pce?&+at&l^EO#>!mf%#mN=kotGz znoNvvL`4s_fjY!fy)_d~N*Gnd{JoNzOI4a7PMm>7qv$C(@Lr6yN8G_r-$Q~pfiF|U z4;LxPQ)&EoAupO>MbRC`1BYQ+yY7A`$}3L&yO|0rJANM)1yp$C2mrxQp_Z@cOQWLS!@}uS zqyWK5WcOj+j-XT(n$VORiCL%s{OGP9U@XXK|=GN`3Q zmxXhXb1Czuw0XW~Kkx0rdzN)zjM$zfdb6-kk)kU{-_LAmbSe3Q7ZNdga3dKqmO)5R zZfw^{>5NG14wLjG$07=^`bT8#`m+2~Ayl?ZYLkc$XAVbkgwX?Zd1?JlS?h)A4#k)+?`yXCmWS+XvoJY`|zCTR6mjChc~!_dJ26V3GfDj0RNk0I_V?|kB@uUYG92W64Sg{2Z;T2N7$Q%_J^H!0%7I_L z>&(N*Pbcf8ZL0vr42aa13#vK1#DDHj)9ACs_*ZGxo5?OT6_c+|UD;i@DJa^XTnYy(e;>!j`u5GI1Fn<@jaeRNbqk zwU#=O-{w6YlXcAd$df%WD#cB^Tg&NLX4&f3E2PJ_x1p~z^gdc0v+kZtr@&q~YV1d4 zlZx$l+soFXh``Hv+I1I$?vXvS0){6TQFqVU?Y?>oYBKB{yLTE{bE!QkjR@RGDOfNh z=g*Y+QCU0^MrwN9Pi3y`E%KrF1$c&Jv_Lq;=Twi!J$0mef46`nR+moBF_wSDJrS{R znbgw_EVEOCKrac*XPjfb`!6<(KLx1tytzpop}XI$&-|uzS>7}yI=J^sME>7&-_2?v3OF{NmE zEpcuog#_^Jg#u+MceMvczW*JE;&gQ{7onOUjxd_N)l&sA@qW0Oi?oeuTfVKlrL@Wr z%QsxUX?UElP5ngh(=i;bFX8$^Y-i;LcPsnhX=i-|BizZXnNRlnin(N{SI|en@5N2k z$N^tZf_|8Lp+JjY*Qv?F(emux&Pv-yH%Lz}`d*T1o!L9t=#-W}1!#6@ZW{u23Sx>t`x4%;YYY_zcm%_-vnQ&l zO3nqxd^x;gahV0x>Ckrtb*ZDJ3csw@qddug(|b0^)Ocu!zocZX)L&ERx)ZN<{zJkK zo0-yg-#aSmE8V{IygffY@8V>i(%=2^if_u?bykyo9lydM5}oWy4gR!0hpD<7OO$Qo zrQ!F-!+WD_pt%|aE`y;vkl2ca&BG$4!_JKn%7t)5OM-eY;nRV>0pl;jnz*Xy{$w)@ zsQ3(abqlswJ|Q~$QmYRn8`*A&_kZGI|Lb|_-(SD~?GaWAn4=9Y#S-iD2GaK#xsx!A zJST4V1MVxUa7^?T=X-ncfop&eitSO@2*csPRoJl9RCs1{KmR0MTAARCn{u@1=#Pn0>sT5Pk8=(#BfJ5a#_{ z0#2;`I6&%`bA13w&)a?djF0v+yUR1`E70Liaj2=LV)s6l_Z5u7~QA$pU#6I zSEF)m_2J}xW;6G*L{Ngk#9E3PQ&j*qFcNUiPq`s#UHrfFCq2gCb!@Fmf>AF@2l z+L}zhA#MjfxJnI>dg_u9FSnJk9$jQS9)tSgVk^b<;gtw0Upy)Nxou6pjAlhv19>P8Rmo-W3VrL7913 z{z^4~y~Ys@k(tBo8naEN4w;eTQ2%-a@kWf3(8#_zynRL-w&P99a%DUjOz;%8t|pW0 z12H6S9XT)vc(|>+Q$a51U}Dtxtbs~$d8Yh-!ykT|MhjXu0j8hZ7{Pq~x?xl~0n>AJ zyy6bq*=j}_STNQ1tleA|sVzdp1Xm&%>{+81R%+&pnYnRLjEt6u<9aj)hT2K-AhLIe zUgc@9v?Bk4vED* z>g*I+TbqCk;O**Jri$Zo$$O4BO$%SiCsi%HDQy#=YG%2KVYx?Niq5Nb)dR)`9XGzw z7OmKA@`qU)Pv<3u~3NZAR4W0rphJZsvCm~1#7GpY{|Om#HneHn(&bDTuK zY8g7@SX?~bJEcElN7{M?a+{v)-A&>A4A7rVfIZfimv9cPo;y7!rf*YK5M);H6{=+p7wzGqNdZy&4^T+?ptlB@!PCw zAOS#L>&fbCCj+rEH@zaXAdlCtb; zTf6jS5n+{MQi6(=K;}5plzRaSjz(4u5;EsDW{+GGr^bx?gvdaX@86{CH?rStVFt4`S9lLsK-UE*0_CWcBTk%o!^S2Z1yn2$SnWh^^V8IA-d9; z{8*JgnC>uw{ipobKUyIr{Z(`O0h#HMvu+Elzdxz6gqeMBd$-IqGo>;<_=JvRw5toNonv`Wn#W3&)*STN@g4tA@? z=V}-BaRf&TuQ$@)N}6wsbQx3=TC`t!GNS0HKAHLXg`(4m7S$x-h#xEOGE(+vsoG{K zR{5$SxQy5VQq?sUX8Jzid@qyqzSONJ_3yT3`&LLM&+U-ijX-KSM;o}djd*dE#vW$Q zJ@Gc(<+w*JN^m_UWrgorK{3&NZels#$~>OB3T5@lnQoUNsTkvP=`ebs{yi&GKNwgE z8N5ftWV!ga{qY>QOWss7j`>V0o2?1PwA4e>w;fMX_;&uN3Z!#4RZ!BYEy$d870y@&t~XM&x$tvnt(%6@ zPNPh`5<~1`HZnAO&bc%XoeuU*`PMHqcdeu^RQQl9}`G_zLPoTi#N=_Jaf%Y&*_%FZ~q#{MMKERfC#phorKP z`u0BnXfLjx?EP-{shPG4+`@}zIwb+~^H* zx2O3>G@G}qr{TPaUt6*+Ol7)aP4o%jO|L(Tn&SD90q4@L5U*D=Arq~20bIzLzF8?) z!*6DGq~?>7LWW^C!8<=c#n?P6_=EV#LGNsoBf>blpEV+z$Zyi@GZ+^Lp4*0z*cJ0J zr380f-PSFpguuy2$Xm!bu0jv9D$pm?!8 zrawGnGYTU(`K%54S~!W5{1}8OKT1i|hYIkz)Vez{Y}G8_OH{nuCczG;tE(lpHS6gN z2S?Ra(hY0{Zp}E(y>D<~%*7^FACWhJNRoCvIhYs$7F zk^$$uoUod8qc)x!X)21;i4@y*v_?uR&bfC_m7yFTXE*!|w0RDtai*%wZ4_=RJMB1KIW#~0HG z6sA0k+;i{1xL;&UyRo!coB_S?-!oeUNsTJ$fNGYbrOZV%%=2W=N1w{jOjX^#hjMI( zw9&@46W_Ybuuq^TGn`*#p3-aRiYBo!P<6#%(to1cNlEG`dMgHF$pp^?0kW0VgWyLY|s9Ip9JthP2byyrM(M z(YSdSNmW)JZ1|~j$Va^I(3|oFR9DMReEi~Y@IQd|t-sOTe2a6l5U*!6xpNuEb_&EL zBH{d*Yo~C@xzP;oDB~HUbw?MDBqyWBXsMbk`{L1kPHTvVaTvY2s>5F=8T&bhwr(R6 z_c2H+x&40r3_i1f?bu3Eh4imalyg;MUgpAVrTm$%tgJQ)bL~|}cW$<7WskogT@lOu zR&HmJ-;b)!4JG zt5`7*dF7z*s5%8VSvN#5@&qeL!{?09WHr$OFZ{eHBVdBDNfZKXP&_CT)e21>Xf>Ll zAdxl5#OS**y2S`E$wc+XJyihnmDDJ1e=j5A^}?JD2EI4eP#{s|S^-q06RHksTBB1; z|4mTw-+KZ4%TDV=0bcBQj=z+Tzm|^YPWx8No>eYDGctB&IF`c=WI;ARj|8v> zPFp=8au5T|kCtJocwZ=pu)UJ8SM)1!_Np$!GP>pyTr1IUviK!A&&o) z8dexTY@f|SD~HcAp+cMZJpI!)W)jd-6QfKvFRC#B+%>CHacEr$kKD>e^3`w=<;L>) zCUtDsGlLgYjZvQU;MSCVf8j~O(JAAPDLELp>nQi)d(mv8MdFB^E6s`0KoHJ774(g) zO)HZcuXu=GtB@?hqd}Xk`(+AHm!DwBO#W$;M<=h~K}a4T2Ekj?@!8C(NImJ%s$>14 z{av%rFDsjU?%!Rfo*l&ur_+*@DF<`hK=v`w_AF7^?lD(suJ^l{E7#nHlbdO#qeo4A ziM=Cid%&Us40jFD(Q_GN`}`dt5si~c0yC@!JaeWuwTI{Qm-2LUk2PN6j>A1@H|8!2 zQ+XjE7TgFL{T>rGhpaCzWDj;UWLJZNFH{V31CDV63_X2pjD1FLU*WuvJr8?&m$=xR z#*0r!M*7O^uPuKjGVoTtHR1Dh6O{4vGuDe?g%g{`&Ep_x4xyKo55Z+Q-9nD$QJOtu zb8t!$bE$q%VK=X3x&{NHD6kf_iW=Nu(u34l^FnaO$5__Xcm-m6vN?&Fo7Sjn1d|;9 z92p1?^EG8s4}P?}JYvc*w6dA}IGmf~>eJ*D&w|g*w7?V4!(L)^VD8oc4Nh`%&nN`~ z=X%Pp8Oe|IeDn^susvoO5En}Jj3;ow4qsNd!t;X@V^?Au!+FM&Q=;JTnwBQHpdY1S znNJ%@zesR^?Po9_jFgxsX&6A@-v&$3+pv|rwal(_DU;?z8B#`hq)lXq9rU@PjU5SJ zCSZ~wF0OoO1z=?V^h_zd&rX%#9zdmwXNAQ}#iD7Q`QIx+jQ>v=#R=eY2S9je5st$|kIakqXs5X8NU} zPEDi>^M~hFfHzaPjGok&cYG4osp-5dq*_zj$}co46^@|&`zHKj9?$H&4egYq9nLIK zGqYUD*9iQJZ7PBjU~Y$KQ&aTI*VA{kZH}F=C9|IV9!zWb924JGN;B7n;B}hrJNCKS zF)!UFDK$wzxOBsYwE(xL$T%N>6aY4BeWyn0eLT7i$SOhEoh~K_%w%X)9@So0jMX25 zn;qz45z<3OITNr0ew)nK=PznJrj<1;TfI%9t7+>~S1YV6W;kRR2QoC9MP&n-N%><; zT{E)LMwzU7xJV=K%o!d!ZWiMnYy8;ilq1CLp5(%7lDK!mqt8(A%zNe@+I^p@W`|V~ zZu`j@)1)S&oQnnOr3=o1ajCDQay)JnoU|U=_FA$HZ5J8V>KmytXtEe&VI?3Scw+cfJhVPM zGv=5*S1J29cSyfY1W+JZqrJTaQ&0MvGS+(v@+sJ_5M&s^_#R#4fjX$9CX84$6FNue zUSgeO!N*3F%Z+m0>=cXTlypur{;nU#KKp5|X~{6u1}T z)F!o4h>=u5*fji!3)e0jH>N!bq;zQdD<5{-R3LUyFZZzMGu5j=HQ)N>j!_4jkr%mO zPP6sef`JB{95QdvQu;W+mQM0~JpPCxv9QV<|vD-x(M_)P&13P_03aaWM~QR=Xi9{;y} znC0w5GcutU!1~w30;_yS%ECNhijTr!7LaC$`V(~CriM;G-)*g} zrd@_dR^!HcrEm0Ev1g{%NIf0+cIAddFQRB(Z}fPRfV}9tkgUmS>v@9M3t%)p2&IU( znIYu;;js$Ie>zzK%CC%7-fGS4dFtj^l=?|7C8TmqW09YVE1hRbVdTtknyF&jiS6M# zfQ+*12bF|(lB|!qi`V=pU0cyyh!v%DF;#I*O2~axmP+@r9r=M8Zg=%~rAxThbl)*- zU0ftjFuvyzpU={@O&){b_yb0)5*XfPbyOw~mL!B&&8iB} zZWeSc8bA4vb-kn|>F}l8+GVY4iqvBfT8d7M=W3UIet2Ru#JTeBiu{IkbjWmGT^62$ zl&?nGI6@h?SYGmsip?$fK-6XTN~dt)x@S(r>S}w?QTZJAAB1=#2mNQso?kRQ%d#3h z&DI1y{;m>WCmNwBYC~Un?i-=&m!38YllL@Ee8Hg{CZZIWFxE0aHO)hoGMt?t)2xgb`639h%f@P4I)+ z6YD+?W@S0(`ab(Hkwo-T-yY)OBGxHhtvT%s?~MJxPZCEd`+mbiB=wyR4rbbARVd-( zKLD+rdeaG~wSn1G&fq{LNGU-2cG4LoW78z-NuDk(X7Rc#n6djF*)oPPwwD|tRI=Zf zDFrt3j&qwzInKp>rYJv}{eAql_i8 zMh*@*5Z>NM!?~(2PCfLE_Z%WGcJoL6K%bXdggkHLZ*fYfMiT6`@}V(|z8pAuA24tE zx}01&I5dSfS{v*HmRUHb0Ubf&dAD}bcV1L8hTx2lYLSsJWs70{o^9+C9U?xa2K_cl zCi_s}y#ko?76OIMx8OqDTjIb4a3LCyFuGXd(D2v)!xW48uYEMM)L|09TD}uoDNG_e zk0GpqB{s|r2WTm9@nBRw%m86UJAtLj5$*k~shY&(%pP9Kq*e;*+f?R?j=bq|Ue)Pp zd{#PLJsxRNS7rs?K6q&i4ArOrlVqLSnuSAk5$`NHL^#Z{YvW8eBhI9ssjIK7%1Spi zyg^?Mu~;%xIm?`vEB#f2O3>`-B$dyLelXa?w{}){I{@<0l)GTqOg!`B@Ut>$MgYfc z!&+k5O7z_9zTX!S&BwYtXBv&;C+CA&qW$$A>sh=U&;c@FNpbDkp>a-b%=*t3saos& zMy zh$(k_F=XvCcmqiiAoD&B*vb+2R+oLZqEq7T-?LEc)Jh+Z?mFAmRyf7zySyU^IKMFK zj1uw9IaQm*iNI03E!S;K)~{!EK1gE6OzgPhFXnVMPiOqalmmmGx}I~mNl8(CJoGW! zIDDzUyAt?)X$jl47npmR@mBdX{FA)a2{OTdu}CV#v9jH*a8p-&;hWsG*t_lt*&y*_ zrGn_zUDIaio_9h3AowV`ht3kB37})zJZ2yx(L8E~PJm^}aTDYJDHOGIz;K ztJqm{Ut!>>XmZ3{%pcu_as8by$f=Do<#r6x%bS)Xpior9aeHCBV9s1^vFWjV;#RGC zxFIw)O-TO_AT-V4@xf%u%v>C)W@?*pwnhE@qAALQLVnA3R6g8q?=WB)I2(?8WJ6iE zKkc7`tr=Qa*ByaB0w3R;Y|`-qQDN;?o$haVfbU17s$Kh!F(i(lb=v{bnyD67%Txj) z)~d0zxbnq19|k*T{Co{9B^^;MV;wnkQd~L3O_OZNJ{26_{a|TUsFq7H9)ZkIxf`{w zT;dfQnsjGdvANAO#WWEubOpGGYKH3&U1wJZ?#O0Y-Jf6Cj+4$37MkS_-&Q$e=6&8+zl2cY!d- z_pZv~;vqn5BKGwHY=>(3VxYS0?!;4>^-06b;)t9ajcwzm*k85?0*lYBxYc&3FN<%E z)y#RdDfS;82)wBa*{%Vci4FS=o^<3oFDn`AA(O1%AUf-BB!i}{l0KR``_fvBetM7B z8+tqG*yK&y_H1dh>4=$E`dKlbQApSNflQ$`2K^3VE2n`ZY%|X((uw_B;9(L(@ucfe zhlqJR3rb+d;uu`S^t1d}OM+iFx*N+mY&OVS!`y4Cs3=n}oL{08C870AiLLSm5z$_X z>Y(}MA&^K6ViB%bRR&rkNfVI1%{0Da2 zwd|)09PP|p=B)l6m-*QY8y4H1L3{I{>?Yo!a@qJ_2$_h$r5<8SkXwdhT!}h9J*H*; z4uZdPO*rNUgRRNWRZ~g;V z75k2l75c9Am!t6px~-pCPL*q{<E!$EY*-PvxssW3_kiM*~{&!$p>y7QC3Q(q`?y2P2l&^+an3cdixR$uM{X< zj)F}g8ZhNOuZ-!*KOVOExv@Rho^)KM!$OSuN4mY@e8lf02*<=K>bmwv-(*;GW%_&t ztsL--JVS*L8@7Etlj!+qx}I&P>xow@N`Uf8(~iROsQDCV4mX>*v1>Yr+e81t%GK{d z~68A1)^(LsKLzzhg=pJXxyqQX3 zL1mzHTI>g*jUQv3HO3y5xxPJ!bSi5W`%;j^gY8lRcxELzW1R*PV<5ShLn8gUO6L`D zQ8WwKWmPmJP&7+BusSRe&3kxO=69xx{=Nv4LJZi6j>=-|zgsN-({9S{1~ve61G6*% z?S22TjP-5-sb?Ba;k7L!3z6PHQY#$RsylRXDqx}8sO~8ylVT-M^ASDiK6cLK6Z;g+ zwvd-VQ=Ed3FrpJB!WCaYP_=`PvYeyFDy=hliU}&v#9HU3ICyl;RwN^iBR#x67Zw81 z5sBU8m3l6j+G^SBL4H?8gm^O$gZyQP){4$uIxxz|rm*0E3 zIDSs?*9UP2lX~OX>izv-^vPkUs$q14+TO&qz1njn&%HWe;?c5ktY&KhOaC=bejUc6 zoBYdv0E%n9DG+R`fTOFQ!v|xOxZHFQ>>#_5tgh|s5@<{K5S{M`ia5U6o=*dpwoJq& zEK-hKnU{3EMByyCIBLU>GvdBcZ?9#G1hxR5w>vH#G%%0$ckkVdk7FkYJ==<>nK2Mj z3;iK3n+mNh`}&9a+aOIUaqD&C9{Y4RJFDml$$1#*;DVk9&q-NA5aa5ZmBbrp#Tv4) zNJ&b4^7MhXA_skj!_HKtod(tl3z4G>Nq~4RR}@ z)Bjv86?oYaVqJh!lFhowbWfE=xC!UVFJ)*P@b{{pW$&&pm}$gj79vPwj^=7ZIEUV8 zRIWuhX)TMm7s8xIkZwGiDht2cAvE_mjUv2O*hYjrF!RX+01h!WI_HE@&MqAFM z3tilmwN_%jzNJ(ifk4a7rQC4hqn8$f!)8!80$eMs6Wb8?Haa#Yb+}ii>D?s%En^an zAJ03b4Zlg<_t`v?DIY5dTKKrv6^v$H zK7Hj;6=_$LT#Ut({ms6m`@!gA9&sE_Tnz!s4oaed( z)ZW4=X}?^o3_5_@JWg9~y>io=6jskwjs6ionPr*kFL&bE3z9OBr&{DZ z94|M5Xd83H5FR!b+R$mz8rd?C}@FrG#%P_S?gu-J0T|PuEOLz>EL}2m!Q7yc&+;#Cua-Vr8S&ik~_fM zrOW|?B_=?m}khh_c@scFMWTP$yMFUEIQviiORlY zpIQEBLdNczBsNfPtpr+pqwo6DSasEg+>>^(>y z+m&SNt|LmaDdvH^894KnL$VuCF$mfn^P~gW5|vPTqFEIgcdcL`0tH@*dVZ(v)M{@R zeb15fIh~Xn#mVpE=Gd1ll9gdlyt&e#qTo8(KONCsR#5E>g_>|~!4Va1F{Dql(w(>fWCCM~x&n@5{8O++Z2yog$Zs4Dle)*3r@c;UWQqBOQ0HC~-KF}ycc2|lu#G0soq=VCP zSBc3y{2F^8#i(nzgtxS1+h(5na|9@QPamd(w>~dt=#Y^yB8I_$ZjoC94AqS88iJCY zy+q~=C2)UUl0EBY4|g;63}s&2jIEp|vGXb5pqZWOU~%>}ae$soNiqH=xcC0D!ciI$ z7XX?1DT>2mcNy$hc~pwFltCoOGIUU55;+5OO~2Hc9I7?VyncIN$fd&IHbG6iz3WvsY2Oe-5=XXM7~(!T)VxvKl=i_cV^5TsBTL@xkDLcd1J99d}@#lj#Q=4 zY$Q&P!e{zq_4>Jk-L&CsboWW}94}VRXw}OWI_YzMUWiJC!xdj0*~%2ZwzZ?QbqLwD zTG&;Tx^+@VJBJM`9qn!cC))3C<~<#;bIz*I1%*ccbN66z$enejc~bMsdgWM-|7$3!)4IOzJJcRADE8;YbJd;b?Yx@L zNE5{4GxD)5^#&_tFxdzZPwN1EoQh#&X&`1-QFrm`xf->ZO22w(9}*@xVyCpMjF)y2#BRa-lbfCz%0rRpu@Jtfzh&V|CH* z7pB&Z^-|Wur?un~I5*Da*xlOcwq+53Y2Q~jC)TquR&9v(#&TJnpCe8Dt)bv8ua;s+ zov$nYCW-O17OGajGR=x?tNgxfLz86>4gFPjkpRV3I5ecnmp7DRR5KYLNVpNVyd2am z#kCNn-83zV140VY9_4H73J#q;G07Pkf9Lx%T~>D~KjGxUkC8lLJR9E05O+I=Falg~ z!BZHCaS?nbCjs`S#;Y*0e>b;RO==MW&{MY(WL3DW%EAbU6xL(`F?mGF%&-nri=i;^ z#2QxwEt+D4{&&vLzo&TqXJk;}e>fR*p^#S$ccj41PRa5RJl;Y{0zMj@Z7j2H9t|0A(!J z5oNW$tqOhpGqnTn+Js$C`Sw*B#T#yjteH4_Sug(e=#799K3CoZm}jS8&(oS|kRCNb zom-372TX>pD@sdP`ilq~%H<_|#GQCfH+Ew&${AiLt>OP6>#8#dLlY}B^IUv*( zMS$W|URw{EQ)Ad0AzTQbqY>wt#U7ZzN4uu*9h0fL-ixZK;PX2=AvQgDpjfX~vaSt) z?`_jZUL{9b%DaFes}?dE9c`rnDL-}lXWsS!a=M^|0yx;HAr zMhe6HNUzYCcnM6IFr&pwZtp0Zy^(p)c_i9;w50gdEQT`0-w$wNTtkp{eJ%71Wp+tJ zRcV@-%fds)F$){9C7JHuBFa2RUUn0zd-z>h%Y3c8hpmS9+@IN?JOkCM;|5Mbneq<2 zO#yx%03QJS86DGl5{N|jFkl*dlTsN`s4mYyn#ALQ02DZ zu-PF{HDh2e~ow{lRLGjnUNZ5|b^h=ErAMI9iHrXSil83NW7Z#wgo- zScFG1k%EJ(c7gAcW$-0oqc3hN+lj}_*IuVm05Hn$G4{G^^}b;LIIL|^y8BU^l5XK& zl(L)Iu`^S#yp$vxmk=m+*V4}TcJXb zdjJ#WvSt(_&{Hg5QB1R7GN9W0`U64z&RqF7Mz61xC!;kw!LkL+!fR^_lh(?JaC1*`xy4NkN;PXU) zaNf~=z=@vZX`qjc)H-h0Bu88suR#TOlg!Mw07?H3$$hzu*ebtDkh0>g$^h(pbcU@o zlEl%a{N0l$FSFJfhkqx1j5TJg+;?NjMlzIHiVzhKrRl@zbuB@)W#*aEQuht>Vw!Ag zlI*n7w~gSQjIdm-=puVW_WVr#*w%rYDpuCmr0H*ZUJ0e(sGFeMS`YIsu~l`0w&ZKv z_ycN-4g2_S*7Jq&M&zfWV~-d$#qL841BB9y+X*j;q19S> zG}i(LbKn#rwS<+BXGhmfS~=bA>PR#?1uxFr-*4q8(L9@Ow11pJl~!OOU>C-)o-FLq zkw%V7E%JFVydZ?IK0}&Sc*-M-DUWqZorAJuq0(rkKxiWF!Z^s@pED~`A1Q#Z<0!?E zHdWk!Vz5PeVH&@=K@QhuEQzTRiuXbHNx8O*E@ zg_t2PIPFEK^khBtnuiNuUHH57%hBg;gk=J^f6Z?anhY67_0_&UmOPYlZTA^f&PL}r zoxn(e$xmp&eCdmE%+*$!o_%^TeU<6YOm-EOEpQ2e=W3|W^x$MZx#7)C7GwV z7WaoDaM^O2SO>Oh#T_iS6>tmU(?@{64D#$5M`#ZVHgKao3g1zscMqxU2!@ug0Rl>R z+U$A6tUhnZF6EIi!}XMv5DVOX)P;@&S_+npUq1g!=k=d;(EsX>!U}i_r9k)65K5o0 z85**Yl3VP->p#bYiB8gcAnf7%!VdJ@s^fd2V@~h%N=vzGSpDzG<9h>Hv<^Xz{HL*k zimohidWXMzSFF4p6f=bG?l2#}h-87tDPYF&^@?&R<8g1FXV@H2()!(R+Y0-Lt5B+< z#aR^Zbz5|I%J7jNd#Csq&&nO|)N#Wru!*S2Z=CIH@}Ex0uTP)3!I0mD3kqq1#j4IT zUm%0yzF>ne^^E}-HUPLD9}CEKC#3h-ugbWhSfljqgsphF;+5HQ z{(=qZ0=x{#O}S4_%w4(0C3A!C9W?|Eos&jb7L96odP(5fz2$A{Gz~BK%{$qDGfcei z+yjhKDBf-MKg8G}<u+VJ)L-oTkOH+m9}ZFhd!oD{sg*;0&xmC=F0)~J} z_0AGogpGroZ*FVMKbE7${Xa=hp&cic7L;%~zN$aB(znlS_4E6%S1_q=gjHZ$Q56QC zchWkb%SnkW!_c=e(K0ua&tcAr_RCtaMXW))9(#b^gnWJskQBaae(D$a)Xw znTFr_n6SHA@7}?j1hKjb>FKYki%A`oZig>#?f$lB5w4d#(bBH;JOzByq?G7{P^xxP zFTrZSdtAMIuy%ck%Hl~feRyY6eDJAO!cy@?>3LGrw>e}_@)C0qd`=NIuu{<8SR)yp zzz+{WB0sND2;$wLCt*r6a4+wfqvo^h^V|x1c~&Qqe#KqP#!W;XJ@+M}JI#yiD5krSKfav!d;in?$+X_v&n~Zs9fOn|MlO>HRH5*QAe>f4=7(10mC4Je-~Uo&_xl(_ zJm{8w(D%wu*VOWt&fk9`D9;^m{+B5-htj9BtUsr!x7_jpSK?0wYHi;$BNe?8{{b{S zM-uu!P`RAZ{Qg`OmP5fl`-&co_P9i#$(QLgMuQNKejoh%f((fIr&nc24O^|V#risq zd!A2^FW;8^H7$x@fBw#E?pd4)2f&>1>I14B4!)CsFfCuEA>rgJH^^@1KxQk>Zk~)+jTH1xo^D!A z`T&=EjWLWHrM-C4nBmo>BgyNf3BjO13MNz`CFt()fAIDu;81@3|G2#jQYsN@EZLbc zW-!+5lzrbN24mm%C4}s2_9bgcA!H3jM2RFsmTcLgNZI+{GfJvYpWpL5-|PBc_jS9^ zxzGMS@8xyg_c_CIR*hCLrT~57LEh4vhL9>+Z(sH+Y~)I}Ki@w=8t3;F-z=i{bCG^b z4%^&CoUOb$l{Equ6Rj#Dkvc#8jn@*uNXb;l&pUs;2xWMb#+VB&PB-O!um==Jt-&^E?BmT3Z@?aMySJcmPyzu{~90+px_wtxAd>`q*b$P$tf9g8_ zp+QTSIHP3j?OY&g+A4~=>KsxiD-$hOb(9m@9D;c-g>p7^LOZzFJAwJJ#Diel#3TV# z%S&n4%gReBnmB+V@@6PI7qkmNEGca;9~=sTXzTOn^9dk8mH$fW z)Fh;2BoC96OTym9><_wP7)k9vq$|MMSi17?K>4v_hVudR5dg*tjFA_h89xw5@bLn~ zMPLXBya0%WNyHF=4;U~XP{sHA&%yG;{)53{W$QZ!9t>7XTSih`g+o$NLWc+T`w)4c z7?%5Gj525^XBSCJ6DKg7529f5J8& zq+&17{!;)`63owwnYqIk4-_lJ0I{%>ib>)Zz-0Z03#bYK=L1p@*uDdN`#sl>1~E@0 zFF%+MhQM?Ugn2^2a0C(zhx3Br`zZi7N!yv)o1yJ2fN|N0+c~2T;y*YF!%93qSqX`0 z=y&QW%PGq0Dsf0_$|&+cf2S@I!+d`sE)SIFFm(|J)P-Y*^~b=!QxFb^{SRG-@nb0d zz3(z;8yA!lM8?L%1to<7Xn=w!pzJJMEWt1Yuc+vE{q2!q7%y(u0zNLiCQ8U(M$adp z22VFjkS@NvNC+i85phK-L)zXr-LX(DZky>`BqB}OyV0nGjXQUTwPLGT`g)4blV{tU z$6Bvfr<^Ui9%DD?esjsrxi@RfW_P!PwV#B_a?kG5TR(PQtqVo%FVCGH6y)R^DMPw0 z1gh(tfv0RYnWFDlf&2$9K!G0=V7oGZaUMsZH(@@YC?=oiiWO5qK#`ytQOeFmD}q8~ ztRSBHCtuwwR`OPOAIjFIuNBFvolB94lejY95Qd|mxED_cC3A%=xahWl7nd2YuceP zGzRa_!7tqKgX4bcXrKf}u>+>e#Lfky&YbnJ8cfabK+j>g68e)XVf+{?`v06-UL@l1 z)Fy~4wLpQXMM~Sfdh6JxAyE-PMsggFJ67P>^FTOgG4NgQ_NQYMaVz=TUiX%ZXFh*k zU9aq%+5B9W`Py4_p!ZRv{;sHDRpJ7@f7j({ACay(gT}|JeWiWlynGqsZ)f{h3rg>`IhetV zRCQ+0A}*N`aGAY-Kvx;t+(26y8&55MjC!ykhz)j>F@=HA7n#B!wCMzu-c&oPp8r|d z87l22ToqK5+50MS$t0Y#Kr@8_*g2yR7m!P*5J$JR5_J~8ehn(!CL{y=$vOcfI0-An zseypJ_>8Ki`QF{>grI4UG(3GHW^#2iZM|T&axUK|XQ(avzL*E7Le;7V2X9+v_r0_1 zpDVZZM4H~>Dcj2Ex?GiNth`{P3H)s88Iup&JAX17-=XO|(BXe#fWPtBKBU6%2v!;W z)N=pMV;FVwcOE;8s1EuhudJgZFTtUNw!P}=tY&YkWRFzfQbd`djvh{KAI??4d(zyavhU$5^9@!!%h76Nm_;TT2yj~BKUUI8Q+a|0s!KPXrDA%uHC z9dTtXB}MJ;)KRpzQ{YlVS-Ac|mVF3wXu5uq3?)$O?{-&SNnJ@t0zfrt{{(6<(BUuK z24w#UY7UVV0bm2{aQ+Lj3GiT$#o>z=#s_c_&|wf9;HUrO#^(M}2hcV@b{WDC-RFHi zUL<%Q6Y(N`;2Z%YHVpuo7!<@0!{8xa@Q)Hddb3~e_u7GaF?|94@&cF$i-Hhf7yuVB zZ!vL9K1>{n4PnNG%_V>YVV+PxIxsgM_PPHC(;k9{4|@Z(9-3G%47+&yiOhe)QTxf? zClt&2KkOg`BR&U_-(i^)+T0w4S@xlv^+CWinxhSWnnC2DMc+>$R8*Ii)&rPCTIV0Y z8HRd)VG`&e9)TV}GY}jh0N}`9!7D<57mT?vbm!&$!9xgOjxhI++4zU&f5B(}P#WN{ ze|-D1#eYmkAP#ZtA35N_Dg(HGoy+~jc0HWANfcPOMzev~qNSDPG{i6ehIlY${htsI0yD(FsF%N)pu^T1L)^pH ze=rfhp8kyx(6nVcNljFm-)T0b!m% zF8~Af9l9MrJq&Qfl)&6T+OO<|k>GzZO@{>he^qC{Stfyhf`{^&nwKwObcWiWhDqSx zK;a?FgycO?7`#9k%niT+{sW@}%-|0y{z7#i7v}n&^MBwgOlcUl9pLXF>H^*Qj~pog zra6$|16!@3rKKrz={MoREGPcJ%$Vl?B3ST4G1VhUgx7w9skT1u>^&>c$^poT-k1CZ;!wf?L1 z!6g45tq(95Q?!$*tF5^W$^*c$d=MA3jT!2Y@xkK8--)MsSxQ+8gJsoq{~#XnUo?im zA!7rCfB0~b0z8KX{+~)Nz+(sFKagB?DP=ur@qPUBrwbHA@4rYZV15slVhH3x*D$K( zSH%L%3kJ6Si`qVf{{L6C{dX{cMfbnYhu&prc{x1}br%!BSLbA=?rE#=J5PUSCTxfH zzsvkw-3##l96Jp5bMQYM;0KKQe`4_eUgQtj1t^Za{(oqn|GViWlK+na3rv-=Ey}_K1cM?Wz}mqK4SY`nVJ6Ml6+n$HXnVWE!h2{zbRZ&X zQZmX4zcLG#x((psHRj>_Q=0!p69W49C*SZKl4m&fTf^_vL%@LE084m`*zW&@V~sC> z&;Y{0v0pR}l{rM`LvQ!F;J11Bzo!E|{&glXz~x^={1A-#Uqu{4y?x{le5Hffxq^6r z1)BpJc)%e}miE9CP{t;h*GPyxX38NRKq5e8V14R>#w;4m%@0lWKN>k5Z7JEyYQN!_ zfAszR%QPR-*}#|Z1I_ru-v1-^%yDRX_rW*@FZ{Rx2H^uh_HPRXECRuxkpIVx zK`1{^3fA8Ww1ox!02If-A8Z(aOqda1!k8P|GGI}DqzQZv192>}!M+E|V#;9Q*7tH4 zkcCP6Q4Ukj0bB#x#iA&nzlWcgJU_9LJul#WDTs#*QX}KQFZs%XgeZZbk$S?Qj==L6uLdg^i{KrTE2a4 zh#MzJBljoKW*57)@Kw|GRI6+5J4%M>SZ)o{{t0Nej!N2Y@Z)o*C%0KNaqi&gatN21 za)3OpuxN&YSR$N)@m?WvMc8p%SgA|=?hPi;|(tKsbO|25i zU`;E!9K7RJ{b}b3tv5J{x?PR9tr{v<&YjkRJP$Ln7Wd0Rt30Tplh)VJVNq>te0

gy8kHzFNgNm5P4qy36^N!7P;_}5}9{`_)nIQ;pI6gxwIfs2PNAM{{10tmB?#Xv^P6C+lCxv(;GXmyOuhl&644)6#5 zkj%f-gDD4s0X`MLhGHG?Kl1(JTHUYpKu&+;Is63n!F*Q?0>Bp}J}9{f-txxTmZ zOHDtN5GEgH0FNvI3kq>UVOBfNu2-E=0CYk?OdK4X>^)G9uE3{4AOv{fzNhiRASO;u z_U;&G?0yKVV1UmlKt8lB3eeCHz!_|dfnW$Y#11gh7y#yMW8!QHu{CjUcCm-J+M(Tm z3QcT)tsf9zmxBx16y;*?0PI|X*w|a3O-%sgWro@0^wYJxAKGsU*o*?XYT|^s&92%U zQf&Zl0E9hEISi`*xe*JC|CLN^QIJ3P+(<~+d+0;KTs#0y16oFa`H%vJm^~O4&R|{` z2qKR8=Tagak{)arh8e?x!^wk!yO@in4N#WCJ)fPEn9z-}llFb}ZL3ZjU1 z#(2T8D?AKOfFL^GtAS&ZF+^)H z;e_k=3qNIwe#_XwabK{hpK)pAwJ=}W82#iuHshPMR?9g#-(1G|;z($B49LTAc80){ zmP2fYL97&~d?ndwM(u(J>*JP(JGIZMBHNN!c)mIs>=5K#(Ur9FE2C#?p{nNLlb)>b zi)RM2vO0u+koMmLzkGC^%5>PvFqhdNnSv(a*5w@k2}E4TS4SQ;>a*F}rs`_(=9?P@ zw{I)=USLw@rQ+|(f=dJE7AT56MVOIoDU>Jg6Z0??S|-g?T!k|ZD$;C#_?Vaq3ZGIT z#zSVQOc`3B-OOhL6DZFnsH?dyw3sqXjNVXALB15bvKjd}ncAHCZndB zvof51Su$F}T%f0W=h2f5Cw-())AjBdn(NQ5PdD3EU#ymKht$eVYXnNVRae}(NIAez z97}Fex*oL4?!}-GT`^?#)mY(TfDQI&SE|;Z>e)f2BBG6G7 z<|}e0`pt#zIJwEaq2}VL(LlZpU7>e@=X3(jfoe~XF+_i%0pl_`w2@3v!#;e|AbtG! z6Oluu)IGCWxh!0ltvV9XJ81QR^Foe~as7j<@~tEnWpoIwuO|l_l}gm;%Cb39a<{ci z@Qu)0=h+MTf~UI-W=MO8>eUKrpTvzskayuLuN+I2X-goJib-f^f}0#&xg)VQk9S$i zj(aMl&(jQaLYwd+m4euDPtk9)A9$}(Z0l^G1_nvAmy+CDPCr(yGcSLfrcHDj{PwYz zilR6Z2c5tucMRI}lR9k#+SMavJ)C}>Xdu>Wc>ToD_3ajW2fRzYc5#j;ROiwMij}{Z zjru##aqfs%(mREEvPh3f1S1&=mzz2e)G z_qLGx>K#Q>u8h}f{P)g*K#^@4Jw}1OJ&HqF2~A`$f(BoG$)JY1$v1Z;t&O5cdTei> zQgxV`-YaZBttWTVAT+3DCtG~0>E2^*>$JhVGdy2%CC**wK4E=}srWI0r>>fbs?u&3 zgJfUGL=>1Qw&P;f#!1n*p>p++nqH$an&@dd-aw_4MRK%ispeOj{6M`56wOhzN@6av zaMS4(j?4E{G&vgdof*DC9B_oY-zS`&9c*aL^1FE7K8nLgwbATTdBZC%A19J|71c+t zEN^lOT?!r2IZ|(9b(8iI@pB;uC9W;Sorx^YKNL$`REw z*^EYUPkk+JEj2{8eJHHULu?$WTD9-QBhJ%Iz9iwGQc1Coe7JX;enM zGNgZ&o30awUz=*~{7s3?-}?1c;6L3!9<#A{aS0GTOI%HJOM7Xaplhg6$w(3zSmLTL zInv{6XneBKgOFHP4)G#k#_w}W7}cvliLm_5Y5253Q&4M|;mS_V<+NqCxTzPRUo5@Q z8r6=8+1XC9R($qsozQ}G-ivZQPJ9b}Cbb6Ma8tE)CaCyI$P%%s;BuxE~OGh}* zWs-xoo{e5Mr*+pFnX+0es~mXP_sG3w6qh_F(nCj!gx!Mrrqi_QM@Lfm4YrRG5JJB3 zP=>A#pKmse)r58?(lE)12n6Rs6Fm~X(pUC;J)R~*F|({&Yb+&pRPPih;Hk3Wo3|}R zpHF&~`OLGdnyY#m2XrU}zkN`2LGS$eGbei~272u5=VIIOC@v8XZP85o5k;NqBZ*0* z;oe$dza8Z^`vFZ^I-wKHJ4DU2>&%d>DlE8 zy2p6&l1>3r%HIg%qmU`4PwwG{i3(q^3z_nrb8QRhWPfb4PRpH`H7e#%lz(nC$XRy_ z|3&TWsTPp=h-DKx32l>vjBP>qI*~Kc8bI#M*(~ zClQWh;VHFsB40)dTM(b#Iq8qF#|a8?OYj`61~bv;d|rI%^);!6tB^{)3OQn6$<7++ z!+NUfwB&ub0gcl!WF+NU->X@J8@N}SOv{C1tf8Oy%u~P|`V2ckFB0{HB?OwSHkcQ1 z`m{Mnh0l^Dcs4&Lit`b_QuADJh-eMuWi<7wviybn({iV>KtnK1tq(Zio0)!8y`s0` zbYS#5scUzisu^v1ejP2Ju%FF84Nc6Gd}S?b?juETVg>KLqRBEFtL@vS(tN2QZE3nW zf%k8AX1#X9p`>?xilY|iTVggtY9ZWOY`#l1xoV)3IBqmv334H(kO`YuizKsXFYU^1qSRnKUgsQ=inE?$A8EH zfy;^4yMv2EfQN&Ni+f~$qd6wXv`&M&PK&orhi`AQ&av)H7(t33K}v9cJ%eIR>%^KW z`I_Q!9DH0{dsi<>dk0VK+6K&O$_C~^BKbMNFetD&L);cvrJ0)8ffa#u8Vcjf1{OzP zb$e4Z%Ec4RDs1WE;vfitxVyV^o7g&Y+dEl^vT=gl(ZF7DHIy^T$qi)&#;k$Bm{kvW zzi-_84{28$loJjP4xTd#2S)=(1_vJ)01g382d?n?jbrOdww=i@*2rIe>BsHvU*j6U zU(;B-aXKU{I3hUWT0}^4XktKaSbju)L~cY`c2*Wo4J{fcVZw_@$JI&qKNE>%z%u5Lhn5H9Jj{1 z&G}FAlB;8CB5EV@!wbR+ywbhWT;q=(TW7MFS^Ln9+xdQtY7~EL9q)9YN{C8?as)ck zG6sF$q{6(yysfmQ;>p91bSiPPkTBnf&~R$gOtrcjsW%eB5+f2@YscTcdTD(3YN^%3 zqikD+rz0Lmen>2iii^uhh&UP<84-TI*ye%V183A#ZDT|9(POST>sq(g^dqvPh_)a( zM`}O=Bhg;;@?qT|hnAw)7ytEA6!=0590ED;2WG12tDMxP8YMjG#@TjBfv1o8nbNzSTn$?b z_Q?CT;*9FS8c|Vt_iAmLk991S*9S;}$#97~RWBy$A7_jQCxcn9#_2(L6|7I+jy7G8 zw6zv$iO4iM@0Fx$F+}E4$?LoD&cADIZ)|O6Mo54ULfqmgERyY{FS6~{mf3A)YuFG~ zsqPurdh?oA_+>{&-S~Bbm846KUWFIw=hb*p(n!^3T)EU~FQuz;QtTP9?ryKr_L=w` zZ3^6b*j%}@bCa67*omtDnQ9jU?!A}KpW|trUq6Cd%cP7%e~vdujOPw0vAwDOevG5LEgU7QE>R4&sUK*53W6{Pt(td1BtnUFIcG_nuyVoyiarq2k2q$%lhUZ}%JsX~X*7B*Q=`C@pUNc0FFmn)5Z z^&tMS((=6*6A7*;_M|)j0eFPFiK-eC3cN;-f8>tOo>qMHJYnZ?Q&m;jy%+pKFFM^s z`fn3txgcRP<%CW(lxN#F0`G%QlszM(pjNNin^0EU@<(2!N?PH2MnYLk){^zi?TQf3 z$#2J!f~K!t-GC%U zrHvaNtG7IqgU595PsbwD)MjlL(f0E;$dbK}?u6`Ge4oh*Lan0Tk|&FcRca87ipV)w z!lqTZ1@px@R4k=HY#Oc+Q@IXuGa`s+4h zEDx5KEQM^YE9QK-vVPIqm4zuJ7vD5bA`+(m@^u~Arv44iJD>aIN$ys{N}G%gPO?SZ zRumTAQ?DC}^gGUVR*(8~f1mbaFzLB(h?DcnlwD&gRdDZtrKrMVoBcGK6*YEx#7cTidiy#3bII)#R&sNM{@Rvg~0=L)Gm~DOS9&PxeZFB3*_GcmM};OPwpoxG zeajdofB0Hr4u!s5X+BB#<;~X!Msk*~xZZ{r?lHYtjP~;~yE-u(lOXs|*Nfb6z-1uR zH#S)2l3Fa0TWLCqUUfnQ;c#JhVWV_)M|%>#;p=sq*7Ij({KK@L%g|b?t~8`tz>@{7 z2%7x0JI?M{&81&)d@rd}j9Q{p&Kc;@Tcv~zb3Mwia9h#utV6r_C-^JBtYhaI;>he@ z4GxxIOrIMrybbzTvJ?Ax<6ZN!x<(PfJN6>(^D^rSHcn+?$55JidxdwxCm&k!czsDW zb2-8V{6CQiimAArrEzQHr-h-nS09A!X8FlgK76AQJWqa(bUtW02WR_+gRIE%xX#!{ zaWJFjYo|Fvbi?XU9nHH!vBp<}{P_{C?pXp~*mBq-ZWJEf1m}Ltj8V&;7l}^`H}S^@ zT|q(rG$JtMp|9J20-7J*JD$TIP>T1+3B+(t%oDo&Ss!*M>VIOC{yYGKbvo`_B7We^ z3>Pn8;DC?mNHBl_53CU%@a+(=CEuN^n3TiTXg_{nj({5eVvk@502Bh}O9A&O;9bX% zKn--@^n`%{1MwT~!@l^drTIZ70e&QKkn6y*y!7(+P}gkyrsut=?-uVXU!K6+a6$3i zt9T^fkob*SToTI*xhgDPbVKjT+)sz+5xE>0I>PNO3?Bnul+4Uhf#&qbCr$`YelmJUgyW6zfHQo@~S+2KR*gxXd2*o zq>Vy0BE`M)8~-Zrmkt@@49`&4CkenexRVZRJ7Inqp%(G1MQzR|A*V#;*mKk}|UKjBIIptXBgfO3yF=-kWpH>KS zwH)aD+9U{3Ildbz+0?lqq@o$x&@<*aF41Qocr$h2Nxo|=ZDUXuvEPcA?}og%hhCq7 z|FhJvlkx7ERGB!w6(5>Q90^8Vi8)H(UT2jUR`e2-_!i^0uD%EIZs_@vpdB!%eo^<8 zipzOeu9S@T@zCS8t$Sq8Tv+<<`fi6S8M(zL*OjLxU!A%Twe+01>0!bdo+5_(?6NkH|C5oDx~iaa~6}wOG1mr_hCsx{9cs`uS6sBb)U!+J4b!u;P#jAjXRw^@+ zKc7ktHv5!G-D#95?9kLH9ILdH+>x~9r4kwz&*??S!OI< z(rq_4Ww0oLZcQMS4mp*z==R|pOYQBG)@i|`e$|g{suLD7snF`P^@L7q=(_uUBE4=I zHuZhaZPeTOqDDd9`m*s{=`pIA#H8427sy!AYr*=fq?wz#V!}xxkNOYh43s@?8IbOd%qLb@Hxe*gT z|K-k?O0PNN3JvpB=@$sf-J-H}-^uphQ!?#e@0f>|gSho>ifheJ%?P4(Of1g2ls7AB zS-R|am2Ve<%suI9ivl@|D|lX*mEXHrQV}N@72U!(>6>5mK|sAYA+3NUC2cal@TQSo zW(%j`#Uv{i*JHYPEL?Mp52$qS#Y+p;skdSnc3F_WT$W~+=C}sKL3bV&c zElyZ)fz1fiYOz#YH7krTI7zRmeOaN;%juz%xj|7Bqqc6x8>-a!R$g_txaUVx70k@b z6BL|c!xA4Wti}^hW_Df|g!yH3M!Ls4YU`ys!fMqjpxSz2=JaVM&vaMc8s-ObUtupy z;K?)WOhKEivIbBuGUOq=5--Xm38lo5$ZZ@AW^<1{0b;927#Cz~Xl_lMp9-g7aSo11 zlp-j6D$mfusUQW8yY3&NE9a;RQWp+5b^5M?Du_)`@r?OVg`7(u{W-kLk!)|Jnue6&b#hwjDlpkvJ5l*G*_ z@gu}mE|ki6yQi4TuC4Q)Zp)U~zCEYlp;IUU)1M;^Ftc>=ip`g2LZq)hYK^p~Ty8dO zXl0USIp=Xlmc=gh4)>Y7{u9Z)9W@3|3wo4T93Oi|PfFo_VHb=uVT@sHn{FB3BrZiO(IeTM`ul5#jw@XW1Dw4Do>SwLY#ZI{%+kn&TfUX)p5w5tFtExIM zm}Md-`p&uP_S+(Y#EfeccM4VaF2xV+r8Y*KY}zZ$uJF7zu52J6>rd3jOCDP3_=J;P z2&`}0AF04T0(ocCKc|&0cCp@(B%J4k>5a$ifX_;D?~o`ot?Bi=SN=3GcU4UM&&VqIe zcJpm#1R^yX}F}25uka7uKl@4Z9LL%zI{2w z!pLjwIA!;MPg8+7a(gu>X4L0H?LhXMrv4^$qe_^?WKfJvgX!Sia#iid_4N)hO42@K zABTneFI^S$UbG31?e1nXwy%C=^*uI1y!|vJa8{2iGA>@}E%`zFt7hVs!}+7{-$7pcqCY(>RBzu52H zv}LfgQ=-iV(SA-h-KtlWVVvD$*FNV{hi*svqzNk4&2kq;EUMKH8)o&g-EO$;`;8FV z^ZI(;m2xF#Jq8c%>ecY^3jt53YOfUWxbm}Yn)kK|Y2P0nsx=-HGdCU?7h7$NDWaoE z8e@h;ii*s%Kt4w*_rv?fs>rgb)=hn;-^jCk6WQ!cY$JOh{b_pI_sTjMzQ6R8ZHhan zPW#0Kml6?Uk-T`Mcf`o+{ErVo!kX8n%7VxTo3B3579AToIVbv#(Vg1)W7I69i8R_v zH-L@On$e8OG!@UL5I0kEkjr~2ks&(-eoysmk7ZQqEi1d1c?EYqTRs;UjM+J5t>C2> zDoFFX-FqDFGaX!*ioSjXpMU%c>eVN^6}OC3p2e=kPo$3=Z{ZJ+ioMk+OX=!us`qLO zJ2rAACSmYl_rO3{8?CmHfNb<*+ApuRhHf&4XfV;|H+vCFoRio}sfyjAcg-$+`Cyvj z`l&l}rzy^>v7pomDbm(U>GPY8G!Hm@Q>HgNF22ni*hz*8+0MDh%5f?K(plYA{j$2d zJL6OK`IKw~e+`dwp1 z_dHfWyOQOUsis`3?5R|cu@WxRpPaM}UkIhqE!~yuuQ)EpF}d1bZ`Wu$o<)|PHs;Tve^=9F)(B0bhc9~I&ZmJAU8w!*3=_g}V~sIqaK_&BYfWB@=qBc-Tb9;4 zODrv6KKv`FV{hLCtM!m_1x@rZKmBAfWW#1Vi~EdHA0AbGM>H|qSIsXiZXD-p(`B8z zviN?;*ICHwZ7@2;L4vpK$^A?HwlIP8MMlxU{Bw=nUeS;`he1*El z;dbyOU3|-n0s$DEB&~F`utk>jb<=x!!@5gp&6) zkk_xfp!edT08E!Mr0XQhCnsm_(do|V@(lxv5^DkN=48Rkh6y!c+XORA0}qF7cJ*d# zv?C*yd1kH-u-hS;p4Yzao3~!0TghBONv zD4;7raOiGcf+JDi&blbw-K`U?ldHC3yEnD`9$oO`;hs2tMr%r362W3s@xWF_Apdx_ z;1j$jv3O4$8d**dJJ~O*HdT+3%x3Z4`1szt`&O^!nOrNkrO^iGnWZf^pCbS024mmg zhRrhxjY~_r^TkU`rDuX}yVCafmo9A5oXPe-_U0i8;j2EqlJq3az(+!hsY1wtj=^hb zHFtbTrjHiGh{vJqieHE~blYOMHr3zs+Li~HE%$J;vL4Y7q!T~eCUCS(WA1dc zlqwflY(z^)Y{6y0)vd_#FD+{jYSa;J_ocVxwp-t9_1&IMs<=4l8lOMc2$h*`_4jG` z_Qv|W|N4w_cgivnL?m{y%~m|^!1~-go+u`eyhK@=*BlUE)_>S(U^eW zohdA@D2mo0$Gt4qe|d@M#;2>RHEsoCGnKs`RitWMJn@MU(~B>O^K0&r4rs_#5sXky zxq?h>bWOz0R{`Hrvv@{h&$>m^QFN_^mbcWlwopu;x=Jo!SslP|2~Pq?6i3s>g1l!*lggm1MU6Va_fRYDKg?ZgLT|()@j9Y#f9`Nesv{TPLeWR=n)Rf z=I49!@2}bxIA1z%xchb&U+^JBZ_H;wG*j7*E$>Z|Fjf5qPHMf^V!A!qBia~sWX!PZ z#~Z3nMGjkZVIq0!ZQAhkv$rxtk9>PBWukHa=JmMinNDfhQ#pmJk1~~Z#k=}tj<|aT z==U@!jOkxtdk<^gg|l71>a-I_ znJ!+^@DaOtf9;sYD6j!Vx=4sf6j|nX<;CWXhTzwgm^sJ7l24-^wA%BT%LM1IJ-U_K ziEI}+t=J>{bi&eU@n!%wWAhOGW~Q1Bn;Q$oXB%aTb{v=JN>A<}ST%LGon@GZTN<4C ziGIeJpw*kp(!rC@PM?n2>mDQZ8Nof#0Y9abqM`%08;+3#e>3mDu#&hGTyt5Lqf(-4 zX{Cq2o9}3T*kJnnabi1)s&+Z*Nd=M$wYSveG5IZ`eAk;b9A#i^CyCLNF72&;2}|P4 zqUwo*@q=;l++>0+v@S%IPj6l3Rxa?rR5@r45-Gno`PeVhE{3nlZrFl!V*~ZV*n2>M zW%b?Sv+O{oOP?tpU!k~q_EuWI<=i>kj&FQtUgj|;4K0KhI+O>tP%=xYoOsjMLxk8f z42)^^OTOnGu+AFdI27erm;yo&7Lc-Q+#IJen${3aelZ>Kh-;M3zFu4BJ!!MY&-)$g9w0a1DRQEHm^xO~uybZgiZ1J}m^y#i`{?2l!y4bo{$~jSor&V- z?pVfC#@lJ?EmrFxFLM-GP$C^0zEU1_l6N6~#8eJ{?sgP(+JVM3Pspi?B$4o%k%WQI zK(Twrh?l$L>)a1Q)cDN&NcpB=VU>WdAIvj1ivxN#d#YXDIRaZE9WKB2L#ecgUVA#*0XA8{9gm*sdkLv5r*sX}m{F`tA+S%S;NSI9W@$T&6? zI5uM;=+->0BD$hCtyey$K6%fpba^)UF^Zy#)&tKy5&ZR7))vjqZhYv%F)=qBh{0Qe zxQn5i&z>niUFd!!dvkzncxz&WC98R+a~ozePnf;}O<2~$=_{^&SL5XvCwr&bLFeXd zA~;t%bR>RJCLHnp@=%5Bu7SK|B121-iduLKrvd`T9m`sSn^9(QUCYqr6&2@F%XWkJ z+Gw$VX=(7v+QhSzzAe#yyn7ePT}U z5JiuYJYTJgN0H_^(MO5R1TQ={JRb#5#Aak?^Ebf9LP93-5D;e_ao-cw2G0$WPLOab z-@lpLvJm{pz~9eAT*gtV>?S2x>`u~fB8+|_83xLiE6IqHh&U1Id%dW+PQi^nTh#U_ zj|Yor!jZzGp~nMxM;D_~Tp7kY{PiZ}RaW!0UIaMB-62x|6WD#hKSO8armAYFC%b%6 zmy0(w@CH(uSj74LTh{^KU8%3VZ`8eZ3WrAPuO;j{cH>`Y&2E727TqMfy0B7k|74Qt z>eJ%jy!9QH#MX+e^=`9w#Z zZqZOD_n`MH#S71%IjyX35pc;zc2j3`+c?bMZRZYLu(&;VN)|kGb={5JYrx_B`_lMW zoj55d4Y#`ib4AK^a`6SPNGEa7vWidGaLP?43+U$#p@bw-&pm42G3`lh&du4yfSuzX z$9A9bD<6Z8zgnvQG9fYaJKTmR2 z8qu^B++o5t--m2#=!F{c`7j!nl0+QD)}dcsGXxpFB&1ER#hBS(s7UtALl8B2UZ zsvvjO)KLo29@g$qqtl>gm{WCkk=uOMUc6=K1ktzY zdk#ojxAc1|(V+Sfz7e)7%^Yq?DvA_Q-}J<<2$|KBO{C96W{Y2t(FlmSFiRyT3pPt8 z-W6ZD3BJ&Ue;?LTwv=9TLA&gPS4(5JeA&yG%a5qsQ)wt8kd1o4Jg2kXtS zU*S;fswd!&5a?8QyLy{CtD+3g;YRFx zXIONc4(#_q8h1E;sFTT6_25J#MHW1RnGQY}mh($2FrY%wn4BM{n&Wg=lsLI8<(G?! zhjs|IYN1OLIc{E(EpU!sII9s{e1~04TAN4H=CpRJwyrs-;=VJTb4G=M=8`mPc%DY& z(^=M&s62zj7(Gg29_xqBaUAnTQT^jGRwBB}{IDn+#(}5SsZmJ?i6Ga9wo$%OH8Oe} zrJDVMTF8OArE(hzrTPJJTAeap`u0Fd((`R4Cll7nwyU?6?^~~yhma(;mypJ44v|j|1Mm@5EqUc@A2HymWvHNbCDZP3;ljT$arluNkZIs<@7$*7Xl#}}LF*miCT8Tp0Md$g;w3k6W)wZUWoQHtFG(*%W0lM_#^J z(VS6Er73Z*VlJYAJmBsSksDDXdN5>JSha-P&~FdpFB|T;`l+uCue)i&L0#Diqw_cQ#@&j0HRB}VpPYHYcxvrNx6K%R5*YHmG}Rp(V~6>U*gAT= zo~khPU%JH3-TrCUpRr@_0l8IA<*|1*_%%`I!(J;)DFr3HSvcP-cU&`({lhIEM_3wz zQE18JhcM?pD~*?ZHxO2NZ|~S$Ob_5TB|*_s3UT0)uRbUe{g~(T)cWg?kDKO-SA!_R z_2}~!6Ltlsd&nyKZ?P#H)6Z)!W$|~Pxx{t5O>NqYvq(z)vzcQ&9O){WCHs=`i;l;w z9l>QibhLN0d$hfh745Sk0o~_)I@UIbZv_(+MS`w$b<|@DBMNrrG>g`)ny=YCZ4v}m}fpILXpcA`qB`Yqoef0(5 zn~*h|zV7j2zJ+-@V;|4tMjMW!^AlNe(NfulZDzE`L>AC-6MC499^B|Tv?8F&5eBt z-0cDzi`lQZo{s8y#H@WrC9s$!tnNwghC+1w;hgx=xCSXD&nW|?0~qs1+c=%@)g2k0*j+f5>gw^<=BD=SlVG3rr6sxKJRj%? zW84=p`L(IK=dGtgL5Do*8ANE&0ZIrr~M9HQq`-a*Tp{IW@sw&A$#5R%U z=5lh)DFR4iVq_ShUq#}`E_C-@DUseC{$uko$0GU8tS=B5-M%#bB`P3Z;OpzhdCb*y zuWl#za>cr%Q!KwY2nAo@K}4gCn~-Qow$&G`{Khm7e+&R777>RC7!r5W*Hkoc@yi##|3g` z6xJMa$Fnxhd7dk2U4Xunznk%F>cNIYBZ7da`{vAq?wf}Sr=7X>|b<4_KDKFclwNgmYh`({Q_ zK6&H88%=^o8O$t&?DUJh85O@uM=HMBkre*WO&r#zAJa>d3kFys&+@LP z+u%>3&sx25Lh?Huy~Xi*md`%O#@cDwTRLJy<+K*}^$?+gvb(2l2c^tLyR5}5!JJ;7 z+GXZD@rjL5f;WlF$$#0I)L<=WOAfOIkf}N*G-b-q|m&`*nr4L)mtKwHhUbw4a z9Y&;kUCs9x@cEDNnr-5fu)6s8(QWMz`p*HU=OCwN45~=wNJ(={vV*RaJPvBQF_|_u zjp8*=ys5kg^|ShB4Bh>l_n}33#Q8;cbuoW`WD1X|)L`UX=R|I^dp5FPJ$LeXPU+&v z>ifl)%vn<6lbm?M%em8f(NSLo<4{2~`Rw9fDIT`deT}mrS}kI-5OUzl13SAGY}vRs zg@r(0OL;Iq{%mP(1;5#xydybf%yo7ov#whQekniSrrrM2dtBJ@a~4^-?8)^3K4mf!@!Y>Jd%O$uTu%G7{fsfvp>n$oV z^T!JU9KX*#9vLglJE3>i9?9Soamtyix-Z@`gh9S`j(+L{7m}K}M{#@9V)x~T>CuTi zCv)FI6Z#~+@(aoA!ARNJDXZ(^Hc@>?&G!U$6h4UnzMvZ7v7p;<6K!wFE?JA+%@KEh z-;c_z9$)l7wb~g3^u|nNj~iQS&o>D=O8Kk#Ykhi?ZR7vyG20ziBBii9>Ktb{Pmyc% zbm4NHGEslx3?)p<(UBxpnu(3#e|ziVH-?^LDoF>ASjLPEa~q3q;R&US`jHeuq*MCtP-hcY_iK>`1_##L;86Wd`0 z=_VQf&d4hhoUJ9MO_S_3p|yT~wEow`?2(om5R>4~MXr_iUsrW~V_}sHp5U4&R@2$k z8!ZN-s$LhZ3bNB?uF~8|L(3>bQ!P*JP~2s<&nt3a*OSk_*mp|qydTxw!m&VS*mwxJn7R@%=o@2yF2Dah4IY_2$r7Mojczvkg%6 zFPm+E-=&9$yL~^#2>gI3uocwAWB*X&e(dluN9>z}V~&_j-3P}U4Rw3~VELZ%_4rsd7d=1n9=k*kJ*gxs6lXWP?LTi4OkhFlN`C;?F{ zg|Y~Ct@SusJcIiRE7jUz1I+=k$a^oq?;-#4?A%qbUWoLobaot>r=Sd3$`o%b=4;W>3t`-X1I zQYSK|z$W!n!xtzbnvN8TVrP^Ndt8)PWF<%=#lk97DdL!v5t?#^%eD9QA<~5`39&i3 z5*Z_cr{3s_MvRsg)HYw#2M1uGQi(xn3v&$N151j!B}A!I$_Rf`3^y{1knzUiC{;-* zO&JoK`C}VRJ9qP?lt|TCYX*TXKo9*=6l5b4X0%mnQiA~$lYlBQtDmc<6=T!WGO142 z1&jGL?nNn&8VmKYgcZt_3tHq6L=DVFi)9zpw9+Px)A2N43D)F`Dm*F8V(SKxvZCaX z_RWgtBVse@3f8oT#}W0p{j!tS`ox@j&R}>Iq+Uy+cnP{{kA?$qQ9j8}d|QZspp4#tn+505`6MicKG&g1n`eSqf=Uw?5NGD#&9K3pL+@m3(=Nou--Toh7>^^Ad5S7>1 zCP1BTKj_7hxe!6^5gxy;2?3wu#Co}jsE=2&7CW&TPA5dFDmw4nb}uuEKqAqVanvXM z?bw;n7eNGT*}EMPpE1I>%=Cx1T(9ne%g>m+L|Eb75)CY-DQYWViEX zvXMHH=gpc24D~1buK4Nw=>U4hM1!ZBHd)B?M{aZoa@1JATlFaptUk;roQ2@?KD#`} zHUa(uCQi?U2F6l<0%Hd{gThEvQ+CMi)=`v$fhK17jos|O*j83*6<&G^L5O%RaD$3W zkbR+SW{iAB$!+7zNd?EHQNDUm>XN8>uz=*5YE4U=HhIZNscH~^R_o@LkjG;n*X*5< z{c~*%)1U25QkQIuBhB3qJ3?g0%zBXxL-Sl%N;kr&IKQcW<>otYNE7Q-Rg*e;KB>i? z&#&q43YQ7<3C(c(T;UhD3rO4}m)|NYzPDoS50Sc+T`uXk`$mH7wt2IyIq)rHk+@{d zul^=U2_ zu56&XYphf6t(tU3?gk!@vsm|nz5zl26Xcj4H{to&-SED))5lajQQ%%eAYi6kB62h7 z>QW4oMl{Eg<%*cirphQ2fp@IqYI0=5QF(4w)o}ml)->rsP$vBT>$y=@LyEidaka3qcubdc6!b0}lvtySC;QW$KwT&GpL|Tx-gP6?}^G zg*%yyppoJA!hLw(VL;Y#zyO~*Rf|-RP~C@cSm;(5sCv{qR{(pa66HSdV$s`OXk*ws z_@?49oKhn@vK5K$A&hpdeHNSZd(h33?9eqyv*9COeu3|DRHO7N!801458MvEJFd7c zxeRs79?~d4)CFJr(g4Ng@xQJ$?o}_<28NE}1evdHWqE8cxy$3hg%{on@B6QD_!O!oU7`b+1i+Z!LT^B}%Q&p1V|u)!mVTJ;+; zJs@@js38zOj=txl%cD_%bX;;Pu>xH1P!^s@+w#xX#-EFFmXozOA#}TW9wg6Yb3*;O z&ve1grYn5{6qaX8)F@{;#jvn^Zj_eM9bW0ehs4ePEbsl&92f30&zV<;F8nHK(X7v8 zBczN1s2=TwNANTc-sjX=buvGdTJSH*R{F5${U`3LfP}N7DosX^A5<>#li@ww5!s9yHG0FY2P5B}euHJ>X0i8g{VHg8S!kR8!1EzQ$&vzyw}2(f zs9bQ%w9h-z(&9a%uQ&feG!1+q+VvqV7P=GpD>?Fg%V2uq%9~e9Rl_+yuA+Zkq>^a3 z+$&VO`NR8GU}%T&ahqC1zIR=W+A8BV#v9M406aW!~azHf3ax(*022CvhzpY_Yb(kf1tSDW*X ze(3ArpZg)Uzn#DQs~`H~!sUNGhT&lQw_})pLp%KS7)FRrlunFJ;t#;X7XsuD$iqK? z#(y9+{tP$%7yZHbfA|l7(0#t}8Gk21{H<#;cegkHVm?^VS^fhHVQcY4h4>R2;&0%J z|71isTDbj-6XE3g1?BkavE1m~={)|E8NvDoll9Nd)}JV>|CuuXZ_O49Jsb0%;?xc5 zkjhF+t-K6zj_K8KLjez&fgP$5$Uu|M#oO|zHM^0c+2exAVj>VmaajO>z0ydB^uy)5 ze&O?ta0^rwjjA?f3zl>ZtB;%B$A#W@)Y&Cq7=f3k<#$dz)^bW^65@>CMxt$E+3|KavKae7X zXRk?ywqus*ef7E^%9frqv{q;}>-7s0H_|yG%2h$!Ltn1$5;SeDBd_n^ZX*fsfht(R zukN0HhBbJ2|IiZ_9yY{IJ3c;M$rRYB3+(es(wM3be~iAabGU(ff{VC)tkuN*7FF%= z2y@%WXk*)WvcbSkLBiO}HEtN(hdxrT6baBW*0Vlj_)>TF5f5S1!> zk&RQFkwD!Lmnw6StEx~|!jeGqfY$Jslmf;r6`jilxmP9Z#l zQOZXjNnay;8>`o&{X`fcFxjP5Mg+@HWCV-J zW6u!StW`XQo@{r}bEGQx(DlS4P2}G%tfQ#msmEHE+u_id8!h_N z7A!7%$9pTc1_!R&wj91WQCu$AiE1mDcpBtBCuDk~ zr|q%d4cKV2i)VD&&IrMo52?3o;6wF8YK3w5R{<4jt@5Pv53Q+GGO_CZvl?7?_ib-; z+RVVk+~DZxt(h1vdGgT&3ra7f#-Z`jlkW1~wCHSEr!Trh`O{F<#kCV|l_Y>WAiYRT z$sS~>TN>cXagfGAE#+G61hi#D)hi~v; zJK}-WDT=EP!8Tot7OlDZw4kVugw7GA4K+R6W?EqAE~3>TEp!5!W!_6zcpzsnX?G{H z_$560r?XV#CjX7K-dmrXgG%=JZrmJvz90l~h4{Cb6DX@wK}()PDH}sY4pJnk>wdnS zR#j)X(`>LxK6GW~i|k>$!-=;cL|oU{EDyv~Cu|!^bZ9lmPGA1&5t)E6Z >3dayTvuHq} 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 literal 0 HcmV?d00001 From 6277bbfdc49d554e8dd797a3713a29cc81b40a52 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 20:51:16 +0100 Subject: [PATCH 012/215] updated readme --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 5cb0757..e9c67c5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ SVO === +This code implements a semi-direct visual odometry pipeline that is described in the paper + +C. Forster, M. Pizzoli, D. Scaramuzza, +"SVO: Fast Semi-Direct Monocular Visual Odometry," +IEEE International Conference on Robotics and Automation (ICRA), 2014. + +Video: http://youtu.be/2YnIMfw6bJY + Disclaimer ---------- From c2a52c68adfef57701e90602f20e3d70d9e28633 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 12 Mar 2014 22:28:31 +0100 Subject: [PATCH 013/215] removed remote_node --- svo_ros/CMakeLists.txt | 2 - svo_ros/include/svo_ros/dataset_imu.h | 70 ----------- svo_ros/src/remote_node.cpp | 169 -------------------------- 3 files changed, 241 deletions(-) delete mode 100644 svo_ros/include/svo_ros/dataset_imu.h delete mode 100644 svo_ros/src/remote_node.cpp diff --git a/svo_ros/CMakeLists.txt b/svo_ros/CMakeLists.txt index 8fcd739..192de3c 100644 --- a/svo_ros/CMakeLists.txt +++ b/svo_ros/CMakeLists.txt @@ -58,5 +58,3 @@ ADD_EXECUTABLE(vo src/vo_node.cpp) TARGET_LINK_LIBRARIES(vo svo_visualizer) ADD_EXECUTABLE(benchmark src/benchmark_node.cpp) TARGET_LINK_LIBRARIES(benchmark svo_visualizer) -ADD_EXECUTABLE(remote src/remote_node.cpp) -TARGET_LINK_LIBRARIES(remote svo_visualizer) \ No newline at end of file diff --git a/svo_ros/include/svo_ros/dataset_imu.h b/svo_ros/include/svo_ros/dataset_imu.h deleted file mode 100644 index 9ee5e66..0000000 --- a/svo_ros/include/svo_ros/dataset_imu.h +++ /dev/null @@ -1,70 +0,0 @@ -// This file is part of SVO - Semi-direct Visual Odometry. -// -// Copyright (C) 2014 Christian Forster -// (Robotics and Perception Group, University of Zurich, Switzerland). -// -// SVO is free software: you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the Free Software -// Foundation, either version 3 of the License, or any later version. -// -// SVO is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#ifndef DATASET_IMU_H_ -#define DATASET_IMU_H_ - -namespace FileType { - -#include -#include -#include - -using ::Eigen::Quaterniond; -using ::Eigen::Vector3d; - -/// Specification of Dataset which contains: Camera Image, Gyroscope Rotation -class DatasetImu -{ -public: - DatasetImu() {} - virtual ~DatasetImu() {} - - double stamp_; - Quaterniond q_imu_; - - friend std::ostream& operator <<(std::ostream& out, const DatasetImu& pair); - friend std::istream& operator >>(std::istream& in, DatasetImu& pair); -}; - -std::ostream& operator <<(std::ostream& out, const DatasetImu& gt) -{ - out - << gt.stamp_ << " " - << gt.q_imu_.x() << " " - << gt.q_imu_.y() << " " - << gt.q_imu_.z() << " " - << gt.q_imu_.w() << " " - << std::endl; - return out; -} - -std::istream& operator >>(std::istream& in, DatasetImu& gt) -{ - in >> gt.stamp_; - double x,y,z,w; - in >> x; - in >> y; - in >> z; - in >> w; - gt.q_imu_ = Quaterniond(w, x, y, z); - return in; -} - -} // end namespace FileType - - -#endif /* DATASET_IMU_H_ */ diff --git a/svo_ros/src/remote_node.cpp b/svo_ros/src/remote_node.cpp deleted file mode 100644 index 8952b21..0000000 --- a/svo_ros/src/remote_node.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// This file is part of SVO - Semi-direct Visual Odometry. -// -// Copyright (C) 2014 Christian Forster -// (Robotics and Perception Group, University of Zurich, Switzerland). -// -// SVO is free software: you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the Free Software -// Foundation, either version 3 of the License, or any later version. -// -// SVO is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class RemoteHandler -{ -public: - ros::NodeHandle& nh_; - vk::UserInputThread input_thread_; - - ros::Publisher pub_key_; - ros::Publisher pub_frames_; - tf::TransformBroadcaster br_; - - vk::RingBuffer acc_timing_; - vk::RingBuffer acc_obs_; - typedef std::map > pose_map_t; - pose_map_t poses_; - std::set published_kfs_; - std::set current_kfs_; - - RemoteHandler(ros::NodeHandle& nh); - ~RemoteHandler(); - void handleUserInput(); - void poseCb(const geometry_msgs::PoseWithCovarianceStampedConstPtr msg); - void infoCb(const svo_msgs::InfoConstPtr msg); -}; - -RemoteHandler::RemoteHandler(ros::NodeHandle& nh) : - nh_(nh), - pub_key_(nh_.advertise ("/svo/remote_key", 10)), - pub_frames_(nh_.advertise("/svo/vis/frame", 100)), - acc_timing_(50), - acc_obs_(50) -{} - -RemoteHandler::~RemoteHandler() -{} - -void RemoteHandler::handleUserInput() -{ - char key = input_thread_.getInput(); - std_msgs::StringPtr msg(new std_msgs::String); - switch(key) - { - case 'q': msg->data = 'q'; pub_key_.publish(msg); break; // quit - case 'r': msg->data = 'r'; pub_key_.publish(msg); break; // reset - case 'p': msg->data = 'p'; pub_key_.publish(msg); break; // pause - case 's': msg->data = 's'; pub_key_.publish(msg); break; // start - default: ; - } -} - -void RemoteHandler::poseCb(const geometry_msgs::PoseWithCovarianceStampedConstPtr msg) -{ - Eigen::Vector3d p(msg->pose.pose.position.x, msg->pose.pose.position.y, msg->pose.pose.position.z); - Eigen::Quaterniond q(msg->pose.pose.orientation.w, msg->pose.pose.orientation.x, msg->pose.pose.orientation.y, msg->pose.pose.orientation.z); - Eigen::Matrix3d R_world_from_frame(q.inverse()); - Eigen::Vector3d p_frame_in_world(-R_world_from_frame*p); - - poses_.insert(std::pair >( - msg->header.seq, - std::pair(p_frame_in_world, R_world_from_frame))); - - // publish trajectory - vk::output_helper::publishPointMarker(pub_frames_, p_frame_in_world, "trajectory_points", - msg->header.stamp, msg->header.seq, 0, 0.006, Eigen::Vector3d(0.,0.,0.5)); - - // publish camera pose tf - tf::StampedTransform transform_msg; - transform_msg.frame_id_ = "cam"; - transform_msg.child_frame_id_ = "world"; - transform_msg.stamp_ = msg->header.stamp; - transform_msg.setOrigin(tf::Vector3(p.x(), p.y(), p.z())); - transform_msg.setRotation(tf::Quaternion(q.x(), q.y(), q.z(), q.w())); - br_.sendTransform(transform_msg); - - // publish keyframes - std::set deleted_kfs; - std::set_difference(published_kfs_.begin(), published_kfs_.end(), current_kfs_.begin(), current_kfs_.end(), std::inserter(deleted_kfs, deleted_kfs.end())); - for(std::set::iterator it=deleted_kfs.begin(); it!=deleted_kfs.end(); ++it) - { - pose_map_t::iterator kf = poses_.find(*it); - if(kf != poses_.end()) - vk::output_helper::publishFrameMarker(pub_frames_, kf->second.second, kf->second.first, "kfs", ros::Time::now(), (*it)*10, 2, 0.015); - } - - std::set unpublished_kfs; - std::set_difference(current_kfs_.begin(), current_kfs_.end(), published_kfs_.begin(), published_kfs_.end(), std::inserter(unpublished_kfs, unpublished_kfs.end())); - for(std::set::iterator it=unpublished_kfs.begin(); it!=unpublished_kfs.end(); ++it) - { - pose_map_t::iterator kf = poses_.find(*it); - if(kf != poses_.end()) - vk::output_helper::publishFrameMarker(pub_frames_, kf->second.second, kf->second.first, "kfs", ros::Time::now(), (*it)*10, 0, 0.015); - } - published_kfs_.swap(current_kfs_); - - - // publish hexacopter - vk::output_helper::publishHexacopterMarker(pub_frames_, "cam", "hexacopter", msg->header.stamp, 1, 0, 0.3, Eigen::Vector3d(0.,0.,1.)); -} - -void RemoteHandler::infoCb(const svo_msgs::InfoConstPtr msg) -{ - std::string kfmsg(""); - current_kfs_.clear(); - for(std::vector::const_iterator it=msg->keyframes.begin(); it!=msg->keyframes.end(); ++it) { - current_kfs_.insert(static_cast(*it)); - if(*it == static_cast(msg->header.seq)) { - kfmsg = "Keyframe!"; - break; - } - } - acc_timing_.push_back(msg->processing_time); - acc_obs_.push_back(msg->num_matches); - - printf("[%i] t=%.2fhz (mean=%.2f) \t n_obs=%i (mean=%i) \t %s\n", - msg->header.seq, 1./msg->processing_time, 1./acc_timing_.getMean(), - msg->num_matches, acc_obs_.getMean(), kfmsg.c_str()); -} - -int main(int argc, char **argv) -{ - ros::init(argc, argv, "svo_remote"); - ros::NodeHandle nh; - RemoteHandler node(nh); - - printf("Listening to User-Input...\n"); - - ros::Subscriber sub_pose = nh.subscribe("/svo/pose", 10, &RemoteHandler::poseCb, &node); - ros::Subscriber sub_info = nh.subscribe("/svo/info", 10, &RemoteHandler::infoCb, &node); - ros::Rate r(100); - while (ros::ok()) - { - node.handleUserInput(); - ros::spinOnce(); - r.sleep(); - } - return 0; -} From a3eaaac1f9af9b2cad8fe90b80c6faedbc51e454 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 13 Mar 2014 09:15:57 +0100 Subject: [PATCH 014/215] Update README.md --- README.md | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e9c67c5..175205e 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ SVO This code implements a semi-direct visual odometry pipeline that is described in the paper -C. Forster, M. Pizzoli, D. Scaramuzza, -"SVO: Fast Semi-Direct Monocular Visual Odometry," -IEEE International Conference on Robotics and Automation (ICRA), 2014. +* C. Forster, M. Pizzoli, D. Scaramuzza, + "__SVO: Fast Semi-Direct Monocular Visual Odometry__," + IEEE International Conference on Robotics and Automation (ICRA), 2014. Video: http://youtu.be/2YnIMfw6bJY @@ -14,10 +14,18 @@ Disclaimer SVO has been tested under ROS Groovy and Hydro and Ubuntu 12.04 and 13.04. This is research code, any fitness for a particular purpose is disclaimed. + +Licence +------- + +The source code is released under a GPLv3 licence. A professional edition license for closed-source projects is also available. Please contact `forster at ifi dot uzh dot ch` for further information. + + Installation Instructions ------------------------- -We use two workspaces, one for the plain CMake projects `Sophus`, `Fast` and optionally `g2o` and another workspace for the Catkin projects `rpg_vikit` and `rpg_svo`. Make sure to clone in the right folder. +SVO can be used conveniently with ROS (www.ros.org). +We use two workspaces, one for the plain CMake projects `Sophus`, `Fast` and optionally `g2o` and another workspace for the ROS-Catkin projects `rpg_vikit` and `rpg_svo`. Make sure to clone in the right folder. #### Sophus - Lie groups @@ -34,7 +42,7 @@ Sophus by Hauke Strasdat implements Lie groups that we need to describe rigid bo You don't need to install the library since `cmake ..` writes the package location to `~.cmake/packages/` where CMake can later find it. -#### Fast Detector +#### Fast - Corner Detector The Fast detector by Edward Rosten is used to detect corners. To simplify installation we provide a CMake package that contains the fast detector from the libCVD library (http://www.edwardrosten.com/cvd/). @@ -47,7 +55,7 @@ To simplify installation we provide a CMake package that contains the fast detec cmake .. make -#### OPTIONAL: g2o - General Graph Optimization +#### g2o - General Graph Optimization _OPTIONAL_ Only required if you want to run bundle adjustment. It is not necessary for visual odometry. In fact, we don't run it on our MAVs. g2o requires the following system dependencies: `cmake, libeigen3-dev, libsuitesparse-dev, libqt4-dev, qt4-qmake, libqglviewer-qt4-dev`, install them with `apt-get` @@ -134,6 +142,8 @@ SVO supports three camera models: 3. The `Ocam` model by Davide Scaramuzza which can be used to model cameras with high field of view or even omnidirectional cameras. Use the OCamCalib toolbox to calibrate your camera: http://rpg.ifi.uzh.ch/software_datasets.html Although SVO can be used with this camera model, the algorithm does not work yet with omnidirectional cameras. +We save the calibration in _YAML_ format (see examples in `svo_ros/param`) and include it in the launchfiles (see examples in `svo_ros/launch`). + Parameter Settings ------------------ @@ -153,11 +163,6 @@ Contributing You are very welcome to contribute to SVO by opening a pull request via Github. I try to follow the ROS C++ style guide http://wiki.ros.org/CppStyleGuide -Licence -------- - -The source code is released under GPLv3 licence. A professional edition license for closed-source projects is also available. Please contact `forster at ifi dot uzh dot ch` for further information. - Citing ------ @@ -168,4 +173,4 @@ If you use SVO in an academic context, please cite the following publication: title = {{SVO: Fast Semi-Direct Monocular Visual Odometry}}, journal = {IEEE International Conference on Robotics and Automation (ICRA)}, year = {2014} - } \ No newline at end of file + } From b250b120960e63daaadb34066e2565ebef45f2f3 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 13 Mar 2014 09:39:34 +0100 Subject: [PATCH 015/215] Update README.md --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 175205e..36cf767 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,10 @@ Licence The source code is released under a GPLv3 licence. A professional edition license for closed-source projects is also available. Please contact `forster at ifi dot uzh dot ch` for further information. +Documentation +------------- + +The API is documented here: http://uzh-rpg.github.io/rpg_svo/doc/ Installation Instructions ------------------------- @@ -149,13 +153,6 @@ Parameter Settings A description of all parameters which can be set via the launchfile is provided in `svo/include/config.h`. The default parameters can be viewed in `svo/src/config.cpp`. Moreover, some additional parameters (mainly rostopic names etc.) are read from the ros parameter server in `svo_ros/vo_node.cpp`. -Generating Code Documentation ------------------------------ - -You can generate a Doxygen documentation as follows - - cd svo - doxygen Doxyfile Contributing ------------ From 978763d814c4c52052ca9663da985048744bc499 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 13 Mar 2014 17:30:12 +0100 Subject: [PATCH 016/215] formatting test launchfile --- svo_ros/launch/test_rig3.launch | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/svo_ros/launch/test_rig3.launch b/svo_ros/launch/test_rig3.launch index 31b85f4..fc0671d 100644 --- a/svo_ros/launch/test_rig3.launch +++ b/svo_ros/launch/test_rig3.launch @@ -2,17 +2,19 @@ - + - + + + From 24b644d82f2187cdc54ca51a187bbe8b34416ab2 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 21 Mar 2014 19:00:47 +0100 Subject: [PATCH 017/215] removed user input and marker visualization in benchmark node --- svo_ros/src/benchmark_node.cpp | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index 2d0ff6e..c919281 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -39,11 +38,9 @@ class BenchmarkNode { svo::FrameHandlerMono* vo_; svo::Visualizer visualizer_; - vk::UserInputThread user_input_thread_; int frame_count_; std::ofstream trace_est_pose_; vk::AbstractCamera* cam_; - bool quit_; public: BenchmarkNode(ros::NodeHandle& nh); @@ -54,8 +51,7 @@ public: BenchmarkNode::BenchmarkNode(ros::NodeHandle& nh) : vo_(NULL), - frame_count_(0), - quit_(false) + frame_count_(0) { // Create Camera if(!vk::camera_loader::loadFromRosNs("svo", cam_)) @@ -103,13 +99,10 @@ void BenchmarkNode::runCamImuBenchmark() throw std::runtime_error("Image could not be loaded."); // Add image to VO - processUserActions(); vo_->addImage(img, it->stamp_); // Visualize visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->stamp_); - if(vo_->stage() != svo::FrameHandlerMono::PAUSED) - visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); // write pose to tracefile if(vo_->stage() == svo::FrameHandlerMono::DEFAULT_FRAME) @@ -123,23 +116,11 @@ void BenchmarkNode::runCamImuBenchmark() trace_est_pose_ << p.x() << " " << p.y() << " " << p.z() << " " << q.x() << " " << q.y() << " " << q.z() << " " << q.w() << endl; } - if (!ros::ok() || quit_) + if (!ros::ok()) break; } } -void BenchmarkNode::processUserActions() -{ - char input = user_input_thread_.getInput(); - switch(input) - { - case 'q': quit_ = true; break; - case 'r': vo_->reset(); break; - case 's': vo_->start(); break; - default: ; - } -} - } // namespace svo int main(int argc, char** argv) From 0ba17d31994f8fa31172da7cf80b85dd6cd76de1 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 21 Mar 2014 19:11:32 +0100 Subject: [PATCH 018/215] cleanup and moved trace to separate function --- svo_ros/src/benchmark_node.cpp | 39 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index c919281..2998c23 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -45,8 +45,8 @@ class BenchmarkNode public: BenchmarkNode(ros::NodeHandle& nh); ~BenchmarkNode(); - void runCamImuBenchmark(); - void processUserActions(); + void tracePose(const SE3& T_w_f, const double timestamp); + void runBenchmark(const std::string& benchmark_dir); }; BenchmarkNode::BenchmarkNode(ros::NodeHandle& nh) : @@ -68,10 +68,21 @@ BenchmarkNode::~BenchmarkNode() delete cam_; } -void BenchmarkNode::runCamImuBenchmark() +void BenchmarkNode::tracePose(const SE3& T_w_f, const double timestamp) +{ + Quaterniond q(T_w_f.unit_quaternion()); + Vector3d p(T_w_f.translation()); + trace_est_pose_.precision(15); + trace_est_pose_.setf(std::ios::fixed, std::ios::floatfield ); + trace_est_pose_ << timestamp << " "; + trace_est_pose_.precision(6); + trace_est_pose_ << p.x() << " " << p.y() << " " << p.z() << " " + << q.x() << " " << q.y() << " " << q.z() << " " << q.w() << endl; +} + +void BenchmarkNode::runBenchmark(const std::string& benchmark_dir) { // create image reader and load dataset - std::string benchmark_dir(vk::getParam("svo/dataset_directory")); std::string filename_benchmark(benchmark_dir + "/images.txt"); vk::FileReader dataset_reader(filename_benchmark); dataset_reader.skipComments(); @@ -84,7 +95,7 @@ void BenchmarkNode::runCamImuBenchmark() std::string trace_est_name(Config::traceDir() + "/traj_estimate.txt"); trace_est_pose_.open(trace_est_name.c_str()); if(trace_est_pose_.fail()) - throw std::runtime_error("ERROR:frame_count_ could not create tracefile. probably the specified folder does not exist."); + throw std::runtime_error("Could not create tracefile. Does folder exist?"); // process dataset for(vk::vector::iterator it = dataset.begin(); @@ -106,16 +117,7 @@ void BenchmarkNode::runCamImuBenchmark() // write pose to tracefile if(vo_->stage() == svo::FrameHandlerMono::DEFAULT_FRAME) - { - Quaterniond q(vo_->lastFrame()->T_f_w_.inverse().unit_quaternion()); - Vector3d p(vo_->lastFrame()->T_f_w_.inverse().translation()); - trace_est_pose_.precision(15); - trace_est_pose_.setf(std::ios::fixed, std::ios::floatfield ); - trace_est_pose_ << it->stamp_<< " "; - trace_est_pose_.precision(6); - trace_est_pose_ << p.x() << " " << p.y() << " " << p.z() << " " - << q.x() << " " << q.y() << " " << q.z() << " " << q.w() << endl; - } + tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->stamp_); if (!ros::ok()) break; } @@ -127,10 +129,9 @@ int main(int argc, char** argv) { ros::init(argc, argv, "svo"); ros::NodeHandle nh; - { - svo::BenchmarkNode benchmark(nh); - benchmark.runCamImuBenchmark(); - } + svo::BenchmarkNode benchmark(nh); + std::string benchmark_dir(vk::getParam("svo/dataset_directory")); + benchmark.runBenchmark(benchmark_dir); printf("BenchmarkNode finished.\n"); return 0; } From de6b9da46e56ca09c411413e98124257b745735f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 21 Mar 2014 19:24:51 +0100 Subject: [PATCH 019/215] make naming consistent with blender dataset type --- svo_ros/include/svo_ros/dataset_img.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/svo_ros/include/svo_ros/dataset_img.h b/svo_ros/include/svo_ros/dataset_img.h index 2d78ef7..4bdbc1f 100644 --- a/svo_ros/include/svo_ros/dataset_img.h +++ b/svo_ros/include/svo_ros/dataset_img.h @@ -33,8 +33,8 @@ public: DatasetImg() {} virtual ~DatasetImg() {} - double stamp_; - std::string imgname_; + double timestamp_; + std::string image_name_; friend std::ostream& operator <<(std::ostream& out, const DatasetImg& pair); friend std::istream& operator >>(std::istream& in, DatasetImg& pair); @@ -43,16 +43,16 @@ public: std::ostream& operator <<(std::ostream& out, const DatasetImg& gt) { out - << gt.stamp_ << " " - << gt.imgname_ << " " + << gt.timestamp_ << " " + << gt.image_name_ << " " << std::endl; return out; } std::istream& operator >>(std::istream& in, DatasetImg& gt) { - in >> gt.stamp_; - in >> gt.imgname_; + in >> gt.timestamp_; + in >> gt.image_name_; return in; } From ddc3d6b7e1ec8d513aca73dec0c858b13b7e466a Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 21 Mar 2014 20:22:22 +0100 Subject: [PATCH 020/215] removed default value for timestamp in frame constructor --- svo/include/svo/frame.h | 4 +--- svo/test/test_depth_filter.cpp | 4 ++-- svo/test/test_sparse_img_align.cpp | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/svo/include/svo/frame.h b/svo/include/svo/frame.h index 68aa548..f4413e7 100644 --- a/svo/include/svo/frame.h +++ b/svo/include/svo/frame.h @@ -17,7 +17,6 @@ #ifndef SVO_FRAME_H_ #define SVO_FRAME_H_ -#include #include #include #include @@ -32,7 +31,6 @@ typedef g2o::VertexSE3Expmap g2oFrameSE3; namespace svo { class Point; -class Frame; struct Feature; typedef list Features; @@ -57,7 +55,7 @@ public: g2oFrameSE3* v_kf_; //!< Temporary pointer to the g2o node object of the keyframe. int last_published_ts_; //!< Timestamp of last publishing. - Frame(vk::AbstractCamera* cam, const cv::Mat& img, double timestamp=0.0); + Frame(vk::AbstractCamera* cam, const cv::Mat& img, double timestamp); ~Frame(); /// Initialize new frame and create image pyramid. diff --git a/svo/test/test_depth_filter.cpp b/svo/test/test_depth_filter.cpp index 09d0034..545d9bc 100644 --- a/svo/test/test_depth_filter.cpp +++ b/svo/test/test_depth_filter.cpp @@ -118,7 +118,7 @@ void DepthFilterTest::testReconstruction( if(i == 0) { // create reference frame and load ground truth depthmap - frame_ref_.reset(new svo::Frame(cam_, img)); + frame_ref_.reset(new svo::Frame(cam_, img, 0.0)); frame_ref_->T_f_w_ = T_w_f.inverse(); depth_filter_->addKeyframe(frame_ref_, 3, 1); vk::blender_utils::loadBlenderDepthmap(dataset_dir+"/depth/" + (*it).image_name_ + "_0.depth", *cam_, depth_ref_); @@ -126,7 +126,7 @@ void DepthFilterTest::testReconstruction( } n_converged_seeds_=0; - frame_cur_ = svo::FramePtr(new svo::Frame(cam_, img)); + frame_cur_ = svo::FramePtr(new svo::Frame(cam_, img, 0.0)); frame_cur_->T_f_w_ = T_w_f.inverse(); depth_filter_->addFrame(frame_cur_); n_converged_per_iteration.push_back(n_converged_seeds_); diff --git a/svo/test/test_sparse_img_align.cpp b/svo/test/test_sparse_img_align.cpp index 1c4437c..51950a8 100644 --- a/svo/test/test_sparse_img_align.cpp +++ b/svo/test/test_sparse_img_align.cpp @@ -86,7 +86,7 @@ void SparseImgAlignTest::testSequence( if(i==0) { // set reference frame - frame_ref_.reset(new svo::Frame(cam_, img)); + frame_ref_.reset(new svo::Frame(cam_, img, 0.0)); frame_ref_->T_f_w_ = T_gt_w; // load ground-truth depth @@ -115,7 +115,7 @@ void SparseImgAlignTest::testSequence( continue; } - frame_cur_.reset(new svo::Frame(cam_, img)); + frame_cur_.reset(new svo::Frame(cam_, img, 0.0)); //frame_cur_->T_f_w_ = frame_ref_->T_f_w_; // start at reference frame frame_cur_->T_f_w_ = T_prev_w; // start at last frame From e9404c4ed8a26e03dfd7b65536d17332391d65a9 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 21 Mar 2014 20:22:56 +0100 Subject: [PATCH 021/215] added functionality to set first frame. used for benchmark node --- svo/include/svo/frame_handler_mono.h | 3 +++ svo/src/frame_handler_mono.cpp | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/svo/include/svo/frame_handler_mono.h b/svo/include/svo/frame_handler_mono.h index 3dc80ab..f15afaf 100644 --- a/svo/include/svo/frame_handler_mono.h +++ b/svo/include/svo/frame_handler_mono.h @@ -34,6 +34,9 @@ public: /// Provide an image. void addImage(const cv::Mat& img, double timestamp); + /// Set the first frame (used for synthetic datasets in benchmark node) + void setFirstFrame(const FramePtr& first_frame); + /// Get the last frame that has been processed. FramePtr lastFrame() { return last_frame_; } diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 95a9787..63672aa 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -74,6 +74,15 @@ addImage(const cv::Mat& img, double timestamp) finishFrameProcessingCommon(last_frame_->id_, res, last_frame_->nObs()); } +void FrameHandlerMono:: +setFirstFrame(const FramePtr& first_frame) +{ + resetAll(); + last_frame_ = first_frame; + map_.addKeyframe(last_frame_); + stage_ = DEFAULT_FRAME; +} + FrameHandlerMono::UpdateResult FrameHandlerMono:: processFirstFrame() { From b25f7c3f5b91ecae992a5f7ffcf66df4b2473a48 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 21 Mar 2014 20:23:18 +0100 Subject: [PATCH 022/215] new benchmark for synthetic datasets. sets the first frame and initializes features from the ground-truth depth-map. NOT TESTED --- svo_ros/src/benchmark_node.cpp | 117 ++++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 23 deletions(-) diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index 2998c23..af929df 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -25,10 +25,14 @@ #include #include #include +#include #include #include +#include #include +#include #include +#include #include #include @@ -46,7 +50,8 @@ public: BenchmarkNode(ros::NodeHandle& nh); ~BenchmarkNode(); void tracePose(const SE3& T_w_f, const double timestamp); - void runBenchmark(const std::string& benchmark_dir); + void runBenchmark(const std::string& dataset_dir); + void runBlenderBenchmark(const std::string& dataset_dir); }; BenchmarkNode::BenchmarkNode(ros::NodeHandle& nh) : @@ -57,6 +62,12 @@ BenchmarkNode::BenchmarkNode(ros::NodeHandle& nh) : if(!vk::camera_loader::loadFromRosNs("svo", cam_)) throw std::runtime_error("Camera model not correctly specified."); + // create pose tracefile + std::string trace_est_name(Config::traceDir() + "/traj_estimate.txt"); + trace_est_pose_.open(trace_est_name.c_str()); + if(trace_est_pose_.fail()) + throw std::runtime_error("Could not create tracefile. Does folder exist?"); + // Initialize VO vo_ = new svo::FrameHandlerMono(cam_); vo_->start(); @@ -80,46 +91,106 @@ void BenchmarkNode::tracePose(const SE3& T_w_f, const double timestamp) << q.x() << " " << q.y() << " " << q.z() << " " << q.w() << endl; } -void BenchmarkNode::runBenchmark(const std::string& benchmark_dir) +void BenchmarkNode::runBenchmark(const std::string& dataset_dir) { // create image reader and load dataset - std::string filename_benchmark(benchmark_dir + "/images.txt"); + std::string filename_benchmark(dataset_dir + "/images.txt"); vk::FileReader dataset_reader(filename_benchmark); dataset_reader.skipComments(); - if(!dataset_reader.next()) - std::runtime_error("Failed to open images file"); + if(!dataset_reader.next()) { + SVO_ERROR_STREAM("Failed opening dataset: "< dataset; dataset_reader.readAllEntries(dataset); - // create pose tracefile - std::string trace_est_name(Config::traceDir() + "/traj_estimate.txt"); - trace_est_pose_.open(trace_est_name.c_str()); - if(trace_est_pose_.fail()) - throw std::runtime_error("Could not create tracefile. Does folder exist?"); - // process dataset - for(vk::vector::iterator it = dataset.begin(); - it != dataset.end(); ++it, ++frame_count_) + for(auto it = dataset.begin(); it != dataset.end() && ros::ok(); ++it, ++frame_count_) { // Read image - std::string img_filename(benchmark_dir + "/" + it->imgname_); + std::string img_filename(dataset_dir + "/" + it->image_name_); cv::Mat img(cv::imread(img_filename, 0)); - if(frame_count_ == 0) - SVO_INFO_STREAM("Reading image "<addImage(img, it->stamp_); + vo_->addImage(img, it->timestamp_); // Visualize - visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->stamp_); + visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->timestamp_); // write pose to tracefile if(vo_->stage() == svo::FrameHandlerMono::DEFAULT_FRAME) - tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->stamp_); - if (!ros::ok()) - break; + tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); + } +} + +void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) +{ + // create image reader and load dataset + std::string filename_benchmark(dataset_dir + "/images.txt"); + vk::FileReader dataset_reader(filename_benchmark); + dataset_reader.skipComments(); + if(!dataset_reader.next()) { + SVO_ERROR_STREAM("Failed opening dataset: "< dataset; + dataset_reader.readAllEntries(dataset); + + // process dataset + for(auto it = dataset.begin(); it != dataset.end() && ros::ok(); ++it, ++frame_count_) + { + // Read image + std::string img_filename(dataset_dir + "/" + it->image_name_ + "_0.png"); + cv::Mat img(cv::imread(img_filename, 0)); + if(img.empty()) { + SVO_ERROR_STREAM("Reading image "<timestamp_)); + frame_ref->T_f_w_ = Sophus::SE3(it->q_, it->t_).inverse(); + + // load ground-truth depth + cv::Mat depthmap; + vk::blender_utils::loadBlenderDepthmap( + dataset_dir+"/depth/"+it->image_name_+"_0.depth", *cam_, depthmap); + + // extract features, generate features with 3D points + svo::feature_detection::FastDetector detector; + svo::feature_detection::Corners corners; + detector.detect(frame_ref->img_pyr_, frame_ref->fts_, svo::Config::gridSize(), + svo::Config::nPyrLevels(), svo::Config::triangMinCornerScore(), &corners); + for(auto corner=corners.begin(); corner!=corners.end(); ++corner) + { + if(corner->score < Config::triangMinCornerScore()) + continue; + svo::Feature* ftr = new svo::Feature(frame_ref.get(), Eigen::Vector2d(corner->x, corner->y), corner->level); + Eigen::Vector3d pt_pos_cur = ftr->f*depthmap.at(corner->y, corner->x); + Eigen::Vector3d pt_pos_world = frame_ref->T_f_w_.inverse()*pt_pos_cur; + svo::Point* point = new svo::Point(pt_pos_world, svo::Point::DEPTH); + ftr->point = point; + frame_ref->addFeature(ftr); + } + SVO_INFO_STREAM("Added "<setFirstFrame(frame_ref); + SVO_INFO_STREAM("Set reference frame."); + continue; + } + + // Add image to VO + vo_->addImage(img, it->timestamp_); + + // write pose to tracefile + if(vo_->stage() == svo::FrameHandlerMono::DEFAULT_FRAME) + tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); } } From bbf5b91bc190937f2f4fec849a07380c32e890e0 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sun, 23 Mar 2014 22:36:22 +0100 Subject: [PATCH 023/215] make rospy package --- svo_analysis/.gitignore | 1 + svo_analysis/CMakeLists.txt | 8 + svo_analysis/package.xml | 19 + svo_analysis/scripts/associate.py | 67 ---- svo_analysis/{ => scripts}/benchmark.py | 0 ...trajectory_comparison.py => comparison.py} | 0 svo_analysis/{ => scripts}/evaluate.py | 4 +- svo_analysis/setup.py | 12 + .../{scripts => src/svo_analysis}/__init__.py | 0 .../svo_analysis}/analyse_dataset.py | 0 .../svo_analysis}/analyse_logs.py | 0 .../svo_analysis}/analyse_timing.py | 0 .../svo_analysis}/analyse_trajectory.py | 0 .../filter_groundtruth_smooth.py | 0 .../svo_analysis}/hand_eye_calib.py | 0 .../svo_analysis}/rotation_utils.py | 0 .../svo_analysis}/transformations.py | 0 .../tum_benchmark_tools/__init__.py | 2 + .../tum_benchmark_tools/associate.py | 128 +++++++ .../tum_benchmark_tools/evaluate_ate.py | 195 ++++++++++ .../tum_benchmark_tools}/evaluate_rpe.py | 345 ++++++++++-------- 21 files changed, 553 insertions(+), 228 deletions(-) create mode 100644 svo_analysis/.gitignore create mode 100644 svo_analysis/CMakeLists.txt create mode 100644 svo_analysis/package.xml delete mode 100644 svo_analysis/scripts/associate.py rename svo_analysis/{ => scripts}/benchmark.py (100%) rename svo_analysis/scripts/{trajectory_comparison.py => comparison.py} (100%) rename svo_analysis/{ => scripts}/evaluate.py (91%) create mode 100644 svo_analysis/setup.py rename svo_analysis/{scripts => src/svo_analysis}/__init__.py (100%) rename svo_analysis/{scripts => src/svo_analysis}/analyse_dataset.py (100%) rename svo_analysis/{scripts => src/svo_analysis}/analyse_logs.py (100%) rename svo_analysis/{scripts => src/svo_analysis}/analyse_timing.py (100%) rename svo_analysis/{scripts => src/svo_analysis}/analyse_trajectory.py (100%) rename svo_analysis/{scripts => src/svo_analysis}/filter_groundtruth_smooth.py (100%) rename svo_analysis/{scripts => src/svo_analysis}/hand_eye_calib.py (100%) rename svo_analysis/{scripts => src/svo_analysis}/rotation_utils.py (100%) rename svo_analysis/{scripts => src/svo_analysis}/transformations.py (100%) create mode 100644 svo_analysis/src/svo_analysis/tum_benchmark_tools/__init__.py create mode 100755 svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py create mode 100755 svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py rename svo_analysis/{scripts => src/svo_analysis/tum_benchmark_tools}/evaluate_rpe.py (53%) diff --git a/svo_analysis/.gitignore b/svo_analysis/.gitignore new file mode 100644 index 0000000..7e99e36 --- /dev/null +++ b/svo_analysis/.gitignore @@ -0,0 +1 @@ +*.pyc \ No newline at end of file diff --git a/svo_analysis/CMakeLists.txt b/svo_analysis/CMakeLists.txt new file mode 100644 index 0000000..53ea7dc --- /dev/null +++ b/svo_analysis/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 2.8.3) +project(svo_analysis) + +find_package(catkin REQUIRED COMPONENTS rospy) +include_directories(${catkin_INCLUDE_DIRS}) + +catkin_python_setup() +#catkin_package(CATKIN_DEPENDS sensor_msgs) \ No newline at end of file diff --git a/svo_analysis/package.xml b/svo_analysis/package.xml new file mode 100644 index 0000000..dcc5a62 --- /dev/null +++ b/svo_analysis/package.xml @@ -0,0 +1,19 @@ + + + svo_analysis + 0.0.1 + + Python scripts to analyse performance of SVO. + + Christian Forster + Christian Forster + BSD + catkin + + rospy + + python-rospkg + python-yaml + rospy + + \ No newline at end of file diff --git a/svo_analysis/scripts/associate.py b/svo_analysis/scripts/associate.py deleted file mode 100644 index 8a7438c..0000000 --- a/svo_analysis/scripts/associate.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/python -# -# Requirements: -# sudo apt-get install python-argparse - -import argparse -import sys -import os -import numpy - - -def read_file_list(filename): - file = open(filename) - data = file.read() - lines = data.replace(","," ").replace("\t"," ").split("\n") - list = [[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"] - list = [(float(l[0]),l[1:]) for l in list if len(l)>1] - return dict(list) - -def associate(first_list, second_list,offset,max_difference): - # first_list = groundtruth - # second_list = estimate - first_keys = first_list.keys() - second_keys = second_list.keys() - potential_matches = [(abs(a - (b + offset)), a, b) - for a in first_keys - for b in second_keys - if abs(a - (b + offset)) < max_difference] - - potential_matches.sort() - matches = [] - for diff, a, b in potential_matches: - if a in first_keys and b in second_keys: - first_keys.remove(a) - second_keys.remove(b) - matches.append((a, b)) - - matches.sort() - - return matches - -if __name__ == '__main__': - - # parse command line - parser = argparse.ArgumentParser(description=''' - This script takes two data files with timestamps and associates them - ''') - parser.add_argument('first_file', help='first text file (format: timestamp data)') - parser.add_argument('second_file', help='second text file (format: timestamp data)') - parser.add_argument('--first_only', help='only output associated lines from first file', action='store_true') - parser.add_argument('--offset', help='time offset added to the timestamps of the second file (default: 0.0)',default=0.0) - parser.add_argument('--max_difference', help='maximally allowed time difference for matching entries (default: 0.02)',default=0.02) - args = parser.parse_args() - - first_list = read_file_list(args.first_file) - second_list = read_file_list(args.second_file) - - matches = associate(first_list, second_list,float(args.offset),float(args.max_difference)) - - if args.first_only: - for a,b in matches: - print("%f %s"%(a," ".join(first_list[a]))) - else: - for a,b in matches: - print("%f %s %f %s"%(a," ".join(first_list[a]),b-float(args.offset)," ".join(second_list[b]))) - - diff --git a/svo_analysis/benchmark.py b/svo_analysis/scripts/benchmark.py similarity index 100% rename from svo_analysis/benchmark.py rename to svo_analysis/scripts/benchmark.py diff --git a/svo_analysis/scripts/trajectory_comparison.py b/svo_analysis/scripts/comparison.py similarity index 100% rename from svo_analysis/scripts/trajectory_comparison.py rename to svo_analysis/scripts/comparison.py diff --git a/svo_analysis/evaluate.py b/svo_analysis/scripts/evaluate.py similarity index 91% rename from svo_analysis/evaluate.py rename to svo_analysis/scripts/evaluate.py index 05af1ee..4cff109 100755 --- a/svo_analysis/evaluate.py +++ b/svo_analysis/scripts/evaluate.py @@ -9,8 +9,8 @@ import argparse import csv import numpy as np from matplotlib import rc -import scripts.analyse_logs as analyse_logs -import scripts.analyse_timing as analyse_timing +import svo_analysis.analyse_logs as analyse_logs +import svo_analysis.analyse_timing as analyse_timing if __name__=="__main__": diff --git a/svo_analysis/setup.py b/svo_analysis/setup.py new file mode 100644 index 0000000..0d94673 --- /dev/null +++ b/svo_analysis/setup.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +from distutils.core import setup +from catkin_pkg.python_setup import generate_distutils_setup + +d = generate_distutils_setup( + packages=['svo_analysis'], + package_dir={'': 'src'}, + install_requires=['rospkg', 'yaml'], + ) + +setup(**d) \ No newline at end of file diff --git a/svo_analysis/scripts/__init__.py b/svo_analysis/src/svo_analysis/__init__.py similarity index 100% rename from svo_analysis/scripts/__init__.py rename to svo_analysis/src/svo_analysis/__init__.py diff --git a/svo_analysis/scripts/analyse_dataset.py b/svo_analysis/src/svo_analysis/analyse_dataset.py similarity index 100% rename from svo_analysis/scripts/analyse_dataset.py rename to svo_analysis/src/svo_analysis/analyse_dataset.py diff --git a/svo_analysis/scripts/analyse_logs.py b/svo_analysis/src/svo_analysis/analyse_logs.py similarity index 100% rename from svo_analysis/scripts/analyse_logs.py rename to svo_analysis/src/svo_analysis/analyse_logs.py diff --git a/svo_analysis/scripts/analyse_timing.py b/svo_analysis/src/svo_analysis/analyse_timing.py similarity index 100% rename from svo_analysis/scripts/analyse_timing.py rename to svo_analysis/src/svo_analysis/analyse_timing.py diff --git a/svo_analysis/scripts/analyse_trajectory.py b/svo_analysis/src/svo_analysis/analyse_trajectory.py similarity index 100% rename from svo_analysis/scripts/analyse_trajectory.py rename to svo_analysis/src/svo_analysis/analyse_trajectory.py diff --git a/svo_analysis/scripts/filter_groundtruth_smooth.py b/svo_analysis/src/svo_analysis/filter_groundtruth_smooth.py similarity index 100% rename from svo_analysis/scripts/filter_groundtruth_smooth.py rename to svo_analysis/src/svo_analysis/filter_groundtruth_smooth.py diff --git a/svo_analysis/scripts/hand_eye_calib.py b/svo_analysis/src/svo_analysis/hand_eye_calib.py similarity index 100% rename from svo_analysis/scripts/hand_eye_calib.py rename to svo_analysis/src/svo_analysis/hand_eye_calib.py diff --git a/svo_analysis/scripts/rotation_utils.py b/svo_analysis/src/svo_analysis/rotation_utils.py similarity index 100% rename from svo_analysis/scripts/rotation_utils.py rename to svo_analysis/src/svo_analysis/rotation_utils.py diff --git a/svo_analysis/scripts/transformations.py b/svo_analysis/src/svo_analysis/transformations.py similarity index 100% rename from svo_analysis/scripts/transformations.py rename to svo_analysis/src/svo_analysis/transformations.py diff --git a/svo_analysis/src/svo_analysis/tum_benchmark_tools/__init__.py b/svo_analysis/src/svo_analysis/tum_benchmark_tools/__init__.py new file mode 100644 index 0000000..633f866 --- /dev/null +++ b/svo_analysis/src/svo_analysis/tum_benchmark_tools/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- + diff --git a/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py b/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py new file mode 100755 index 0000000..554314a --- /dev/null +++ b/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py @@ -0,0 +1,128 @@ +#!/usr/bin/python +# Software License Agreement (BSD License) +# +# Copyright (c) 2013, Juergen Sturm, TUM +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of TUM nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Requirements: +# sudo apt-get install python-argparse + +""" +The Kinect provides the color and depth images in an un-synchronized way. This means that the set of time stamps from the color images do not intersect with those of the depth images. Therefore, we need some way of associating color images to depth images. + +For this purpose, you can use the ''associate.py'' script. It reads the time stamps from the rgb.txt file and the depth.txt file, and joins them by finding the best matches. +""" + +import argparse +import sys +import os +import numpy + + +def read_file_list(filename): + """ + Reads a trajectory from a text file. + + File format: + The file format is "stamp d1 d2 d3 ...", where stamp denotes the time stamp (to be matched) + and "d1 d2 d3.." is arbitary data (e.g., a 3D position and 3D orientation) associated to this timestamp. + + Input: + filename -- File name + + Output: + dict -- dictionary of (stamp,data) tuples + + """ + file = open(filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + list = [[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"] + list = [(float(l[0]),l[1:]) for l in list if len(l)>1] + return dict(list) + +def associate(first_list, second_list,offset,max_difference): + """ + Associate two dictionaries of (stamp,data). As the time stamps never match exactly, we aim + to find the closest match for every input tuple. + + Input: + first_list -- first dictionary of (stamp,data) tuples + second_list -- second dictionary of (stamp,data) tuples + offset -- time offset between both dictionaries (e.g., to model the delay between the sensors) + max_difference -- search radius for candidate generation + + Output: + matches -- list of matched tuples ((stamp1,data1),(stamp2,data2)) + + """ + first_keys = first_list.keys() + second_keys = second_list.keys() + potential_matches = [(abs(a - (b + offset)), a, b) + for a in first_keys + for b in second_keys + if abs(a - (b + offset)) < max_difference] + potential_matches.sort() + matches = [] + for diff, a, b in potential_matches: + if a in first_keys and b in second_keys: + first_keys.remove(a) + second_keys.remove(b) + matches.append((a, b)) + + matches.sort() + return matches + +if __name__ == '__main__': + + # parse command line + parser = argparse.ArgumentParser(description=''' + This script takes two data files with timestamps and associates them + ''') + parser.add_argument('first_file', help='first text file (format: timestamp data)') + parser.add_argument('second_file', help='second text file (format: timestamp data)') + parser.add_argument('--first_only', help='only output associated lines from first file', action='store_true') + parser.add_argument('--offset', help='time offset added to the timestamps of the second file (default: 0.0)',default=0.0) + parser.add_argument('--max_difference', help='maximally allowed time difference for matching entries (default: 0.02)',default=0.02) + args = parser.parse_args() + + first_list = read_file_list(args.first_file) + second_list = read_file_list(args.second_file) + + matches = associate(first_list, second_list,float(args.offset),float(args.max_difference)) + + if args.first_only: + for a,b in matches: + print("%f %s"%(a," ".join(first_list[a]))) + else: + for a,b in matches: + print("%f %s %f %s"%(a," ".join(first_list[a]),b-float(args.offset)," ".join(second_list[b]))) + + diff --git a/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py b/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py new file mode 100755 index 0000000..683b598 --- /dev/null +++ b/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py @@ -0,0 +1,195 @@ +#!/usr/bin/python +# Software License Agreement (BSD License) +# +# Copyright (c) 2013, Juergen Sturm, TUM +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of TUM nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Requirements: +# sudo apt-get install python-argparse + +""" +This script computes the absolute trajectory error from the ground truth +trajectory and the estimated trajectory. +""" + +import sys +import numpy +import argparse +import associate + +def align(model,data): + """Align two trajectories using the method of Horn (closed-form). + + Input: + model -- first trajectory (3xn) + data -- second trajectory (3xn) + + Output: + rot -- rotation matrix (3x3) + trans -- translation vector (3x1) + trans_error -- translational error per point (1xn) + + """ + numpy.set_printoptions(precision=3,suppress=True) + model_zerocentered = model - model.mean(1) + data_zerocentered = data - data.mean(1) + + W = numpy.zeros( (3,3) ) + for column in range(model.shape[1]): + W += numpy.outer(model_zerocentered[:,column],data_zerocentered[:,column]) + U,d,Vh = numpy.linalg.linalg.svd(W.transpose()) + S = numpy.matrix(numpy.identity( 3 )) + if(numpy.linalg.det(U) * numpy.linalg.det(Vh)<0): + S[2,2] = -1 + rot = U*S*Vh + trans = data.mean(1) - rot * model.mean(1) + + model_aligned = rot * model + trans + alignment_error = model_aligned - data + + trans_error = numpy.sqrt(numpy.sum(numpy.multiply(alignment_error,alignment_error),0)).A[0] + + return rot,trans,trans_error + +def plot_traj(ax,stamps,traj,style,color,label): + """ + Plot a trajectory using matplotlib. + + Input: + ax -- the plot + stamps -- time stamps (1xn) + traj -- trajectory (3xn) + style -- line style + color -- line color + label -- plot legend + + """ + stamps.sort() + interval = numpy.median([s-t for s,t in zip(stamps[1:],stamps[:-1])]) + x = [] + y = [] + last = stamps[0] + for i in range(len(stamps)): + if stamps[i]-last < 2*interval: + x.append(traj[i][0]) + y.append(traj[i][1]) + elif len(x)>0: + ax.plot(x,y,style,color=color,label=label) + label="" + x=[] + y=[] + last= stamps[i] + if len(x)>0: + ax.plot(x,y,style,color=color,label=label) + + +if __name__=="__main__": + # parse command line + parser = argparse.ArgumentParser(description=''' + This script computes the absolute trajectory error from the ground truth trajectory and the estimated trajectory. + ''') + parser.add_argument('first_file', help='ground truth trajectory (format: timestamp tx ty tz qx qy qz qw)') + parser.add_argument('second_file', help='estimated trajectory (format: timestamp tx ty tz qx qy qz qw)') + parser.add_argument('--offset', help='time offset added to the timestamps of the second file (default: 0.0)',default=0.0) + parser.add_argument('--scale', help='scaling factor for the second trajectory (default: 1.0)',default=1.0) + parser.add_argument('--max_difference', help='maximally allowed time difference for matching entries (default: 0.02)',default=0.02) + parser.add_argument('--save', help='save aligned second trajectory to disk (format: stamp2 x2 y2 z2)') + parser.add_argument('--save_associations', help='save associated first and aligned second trajectory to disk (format: stamp1 x1 y1 z1 stamp2 x2 y2 z2)') + parser.add_argument('--plot', help='plot the first and the aligned second trajectory to an image (format: png)') + parser.add_argument('--verbose', help='print all evaluation data (otherwise, only the RMSE absolute translational error in meters after alignment will be printed)', action='store_true') + args = parser.parse_args() + + first_list = associate.read_file_list(args.first_file) + second_list = associate.read_file_list(args.second_file) + + matches = associate.associate(first_list, second_list,float(args.offset),float(args.max_difference)) + if len(matches)<2: + sys.exit("Couldn't find matching timestamp pairs between groundtruth and estimated trajectory! Did you choose the correct sequence?") + + + first_xyz = numpy.matrix([[float(value) for value in first_list[a][0:3]] for a,b in matches]).transpose() + second_xyz = numpy.matrix([[float(value)*float(args.scale) for value in second_list[b][0:3]] for a,b in matches]).transpose() + rot,trans,trans_error = align(second_xyz,first_xyz) + + second_xyz_aligned = rot * second_xyz + trans + + first_stamps = first_list.keys() + first_stamps.sort() + first_xyz_full = numpy.matrix([[float(value) for value in first_list[b][0:3]] for b in first_stamps]).transpose() + + second_stamps = second_list.keys() + second_stamps.sort() + second_xyz_full = numpy.matrix([[float(value)*float(args.scale) for value in second_list[b][0:3]] for b in second_stamps]).transpose() + second_xyz_full_aligned = rot * second_xyz_full + trans + + if args.verbose: + print "compared_pose_pairs %d pairs"%(len(trans_error)) + + print "absolute_translational_error.rmse %f m"%numpy.sqrt(numpy.dot(trans_error,trans_error) / len(trans_error)) + print "absolute_translational_error.mean %f m"%numpy.mean(trans_error) + print "absolute_translational_error.median %f m"%numpy.median(trans_error) + print "absolute_translational_error.std %f m"%numpy.std(trans_error) + print "absolute_translational_error.min %f m"%numpy.min(trans_error) + print "absolute_translational_error.max %f m"%numpy.max(trans_error) + else: + print "%f"%numpy.sqrt(numpy.dot(trans_error,trans_error) / len(trans_error)) + + if args.save_associations: + file = open(args.save_associations,"w") + file.write("\n".join(["%f %f %f %f %f %f %f %f"%(a,x1,y1,z1,b,x2,y2,z2) for (a,b),(x1,y1,z1),(x2,y2,z2) in zip(matches,first_xyz.transpose().A,second_xyz_aligned.transpose().A)])) + file.close() + + if args.save: + file = open(args.save,"w") + file.write("\n".join(["%f "%stamp+" ".join(["%f"%d for d in line]) for stamp,line in zip(second_stamps,second_xyz_full_aligned.transpose().A)])) + file.close() + + if args.plot: + import matplotlib + matplotlib.use('Agg') + import matplotlib.pyplot as plt + import matplotlib.pylab as pylab + from matplotlib.patches import Ellipse + fig = plt.figure() + ax = fig.add_subplot(111) + plot_traj(ax,first_stamps,first_xyz_full.transpose().A,'-',"black","ground truth") + plot_traj(ax,second_stamps,second_xyz_full_aligned.transpose().A,'-',"blue","estimated") + + label="difference" + for (a,b),(x1,y1,z1),(x2,y2,z2) in zip(matches,first_xyz.transpose().A,second_xyz_aligned.transpose().A): + ax.plot([x1,x2],[y1,y2],'-',color="red",label=label) + label="" + + ax.legend() + + ax.set_xlabel('x [m]') + ax.set_ylabel('y [m]') + plt.savefig(args.plot,dpi=90) + diff --git a/svo_analysis/scripts/evaluate_rpe.py b/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_rpe.py similarity index 53% rename from svo_analysis/scripts/evaluate_rpe.py rename to svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_rpe.py index 1ba24a7..fb42e4a 100755 --- a/svo_analysis/scripts/evaluate_rpe.py +++ b/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_rpe.py @@ -1,25 +1,92 @@ #!/usr/bin/python +# Software License Agreement (BSD License) +# +# Copyright (c) 2013, Juergen Sturm, TUM +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of TUM nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +""" +This script computes the relative pose error from the ground truth trajectory +and the estimated trajectory. +""" -import yaml import argparse import random import numpy import sys -import transformations -import matplotlib -import matplotlib.pyplot as plt -import matplotlib.pylab as pylab -from matplotlib import rc + +_EPS = numpy.finfo(float).eps * 4.0 def transform44(l): + """ + Generate a 4x4 homogeneous transformation matrix from a 3D point and unit quaternion. + + Input: + l -- tuple consisting of (stamp,tx,ty,tz,qx,qy,qz,qw) where + (tx,ty,tz) is the 3D position and (qx,qy,qz,qw) is the unit quaternion. + + Output: + matrix -- 4x4 homogeneous transformation matrix + """ t = l[1:4] - q = l[4:8] - return numpy.dot(transformations.translation_matrix(t),transformations.quaternion_matrix(q)) + q = numpy.array(l[4:8], dtype=numpy.float64, copy=True) + nq = numpy.dot(q, q) + if nq < _EPS: + return numpy.array(( + ( 1.0, 0.0, 0.0, t[0]) + ( 0.0, 1.0, 0.0, t[1]) + ( 0.0, 0.0, 1.0, t[2]) + ( 0.0, 0.0, 0.0, 1.0) + ), dtype=numpy.float64) + q *= numpy.sqrt(2.0 / nq) + q = numpy.outer(q, q) + return numpy.array(( + (1.0-q[1, 1]-q[2, 2], q[0, 1]-q[2, 3], q[0, 2]+q[1, 3], t[0]), + ( q[0, 1]+q[2, 3], 1.0-q[0, 0]-q[2, 2], q[1, 2]-q[0, 3], t[1]), + ( q[0, 2]-q[1, 3], q[1, 2]+q[0, 3], 1.0-q[0, 0]-q[1, 1], t[2]), + ( 0.0, 0.0, 0.0, 1.0) + ), dtype=numpy.float64) def read_trajectory(filename, matrix=True): + """ + Read a trajectory from a text file. + + Input: + filename -- file to be read + matrix -- convert poses to 4x4 matrices + + Output: + dictionary of stamped 3D poses + """ file = open(filename) data = file.read() - lines = data.replace(","," ").replace("\t"," ").split("\n") + lines = data.replace(","," ").replace("\t"," ").split("\n") list = [[float(v.strip()) for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"] list_ok = [] for i,l in enumerate(list): @@ -27,7 +94,7 @@ def read_trajectory(filename, matrix=True): continue isnan = False for v in l: - if numpy.isnan(v): + if numpy.isnan(v): isnan = True break if isnan: @@ -41,6 +108,16 @@ def read_trajectory(filename, matrix=True): return traj def find_closest_index(L,t): + """ + Find the index of the closest value in a list. + + Input: + L -- the list + t -- value to be found + + Output: + index of the closest element + """ beginning = 0 difference = abs(L[0] - t) best = 0 @@ -59,9 +136,22 @@ def find_closest_index(L,t): return best def ominus(a,b): + """ + Compute the relative 3D transformation between a and b. + + Input: + a -- first pose (homogeneous 4x4 matrix) + b -- second pose (homogeneous 4x4 matrix) + + Output: + Relative 3D transformation from a to b. + """ return numpy.dot(numpy.linalg.inv(a),b) def scale(a,scalar): + """ + Scale the translational components of a 4x4 homogeneous matrix by a scale factor. + """ return numpy.array( [[a[0,0], a[0,1], a[0,2], a[0,3]*scalar], [a[1,0], a[1,1], a[1,2], a[1,3]*scalar], @@ -70,13 +160,22 @@ def scale(a,scalar): ) def compute_distance(transform): + """ + Compute the distance of the translational component of a 4x4 homogeneous matrix. + """ return numpy.linalg.norm(transform[0:3,3]) def compute_angle(transform): + """ + Compute the rotation angle from a 4x4 homogeneous matrix. + """ # an invitation to 3-d vision, p 27 return numpy.arccos( min(1,max(-1, (numpy.trace(transform[0:3,0:3]) - 1)/2) )) def distances_along_trajectory(traj): + """ + Compute the translational distances along a trajectory. + """ keys = traj.keys() keys.sort() motion = [ominus(traj[keys[i+1]],traj[keys[i]]) for i in range(len(keys)-1)] @@ -86,8 +185,11 @@ def distances_along_trajectory(traj): sum += compute_distance(t) distances.append(sum) return distances - + def rotations_along_trajectory(traj,scale): + """ + Compute the angular rotations along a trajectory. + """ keys = traj.keys() keys.sort() motion = [ominus(traj[keys[i+1]],traj[keys[i]]) for i in range(len(keys)-1)] @@ -97,60 +199,36 @@ def rotations_along_trajectory(traj,scale): sum += compute_angle(t)*scale distances.append(sum) return distances + -def interpolate_transformation(alpha,a,b): - qa,ta = transformations.quaternion_from_matrix(a),transformations.translation_from_matrix(a) - qb,tb = transformations.quaternion_from_matrix(b),transformations.translation_from_matrix(b) - qr = transformations.quaternion_slerp(qa,qb,alpha) - tr = (1-alpha) * ta + (alpha) * tb - r = numpy.dot(transformations.translation_matrix(tr),transformations.quaternion_matrix(qr)) - return r - -def interpolate_and_resample(traj_gt,stamps_est,param_offset,gt_max_time_difference): - traj_new = {} - +def evaluate_trajectory(traj_gt,traj_est,param_max_pairs=10000,param_fixed_delta=False,param_delta=1.00,param_delta_unit="s",param_offset=0.00,param_scale=1.00): + """ + Compute the relative pose error between two trajectories. + + Input: + traj_gt -- the first trajectory (ground truth) + traj_est -- the second trajectory (estimated trajectory) + param_max_pairs -- number of relative poses to be evaluated + param_fixed_delta -- false: evaluate over all possible pairs + true: only evaluate over pairs with a given distance (delta) + param_delta -- distance between the evaluated pairs + param_delta_unit -- unit for comparison: + "s": seconds + "m": meters + "rad": radians + "deg": degrees + "f": frames + param_offset -- time offset between two trajectories (to model the delay) + param_scale -- scale to be applied to the second trajectory + + Output: + list of compared poses and the resulting translation and rotation error + """ stamps_gt = list(traj_gt.keys()) - stamps_gt.sort() - - for t_est in stamps_est: - t_new = t_est + param_offset - i_nearest = find_closest_index(stamps_gt,t_est + param_offset) - if stamps_gt[i_nearest] >= t_new and i_nearest>0: - i_low = i_nearest-1 - i_high = i_nearest - else: - i_low = i_nearest - i_high = i_nearest+1 - if i_low<0 or i_high>=len(stamps_gt): - continue - - t_low = stamps_gt[i_low] - t_high = stamps_gt[i_high] - - if(abs( t_new - (t_low + param_offset) ) > gt_max_time_difference or - abs( t_new - (t_high + param_offset) ) > gt_max_time_difference): - continue - - alpha = (t_new - (t_low + param_offset)) / (t_high - t_low) - transform = interpolate_transformation(alpha,traj_gt[t_low],traj_gt[t_high]) - traj_new[t_new] = transform - return traj_new - - -def evaluate_trajectory(traj_gt,traj_est,param_max_pairs=10000,param_fixed_delta=False,param_delta=1.00,param_delta_unit="s",param_offset=0.00,param_scale=1.00,param_interpolation=True): stamps_est = list(traj_est.keys()) - stamps_est.sort() - stamps_gt = list(traj_gt.keys()) stamps_gt.sort() - - gt_interval = numpy.median([s-t for s,t in zip(stamps_gt[1:],stamps_gt[:-1])]) - gt_max_time_difference = 2*gt_interval - - if param_interpolation: - traj_gt = interpolate_and_resample(traj_gt,stamps_est,param_offset,gt_max_time_difference) - stamps_gt = list(traj_gt.keys()) - stamps_gt.sort() - + stamps_est.sort() + stamps_est_return = [] for t_est in stamps_est: t_gt = stamps_gt[find_closest_index(stamps_gt,t_est + param_offset)] @@ -184,11 +262,14 @@ def evaluate_trajectory(traj_gt,traj_est,param_max_pairs=10000,param_fixed_delta pairs = [] for i in range(len(traj_est)): j = find_closest_index(index_est,index_est[i] + param_delta) - if j!=len(traj_est)-1: + if j!=len(traj_est)-1: pairs.append((i,j)) if(param_max_pairs!=0 and len(pairs)>param_max_pairs): pairs = random.sample(pairs,param_max_pairs) - + + gt_interval = numpy.median([s-t for s,t in zip(stamps_gt[1:],stamps_gt[:-1])]) + gt_max_time_difference = 2*gt_interval + result = [] for i,j in pairs: stamp_est_0 = stamps_est[i] @@ -196,32 +277,29 @@ def evaluate_trajectory(traj_gt,traj_est,param_max_pairs=10000,param_fixed_delta stamp_gt_0 = stamps_gt[ find_closest_index(stamps_gt,stamp_est_0 + param_offset) ] stamp_gt_1 = stamps_gt[ find_closest_index(stamps_gt,stamp_est_1 + param_offset) ] - + if(abs(stamp_gt_0 - (stamp_est_0 + param_offset)) > gt_max_time_difference or abs(stamp_gt_1 - (stamp_est_1 + param_offset)) > gt_max_time_difference): continue - + error44 = ominus( scale( ominus( traj_est[stamp_est_1], traj_est[stamp_est_0] ),param_scale), ominus( traj_gt[stamp_gt_1], traj_gt[stamp_gt_0] ) ) - trans = compute_distance(error44) rot = compute_angle(error44) - - motion_gt = ominus( traj_gt[stamp_gt_1], traj_gt[stamp_gt_0] ) - trans_gt = compute_distance(motion_gt) - rot_gt = compute_angle(motion_gt) - if(rot < 0.07): - result.append([stamp_est_0,stamp_est_1,stamp_gt_0,stamp_gt_1,trans,rot,trans_gt,rot_gt]) - + result.append([stamp_est_0,stamp_est_1,stamp_gt_0,stamp_gt_1,trans,rot]) + if len(result)<2: raise Exception("Couldn't find matching timestamp pairs between groundtruth and estimated trajectory!") - + return result def percentile(seq,q): + """ + Return the q-percentile of a list + """ seq_sorted = list(seq) seq_sorted.sort() return seq_sorted[int((len(seq_sorted)-1)*q)] @@ -229,45 +307,28 @@ def percentile(seq,q): if __name__ == '__main__': random.seed(0) - # config ------------------------------------------------------------------------- - - dataset='20131003_1937_nslam_i7_asl2_fast' - dataset_dir = '../results/'+dataset - - #--------------------------------------------------------------------------------- - - # load dataset parameters - params_stream = open(dataset_dir+'/params.yaml') - params = yaml.load(params_stream) - - # set trajectory groundtruth and estimate file - traj_groundtruth = params['dataset_directory']+'/groundtruth_filtered.txt' - traj_estimate_rotated = dataset_dir+'/traj_estimate_rotated.txt' - parser = argparse.ArgumentParser(description=''' - This script computes the relative pose error from the ground truth trajectory and the estimated trajectory. + This script computes the relative pose error from the ground truth trajectory and the estimated trajectory. ''') - parser.add_argument('--groundtruth_file', help='ground-truth trajectory file (format: "timestamp tx ty tz qx qy qz qw")', default=traj_groundtruth) - parser.add_argument('--estimated_file', help='estimated trajectory file (format: "timestamp tx ty tz qx qy qz qw")', default=traj_estimate_rotated) - parser.add_argument('--interpolate', help='interpolate and resample the ground truth trajectory', default=True) + parser.add_argument('groundtruth_file', help='ground-truth trajectory file (format: "timestamp tx ty tz qx qy qz qw")') + parser.add_argument('estimated_file', help='estimated trajectory file (format: "timestamp tx ty tz qx qy qz qw")') parser.add_argument('--max_pairs', help='maximum number of pose comparisons (default: 10000, set to zero to disable downsampling)', default=10000) - parser.add_argument('--fixed_delta', help='only consider pose pairs that have a distance of delta delta_unit (e.g., for evaluating the drift per second/meter/radian)', default=True) + parser.add_argument('--fixed_delta', help='only consider pose pairs that have a distance of delta delta_unit (e.g., for evaluating the drift per second/meter/radian)', action='store_true') parser.add_argument('--delta', help='delta for evaluation (default: 1.0)',default=1.0) parser.add_argument('--delta_unit', help='unit of delta (options: \'s\' for seconds, \'m\' for meters, \'rad\' for radians, \'f\' for frames; default: \'s\')',default='s') parser.add_argument('--offset', help='time offset between ground-truth and estimated trajectory (default: 0.0)',default=0.0) parser.add_argument('--scale', help='scaling factor for the estimated trajectory (default: 1.0)',default=1.0) parser.add_argument('--save', help='text file to which the evaluation will be saved (format: stamp_est0 stamp_est1 stamp_gt0 stamp_gt1 trans_error rot_error)') - parser.add_argument('--plot', help='plot the result to a file (requires --fixed_delta, output format: png)', default=True) - parser.add_argument('--plotname', help='plot the result to a file (requires --fixed_delta, output format: png)', default='rpe.png') - parser.add_argument('--verbose', help='print all evaluation data (otherwise, only the mean translational error measured in meters will be printed)', default=True) + parser.add_argument('--plot', help='plot the result to a file (requires --fixed_delta, output format: png)') + parser.add_argument('--verbose', help='print all evaluation data (otherwise, only the mean translational error measured in meters will be printed)', action='store_true') args = parser.parse_args() - + if args.plot and not args.fixed_delta: sys.exit("The '--plot' option can only be used in combination with '--fixed_delta'") - + traj_gt = read_trajectory(args.groundtruth_file) traj_est = read_trajectory(args.estimated_file) - + result = evaluate_trajectory(traj_gt, traj_est, int(args.max_pairs), @@ -275,81 +336,47 @@ if __name__ == '__main__': float(args.delta), args.delta_unit, float(args.offset), - float(args.scale), - args.interpolate) - + float(args.scale)) + stamps = numpy.array(result)[:,0] trans_error = numpy.array(result)[:,4] rot_error = numpy.array(result)[:,5] - - results = dict() - results['trans_rmse'] = float(numpy.sqrt(numpy.dot(trans_error,trans_error) / len(trans_error))) - results['trans_mean'] = float(numpy.mean(trans_error)) - results['trans_median'] = float(numpy.median(trans_error)) - results['trans_std'] = float(numpy.std(trans_error)) - results['trans_min'] = float(numpy.min(trans_error)) - results['trans_max'] = float(numpy.max(trans_error)) - results['rot_rmse'] = float((numpy.sqrt(numpy.dot(rot_error,rot_error) / len(rot_error)) * 180.0 / numpy.pi)) - results['rot_mean'] = float((numpy.mean(rot_error) * 180.0 / numpy.pi)) - results['rot_median'] = float(numpy.median(rot_error) * 180.0 / numpy.pi) - results['rot_std'] = float((numpy.std(rot_error) * 180.0 / numpy.pi)) - results['rot_min'] = float((numpy.min(rot_error) * 180.0 / numpy.pi)) - results['rot_max'] = float((numpy.max(rot_error) * 180.0 / numpy.pi)) - - # dump experiment results to file: - results_file = params['trace_dir']+'/rpe_results.yaml' - with open(results_file,'w') as outfile: - outfile.write( yaml.dump(results, default_flow_style=False) ) - - if args.save: + if args.save: f = open(args.save,"w") f.write("\n".join([" ".join(["%f"%v for v in line]) for line in result])) f.close() - + if args.verbose: print "compared_pose_pairs %d pairs"%(len(trans_error)) - print "translational_error.rmse %f m"%results['trans_rmse'] - print "translational_error.mean %f m"%results['trans_mean'] - print "translational_error.median %f m"%results['trans_median'] - print "translational_error.std %f m"%results['trans_std'] - print "translational_error.min %f m"%results['trans_min'] - print "translational_error.max %f m"%results['trans_max'] + print "translational_error.rmse %f m"%numpy.sqrt(numpy.dot(trans_error,trans_error) / len(trans_error)) + print "translational_error.mean %f m"%numpy.mean(trans_error) + print "translational_error.median %f m"%numpy.median(trans_error) + print "translational_error.std %f m"%numpy.std(trans_error) + print "translational_error.min %f m"%numpy.min(trans_error) + print "translational_error.max %f m"%numpy.max(trans_error) - print "rotational_error.rmse %f deg"%results['rot_rmse'] - print "rotational_error.mean %f deg"%results['rot_mean'] - print "rotational_error.median %f deg"%results['rot_median'] - print "rotational_error.std %f deg"%results['rot_std'] - print "rotational_error.min %f deg"%results['rot_min'] - print "rotational_error.max %f deg"%results['rot_max'] + print "rotational_error.rmse %f deg"%(numpy.sqrt(numpy.dot(rot_error,rot_error) / len(rot_error)) * 180.0 / numpy.pi) + print "rotational_error.mean %f deg"%(numpy.mean(rot_error) * 180.0 / numpy.pi) + print "rotational_error.median %f deg"%numpy.median(rot_error) + print "rotational_error.std %f deg"%(numpy.std(rot_error) * 180.0 / numpy.pi) + print "rotational_error.min %f deg"%(numpy.min(rot_error) * 180.0 / numpy.pi) + print "rotational_error.max %f deg"%(numpy.max(rot_error) * 180.0 / numpy.pi) else: print numpy.mean(trans_error) - if args.plot: - - # tell matplotlib to use latex font - rc('font',**{'family':'serif','serif':['Cardo']}) - rc('text', usetex=True) - - #matplotlib.use('Agg') # no window should appear? - - fig = plt.figure(figsize=(8, 3)) - ax = fig.add_subplot(111) + if args.plot: + import matplotlib + matplotlib.use('Agg') + import matplotlib.pyplot as plt + import matplotlib.pylab as pylab + fig = plt.figure() + ax = fig.add_subplot(111) ax.plot(stamps - stamps[0],trans_error,'-',color="blue") #ax.plot([t for t,e in err_rot],[e for t,e in err_rot],'-',color="red") ax.set_xlabel('time [s]') ax.set_ylabel('translational error [m]') - plt.tight_layout() - plt.savefig(dataset_dir+'/rpe_trans_error.pdf') - plt.show() + plt.savefig(args.plot,dpi=300) + - fig = plt.figure(figsize=(8, 3)) - ax = fig.add_subplot(111) - ax.plot(stamps - stamps[0],rot_error* 180.0 / numpy.pi,'-',color="blue") - #ax.plot([t for t,e in err_rot],[e for t,e in err_rot],'-',color="red") - ax.set_xlabel('time [s]') - ax.set_ylabel('rot error [deg]') - plt.tight_layout() - plt.savefig(dataset_dir+'/rpe_rot_error.pdf') - plt.show() \ No newline at end of file From ced00885c55dff9d8ec21119856a686df0488cf2 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 24 Mar 2014 10:09:58 +0100 Subject: [PATCH 024/215] refactor --- svo/CMakeLists.txt | 2 +- svo/test/benchmark.csv | 612 +++++++++--------- .../experiments/flying_room_1_fast.yaml | 2 + svo_analysis/scripts/benchmark.py | 72 ++- svo_analysis/src/svo_analysis/cpu_info.py | 10 + 5 files changed, 361 insertions(+), 337 deletions(-) create mode 100644 svo_analysis/experiments/flying_room_1_fast.yaml create mode 100644 svo_analysis/src/svo_analysis/cpu_info.py diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 16b1cba..7612a94 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -2,7 +2,7 @@ # user build settings SET(DEBUG FALSE) -SET(TRACE FALSE) +SET(TRACE TRUE) SET(HAVE_G2O FALSE) ################################################################################ diff --git a/svo/test/benchmark.csv b/svo/test/benchmark.csv index e6f88a3..a3831e4 100644 --- a/svo/test/benchmark.csv +++ b/svo/test/benchmark.csv @@ -1,307 +1,307 @@ local_ba,point_optimizer,pose_optimizer,pyramid_creation,reproject,sparse_img_align,tot_time,dropout,img_align_n_tracked,loba_err_fin,loba_err_init,loba_n_erredges_fin,loba_n_erredges_init,n_candidates,repr_n_mps,repr_n_new_references,sfba_error_final,sfba_error_init,sfba_n_edges_final,sfba_thresh -0.000000000000000,0.000000000000000,0.000000000000000,0.000203000000000,0.000000000000000,0.000000000000000,0.006850000000000,1.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000109000000000,0.000000000000000,0.000000000000000,0.015619000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000085000000000,0.000000000000000,0.000000000000000,0.015440000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000096000000000,0.000000000000000,0.000000000000000,0.016054000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000104000000000,0.000000000000000,0.000000000000000,0.022404000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000086000000000,0.000000000000000,0.000000000000000,0.027997000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000120000000000,0.000000000000000,0.000000000000000,0.031598000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000085000000000,0.000000000000000,0.000000000000000,0.030167000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000115000000000,0.000000000000000,0.000000000000000,0.029319000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000085000000000,0.000000000000000,0.000000000000000,0.030061000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000118000000000,0.000000000000000,0.000000000000000,0.034386000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000000000000000,0.000000000000000,0.000086000000000,0.000000000000000,0.000000000000000,0.089886000000000,1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 -0.000000000000000,0.000031000000000,0.000123000000000,0.000083000000000,0.000787000000000,0.001478000000000,0.002580000000000,0.000000000000000,279.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,148.000000000000000,121.000000000000000,0.170175036288459,0.209622100274688,121.000000000000000,0.310240723182540 -0.000000000000000,0.000021000000000,0.000169000000000,0.000094000000000,0.000742000000000,0.000759000000000,0.001820000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,151.000000000000000,121.000000000000000,0.200086249073657,0.226929968841294,119.000000000000000,0.335856340084193 -0.000000000000000,0.000025000000000,0.000161000000000,0.000087000000000,0.000786000000000,0.000849000000000,0.001929000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,150.000000000000000,121.000000000000000,0.220021652685224,0.250579787227198,120.000000000000000,0.370858080741496 -0.000000000000000,0.000022000000000,0.000154000000000,0.000080000000000,0.000833000000000,0.000799000000000,0.001908000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,153.000000000000000,121.000000000000000,0.241933925519325,0.315090765827434,119.000000000000000,0.466334367626374 -0.000000000000000,0.000022000000000,0.000147000000000,0.000078000000000,0.000733000000000,0.000857000000000,0.001878000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,145.000000000000000,121.000000000000000,0.272951477661557,0.278442109473506,118.000000000000000,0.412094340922640 -0.000000000000000,0.000028000000000,0.000163000000000,0.000105000000000,0.000998000000000,0.000769000000000,0.002090000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,176.000000000000000,121.000000000000000,0.295685270342958,0.345204254144622,120.000000000000000,0.510902319377397 -0.000000000000000,0.000026000000000,0.000096000000000,0.000108000000000,0.000884000000000,0.000849000000000,0.001987000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,154.000000000000000,121.000000000000000,0.280726298758396,0.351937246615374,119.000000000000000,0.520867118388044 -0.000000000000000,0.000027000000000,0.000145000000000,0.000077000000000,0.000795000000000,0.000757000000000,0.001822000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,160.000000000000000,121.000000000000000,0.299712701755874,0.325868377142253,119.000000000000000,0.482285213145440 -0.000000000000000,0.000017000000000,0.000088000000000,0.000082000000000,0.000819000000000,0.000723000000000,0.001753000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,157.000000000000000,121.000000000000000,0.266414412346027,0.325724036228748,121.000000000000000,0.482071564765419 -0.000000000000000,0.000018000000000,0.000117000000000,0.000090000000000,0.000805000000000,0.000748000000000,0.001799000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,53.000000000000000,146.000000000000000,121.000000000000000,0.268513468986649,0.275002624188711,120.000000000000000,0.407003878905728 -0.000000000000000,0.000017000000000,0.000084000000000,0.000077000000000,0.000701000000000,0.000777000000000,0.001677000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,76.000000000000000,141.000000000000000,121.000000000000000,0.291779187140528,0.283057832886000,119.000000000000000,0.418925579815900 -0.000000000000000,0.000019000000000,0.000215000000000,0.000093000000000,0.000797000000000,0.000821000000000,0.001970000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,96.000000000000000,146.000000000000000,121.000000000000000,0.284752636918227,0.313033086538782,118.000000000000000,0.463288955787851 -0.000000000000000,0.000018000000000,0.000115000000000,0.000087000000000,0.000928000000000,0.000752000000000,0.001937000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,108.000000000000000,164.000000000000000,121.000000000000000,0.266984542077384,0.310809089011309,117.000000000000000,0.459997446489587 -0.000000000000000,0.000018000000000,0.000145000000000,0.000076000000000,0.000879000000000,0.000667000000000,0.001797000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,82.000000000000000,172.000000000000000,121.000000000000000,0.281472783188953,0.318106490866299,118.000000000000000,0.470797632399925 -0.000000000000000,0.000025000000000,0.000097000000000,0.000092000000000,0.001059000000000,0.001001000000000,0.002299000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,82.000000000000000,169.000000000000000,121.000000000000000,0.259578545621370,0.296051217193402,118.000000000000000,0.438155829408007 -0.000000000000000,0.000023000000000,0.000152000000000,0.000090000000000,0.000987000000000,0.000683000000000,0.001956000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,88.000000000000000,169.000000000000000,121.000000000000000,0.260854021729684,0.463271425215932,119.000000000000000,0.685641725628487 -0.000000000000000,0.000012000000000,0.000147000000000,0.000078000000000,0.000828000000000,0.000628000000000,0.001713000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,100.000000000000000,162.000000000000000,121.000000000000000,0.224857463762793,0.241819177256775,120.000000000000000,0.357892398925400 -0.000000000000000,0.000015000000000,0.000176000000000,0.000082000000000,0.000976000000000,0.000761000000000,0.002033000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,175.000000000000000,163.000000000000000,121.000000000000000,0.232802573731276,0.307670936583970,121.000000000000000,0.455352982415734 -0.000000000000000,0.000015000000000,0.000150000000000,0.000089000000000,0.000914000000000,0.000700000000000,0.001890000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,215.000000000000000,163.000000000000000,121.000000000000000,0.223503209746196,0.245376568533207,121.000000000000000,0.363157337925476 -0.000000000000000,0.000014000000000,0.000085000000000,0.000085000000000,0.000830000000000,0.000688000000000,0.001724000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,236.000000000000000,160.000000000000000,121.000000000000000,0.238679764456232,0.260245227551971,121.000000000000000,0.385162944164610 -0.000000000000000,0.000017000000000,0.000094000000000,0.000082000000000,0.001027000000000,0.000661000000000,0.001919000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,253.000000000000000,156.000000000000000,121.000000000000000,0.240028080500584,0.347317487309391,119.000000000000000,0.514029864789977 -0.000000000000000,0.000017000000000,0.000107000000000,0.000086000000000,0.001095000000000,0.000731000000000,0.002049000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,225.000000000000000,203.000000000000000,121.000000000000000,0.237050681546672,0.342187692298344,118.000000000000000,0.506437791010399 -0.000000000000000,0.000027000000000,0.000087000000000,0.000082000000000,0.001031000000000,0.000707000000000,0.001956000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,224.000000000000000,192.000000000000000,121.000000000000000,0.228256268353354,0.255917210772511,118.000000000000000,0.378757460447388 -0.000000000000000,0.000028000000000,0.000163000000000,0.000113000000000,0.001066000000000,0.000688000000000,0.002083000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,237.000000000000000,174.000000000000000,121.000000000000000,0.253024524781435,0.270830951731115,117.000000000000000,0.400829834964262 -0.000000000000000,0.000024000000000,0.000148000000000,0.000082000000000,0.000924000000000,0.000665000000000,0.001864000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,243.000000000000000,168.000000000000000,121.000000000000000,0.255837794475283,0.309767339197390,117.000000000000000,0.458455660309276 -0.000000000000000,0.000024000000000,0.000086000000000,0.000079000000000,0.000949000000000,0.000709000000000,0.001867000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,247.000000000000000,176.000000000000000,121.000000000000000,0.242039138156127,0.295753126320285,120.000000000000000,0.437714633120047 -0.000000000000000,0.000017000000000,0.000162000000000,0.000105000000000,0.001033000000000,0.000869000000000,0.002208000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,284.000000000000000,173.000000000000000,121.000000000000000,0.234035640036960,0.262962619721412,120.000000000000000,0.389184684115904 -0.000000000000000,0.000017000000000,0.000148000000000,0.000084000000000,0.000934000000000,0.000632000000000,0.001837000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,323.000000000000000,168.000000000000000,121.000000000000000,0.243963350316049,0.254676670136256,118.000000000000000,0.376921484440742 -0.000000000000000,0.000020000000000,0.000115000000000,0.000080000000000,0.000954000000000,0.000883000000000,0.002074000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,346.000000000000000,164.000000000000000,121.000000000000000,0.237498578056768,0.242318556788754,120.000000000000000,0.358631474732560 -0.000000000000000,0.000026000000000,0.000160000000000,0.000084000000000,0.001068000000000,0.000705000000000,0.002067000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,360.000000000000000,174.000000000000000,121.000000000000000,0.231204379503806,0.310626553544348,119.000000000000000,0.459727290210615 -0.000000000000000,0.000025000000000,0.000107000000000,0.000082000000000,0.000854000000000,0.000734000000000,0.001826000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,371.000000000000000,154.000000000000000,121.000000000000000,0.226372225769396,0.240389889691023,118.000000000000000,0.355777042407619 -0.000000000000000,0.000018000000000,0.000109000000000,0.000077000000000,0.000903000000000,0.000645000000000,0.001789000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,383.000000000000000,163.000000000000000,121.000000000000000,0.243430388985134,0.289702067134667,116.000000000000000,0.428759091467402 -0.000000000000000,0.000023000000000,0.000162000000000,0.000088000000000,0.001172000000000,0.000728000000000,0.002190000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,351.000000000000000,189.000000000000000,121.000000000000000,0.238491169554930,0.289513420723387,119.000000000000000,0.428479887859349 -0.000000000000000,0.000021000000000,0.000095000000000,0.000089000000000,0.001107000000000,0.000638000000000,0.001974000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,351.000000000000000,187.000000000000000,121.000000000000000,0.253535525839367,0.299150984189304,119.000000000000000,0.442743431776745 -0.000000000000000,0.000012000000000,0.000107000000000,0.000073000000000,0.001079000000000,0.000677000000000,0.001968000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,360.000000000000000,182.000000000000000,121.000000000000000,0.242747319355396,0.331002407056278,119.000000000000000,0.489883554348514 -0.000000000000000,0.000022000000000,0.000152000000000,0.000092000000000,0.001093000000000,0.000806000000000,0.002196000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,420.000000000000000,166.000000000000000,121.000000000000000,0.214060131146887,0.291831223233246,120.000000000000000,0.431910240805571 -0.000000000000000,0.000013000000000,0.000086000000000,0.000086000000000,0.001065000000000,0.000781000000000,0.002051000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,467.000000000000000,189.000000000000000,121.000000000000000,0.191542689678233,0.219467905989458,120.000000000000000,0.324812508085401 -0.000000000000000,0.000017000000000,0.000087000000000,0.000076000000000,0.001000000000000,0.000696000000000,0.001897000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,491.000000000000000,176.000000000000000,121.000000000000000,0.237287862315746,0.290385534097234,119.000000000000000,0.429770572749869 -0.000000000000000,0.000015000000000,0.000098000000000,0.000115000000000,0.001209000000000,0.000852000000000,0.002312000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,503.000000000000000,195.000000000000000,121.000000000000000,0.255419259577233,0.271365864372703,119.000000000000000,0.401621476258818 -0.000000000000000,0.000014000000000,0.000106000000000,0.000102000000000,0.001070000000000,0.000640000000000,0.001952000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,519.000000000000000,192.000000000000000,121.000000000000000,0.243354924512186,0.322133979720464,118.000000000000000,0.476758255408191 -0.000000000000000,0.000015000000000,0.000087000000000,0.000074000000000,0.001024000000000,0.000658000000000,0.001878000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,537.000000000000000,182.000000000000000,121.000000000000000,0.256839605640840,0.290001626967172,120.000000000000000,0.429202410592353 -0.000000000000000,0.000019000000000,0.000171000000000,0.000101000000000,0.001223000000000,0.000747000000000,0.002282000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,551.000000000000000,186.000000000000000,121.000000000000000,0.234920975451741,0.278307444024956,121.000000000000000,0.411895021692308 -0.000000000000000,0.000020000000000,0.000085000000000,0.000077000000000,0.001001000000000,0.000765000000000,0.001993000000000,1.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,566.000000000000000,182.000000000000000,121.000000000000000,0.236213272390075,0.243545153610833,120.000000000000000,0.360446828894150 -0.000000000000000,0.000019000000000,0.000102000000000,0.000073000000000,0.001140000000000,0.000640000000000,0.001988000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,523.000000000000000,194.000000000000000,121.000000000000000,0.256770484355549,0.281629623166612,120.000000000000000,0.416811865969600 -0.000000000000000,0.000018000000000,0.000099000000000,0.000139000000000,0.001286000000000,0.000761000000000,0.002328000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,523.000000000000000,193.000000000000000,121.000000000000000,0.238587016371888,0.245006436065432,120.000000000000000,0.362609544894325 -0.000000000000000,0.000020000000000,0.000152000000000,0.000079000000000,0.001167000000000,0.000673000000000,0.002111000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,525.000000000000000,207.000000000000000,121.000000000000000,0.272520106859475,0.292688892408874,120.000000000000000,0.433179596238706 -0.000000000000000,0.000022000000000,0.000132000000000,0.000074000000000,0.001159000000000,0.000620000000000,0.002036000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,532.000000000000000,193.000000000000000,121.000000000000000,0.300157301652565,0.352279034698071,121.000000000000000,0.521372960116753 -0.000000000000000,0.000025000000000,0.000088000000000,0.000085000000000,0.001215000000000,0.000771000000000,0.002209000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,541.000000000000000,192.000000000000000,121.000000000000000,0.262925275260352,0.296134704229152,121.000000000000000,0.438279358303388 -0.000000000000000,0.000018000000000,0.000115000000000,0.000090000000000,0.001041000000000,0.000632000000000,0.001918000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,565.000000000000000,171.000000000000000,121.000000000000000,0.281978346961253,0.308467305071063,121.000000000000000,0.456531611839373 -0.000000000000000,0.000024000000000,0.000152000000000,0.000078000000000,0.001256000000000,0.000758000000000,0.002299000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,608.000000000000000,201.000000000000000,121.000000000000000,0.262127606608173,0.344179498178872,120.000000000000000,0.509385653434813 -0.000000000000000,0.000015000000000,0.000150000000000,0.000084000000000,0.001197000000000,0.000656000000000,0.002124000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,636.000000000000000,196.000000000000000,121.000000000000000,0.243118892914018,0.307363483400101,120.000000000000000,0.454897987687333 -0.000000000000000,0.000021000000000,0.000153000000000,0.000080000000000,0.001146000000000,0.000654000000000,0.002075000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,663.000000000000000,198.000000000000000,121.000000000000000,0.308232628226545,0.324201861364523,120.000000000000000,0.479818779824340 -0.000000000000000,0.000014000000000,0.000090000000000,0.000080000000000,0.001210000000000,0.000638000000000,0.002083000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,687.000000000000000,198.000000000000000,121.000000000000000,0.262176220963531,0.309537239684066,120.000000000000000,0.458115096603436 -0.000000000000000,0.000016000000000,0.000088000000000,0.000083000000000,0.001372000000000,0.000608000000000,0.002184000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,661.000000000000000,229.000000000000000,121.000000000000000,0.297772564345863,0.357204547667525,120.000000000000000,0.528662731800066 -0.000000000000000,0.000019000000000,0.000117000000000,0.000170000000000,0.001186000000000,0.000723000000000,0.002237000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,661.000000000000000,195.000000000000000,121.000000000000000,0.273843523747758,0.292259687716359,119.000000000000000,0.432544362541022 -0.000000000000000,0.000024000000000,0.000153000000000,0.000084000000000,0.001302000000000,0.000641000000000,0.002227000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,668.000000000000000,208.000000000000000,121.000000000000000,0.290286911670839,0.351299244972216,120.000000000000000,0.519922910820696 -0.000000000000000,0.000016000000000,0.000088000000000,0.000087000000000,0.001312000000000,0.000624000000000,0.002148000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,681.000000000000000,211.000000000000000,121.000000000000000,0.258959269785308,0.286064925174815,120.000000000000000,0.423376082295636 -0.000000000000000,0.000032000000000,0.000153000000000,0.000075000000000,0.001269000000000,0.000651000000000,0.002202000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,695.000000000000000,219.000000000000000,121.000000000000000,0.299842600943275,0.306289515328744,118.000000000000000,0.453308488218462 -0.000000000000000,0.000019000000000,0.000193000000000,0.000085000000000,0.001467000000000,0.000596000000000,0.002394000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,704.000000000000000,201.000000000000000,121.000000000000000,0.274895790792161,0.339772965508454,119.000000000000000,0.502863994936072 -0.000000000000000,0.000017000000000,0.000154000000000,0.000080000000000,0.001269000000000,0.000617000000000,0.002161000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,712.000000000000000,205.000000000000000,121.000000000000000,0.276261362669988,0.281418870291626,120.000000000000000,0.416499935291270 -0.000000000000000,0.000016000000000,0.000086000000000,0.000075000000000,0.001135000000000,0.000709000000000,0.002044000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,743.000000000000000,194.000000000000000,121.000000000000000,0.308428304394499,0.293336201315787,118.000000000000000,0.434137551702758 -0.000000000000000,0.000018000000000,0.000171000000000,0.000082000000000,0.001466000000000,0.000783000000000,0.002546000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,769.000000000000000,216.000000000000000,121.000000000000000,0.273449756649530,0.322902720385252,119.000000000000000,0.477896045491622 -0.000000000000000,0.000016000000000,0.000087000000000,0.000083000000000,0.001273000000000,0.000696000000000,0.002177000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,791.000000000000000,204.000000000000000,121.000000000000000,0.288082179726881,0.251959464844591,120.000000000000000,0.372900022480006 -0.000000000000000,0.000016000000000,0.000085000000000,0.000074000000000,0.001110000000000,0.000812000000000,0.002149000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,803.000000000000000,190.000000000000000,121.000000000000000,0.282457893847037,0.276453430621912,117.000000000000000,0.409151077978374 -0.000000000000000,0.000013000000000,0.000172000000000,0.000092000000000,0.001460000000000,0.000864000000000,0.002617000000000,0.000000000000000,111.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,781.000000000000000,208.000000000000000,121.000000000000000,0.294189238611744,0.317837647902468,121.000000000000000,0.470399701551591 -0.000000000000000,0.000011000000000,0.000108000000000,0.000167000000000,0.001206000000000,0.000875000000000,0.002390000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,781.000000000000000,194.000000000000000,121.000000000000000,0.243742619771063,0.304182365871834,119.000000000000000,0.450189939591226 -0.000000000000000,0.000012000000000,0.000101000000000,0.000079000000000,0.001300000000000,0.000731000000000,0.002246000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,803.000000000000000,220.000000000000000,121.000000000000000,0.265019461457802,0.270352874765002,119.000000000000000,0.400122247905802 -0.000000000000000,0.000020000000000,0.000165000000000,0.000097000000000,0.001379000000000,0.000946000000000,0.002634000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,811.000000000000000,196.000000000000000,121.000000000000000,0.253755606620435,0.269982081521535,119.000000000000000,0.399573494543632 -0.000000000000000,0.000016000000000,0.000164000000000,0.000085000000000,0.001383000000000,0.000747000000000,0.002418000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,821.000000000000000,217.000000000000000,121.000000000000000,0.242158681319397,0.277544822144716,118.000000000000000,0.410766329481695 -0.000000000000000,0.000019000000000,0.000149000000000,0.000078000000000,0.001258000000000,0.000689000000000,0.002215000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,826.000000000000000,208.000000000000000,121.000000000000000,0.247027054438406,0.299934280502362,119.000000000000000,0.443902753492513 -0.000000000000000,0.000021000000000,0.000089000000000,0.000096000000000,0.001356000000000,0.000776000000000,0.002363000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,835.000000000000000,206.000000000000000,121.000000000000000,0.251693428883974,0.262689374323986,119.000000000000000,0.388780283669121 -0.000000000000000,0.000014000000000,0.000148000000000,0.000100000000000,0.001257000000000,0.000655000000000,0.002196000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,858.000000000000000,208.000000000000000,121.000000000000000,0.204260997947582,0.239470873759942,121.000000000000000,0.354416885149381 -0.000000000000000,0.000023000000000,0.000162000000000,0.000076000000000,0.001146000000000,0.000648000000000,0.002087000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,887.000000000000000,182.000000000000000,121.000000000000000,0.288689598171738,0.321106098890548,121.000000000000000,0.475237040529197 -0.000000000000000,0.000024000000000,0.000153000000000,0.000091000000000,0.001220000000000,0.000643000000000,0.002186000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,895.000000000000000,169.000000000000000,121.000000000000000,0.226469268954673,0.283662212895001,120.000000000000000,0.419820102888912 -0.000000000000000,0.000024000000000,0.000085000000000,0.000080000000000,0.001237000000000,0.000635000000000,0.002077000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,887.000000000000000,201.000000000000000,121.000000000000000,0.248977774242743,0.301416583242808,121.000000000000000,0.446096553891485 -0.000000000000000,0.000021000000000,0.000171000000000,0.000164000000000,0.001414000000000,0.000769000000000,0.002569000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,881.000000000000000,197.000000000000000,121.000000000000000,0.197091396735570,0.215309872281506,121.000000000000000,0.318658631095349 -0.000000000000000,0.000020000000000,0.000151000000000,0.000085000000000,0.001385000000000,0.000841000000000,0.002509000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,888.000000000000000,208.000000000000000,121.000000000000000,0.211961816387840,0.217745091845774,121.000000000000000,0.322262753412405 -0.000000000000000,0.000018000000000,0.000150000000000,0.000078000000000,0.001242000000000,0.000841000000000,0.002356000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,913.000000000000000,191.000000000000000,121.000000000000000,0.223779838328298,0.264533102759499,119.000000000000000,0.391509013717953 -0.000000000000000,0.000022000000000,0.000097000000000,0.000097000000000,0.001450000000000,0.000723000000000,0.002416000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,960.000000000000000,191.000000000000000,121.000000000000000,0.192480719814296,0.242812842123578,120.000000000000000,0.359363019522775 -0.000000000000000,0.000020000000000,0.000090000000000,0.000082000000000,0.001223000000000,0.000684000000000,0.002125000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1010.000000000000000,186.000000000000000,121.000000000000000,0.226246256927728,0.246572316756408,121.000000000000000,0.364927025819891 -0.000000000000000,0.000018000000000,0.000107000000000,0.000079000000000,0.001240000000000,0.000867000000000,0.002334000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1043.000000000000000,191.000000000000000,121.000000000000000,0.213017300445347,0.226962316320547,121.000000000000000,0.335904230275835 -0.000000000000000,0.000016000000000,0.000187000000000,0.000091000000000,0.001459000000000,0.000724000000000,0.002629000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1066.000000000000000,197.000000000000000,121.000000000000000,0.236488382783212,0.308296711179547,118.000000000000000,0.456279145868659 -0.000000000000000,0.000016000000000,0.000147000000000,0.000085000000000,0.001434000000000,0.000889000000000,0.002595000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1045.000000000000000,222.000000000000000,121.000000000000000,0.203395568382791,0.322649411912471,119.000000000000000,0.477521162587761 -0.000000000000000,0.000019000000000,0.000093000000000,0.000103000000000,0.001526000000000,0.000764000000000,0.002542000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1041.000000000000000,208.000000000000000,121.000000000000000,0.217461375876614,0.242876047600301,119.000000000000000,0.359456575981592 -0.000000000000000,0.000012000000000,0.000089000000000,0.000085000000000,0.001381000000000,0.000699000000000,0.002299000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,202.000000000000000,121.000000000000000,0.237082694302344,0.363703604736602,120.000000000000000,0.538281356749968 -0.000000000000000,0.000013000000000,0.000106000000000,0.000083000000000,0.001290000000000,0.000760000000000,0.002283000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1051.000000000000000,204.000000000000000,121.000000000000000,0.204040454954466,0.217778632970223,121.000000000000000,0.322312387363004 -0.000000000000000,0.000021000000000,0.000089000000000,0.000095000000000,0.001523000000000,0.000740000000000,0.002518000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1092.000000000000000,216.000000000000000,121.000000000000000,0.189496933340522,0.218462243311750,119.000000000000000,0.323324121364161 -0.000000000000000,0.000016000000000,0.000114000000000,0.000088000000000,0.001265000000000,0.000870000000000,0.002384000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1150.000000000000000,195.000000000000000,121.000000000000000,0.234911952172899,0.229829985444704,121.000000000000000,0.340148387945673 -0.000000000000000,0.000022000000000,0.000165000000000,0.000090000000000,0.001383000000000,0.000870000000000,0.002564000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1188.000000000000000,188.000000000000000,121.000000000000000,0.238956119978159,0.242241004289434,119.000000000000000,0.358516689903833 -0.000000000000000,0.000024000000000,0.000125000000000,0.000088000000000,0.001295000000000,0.000732000000000,0.002498000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1209.000000000000000,181.000000000000000,121.000000000000000,0.231068618034561,0.351821584870681,121.000000000000000,0.520695977291580 -0.000000000000000,0.000009000000000,0.000086000000000,0.000086000000000,0.001377000000000,0.000690000000000,0.002304000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1131.000000000000000,223.000000000000000,121.000000000000000,0.232053202367997,0.243086811406556,121.000000000000000,0.359768506659923 -0.000000000000000,0.000015000000000,0.000156000000000,0.000090000000000,0.001467000000000,0.000758000000000,0.002521000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1126.000000000000000,205.000000000000000,121.000000000000000,0.217720599422460,0.232179181942645,120.000000000000000,0.343625190587007 -0.000000000000000,0.000022000000000,0.000088000000000,0.000083000000000,0.001420000000000,0.000856000000000,0.002503000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1122.000000000000000,225.000000000000000,121.000000000000000,0.210873068435952,0.231191074937355,120.000000000000000,0.342162783347037 -0.000000000000000,0.000010000000000,0.000096000000000,0.000092000000000,0.001468000000000,0.000882000000000,0.002583000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1124.000000000000000,218.000000000000000,121.000000000000000,0.199078575841603,0.231934072485734,121.000000000000000,0.343262412908369 -0.000000000000000,0.000014000000000,0.000090000000000,0.000084000000000,0.001429000000000,0.000750000000000,0.002400000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1131.000000000000000,217.000000000000000,121.000000000000000,0.199480471035799,0.201976563717399,121.000000000000000,0.298925319680116 -0.000000000000000,0.000016000000000,0.000086000000000,0.000082000000000,0.001377000000000,0.000677000000000,0.002270000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1170.000000000000000,216.000000000000000,121.000000000000000,0.220678346305332,0.284081275414871,121.000000000000000,0.420440299824576 -0.000000000000000,0.000027000000000,0.000102000000000,0.000086000000000,0.001575000000000,0.000893000000000,0.002726000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1207.000000000000000,220.000000000000000,121.000000000000000,0.211162657455426,0.207040156377078,121.000000000000000,0.306419439695680 -0.000000000000000,0.000016000000000,0.000108000000000,0.000083000000000,0.001461000000000,0.000764000000000,0.002474000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1249.000000000000000,230.000000000000000,121.000000000000000,0.227293453622315,0.273472763274248,121.000000000000000,0.404739696351758 -0.000000000000000,0.000016000000000,0.000088000000000,0.000078000000000,0.001528000000000,0.000670000000000,0.002548000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,235.000000000000000,121.000000000000000,0.230650938262149,0.341719334696620,121.000000000000000,0.505744634189104 -0.000000000000000,0.000014000000000,0.000157000000000,0.000097000000000,0.001482000000000,0.000903000000000,0.002719000000000,0.000000000000000,106.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1118.000000000000000,225.000000000000000,121.000000000000000,0.192289115182234,0.284781239296802,121.000000000000000,0.421476244276178 -0.000000000000000,0.000009000000000,0.000107000000000,0.000085000000000,0.001393000000000,0.000822000000000,0.002450000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1112.000000000000000,223.000000000000000,121.000000000000000,0.206644050900703,0.414842370987539,120.000000000000000,0.613966712358429 -0.000000000000000,0.000013000000000,0.000119000000000,0.000087000000000,0.001684000000000,0.000696000000000,0.002637000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1116.000000000000000,248.000000000000000,121.000000000000000,0.217279659889557,0.386405943424662,121.000000000000000,0.571880811943511 -0.000000000000000,0.000013000000000,0.000107000000000,0.000086000000000,0.001569000000000,0.000810000000000,0.002621000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1115.000000000000000,245.000000000000000,121.000000000000000,0.205227319768628,0.260415513728504,121.000000000000000,0.385414955241683 -0.000000000000000,0.000017000000000,0.000090000000000,0.000082000000000,0.001607000000000,0.000835000000000,0.002666000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1141.000000000000000,234.000000000000000,121.000000000000000,0.215577332340184,0.253414375214643,120.000000000000000,0.375053286801197 -0.000000000000000,0.000018000000000,0.000118000000000,0.000089000000000,0.001476000000000,0.000855000000000,0.002594000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1162.000000000000000,189.000000000000000,121.000000000000000,0.263380285246488,0.344156012084719,121.000000000000000,0.509350879343151 -0.000000000000000,0.000019000000000,0.000107000000000,0.000079000000000,0.001350000000000,0.000913000000000,0.002498000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1191.000000000000000,211.000000000000000,121.000000000000000,0.211941539220644,0.302129709054244,121.000000000000000,0.447152008225909 -0.000000000000000,0.000017000000000,0.000113000000000,0.000084000000000,0.001500000000000,0.000792000000000,0.002540000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1216.000000000000000,227.000000000000000,121.000000000000000,0.202379365741516,0.390009847847033,120.000000000000000,0.577214540970843 -0.000000000000000,0.000011000000000,0.000089000000000,0.000087000000000,0.001487000000000,0.000793000000000,0.002500000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1231.000000000000000,213.000000000000000,121.000000000000000,0.214175551012714,0.216953676956891,120.000000000000000,0.321091452830759 -0.000000000000000,0.000015000000000,0.000086000000000,0.000080000000000,0.001432000000000,0.000687000000000,0.002331000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,223.000000000000000,121.000000000000000,0.199434039847726,0.257284849007253,121.000000000000000,0.380781610790163 -0.000000000000000,0.000014000000000,0.000093000000000,0.000084000000000,0.001629000000000,0.000756000000000,0.002612000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,237.000000000000000,121.000000000000000,0.197980635555219,0.261749609075989,121.000000000000000,0.387389446361990 -0.000000000000000,0.000017000000000,0.000088000000000,0.000087000000000,0.001493000000000,0.000846000000000,0.002566000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1233.000000000000000,228.000000000000000,121.000000000000000,0.236508484356981,0.240200224772688,121.000000000000000,0.355496322487429 -0.000000000000000,0.000014000000000,0.000164000000000,0.000088000000000,0.001671000000000,0.000811000000000,0.002926000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,248.000000000000000,121.000000000000000,0.184315305243839,0.201680214668134,121.000000000000000,0.298486726394656 -0.000000000000000,0.000013000000000,0.000164000000000,0.000099000000000,0.001590000000000,0.000831000000000,0.002766000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1105.000000000000000,230.000000000000000,121.000000000000000,0.190613955848338,0.200507971284196,120.000000000000000,0.296751787320034 -0.000000000000000,0.000016000000000,0.000087000000000,0.000085000000000,0.001377000000000,0.000850000000000,0.002444000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1104.000000000000000,218.000000000000000,121.000000000000000,0.200535674470726,0.209035608733197,120.000000000000000,0.309372710300047 -0.000000000000000,0.000013000000000,0.000091000000000,0.000089000000000,0.001407000000000,0.000797000000000,0.002429000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1144.000000000000000,201.000000000000000,121.000000000000000,0.227018445721033,0.269171979187375,121.000000000000000,0.398374546537365 -0.000000000000000,0.000024000000000,0.000159000000000,0.000086000000000,0.001427000000000,0.000852000000000,0.002589000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1182.000000000000000,206.000000000000000,121.000000000000000,0.206458268024795,0.213071493736729,121.000000000000000,0.315345817611568 -0.000000000000000,0.000023000000000,0.000096000000000,0.000084000000000,0.001443000000000,0.000848000000000,0.002527000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1214.000000000000000,197.000000000000000,121.000000000000000,0.195773117170614,0.235723820191720,120.000000000000000,0.348871251500985 -0.000000000000000,0.000018000000000,0.000166000000000,0.000097000000000,0.001547000000000,0.000786000000000,0.002646000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,206.000000000000000,121.000000000000000,0.202449512908354,0.259327833750046,121.000000000000000,0.383805213005791 -0.000000000000000,0.000015000000000,0.000089000000000,0.000085000000000,0.001354000000000,0.000899000000000,0.002473000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1255.000000000000000,195.000000000000000,121.000000000000000,0.234803205654552,0.251609191002594,120.000000000000000,0.372381595360564 -0.000000000000000,0.000015000000000,0.000148000000000,0.000079000000000,0.001434000000000,0.000759000000000,0.002612000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1267.000000000000000,221.000000000000000,121.000000000000000,0.207185371940379,0.272198837560189,121.000000000000000,0.402854263297596 -0.000000000000000,0.000014000000000,0.000110000000000,0.000089000000000,0.001471000000000,0.000697000000000,0.002442000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1147.000000000000000,216.000000000000000,121.000000000000000,0.170542136055104,0.199853580496046,121.000000000000000,0.295783293486634 -0.000000000000000,0.000011000000000,0.000140000000000,0.000086000000000,0.001577000000000,0.000769000000000,0.002617000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1147.000000000000000,234.000000000000000,121.000000000000000,0.189245949418993,0.197736413403659,121.000000000000000,0.292649910272330 -0.000000000000000,0.000018000000000,0.000166000000000,0.000094000000000,0.001662000000000,0.000699000000000,0.002677000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1177.000000000000000,225.000000000000000,121.000000000000000,0.198921843902340,0.245387061075502,119.000000000000000,0.363172854853005 -0.000000000000000,0.000010000000000,0.000149000000000,0.000107000000000,0.001458000000000,0.000785000000000,0.002541000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1221.000000000000000,222.000000000000000,121.000000000000000,0.196061687568370,0.262447572567731,121.000000000000000,0.388422408733057 -0.000000000000000,0.000013000000000,0.000150000000000,0.000086000000000,0.001461000000000,0.000690000000000,0.002431000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1264.000000000000000,222.000000000000000,121.000000000000000,0.188165247064654,0.226893158617754,120.000000000000000,0.335801879206626 -0.000000000000000,0.000011000000000,0.000087000000000,0.000090000000000,0.001543000000000,0.000884000000000,0.002648000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1280.000000000000000,221.000000000000000,121.000000000000000,0.195179134679885,0.208025099223027,119.000000000000000,0.307877146368027 -0.000000000000000,0.000014000000000,0.000208000000000,0.000082000000000,0.001576000000000,0.000716000000000,0.002630000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1295.000000000000000,262.000000000000000,121.000000000000000,0.204969117934416,0.216857241486732,119.000000000000000,0.320948742586853 -0.000000000000000,0.000024000000000,0.000169000000000,0.000098000000000,0.001343000000000,0.000853000000000,0.002520000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1303.000000000000000,192.000000000000000,121.000000000000000,0.227441413063451,0.257511508846672,120.000000000000000,0.381117019034739 -0.000000000000000,0.000009000000000,0.000087000000000,0.000083000000000,0.001482000000000,0.000867000000000,0.002560000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1303.000000000000000,234.000000000000000,121.000000000000000,0.206543419238523,0.240601524255942,121.000000000000000,0.356090287223134 -0.000000000000000,0.000017000000000,0.000085000000000,0.000090000000000,0.001430000000000,0.000831000000000,0.002586000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1312.000000000000000,207.000000000000000,121.000000000000000,0.208575675835164,0.214150033311086,121.000000000000000,0.316942039397577 -0.000000000000000,0.000015000000000,0.000164000000000,0.000102000000000,0.001530000000000,0.000841000000000,0.002712000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1139.000000000000000,223.000000000000000,121.000000000000000,0.209522023711657,0.213144284667314,121.000000000000000,0.315453551588861 -0.000000000000000,0.000015000000000,0.000105000000000,0.000078000000000,0.001301000000000,0.000820000000000,0.002350000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1137.000000000000000,212.000000000000000,121.000000000000000,0.214867803164927,0.261245240464500,120.000000000000000,0.386642965897231 -0.000000000000000,0.000016000000000,0.000101000000000,0.000080000000000,0.001381000000000,0.000813000000000,0.002424000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1182.000000000000000,188.000000000000000,121.000000000000000,0.205519375020890,0.194082271824269,121.000000000000000,0.287241755590969 -0.000000000000000,0.000013000000000,0.000149000000000,0.000084000000000,0.001317000000000,0.000634000000000,0.002230000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,190.000000000000000,121.000000000000000,0.193630790736426,0.209509974832839,121.000000000000000,0.310074762819209 -0.000000000000000,0.000020000000000,0.000095000000000,0.000087000000000,0.001465000000000,0.000730000000000,0.002432000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1251.000000000000000,218.000000000000000,121.000000000000000,0.192820932489665,0.213663301525895,121.000000000000000,0.316221664773433 -0.000000000000000,0.000019000000000,0.000163000000000,0.000085000000000,0.001400000000000,0.000794000000000,0.002498000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1258.000000000000000,187.000000000000000,121.000000000000000,0.178472893331951,0.196146108608914,120.000000000000000,0.290296240030441 -0.000000000000000,0.000012000000000,0.000108000000000,0.000091000000000,0.001293000000000,0.000751000000000,0.002285000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1274.000000000000000,203.000000000000000,121.000000000000000,0.204380791067604,0.211515445058425,119.000000000000000,0.313042868010643 -0.000000000000000,0.000017000000000,0.000161000000000,0.000078000000000,0.001276000000000,0.000745000000000,0.002316000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1284.000000000000000,207.000000000000000,121.000000000000000,0.187808408411530,0.214316116353771,121.000000000000000,0.317187858866760 -0.000000000000000,0.000015000000000,0.000093000000000,0.000089000000000,0.001466000000000,0.000749000000000,0.002445000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1286.000000000000000,207.000000000000000,121.000000000000000,0.199989980411572,0.230213140472726,121.000000000000000,0.340715438140956 -0.000000000000000,0.000016000000000,0.000150000000000,0.000081000000000,0.001405000000000,0.000699000000000,0.002385000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,213.000000000000000,121.000000000000000,0.206268660764417,0.237247311670881,121.000000000000000,0.351126007647841 -0.000000000000000,0.000020000000000,0.000155000000000,0.000079000000000,0.001337000000000,0.000555000000000,0.002180000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1279.000000000000000,203.000000000000000,121.000000000000000,0.183003834372267,0.219788084820077,121.000000000000000,0.325286355628032 -0.000000000000000,0.000024000000000,0.000162000000000,0.000089000000000,0.001394000000000,0.000718000000000,0.002565000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1272.000000000000000,191.000000000000000,121.000000000000000,0.186553971804931,0.182751341988290,121.000000000000000,0.270472000430761 -0.000000000000000,0.000016000000000,0.000109000000000,0.000097000000000,0.001309000000000,0.000793000000000,0.002379000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1148.000000000000000,206.000000000000000,121.000000000000000,0.182081620850879,0.190648173777097,119.000000000000000,0.282159304756511 -0.000000000000000,0.000018000000000,0.000165000000000,0.000085000000000,0.001434000000000,0.001000000000000,0.002736000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1146.000000000000000,198.000000000000000,121.000000000000000,0.161190220960006,0.185797469108689,121.000000000000000,0.274980249131025 -0.000000000000000,0.000017000000000,0.000065000000000,0.000084000000000,0.001165000000000,0.000868000000000,0.002227000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1202.000000000000000,183.000000000000000,121.000000000000000,0.182593650165736,0.182593650165736,120.000000000000000,0.270238614721097 -0.000000000000000,0.000013000000000,0.000106000000000,0.000081000000000,0.001303000000000,0.000768000000000,0.002301000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1222.000000000000000,185.000000000000000,121.000000000000000,0.166736786826383,0.199418227406995,120.000000000000000,0.295138987188000 -0.000000000000000,0.000015000000000,0.000109000000000,0.000095000000000,0.001360000000000,0.000938000000000,0.002546000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1249.000000000000000,189.000000000000000,121.000000000000000,0.191808443828625,0.226302606500564,121.000000000000000,0.334927876891194 -0.000000000000000,0.000019000000000,0.000163000000000,0.000087000000000,0.001234000000000,0.000928000000000,0.002463000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,165.000000000000000,121.000000000000000,0.166580449599247,0.180745814173528,121.000000000000000,0.267503794151850 -0.000000000000000,0.000023000000000,0.000090000000000,0.000087000000000,0.001327000000000,0.000948000000000,0.002508000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1289.000000000000000,189.000000000000000,121.000000000000000,0.204446978142314,0.213236190122245,120.000000000000000,0.315589564787498 -0.000000000000000,0.000012000000000,0.000089000000000,0.000086000000000,0.001424000000000,0.000752000000000,0.002394000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1303.000000000000000,207.000000000000000,121.000000000000000,0.189969084150173,0.239096854811035,121.000000000000000,0.353863330132112 -0.000000000000000,0.000018000000000,0.000151000000000,0.000084000000000,0.001303000000000,0.000702000000000,0.002297000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1309.000000000000000,198.000000000000000,121.000000000000000,0.203248106998635,0.283179509252321,120.000000000000000,0.419105667153969 -0.000000000000000,0.000018000000000,0.000121000000000,0.000114000000000,0.001451000000000,0.000873000000000,0.002610000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1309.000000000000000,186.000000000000000,121.000000000000000,0.193450874101625,0.200224929073400,120.000000000000000,0.296332880820479 -0.000000000000000,0.000016000000000,0.000099000000000,0.000085000000000,0.001266000000000,0.000850000000000,0.002346000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1307.000000000000000,182.000000000000000,121.000000000000000,0.190247303390951,0.176735411055755,120.000000000000000,0.261568417740656 -0.000000000000000,0.000017000000000,0.000148000000000,0.000080000000000,0.001332000000000,0.000666000000000,0.002391000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1339.000000000000000,203.000000000000000,121.000000000000000,0.200414786051663,0.221307330406924,119.000000000000000,0.327534844351391 -0.000000000000000,0.000016000000000,0.000157000000000,0.000094000000000,0.001205000000000,0.000724000000000,0.002264000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1203.000000000000000,168.000000000000000,121.000000000000000,0.199743231584850,0.225956586080112,121.000000000000000,0.334415767738987 -0.000000000000000,0.000011000000000,0.000087000000000,0.000092000000000,0.001277000000000,0.000769000000000,0.002270000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1198.000000000000000,184.000000000000000,121.000000000000000,0.148096017248236,0.229791243682201,121.000000000000000,0.340091046075047 -0.000000000000000,0.000015000000000,0.000098000000000,0.000084000000000,0.001401000000000,0.000839000000000,0.002470000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,207.000000000000000,121.000000000000000,0.171701277226300,0.189474819161897,121.000000000000000,0.280422723010407 -0.000000000000000,0.000015000000000,0.000157000000000,0.000086000000000,0.001295000000000,0.000747000000000,0.002332000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1272.000000000000000,197.000000000000000,121.000000000000000,0.154842494097145,0.164895074486922,120.000000000000000,0.244044726914351 -0.000000000000000,0.000013000000000,0.000151000000000,0.000078000000000,0.001295000000000,0.000656000000000,0.002225000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1288.000000000000000,190.000000000000000,121.000000000000000,0.171037240946432,0.274189059551541,121.000000000000000,0.405799825981935 -0.000000000000000,0.000012000000000,0.000163000000000,0.000096000000000,0.001404000000000,0.000731000000000,0.002442000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1300.000000000000000,186.000000000000000,121.000000000000000,0.183021843966101,0.234105160743232,121.000000000000000,0.346475629956656 -0.000000000000000,0.000015000000000,0.000096000000000,0.000083000000000,0.001337000000000,0.000726000000000,0.002288000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1307.000000000000000,185.000000000000000,121.000000000000000,0.183461220328528,0.207991417189789,121.000000000000000,0.307827284970608 -0.000000000000000,0.000016000000000,0.000149000000000,0.000080000000000,0.001274000000000,0.000606000000000,0.002156000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1313.000000000000000,200.000000000000000,121.000000000000000,0.203158950593758,0.241305735673881,121.000000000000000,0.357132499098233 -0.000000000000000,0.000012000000000,0.000152000000000,0.000083000000000,0.001408000000000,0.000621000000000,0.002310000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1319.000000000000000,207.000000000000000,121.000000000000000,0.172769464465069,0.242423202061487,121.000000000000000,0.358786340745426 -0.000000000000000,0.000017000000000,0.000155000000000,0.000087000000000,0.001210000000000,0.000693000000000,0.002332000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1314.000000000000000,179.000000000000000,121.000000000000000,0.189900236210407,0.248224778263959,121.000000000000000,0.367372660392853 -0.000000000000000,0.000013000000000,0.000157000000000,0.000092000000000,0.001368000000000,0.000607000000000,0.002301000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1110.000000000000000,204.000000000000000,121.000000000000000,0.167414207784906,0.238891530166090,121.000000000000000,0.353559486451843 -0.000000000000000,0.000017000000000,0.000092000000000,0.000082000000000,0.001333000000000,0.000748000000000,0.002306000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1103.000000000000000,197.000000000000000,121.000000000000000,0.164998017179115,0.188230341089860,121.000000000000000,0.278580909202036 -0.000000000000000,0.000011000000000,0.000150000000000,0.000082000000000,0.001388000000000,0.000755000000000,0.002418000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1146.000000000000000,219.000000000000000,121.000000000000000,0.173088299071632,0.182167160144569,121.000000000000000,0.269607399250574 -0.000000000000000,0.000014000000000,0.000095000000000,0.000091000000000,0.001460000000000,0.000843000000000,0.002540000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1188.000000000000000,199.000000000000000,121.000000000000000,0.159193450711399,0.194342796414950,121.000000000000000,0.287627328495391 -0.000000000000000,0.000023000000000,0.000162000000000,0.000084000000000,0.001428000000000,0.000661000000000,0.002402000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1213.000000000000000,213.000000000000000,121.000000000000000,0.163604775275874,0.178874584867471,121.000000000000000,0.264734376394025 -0.000000000000000,0.000015000000000,0.000091000000000,0.000079000000000,0.001243000000000,0.000704000000000,0.002165000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1240.000000000000000,184.000000000000000,121.000000000000000,0.179908260850595,0.207929795609648,121.000000000000000,0.307736104067471 -0.000000000000000,0.000014000000000,0.000152000000000,0.000086000000000,0.001314000000000,0.000826000000000,0.002424000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1263.000000000000000,189.000000000000000,121.000000000000000,0.159876479501220,0.178421775752828,121.000000000000000,0.264064216973465 -0.000000000000000,0.000013000000000,0.000087000000000,0.000080000000000,0.001408000000000,0.000757000000000,0.002377000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,210.000000000000000,121.000000000000000,0.180877939732212,0.181463986212420,121.000000000000000,0.268566703687611 -0.000000000000000,0.000011000000000,0.000088000000000,0.000086000000000,0.001449000000000,0.000746000000000,0.002414000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1279.000000000000000,209.000000000000000,121.000000000000000,0.194139433375495,0.249420140021997,121.000000000000000,0.369141792306152 -0.000000000000000,0.000013000000000,0.000095000000000,0.000083000000000,0.001315000000000,0.000730000000000,0.002270000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1277.000000000000000,178.000000000000000,121.000000000000000,0.156793757882320,0.178864440219203,120.000000000000000,0.264719390175743 -0.000000000000000,0.000012000000000,0.000127000000000,0.000079000000000,0.001313000000000,0.000701000000000,0.002265000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,185.000000000000000,121.000000000000000,0.164883000136156,0.240733177667065,121.000000000000000,0.356285108060795 -0.000000000000000,0.000014000000000,0.000166000000000,0.000100000000000,0.001393000000000,0.000725000000000,0.002432000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1318.000000000000000,183.000000000000000,121.000000000000000,0.135728889598211,0.162060045311901,119.000000000000000,0.239848863786058 -0.000000000000000,0.000015000000000,0.000155000000000,0.000089000000000,0.001343000000000,0.000750000000000,0.002387000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1356.000000000000000,191.000000000000000,121.000000000000000,0.173788063146282,0.195529217779223,121.000000000000000,0.289383243221234 -0.000000000000000,0.000016000000000,0.000150000000000,0.000078000000000,0.001258000000000,0.000644000000000,0.002300000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1395.000000000000000,185.000000000000000,121.000000000000000,0.151475576157850,0.175539257809215,121.000000000000000,0.259798098049517 -0.000000000000000,0.000011000000000,0.000151000000000,0.000096000000000,0.001555000000000,0.000651000000000,0.002540000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1235.000000000000000,239.000000000000000,121.000000000000000,0.155311911245058,0.179651409086422,121.000000000000000,0.265884094799596 -0.000000000000000,0.000013000000000,0.000088000000000,0.000084000000000,0.001324000000000,0.000729000000000,0.002270000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,203.000000000000000,121.000000000000000,0.164537143262273,0.221612984534127,121.000000000000000,0.327987236077292 -0.000000000000000,0.000013000000000,0.000098000000000,0.000087000000000,0.001493000000000,0.000702000000000,0.002430000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1240.000000000000000,208.000000000000000,121.000000000000000,0.175143219815607,0.215695284047881,121.000000000000000,0.319229017177332 -0.000000000000000,0.000023000000000,0.000119000000000,0.000088000000000,0.001527000000000,0.000683000000000,0.002476000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,213.000000000000000,121.000000000000000,0.153675591056653,0.182664252108742,121.000000000000000,0.270343088627296 -0.000000000000000,0.000014000000000,0.000151000000000,0.000078000000000,0.001233000000000,0.000696000000000,0.002204000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1239.000000000000000,203.000000000000000,121.000000000000000,0.153229115354477,0.193081832581164,121.000000000000000,0.285761102061624 -0.000000000000000,0.000021000000000,0.000143000000000,0.000123000000000,0.001403000000000,0.000694000000000,0.002424000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1238.000000000000000,184.000000000000000,121.000000000000000,0.139965152794629,0.227002185063016,120.000000000000000,0.335963240089810 -0.000000000000000,0.000015000000000,0.000110000000000,0.000088000000000,0.001404000000000,0.000704000000000,0.002355000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,209.000000000000000,121.000000000000000,0.137197338848433,0.208531405635090,121.000000000000000,0.308626482553977 -0.000000000000000,0.000018000000000,0.000088000000000,0.000079000000000,0.001190000000000,0.000700000000000,0.002107000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,188.000000000000000,121.000000000000000,0.130941105653028,0.146060909721641,121.000000000000000,0.216170158735599 -0.000000000000000,0.000021000000000,0.000118000000000,0.000089000000000,0.001415000000000,0.000816000000000,0.002492000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,184.000000000000000,121.000000000000000,0.153353796799625,0.199263806316360,121.000000000000000,0.294910453677173 -0.000000000000000,0.000017000000000,0.000151000000000,0.000082000000000,0.001223000000000,0.000698000000000,0.002202000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1228.000000000000000,179.000000000000000,121.000000000000000,0.140213553319483,0.175196026122660,121.000000000000000,0.259290133483817 -0.000000000000000,0.000019000000000,0.000155000000000,0.000078000000000,0.001255000000000,0.000811000000000,0.002351000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1229.000000000000000,190.000000000000000,121.000000000000000,0.130014281845411,0.153376137782893,120.000000000000000,0.226996677933372 -0.000000000000000,0.000017000000000,0.000119000000000,0.000089000000000,0.001341000000000,0.000705000000000,0.002417000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1228.000000000000000,181.000000000000000,121.000000000000000,0.153048040967559,0.195396547391727,121.000000000000000,0.289186880799568 -0.000000000000000,0.000034000000000,0.000168000000000,0.000085000000000,0.001355000000000,0.000876000000000,0.002565000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1098.000000000000000,224.000000000000000,121.000000000000000,0.139772469128747,0.173322524076028,121.000000000000000,0.256517354567422 -0.000000000000000,0.000017000000000,0.000164000000000,0.000090000000000,0.001416000000000,0.000893000000000,0.002614000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1096.000000000000000,199.000000000000000,121.000000000000000,0.153304734612976,0.183642468789981,120.000000000000000,0.271790863455149 -0.000000000000000,0.000016000000000,0.000151000000000,0.000085000000000,0.001314000000000,0.000712000000000,0.002309000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1169.000000000000000,206.000000000000000,121.000000000000000,0.142897294139319,0.181555340311233,120.000000000000000,0.268701908186442 -0.000000000000000,0.000015000000000,0.000117000000000,0.000085000000000,0.001376000000000,0.000780000000000,0.002405000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1216.000000000000000,222.000000000000000,121.000000000000000,0.126799378274116,0.146656265445468,120.000000000000000,0.217051287718072 -0.000000000000000,0.000016000000000,0.000165000000000,0.000106000000000,0.001478000000000,0.000760000000000,0.002565000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1236.000000000000000,202.000000000000000,121.000000000000000,0.140084421158853,0.204486312942259,121.000000000000000,0.302639753705096 -0.000000000000000,0.000011000000000,0.000107000000000,0.000080000000000,0.001194000000000,0.000749000000000,0.002169000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1246.000000000000000,201.000000000000000,121.000000000000000,0.139419993339841,0.168128905916729,121.000000000000000,0.248830789269877 -0.000000000000000,0.000014000000000,0.000152000000000,0.000092000000000,0.001362000000000,0.000736000000000,0.002390000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1247.000000000000000,196.000000000000000,121.000000000000000,0.145258293429478,0.175683893358186,121.000000000000000,0.260012150779442 -0.000000000000000,0.000017000000000,0.000165000000000,0.000083000000000,0.001281000000000,0.000789000000000,0.002367000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1243.000000000000000,182.000000000000000,121.000000000000000,0.130776175712068,0.189705854296339,121.000000000000000,0.280764651397170 -0.000000000000000,0.000014000000000,0.000148000000000,0.000080000000000,0.001146000000000,0.000646000000000,0.002066000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1231.000000000000000,185.000000000000000,121.000000000000000,0.160961980060978,0.209744716515705,121.000000000000000,0.310422175201532 -0.000000000000000,0.000017000000000,0.000165000000000,0.000099000000000,0.001434000000000,0.000756000000000,0.002649000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1229.000000000000000,192.000000000000000,121.000000000000000,0.148237727429110,0.178425698740388,121.000000000000000,0.264070029503321 -0.000000000000000,0.000009000000000,0.000152000000000,0.000088000000000,0.001271000000000,0.000627000000000,0.002203000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1070.000000000000000,202.000000000000000,121.000000000000000,0.145517296057557,0.194221829742895,121.000000000000000,0.287448302575818 -0.000000000000000,0.000013000000000,0.000171000000000,0.000110000000000,0.001292000000000,0.000667000000000,0.002296000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1062.000000000000000,207.000000000000000,121.000000000000000,0.144870620749843,0.185268776731061,120.000000000000000,0.274197806796764 -0.000000000000000,0.000012000000000,0.000167000000000,0.000090000000000,0.001672000000000,0.000784000000000,0.002761000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1051.000000000000000,240.000000000000000,121.000000000000000,0.147451415472805,0.239110494103313,121.000000000000000,0.353883547627265 -0.000000000000000,0.000023000000000,0.000169000000000,0.000084000000000,0.001225000000000,0.000708000000000,0.002240000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1058.000000000000000,193.000000000000000,121.000000000000000,0.139221728219021,0.208258123486744,121.000000000000000,0.308222006291587 -0.000000000000000,0.000018000000000,0.000114000000000,0.000095000000000,0.001441000000000,0.000867000000000,0.002569000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1122.000000000000000,195.000000000000000,121.000000000000000,0.144798866574318,0.161179631549979,121.000000000000000,0.238545871495364 -0.000000000000000,0.000015000000000,0.000087000000000,0.000084000000000,0.001190000000000,0.000950000000000,0.002357000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1161.000000000000000,181.000000000000000,121.000000000000000,0.156951809426305,0.174642571732918,121.000000000000000,0.258471021667723 -0.000000000000000,0.000025000000000,0.000109000000000,0.000081000000000,0.001177000000000,0.000732000000000,0.002154000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1178.000000000000000,188.000000000000000,121.000000000000000,0.143966687089071,0.148286357619255,121.000000000000000,0.219463816142722 -0.000000000000000,0.000016000000000,0.000167000000000,0.000091000000000,0.001397000000000,0.000699000000000,0.002561000000000,1.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1185.000000000000000,186.000000000000000,121.000000000000000,0.141904983877111,0.215844079586902,120.000000000000000,0.319449236243278 -0.000000000000000,0.000013000000000,0.000107000000000,0.000086000000000,0.001203000000000,0.000597000000000,0.002056000000000,0.000000000000000,109.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1024.000000000000000,198.000000000000000,121.000000000000000,0.158784086059447,0.201694183533691,121.000000000000000,0.298507398783450 -0.000000000000000,0.000011000000000,0.000112000000000,0.000087000000000,0.001357000000000,0.000625000000000,0.002227000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1012.000000000000000,200.000000000000000,121.000000000000000,0.142538196203460,0.192228508218454,121.000000000000000,0.284498190955069 -0.000000000000000,0.000011000000000,0.000111000000000,0.000090000000000,0.001358000000000,0.000662000000000,0.002264000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1012.000000000000000,207.000000000000000,121.000000000000000,0.168549877781207,0.187821262175372,121.000000000000000,0.277975471037833 -0.000000000000000,0.000012000000000,0.000149000000000,0.000117000000000,0.001286000000000,0.000829000000000,0.002423000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1008.000000000000000,214.000000000000000,121.000000000000000,0.143759909717310,0.192182987333624,121.000000000000000,0.284430816152474 -0.000000000000000,0.000015000000000,0.000167000000000,0.000090000000000,0.001493000000000,0.000810000000000,0.002612000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1001.000000000000000,212.000000000000000,121.000000000000000,0.174890959675259,0.213312437262072,121.000000000000000,0.315702428954185 -0.000000000000000,0.000019000000000,0.000151000000000,0.000086000000000,0.001409000000000,0.000712000000000,0.002407000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1001.000000000000000,207.000000000000000,121.000000000000000,0.152789140763855,0.164105200132453,121.000000000000000,0.242875700800910 -0.000000000000000,0.000016000000000,0.000087000000000,0.000081000000000,0.001205000000000,0.000602000000000,0.002152000000000,1.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1043.000000000000000,199.000000000000000,121.000000000000000,0.163939125281343,0.202213714394798,120.000000000000000,0.299276295395959 -0.000000000000000,0.000011000000000,0.000111000000000,0.000101000000000,0.001485000000000,0.000606000000000,0.002388000000000,0.000000000000000,105.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,933.000000000000000,228.000000000000000,121.000000000000000,0.162381916777401,0.199296542527132,121.000000000000000,0.294958899849931 -0.000000000000000,0.000012000000000,0.000086000000000,0.000086000000000,0.001214000000000,0.000711000000000,0.002139000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,930.000000000000000,188.000000000000000,121.000000000000000,0.126548973306942,0.138574150155498,120.000000000000000,0.205089745706516 -0.000000000000000,0.000012000000000,0.000167000000000,0.000087000000000,0.001455000000000,0.000638000000000,0.002392000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,959.000000000000000,226.000000000000000,121.000000000000000,0.166801187642930,0.183010323861591,120.000000000000000,0.270855273595110 -0.000000000000000,0.000014000000000,0.000088000000000,0.000087000000000,0.001409000000000,0.000740000000000,0.002371000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,966.000000000000000,208.000000000000000,121.000000000000000,0.151605751950910,0.214754024488413,120.000000000000000,0.317835955945735 -0.000000000000000,0.000017000000000,0.000112000000000,0.000085000000000,0.001310000000000,0.000658000000000,0.002217000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,966.000000000000000,202.000000000000000,121.000000000000000,0.149723343863280,0.232974269786109,121.000000000000000,0.344801899348607 -0.000000000000000,0.000014000000000,0.000143000000000,0.000095000000000,0.001352000000000,0.001073000000000,0.002710000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,980.000000000000000,184.000000000000000,121.000000000000000,0.155861567427539,0.183956647347986,120.000000000000000,0.272255840571782 -0.000000000000000,0.000014000000000,0.000149000000000,0.000084000000000,0.001120000000000,0.000720000000000,0.002120000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,984.000000000000000,177.000000000000000,121.000000000000000,0.150101106525736,0.181285553460186,121.000000000000000,0.268302612657185 -0.000000000000000,0.000011000000000,0.000154000000000,0.000077000000000,0.001135000000000,0.000704000000000,0.002114000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1009.000000000000000,162.000000000000000,121.000000000000000,0.164203457795522,0.166918334037277,121.000000000000000,0.247039140121353 -0.000000000000000,0.000014000000000,0.000153000000000,0.000087000000000,0.001265000000000,0.000661000000000,0.002212000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1044.000000000000000,184.000000000000000,121.000000000000000,0.166079753752638,0.235937082097295,121.000000000000000,0.349186897144050 -0.000000000000000,0.000016000000000,0.000087000000000,0.000079000000000,0.001083000000000,0.000776000000000,0.002071000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1065.000000000000000,179.000000000000000,121.000000000000000,0.140784932440615,0.174109634177219,121.000000000000000,0.257682261366227 -0.000000000000000,0.000017000000000,0.000177000000000,0.000085000000000,0.001217000000000,0.000893000000000,0.002614000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1085.000000000000000,173.000000000000000,121.000000000000000,0.136693367503916,0.164873100634404,121.000000000000000,0.244012202019025 -0.000000000000000,0.000010000000000,0.000111000000000,0.000098000000000,0.001335000000000,0.000674000000000,0.002290000000000,0.000000000000000,108.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,940.000000000000000,210.000000000000000,121.000000000000000,0.152064884062461,0.157064948938113,121.000000000000000,0.232456109236813 -0.000000000000000,0.000009000000000,0.000148000000000,0.000085000000000,0.001199000000000,0.000682000000000,0.002153000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,937.000000000000000,196.000000000000000,121.000000000000000,0.149276999735119,0.172780031999726,121.000000000000000,0.255714442019319 -0.000000000000000,0.000016000000000,0.000157000000000,0.000094000000000,0.001300000000000,0.000821000000000,0.002420000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,948.000000000000000,187.000000000000000,121.000000000000000,0.151768200456098,0.155713508180996,121.000000000000000,0.230455992441400 -0.000000000000000,0.000019000000000,0.000116000000000,0.000085000000000,0.001196000000000,0.000791000000000,0.002239000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,950.000000000000000,186.000000000000000,121.000000000000000,0.144000321191294,0.179229516503960,121.000000000000000,0.265259702733687 -0.000000000000000,0.000013000000000,0.000154000000000,0.000083000000000,0.001139000000000,0.000808000000000,0.002231000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,960.000000000000000,170.000000000000000,121.000000000000000,0.152250251263816,0.176190168633417,121.000000000000000,0.260761436421654 -0.000000000000000,0.000015000000000,0.000087000000000,0.000085000000000,0.001127000000000,0.000768000000000,0.002115000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,983.000000000000000,164.000000000000000,121.000000000000000,0.129302901903334,0.143871781002835,121.000000000000000,0.212930229321842 -0.000000000000000,0.000013000000000,0.000110000000000,0.000120000000000,0.001152000000000,0.000761000000000,0.002188000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1013.000000000000000,181.000000000000000,121.000000000000000,0.137216294671414,0.165518456926789,121.000000000000000,0.244967327033756 -0.000000000000000,0.000022000000000,0.000167000000000,0.000085000000000,0.001236000000000,0.000710000000000,0.002252000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,170.000000000000000,121.000000000000000,0.162107693844438,0.225222383429965,121.000000000000000,0.333329153190160 -0.000000000000000,0.000014000000000,0.000108000000000,0.000083000000000,0.001153000000000,0.000703000000000,0.002206000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1073.000000000000000,176.000000000000000,121.000000000000000,0.142487698690500,0.215619270887844,121.000000000000000,0.319116532088679 -0.000000000000000,0.000016000000000,0.000149000000000,0.000080000000000,0.001141000000000,0.000754000000000,0.002190000000000,0.000000000000000,109.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,919.000000000000000,194.000000000000000,121.000000000000000,0.144721479076393,0.144784816827571,121.000000000000000,0.214281516154081 -0.000000000000000,0.000013000000000,0.000152000000000,0.000093000000000,0.001294000000000,0.000832000000000,0.002420000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,915.000000000000000,177.000000000000000,121.000000000000000,0.149099082449318,0.191998203412644,121.000000000000000,0.284157323986802 -0.000000000000000,0.000018000000000,0.000087000000000,0.000081000000000,0.001097000000000,0.000702000000000,0.002015000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,933.000000000000000,176.000000000000000,121.000000000000000,0.155861769273800,0.170207046079660,121.000000000000000,0.251906426263653 -0.000000000000000,0.000014000000000,0.000089000000000,0.000078000000000,0.001146000000000,0.000908000000000,0.002268000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,942.000000000000000,168.000000000000000,121.000000000000000,0.138592736529167,0.162826237027208,121.000000000000000,0.240982837817279 -0.000000000000000,0.000020000000000,0.000091000000000,0.000094000000000,0.001136000000000,0.000619000000000,0.001992000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,952.000000000000000,158.000000000000000,121.000000000000000,0.145657951253513,0.188004859202689,121.000000000000000,0.278247194172679 -0.000000000000000,0.000020000000000,0.000125000000000,0.000078000000000,0.001053000000000,0.000766000000000,0.002073000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,981.000000000000000,173.000000000000000,121.000000000000000,0.128806331282994,0.198803320775784,121.000000000000000,0.294228921915590 -0.000000000000000,0.000019000000000,0.000167000000000,0.000089000000000,0.001255000000000,0.000878000000000,0.002445000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1004.000000000000000,174.000000000000000,121.000000000000000,0.118066645939065,0.158172695543332,121.000000000000000,0.234095596462448 -0.000000000000000,0.000014000000000,0.000107000000000,0.000083000000000,0.001134000000000,0.000719000000000,0.002090000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1033.000000000000000,174.000000000000000,121.000000000000000,0.120270585655071,0.185382011446256,121.000000000000000,0.274365384559707 -0.000000000000000,0.000023000000000,0.000149000000000,0.000076000000000,0.001048000000000,0.000778000000000,0.002104000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1055.000000000000000,177.000000000000000,121.000000000000000,0.111655902944065,0.127479790231990,121.000000000000000,0.188670081746738 -0.000000000000000,0.000024000000000,0.000165000000000,0.000093000000000,0.001273000000000,0.000666000000000,0.002422000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1068.000000000000000,161.000000000000000,121.000000000000000,0.137252105053442,0.201665031989628,121.000000000000000,0.298464234431299 -0.000000000000000,0.000016000000000,0.000151000000000,0.000085000000000,0.001226000000000,0.000594000000000,0.002131000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,917.000000000000000,199.000000000000000,121.000000000000000,0.109849180876551,0.169849754533253,121.000000000000000,0.251377637677945 -0.000000000000000,0.000019000000000,0.000166000000000,0.000083000000000,0.001090000000000,0.000732000000000,0.002128000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,914.000000000000000,161.000000000000000,121.000000000000000,0.094619378225366,0.127736587063336,121.000000000000000,0.189050145383732 -0.000000000000000,0.000019000000000,0.000109000000000,0.000094000000000,0.001174000000000,0.000652000000000,0.002081000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,924.000000000000000,172.000000000000000,121.000000000000000,0.095987819870883,0.183985249071388,121.000000000000000,0.272298170952257 -0.000000000000000,0.000013000000000,0.000151000000000,0.000081000000000,0.001173000000000,0.000806000000000,0.002255000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,931.000000000000000,188.000000000000000,121.000000000000000,0.103214005987484,0.160102278671277,121.000000000000000,0.236951368196443 -0.000000000000000,0.000016000000000,0.000166000000000,0.000090000000000,0.001244000000000,0.000853000000000,0.002405000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,933.000000000000000,176.000000000000000,121.000000000000000,0.107624598314130,0.132136716401229,121.000000000000000,0.195562352203489 -0.000000000000000,0.000019000000000,0.000160000000000,0.000083000000000,0.001074000000000,0.000663000000000,0.002029000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,968.000000000000000,161.000000000000000,121.000000000000000,0.105311906661098,0.145668800777700,121.000000000000000,0.215589815537253 -0.000000000000000,0.000016000000000,0.000109000000000,0.000079000000000,0.001079000000000,0.000825000000000,0.002137000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,999.000000000000000,164.000000000000000,121.000000000000000,0.115404334777576,0.144024386113689,121.000000000000000,0.213156084014562 -0.000000000000000,0.000016000000000,0.000093000000000,0.000099000000000,0.001239000000000,0.000811000000000,0.002291000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1014.000000000000000,171.000000000000000,121.000000000000000,0.102620214117170,0.192238051746968,120.000000000000000,0.284512317929807 -0.000000000000000,0.000019000000000,0.000086000000000,0.000082000000000,0.001037000000000,0.000718000000000,0.001972000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1040.000000000000000,170.000000000000000,121.000000000000000,0.105335250265535,0.144890464932436,121.000000000000000,0.214437873207215 -0.000000000000000,0.000017000000000,0.000109000000000,0.000079000000000,0.001050000000000,0.000705000000000,0.001992000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1061.000000000000000,160.000000000000000,121.000000000000000,0.102004773526380,0.101331023468228,121.000000000000000,0.149969916793428 -0.000000000000000,0.000019000000000,0.000120000000000,0.000096000000000,0.001236000000000,0.000783000000000,0.002289000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1076.000000000000000,160.000000000000000,121.000000000000000,0.101321819984142,0.125092002453206,121.000000000000000,0.185136164681599 -0.000000000000000,0.000017000000000,0.000151000000000,0.000083000000000,0.001093000000000,0.000805000000000,0.002181000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1087.000000000000000,166.000000000000000,121.000000000000000,0.100949350996349,0.133208193438679,121.000000000000000,0.197148136707625 -0.000000000000000,0.000016000000000,0.000166000000000,0.000086000000000,0.001225000000000,0.000614000000000,0.002142000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1094.000000000000000,173.000000000000000,121.000000000000000,0.113902102274736,0.263501176586062,121.000000000000000,0.389981758862282 -0.000000000000000,0.000017000000000,0.000110000000000,0.000085000000000,0.001057000000000,0.000701000000000,0.002002000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1103.000000000000000,147.000000000000000,121.000000000000000,0.112950870334457,0.159164000744430,121.000000000000000,0.235562729541910 -0.000000000000000,0.000015000000000,0.000148000000000,0.000081000000000,0.001005000000000,0.000710000000000,0.002002000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1107.000000000000000,160.000000000000000,121.000000000000000,0.096261721291800,0.169941815822129,121.000000000000000,0.251513903595272 -0.000000000000000,0.000014000000000,0.000111000000000,0.000087000000000,0.001226000000000,0.000704000000000,0.002175000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1134.000000000000000,179.000000000000000,121.000000000000000,0.100695432310273,0.149404926005425,121.000000000000000,0.221119300461396 -0.000000000000000,0.000017000000000,0.000159000000000,0.000084000000000,0.001069000000000,0.000609000000000,0.001969000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1163.000000000000000,157.000000000000000,121.000000000000000,0.104264909242810,0.168733357468614,121.000000000000000,0.249725362886627 -0.000000000000000,0.000016000000000,0.000084000000000,0.000079000000000,0.000994000000000,0.000786000000000,0.001989000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1186.000000000000000,161.000000000000000,121.000000000000000,0.098764835183793,0.142076743187060,121.000000000000000,0.210273574643228 -0.000000000000000,0.000014000000000,0.000113000000000,0.000090000000000,0.001119000000000,0.000653000000000,0.002020000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1204.000000000000000,154.000000000000000,121.000000000000000,0.099700583140545,0.115489183389192,121.000000000000000,0.170923985837824 -0.000000000000000,0.000015000000000,0.000088000000000,0.000083000000000,0.001096000000000,0.000758000000000,0.002070000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1224.000000000000000,165.000000000000000,121.000000000000000,0.113531975395493,0.159479019440782,121.000000000000000,0.236028944980121 -0.000000000000000,0.000016000000000,0.000106000000000,0.000080000000000,0.000950000000000,0.000689000000000,0.001870000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1236.000000000000000,152.000000000000000,121.000000000000000,0.101278477365169,0.121853029810147,121.000000000000000,0.180342482857587 -0.000000000000000,0.000026000000000,0.000157000000000,0.000086000000000,0.001250000000000,0.000748000000000,0.002309000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1243.000000000000000,177.000000000000000,121.000000000000000,0.113386397852020,0.206475855003173,121.000000000000000,0.305584280242809 -0.000000000000000,0.000018000000000,0.000087000000000,0.000081000000000,0.001080000000000,0.000613000000000,0.001908000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1252.000000000000000,162.000000000000000,121.000000000000000,0.103012888489708,0.192649617277085,121.000000000000000,0.285121445786875 -0.000000000000000,0.000014000000000,0.000084000000000,0.000078000000000,0.001104000000000,0.000752000000000,0.002063000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1267.000000000000000,181.000000000000000,121.000000000000000,0.119108801565499,0.146565581346541,121.000000000000000,0.216917068822130 -0.000000000000000,0.000017000000000,0.000169000000000,0.000087000000000,0.001262000000000,0.000745000000000,0.002313000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1272.000000000000000,162.000000000000000,121.000000000000000,0.113261864886997,0.130198323725397,121.000000000000000,0.192693514913252 -0.000000000000000,0.000013000000000,0.000147000000000,0.000081000000000,0.001101000000000,0.000691000000000,0.002065000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1269.000000000000000,173.000000000000000,121.000000000000000,0.115292532476552,0.143763553384774,121.000000000000000,0.212770056216498 -0.000000000000000,0.000017000000000,0.000089000000000,0.000077000000000,0.001052000000000,0.000711000000000,0.001978000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1264.000000000000000,159.000000000000000,121.000000000000000,0.101382577834875,0.107355247718934,121.000000000000000,0.158885781611837 -0.000000000000000,0.000016000000000,0.000118000000000,0.000092000000000,0.001316000000000,0.000678000000000,0.002256000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1260.000000000000000,177.000000000000000,121.000000000000000,0.124156248079858,0.184101498216806,121.000000000000000,0.272470221836003 -0.000000000000000,0.000018000000000,0.000151000000000,0.000083000000000,0.001038000000000,0.000700000000000,0.002018000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1259.000000000000000,160.000000000000000,121.000000000000000,0.124874729225317,0.136317718156052,121.000000000000000,0.201750219857265 -0.000000000000000,0.000019000000000,0.000118000000000,0.000088000000000,0.001213000000000,0.000732000000000,0.002204000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1256.000000000000000,175.000000000000000,121.000000000000000,0.137395115258524,0.272990416298521,121.000000000000000,0.404025816597931 -0.000000000000000,0.000033000000000,0.000166000000000,0.000098000000000,0.001332000000000,0.000676000000000,0.002341000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1256.000000000000000,175.000000000000000,121.000000000000000,0.125440559596022,0.192594450198696,121.000000000000000,0.285039792378329 -0.000000000000000,0.000011000000000,0.000147000000000,0.000080000000000,0.001052000000000,0.000650000000000,0.001970000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1254.000000000000000,161.000000000000000,121.000000000000000,0.135853494715468,0.174263471494220,121.000000000000000,0.257909935633510 -0.000000000000000,0.000016000000000,0.000118000000000,0.000078000000000,0.001158000000000,0.000816000000000,0.002217000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1253.000000000000000,167.000000000000000,121.000000000000000,0.122720689566236,0.207186929273245,121.000000000000000,0.306636651409222 -0.000000000000000,0.000015000000000,0.000117000000000,0.000091000000000,0.001177000000000,0.000833000000000,0.002267000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1249.000000000000000,162.000000000000000,121.000000000000000,0.131197397185608,0.147375515585527,121.000000000000000,0.218115764109708 -0.000000000000000,0.000011000000000,0.000150000000000,0.000081000000000,0.001038000000000,0.000708000000000,0.002171000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1238.000000000000000,166.000000000000000,121.000000000000000,0.137378655081558,0.217187593785681,121.000000000000000,0.321437652163372 -0.000000000000000,0.000014000000000,0.000152000000000,0.000092000000000,0.001138000000000,0.000700000000000,0.002154000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1068.000000000000000,186.000000000000000,121.000000000000000,0.145478356636836,0.211190875078835,121.000000000000000,0.312562500325826 -0.000000000000000,0.000014000000000,0.000151000000000,0.000087000000000,0.001380000000000,0.000695000000000,0.002361000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1066.000000000000000,208.000000000000000,121.000000000000000,0.145910261187635,0.270725437624101,121.000000000000000,0.400673629542342 -0.000000000000000,0.000010000000000,0.000106000000000,0.000080000000000,0.001226000000000,0.000670000000000,0.002123000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1063.000000000000000,202.000000000000000,121.000000000000000,0.142580547861068,0.222707058106822,121.000000000000000,0.329606455264036 -0.000000000000000,0.000016000000000,0.000091000000000,0.000082000000000,0.001339000000000,0.000780000000000,0.002343000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1056.000000000000000,206.000000000000000,121.000000000000000,0.127026409458953,0.138078812827686,121.000000000000000,0.204356634060426 -0.000000000000000,0.000015000000000,0.000112000000000,0.000084000000000,0.001327000000000,0.000760000000000,0.002333000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1046.000000000000000,203.000000000000000,121.000000000000000,0.143390011522010,0.189299220864586,121.000000000000000,0.280162852382094 -0.000000000000000,0.000012000000000,0.000153000000000,0.000080000000000,0.001259000000000,0.000815000000000,0.002350000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1041.000000000000000,190.000000000000000,121.000000000000000,0.146470888134392,0.170045702350971,121.000000000000000,0.251667632374036 -0.000000000000000,0.000016000000000,0.000109000000000,0.000082000000000,0.001303000000000,0.000864000000000,0.002410000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1035.000000000000000,192.000000000000000,121.000000000000000,0.145288024491270,0.152085543829851,120.000000000000000,0.225086604806994 -0.000000000000000,0.000015000000000,0.000130000000000,0.000082000000000,0.001210000000000,0.000564000000000,0.002031000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1033.000000000000000,195.000000000000000,121.000000000000000,0.150132403510209,0.284875350032339,121.000000000000000,0.421615517545908 -0.000000000000000,0.000017000000000,0.000142000000000,0.000087000000000,0.001179000000000,0.000822000000000,0.002279000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1032.000000000000000,177.000000000000000,121.000000000000000,0.150560599418679,0.158144787063228,121.000000000000000,0.234054276956730 -0.000000000000000,0.000014000000000,0.000166000000000,0.000090000000000,0.001346000000000,0.000786000000000,0.002438000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1025.000000000000000,195.000000000000000,121.000000000000000,0.143981650642650,0.191284534828251,121.000000000000000,0.283101111496310 -0.000000000000000,0.000011000000000,0.000086000000000,0.000079000000000,0.001157000000000,0.000713000000000,0.002195000000000,1.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1022.000000000000000,190.000000000000000,121.000000000000000,0.154353905338326,0.194713119296172,121.000000000000000,0.288175424788969 -0.000000000000000,0.000015000000000,0.000156000000000,0.000097000000000,0.001181000000000,0.000713000000000,0.002220000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,838.000000000000000,198.000000000000000,121.000000000000000,0.139070972107019,0.141121163279108,121.000000000000000,0.208859322949524 -0.000000000000000,0.000015000000000,0.000151000000000,0.000089000000000,0.001225000000000,0.000800000000000,0.002315000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,835.000000000000000,186.000000000000000,121.000000000000000,0.138520459895391,0.192364562878898,121.000000000000000,0.284699557206785 -0.000000000000000,0.000016000000000,0.000166000000000,0.000083000000000,0.001375000000000,0.000800000000000,0.002476000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,831.000000000000000 \ No newline at end of file +0.000000000000000,0.000000000000000,0.000000000000000,0.000231000000000,0.000000000000000,0.000000000000000,0.005536000000000,1.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000326000000000,0.000000000000000,0.000000000000000,0.016564000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000189000000000,0.000000000000000,0.000000000000000,0.016754000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000133000000000,0.000000000000000,0.000000000000000,0.017082000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000136000000000,0.000000000000000,0.000000000000000,0.023259000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000120000000000,0.000000000000000,0.000000000000000,0.029114000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000231000000000,0.000000000000000,0.000000000000000,0.032538000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000123000000000,0.000000000000000,0.000000000000000,0.031375000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000137000000000,0.000000000000000,0.000000000000000,0.029995000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000119000000000,0.000000000000000,0.000000000000000,0.030888000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000461000000000,0.000000000000000,0.000000000000000,0.036835000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000159000000000,0.000000000000000,0.000000000000000,0.090994000000000,1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000036000000000,0.000143000000000,0.000117000000000,0.000836000000000,0.001616000000000,0.002862000000000,0.000000000000000,279.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,148.000000000000000,121.000000000000000,0.170175036288445,0.209622100274678,121.000000000000000,0.310240723182540 +0.000000000000000,0.000025000000000,0.000180000000000,0.000123000000000,0.000817000000000,0.000802000000000,0.001981000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,151.000000000000000,121.000000000000000,0.200086249066279,0.226929968835210,119.000000000000000,0.335856340084193 +0.000000000000000,0.000043000000000,0.000247000000000,0.000202000000000,0.000836000000000,0.000882000000000,0.002289000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,150.000000000000000,121.000000000000000,0.220021653137765,0.250579787207819,120.000000000000000,0.370858080741496 +0.000000000000000,0.000027000000000,0.000173000000000,0.000125000000000,0.000796000000000,0.000863000000000,0.002018000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,153.000000000000000,121.000000000000000,0.241933923583207,0.315090761433966,119.000000000000000,0.466334367626374 +0.000000000000000,0.000025000000000,0.000171000000000,0.000123000000000,0.000752000000000,0.000893000000000,0.002012000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,145.000000000000000,121.000000000000000,0.272951476803891,0.278442112643762,118.000000000000000,0.412094340922640 +0.000000000000000,0.000058000000000,0.000180000000000,0.000213000000000,0.001057000000000,0.000834000000000,0.002415000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,176.000000000000000,121.000000000000000,0.295685268713144,0.345204254249458,120.000000000000000,0.510902319377397 +0.000000000000000,0.000029000000000,0.000104000000000,0.000125000000000,0.000868000000000,0.000845000000000,0.002006000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,154.000000000000000,121.000000000000000,0.280726297104857,0.351937246921774,119.000000000000000,0.520867118388044 +0.000000000000000,0.000030000000000,0.000173000000000,0.000117000000000,0.000872000000000,0.000829000000000,0.002054000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,160.000000000000000,121.000000000000000,0.299712702632539,0.325868379793256,119.000000000000000,0.482285213145440 +0.000000000000000,0.000030000000000,0.000135000000000,0.000312000000000,0.001611000000000,0.000955000000000,0.003094000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,157.000000000000000,121.000000000000000,0.266414418920375,0.325723952270968,121.000000000000000,0.482071463677943 +0.000000000000000,0.000019000000000,0.000134000000000,0.000120000000000,0.000807000000000,0.000746000000000,0.001858000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,52.000000000000000,146.000000000000000,121.000000000000000,0.268513470166789,0.275002624777888,120.000000000000000,0.407003878905728 +0.000000000000000,0.000023000000000,0.000116000000000,0.000137000000000,0.000918000000000,0.000845000000000,0.002086000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,76.000000000000000,141.000000000000000,121.000000000000000,0.291779184224341,0.283057831418736,119.000000000000000,0.418925579815900 +0.000000000000000,0.000020000000000,0.000174000000000,0.000139000000000,0.000841000000000,0.000842000000000,0.002050000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,97.000000000000000,146.000000000000000,121.000000000000000,0.284752630550729,0.313033048850307,118.000000000000000,0.463288905244113 +0.000000000000000,0.000018000000000,0.000125000000000,0.000116000000000,0.000918000000000,0.000737000000000,0.001957000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,108.000000000000000,164.000000000000000,121.000000000000000,0.266984542461140,0.310809088449218,117.000000000000000,0.459997446489587 +0.000000000000000,0.000025000000000,0.000187000000000,0.000215000000000,0.001123000000000,0.000838000000000,0.002412000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,82.000000000000000,172.000000000000000,121.000000000000000,0.281472742741066,0.318106456171594,118.000000000000000,0.470797581856187 +0.000000000000000,0.000032000000000,0.000104000000000,0.000133000000000,0.000982000000000,0.001074000000000,0.002360000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,82.000000000000000,169.000000000000000,121.000000000000000,0.259578544711984,0.296051216412790,118.000000000000000,0.438155829408007 +0.000000000000000,0.000026000000000,0.000173000000000,0.000114000000000,0.000975000000000,0.000678000000000,0.001991000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,87.000000000000000,169.000000000000000,121.000000000000000,0.260854021690335,0.463271429083291,119.000000000000000,0.685641725628487 +0.000000000000000,0.000020000000000,0.000231000000000,0.000213000000000,0.001255000000000,0.000764000000000,0.002547000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,100.000000000000000,162.000000000000000,121.000000000000000,0.224857460689169,0.241819176684415,120.000000000000000,0.357892398925400 +0.000000000000000,0.000016000000000,0.000174000000000,0.000123000000000,0.000964000000000,0.000761000000000,0.002072000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,177.000000000000000,163.000000000000000,121.000000000000000,0.232802572049831,0.307670939545318,121.000000000000000,0.455352982415734 +0.000000000000000,0.000019000000000,0.000171000000000,0.000117000000000,0.000954000000000,0.000685000000000,0.001989000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,215.000000000000000,163.000000000000000,121.000000000000000,0.223503314093231,0.245376537152124,121.000000000000000,0.363157262109869 +0.000000000000000,0.000022000000000,0.000153000000000,0.000321000000000,0.001789000000000,0.000999000000000,0.003323000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,236.000000000000000,160.000000000000000,121.000000000000000,0.238679756461930,0.260245176933572,121.000000000000000,0.385162868349003 +0.000000000000000,0.000017000000000,0.000103000000000,0.000121000000000,0.000950000000000,0.000690000000000,0.001925000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,253.000000000000000,156.000000000000000,121.000000000000000,0.240028083468930,0.347317483304434,119.000000000000000,0.514029864789977 +0.000000000000000,0.000026000000000,0.000155000000000,0.000141000000000,0.001421000000000,0.000834000000000,0.002605000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,225.000000000000000,203.000000000000000,121.000000000000000,0.237050818956117,0.342187690832661,118.000000000000000,0.506437791010399 +0.000000000000000,0.000031000000000,0.000105000000000,0.000133000000000,0.001151000000000,0.000787000000000,0.002244000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,224.000000000000000,192.000000000000000,121.000000000000000,0.228256287503905,0.255917399607126,118.000000000000000,0.378757763709815 +0.000000000000000,0.000029000000000,0.000173000000000,0.000116000000000,0.001046000000000,0.000670000000000,0.002067000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,237.000000000000000,174.000000000000000,121.000000000000000,0.253024524323249,0.270830988595337,117.000000000000000,0.400829860236131 +0.000000000000000,0.000032000000000,0.000206000000000,0.000201000000000,0.001159000000000,0.000767000000000,0.002415000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,243.000000000000000,168.000000000000000,121.000000000000000,0.255837803512081,0.309767343777557,117.000000000000000,0.458455710853014 +0.000000000000000,0.000029000000000,0.000102000000000,0.000134000000000,0.001078000000000,0.000785000000000,0.002160000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,247.000000000000000,176.000000000000000,121.000000000000000,0.242039161090674,0.295753112981567,120.000000000000000,0.437714633120047 +0.000000000000000,0.000018000000000,0.000174000000000,0.000117000000000,0.001043000000000,0.000946000000000,0.002334000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,284.000000000000000,173.000000000000000,121.000000000000000,0.234035474669157,0.262962395172133,120.000000000000000,0.389184330309739 +0.000000000000000,0.000042000000000,0.000251000000000,0.000203000000000,0.001816000000000,0.000807000000000,0.003189000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,323.000000000000000,168.000000000000000,121.000000000000000,0.243963461663248,0.254676688230514,118.000000000000000,0.376921484440742 +0.000000000000000,0.000022000000000,0.000128000000000,0.000121000000000,0.001084000000000,0.000899000000000,0.002287000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,346.000000000000000,164.000000000000000,121.000000000000000,0.237498671286056,0.242318617577444,120.000000000000000,0.358631550548166 +0.000000000000000,0.000042000000000,0.000198000000000,0.000115000000000,0.001158000000000,0.000720000000000,0.002269000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,360.000000000000000,174.000000000000000,121.000000000000000,0.231204372046851,0.310626801011824,119.000000000000000,0.459727694560518 +0.000000000000000,0.000020000000000,0.000128000000000,0.000280000000000,0.000998000000000,0.000883000000000,0.002349000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,371.000000000000000,154.000000000000000,121.000000000000000,0.226372262196515,0.240389813013775,118.000000000000000,0.355776916048274 +0.000000000000000,0.000020000000000,0.000125000000000,0.000116000000000,0.001040000000000,0.000676000000000,0.002025000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,383.000000000000000,163.000000000000000,121.000000000000000,0.243430360339485,0.289701992216838,116.000000000000000,0.428758939836188 +0.000000000000000,0.000028000000000,0.000186000000000,0.000201000000000,0.001357000000000,0.000862000000000,0.002663000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,351.000000000000000,189.000000000000000,121.000000000000000,0.238491256129826,0.289513389727138,119.000000000000000,0.428479837315611 +0.000000000000000,0.000024000000000,0.000104000000000,0.000131000000000,0.001197000000000,0.000689000000000,0.002178000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,351.000000000000000,187.000000000000000,121.000000000000000,0.253535521704090,0.299150905814168,119.000000000000000,0.442743330689269 +0.000000000000000,0.000013000000000,0.000128000000000,0.000142000000000,0.001157000000000,0.000751000000000,0.002226000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,360.000000000000000,182.000000000000000,121.000000000000000,0.242747326189240,0.331002657945821,119.000000000000000,0.489883908154680 +0.000000000000000,0.000041000000000,0.000225000000000,0.000214000000000,0.001614000000000,0.000892000000000,0.003073000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,420.000000000000000,166.000000000000000,121.000000000000000,0.214060199250618,0.291833988602564,120.000000000000000,0.431914284304601 +0.000000000000000,0.000016000000000,0.000113000000000,0.000126000000000,0.001256000000000,0.000871000000000,0.002419000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,467.000000000000000,189.000000000000000,121.000000000000000,0.191542639509251,0.219467558857437,120.000000000000000,0.324811977376153 +0.000000000000000,0.000022000000000,0.000110000000000,0.000116000000000,0.001163000000000,0.000737000000000,0.002178000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,491.000000000000000,176.000000000000000,121.000000000000000,0.237287779136815,0.290385733638894,119.000000000000000,0.429770876012296 +0.000000000000000,0.000016000000000,0.000108000000000,0.000532000000000,0.001507000000000,0.001176000000000,0.003390000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,503.000000000000000,195.000000000000000,121.000000000000000,0.255418654779892,0.271366103996528,119.000000000000000,0.401621830064983 +0.000000000000000,0.000023000000000,0.000128000000000,0.000118000000000,0.001247000000000,0.000704000000000,0.002255000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,519.000000000000000,192.000000000000000,121.000000000000000,0.243354932726649,0.322133765000893,118.000000000000000,0.476758002689501 +0.000000000000000,0.000028000000000,0.000117000000000,0.000194000000000,0.001487000000000,0.000763000000000,0.002640000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,537.000000000000000,182.000000000000000,121.000000000000000,0.256839812012575,0.290001379744665,120.000000000000000,0.429202006242450 +0.000000000000000,0.000021000000000,0.000192000000000,0.000135000000000,0.001268000000000,0.000737000000000,0.002390000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,551.000000000000000,186.000000000000000,121.000000000000000,0.234921062453291,0.278307687859489,121.000000000000000,0.411895400770342 +0.000000000000000,0.000023000000000,0.000110000000000,0.000128000000000,0.001205000000000,0.000853000000000,0.002375000000000,1.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,566.000000000000000,182.000000000000000,121.000000000000000,0.236213436253286,0.243545081705577,120.000000000000000,0.360446727806674 +0.000000000000000,0.000033000000000,0.000148000000000,0.000221000000000,0.001810000000000,0.000752000000000,0.003004000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,523.000000000000000,194.000000000000000,121.000000000000000,0.256770574347429,0.281629144927868,120.000000000000000,0.416811158357270 +0.000000000000000,0.000018000000000,0.000107000000000,0.000166000000000,0.001283000000000,0.000754000000000,0.002364000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,523.000000000000000,193.000000000000000,121.000000000000000,0.238569415669078,0.245006057597332,120.000000000000000,0.362608988913209 +0.000000000000000,0.000026000000000,0.000199000000000,0.000126000000000,0.001415000000000,0.000739000000000,0.002538000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,525.000000000000000,207.000000000000000,121.000000000000000,0.272522903927536,0.292694935292295,120.000000000000000,0.433188542480310 +0.000000000000000,0.000024000000000,0.000152000000000,0.000385000000000,0.001329000000000,0.000772000000000,0.002715000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,532.000000000000000,193.000000000000000,121.000000000000000,0.300157389608362,0.352279544787609,121.000000000000000,0.521373718272822 +0.000000000000000,0.000025000000000,0.000103000000000,0.000124000000000,0.001300000000000,0.000765000000000,0.002352000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,542.000000000000000,192.000000000000000,121.000000000000000,0.262925192895899,0.296136504354747,121.000000000000000,0.438282037121495 +0.000000000000000,0.000027000000000,0.000159000000000,0.000227000000000,0.001454000000000,0.000792000000000,0.002702000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,565.000000000000000,171.000000000000000,121.000000000000000,0.281949830225302,0.308467076957178,121.000000000000000,0.456531258033208 +0.000000000000000,0.000027000000000,0.000177000000000,0.000130000000000,0.001440000000000,0.000817000000000,0.002620000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,608.000000000000000,201.000000000000000,121.000000000000000,0.262127192155801,0.344178587739890,120.000000000000000,0.509384339297628 +0.000000000000000,0.000031000000000,0.000173000000000,0.000122000000000,0.001320000000000,0.000744000000000,0.002429000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,636.000000000000000,196.000000000000000,121.000000000000000,0.243118415564597,0.307364154563702,120.000000000000000,0.454898948018352 +0.000000000000000,0.000031000000000,0.000237000000000,0.000391000000000,0.002601000000000,0.000982000000000,0.004294000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,663.000000000000000,198.000000000000000,121.000000000000000,0.308234194177187,0.324201216218454,120.000000000000000,0.479817768949582 +0.000000000000000,0.000016000000000,0.000102000000000,0.000118000000000,0.001370000000000,0.000653000000000,0.002310000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,687.000000000000000,198.000000000000000,121.000000000000000,0.262171425081880,0.309537417467615,120.000000000000000,0.458115349322126 +0.000000000000000,0.000024000000000,0.000120000000000,0.000223000000000,0.001806000000000,0.000776000000000,0.002976000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,661.000000000000000,229.000000000000000,121.000000000000000,0.297772053023002,0.357203726783215,120.000000000000000,0.528661518750357 +0.000000000000000,0.000022000000000,0.000131000000000,0.000225000000000,0.001322000000000,0.000818000000000,0.002549000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,661.000000000000000,195.000000000000000,121.000000000000000,0.273836774721146,0.292258185663714,119.000000000000000,0.432542138616555 +0.000000000000000,0.000028000000000,0.000189000000000,0.000113000000000,0.001354000000000,0.000656000000000,0.002369000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,668.000000000000000,208.000000000000000,121.000000000000000,0.290291300745150,0.351263582277828,120.000000000000000,0.519870092614610 +0.000000000000000,0.000020000000000,0.000106000000000,0.000362000000000,0.002527000000000,0.000881000000000,0.003941000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,682.000000000000000,211.000000000000000,121.000000000000000,0.258959916330166,0.286061529228379,120.000000000000000,0.423371078465586 +0.000000000000000,0.000023000000000,0.000183000000000,0.000117000000000,0.001452000000000,0.000716000000000,0.002520000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,696.000000000000000,219.000000000000000,121.000000000000000,0.299843168031565,0.306288599781015,118.000000000000000,0.453307123537539 +0.000000000000000,0.000024000000000,0.000190000000000,0.000229000000000,0.001590000000000,0.000704000000000,0.002778000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,704.000000000000000,201.000000000000000,121.000000000000000,0.274895969986079,0.339774469390948,119.000000000000000,0.502866218860539 +0.000000000000000,0.000032000000000,0.000184000000000,0.000127000000000,0.001388000000000,0.000658000000000,0.002422000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,712.000000000000000,205.000000000000000,121.000000000000000,0.276261011279968,0.281429264300083,120.000000000000000,0.416515325859454 +0.000000000000000,0.000019000000000,0.000103000000000,0.000122000000000,0.001302000000000,0.000759000000000,0.002334000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,743.000000000000000,194.000000000000000,121.000000000000000,0.308426080941849,0.293337004748022,118.000000000000000,0.434138764752467 +0.000000000000000,0.000020000000000,0.000188000000000,0.000336000000000,0.002590000000000,0.000953000000000,0.004130000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,769.000000000000000,216.000000000000000,121.000000000000000,0.273447755201539,0.322902569141660,119.000000000000000,0.477895792772933 +0.000000000000000,0.000019000000000,0.000104000000000,0.000118000000000,0.001466000000000,0.000743000000000,0.002480000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,791.000000000000000,204.000000000000000,121.000000000000000,0.288081750238067,0.251959938318303,120.000000000000000,0.372900704820467 +0.000000000000000,0.000024000000000,0.000118000000000,0.000231000000000,0.001575000000000,0.000986000000000,0.003013000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,803.000000000000000,190.000000000000000,121.000000000000000,0.282457846343284,0.276454604943847,117.000000000000000,0.409152821737331 +0.000000000000000,0.000016000000000,0.000210000000000,0.000129000000000,0.001436000000000,0.000881000000000,0.002693000000000,0.000000000000000,111.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,781.000000000000000,208.000000000000000,121.000000000000000,0.294182859046983,0.317841061067694,121.000000000000000,0.470404755925379 +0.000000000000000,0.000015000000000,0.000142000000000,0.000184000000000,0.001424000000000,0.000955000000000,0.002755000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,781.000000000000000,194.000000000000000,121.000000000000000,0.243748783908456,0.304183797141307,119.000000000000000,0.450192011884479 +0.000000000000000,0.000014000000000,0.000107000000000,0.000318000000000,0.001624000000000,0.000893000000000,0.002992000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,803.000000000000000,220.000000000000000,121.000000000000000,0.265012454662619,0.270354981784829,119.000000000000000,0.400125381617550 +0.000000000000000,0.000023000000000,0.000213000000000,0.000128000000000,0.001340000000000,0.000949000000000,0.002681000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,811.000000000000000,196.000000000000000,121.000000000000000,0.253755971722852,0.269982133879470,119.000000000000000,0.399573570359238 +0.000000000000000,0.000038000000000,0.000249000000000,0.000219000000000,0.001747000000000,0.000847000000000,0.003214000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,821.000000000000000,217.000000000000000,121.000000000000000,0.242158110541114,0.277566291448718,118.000000000000000,0.410798121492822 +0.000000000000000,0.000022000000000,0.000200000000000,0.000131000000000,0.001465000000000,0.000761000000000,0.002608000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,826.000000000000000,208.000000000000000,121.000000000000000,0.247025005586580,0.299927107710462,119.000000000000000,0.443892088763821 +0.000000000000000,0.000028000000000,0.000129000000000,0.000115000000000,0.001507000000000,0.000767000000000,0.002582000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,835.000000000000000,206.000000000000000,121.000000000000000,0.251694282278063,0.262688495423133,119.000000000000000,0.388778969531936 +0.000000000000000,0.000018000000000,0.000176000000000,0.000303000000000,0.001569000000000,0.000763000000000,0.002865000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,858.000000000000000,208.000000000000000,121.000000000000000,0.204259521447942,0.239471125876921,121.000000000000000,0.354417264227415 +0.000000000000000,0.000027000000000,0.000197000000000,0.000119000000000,0.001520000000000,0.000717000000000,0.002613000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,887.000000000000000,182.000000000000000,121.000000000000000,0.288688133937508,0.321107040561571,121.000000000000000,0.475238455753857 +0.000000000000000,0.000074000000000,0.000308000000000,0.000231000000000,0.002302000000000,0.000817000000000,0.004009000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,895.000000000000000,169.000000000000000,121.000000000000000,0.226466756684178,0.283662806855079,120.000000000000000,0.419820962132456 +0.000000000000000,0.000032000000000,0.000120000000000,0.000146000000000,0.001779000000000,0.000719000000000,0.002820000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,887.000000000000000,201.000000000000000,121.000000000000000,0.248964133477333,0.301424345755280,121.000000000000000,0.446108027319984 +0.000000000000000,0.000031000000000,0.000209000000000,0.000347000000000,0.002379000000000,0.001268000000000,0.004286000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,881.000000000000000,197.000000000000000,121.000000000000000,0.197089987231914,0.215315450958625,121.000000000000000,0.318666844452755 +0.000000000000000,0.000022000000000,0.000183000000000,0.000138000000000,0.001523000000000,0.000904000000000,0.002805000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,889.000000000000000,208.000000000000000,121.000000000000000,0.211913610123421,0.217730864556872,121.000000000000000,0.322241701945577 +0.000000000000000,0.000023000000000,0.000188000000000,0.000135000000000,0.001539000000000,0.001010000000000,0.002927000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,912.000000000000000,191.000000000000000,121.000000000000000,0.223781553150169,0.264534665335954,119.000000000000000,0.391511288186158 +0.000000000000000,0.000024000000000,0.000111000000000,0.000561000000000,0.002319000000000,0.001083000000000,0.004153000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,959.000000000000000,191.000000000000000,121.000000000000000,0.192480342616366,0.242812113218322,120.000000000000000,0.359361932832411 +0.000000000000000,0.000023000000000,0.000113000000000,0.000129000000000,0.001473000000000,0.000780000000000,0.002555000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1010.000000000000000,186.000000000000000,121.000000000000000,0.226239188570666,0.246580462159093,121.000000000000000,0.364939080501376 +0.000000000000000,0.000025000000000,0.000147000000000,0.000235000000000,0.001877000000000,0.001081000000000,0.003415000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1042.000000000000000,191.000000000000000,121.000000000000000,0.213010810373553,0.226959616128893,121.000000000000000,0.335900212048673 +0.000000000000000,0.000019000000000,0.000180000000000,0.000123000000000,0.001581000000000,0.000797000000000,0.002856000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1066.000000000000000,197.000000000000000,121.000000000000000,0.236500218717681,0.308339991149568,118.000000000000000,0.456343184784554 +0.000000000000000,0.000020000000000,0.000176000000000,0.000124000000000,0.001670000000000,0.001020000000000,0.003039000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1045.000000000000000,222.000000000000000,121.000000000000000,0.203403550946325,0.322649020817046,119.000000000000000,0.477520556062907 +0.000000000000000,0.000021000000000,0.000102000000000,0.000120000000000,0.001506000000000,0.000747000000000,0.002537000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1040.000000000000000,208.000000000000000,121.000000000000000,0.217457541731394,0.242874100604298,119.000000000000000,0.359453694988533 +0.000000000000000,0.000014000000000,0.000102000000000,0.000114000000000,0.001438000000000,0.000775000000000,0.002481000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,202.000000000000000,121.000000000000000,0.237066555963892,0.363698547046353,120.000000000000000,0.538273825733024 +0.000000000000000,0.000028000000000,0.000138000000000,0.000130000000000,0.001867000000000,0.000905000000000,0.003190000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1051.000000000000000,204.000000000000000,121.000000000000000,0.204004037194742,0.217771792656962,121.000000000000000,0.322302253343558 +0.000000000000000,0.000016000000000,0.000108000000000,0.000146000000000,0.001730000000000,0.000807000000000,0.002848000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1092.000000000000000,216.000000000000000,121.000000000000000,0.189498788663577,0.218460412109291,119.000000000000000,0.323321417274184 +0.000000000000000,0.000021000000000,0.000142000000000,0.000136000000000,0.001571000000000,0.000950000000000,0.002860000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1150.000000000000000,195.000000000000000,121.000000000000000,0.234911243099688,0.229840840010708,121.000000000000000,0.340164460854319 +0.000000000000000,0.000023000000000,0.000178000000000,0.000327000000000,0.001509000000000,0.001060000000000,0.003143000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1188.000000000000000,188.000000000000000,121.000000000000000,0.238938910296195,0.242239031677996,119.000000000000000,0.358513758367035 +0.000000000000000,0.000026000000000,0.000127000000000,0.000121000000000,0.001413000000000,0.000746000000000,0.002666000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1209.000000000000000,181.000000000000000,121.000000000000000,0.231069770120829,0.351821144360750,121.000000000000000,0.520695269679250 +0.000000000000000,0.000013000000000,0.000123000000000,0.000156000000000,0.002291000000000,0.000810000000000,0.003493000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1131.000000000000000,223.000000000000000,121.000000000000000,0.232050436410629,0.243086413240903,121.000000000000000,0.359767900135068 +0.000000000000000,0.000017000000000,0.000183000000000,0.000122000000000,0.001660000000000,0.000828000000000,0.002856000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1126.000000000000000,205.000000000000000,121.000000000000000,0.217672407670591,0.232176089084970,120.000000000000000,0.343620616378729 +0.000000000000000,0.000025000000000,0.000104000000000,0.000126000000000,0.001640000000000,0.000956000000000,0.002894000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1122.000000000000000,225.000000000000000,121.000000000000000,0.210874531577464,0.231177462797771,120.000000000000000,0.342142641667492 +0.000000000000000,0.000011000000000,0.000104000000000,0.000149000000000,0.001579000000000,0.000928000000000,0.002811000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1124.000000000000000,218.000000000000000,121.000000000000000,0.199068638688048,0.231930228681434,121.000000000000000,0.343256752009726 +0.000000000000000,0.000016000000000,0.000105000000000,0.000114000000000,0.001529000000000,0.000835000000000,0.002636000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1131.000000000000000,217.000000000000000,121.000000000000000,0.199461859922069,0.201973412653913,121.000000000000000,0.298920644384362 +0.000000000000000,0.000020000000000,0.000107000000000,0.000175000000000,0.002271000000000,0.000832000000000,0.003453000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1170.000000000000000,216.000000000000000,121.000000000000000,0.220686177070489,0.284068818474203,121.000000000000000,0.420421851360250 +0.000000000000000,0.000021000000000,0.000110000000000,0.000115000000000,0.001720000000000,0.000987000000000,0.002996000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1207.000000000000000,220.000000000000000,121.000000000000000,0.211157109658996,0.207022193542394,121.000000000000000,0.306392853689555 +0.000000000000000,0.000019000000000,0.000128000000000,0.000124000000000,0.001660000000000,0.000836000000000,0.002805000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1249.000000000000000,230.000000000000000,121.000000000000000,0.227298389602018,0.273505984323976,121.000000000000000,0.404788875408716 +0.000000000000000,0.000019000000000,0.000103000000000,0.000135000000000,0.001696000000000,0.000751000000000,0.002919000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,235.000000000000000,121.000000000000000,0.230641563123264,0.341660758731761,121.000000000000000,0.505657951678639 +0.000000000000000,0.000015000000000,0.000177000000000,0.000130000000000,0.001556000000000,0.000919000000000,0.002864000000000,0.000000000000000,106.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1118.000000000000000,225.000000000000000,121.000000000000000,0.192303276106424,0.284766422639249,121.000000000000000,0.421454308293938 +0.000000000000000,0.000013000000000,0.000138000000000,0.000178000000000,0.002041000000000,0.000992000000000,0.003412000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1112.000000000000000,223.000000000000000,121.000000000000000,0.206634709237684,0.414844586254086,120.000000000000000,0.613969997701391 +0.000000000000000,0.000015000000000,0.000134000000000,0.000127000000000,0.001905000000000,0.000764000000000,0.002995000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1116.000000000000000,248.000000000000000,121.000000000000000,0.217282816286385,0.386388750278064,121.000000000000000,0.571855388443357 +0.000000000000000,0.000016000000000,0.000128000000000,0.000127000000000,0.001825000000000,0.000925000000000,0.003066000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1115.000000000000000,245.000000000000000,121.000000000000000,0.205232081617916,0.260414398266005,121.000000000000000,0.385413312570202 +0.000000000000000,0.000020000000000,0.000107000000000,0.000141000000000,0.001807000000000,0.000923000000000,0.003060000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1141.000000000000000,234.000000000000000,121.000000000000000,0.215575249362573,0.253408200953891,120.000000000000000,0.375044163656510 +0.000000000000000,0.000019000000000,0.000128000000000,0.000120000000000,0.001568000000000,0.000884000000000,0.002762000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1162.000000000000000,189.000000000000000,121.000000000000000,0.263382144346756,0.344167879309156,121.000000000000000,0.509368468563933 +0.000000000000000,0.000023000000000,0.000131000000000,0.000373000000000,0.001757000000000,0.001182000000000,0.003515000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1191.000000000000000,211.000000000000000,121.000000000000000,0.211945557067404,0.302128504397490,121.000000000000000,0.447150188651345 +0.000000000000000,0.000025000000000,0.000154000000000,0.000124000000000,0.001844000000000,0.000803000000000,0.003004000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1216.000000000000000,227.000000000000000,121.000000000000000,0.202381916559221,0.390013881008811,120.000000000000000,0.577220555675650 +0.000000000000000,0.000015000000000,0.000109000000000,0.000129000000000,0.001708000000000,0.000890000000000,0.002894000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1231.000000000000000,213.000000000000000,121.000000000000000,0.214162701863959,0.216971594768139,120.000000000000000,0.321117988293146 +0.000000000000000,0.000019000000000,0.000106000000000,0.000141000000000,0.001738000000000,0.000788000000000,0.002834000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,223.000000000000000,121.000000000000000,0.199426583525084,0.257295226754736,121.000000000000000,0.380796925542741 +0.000000000000000,0.000015000000000,0.000104000000000,0.000127000000000,0.001749000000000,0.000817000000000,0.002854000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,237.000000000000000,121.000000000000000,0.197980287517504,0.261753748672962,121.000000000000000,0.387395536882405 +0.000000000000000,0.000022000000000,0.000120000000000,0.000159000000000,0.002300000000000,0.000963000000000,0.003628000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1233.000000000000000,228.000000000000000,121.000000000000000,0.236498759179881,0.240201532654298,121.000000000000000,0.355498268421338 +0.000000000000000,0.000017000000000,0.000181000000000,0.000128000000000,0.001959000000000,0.000872000000000,0.003382000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,248.000000000000000,121.000000000000000,0.184287569106640,0.201686577196243,121.000000000000000,0.298496127529902 +0.000000000000000,0.000013000000000,0.000178000000000,0.000136000000000,0.001684000000000,0.000852000000000,0.002943000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1105.000000000000000,230.000000000000000,121.000000000000000,0.190585604418642,0.200521952748998,120.000000000000000,0.296772510252565 +0.000000000000000,0.000019000000000,0.000106000000000,0.000143000000000,0.001668000000000,0.000981000000000,0.002955000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1104.000000000000000,218.000000000000000,121.000000000000000,0.200527511479873,0.209064190915326,120.000000000000000,0.309415015408653 +0.000000000000000,0.000014000000000,0.000104000000000,0.000123000000000,0.001517000000000,0.000849000000000,0.002647000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1144.000000000000000,201.000000000000000,121.000000000000000,0.227018266784565,0.269186250934732,121.000000000000000,0.398395648547930 +0.000000000000000,0.000017000000000,0.000178000000000,0.000348000000000,0.001620000000000,0.001141000000000,0.003354000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1182.000000000000000,206.000000000000000,121.000000000000000,0.206456021778136,0.213075158345683,121.000000000000000,0.315351251063391 +0.000000000000000,0.000026000000000,0.000108000000000,0.000150000000000,0.001619000000000,0.000821000000000,0.002770000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1214.000000000000000,197.000000000000000,121.000000000000000,0.195769620795380,0.235699009656539,120.000000000000000,0.348834556747284 +0.000000000000000,0.000018000000000,0.000178000000000,0.000127000000000,0.001593000000000,0.000826000000000,0.002776000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,206.000000000000000,121.000000000000000,0.202443810598108,0.259322628022743,121.000000000000000,0.383797505085764 +0.000000000000000,0.000018000000000,0.000105000000000,0.000140000000000,0.001539000000000,0.001030000000000,0.002870000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1255.000000000000000,195.000000000000000,121.000000000000000,0.234795060265796,0.251596569636394,120.000000000000000,0.372362919449417 +0.000000000000000,0.000017000000000,0.000175000000000,0.000125000000000,0.001584000000000,0.000833000000000,0.002923000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1267.000000000000000,221.000000000000000,121.000000000000000,0.207163879614002,0.272216719799699,121.000000000000000,0.402880748216245 +0.000000000000000,0.000017000000000,0.000133000000000,0.000153000000000,0.002442000000000,0.000831000000000,0.003670000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1147.000000000000000,216.000000000000000,121.000000000000000,0.170524915168911,0.199849692332816,121.000000000000000,0.295777531500515 +0.000000000000000,0.000013000000000,0.000157000000000,0.000149000000000,0.001748000000000,0.000942000000000,0.003057000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1147.000000000000000,234.000000000000000,121.000000000000000,0.189221335752284,0.197743002271810,121.000000000000000,0.292659639941872 +0.000000000000000,0.000020000000000,0.000178000000000,0.000125000000000,0.001721000000000,0.000742000000000,0.002827000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1176.000000000000000,225.000000000000000,121.000000000000000,0.198900978356214,0.245389821232497,119.000000000000000,0.363176948895773 +0.000000000000000,0.000013000000000,0.000176000000000,0.000145000000000,0.001697000000000,0.000855000000000,0.002929000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1221.000000000000000,222.000000000000000,121.000000000000000,0.196051895442564,0.262432687056220,121.000000000000000,0.388400396935210 +0.000000000000000,0.000015000000000,0.000176000000000,0.000128000000000,0.001658000000000,0.000736000000000,0.002754000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1264.000000000000000,222.000000000000000,121.000000000000000,0.188130722176495,0.226906201366918,120.000000000000000,0.335821186914497 +0.000000000000000,0.000015000000000,0.000114000000000,0.000128000000000,0.001732000000000,0.000994000000000,0.003025000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1280.000000000000000,221.000000000000000,121.000000000000000,0.195205519657246,0.208004184809569,119.000000000000000,0.307846188328575 +0.000000000000000,0.000020000000000,0.000195000000000,0.000126000000000,0.002006000000000,0.000791000000000,0.003194000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1295.000000000000000,262.000000000000000,121.000000000000000,0.204929539974912,0.216820480192029,119.000000000000000,0.320894306981155 +0.000000000000000,0.000017000000000,0.000176000000000,0.000139000000000,0.001546000000000,0.000896000000000,0.002812000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1303.000000000000000,192.000000000000000,121.000000000000000,0.226704780607630,0.257512342665443,120.000000000000000,0.381118257356317 +0.000000000000000,0.000011000000000,0.000105000000000,0.000299000000000,0.001761000000000,0.001102000000000,0.003328000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1303.000000000000000,234.000000000000000,121.000000000000000,0.206579202251784,0.240623999885611,121.000000000000000,0.356123519730790 +0.000000000000000,0.000020000000000,0.000103000000000,0.000130000000000,0.001498000000000,0.000871000000000,0.002766000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1312.000000000000000,207.000000000000000,121.000000000000000,0.208586912880041,0.214158703806542,121.000000000000000,0.316954877506999 +0.000000000000000,0.000017000000000,0.000176000000000,0.000374000000000,0.001665000000000,0.000976000000000,0.003373000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1139.000000000000000,223.000000000000000,121.000000000000000,0.209543770412094,0.213150938854858,121.000000000000000,0.315463382345879 +0.000000000000000,0.000021000000000,0.000157000000000,0.000124000000000,0.001652000000000,0.000947000000000,0.002947000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1137.000000000000000,212.000000000000000,121.000000000000000,0.214888927283406,0.261239649375707,120.000000000000000,0.386634701996087 +0.000000000000000,0.000018000000000,0.000104000000000,0.000124000000000,0.001479000000000,0.000897000000000,0.002661000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1182.000000000000000,188.000000000000000,121.000000000000000,0.205526459876717,0.194046988139053,121.000000000000000,0.287189543909738 +0.000000000000000,0.000016000000000,0.000175000000000,0.000142000000000,0.001509000000000,0.000744000000000,0.002626000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,190.000000000000000,121.000000000000000,0.193638964960760,0.209501566643394,121.000000000000000,0.310062329059690 +0.000000000000000,0.000022000000000,0.000103000000000,0.000125000000000,0.001561000000000,0.000725000000000,0.002572000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1250.000000000000000,218.000000000000000,121.000000000000000,0.192895828207804,0.213686959411965,121.000000000000000,0.316256716855654 +0.000000000000000,0.000023000000000,0.000184000000000,0.000162000000000,0.001899000000000,0.000812000000000,0.003140000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1258.000000000000000,187.000000000000000,121.000000000000000,0.178433372351327,0.196124969530122,120.000000000000000,0.290264953456693 +0.000000000000000,0.000016000000000,0.000134000000000,0.000140000000000,0.001663000000000,0.000876000000000,0.002874000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1274.000000000000000,203.000000000000000,121.000000000000000,0.204379056805537,0.211513754780143,119.000000000000000,0.313040366095618 +0.000000000000000,0.000020000000000,0.000176000000000,0.000130000000000,0.001587000000000,0.000869000000000,0.002823000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1284.000000000000000,206.000000000000000,121.000000000000000,0.194394953473234,0.214318086264921,121.000000000000000,0.317190765131688 +0.000000000000000,0.000017000000000,0.000107000000000,0.000148000000000,0.001575000000000,0.000805000000000,0.002693000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1286.000000000000000,205.000000000000000,121.000000000000000,0.192692252511560,0.217301832678175,121.000000000000000,0.321606720966583 +0.000000000000000,0.000020000000000,0.000173000000000,0.000124000000000,0.001507000000000,0.000785000000000,0.002649000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,210.000000000000000,121.000000000000000,0.204881580167579,0.231890569564824,121.000000000000000,0.343198045458178 +0.000000000000000,0.000041000000000,0.000220000000000,0.000144000000000,0.001900000000000,0.000655000000000,0.003038000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,206.000000000000000,121.000000000000000,0.174115401194611,0.223973720218107,121.000000000000000,0.331481122502030 +0.000000000000000,0.000043000000000,0.000182000000000,0.000145000000000,0.001457000000000,0.000728000000000,0.002734000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1272.000000000000000,191.000000000000000,121.000000000000000,0.194538477548438,0.187220557909554,121.000000000000000,0.277086431960381 +0.000000000000000,0.000020000000000,0.000182000000000,0.000129000000000,0.001451000000000,0.000813000000000,0.002657000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1148.000000000000000,207.000000000000000,121.000000000000000,0.209547468410092,0.205381330935579,119.000000000000000,0.303964378715603 +0.000000000000000,0.000037000000000,0.000255000000000,0.000211000000000,0.002943000000000,0.001198000000000,0.004740000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1146.000000000000000,192.000000000000000,121.000000000000000,0.194112090334278,0.213834860708738,121.000000000000000,0.316475596512546 +0.000000000000000,0.000021000000000,0.000119000000000,0.000128000000000,0.001482000000000,0.000836000000000,0.002622000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1196.000000000000000,188.000000000000000,121.000000000000000,0.194707145965396,0.200711676435348,120.000000000000000,0.297053280716492 +0.000000000000000,0.000018000000000,0.000128000000000,0.000353000000000,0.001530000000000,0.001123000000000,0.003198000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1222.000000000000000,182.000000000000000,121.000000000000000,0.165297929068422,0.223118899091734,120.000000000000000,0.330215962199139 +0.000000000000000,0.000019000000000,0.000133000000000,0.000124000000000,0.001554000000000,0.001016000000000,0.002890000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1250.000000000000000,187.000000000000000,121.000000000000000,0.189732092265728,0.231665076279646,121.000000000000000,0.342864305156952 +0.000000000000000,0.000018000000000,0.000195000000000,0.000130000000000,0.001387000000000,0.000871000000000,0.002639000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,167.000000000000000,121.000000000000000,0.173396135722069,0.185374303680201,121.000000000000000,0.274353961674946 +0.000000000000000,0.000015000000000,0.000105000000000,0.000165000000000,0.001566000000000,0.001052000000000,0.002950000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1292.000000000000000,196.000000000000000,121.000000000000000,0.192868888286218,0.205034141945327,120.000000000000000,0.303450551076308 +0.000000000000000,0.000014000000000,0.000102000000000,0.000127000000000,0.001521000000000,0.000791000000000,0.002592000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1302.000000000000000,199.000000000000000,121.000000000000000,0.190528673137881,0.222906754530888,121.000000000000000,0.329902009771293 +0.000000000000000,0.000021000000000,0.000215000000000,0.000167000000000,0.001934000000000,0.000805000000000,0.003204000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1308.000000000000000,190.000000000000000,121.000000000000000,0.202526348712512,0.259278841345545,120.000000000000000,0.383732682741932 +0.000000000000000,0.000022000000000,0.000156000000000,0.000126000000000,0.001696000000000,0.000788000000000,0.002834000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1308.000000000000000,190.000000000000000,121.000000000000000,0.196451913404442,0.201069768524068,120.000000000000000,0.297583282351909 +0.000000000000000,0.000025000000000,0.000103000000000,0.000132000000000,0.001543000000000,0.000902000000000,0.002745000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1305.000000000000000,194.000000000000000,121.000000000000000,0.200871633124814,0.183908150343481,120.000000000000000,0.272184068463992 +0.000000000000000,0.000025000000000,0.000102000000000,0.000150000000000,0.001478000000000,0.000854000000000,0.002788000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1335.000000000000000,179.000000000000000,121.000000000000000,0.193823047570574,0.212329442302877,119.000000000000000,0.314247578003029 +0.000000000000000,0.000016000000000,0.000196000000000,0.000126000000000,0.001299000000000,0.000752000000000,0.002455000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1194.000000000000000,176.000000000000000,121.000000000000000,0.207923081779578,0.229508478265270,121.000000000000000,0.339672543925396 +0.000000000000000,0.000018000000000,0.000110000000000,0.000166000000000,0.001844000000000,0.000982000000000,0.003170000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1189.000000000000000,180.000000000000000,121.000000000000000,0.163342705330096,0.249575746286056,120.000000000000000,0.369372120119674 +0.000000000000000,0.000015000000000,0.000183000000000,0.000124000000000,0.001749000000000,0.000847000000000,0.002963000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1218.000000000000000,212.000000000000000,121.000000000000000,0.173881865983057,0.194395754595030,121.000000000000000,0.287705721832844 +0.000000000000000,0.000026000000000,0.000176000000000,0.000127000000000,0.001498000000000,0.000877000000000,0.002752000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1259.000000000000000,185.000000000000000,121.000000000000000,0.155523040470466,0.162766723518840,120.000000000000000,0.240894740082153 +0.000000000000000,0.000015000000000,0.000177000000000,0.000144000000000,0.001550000000000,0.000743000000000,0.002669000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,192.000000000000000,121.000000000000000,0.152934150143871,0.272911472202902,121.000000000000000,0.403908984747820 +0.000000000000000,0.000014000000000,0.000174000000000,0.000116000000000,0.001439000000000,0.000731000000000,0.002513000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1291.000000000000000,196.000000000000000,121.000000000000000,0.188113809380047,0.184618919088813,121.000000000000000,0.273236010008633 +0.000000000000000,0.000016000000000,0.000106000000000,0.000145000000000,0.002198000000000,0.000804000000000,0.003318000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1299.000000000000000,184.000000000000000,121.000000000000000,0.189391540723312,0.210953756830538,121.000000000000000,0.312211549881851 +0.000000000000000,0.000019000000000,0.000181000000000,0.000116000000000,0.001662000000000,0.000840000000000,0.002865000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1306.000000000000000,204.000000000000000,121.000000000000000,0.184488742976474,0.215925329354907,121.000000000000000,0.319569479795696 +0.000000000000000,0.000016000000000,0.000183000000000,0.000132000000000,0.001540000000000,0.000737000000000,0.002647000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1313.000000000000000,197.000000000000000,121.000000000000000,0.164667840588859,0.233194073999862,121.000000000000000,0.345127224117476 +0.000000000000000,0.000017000000000,0.000177000000000,0.000144000000000,0.001453000000000,0.000747000000000,0.002725000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1307.000000000000000,179.000000000000000,121.000000000000000,0.190996220324968,0.267097150771334,121.000000000000000,0.395303787014294 +0.000000000000000,0.000017000000000,0.000177000000000,0.000120000000000,0.001414000000000,0.000681000000000,0.002474000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1109.000000000000000,205.000000000000000,121.000000000000000,0.175048358387321,0.227273301247532,121.000000000000000,0.336364481552976 +0.000000000000000,0.000023000000000,0.000186000000000,0.000160000000000,0.001932000000000,0.000738000000000,0.003097000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1100.000000000000000,194.000000000000000,121.000000000000000,0.173557283673669,0.191658131610694,121.000000000000000,0.283654034716855 +0.000000000000000,0.000019000000000,0.000107000000000,0.000116000000000,0.001671000000000,0.000745000000000,0.002708000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1144.000000000000000,204.000000000000000,121.000000000000000,0.158568907261423,0.243359531069700,121.000000000000000,0.360172098406900 +0.000000000000000,0.000018000000000,0.000103000000000,0.000132000000000,0.001512000000000,0.000732000000000,0.002547000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1187.000000000000000,194.000000000000000,121.000000000000000,0.146749823653506,0.164413086505490,121.000000000000000,0.243331352597904 +0.000000000000000,0.000014000000000,0.000181000000000,0.000144000000000,0.001537000000000,0.000892000000000,0.002808000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1214.000000000000000,196.000000000000000,121.000000000000000,0.131283592229348,0.155956326816494,121.000000000000000,0.230815358417731 +0.000000000000000,0.000012000000000,0.000176000000000,0.000121000000000,0.001482000000000,0.000877000000000,0.002705000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,196.000000000000000,121.000000000000000,0.159033296053125,0.194395333842714,121.000000000000000,0.287705090036121 +0.000000000000000,0.000020000000000,0.000211000000000,0.000162000000000,0.001881000000000,0.000840000000000,0.003174000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1262.000000000000000,184.000000000000000,121.000000000000000,0.163845159646448,0.177604150932044,121.000000000000000,0.262854149344864 +0.000000000000000,0.000015000000000,0.000115000000000,0.000124000000000,0.001771000000000,0.000924000000000,0.002997000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1269.000000000000000,218.000000000000000,121.000000000000000,0.167741708685618,0.187775885781358,121.000000000000000,0.277908323682058 +0.000000000000000,0.000012000000000,0.000104000000000,0.000127000000000,0.001764000000000,0.000780000000000,0.002830000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,229.000000000000000,121.000000000000000,0.186347950475868,0.251813866360726,121.000000000000000,0.372684503981683 +0.000000000000000,0.000020000000000,0.000102000000000,0.000142000000000,0.001444000000000,0.000872000000000,0.002621000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1275.000000000000000,174.000000000000000,121.000000000000000,0.166303486197133,0.189747084068580,120.000000000000000,0.280825682960661 +0.000000000000000,0.000016000000000,0.000125000000000,0.000117000000000,0.001504000000000,0.000769000000000,0.002568000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,202.000000000000000,121.000000000000000,0.167769122437661,0.195787376215580,121.000000000000000,0.289765303335874 +0.000000000000000,0.000029000000000,0.000158000000000,0.000154000000000,0.001818000000000,0.000771000000000,0.003044000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1304.000000000000000,177.000000000000000,121.000000000000000,0.158463858246833,0.191255881763862,119.000000000000000,0.283058705300228 +0.000000000000000,0.000020000000000,0.000185000000000,0.000118000000000,0.001683000000000,0.000786000000000,0.002860000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1339.000000000000000,206.000000000000000,121.000000000000000,0.161183566619254,0.178028171732775,121.000000000000000,0.263481700394391 +0.000000000000000,0.000017000000000,0.000177000000000,0.000136000000000,0.001597000000000,0.000782000000000,0.002874000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1383.000000000000000,198.000000000000000,121.000000000000000,0.142916686874711,0.162123928033689,121.000000000000000,0.239943431119633 +0.000000000000000,0.000016000000000,0.000127000000000,0.000234000000000,0.001629000000000,0.000716000000000,0.002906000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,214.000000000000000,121.000000000000000,0.154355717762879,0.218609409653489,121.000000000000000,0.323541914330688 +0.000000000000000,0.000018000000000,0.000175000000000,0.000117000000000,0.001623000000000,0.000874000000000,0.002848000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1218.000000000000000,227.000000000000000,121.000000000000000,0.174558038196839,0.199124535422790,121.000000000000000,0.294704311042227 +0.000000000000000,0.000023000000000,0.000101000000000,0.000109000000000,0.001533000000000,0.000703000000000,0.002504000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1228.000000000000000,215.000000000000000,121.000000000000000,0.137995003938898,0.152632389051692,121.000000000000000,0.225895936409808 +0.000000000000000,0.000027000000000,0.000177000000000,0.000139000000000,0.001775000000000,0.000662000000000,0.002820000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1232.000000000000000,237.000000000000000,121.000000000000000,0.135541904251767,0.167668386817417,121.000000000000000,0.248149206964557 +0.000000000000000,0.000022000000000,0.000181000000000,0.000307000000000,0.001635000000000,0.001033000000000,0.003237000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1233.000000000000000,200.000000000000000,121.000000000000000,0.163536557849499,0.206044880204936,121.000000000000000,0.304946443542624 +0.000000000000000,0.000013000000000,0.000197000000000,0.000138000000000,0.001693000000000,0.000665000000000,0.002750000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1227.000000000000000,224.000000000000000,121.000000000000000,0.153373223673703,0.199555553830275,120.000000000000000,0.295342223558018 +0.000000000000000,0.000022000000000,0.000130000000000,0.000127000000000,0.001747000000000,0.000744000000000,0.002816000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,234.000000000000000,121.000000000000000,0.139032943637894,0.186670354479152,121.000000000000000,0.276272121799386 +0.000000000000000,0.000023000000000,0.000189000000000,0.000117000000000,0.001436000000000,0.000905000000000,0.002707000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,191.000000000000000,121.000000000000000,0.139072087006321,0.170137357542569,121.000000000000000,0.251803291766507 +0.000000000000000,0.000019000000000,0.000189000000000,0.000134000000000,0.001636000000000,0.001043000000000,0.003059000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1226.000000000000000,205.000000000000000,121.000000000000000,0.147221191440148,0.219839242753776,121.000000000000000,0.325362095419246 +0.000000000000000,0.000026000000000,0.000136000000000,0.000141000000000,0.001640000000000,0.000834000000000,0.002814000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1226.000000000000000,198.000000000000000,121.000000000000000,0.134535729635055,0.177361976863745,120.000000000000000,0.262495743699553 +0.000000000000000,0.000024000000000,0.000188000000000,0.000137000000000,0.001576000000000,0.000999000000000,0.002968000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1224.000000000000000,202.000000000000000,121.000000000000000,0.150440594097383,0.170822892372034,120.000000000000000,0.252817881488855 +0.000000000000000,0.000018000000000,0.000128000000000,0.000123000000000,0.001595000000000,0.000906000000000,0.002923000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,211.000000000000000,121.000000000000000,0.161157776486683,0.176850558454008,121.000000000000000,0.261738825952921 +0.000000000000000,0.000023000000000,0.000171000000000,0.000136000000000,0.001546000000000,0.000836000000000,0.002772000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1094.000000000000000,211.000000000000000,121.000000000000000,0.135044752661059,0.176661372259443,121.000000000000000,0.261458838916931 +0.000000000000000,0.000016000000000,0.000180000000000,0.000129000000000,0.001692000000000,0.000849000000000,0.002919000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1089.000000000000000,203.000000000000000,121.000000000000000,0.143949354754192,0.167668782751111,120.000000000000000,0.248149788217542 +0.000000000000000,0.000017000000000,0.000108000000000,0.000139000000000,0.001568000000000,0.000704000000000,0.002578000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1166.000000000000000,200.000000000000000,121.000000000000000,0.155160670749007,0.231930876186467,120.000000000000000,0.343257712340746 +0.000000000000000,0.000035000000000,0.000227000000000,0.000132000000000,0.001664000000000,0.000790000000000,0.002968000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1216.000000000000000,195.000000000000000,121.000000000000000,0.133676069237326,0.147626375091364,120.000000000000000,0.218487058408179 +0.000000000000000,0.000015000000000,0.000128000000000,0.000120000000000,0.001551000000000,0.000732000000000,0.002590000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1232.000000000000000,204.000000000000000,121.000000000000000,0.122400626475427,0.146223124911287,121.000000000000000,0.216410216218663 +0.000000000000000,0.000020000000000,0.000245000000000,0.000118000000000,0.001618000000000,0.000770000000000,0.002815000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1238.000000000000000,219.000000000000000,121.000000000000000,0.137303784430655,0.150577933818061,121.000000000000000,0.222855351498252 +0.000000000000000,0.000016000000000,0.000214000000000,0.000131000000000,0.001570000000000,0.000888000000000,0.002875000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1239.000000000000000,183.000000000000000,121.000000000000000,0.131464957645487,0.148026075188344,121.000000000000000,0.219078597044465 +0.000000000000000,0.000018000000000,0.000103000000000,0.000139000000000,0.001556000000000,0.000929000000000,0.002796000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,197.000000000000000,121.000000000000000,0.128347170794260,0.131002024287506,121.000000000000000,0.193882998604601 +0.000000000000000,0.000034000000000,0.000281000000000,0.000139000000000,0.001662000000000,0.000725000000000,0.002956000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1226.000000000000000,194.000000000000000,121.000000000000000,0.162024538919116,0.207094523301695,121.000000000000000,0.306499905326386 +0.000000000000000,0.000019000000000,0.000198000000000,0.000119000000000,0.001621000000000,0.000844000000000,0.002973000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,215.000000000000000,121.000000000000000,0.153235488057770,0.262436341625619,121.000000000000000,0.388405779843294 +0.000000000000000,0.000021000000000,0.000198000000000,0.000131000000000,0.001561000000000,0.000847000000000,0.002828000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1054.000000000000000,201.000000000000000,121.000000000000000,0.157919685289792,0.167838875425546,121.000000000000000,0.248401521304057 +0.000000000000000,0.000015000000000,0.000170000000000,0.000130000000000,0.001648000000000,0.000666000000000,0.002683000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,211.000000000000000,121.000000000000000,0.142424009465490,0.209332762567431,120.000000000000000,0.309812491363346 +0.000000000000000,0.000020000000000,0.000127000000000,0.000139000000000,0.001528000000000,0.000726000000000,0.002588000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1039.000000000000000,207.000000000000000,121.000000000000000,0.140603779602412,0.159626649619649,121.000000000000000,0.236247445558979 +0.000000000000000,0.000019000000000,0.000194000000000,0.000143000000000,0.001999000000000,0.000624000000000,0.003025000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1040.000000000000000,205.000000000000000,121.000000000000000,0.147458908627836,0.237281094131071,121.000000000000000,0.351176020676474 +0.000000000000000,0.000022000000000,0.000175000000000,0.000126000000000,0.001454000000000,0.000837000000000,0.002656000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1106.000000000000000,198.000000000000000,121.000000000000000,0.125862132363062,0.146166756283214,120.000000000000000,0.216326793779291 +0.000000000000000,0.000018000000000,0.000233000000000,0.000119000000000,0.001470000000000,0.000923000000000,0.002807000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1145.000000000000000,188.000000000000000,121.000000000000000,0.148866800739627,0.175671536734951,121.000000000000000,0.259993879218198 +0.000000000000000,0.000021000000000,0.000205000000000,0.000128000000000,0.001543000000000,0.000761000000000,0.002708000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1156.000000000000000,186.000000000000000,121.000000000000000,0.127848678819928,0.170790549426913,121.000000000000000,0.252770016569082 +0.000000000000000,0.000016000000000,0.000176000000000,0.000145000000000,0.001515000000000,0.000719000000000,0.002758000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1165.000000000000000,189.000000000000000,121.000000000000000,0.145912191034524,0.246210134411681,121.000000000000000,0.364391034751536 +0.000000000000000,0.000017000000000,0.000137000000000,0.000142000000000,0.001535000000000,0.000625000000000,0.002544000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1007.000000000000000,197.000000000000000,121.000000000000000,0.155415123408675,0.250107101898265,121.000000000000000,0.370158504865490 +0.000000000000000,0.000018000000000,0.000187000000000,0.000129000000000,0.001485000000000,0.000745000000000,0.002609000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,997.000000000000000,196.000000000000000,121.000000000000000,0.156330994449520,0.195977327324711,121.000000000000000,0.290046452877835 +0.000000000000000,0.000027000000000,0.000216000000000,0.000122000000000,0.001463000000000,0.000715000000000,0.002603000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,994.000000000000000,202.000000000000000,121.000000000000000,0.148181823678736,0.163960783045368,121.000000000000000,0.242661951333412 +0.000000000000000,0.000021000000000,0.000148000000000,0.000131000000000,0.001726000000000,0.000788000000000,0.002871000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,990.000000000000000,214.000000000000000,121.000000000000000,0.159041550968813,0.290710356872846,121.000000000000000,0.430251294240852 +0.000000000000000,0.000014000000000,0.000109000000000,0.000146000000000,0.001782000000000,0.000832000000000,0.002935000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,989.000000000000000,237.000000000000000,121.000000000000000,0.144598980992546,0.166027958406800,121.000000000000000,0.245721363787328 +0.000000000000000,0.000033000000000,0.000225000000000,0.000141000000000,0.001562000000000,0.000724000000000,0.002797000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,989.000000000000000,200.000000000000000,121.000000000000000,0.138993500529387,0.196990361228138,121.000000000000000,0.291545731774589 +0.000000000000000,0.000018000000000,0.000102000000000,0.000130000000000,0.001577000000000,0.000768000000000,0.002776000000000,1.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1025.000000000000000,218.000000000000000,121.000000000000000,0.159928213604770,0.189984919538914,121.000000000000000,0.281177669551262 +0.000000000000000,0.000012000000000,0.000247000000000,0.000124000000000,0.001584000000000,0.000607000000000,0.002648000000000,0.000000000000000,108.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,912.000000000000000,232.000000000000000,121.000000000000000,0.169367654114597,0.221725877325533,121.000000000000000,0.328154308402856 +0.000000000000000,0.000029000000000,0.000128000000000,0.000128000000000,0.001642000000000,0.000782000000000,0.002760000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,911.000000000000000,211.000000000000000,121.000000000000000,0.147968518377667,0.154122927463339,121.000000000000000,0.228101943121478 +0.000000000000000,0.000016000000000,0.000176000000000,0.000142000000000,0.001527000000000,0.000917000000000,0.002821000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,946.000000000000000,207.000000000000000,121.000000000000000,0.137541055415491,0.157761641471241,121.000000000000000,0.233487226761447 +0.000000000000000,0.000032000000000,0.000147000000000,0.000136000000000,0.001548000000000,0.000751000000000,0.002712000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,954.000000000000000,199.000000000000000,121.000000000000000,0.162415187446687,0.197580421079148,121.000000000000000,0.292419026477691 +0.000000000000000,0.000019000000000,0.000178000000000,0.000129000000000,0.001473000000000,0.000728000000000,0.002570000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,952.000000000000000,191.000000000000000,121.000000000000000,0.171041015417160,0.194915117263576,121.000000000000000,0.288474365726664 +0.000000000000000,0.000029000000000,0.000197000000000,0.000115000000000,0.001354000000000,0.000809000000000,0.002551000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,965.000000000000000,175.000000000000000,121.000000000000000,0.154222763807780,0.285544163762687,120.000000000000000,0.422605366108563 +0.000000000000000,0.000019000000000,0.000139000000000,0.000125000000000,0.001460000000000,0.000814000000000,0.002600000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,968.000000000000000,171.000000000000000,121.000000000000000,0.150595603214115,0.221852768512487,121.000000000000000,0.328342103660952 +0.000000000000000,0.000013000000000,0.000104000000000,0.000134000000000,0.001356000000000,0.000752000000000,0.002398000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,996.000000000000000,168.000000000000000,121.000000000000000,0.147430237486138,0.148159285827304,121.000000000000000,0.219275742894069 +0.000000000000000,0.000020000000000,0.000193000000000,0.000142000000000,0.001953000000000,0.000947000000000,0.003301000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1030.000000000000000,177.000000000000000,121.000000000000000,0.145798815037739,0.159663663944367,121.000000000000000,0.236302234970841 +0.000000000000000,0.000015000000000,0.000103000000000,0.000115000000000,0.001290000000000,0.000699000000000,0.002255000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,172.000000000000000,121.000000000000000,0.142196014156506,0.187147109561421,121.000000000000000,0.276977737652069 +0.000000000000000,0.000024000000000,0.000160000000000,0.000150000000000,0.001811000000000,0.000777000000000,0.003271000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1069.000000000000000,202.000000000000000,121.000000000000000,0.139609449101900,0.165271225439012,121.000000000000000,0.244601415643369 +0.000000000000000,0.000018000000000,0.000179000000000,0.000151000000000,0.001532000000000,0.000737000000000,0.002693000000000,0.000000000000000,97.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,912.000000000000000,203.000000000000000,121.000000000000000,0.147947477270869,0.179555832175793,121.000000000000000,0.265742648149137 +0.000000000000000,0.000019000000000,0.000177000000000,0.000125000000000,0.001512000000000,0.000717000000000,0.002588000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,911.000000000000000,212.000000000000000,121.000000000000000,0.147575394987053,0.165266294276773,121.000000000000000,0.244594112073245 +0.000000000000000,0.000016000000000,0.000106000000000,0.000137000000000,0.001490000000000,0.000826000000000,0.002618000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,915.000000000000000,203.000000000000000,121.000000000000000,0.154152939014589,0.159181033056470,121.000000000000000,0.235587925595243 +0.000000000000000,0.000013000000000,0.000177000000000,0.000117000000000,0.001355000000000,0.000751000000000,0.002448000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,921.000000000000000,192.000000000000000,121.000000000000000,0.150692609588339,0.183809895950044,121.000000000000000,0.272038654130109 +0.000000000000000,0.000023000000000,0.000221000000000,0.000167000000000,0.001790000000000,0.000948000000000,0.003199000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,932.000000000000000,170.000000000000000,121.000000000000000,0.149963553230709,0.203273297272569,121.000000000000000,0.300844465407444 +0.000000000000000,0.000026000000000,0.000151000000000,0.000122000000000,0.001357000000000,0.000723000000000,0.002422000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,961.000000000000000,168.000000000000000,121.000000000000000,0.142178288778563,0.151033799800819,121.000000000000000,0.223530034583352 +0.000000000000000,0.000018000000000,0.000155000000000,0.000123000000000,0.001394000000000,0.000766000000000,0.002492000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,986.000000000000000,182.000000000000000,121.000000000000000,0.141207634148801,0.172667793318101,121.000000000000000,0.255548330024774 +0.000000000000000,0.000018000000000,0.000174000000000,0.000143000000000,0.001389000000000,0.000790000000000,0.002550000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1023.000000000000000,171.000000000000000,121.000000000000000,0.140177814193211,0.162740001476768,121.000000000000000,0.240855214879131 +0.000000000000000,0.000021000000000,0.000173000000000,0.000122000000000,0.001280000000000,0.000796000000000,0.002581000000000,1.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1049.000000000000000,171.000000000000000,121.000000000000000,0.138041804635574,0.175894893269503,121.000000000000000,0.260324460535807 +0.000000000000000,0.000040000000000,0.000240000000000,0.000156000000000,0.001610000000000,0.000905000000000,0.003078000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,887.000000000000000,181.000000000000000,121.000000000000000,0.128640393991057,0.132619727567557,121.000000000000000,0.196277204924269 +0.000000000000000,0.000016000000000,0.000181000000000,0.000117000000000,0.001424000000000,0.000760000000000,0.002543000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,886.000000000000000,172.000000000000000,121.000000000000000,0.138352531751683,0.243902625004102,121.000000000000000,0.360975895470416 +0.000000000000000,0.000020000000000,0.000178000000000,0.000131000000000,0.001344000000000,0.000965000000000,0.002674000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,904.000000000000000,177.000000000000000,121.000000000000000,0.132849298892330,0.165943140041726,121.000000000000000,0.245595863686171 +0.000000000000000,0.000018000000000,0.000129000000000,0.000145000000000,0.001297000000000,0.000878000000000,0.002506000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,916.000000000000000,164.000000000000000,121.000000000000000,0.139100399764650,0.179464095411716,121.000000000000000,0.265606862397320 +0.000000000000000,0.000015000000000,0.000175000000000,0.000119000000000,0.001188000000000,0.000717000000000,0.002249000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,926.000000000000000,158.000000000000000,121.000000000000000,0.124508577433483,0.232688205210390,121.000000000000000,0.344378545000118 +0.000000000000000,0.000041000000000,0.000173000000000,0.000189000000000,0.001590000000000,0.000722000000000,0.002820000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,950.000000000000000,167.000000000000000,121.000000000000000,0.124364211160562,0.198989442345874,121.000000000000000,0.294504385287040 +0.000000000000000,0.000022000000000,0.000180000000000,0.000121000000000,0.001454000000000,0.000762000000000,0.002586000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,981.000000000000000,174.000000000000000,121.000000000000000,0.121986273502660,0.181985786779231,121.000000000000000,0.269338961458690 +0.000000000000000,0.000022000000000,0.000175000000000,0.000128000000000,0.001283000000000,0.000822000000000,0.002468000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1006.000000000000000,154.000000000000000,121.000000000000000,0.120933033868538,0.208757551950541,121.000000000000000,0.308961183186222 +0.000000000000000,0.000026000000000,0.000175000000000,0.000143000000000,0.001286000000000,0.000813000000000,0.002485000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1029.000000000000000,160.000000000000000,121.000000000000000,0.109269904153490,0.130322654376541,121.000000000000000,0.192877532026941 +0.000000000000000,0.000023000000000,0.000175000000000,0.000120000000000,0.001254000000000,0.000637000000000,0.002411000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1040.000000000000000,160.000000000000000,121.000000000000000,0.126897062957379,0.186841162125259,121.000000000000000,0.276524916304396 +0.000000000000000,0.000021000000000,0.000140000000000,0.000122000000000,0.001471000000000,0.000691000000000,0.002520000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,891.000000000000000,190.000000000000000,121.000000000000000,0.112694197899670,0.185521960041402,121.000000000000000,0.274572512797542 +0.000000000000000,0.000020000000000,0.000176000000000,0.000199000000000,0.001263000000000,0.000879000000000,0.002581000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,888.000000000000000,161.000000000000000,121.000000000000000,0.099793871260750,0.108940668612828,121.000000000000000,0.161232198827340 +0.000000000000000,0.000018000000000,0.000103000000000,0.000137000000000,0.001309000000000,0.000726000000000,0.002333000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,901.000000000000000,171.000000000000000,121.000000000000000,0.091727983876207,0.161347683449736,121.000000000000000,0.238794571957605 +0.000000000000000,0.000018000000000,0.000175000000000,0.000143000000000,0.001336000000000,0.000860000000000,0.002571000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,909.000000000000000,175.000000000000000,121.000000000000000,0.124196463571817,0.147059251648374,121.000000000000000,0.217647703825064 +0.000000000000000,0.000019000000000,0.000174000000000,0.000125000000000,0.001265000000000,0.000845000000000,0.002464000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,911.000000000000000,175.000000000000000,121.000000000000000,0.114265472855587,0.148521989180687,121.000000000000000,0.219812542662230 +0.000000000000000,0.000030000000000,0.000158000000000,0.000151000000000,0.001613000000000,0.000756000000000,0.002826000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,943.000000000000000,170.000000000000000,121.000000000000000,0.092242007337942,0.147927216635033,121.000000000000000,0.218932272923301 +0.000000000000000,0.000017000000000,0.000106000000000,0.000120000000000,0.001308000000000,0.001030000000000,0.002622000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,970.000000000000000,159.000000000000000,121.000000000000000,0.106941604326635,0.142972503313410,121.000000000000000,0.211599311615969 +0.000000000000000,0.000021000000000,0.000127000000000,0.000130000000000,0.001305000000000,0.000748000000000,0.002368000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,989.000000000000000,164.000000000000000,121.000000000000000,0.114683633251297,0.167145956283516,121.000000000000000,0.247376014134327 +0.000000000000000,0.000023000000000,0.000135000000000,0.000297000000000,0.001353000000000,0.000968000000000,0.002824000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1014.000000000000000,170.000000000000000,121.000000000000000,0.103049615014965,0.141054167934770,121.000000000000000,0.208760168771737 +0.000000000000000,0.000020000000000,0.000101000000000,0.000125000000000,0.001114000000000,0.000766000000000,0.002163000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1033.000000000000000,149.000000000000000,121.000000000000000,0.088395574941732,0.099895628586074,121.000000000000000,0.147845538218435 +0.000000000000000,0.000023000000000,0.000190000000000,0.000110000000000,0.001226000000000,0.000774000000000,0.002371000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,162.000000000000000,121.000000000000000,0.098469632616480,0.121321004607324,121.000000000000000,0.179555087237014 +0.000000000000000,0.000022000000000,0.000180000000000,0.000138000000000,0.001374000000000,0.001109000000000,0.002867000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1058.000000000000000,162.000000000000000,121.000000000000000,0.106165831669812,0.125397650867987,120.000000000000000,0.185588518499696 +0.000000000000000,0.000022000000000,0.000177000000000,0.000138000000000,0.001328000000000,0.000617000000000,0.002320000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1063.000000000000000,154.000000000000000,121.000000000000000,0.100439787680905,0.214221605374360,121.000000000000000,0.317047979072175 +0.000000000000000,0.000019000000000,0.000114000000000,0.000131000000000,0.001262000000000,0.000730000000000,0.002294000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1073.000000000000000,151.000000000000000,121.000000000000000,0.101286833254115,0.171921771357668,121.000000000000000,0.254444227342640 +0.000000000000000,0.000018000000000,0.000111000000000,0.000120000000000,0.001321000000000,0.000814000000000,0.002422000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1075.000000000000000,159.000000000000000,121.000000000000000,0.100562747826060,0.189141833234101,121.000000000000000,0.279929921566071 +0.000000000000000,0.000020000000000,0.000137000000000,0.000115000000000,0.001291000000000,0.000697000000000,0.002305000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1102.000000000000000,170.000000000000000,121.000000000000000,0.108513981039663,0.171230581801412,121.000000000000000,0.253421272631674 +0.000000000000000,0.000023000000000,0.000142000000000,0.000126000000000,0.001300000000000,0.000836000000000,0.002476000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1133.000000000000000,146.000000000000000,121.000000000000000,0.093525447667265,0.136448459114485,121.000000000000000,0.201943713921807 +0.000000000000000,0.000018000000000,0.000175000000000,0.000137000000000,0.001338000000000,0.000746000000000,0.002454000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1153.000000000000000,167.000000000000000,121.000000000000000,0.098830315127647,0.135984610426414,121.000000000000000,0.201257228873912 +0.000000000000000,0.000016000000000,0.000153000000000,0.000133000000000,0.001342000000000,0.000846000000000,0.002529000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1169.000000000000000,168.000000000000000,121.000000000000000,0.104911664860530,0.116528427363267,121.000000000000000,0.172462069689336 +0.000000000000000,0.000016000000000,0.000177000000000,0.000153000000000,0.001420000000000,0.001057000000000,0.002862000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1189.000000000000000,171.000000000000000,121.000000000000000,0.112357270101045,0.155883824635645,121.000000000000000,0.230708054062211 +0.000000000000000,0.000019000000000,0.000183000000000,0.000118000000000,0.001173000000000,0.000692000000000,0.002218000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1205.000000000000000,160.000000000000000,121.000000000000000,0.114134537418471,0.211839504506888,121.000000000000000,0.313522477539393 +0.000000000000000,0.000022000000000,0.000144000000000,0.000340000000000,0.002673000000000,0.001050000000000,0.004300000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1210.000000000000000,169.000000000000000,121.000000000000000,0.118247530316238,0.220707314595291,121.000000000000000,0.326646841420566 +0.000000000000000,0.000021000000000,0.000121000000000,0.000119000000000,0.001312000000000,0.000708000000000,0.002323000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1221.000000000000000,159.000000000000000,121.000000000000000,0.108077994964789,0.189119078021565,121.000000000000000,0.279896234164773 +0.000000000000000,0.000022000000000,0.000131000000000,0.000170000000000,0.001575000000000,0.000930000000000,0.002873000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1227.000000000000000,161.000000000000000,121.000000000000000,0.111392372838571,0.157100432720142,121.000000000000000,0.232508649452340 +0.000000000000000,0.000021000000000,0.000129000000000,0.000146000000000,0.001357000000000,0.001069000000000,0.002758000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1238.000000000000000,169.000000000000000,121.000000000000000,0.115843692072703,0.148606734789863,121.000000000000000,0.219937966947781 +0.000000000000000,0.000018000000000,0.000196000000000,0.000246000000000,0.003021000000000,0.001245000000000,0.004778000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1237.000000000000000,170.000000000000000,121.000000000000000,0.110486981424295,0.140524548316829,121.000000000000000,0.207976323848749 +0.000000000000000,0.000019000000000,0.000176000000000,0.000120000000000,0.001319000000000,0.000781000000000,0.002451000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,166.000000000000000,121.000000000000000,0.116858932300554,0.142202739311708,121.000000000000000,0.210460043128204 +0.000000000000000,0.000023000000000,0.000194000000000,0.000117000000000,0.001352000000000,0.000677000000000,0.002411000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1229.000000000000000,165.000000000000000,121.000000000000000,0.110055898076008,0.160160155663640,121.000000000000000,0.237037039832150 +0.000000000000000,0.000019000000000,0.000128000000000,0.000129000000000,0.001375000000000,0.000783000000000,0.002473000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,170.000000000000000,121.000000000000000,0.126041915882071,0.160651736154074,121.000000000000000,0.237764591667073 +0.000000000000000,0.000024000000000,0.000199000000000,0.000203000000000,0.001799000000000,0.000878000000000,0.003158000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1227.000000000000000,182.000000000000000,121.000000000000000,0.131395777815393,0.222014190834195,121.000000000000000,0.328581023909914 +0.000000000000000,0.000019000000000,0.000103000000000,0.000125000000000,0.001415000000000,0.000879000000000,0.002580000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1227.000000000000000,183.000000000000000,121.000000000000000,0.135634727713905,0.187089754575309,121.000000000000000,0.276892849444298 +0.000000000000000,0.000017000000000,0.000101000000000,0.000119000000000,0.001263000000000,0.000774000000000,0.002307000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1226.000000000000000,171.000000000000000,121.000000000000000,0.140713971719655,0.131521683676958,121.000000000000000,0.194652084756127 +0.000000000000000,0.000016000000000,0.000127000000000,0.000147000000000,0.001449000000000,0.000744000000000,0.002523000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1225.000000000000000,178.000000000000000,121.000000000000000,0.139061294677762,0.203192935815326,121.000000000000000,0.300725561264080 +0.000000000000000,0.000018000000000,0.000191000000000,0.000120000000000,0.001241000000000,0.000897000000000,0.002515000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1221.000000000000000,165.000000000000000,121.000000000000000,0.137698280788293,0.173674353597993,121.000000000000000,0.257038030883200 +0.000000000000000,0.000018000000000,0.000177000000000,0.000127000000000,0.001350000000000,0.000790000000000,0.002651000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1209.000000000000000,165.000000000000000,121.000000000000000,0.156706447381789,0.199509549579289,121.000000000000000,0.295274141143093 +0.000000000000000,0.000016000000000,0.000153000000000,0.000147000000000,0.001501000000000,0.000734000000000,0.002643000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1046.000000000000000,206.000000000000000,121.000000000000000,0.145254964747455,0.192623491876607,121.000000000000000,0.285082754555528 +0.000000000000000,0.000017000000000,0.000175000000000,0.000117000000000,0.001356000000000,0.000838000000000,0.002539000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1044.000000000000000,191.000000000000000,121.000000000000000,0.154344725976771,0.284210388757305,121.000000000000000,0.420631380425634 +0.000000000000000,0.000021000000000,0.000118000000000,0.000127000000000,0.001456000000000,0.000725000000000,0.002492000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1039.000000000000000,193.000000000000000,121.000000000000000,0.154361389589804,0.236960337646421,121.000000000000000,0.350701313890299 +0.000000000000000,0.000018000000000,0.000108000000000,0.000128000000000,0.001548000000000,0.000868000000000,0.002721000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1036.000000000000000,190.000000000000000,121.000000000000000,0.144847037730729,0.155773166896081,121.000000000000000,0.230544292351477 +0.000000000000000,0.000018000000000,0.000129000000000,0.000124000000000,0.001383000000000,0.000975000000000,0.002669000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1027.000000000000000,183.000000000000000,121.000000000000000,0.145841805810321,0.158516249676071,121.000000000000000,0.234604041193658 +0.000000000000000,0.000028000000000,0.000216000000000,0.000131000000000,0.001615000000000,0.000765000000000,0.002878000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1020.000000000000000,192.000000000000000,121.000000000000000,0.144426676201549,0.156437471874113,121.000000000000000,0.231527443868863 +0.000000000000000,0.000021000000000,0.000153000000000,0.000120000000000,0.001406000000000,0.000771000000000,0.002509000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1015.000000000000000,188.000000000000000,121.000000000000000,0.147869059454709,0.168692675134760,120.000000000000000,0.249665165294811 +0.000000000000000,0.000021000000000,0.000170000000000,0.000115000000000,0.001425000000000,0.000608000000000,0.002395000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1012.000000000000000,187.000000000000000,121.000000000000000,0.168987279193652,0.289264692226178,121.000000000000000,0.428111727272626 +0.000000000000000,0.000017000000000,0.000135000000000,0.000127000000000,0.001615000000000,0.000791000000000,0.002734000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1011.000000000000000,192.000000000000000,121.000000000000000,0.170578883496370,0.166353065557405,121.000000000000000,0.246202540171952 +0.000000000000000,0.000019000000000,0.000178000000000,0.000136000000000,0.001520000000000,0.000741000000000,0.002636000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1005.000000000000000,203.000000000000000,121.000000000000000,0.156640038600278,0.207055055847171,121.000000000000000,0.306441476765396 +0.000000000000000,0.000033000000000,0.000177000000000,0.000135000000000,0.001641000000000,0.000861000000000,0.003288000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,999.000000000000000,186.000000000000000,121.000000000000000,0.143274685502394,0.179257874186524,121.000000000000000,0.265301654036128 +0.000000000000000,0.000015000000000,0.000129000000000,0.000142000000000,0.001443000000000,0.000740000000000,0.002555000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,821.000000000000000,202.000000000000000,121.000000000000000,0.156881076812533,0.218447877056405,121.000000000000000,0.323302867722382 +0.000000000000000,0.000036000000000,0.000177000000000,0.000151000000000,0.001530000000000,0.000725000000000,0.002741000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,820.000000000000000,168.000000000000000,121.000000000000000,0.155951030020751,0.213023655758012,121.000000000000000,0.315275031106667 +0.000000000000000,0.000030000000000,0.000196000000000,0.000128000000000,0.001426000000000,0.000831000000000,0.002660000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,816.000000000000000 \ No newline at end of file diff --git a/svo_analysis/experiments/flying_room_1_fast.yaml b/svo_analysis/experiments/flying_room_1_fast.yaml new file mode 100644 index 0000000..018e1fe --- /dev/null +++ b/svo_analysis/experiments/flying_room_1_fast.yaml @@ -0,0 +1,2 @@ +dataset: flying_room_1_rig_1 +param_settings: vo_fast \ No newline at end of file diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index da32e70..ce8727a 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -7,7 +7,10 @@ Created on Sat Aug 10 18:21:47 2013 import os import yaml +import rospkg +import argparse import time +import svo_analysis.cpu_info as cpu_info class RosNode: def __init__(self, package, executable): @@ -18,50 +21,59 @@ class RosNode: parameter_string = '' for key in parameter_dictionary.keys(): parameter_string = parameter_string + ' _' + key + ':=' + str(parameter_dictionary[key]) + print('starting ros node') os.system('rosrun ' + self.package + ' ' + self.executable + ' ' + parameter_string) + print('ros node finished processing') if __name__=="__main__": - # config: - home_dir = os.getenv("HOME") - dataset_dir = home_dir+'/Datasets/SlamBenchmark/' - algo_dir = home_dir+'/workspace/rpg_slam/svo_ros' - trace_dir = home_dir+'/workspace/rpg_slam/svo_analysis/results' - platform = 'i7' + # parse command line + parser = argparse.ArgumentParser(description=''' + Runs SVO with the dataset and parameters specified in the provided experiment file. + ''') + parser.add_argument('experiment_file', help='experiment file in svo_analysis/experiments folder') + parser.add_argument('--name', help='experiment name') + parser.add_argument('--evaluate', help='evaluate tracefile after running SVO', action='store_true') + args = parser.parse_args() + + # load experiment parameters + expParamsFile = os.path.join(rospkg.RosPack().get_path('svo_analysis'), + 'experiments', args.experiment_file+'.yaml') + expParams = yaml.load(open(expParamsFile, 'r')) + expParams['time'] = time.strftime("%Y%m%d_%H%M", time.localtime()) + #expParams['platform'] = cpu_info.getCpuInfo() + expParams['experiment_name'] = args.name + if(expParams['experiment_name'] == None): + expParams['experiment_name'] = expParams['time']+'_svo_' + args.experiment_file + + # load dataset parameters + datasetParamsFile = os.path.join(rospkg.RosPack().get_path('Datasets'), + expParams['dataset'], 'dataset_params.yaml') + datasetParams = yaml.load(open(datasetParamsFile,'r')) - # load parameters - experiment_name = 'asl2_fast' - experiment_file = 'experiments/'+experiment_name+'.yaml' - experiment_file_stream = open(experiment_file,'r') - experiment_dict = yaml.load(experiment_file_stream) + # load algorithm parameters + algoParamsFile = os.path.join(rospkg.RosPack().get_path('svo_ros'), + 'param', expParams['param_settings']+'.yaml') + algoParams = yaml.load(open(algoParamsFile,'r')) + + # combine all parameters + params = dict(expParams.items() + datasetParams.items() + algoParams.items()) + params['trace_name'] = 'trace' + params['trace_dir'] = os.path.join(rospkg.RosPack().get_path('svo_analysis'), + 'results', params['experiment_name']) - dataset_param_file = dataset_dir+experiment_dict['dataset']+'/dataset_params.yaml' - dataset_param_file_stream = open(dataset_param_file,'r') - dataset_param_dict = yaml.load(dataset_param_file_stream) - - algo_param_file = algo_dir+'/param/'+experiment_dict['param_settings']+'.param' - algo_param_file_stream = open(algo_param_file,'r') - algo_param_dict = yaml.load(algo_param_file_stream) - - params = dict(dataset_param_dict.items() + algo_param_dict.items() + experiment_dict.items()) - localtime = time.localtime() - params['trace_name'] = time.strftime("%Y%m%d_%H%M", localtime)+'_nslam_'+platform+'_'+experiment_name - params['trace_dir'] = trace_dir+'/'+params['trace_name'] - params['run_id'] = 0 - - # create folder for experiment results + # create folder for tracing if not os.path.exists(params['trace_dir']): os.makedirs(params['trace_dir']) - + # dump experiment params to file: params_dump_file = params['trace_dir']+'/params.yaml' with open(params_dump_file,'w') as outfile: - outfile.write( yaml.dump(params, default_flow_style=False) ) + outfile.write(yaml.dump(params, default_flow_style=False)) # start ros node - print 'starting ros node' node = RosNode('svo_ros','benchmark') node.run(params) - print 'ros node finished processing' + diff --git a/svo_analysis/src/svo_analysis/cpu_info.py b/svo_analysis/src/svo_analysis/cpu_info.py new file mode 100644 index 0000000..48e661f --- /dev/null +++ b/svo_analysis/src/svo_analysis/cpu_info.py @@ -0,0 +1,10 @@ +#!/usr/bin/python + +import subprocess, re + +def getCpuInfo(): + command = "cat /proc/cpuinfo" + all_info = subprocess.check_output(command, shell=True).strip() + for line in all_info.split("\n"): + if "model name" in line: + return re.sub( ".*model name.*:", "", line,1) \ No newline at end of file From c4a26bcb08a44b4ae58b93a4b3eaf3b7b591910e Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 24 Mar 2014 15:00:09 +0100 Subject: [PATCH 025/215] rename project --- svo/Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/Doxyfile b/svo/Doxyfile index fb60d29..b1b4256 100644 --- a/svo/Doxyfile +++ b/svo/Doxyfile @@ -648,7 +648,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = "src", "include/nano_slam" +INPUT = "src", "include/svo" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is From 797480a84c9bf93db99ee8f048aadf1ad07fb0ac Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 24 Mar 2014 15:00:48 +0100 Subject: [PATCH 026/215] no tracing --- svo/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 7612a94..16b1cba 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -2,7 +2,7 @@ # user build settings SET(DEBUG FALSE) -SET(TRACE TRUE) +SET(TRACE FALSE) SET(HAVE_G2O FALSE) ################################################################################ From 1311ed95a05755d445e6189479105be6b9f65c75 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 24 Mar 2014 15:01:33 +0100 Subject: [PATCH 027/215] tested and fixed setFirstFrame() function --- svo/src/frame_handler_base.cpp | 2 +- svo/src/frame_handler_mono.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index 3d530f7..991268c 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -96,7 +96,6 @@ startFrameProcessingCommon() { resetAll(); stage_ = FIRST_FRAME; - set_start_ = false; } if(stage_ == PAUSED) @@ -145,6 +144,7 @@ resetCommon() map_.reset(); stage_ = PAUSED; set_reset_ = false; + set_start_ = false; tracking_quality_ = BAD; depth_filter_->reset(); num_obs_last_ = 0; diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 63672aa..1c4c814 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -79,6 +79,7 @@ setFirstFrame(const FramePtr& first_frame) { resetAll(); last_frame_ = first_frame; + last_frame_->setKeyframe(); map_.addKeyframe(last_frame_); stage_ = DEFAULT_FRAME; } From f65c2b19f08ac3ce8ede9d98345192c7807951a5 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 24 Mar 2014 15:02:21 +0100 Subject: [PATCH 028/215] tested and fixed benchmark node on synthetic dataset --- svo_ros/src/benchmark_node.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index af929df..e0235ab 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -130,7 +130,7 @@ void BenchmarkNode::runBenchmark(const std::string& dataset_dir) void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) { // create image reader and load dataset - std::string filename_benchmark(dataset_dir + "/images.txt"); + std::string filename_benchmark(dataset_dir + "/trajectory.txt"); vk::FileReader dataset_reader(filename_benchmark); dataset_reader.skipComments(); if(!dataset_reader.next()) { @@ -144,7 +144,7 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) for(auto it = dataset.begin(); it != dataset.end() && ros::ok(); ++it, ++frame_count_) { // Read image - std::string img_filename(dataset_dir + "/" + it->image_name_ + "_0.png"); + std::string img_filename(dataset_dir + "/img/" + it->image_name_ + "_0.png"); cv::Mat img(cv::imread(img_filename, 0)); if(img.empty()) { SVO_ERROR_STREAM("Reading image "<T_f_w_.inverse()*pt_pos_cur; svo::Point* point = new svo::Point(pt_pos_world, svo::Point::DEPTH); ftr->point = point; + ftr->point->addFrameRef(ftr); frame_ref->addFeature(ftr); } SVO_INFO_STREAM("Added "<("svo/dataset_directory")); - benchmark.runBenchmark(benchmark_dir); + if(vk::getParam("svo/dataset_is_blender", false)) + benchmark.runBlenderBenchmark(benchmark_dir); + else + benchmark.runBenchmark(benchmark_dir); printf("BenchmarkNode finished.\n"); return 0; } From b9a9dd7b7f8bc7a31bd99c40bb90d3c5fa0922d0 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 24 Mar 2014 15:03:03 +0100 Subject: [PATCH 029/215] tested and fixed new benchmark node --- svo_analysis/scripts/benchmark.py | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index ce8727a..3018d11 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -10,20 +10,8 @@ import yaml import rospkg import argparse import time -import svo_analysis.cpu_info as cpu_info - -class RosNode: - def __init__(self, package, executable): - self.package = package - self.executable = executable - - def run(self, parameter_dictionary): - parameter_string = '' - for key in parameter_dictionary.keys(): - parameter_string = parameter_string + ' _' + key + ':=' + str(parameter_dictionary[key]) - print('starting ros node') - os.system('rosrun ' + self.package + ' ' + self.executable + ' ' + parameter_string) - print('ros node finished processing') +import vikit_py.cpu_info as cpu_info +import vikit_py.ros_node as ros_node if __name__=="__main__": @@ -47,8 +35,10 @@ if __name__=="__main__": expParams['experiment_name'] = expParams['time']+'_svo_' + args.experiment_file # load dataset parameters - datasetParamsFile = os.path.join(rospkg.RosPack().get_path('Datasets'), - expParams['dataset'], 'dataset_params.yaml') + expParams['dataset_directory'] = os.path.join(rospkg.RosPack().get_path('Datasets'), expParams['dataset']) + if not os.path.exists(expParams['dataset_directory']): + raise Exception("Provided dataset folder does not exist.") + datasetParamsFile = os.path.join(expParams['dataset_directory'], 'dataset_params.yaml') datasetParams = yaml.load(open(datasetParamsFile,'r')) # load algorithm parameters @@ -72,7 +62,7 @@ if __name__=="__main__": outfile.write(yaml.dump(params, default_flow_style=False)) # start ros node - node = RosNode('svo_ros','benchmark') + node = ros_node.RosNode('svo_ros','benchmark') node.run(params) From ea7b382a2bedbd97422dcb35145b7bc7f1213845 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 24 Mar 2014 15:03:19 +0100 Subject: [PATCH 030/215] moved some python functions to vikit --- svo_analysis/src/svo_analysis/cpu_info.py | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 svo_analysis/src/svo_analysis/cpu_info.py diff --git a/svo_analysis/src/svo_analysis/cpu_info.py b/svo_analysis/src/svo_analysis/cpu_info.py deleted file mode 100644 index 48e661f..0000000 --- a/svo_analysis/src/svo_analysis/cpu_info.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/python - -import subprocess, re - -def getCpuInfo(): - command = "cat /proc/cpuinfo" - all_info = subprocess.check_output(command, shell=True).strip() - for line in all_info.split("\n"): - if "model name" in line: - return re.sub( ".*model name.*:", "", line,1) \ No newline at end of file From 0b0a9a51b01ecd4e0e8bcede5c90cbe27c9e1b75 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 25 Mar 2014 14:39:35 +0100 Subject: [PATCH 031/215] tracing and plotting of pose error for synthetic datasets --- svo/CMakeLists.txt | 2 +- svo_analysis/scripts/benchmark.py | 14 +- svo_analysis/src/svo_analysis/__init__.py | 2 - .../src/svo_analysis/analyse_dataset.py | 1 - svo_analysis/src/svo_analysis/analyse_logs.py | 8 +- .../src/svo_analysis/analyse_trajectory.py | 110 +- .../src/svo_analysis/hand_eye_calib.py | 79 +- .../src/svo_analysis/rotation_utils.py | 143 -- .../src/svo_analysis/transformations.py | 1705 ----------------- svo_ros/src/benchmark_node.cpp | 39 +- 10 files changed, 105 insertions(+), 1998 deletions(-) delete mode 100644 svo_analysis/src/svo_analysis/rotation_utils.py delete mode 100644 svo_analysis/src/svo_analysis/transformations.py diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 16b1cba..7612a94 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -2,7 +2,7 @@ # user build settings SET(DEBUG FALSE) -SET(TRACE FALSE) +SET(TRACE TRUE) SET(HAVE_G2O FALSE) ################################################################################ diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index 3018d11..4cebf88 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -10,6 +10,7 @@ import yaml import rospkg import argparse import time +import svo_analysis.analyse_trajectory as analyse_trajectory import vikit_py.cpu_info as cpu_info import vikit_py.ros_node as ros_node @@ -29,7 +30,7 @@ if __name__=="__main__": 'experiments', args.experiment_file+'.yaml') expParams = yaml.load(open(expParamsFile, 'r')) expParams['time'] = time.strftime("%Y%m%d_%H%M", time.localtime()) - #expParams['platform'] = cpu_info.getCpuInfo() + expParams['platform'] = cpu_info.get_cpu_info() expParams['experiment_name'] = args.name if(expParams['experiment_name'] == None): expParams['experiment_name'] = expParams['time']+'_svo_' + args.experiment_file @@ -43,7 +44,7 @@ if __name__=="__main__": # load algorithm parameters algoParamsFile = os.path.join(rospkg.RosPack().get_path('svo_ros'), - 'param', expParams['param_settings']+'.yaml') + 'param', expParams['param_settings']+'.yaml') algoParams = yaml.load(open(algoParamsFile,'r')) # combine all parameters @@ -61,9 +62,16 @@ if __name__=="__main__": with open(params_dump_file,'w') as outfile: outfile.write(yaml.dump(params, default_flow_style=False)) - # start ros node + # execute ros node node = ros_node.RosNode('svo_ros','benchmark') node.run(params) + # TODO: check if it is a synthetic dataset + # plot trajectory error + analyse_trajectory.analyse_trajectory(params['trace_dir']) + + + + diff --git a/svo_analysis/src/svo_analysis/__init__.py b/svo_analysis/src/svo_analysis/__init__.py index 633f866..e69de29 100644 --- a/svo_analysis/src/svo_analysis/__init__.py +++ b/svo_analysis/src/svo_analysis/__init__.py @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- - diff --git a/svo_analysis/src/svo_analysis/analyse_dataset.py b/svo_analysis/src/svo_analysis/analyse_dataset.py index fa257b8..53a2501 100644 --- a/svo_analysis/src/svo_analysis/analyse_dataset.py +++ b/svo_analysis/src/svo_analysis/analyse_dataset.py @@ -4,7 +4,6 @@ import associate import numpy as np import matplotlib.pyplot as plt import yaml -import transformations def loadDataset(filename): file = open(filename) diff --git a/svo_analysis/src/svo_analysis/analyse_logs.py b/svo_analysis/src/svo_analysis/analyse_logs.py index be14feb..2f368ec 100755 --- a/svo_analysis/src/svo_analysis/analyse_logs.py +++ b/svo_analysis/src/svo_analysis/analyse_logs.py @@ -6,6 +6,10 @@ import numpy as np import matplotlib.pyplot as plt from matplotlib import rc +# tell matplotlib to use latex font +rc('font',**{'family':'serif','serif':['Cardo']}) +rc('text', usetex=True) + def analyse_logs(D, trace_name): # identify measurements which result from normal frames and which from keyframes @@ -124,9 +128,5 @@ if __name__=="__main__": for field, value in D.items(): D[field] = np.array(D[field]) - # tell matplotlib to use latex font - rc('font',**{'family':'serif','serif':['Cardo']}) - rc('text', usetex=True) - analyse_logs(D, args.trace_name) diff --git a/svo_analysis/src/svo_analysis/analyse_trajectory.py b/svo_analysis/src/svo_analysis/analyse_trajectory.py index f70cd62..f2a800e 100644 --- a/svo_analysis/src/svo_analysis/analyse_trajectory.py +++ b/svo_analysis/src/svo_analysis/analyse_trajectory.py @@ -1,43 +1,52 @@ # -*- coding: utf-8 -*- -import associate -import numpy as np -import matplotlib.pyplot as plt +import os import yaml -import transformations +from .tum_benchmark_tools import associate +import matplotlib.pyplot as plt +import vikit_py.transformations as transformations +import vikit_py.align_trajectory as align_trajectory +import numpy as np + +# plot options from matplotlib import rc +rc('font',**{'family':'serif','serif':['Cardo']}) +rc('text', usetex=True) -def alignSim3(model, data, n): +def plot_translation_error(timestamps, translation_error, results_dir): + fig = plt.figure(figsize=(8, 2.5)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='position drift [mm]', xlim=[0,timestamps[-1]-timestamps[0]+4]) + ax.plot(timestamps-timestamps[0], translation_error[:,0]*1000, 'r-', label='x') + ax.plot(timestamps-timestamps[0], translation_error[:,1]*1000, 'g-', label='y') + ax.plot(timestamps-timestamps[0], translation_error[:,2]*1000, 'b-', label='z') + ax.legend() + fig.tight_layout() + fig.savefig(results_dir+'/translation_error.pdf') - # select the first n datapoints and remove its mean so their center is zero - M = model[0:n,:] - D = data[0:n,:] +def plot_rotation_error(timestamps, rotation_error, results_dir): + fig = plt.figure(figsize=(8, 2.5)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='orientation drift [rad]', xlim=[0,timestamps[-1]-timestamps[0]+4]) + ax.plot(timestamps-timestamps[0], rotation_error[:,0], 'r-', label='yaw') + ax.plot(timestamps-timestamps[0], rotation_error[:,1], 'g-', label='pitch') + ax.plot(timestamps-timestamps[0], rotation_error[:,2], 'b-', label='roll') + ax.legend() + fig.tight_layout() + fig.savefig(results_dir+'/orientation_error.pdf') - # substract mean - mu_M = M.mean(0) - mu_D = D.mean(0) - M_zerocentered = M - mu_M - D_zerocentered = D - mu_D - - # correlation - C = 1.0/n*np.dot(M_zerocentered.transpose(), D_zerocentered) - sigma2 = 1.0/n*np.multiply(D_zerocentered,D_zerocentered).sum() - U_svd,D_svd,V_svd = np.linalg.linalg.svd(C) - D_svd = np.diag(D_svd) - V_svd = np.transpose(V_svd) - S = np.eye(3) - - if(np.linalg.det(U_svd)*np.linalg.det(V_svd) < 0): - S[2,2] = -1 - - R = np.dot(U_svd, np.dot(S, np.transpose(V_svd))) - s = 1.0/sigma2*np.trace(np.dot(D_svd, S)) - t = mu_M-s*np.dot(R,mu_D) - - return s, R, t - - -def getRigidBodyTrafo(quat,trans): +def analyse_trajectory(results_dir): + # plot translation error + data = np.loadtxt(os.path.join(results_dir, 'translation_error.txt')) + timestamps = data[:,0] + translation_error = data[:,1:4] + plot_translation_error(timestamps, translation_error, results_dir) + + # plot orientation error + data = np.loadtxt(os.path.join(results_dir, 'orientation_error.txt')) + timestamps = data[:,0] + orientation_error = data[:,1:4] + plot_rotation_error(timestamps, orientation_error, results_dir) + +def get_rigid_body_trafo(quat,trans): T = transformations.quaternion_matrix(quat) T[0:3,3] = trans return T @@ -50,10 +59,6 @@ if __name__ == '__main__': save = True results_dir = '../results/'+dataset - # plot options - rc('font',**{'family':'serif','serif':['Cardo']}) - rc('text', usetex=True) - # load dataset parameters params_stream = open(results_dir+'/params.yaml') params = yaml.load(params_stream) @@ -72,7 +77,7 @@ if __name__ == '__main__': P = yaml.load(dataset_param_file_stream) T_cm_quat = np.array([P['calib_Tcm_qx'], P['calib_Tcm_qy'], P['calib_Tcm_qz'], P['calib_Tcm_qw']]) T_cm_tran = np.array([P['calib_Tcm_tx'], P['calib_Tcm_ty'], P['calib_Tcm_tz']]) - T_cm = getRigidBodyTrafo(T_cm_quat, T_cm_tran) + T_cm = get_rigid_body_trafo(T_cm_quat, T_cm_tran) T_mc = transformations.inverse_matrix(T_cm) # load data @@ -94,12 +99,12 @@ if __name__ == '__main__': # align Sim3 to get scale if(n_align_frames > np.shape(matches)[0]): raise NameError('n_matches_for_scale is too large') - scale,rot,trans = alignSim3(p_gt, p_es, n_align_frames) + scale,rot,trans = align_trajectory.align_sim3(p_gt, p_es, n_align_frames) print 'scale = '+str(scale) # get trafo between (v)ision and (o)ptitrack frame - T_om = getRigidBodyTrafo(q_gt[0,:], p_gt[0,:]) - T_vc = getRigidBodyTrafo(q_es[0,:], scale*p_es[0,:]) + T_om = get_rigid_body_trafo(q_gt[0,:], p_gt[0,:]) + T_vc = get_rigid_body_trafo(q_es[0,:], scale*p_es[0,:]) T_cv = transformations.inverse_matrix(T_vc) T_ov = np.dot(T_om, np.dot(T_mc, T_cv)) print 'T_ov = ' + str(T_ov) @@ -111,7 +116,7 @@ if __name__ == '__main__': # rotate trajectory for i in range(np.shape(matches)[0]): - T_vc = getRigidBodyTrafo(q_es[i,:],p_es[i,:]) + T_vc = get_rigid_body_trafo(q_es[i,:],p_es[i,:]) T_vc[0:3,3] *= scale T_om = np.dot(T_ov, np.dot(T_vc, T_cm)) p_es_aligned[i,:] = T_om[0:3,3] @@ -136,15 +141,9 @@ if __name__ == '__main__': # plot position error (drift) translation_error = (p_gt-p_es_aligned) - fig = plt.figure(figsize=(8, 2.5)) - ax = fig.add_subplot(111, xlabel='time [s]', ylabel='position drift [m]', xlim=[0,t_es[-1]+4]) - ax.plot(t_es, translation_error[:,0], 'r-', label='x') - ax.plot(t_es, translation_error[:,1], 'g-', label='y') - ax.plot(t_es, translation_error[:,2], 'b-', label='z') - fig.tight_layout() + plot_translation_error(t_es, translation_error, results_dir) if save: - fig.savefig(results_dir+'/translation_error.pdf') f = open(translation_error_filename,'w') for i in range(translation_error.shape[0]): f.write('%.7f %.5f %.5f %.5f\n'%(t_es[i], translation_error[i,0], translation_error[i,1], translation_error[i,2])) @@ -152,16 +151,9 @@ if __name__ == '__main__': # plot orientation error (drift) orientation_error = (rpy_gt - rpy_es_aligned) - fig = plt.figure(figsize=(8, 2.5)) - ax = fig.add_subplot(111, xlabel='time [s]', ylabel='orientation drift [rad]', xlim=[0,t_es[-1]+4]) - ax.plot(t_es, orientation_error[:,0], 'r--', label='yaw') - ax.plot(t_es, orientation_error[:,1], 'g--', label='pitch') - ax.plot(t_es, orientation_error[:,2], 'b--', label='roll') - ax.legend() - fig.tight_layout() - - if save: - fig.savefig(results_dir+'/orientation_error.pdf') + plot_rotation_error(t_es, orientation_error, results_dir) + + if save: f = open(orientation_error_filename,'w') for i in range(orientation_error.shape[0]): f.write('%.7f %.5f %.5f %.5f\n'%(t_es[i], orientation_error[i,0], orientation_error[i,1], orientation_error[i,2])) diff --git a/svo_analysis/src/svo_analysis/hand_eye_calib.py b/svo_analysis/src/svo_analysis/hand_eye_calib.py index 7a7bb1b..f0eae14 100644 --- a/svo_analysis/src/svo_analysis/hand_eye_calib.py +++ b/svo_analysis/src/svo_analysis/hand_eye_calib.py @@ -11,81 +11,6 @@ import associate import rotation_utils as ru import matplotlib.pyplot as plt -def alignSim3(model, data, n): - - # select the first n datapoints and remove its mean so their center is zero - M = model[0:n,:] - D = data[0:n,:] - - # substract mean - mu_M = M.mean(0) - mu_D = D.mean(0) - M_zerocentered = M - mu_M - D_zerocentered = D - mu_D - - # correlation - C = 1.0/n*np.dot(M_zerocentered.transpose(), D_zerocentered) - sigma2 = 1.0/n*np.multiply(D_zerocentered,D_zerocentered).sum() - U_svd,D_svd,V_svd = np.linalg.linalg.svd(C) - D_svd = np.diag(D_svd) - V_svd = np.transpose(V_svd) - S = np.eye(3) - - if(np.linalg.det(U_svd)*np.linalg.det(V_svd) < 0): - S[2,2] = -1 - - R = np.dot(U_svd, np.dot(S, np.transpose(V_svd))) - s = 1.0/sigma2*np.trace(np.dot(D_svd, S)) - t = mu_M-s*np.dot(R,mu_D) - - return s, R, t - -def matrixLog(A): - theta = np.arccos((np.trace(A)-1.0)/2.0) - log_theta = 0.5*theta/np.sin(theta) * (A - A.transpose()) - x = np.array([log_theta[2,1], log_theta[0,2], log_theta[1,0]]) - return x - -def handEyeCalib(q_gt, q_es, p_gt, p_es, I, delta=10, verbose=True): - ''' Implementation of the least squares solution described in the paper: - Robot Sensor Calibration: Solving AX=XB on the Euclidean Group - by Frank C. Park and Bryan J. Martin - ''' - n = np.shape(I)[0] - M = np.zeros([3,3]) - C = np.zeros([3*n, 3]) - b_A = np.zeros([3*n,1]) - b_B = np.zeros([3*n,1]) - for ix, i in enumerate(I): - A1 = ru.quat2dcm(q_es[i,:]) - A2 = ru.quat2dcm(q_es[i+delta,:]) - A = np.dot(A1.transpose(), A2) - B1 = ru.quat2dcm(q_gt[i,:]) - B2 = ru.quat2dcm(q_gt[i+delta,:]) - B = np.dot(B1.transpose(), B2) - alpha = matrixLog(A) - beta = matrixLog(B) - M = M + np.dot(np.matrix(beta).transpose(), np.matrix(alpha)) - C[3*ix:3*ix+3,:] = np.eye(3) - A - b_A[3*ix:3*ix+3,0] = np.dot(np.transpose(A1), p_es[i+delta,:]-p_es[i,:]) - b_B[3*ix:3*ix+3,0] = np.dot(np.transpose(B1), p_gt[i+delta,:]-p_gt[i,:]) - - # compute rotation - D,V = np.linalg.linalg.eig(np.dot(M.transpose(), M)) - Lambda = np.diag([np.sqrt(1.0/D[0]), np.sqrt(1.0/D[1]), np.sqrt(1.0/D[2])]) - Vinv = np.linalg.linalg.inv(V) - X = np.dot(V, np.dot(Lambda, np.dot(Vinv, M.transpose()))) - - # compute translation - d = np.zeros([3*n,1]) - for i in range(n): - d[3*i:3*i+3,:] = b_A[3*i:3*i+3,:] - np.dot(X, b_B[3*i:3*i+3,:]) - - b = np.dot(np.linalg.inv(np.dot(np.transpose(C),C)), np.dot(np.transpose(C),d)) - - return np.array(X),b - - # user config display = True dataset = '20130906_2149_ptam_i7_asl2' @@ -121,7 +46,7 @@ q_es = np.array([[float(value) for value in data_es[b][3:7]] for a,b in matches] # -------------------------------------------------------------------------------- # align Sim3 to get scale -scale,rot,trans = alignSim3(p_gt, p_es, np.shape(matches)[0]) +scale,rot,trans = align_sim3(p_gt, p_es, np.shape(matches)[0]) p_es = scale*p_es #p_es = np.transpose(scale*np.dot(rot,np.transpose(p_es)))+trans @@ -142,7 +67,7 @@ if display: # select random measurements I = np.array(rand(n_measurements,1)*(np.shape(matches)[0]-delta), dtype=int)[:,0] -R,b = handEyeCalib(q_gt, q_es, p_gt, p_es, I, delta, True) +R,b = hand_eye_calib(q_gt, q_es, p_gt, p_es, I, delta, True) print 'quat = ' + str(ru.dcm2quat(R)) print 'b = ' + str(b) diff --git a/svo_analysis/src/svo_analysis/rotation_utils.py b/svo_analysis/src/svo_analysis/rotation_utils.py deleted file mode 100644 index 4c7b711..0000000 --- a/svo_analysis/src/svo_analysis/rotation_utils.py +++ /dev/null @@ -1,143 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Jun 28 10:42:37 2013 - -@author: cforster -""" - -import math -import numpy as np - -# epsilon for testing whether a number is close to zero -_EPS = np.finfo(float).eps * 4.0 - -# axis sequences for Euler angles -_NEXT_AXIS = [1, 2, 0, 1] - -# map axes strings to/from tuples of inner axis, parity, repetition, frame -_AXES2TUPLE = { - 'sxyz': (0, 0, 0, 0), 'sxyx': (0, 0, 1, 0), 'sxzy': (0, 1, 0, 0), - 'sxzx': (0, 1, 1, 0), 'syzx': (1, 0, 0, 0), 'syzy': (1, 0, 1, 0), - 'syxz': (1, 1, 0, 0), 'syxy': (1, 1, 1, 0), 'szxy': (2, 0, 0, 0), - 'szxz': (2, 0, 1, 0), 'szyx': (2, 1, 0, 0), 'szyz': (2, 1, 1, 0), - 'rzyx': (0, 0, 0, 1), 'rxyx': (0, 0, 1, 1), 'ryzx': (0, 1, 0, 1), - 'rxzx': (0, 1, 1, 1), 'rxzy': (1, 0, 0, 1), 'ryzy': (1, 0, 1, 1), - 'rzxy': (1, 1, 0, 1), 'ryxy': (1, 1, 1, 1), 'ryxz': (2, 0, 0, 1), - 'rzxz': (2, 0, 1, 1), 'rxyz': (2, 1, 0, 1), 'rzyz': (2, 1, 1, 1)} - -_TUPLE2AXES = dict((v, k) for k, v in _AXES2TUPLE.items()) - - -def quat2dcm(quaternion): - """Convert Quaternion [x y z w] to Direct Cosine Matrix representation """ - q = np.array(quaternion[:4], dtype=np.float64, copy=True) - nq = np.dot(q, q) - if nq < _EPS: - return np.identity(4) - q *= math.sqrt(2.0 / nq) - q = np.outer(q, q) - return np.array([ [1.0-q[1, 1]-q[2, 2], q[0, 1]-q[2, 3], q[0, 2]+q[1, 3]], - [ q[0, 1]+q[2, 3], 1.0-q[0, 0]-q[2, 2], q[1, 2]-q[0, 3]], - [ q[0, 2]-q[1, 3], q[1, 2]+q[0, 3], 1.0-q[0, 0]-q[1, 1]]], - dtype=np.float64) - -def dcm2quat(matrix): - """Convert Direct Cosine Matrix to Quaternion - - This algorithm comes from "Quaternion Calculus and Fast Animation", - Ken Shoemake, 1987 SIGGRAPH course notes - """ - q = np.empty((4, ), dtype=np.float64) - M = np.array(matrix, dtype=np.float64, copy=False)[:3, :3] - t = np.trace(M) - if (t > 0): - t = math.sqrt(t + 1.0); - q[3] = 0.5*t; - t = 0.5/t; - q[0] = (M[2,1] - M[1,2]) * t; - q[1] = (M[0,2] - M[2,0]) * t; - q[2] = (M[1,0] - M[0,1]) * t; - else: - i = 0; - if (M[1,1] > M[0,0]): - i = 1; - if (M[2,2] > M[i,i]): - i = 2; - j = (i+1)%3; - k = (j+1)%3; - - t = math.sqrt(M[i,i]-M[j,j]-M[k,k] + 1.0); - q[i] = 0.5 * t; - t = 0.5/t; - q[3] = (M[k,j]-M[j,k])*t; - q[j] = (M[j,i]+M[i,j])*t; - q[k] = (M[k,i]+M[i,k])*t; - return q - -def dcm2rpy(matrix, axes='sxyz'): - """Return Euler angles from rotation matrix for specified axis sequence. - - axes : One of 24 axis sequences as string or encoded tuple - - Note that many Euler angle triplets can describe one matrix. - - >>> R0 = euler_matrix(1, 2, 3, 'syxz') - >>> al, be, ga = euler_from_matrix(R0, 'syxz') - >>> R1 = euler_matrix(al, be, ga, 'syxz') - >>> numpy.allclose(R0, R1) - True - >>> angles = (4.0*math.pi) * (numpy.random.random(3) - 0.5) - >>> for axes in _AXES2TUPLE.keys(): - ... R0 = euler_matrix(axes=axes, *angles) - ... R1 = euler_matrix(axes=axes, *euler_from_matrix(R0, axes)) - ... if not numpy.allclose(R0, R1): print axes, "failed" - - """ - try: - firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()] - except (AttributeError, KeyError): - _ = _TUPLE2AXES[axes] - firstaxis, parity, repetition, frame = axes - - i = firstaxis - j = _NEXT_AXIS[i+parity] - k = _NEXT_AXIS[i-parity+1] - - M = np.array(matrix, dtype=np.float64, copy=False)[:3, :3] - if repetition: - sy = math.sqrt(M[i, j]*M[i, j] + M[i, k]*M[i, k]) - if sy > _EPS: - ax = math.atan2( M[i, j], M[i, k]) - ay = math.atan2( sy, M[i, i]) - az = math.atan2( M[j, i], -M[k, i]) - else: - ax = math.atan2(-M[j, k], M[j, j]) - ay = math.atan2( sy, M[i, i]) - az = 0.0 - else: - cy = math.sqrt(M[i, i]*M[i, i] + M[j, i]*M[j, i]) - if cy > _EPS: - ax = math.atan2( M[k, j], M[k, k]) - ay = math.atan2(-M[k, i], cy) - az = math.atan2( M[j, i], M[i, i]) - else: - ax = math.atan2(-M[j, k], M[j, j]) - ay = math.atan2(-M[k, i], cy) - az = 0.0 - - if parity: - ax, ay, az = -ax, -ay, -az - if frame: - ax, az = az, ax - return ax, ay, az - -def quat2rpy(quaternion, axes='sxyz'): - """Return Euler angles from quaternion for specified axis sequence. - - >>> angles = euler_from_quaternion([0.06146124, 0, 0, 0.99810947]) - >>> numpy.allclose(angles, [0.123, 0, 0]) - True - - """ - return dcm2rpy(quat2dcm(quaternion), axes) - diff --git a/svo_analysis/src/svo_analysis/transformations.py b/svo_analysis/src/svo_analysis/transformations.py deleted file mode 100644 index 6d6f19e..0000000 --- a/svo_analysis/src/svo_analysis/transformations.py +++ /dev/null @@ -1,1705 +0,0 @@ -# -*- coding: utf-8 -*- -# transformations.py - -# Copyright (c) 2006, Christoph Gohlke -# Copyright (c) 2006-2009, The Regents of the University of California -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the copyright holders nor the names of any -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -"""Homogeneous Transformation Matrices and Quaternions. - -A library for calculating 4x4 matrices for translating, rotating, reflecting, -scaling, shearing, projecting, orthogonalizing, and superimposing arrays of -3D homogeneous coordinates as well as for converting between rotation matrices, -Euler angles, and quaternions. Also includes an Arcball control object and -functions to decompose transformation matrices. - -:Authors: - `Christoph Gohlke `__, - Laboratory for Fluorescence Dynamics, University of California, Irvine - -:Version: 20090418 - -Requirements ------------- - -* `Python 2.6 `__ -* `Numpy 1.3 `__ -* `transformations.c 20090418 `__ - (optional implementation of some functions in C) - -Notes ------ - -Matrices (M) can be inverted using numpy.linalg.inv(M), concatenated using -numpy.dot(M0, M1), or used to transform homogeneous coordinates (v) using -numpy.dot(M, v) for shape (4, \*) "point of arrays", respectively -numpy.dot(v, M.T) for shape (\*, 4) "array of points". - -Calculations are carried out with numpy.float64 precision. - -This Python implementation is not optimized for speed. - -Vector, point, quaternion, and matrix function arguments are expected to be -"array like", i.e. tuple, list, or numpy arrays. - -Return types are numpy arrays unless specified otherwise. - -Angles are in radians unless specified otherwise. - -Quaternions ix+jy+kz+w are represented as [x, y, z, w]. - -Use the transpose of transformation matrices for OpenGL glMultMatrixd(). - -A triple of Euler angles can be applied/interpreted in 24 ways, which can -be specified using a 4 character string or encoded 4-tuple: - - *Axes 4-string*: e.g. 'sxyz' or 'ryxy' - - - first character : rotations are applied to 's'tatic or 'r'otating frame - - remaining characters : successive rotation axis 'x', 'y', or 'z' - - *Axes 4-tuple*: e.g. (0, 0, 0, 0) or (1, 1, 1, 1) - - - inner axis: code of axis ('x':0, 'y':1, 'z':2) of rightmost matrix. - - parity : even (0) if inner axis 'x' is followed by 'y', 'y' is followed - by 'z', or 'z' is followed by 'x'. Otherwise odd (1). - - repetition : first and last axis are same (1) or different (0). - - frame : rotations are applied to static (0) or rotating (1) frame. - -References ----------- - -(1) Matrices and transformations. Ronald Goldman. - In "Graphics Gems I", pp 472-475. Morgan Kaufmann, 1990. -(2) More matrices and transformations: shear and pseudo-perspective. - Ronald Goldman. In "Graphics Gems II", pp 320-323. Morgan Kaufmann, 1991. -(3) Decomposing a matrix into simple transformations. Spencer Thomas. - In "Graphics Gems II", pp 320-323. Morgan Kaufmann, 1991. -(4) Recovering the data from the transformation matrix. Ronald Goldman. - In "Graphics Gems II", pp 324-331. Morgan Kaufmann, 1991. -(5) Euler angle conversion. Ken Shoemake. - In "Graphics Gems IV", pp 222-229. Morgan Kaufmann, 1994. -(6) Arcball rotation control. Ken Shoemake. - In "Graphics Gems IV", pp 175-192. Morgan Kaufmann, 1994. -(7) Representing attitude: Euler angles, unit quaternions, and rotation - vectors. James Diebel. 2006. -(8) A discussion of the solution for the best rotation to relate two sets - of vectors. W Kabsch. Acta Cryst. 1978. A34, 827-828. -(9) Closed-form solution of absolute orientation using unit quaternions. - BKP Horn. J Opt Soc Am A. 1987. 4(4), 629-642. -(10) Quaternions. Ken Shoemake. - http://www.sfu.ca/~jwa3/cmpt461/files/quatut.pdf -(11) From quaternion to matrix and back. JMP van Waveren. 2005. - http://www.intel.com/cd/ids/developer/asmo-na/eng/293748.htm -(12) Uniform random rotations. Ken Shoemake. - In "Graphics Gems III", pp 124-132. Morgan Kaufmann, 1992. - - -Examples --------- - ->>> alpha, beta, gamma = 0.123, -1.234, 2.345 ->>> origin, xaxis, yaxis, zaxis = (0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1) ->>> I = identity_matrix() ->>> Rx = rotation_matrix(alpha, xaxis) ->>> Ry = rotation_matrix(beta, yaxis) ->>> Rz = rotation_matrix(gamma, zaxis) ->>> R = concatenate_matrices(Rx, Ry, Rz) ->>> euler = euler_from_matrix(R, 'rxyz') ->>> numpy.allclose([alpha, beta, gamma], euler) -True ->>> Re = euler_matrix(alpha, beta, gamma, 'rxyz') ->>> is_same_transform(R, Re) -True ->>> al, be, ga = euler_from_matrix(Re, 'rxyz') ->>> is_same_transform(Re, euler_matrix(al, be, ga, 'rxyz')) -True ->>> qx = quaternion_about_axis(alpha, xaxis) ->>> qy = quaternion_about_axis(beta, yaxis) ->>> qz = quaternion_about_axis(gamma, zaxis) ->>> q = quaternion_multiply(qx, qy) ->>> q = quaternion_multiply(q, qz) ->>> Rq = quaternion_matrix(q) ->>> is_same_transform(R, Rq) -True ->>> S = scale_matrix(1.23, origin) ->>> T = translation_matrix((1, 2, 3)) ->>> Z = shear_matrix(beta, xaxis, origin, zaxis) ->>> R = random_rotation_matrix(numpy.random.rand(3)) ->>> M = concatenate_matrices(T, R, Z, S) ->>> scale, shear, angles, trans, persp = decompose_matrix(M) ->>> numpy.allclose(scale, 1.23) -True ->>> numpy.allclose(trans, (1, 2, 3)) -True ->>> numpy.allclose(shear, (0, math.tan(beta), 0)) -True ->>> is_same_transform(R, euler_matrix(axes='sxyz', *angles)) -True ->>> M1 = compose_matrix(scale, shear, angles, trans, persp) ->>> is_same_transform(M, M1) -True - -""" - -from __future__ import division - -import warnings -import math - -import numpy - -# Documentation in HTML format can be generated with Epydoc -__docformat__ = "restructuredtext en" - - -def identity_matrix(): - """Return 4x4 identity/unit matrix. - - >>> I = identity_matrix() - >>> numpy.allclose(I, numpy.dot(I, I)) - True - >>> numpy.sum(I), numpy.trace(I) - (4.0, 4.0) - >>> numpy.allclose(I, numpy.identity(4, dtype=numpy.float64)) - True - - """ - return numpy.identity(4, dtype=numpy.float64) - - -def translation_matrix(direction): - """Return matrix to translate by direction vector. - - >>> v = numpy.random.random(3) - 0.5 - >>> numpy.allclose(v, translation_matrix(v)[:3, 3]) - True - - """ - M = numpy.identity(4) - M[:3, 3] = direction[:3] - return M - - -def translation_from_matrix(matrix): - """Return translation vector from translation matrix. - - >>> v0 = numpy.random.random(3) - 0.5 - >>> v1 = translation_from_matrix(translation_matrix(v0)) - >>> numpy.allclose(v0, v1) - True - - """ - return numpy.array(matrix, copy=False)[:3, 3].copy() - - -def reflection_matrix(point, normal): - """Return matrix to mirror at plane defined by point and normal vector. - - >>> v0 = numpy.random.random(4) - 0.5 - >>> v0[3] = 1.0 - >>> v1 = numpy.random.random(3) - 0.5 - >>> R = reflection_matrix(v0, v1) - >>> numpy.allclose(2., numpy.trace(R)) - True - >>> numpy.allclose(v0, numpy.dot(R, v0)) - True - >>> v2 = v0.copy() - >>> v2[:3] += v1 - >>> v3 = v0.copy() - >>> v2[:3] -= v1 - >>> numpy.allclose(v2, numpy.dot(R, v3)) - True - - """ - normal = unit_vector(normal[:3]) - M = numpy.identity(4) - M[:3, :3] -= 2.0 * numpy.outer(normal, normal) - M[:3, 3] = (2.0 * numpy.dot(point[:3], normal)) * normal - return M - - -def reflection_from_matrix(matrix): - """Return mirror plane point and normal vector from reflection matrix. - - >>> v0 = numpy.random.random(3) - 0.5 - >>> v1 = numpy.random.random(3) - 0.5 - >>> M0 = reflection_matrix(v0, v1) - >>> point, normal = reflection_from_matrix(M0) - >>> M1 = reflection_matrix(point, normal) - >>> is_same_transform(M0, M1) - True - - """ - M = numpy.array(matrix, dtype=numpy.float64, copy=False) - # normal: unit eigenvector corresponding to eigenvalue -1 - l, V = numpy.linalg.eig(M[:3, :3]) - i = numpy.where(abs(numpy.real(l) + 1.0) < 1e-8)[0] - if not len(i): - raise ValueError("no unit eigenvector corresponding to eigenvalue -1") - normal = numpy.real(V[:, i[0]]).squeeze() - # point: any unit eigenvector corresponding to eigenvalue 1 - l, V = numpy.linalg.eig(M) - i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] - if not len(i): - raise ValueError("no unit eigenvector corresponding to eigenvalue 1") - point = numpy.real(V[:, i[-1]]).squeeze() - point /= point[3] - return point, normal - - -def rotation_matrix(angle, direction, point=None): - """Return matrix to rotate about axis defined by point and direction. - - >>> angle = (random.random() - 0.5) * (2*math.pi) - >>> direc = numpy.random.random(3) - 0.5 - >>> point = numpy.random.random(3) - 0.5 - >>> R0 = rotation_matrix(angle, direc, point) - >>> R1 = rotation_matrix(angle-2*math.pi, direc, point) - >>> is_same_transform(R0, R1) - True - >>> R0 = rotation_matrix(angle, direc, point) - >>> R1 = rotation_matrix(-angle, -direc, point) - >>> is_same_transform(R0, R1) - True - >>> I = numpy.identity(4, numpy.float64) - >>> numpy.allclose(I, rotation_matrix(math.pi*2, direc)) - True - >>> numpy.allclose(2., numpy.trace(rotation_matrix(math.pi/2, - ... direc, point))) - True - - """ - sina = math.sin(angle) - cosa = math.cos(angle) - direction = unit_vector(direction[:3]) - # rotation matrix around unit vector - R = numpy.array(((cosa, 0.0, 0.0), - (0.0, cosa, 0.0), - (0.0, 0.0, cosa)), dtype=numpy.float64) - R += numpy.outer(direction, direction) * (1.0 - cosa) - direction *= sina - R += numpy.array((( 0.0, -direction[2], direction[1]), - ( direction[2], 0.0, -direction[0]), - (-direction[1], direction[0], 0.0)), - dtype=numpy.float64) - M = numpy.identity(4) - M[:3, :3] = R - if point is not None: - # rotation not around origin - point = numpy.array(point[:3], dtype=numpy.float64, copy=False) - M[:3, 3] = point - numpy.dot(R, point) - return M - - -def rotation_from_matrix(matrix): - """Return rotation angle and axis from rotation matrix. - - >>> angle = (random.random() - 0.5) * (2*math.pi) - >>> direc = numpy.random.random(3) - 0.5 - >>> point = numpy.random.random(3) - 0.5 - >>> R0 = rotation_matrix(angle, direc, point) - >>> angle, direc, point = rotation_from_matrix(R0) - >>> R1 = rotation_matrix(angle, direc, point) - >>> is_same_transform(R0, R1) - True - - """ - R = numpy.array(matrix, dtype=numpy.float64, copy=False) - R33 = R[:3, :3] - # direction: unit eigenvector of R33 corresponding to eigenvalue of 1 - l, W = numpy.linalg.eig(R33.T) - i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] - if not len(i): - raise ValueError("no unit eigenvector corresponding to eigenvalue 1") - direction = numpy.real(W[:, i[-1]]).squeeze() - # point: unit eigenvector of R33 corresponding to eigenvalue of 1 - l, Q = numpy.linalg.eig(R) - i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] - if not len(i): - raise ValueError("no unit eigenvector corresponding to eigenvalue 1") - point = numpy.real(Q[:, i[-1]]).squeeze() - point /= point[3] - # rotation angle depending on direction - cosa = (numpy.trace(R33) - 1.0) / 2.0 - if abs(direction[2]) > 1e-8: - sina = (R[1, 0] + (cosa-1.0)*direction[0]*direction[1]) / direction[2] - elif abs(direction[1]) > 1e-8: - sina = (R[0, 2] + (cosa-1.0)*direction[0]*direction[2]) / direction[1] - else: - sina = (R[2, 1] + (cosa-1.0)*direction[1]*direction[2]) / direction[0] - angle = math.atan2(sina, cosa) - return angle, direction, point - - -def scale_matrix(factor, origin=None, direction=None): - """Return matrix to scale by factor around origin in direction. - - Use factor -1 for point symmetry. - - >>> v = (numpy.random.rand(4, 5) - 0.5) * 20.0 - >>> v[3] = 1.0 - >>> S = scale_matrix(-1.234) - >>> numpy.allclose(numpy.dot(S, v)[:3], -1.234*v[:3]) - True - >>> factor = random.random() * 10 - 5 - >>> origin = numpy.random.random(3) - 0.5 - >>> direct = numpy.random.random(3) - 0.5 - >>> S = scale_matrix(factor, origin) - >>> S = scale_matrix(factor, origin, direct) - - """ - if direction is None: - # uniform scaling - M = numpy.array(((factor, 0.0, 0.0, 0.0), - (0.0, factor, 0.0, 0.0), - (0.0, 0.0, factor, 0.0), - (0.0, 0.0, 0.0, 1.0)), dtype=numpy.float64) - if origin is not None: - M[:3, 3] = origin[:3] - M[:3, 3] *= 1.0 - factor - else: - # nonuniform scaling - direction = unit_vector(direction[:3]) - factor = 1.0 - factor - M = numpy.identity(4) - M[:3, :3] -= factor * numpy.outer(direction, direction) - if origin is not None: - M[:3, 3] = (factor * numpy.dot(origin[:3], direction)) * direction - return M - - -def scale_from_matrix(matrix): - """Return scaling factor, origin and direction from scaling matrix. - - >>> factor = random.random() * 10 - 5 - >>> origin = numpy.random.random(3) - 0.5 - >>> direct = numpy.random.random(3) - 0.5 - >>> S0 = scale_matrix(factor, origin) - >>> factor, origin, direction = scale_from_matrix(S0) - >>> S1 = scale_matrix(factor, origin, direction) - >>> is_same_transform(S0, S1) - True - >>> S0 = scale_matrix(factor, origin, direct) - >>> factor, origin, direction = scale_from_matrix(S0) - >>> S1 = scale_matrix(factor, origin, direction) - >>> is_same_transform(S0, S1) - True - - """ - M = numpy.array(matrix, dtype=numpy.float64, copy=False) - M33 = M[:3, :3] - factor = numpy.trace(M33) - 2.0 - try: - # direction: unit eigenvector corresponding to eigenvalue factor - l, V = numpy.linalg.eig(M33) - i = numpy.where(abs(numpy.real(l) - factor) < 1e-8)[0][0] - direction = numpy.real(V[:, i]).squeeze() - direction /= vector_norm(direction) - except IndexError: - # uniform scaling - factor = (factor + 2.0) / 3.0 - direction = None - # origin: any eigenvector corresponding to eigenvalue 1 - l, V = numpy.linalg.eig(M) - i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] - if not len(i): - raise ValueError("no eigenvector corresponding to eigenvalue 1") - origin = numpy.real(V[:, i[-1]]).squeeze() - origin /= origin[3] - return factor, origin, direction - - -def projection_matrix(point, normal, direction=None, - perspective=None, pseudo=False): - """Return matrix to project onto plane defined by point and normal. - - Using either perspective point, projection direction, or none of both. - - If pseudo is True, perspective projections will preserve relative depth - such that Perspective = dot(Orthogonal, PseudoPerspective). - - >>> P = projection_matrix((0, 0, 0), (1, 0, 0)) - >>> numpy.allclose(P[1:, 1:], numpy.identity(4)[1:, 1:]) - True - >>> point = numpy.random.random(3) - 0.5 - >>> normal = numpy.random.random(3) - 0.5 - >>> direct = numpy.random.random(3) - 0.5 - >>> persp = numpy.random.random(3) - 0.5 - >>> P0 = projection_matrix(point, normal) - >>> P1 = projection_matrix(point, normal, direction=direct) - >>> P2 = projection_matrix(point, normal, perspective=persp) - >>> P3 = projection_matrix(point, normal, perspective=persp, pseudo=True) - >>> is_same_transform(P2, numpy.dot(P0, P3)) - True - >>> P = projection_matrix((3, 0, 0), (1, 1, 0), (1, 0, 0)) - >>> v0 = (numpy.random.rand(4, 5) - 0.5) * 20.0 - >>> v0[3] = 1.0 - >>> v1 = numpy.dot(P, v0) - >>> numpy.allclose(v1[1], v0[1]) - True - >>> numpy.allclose(v1[0], 3.0-v1[1]) - True - - """ - M = numpy.identity(4) - point = numpy.array(point[:3], dtype=numpy.float64, copy=False) - normal = unit_vector(normal[:3]) - if perspective is not None: - # perspective projection - perspective = numpy.array(perspective[:3], dtype=numpy.float64, - copy=False) - M[0, 0] = M[1, 1] = M[2, 2] = numpy.dot(perspective-point, normal) - M[:3, :3] -= numpy.outer(perspective, normal) - if pseudo: - # preserve relative depth - M[:3, :3] -= numpy.outer(normal, normal) - M[:3, 3] = numpy.dot(point, normal) * (perspective+normal) - else: - M[:3, 3] = numpy.dot(point, normal) * perspective - M[3, :3] = -normal - M[3, 3] = numpy.dot(perspective, normal) - elif direction is not None: - # parallel projection - direction = numpy.array(direction[:3], dtype=numpy.float64, copy=False) - scale = numpy.dot(direction, normal) - M[:3, :3] -= numpy.outer(direction, normal) / scale - M[:3, 3] = direction * (numpy.dot(point, normal) / scale) - else: - # orthogonal projection - M[:3, :3] -= numpy.outer(normal, normal) - M[:3, 3] = numpy.dot(point, normal) * normal - return M - - -def projection_from_matrix(matrix, pseudo=False): - """Return projection plane and perspective point from projection matrix. - - Return values are same as arguments for projection_matrix function: - point, normal, direction, perspective, and pseudo. - - >>> point = numpy.random.random(3) - 0.5 - >>> normal = numpy.random.random(3) - 0.5 - >>> direct = numpy.random.random(3) - 0.5 - >>> persp = numpy.random.random(3) - 0.5 - >>> P0 = projection_matrix(point, normal) - >>> result = projection_from_matrix(P0) - >>> P1 = projection_matrix(*result) - >>> is_same_transform(P0, P1) - True - >>> P0 = projection_matrix(point, normal, direct) - >>> result = projection_from_matrix(P0) - >>> P1 = projection_matrix(*result) - >>> is_same_transform(P0, P1) - True - >>> P0 = projection_matrix(point, normal, perspective=persp, pseudo=False) - >>> result = projection_from_matrix(P0, pseudo=False) - >>> P1 = projection_matrix(*result) - >>> is_same_transform(P0, P1) - True - >>> P0 = projection_matrix(point, normal, perspective=persp, pseudo=True) - >>> result = projection_from_matrix(P0, pseudo=True) - >>> P1 = projection_matrix(*result) - >>> is_same_transform(P0, P1) - True - - """ - M = numpy.array(matrix, dtype=numpy.float64, copy=False) - M33 = M[:3, :3] - l, V = numpy.linalg.eig(M) - i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] - if not pseudo and len(i): - # point: any eigenvector corresponding to eigenvalue 1 - point = numpy.real(V[:, i[-1]]).squeeze() - point /= point[3] - # direction: unit eigenvector corresponding to eigenvalue 0 - l, V = numpy.linalg.eig(M33) - i = numpy.where(abs(numpy.real(l)) < 1e-8)[0] - if not len(i): - raise ValueError("no eigenvector corresponding to eigenvalue 0") - direction = numpy.real(V[:, i[0]]).squeeze() - direction /= vector_norm(direction) - # normal: unit eigenvector of M33.T corresponding to eigenvalue 0 - l, V = numpy.linalg.eig(M33.T) - i = numpy.where(abs(numpy.real(l)) < 1e-8)[0] - if len(i): - # parallel projection - normal = numpy.real(V[:, i[0]]).squeeze() - normal /= vector_norm(normal) - return point, normal, direction, None, False - else: - # orthogonal projection, where normal equals direction vector - return point, direction, None, None, False - else: - # perspective projection - i = numpy.where(abs(numpy.real(l)) > 1e-8)[0] - if not len(i): - raise ValueError( - "no eigenvector not corresponding to eigenvalue 0") - point = numpy.real(V[:, i[-1]]).squeeze() - point /= point[3] - normal = - M[3, :3] - perspective = M[:3, 3] / numpy.dot(point[:3], normal) - if pseudo: - perspective -= normal - return point, normal, None, perspective, pseudo - - -def clip_matrix(left, right, bottom, top, near, far, perspective=False): - """Return matrix to obtain normalized device coordinates from frustrum. - - The frustrum bounds are axis-aligned along x (left, right), - y (bottom, top) and z (near, far). - - Normalized device coordinates are in range [-1, 1] if coordinates are - inside the frustrum. - - If perspective is True the frustrum is a truncated pyramid with the - perspective point at origin and direction along z axis, otherwise an - orthographic canonical view volume (a box). - - Homogeneous coordinates transformed by the perspective clip matrix - need to be dehomogenized (devided by w coordinate). - - >>> frustrum = numpy.random.rand(6) - >>> frustrum[1] += frustrum[0] - >>> frustrum[3] += frustrum[2] - >>> frustrum[5] += frustrum[4] - >>> M = clip_matrix(*frustrum, perspective=False) - >>> numpy.dot(M, [frustrum[0], frustrum[2], frustrum[4], 1.0]) - array([-1., -1., -1., 1.]) - >>> numpy.dot(M, [frustrum[1], frustrum[3], frustrum[5], 1.0]) - array([ 1., 1., 1., 1.]) - >>> M = clip_matrix(*frustrum, perspective=True) - >>> v = numpy.dot(M, [frustrum[0], frustrum[2], frustrum[4], 1.0]) - >>> v / v[3] - array([-1., -1., -1., 1.]) - >>> v = numpy.dot(M, [frustrum[1], frustrum[3], frustrum[4], 1.0]) - >>> v / v[3] - array([ 1., 1., -1., 1.]) - - """ - if left >= right or bottom >= top or near >= far: - raise ValueError("invalid frustrum") - if perspective: - if near <= _EPS: - raise ValueError("invalid frustrum: near <= 0") - t = 2.0 * near - M = ((-t/(right-left), 0.0, (right+left)/(right-left), 0.0), - (0.0, -t/(top-bottom), (top+bottom)/(top-bottom), 0.0), - (0.0, 0.0, -(far+near)/(far-near), t*far/(far-near)), - (0.0, 0.0, -1.0, 0.0)) - else: - M = ((2.0/(right-left), 0.0, 0.0, (right+left)/(left-right)), - (0.0, 2.0/(top-bottom), 0.0, (top+bottom)/(bottom-top)), - (0.0, 0.0, 2.0/(far-near), (far+near)/(near-far)), - (0.0, 0.0, 0.0, 1.0)) - return numpy.array(M, dtype=numpy.float64) - - -def shear_matrix(angle, direction, point, normal): - """Return matrix to shear by angle along direction vector on shear plane. - - The shear plane is defined by a point and normal vector. The direction - vector must be orthogonal to the plane's normal vector. - - A point P is transformed by the shear matrix into P" such that - the vector P-P" is parallel to the direction vector and its extent is - given by the angle of P-P'-P", where P' is the orthogonal projection - of P onto the shear plane. - - >>> angle = (random.random() - 0.5) * 4*math.pi - >>> direct = numpy.random.random(3) - 0.5 - >>> point = numpy.random.random(3) - 0.5 - >>> normal = numpy.cross(direct, numpy.random.random(3)) - >>> S = shear_matrix(angle, direct, point, normal) - >>> numpy.allclose(1.0, numpy.linalg.det(S)) - True - - """ - normal = unit_vector(normal[:3]) - direction = unit_vector(direction[:3]) - if abs(numpy.dot(normal, direction)) > 1e-6: - raise ValueError("direction and normal vectors are not orthogonal") - angle = math.tan(angle) - M = numpy.identity(4) - M[:3, :3] += angle * numpy.outer(direction, normal) - M[:3, 3] = -angle * numpy.dot(point[:3], normal) * direction - return M - - -def shear_from_matrix(matrix): - """Return shear angle, direction and plane from shear matrix. - - >>> angle = (random.random() - 0.5) * 4*math.pi - >>> direct = numpy.random.random(3) - 0.5 - >>> point = numpy.random.random(3) - 0.5 - >>> normal = numpy.cross(direct, numpy.random.random(3)) - >>> S0 = shear_matrix(angle, direct, point, normal) - >>> angle, direct, point, normal = shear_from_matrix(S0) - >>> S1 = shear_matrix(angle, direct, point, normal) - >>> is_same_transform(S0, S1) - True - - """ - M = numpy.array(matrix, dtype=numpy.float64, copy=False) - M33 = M[:3, :3] - # normal: cross independent eigenvectors corresponding to the eigenvalue 1 - l, V = numpy.linalg.eig(M33) - i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-4)[0] - if len(i) < 2: - raise ValueError("No two linear independent eigenvectors found %s" % l) - V = numpy.real(V[:, i]).squeeze().T - lenorm = -1.0 - for i0, i1 in ((0, 1), (0, 2), (1, 2)): - n = numpy.cross(V[i0], V[i1]) - l = vector_norm(n) - if l > lenorm: - lenorm = l - normal = n - normal /= lenorm - # direction and angle - direction = numpy.dot(M33 - numpy.identity(3), normal) - angle = vector_norm(direction) - direction /= angle - angle = math.atan(angle) - # point: eigenvector corresponding to eigenvalue 1 - l, V = numpy.linalg.eig(M) - i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0] - if not len(i): - raise ValueError("no eigenvector corresponding to eigenvalue 1") - point = numpy.real(V[:, i[-1]]).squeeze() - point /= point[3] - return angle, direction, point, normal - - -def decompose_matrix(matrix): - """Return sequence of transformations from transformation matrix. - - matrix : array_like - Non-degenerative homogeneous transformation matrix - - Return tuple of: - scale : vector of 3 scaling factors - shear : list of shear factors for x-y, x-z, y-z axes - angles : list of Euler angles about static x, y, z axes - translate : translation vector along x, y, z axes - perspective : perspective partition of matrix - - Raise ValueError if matrix is of wrong type or degenerative. - - >>> T0 = translation_matrix((1, 2, 3)) - >>> scale, shear, angles, trans, persp = decompose_matrix(T0) - >>> T1 = translation_matrix(trans) - >>> numpy.allclose(T0, T1) - True - >>> S = scale_matrix(0.123) - >>> scale, shear, angles, trans, persp = decompose_matrix(S) - >>> scale[0] - 0.123 - >>> R0 = euler_matrix(1, 2, 3) - >>> scale, shear, angles, trans, persp = decompose_matrix(R0) - >>> R1 = euler_matrix(*angles) - >>> numpy.allclose(R0, R1) - True - - """ - M = numpy.array(matrix, dtype=numpy.float64, copy=True).T - if abs(M[3, 3]) < _EPS: - raise ValueError("M[3, 3] is zero") - M /= M[3, 3] - P = M.copy() - P[:, 3] = 0, 0, 0, 1 - if not numpy.linalg.det(P): - raise ValueError("Matrix is singular") - - scale = numpy.zeros((3, ), dtype=numpy.float64) - shear = [0, 0, 0] - angles = [0, 0, 0] - - if any(abs(M[:3, 3]) > _EPS): - perspective = numpy.dot(M[:, 3], numpy.linalg.inv(P.T)) - M[:, 3] = 0, 0, 0, 1 - else: - perspective = numpy.array((0, 0, 0, 1), dtype=numpy.float64) - - translate = M[3, :3].copy() - M[3, :3] = 0 - - row = M[:3, :3].copy() - scale[0] = vector_norm(row[0]) - row[0] /= scale[0] - shear[0] = numpy.dot(row[0], row[1]) - row[1] -= row[0] * shear[0] - scale[1] = vector_norm(row[1]) - row[1] /= scale[1] - shear[0] /= scale[1] - shear[1] = numpy.dot(row[0], row[2]) - row[2] -= row[0] * shear[1] - shear[2] = numpy.dot(row[1], row[2]) - row[2] -= row[1] * shear[2] - scale[2] = vector_norm(row[2]) - row[2] /= scale[2] - shear[1:] /= scale[2] - - if numpy.dot(row[0], numpy.cross(row[1], row[2])) < 0: - scale *= -1 - row *= -1 - - angles[1] = math.asin(-row[0, 2]) - if math.cos(angles[1]): - angles[0] = math.atan2(row[1, 2], row[2, 2]) - angles[2] = math.atan2(row[0, 1], row[0, 0]) - else: - #angles[0] = math.atan2(row[1, 0], row[1, 1]) - angles[0] = math.atan2(-row[2, 1], row[1, 1]) - angles[2] = 0.0 - - return scale, shear, angles, translate, perspective - - -def compose_matrix(scale=None, shear=None, angles=None, translate=None, - perspective=None): - """Return transformation matrix from sequence of transformations. - - This is the inverse of the decompose_matrix function. - - Sequence of transformations: - scale : vector of 3 scaling factors - shear : list of shear factors for x-y, x-z, y-z axes - angles : list of Euler angles about static x, y, z axes - translate : translation vector along x, y, z axes - perspective : perspective partition of matrix - - >>> scale = numpy.random.random(3) - 0.5 - >>> shear = numpy.random.random(3) - 0.5 - >>> angles = (numpy.random.random(3) - 0.5) * (2*math.pi) - >>> trans = numpy.random.random(3) - 0.5 - >>> persp = numpy.random.random(4) - 0.5 - >>> M0 = compose_matrix(scale, shear, angles, trans, persp) - >>> result = decompose_matrix(M0) - >>> M1 = compose_matrix(*result) - >>> is_same_transform(M0, M1) - True - - """ - M = numpy.identity(4) - if perspective is not None: - P = numpy.identity(4) - P[3, :] = perspective[:4] - M = numpy.dot(M, P) - if translate is not None: - T = numpy.identity(4) - T[:3, 3] = translate[:3] - M = numpy.dot(M, T) - if angles is not None: - R = euler_matrix(angles[0], angles[1], angles[2], 'sxyz') - M = numpy.dot(M, R) - if shear is not None: - Z = numpy.identity(4) - Z[1, 2] = shear[2] - Z[0, 2] = shear[1] - Z[0, 1] = shear[0] - M = numpy.dot(M, Z) - if scale is not None: - S = numpy.identity(4) - S[0, 0] = scale[0] - S[1, 1] = scale[1] - S[2, 2] = scale[2] - M = numpy.dot(M, S) - M /= M[3, 3] - return M - - -def orthogonalization_matrix(lengths, angles): - """Return orthogonalization matrix for crystallographic cell coordinates. - - Angles are expected in degrees. - - The de-orthogonalization matrix is the inverse. - - >>> O = orthogonalization_matrix((10., 10., 10.), (90., 90., 90.)) - >>> numpy.allclose(O[:3, :3], numpy.identity(3, float) * 10) - True - >>> O = orthogonalization_matrix([9.8, 12.0, 15.5], [87.2, 80.7, 69.7]) - >>> numpy.allclose(numpy.sum(O), 43.063229) - True - - """ - a, b, c = lengths - angles = numpy.radians(angles) - sina, sinb, _ = numpy.sin(angles) - cosa, cosb, cosg = numpy.cos(angles) - co = (cosa * cosb - cosg) / (sina * sinb) - return numpy.array(( - ( a*sinb*math.sqrt(1.0-co*co), 0.0, 0.0, 0.0), - (-a*sinb*co, b*sina, 0.0, 0.0), - ( a*cosb, b*cosa, c, 0.0), - ( 0.0, 0.0, 0.0, 1.0)), - dtype=numpy.float64) - - -def superimposition_matrix(v0, v1, scaling=False, usesvd=True): - """Return matrix to transform given vector set into second vector set. - - v0 and v1 are shape (3, \*) or (4, \*) arrays of at least 3 vectors. - - If usesvd is True, the weighted sum of squared deviations (RMSD) is - minimized according to the algorithm by W. Kabsch [8]. Otherwise the - quaternion based algorithm by B. Horn [9] is used (slower when using - this Python implementation). - - The returned matrix performs rotation, translation and uniform scaling - (if specified). - - >>> v0 = numpy.random.rand(3, 10) - >>> M = superimposition_matrix(v0, v0) - >>> numpy.allclose(M, numpy.identity(4)) - True - >>> R = random_rotation_matrix(numpy.random.random(3)) - >>> v0 = ((1,0,0), (0,1,0), (0,0,1), (1,1,1)) - >>> v1 = numpy.dot(R, v0) - >>> M = superimposition_matrix(v0, v1) - >>> numpy.allclose(v1, numpy.dot(M, v0)) - True - >>> v0 = (numpy.random.rand(4, 100) - 0.5) * 20.0 - >>> v0[3] = 1.0 - >>> v1 = numpy.dot(R, v0) - >>> M = superimposition_matrix(v0, v1) - >>> numpy.allclose(v1, numpy.dot(M, v0)) - True - >>> S = scale_matrix(random.random()) - >>> T = translation_matrix(numpy.random.random(3)-0.5) - >>> M = concatenate_matrices(T, R, S) - >>> v1 = numpy.dot(M, v0) - >>> v0[:3] += numpy.random.normal(0.0, 1e-9, 300).reshape(3, -1) - >>> M = superimposition_matrix(v0, v1, scaling=True) - >>> numpy.allclose(v1, numpy.dot(M, v0)) - True - >>> M = superimposition_matrix(v0, v1, scaling=True, usesvd=False) - >>> numpy.allclose(v1, numpy.dot(M, v0)) - True - >>> v = numpy.empty((4, 100, 3), dtype=numpy.float64) - >>> v[:, :, 0] = v0 - >>> M = superimposition_matrix(v0, v1, scaling=True, usesvd=False) - >>> numpy.allclose(v1, numpy.dot(M, v[:, :, 0])) - True - - """ - v0 = numpy.array(v0, dtype=numpy.float64, copy=False)[:3] - v1 = numpy.array(v1, dtype=numpy.float64, copy=False)[:3] - - if v0.shape != v1.shape or v0.shape[1] < 3: - raise ValueError("Vector sets are of wrong shape or type.") - - # move centroids to origin - t0 = numpy.mean(v0, axis=1) - t1 = numpy.mean(v1, axis=1) - v0 = v0 - t0.reshape(3, 1) - v1 = v1 - t1.reshape(3, 1) - - if usesvd: - # Singular Value Decomposition of covariance matrix - u, s, vh = numpy.linalg.svd(numpy.dot(v1, v0.T)) - # rotation matrix from SVD orthonormal bases - R = numpy.dot(u, vh) - if numpy.linalg.det(R) < 0.0: - # R does not constitute right handed system - R -= numpy.outer(u[:, 2], vh[2, :]*2.0) - s[-1] *= -1.0 - # homogeneous transformation matrix - M = numpy.identity(4) - M[:3, :3] = R - else: - # compute symmetric matrix N - xx, yy, zz = numpy.sum(v0 * v1, axis=1) - xy, yz, zx = numpy.sum(v0 * numpy.roll(v1, -1, axis=0), axis=1) - xz, yx, zy = numpy.sum(v0 * numpy.roll(v1, -2, axis=0), axis=1) - N = ((xx+yy+zz, yz-zy, zx-xz, xy-yx), - (yz-zy, xx-yy-zz, xy+yx, zx+xz), - (zx-xz, xy+yx, -xx+yy-zz, yz+zy), - (xy-yx, zx+xz, yz+zy, -xx-yy+zz)) - # quaternion: eigenvector corresponding to most positive eigenvalue - l, V = numpy.linalg.eig(N) - q = V[:, numpy.argmax(l)] - q /= vector_norm(q) # unit quaternion - q = numpy.roll(q, -1) # move w component to end - # homogeneous transformation matrix - M = quaternion_matrix(q) - - # scale: ratio of rms deviations from centroid - if scaling: - v0 *= v0 - v1 *= v1 - M[:3, :3] *= math.sqrt(numpy.sum(v1) / numpy.sum(v0)) - - # translation - M[:3, 3] = t1 - T = numpy.identity(4) - T[:3, 3] = -t0 - M = numpy.dot(M, T) - return M - - -def euler_matrix(ai, aj, ak, axes='sxyz'): - """Return homogeneous rotation matrix from Euler angles and axis sequence. - - ai, aj, ak : Euler's roll, pitch and yaw angles - axes : One of 24 axis sequences as string or encoded tuple - - >>> R = euler_matrix(1, 2, 3, 'syxz') - >>> numpy.allclose(numpy.sum(R[0]), -1.34786452) - True - >>> R = euler_matrix(1, 2, 3, (0, 1, 0, 1)) - >>> numpy.allclose(numpy.sum(R[0]), -0.383436184) - True - >>> ai, aj, ak = (4.0*math.pi) * (numpy.random.random(3) - 0.5) - >>> for axes in _AXES2TUPLE.keys(): - ... R = euler_matrix(ai, aj, ak, axes) - >>> for axes in _TUPLE2AXES.keys(): - ... R = euler_matrix(ai, aj, ak, axes) - - """ - try: - firstaxis, parity, repetition, frame = _AXES2TUPLE[axes] - except (AttributeError, KeyError): - _ = _TUPLE2AXES[axes] - firstaxis, parity, repetition, frame = axes - - i = firstaxis - j = _NEXT_AXIS[i+parity] - k = _NEXT_AXIS[i-parity+1] - - if frame: - ai, ak = ak, ai - if parity: - ai, aj, ak = -ai, -aj, -ak - - si, sj, sk = math.sin(ai), math.sin(aj), math.sin(ak) - ci, cj, ck = math.cos(ai), math.cos(aj), math.cos(ak) - cc, cs = ci*ck, ci*sk - sc, ss = si*ck, si*sk - - M = numpy.identity(4) - if repetition: - M[i, i] = cj - M[i, j] = sj*si - M[i, k] = sj*ci - M[j, i] = sj*sk - M[j, j] = -cj*ss+cc - M[j, k] = -cj*cs-sc - M[k, i] = -sj*ck - M[k, j] = cj*sc+cs - M[k, k] = cj*cc-ss - else: - M[i, i] = cj*ck - M[i, j] = sj*sc-cs - M[i, k] = sj*cc+ss - M[j, i] = cj*sk - M[j, j] = sj*ss+cc - M[j, k] = sj*cs-sc - M[k, i] = -sj - M[k, j] = cj*si - M[k, k] = cj*ci - return M - - -def euler_from_matrix(matrix, axes='sxyz'): - """Return Euler angles from rotation matrix for specified axis sequence. - - axes : One of 24 axis sequences as string or encoded tuple - - Note that many Euler angle triplets can describe one matrix. - - >>> R0 = euler_matrix(1, 2, 3, 'syxz') - >>> al, be, ga = euler_from_matrix(R0, 'syxz') - >>> R1 = euler_matrix(al, be, ga, 'syxz') - >>> numpy.allclose(R0, R1) - True - >>> angles = (4.0*math.pi) * (numpy.random.random(3) - 0.5) - >>> for axes in _AXES2TUPLE.keys(): - ... R0 = euler_matrix(axes=axes, *angles) - ... R1 = euler_matrix(axes=axes, *euler_from_matrix(R0, axes)) - ... if not numpy.allclose(R0, R1): print axes, "failed" - - """ - try: - firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()] - except (AttributeError, KeyError): - _ = _TUPLE2AXES[axes] - firstaxis, parity, repetition, frame = axes - - i = firstaxis - j = _NEXT_AXIS[i+parity] - k = _NEXT_AXIS[i-parity+1] - - M = numpy.array(matrix, dtype=numpy.float64, copy=False)[:3, :3] - if repetition: - sy = math.sqrt(M[i, j]*M[i, j] + M[i, k]*M[i, k]) - if sy > _EPS: - ax = math.atan2( M[i, j], M[i, k]) - ay = math.atan2( sy, M[i, i]) - az = math.atan2( M[j, i], -M[k, i]) - else: - ax = math.atan2(-M[j, k], M[j, j]) - ay = math.atan2( sy, M[i, i]) - az = 0.0 - else: - cy = math.sqrt(M[i, i]*M[i, i] + M[j, i]*M[j, i]) - if cy > _EPS: - ax = math.atan2( M[k, j], M[k, k]) - ay = math.atan2(-M[k, i], cy) - az = math.atan2( M[j, i], M[i, i]) - else: - ax = math.atan2(-M[j, k], M[j, j]) - ay = math.atan2(-M[k, i], cy) - az = 0.0 - - if parity: - ax, ay, az = -ax, -ay, -az - if frame: - ax, az = az, ax - return ax, ay, az - - -def euler_from_quaternion(quaternion, axes='sxyz'): - """Return Euler angles from quaternion for specified axis sequence. - - >>> angles = euler_from_quaternion([0.06146124, 0, 0, 0.99810947]) - >>> numpy.allclose(angles, [0.123, 0, 0]) - True - - """ - return euler_from_matrix(quaternion_matrix(quaternion), axes) - - -def quaternion_from_euler(ai, aj, ak, axes='sxyz'): - """Return quaternion from Euler angles and axis sequence. - - ai, aj, ak : Euler's roll, pitch and yaw angles - axes : One of 24 axis sequences as string or encoded tuple - - >>> q = quaternion_from_euler(1, 2, 3, 'ryxz') - >>> numpy.allclose(q, [0.310622, -0.718287, 0.444435, 0.435953]) - True - - """ - try: - firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()] - except (AttributeError, KeyError): - _ = _TUPLE2AXES[axes] - firstaxis, parity, repetition, frame = axes - - i = firstaxis - j = _NEXT_AXIS[i+parity] - k = _NEXT_AXIS[i-parity+1] - - if frame: - ai, ak = ak, ai - if parity: - aj = -aj - - ai /= 2.0 - aj /= 2.0 - ak /= 2.0 - ci = math.cos(ai) - si = math.sin(ai) - cj = math.cos(aj) - sj = math.sin(aj) - ck = math.cos(ak) - sk = math.sin(ak) - cc = ci*ck - cs = ci*sk - sc = si*ck - ss = si*sk - - quaternion = numpy.empty((4, ), dtype=numpy.float64) - if repetition: - quaternion[i] = cj*(cs + sc) - quaternion[j] = sj*(cc + ss) - quaternion[k] = sj*(cs - sc) - quaternion[3] = cj*(cc - ss) - else: - quaternion[i] = cj*sc - sj*cs - quaternion[j] = cj*ss + sj*cc - quaternion[k] = cj*cs - sj*sc - quaternion[3] = cj*cc + sj*ss - if parity: - quaternion[j] *= -1 - - return quaternion - - -def quaternion_about_axis(angle, axis): - """Return quaternion for rotation about axis. - - >>> q = quaternion_about_axis(0.123, (1, 0, 0)) - >>> numpy.allclose(q, [0.06146124, 0, 0, 0.99810947]) - True - - """ - quaternion = numpy.zeros((4, ), dtype=numpy.float64) - quaternion[:3] = axis[:3] - qlen = vector_norm(quaternion) - if qlen > _EPS: - quaternion *= math.sin(angle/2.0) / qlen - quaternion[3] = math.cos(angle/2.0) - return quaternion - - -def quaternion_matrix(quaternion): - """Return homogeneous rotation matrix from quaternion. - - >>> R = quaternion_matrix([0.06146124, 0, 0, 0.99810947]) - >>> numpy.allclose(R, rotation_matrix(0.123, (1, 0, 0))) - True - - """ - q = numpy.array(quaternion[:4], dtype=numpy.float64, copy=True) - nq = numpy.dot(q, q) - if nq < _EPS: - return numpy.identity(4) - q *= math.sqrt(2.0 / nq) - q = numpy.outer(q, q) - return numpy.array(( - (1.0-q[1, 1]-q[2, 2], q[0, 1]-q[2, 3], q[0, 2]+q[1, 3], 0.0), - ( q[0, 1]+q[2, 3], 1.0-q[0, 0]-q[2, 2], q[1, 2]-q[0, 3], 0.0), - ( q[0, 2]-q[1, 3], q[1, 2]+q[0, 3], 1.0-q[0, 0]-q[1, 1], 0.0), - ( 0.0, 0.0, 0.0, 1.0) - ), dtype=numpy.float64) - - -def quaternion_from_matrix(matrix): - """Return quaternion from rotation matrix. - - >>> R = rotation_matrix(0.123, (1, 2, 3)) - >>> q = quaternion_from_matrix(R) - >>> numpy.allclose(q, [0.0164262, 0.0328524, 0.0492786, 0.9981095]) - True - - """ - q = numpy.empty((4, ), dtype=numpy.float64) - M = numpy.array(matrix, dtype=numpy.float64, copy=False)[:4, :4] - t = numpy.trace(M) - if t > M[3, 3]: - q[3] = t - q[2] = M[1, 0] - M[0, 1] - q[1] = M[0, 2] - M[2, 0] - q[0] = M[2, 1] - M[1, 2] - else: - i, j, k = 0, 1, 2 - if M[1, 1] > M[0, 0]: - i, j, k = 1, 2, 0 - if M[2, 2] > M[i, i]: - i, j, k = 2, 0, 1 - t = M[i, i] - (M[j, j] + M[k, k]) + M[3, 3] - q[i] = t - q[j] = M[i, j] + M[j, i] - q[k] = M[k, i] + M[i, k] - q[3] = M[k, j] - M[j, k] - q *= 0.5 / math.sqrt(t * M[3, 3]) - return q - - -def quaternion_multiply(quaternion1, quaternion0): - """Return multiplication of two quaternions. - - >>> q = quaternion_multiply([1, -2, 3, 4], [-5, 6, 7, 8]) - >>> numpy.allclose(q, [-44, -14, 48, 28]) - True - - """ - x0, y0, z0, w0 = quaternion0 - x1, y1, z1, w1 = quaternion1 - return numpy.array(( - x1*w0 + y1*z0 - z1*y0 + w1*x0, - -x1*z0 + y1*w0 + z1*x0 + w1*y0, - x1*y0 - y1*x0 + z1*w0 + w1*z0, - -x1*x0 - y1*y0 - z1*z0 + w1*w0), dtype=numpy.float64) - - -def quaternion_conjugate(quaternion): - """Return conjugate of quaternion. - - >>> q0 = random_quaternion() - >>> q1 = quaternion_conjugate(q0) - >>> q1[3] == q0[3] and all(q1[:3] == -q0[:3]) - True - - """ - return numpy.array((-quaternion[0], -quaternion[1], - -quaternion[2], quaternion[3]), dtype=numpy.float64) - - -def quaternion_inverse(quaternion): - """Return inverse of quaternion. - - >>> q0 = random_quaternion() - >>> q1 = quaternion_inverse(q0) - >>> numpy.allclose(quaternion_multiply(q0, q1), [0, 0, 0, 1]) - True - - """ - return quaternion_conjugate(quaternion) / numpy.dot(quaternion, quaternion) - - -def quaternion_slerp(quat0, quat1, fraction, spin=0, shortestpath=True): - """Return spherical linear interpolation between two quaternions. - - >>> q0 = random_quaternion() - >>> q1 = random_quaternion() - >>> q = quaternion_slerp(q0, q1, 0.0) - >>> numpy.allclose(q, q0) - True - >>> q = quaternion_slerp(q0, q1, 1.0, 1) - >>> numpy.allclose(q, q1) - True - >>> q = quaternion_slerp(q0, q1, 0.5) - >>> angle = math.acos(numpy.dot(q0, q)) - >>> numpy.allclose(2.0, math.acos(numpy.dot(q0, q1)) / angle) or \ - numpy.allclose(2.0, math.acos(-numpy.dot(q0, q1)) / angle) - True - - """ - q0 = unit_vector(quat0[:4]) - q1 = unit_vector(quat1[:4]) - if fraction == 0.0: - return q0 - elif fraction == 1.0: - return q1 - d = numpy.dot(q0, q1) - if abs(abs(d) - 1.0) < _EPS: - return q0 - if shortestpath and d < 0.0: - # invert rotation - d = -d - q1 *= -1.0 - angle = math.acos(d) + spin * math.pi - if abs(angle) < _EPS: - return q0 - isin = 1.0 / math.sin(angle) - q0 *= math.sin((1.0 - fraction) * angle) * isin - q1 *= math.sin(fraction * angle) * isin - q0 += q1 - return q0 - - -def random_quaternion(rand=None): - """Return uniform random unit quaternion. - - rand: array like or None - Three independent random variables that are uniformly distributed - between 0 and 1. - - >>> q = random_quaternion() - >>> numpy.allclose(1.0, vector_norm(q)) - True - >>> q = random_quaternion(numpy.random.random(3)) - >>> q.shape - (4,) - - """ - if rand is None: - rand = numpy.random.rand(3) - else: - assert len(rand) == 3 - r1 = numpy.sqrt(1.0 - rand[0]) - r2 = numpy.sqrt(rand[0]) - pi2 = math.pi * 2.0 - t1 = pi2 * rand[1] - t2 = pi2 * rand[2] - return numpy.array((numpy.sin(t1)*r1, - numpy.cos(t1)*r1, - numpy.sin(t2)*r2, - numpy.cos(t2)*r2), dtype=numpy.float64) - - -def random_rotation_matrix(rand=None): - """Return uniform random rotation matrix. - - rnd: array like - Three independent random variables that are uniformly distributed - between 0 and 1 for each returned quaternion. - - >>> R = random_rotation_matrix() - >>> numpy.allclose(numpy.dot(R.T, R), numpy.identity(4)) - True - - """ - return quaternion_matrix(random_quaternion(rand)) - - -class Arcball(object): - """Virtual Trackball Control. - - >>> ball = Arcball() - >>> ball = Arcball(initial=numpy.identity(4)) - >>> ball.place([320, 320], 320) - >>> ball.down([500, 250]) - >>> ball.drag([475, 275]) - >>> R = ball.matrix() - >>> numpy.allclose(numpy.sum(R), 3.90583455) - True - >>> ball = Arcball(initial=[0, 0, 0, 1]) - >>> ball.place([320, 320], 320) - >>> ball.setaxes([1,1,0], [-1, 1, 0]) - >>> ball.setconstrain(True) - >>> ball.down([400, 200]) - >>> ball.drag([200, 400]) - >>> R = ball.matrix() - >>> numpy.allclose(numpy.sum(R), 0.2055924) - True - >>> ball.next() - - """ - - def __init__(self, initial=None): - """Initialize virtual trackball control. - - initial : quaternion or rotation matrix - - """ - self._axis = None - self._axes = None - self._radius = 1.0 - self._center = [0.0, 0.0] - self._vdown = numpy.array([0, 0, 1], dtype=numpy.float64) - self._constrain = False - - if initial is None: - self._qdown = numpy.array([0, 0, 0, 1], dtype=numpy.float64) - else: - initial = numpy.array(initial, dtype=numpy.float64) - if initial.shape == (4, 4): - self._qdown = quaternion_from_matrix(initial) - elif initial.shape == (4, ): - initial /= vector_norm(initial) - self._qdown = initial - else: - raise ValueError("initial not a quaternion or matrix.") - - self._qnow = self._qpre = self._qdown - - def place(self, center, radius): - """Place Arcball, e.g. when window size changes. - - center : sequence[2] - Window coordinates of trackball center. - radius : float - Radius of trackball in window coordinates. - - """ - self._radius = float(radius) - self._center[0] = center[0] - self._center[1] = center[1] - - def setaxes(self, *axes): - """Set axes to constrain rotations.""" - if axes is None: - self._axes = None - else: - self._axes = [unit_vector(axis) for axis in axes] - - def setconstrain(self, constrain): - """Set state of constrain to axis mode.""" - self._constrain = constrain == True - - def getconstrain(self): - """Return state of constrain to axis mode.""" - return self._constrain - - def down(self, point): - """Set initial cursor window coordinates and pick constrain-axis.""" - self._vdown = arcball_map_to_sphere(point, self._center, self._radius) - self._qdown = self._qpre = self._qnow - - if self._constrain and self._axes is not None: - self._axis = arcball_nearest_axis(self._vdown, self._axes) - self._vdown = arcball_constrain_to_axis(self._vdown, self._axis) - else: - self._axis = None - - def drag(self, point): - """Update current cursor window coordinates.""" - vnow = arcball_map_to_sphere(point, self._center, self._radius) - - if self._axis is not None: - vnow = arcball_constrain_to_axis(vnow, self._axis) - - self._qpre = self._qnow - - t = numpy.cross(self._vdown, vnow) - if numpy.dot(t, t) < _EPS: - self._qnow = self._qdown - else: - q = [t[0], t[1], t[2], numpy.dot(self._vdown, vnow)] - self._qnow = quaternion_multiply(q, self._qdown) - - def next(self, acceleration=0.0): - """Continue rotation in direction of last drag.""" - q = quaternion_slerp(self._qpre, self._qnow, 2.0+acceleration, False) - self._qpre, self._qnow = self._qnow, q - - def matrix(self): - """Return homogeneous rotation matrix.""" - return quaternion_matrix(self._qnow) - - -def arcball_map_to_sphere(point, center, radius): - """Return unit sphere coordinates from window coordinates.""" - v = numpy.array(((point[0] - center[0]) / radius, - (center[1] - point[1]) / radius, - 0.0), dtype=numpy.float64) - n = v[0]*v[0] + v[1]*v[1] - if n > 1.0: - v /= math.sqrt(n) # position outside of sphere - else: - v[2] = math.sqrt(1.0 - n) - return v - - -def arcball_constrain_to_axis(point, axis): - """Return sphere point perpendicular to axis.""" - v = numpy.array(point, dtype=numpy.float64, copy=True) - a = numpy.array(axis, dtype=numpy.float64, copy=True) - v -= a * numpy.dot(a, v) # on plane - n = vector_norm(v) - if n > _EPS: - if v[2] < 0.0: - v *= -1.0 - v /= n - return v - if a[2] == 1.0: - return numpy.array([1, 0, 0], dtype=numpy.float64) - return unit_vector([-a[1], a[0], 0]) - - -def arcball_nearest_axis(point, axes): - """Return axis, which arc is nearest to point.""" - point = numpy.array(point, dtype=numpy.float64, copy=False) - nearest = None - mx = -1.0 - for axis in axes: - t = numpy.dot(arcball_constrain_to_axis(point, axis), point) - if t > mx: - nearest = axis - mx = t - return nearest - - -# epsilon for testing whether a number is close to zero -_EPS = numpy.finfo(float).eps * 4.0 - -# axis sequences for Euler angles -_NEXT_AXIS = [1, 2, 0, 1] - -# map axes strings to/from tuples of inner axis, parity, repetition, frame -_AXES2TUPLE = { - 'sxyz': (0, 0, 0, 0), 'sxyx': (0, 0, 1, 0), 'sxzy': (0, 1, 0, 0), - 'sxzx': (0, 1, 1, 0), 'syzx': (1, 0, 0, 0), 'syzy': (1, 0, 1, 0), - 'syxz': (1, 1, 0, 0), 'syxy': (1, 1, 1, 0), 'szxy': (2, 0, 0, 0), - 'szxz': (2, 0, 1, 0), 'szyx': (2, 1, 0, 0), 'szyz': (2, 1, 1, 0), - 'rzyx': (0, 0, 0, 1), 'rxyx': (0, 0, 1, 1), 'ryzx': (0, 1, 0, 1), - 'rxzx': (0, 1, 1, 1), 'rxzy': (1, 0, 0, 1), 'ryzy': (1, 0, 1, 1), - 'rzxy': (1, 1, 0, 1), 'ryxy': (1, 1, 1, 1), 'ryxz': (2, 0, 0, 1), - 'rzxz': (2, 0, 1, 1), 'rxyz': (2, 1, 0, 1), 'rzyz': (2, 1, 1, 1)} - -_TUPLE2AXES = dict((v, k) for k, v in _AXES2TUPLE.items()) - -# helper functions - -def vector_norm(data, axis=None, out=None): - """Return length, i.e. eucledian norm, of ndarray along axis. - - >>> v = numpy.random.random(3) - >>> n = vector_norm(v) - >>> numpy.allclose(n, numpy.linalg.norm(v)) - True - >>> v = numpy.random.rand(6, 5, 3) - >>> n = vector_norm(v, axis=-1) - >>> numpy.allclose(n, numpy.sqrt(numpy.sum(v*v, axis=2))) - True - >>> n = vector_norm(v, axis=1) - >>> numpy.allclose(n, numpy.sqrt(numpy.sum(v*v, axis=1))) - True - >>> v = numpy.random.rand(5, 4, 3) - >>> n = numpy.empty((5, 3), dtype=numpy.float64) - >>> vector_norm(v, axis=1, out=n) - >>> numpy.allclose(n, numpy.sqrt(numpy.sum(v*v, axis=1))) - True - >>> vector_norm([]) - 0.0 - >>> vector_norm([1.0]) - 1.0 - - """ - data = numpy.array(data, dtype=numpy.float64, copy=True) - if out is None: - if data.ndim == 1: - return math.sqrt(numpy.dot(data, data)) - data *= data - out = numpy.atleast_1d(numpy.sum(data, axis=axis)) - numpy.sqrt(out, out) - return out - else: - data *= data - numpy.sum(data, axis=axis, out=out) - numpy.sqrt(out, out) - - -def unit_vector(data, axis=None, out=None): - """Return ndarray normalized by length, i.e. eucledian norm, along axis. - - >>> v0 = numpy.random.random(3) - >>> v1 = unit_vector(v0) - >>> numpy.allclose(v1, v0 / numpy.linalg.norm(v0)) - True - >>> v0 = numpy.random.rand(5, 4, 3) - >>> v1 = unit_vector(v0, axis=-1) - >>> v2 = v0 / numpy.expand_dims(numpy.sqrt(numpy.sum(v0*v0, axis=2)), 2) - >>> numpy.allclose(v1, v2) - True - >>> v1 = unit_vector(v0, axis=1) - >>> v2 = v0 / numpy.expand_dims(numpy.sqrt(numpy.sum(v0*v0, axis=1)), 1) - >>> numpy.allclose(v1, v2) - True - >>> v1 = numpy.empty((5, 4, 3), dtype=numpy.float64) - >>> unit_vector(v0, axis=1, out=v1) - >>> numpy.allclose(v1, v2) - True - >>> list(unit_vector([])) - [] - >>> list(unit_vector([1.0])) - [1.0] - - """ - if out is None: - data = numpy.array(data, dtype=numpy.float64, copy=True) - if data.ndim == 1: - data /= math.sqrt(numpy.dot(data, data)) - return data - else: - if out is not data: - out[:] = numpy.array(data, copy=False) - data = out - length = numpy.atleast_1d(numpy.sum(data*data, axis)) - numpy.sqrt(length, length) - if axis is not None: - length = numpy.expand_dims(length, axis) - data /= length - if out is None: - return data - - -def random_vector(size): - """Return array of random doubles in the half-open interval [0.0, 1.0). - - >>> v = random_vector(10000) - >>> numpy.all(v >= 0.0) and numpy.all(v < 1.0) - True - >>> v0 = random_vector(10) - >>> v1 = random_vector(10) - >>> numpy.any(v0 == v1) - False - - """ - return numpy.random.random(size) - - -def inverse_matrix(matrix): - """Return inverse of square transformation matrix. - - >>> M0 = random_rotation_matrix() - >>> M1 = inverse_matrix(M0.T) - >>> numpy.allclose(M1, numpy.linalg.inv(M0.T)) - True - >>> for size in range(1, 7): - ... M0 = numpy.random.rand(size, size) - ... M1 = inverse_matrix(M0) - ... if not numpy.allclose(M1, numpy.linalg.inv(M0)): print size - - """ - return numpy.linalg.inv(matrix) - - -def concatenate_matrices(*matrices): - """Return concatenation of series of transformation matrices. - - >>> M = numpy.random.rand(16).reshape((4, 4)) - 0.5 - >>> numpy.allclose(M, concatenate_matrices(M)) - True - >>> numpy.allclose(numpy.dot(M, M.T), concatenate_matrices(M, M.T)) - True - - """ - M = numpy.identity(4) - for i in matrices: - M = numpy.dot(M, i) - return M - - -def is_same_transform(matrix0, matrix1): - """Return True if two matrices perform same transformation. - - >>> is_same_transform(numpy.identity(4), numpy.identity(4)) - True - >>> is_same_transform(numpy.identity(4), random_rotation_matrix()) - False - - """ - matrix0 = numpy.array(matrix0, dtype=numpy.float64, copy=True) - matrix0 /= matrix0[3, 3] - matrix1 = numpy.array(matrix1, dtype=numpy.float64, copy=True) - matrix1 /= matrix1[3, 3] - return numpy.allclose(matrix0, matrix1) - - -def _import_module(module_name, warn=True, prefix='_py_', ignore='_'): - """Try import all public attributes from module into global namespace. - - Existing attributes with name clashes are renamed with prefix. - Attributes starting with underscore are ignored by default. - - Return True on successful import. - - """ - try: - module = __import__(module_name) - except ImportError: - if warn: - warnings.warn("Failed to import module " + module_name) - else: - for attr in dir(module): - if ignore and attr.startswith(ignore): - continue - if prefix: - if attr in globals(): - globals()[prefix + attr] = globals()[attr] - elif warn: - warnings.warn("No Python implementation of " + attr) - globals()[attr] = getattr(module, attr) - return True diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index e0235ab..561f131 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -44,12 +44,15 @@ class BenchmarkNode svo::Visualizer visualizer_; int frame_count_; std::ofstream trace_est_pose_; + std::ofstream trace_trans_error_; + std::ofstream trace_rot_error_; vk::AbstractCamera* cam_; public: BenchmarkNode(ros::NodeHandle& nh); ~BenchmarkNode(); void tracePose(const SE3& T_w_f, const double timestamp); + void tracePoseError(const SE3& T_f_gt, const double timestamp); void runBenchmark(const std::string& dataset_dir); void runBlenderBenchmark(const std::string& dataset_dir); }; @@ -91,6 +94,22 @@ void BenchmarkNode::tracePose(const SE3& T_w_f, const double timestamp) << q.x() << " " << q.y() << " " << q.z() << " " << q.w() << endl; } +void BenchmarkNode::tracePoseError(const SE3& T_f_gt, const double timestamp) +{ + Vector3d et(T_f_gt.translation()); // translation error + trace_trans_error_.precision(15); + trace_trans_error_.setf(std::ios::fixed, std::ios::floatfield ); + trace_trans_error_ << timestamp << " "; + trace_trans_error_.precision(6); + trace_trans_error_ << et.x() << " " << et.y() << " " << et.z() << " " << endl; + Vector3d er(vk::dcm2rpy(T_f_gt.rotation_matrix())); // rotation error in roll-pitch-yaw + trace_rot_error_.precision(15); + trace_rot_error_.setf(std::ios::fixed, std::ios::floatfield ); + trace_rot_error_ << timestamp << " "; + trace_rot_error_.precision(6); + trace_rot_error_ << er.x() << " " << er.y() << " " << er.z() << " " << endl; +} + void BenchmarkNode::runBenchmark(const std::string& dataset_dir) { // create image reader and load dataset @@ -140,6 +159,11 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) std::vector dataset; dataset_reader.readAllEntries(dataset); + trace_trans_error_.open(Config::traceDir() + "/translation_error.txt"); + trace_rot_error_.open(Config::traceDir() + "/orientation_error.txt"); + if(trace_trans_error_.fail() || trace_rot_error_.fail()) + throw std::runtime_error("Could not create tracefile. Does folder exist?"); + // process dataset for(auto it = dataset.begin(); it != dataset.end() && ros::ok(); ++it, ++frame_count_) { @@ -151,12 +175,15 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) return; } + // Read ground-truth pose + Sophus::SE3 T_w_gt(it->q_, it->t_); + // Set reference frame with depth if(frame_count_ == 0) { // set reference frame at ground-truth pose FramePtr frame_ref(new Frame(cam_, img, it->timestamp_)); - frame_ref->T_f_w_ = Sophus::SE3(it->q_, it->t_).inverse(); + frame_ref->T_f_w_ = T_w_gt.inverse(); // load ground-truth depth cv::Mat depthmap; @@ -189,9 +216,15 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) // Add image to VO vo_->addImage(img, it->timestamp_); + if(vo_->stage() != svo::FrameHandlerMono::DEFAULT_FRAME) + continue; + + // Compute pose error and trace to file + Sophus::SE3 T_f_gt(vo_->lastFrame()->T_f_w_*T_w_gt); + tracePoseError(T_f_gt, it->timestamp_); + // write pose to tracefile - if(vo_->stage() == svo::FrameHandlerMono::DEFAULT_FRAME) - tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); + tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); } } From 12451cff17ce3058c7ae1bbf6a0b66fae2116e54 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 27 Mar 2014 11:17:47 +0100 Subject: [PATCH 032/215] trace timestamp with logs for plotting --- svo/include/svo/frame_handler_base.h | 8 ++++---- svo/src/frame_handler_base.cpp | 9 +++++++-- svo/src/frame_handler_mono.cpp | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/svo/include/svo/frame_handler_base.h b/svo/include/svo/frame_handler_base.h index 51286c7..d8d8109 100644 --- a/svo/include/svo/frame_handler_base.h +++ b/svo/include/svo/frame_handler_base.h @@ -90,13 +90,13 @@ protected: DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. /// Before a frame is processed, this function is called. - bool startFrameProcessingCommon(); + bool startFrameProcessingCommon(const double timestamp); /// When a frame is finished processing, this function is called. int finishFrameProcessingCommon( - size_t update_id, - UpdateResult dropout, - size_t num_observations); + const size_t update_id, + const UpdateResult dropout, + const size_t num_observations); /// Reset the map and frame handler to start from scratch. void resetCommon(); diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index 991268c..04227ec 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -56,6 +56,7 @@ FrameHandlerBase() : g_permon->addTimer("point_optimizer"); g_permon->addTimer("local_ba"); g_permon->addTimer("tot_time"); + g_permon->addLog("timestamp"); g_permon->addLog("img_align_n_tracked"); g_permon->addLog("repr_n_mps"); g_permon->addLog("repr_n_new_references"); @@ -90,7 +91,7 @@ FrameHandlerBase:: } bool FrameHandlerBase:: -startFrameProcessingCommon() +startFrameProcessingCommon(const double timestamp) { if(set_start_) { @@ -101,6 +102,7 @@ startFrameProcessingCommon() if(stage_ == PAUSED) return false; + SVO_LOG(timestamp); SVO_DEBUG_STREAM("New Frame"); SVO_START_TIMER("tot_time"); timer_.start(); @@ -111,7 +113,10 @@ startFrameProcessingCommon() } int FrameHandlerBase:: -finishFrameProcessingCommon(size_t update_id, UpdateResult dropout, size_t num_observations) +finishFrameProcessingCommon( + const size_t update_id, + const UpdateResult dropout, + const size_t num_observations) { SVO_DEBUG_STREAM("Frame: "<reset(); num_obs_last_ = 0; SVO_INFO_STREAM("RESET"); @@ -159,22 +160,22 @@ resetCommon() void FrameHandlerBase:: setTrackingQuality(const size_t num_observations) { - tracking_quality_ = GOOD; + tracking_quality_ = TRACKING_GOOD; if(num_observations < Config::qualityMinFts()) { ROS_WARN_STREAM_THROTTLE(0.5, "Tracking less than "<< Config::qualityMinFts() <<" features!"); - tracking_quality_ = BAD; + tracking_quality_ = TRACKING_BAD; } const int feature_drop = static_cast(num_obs_last_) - num_observations; if(feature_drop > Config::qualityMaxFtsDrop()) { ROS_WARN_STREAM("Lost "<< feature_drop <<" features!"); - tracking_quality_ = BAD; + tracking_quality_ = TRACKING_BAD; } if(num_observations < 20) { ROS_ERROR_STREAM("Tracking less than 20 features!"); - tracking_quality_ = INSUFFICIENT; + tracking_quality_ = TRACKING_INSUFFICIENT; } } diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 105d546..b0846c0 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -58,12 +58,12 @@ addImage(const cv::Mat& img, const double timestamp) SVO_STOP_TIMER("pyramid_creation"); // process frame - UpdateResult res = FAILURE; - if(stage_ == DEFAULT_FRAME) + UpdateResult res = RESULT_FAILURE; + if(stage_ == STAGE_DEFAULT_FRAME) res = processFrame(); - else if(stage_ == SECOND_FRAME) + else if(stage_ == STAGE_SECOND_FRAME) res = processSecondFrame(); - else if(stage_ == FIRST_FRAME) + else if(stage_ == STAGE_FIRST_FRAME) res = processFirstFrame(); // set last frame @@ -81,7 +81,7 @@ setFirstFrame(const FramePtr& first_frame) last_frame_ = first_frame; last_frame_->setKeyframe(); map_.addKeyframe(last_frame_); - stage_ = DEFAULT_FRAME; + stage_ = STAGE_DEFAULT_FRAME; } FrameHandlerMono::UpdateResult FrameHandlerMono:: @@ -89,12 +89,12 @@ processFirstFrame() { new_frame_->T_f_w_ = T_f_w_init_; if(klt_homography_init_.addFirstFrame(new_frame_) == initialization::FAILURE) - return NO_KEYFRAME; + return RESULT_NO_KEYFRAME; new_frame_->setKeyframe(); map_.addKeyframe(new_frame_); - stage_ = SECOND_FRAME; + stage_ = STAGE_SECOND_FRAME; SVO_INFO_STREAM("Init: Selected first frame."); - return IS_KEYFRAME; + return RESULT_IS_KEYFRAME; } FrameHandlerMono::UpdateResult FrameHandlerMono:: @@ -102,9 +102,9 @@ processSecondFrame() { initialization::InitResult res = klt_homography_init_.addSecondFrame(new_frame_); if(res == initialization::FAILURE) - return FAILURE; + return RESULT_FAILURE; else if(res == initialization::NO_KEYFRAME) - return NO_KEYFRAME; + return RESULT_NO_KEYFRAME; // two-frame bundle adjustment #ifdef USE_BUNDLE_ADJUSTMENT @@ -118,10 +118,10 @@ processSecondFrame() // add frame to map new_frame_->setKeyframe(); map_.addKeyframe(new_frame_); - stage_ = DEFAULT_FRAME; + stage_ = STAGE_DEFAULT_FRAME; klt_homography_init_.reset(); SVO_INFO_STREAM("Init: Selected second frame, triangulated initial map."); - return IS_KEYFRAME; + return RESULT_IS_KEYFRAME; } FrameHandlerMono::UpdateResult FrameHandlerMono:: @@ -150,7 +150,7 @@ processFrame() SVO_DEBUG_STREAM("Reprojection:\t nPoints = "<addFrame(new_frame_); - return NO_KEYFRAME; + return RESULT_NO_KEYFRAME; } // new keyframe selected @@ -224,7 +224,7 @@ processFrame() new_frame_->setKeyframe(); map_.addKeyframe(new_frame_); - return IS_KEYFRAME; + return RESULT_IS_KEYFRAME; } void FrameHandlerMono:: diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index 561f131..fb121cc 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -141,7 +141,7 @@ void BenchmarkNode::runBenchmark(const std::string& dataset_dir) visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->timestamp_); // write pose to tracefile - if(vo_->stage() == svo::FrameHandlerMono::DEFAULT_FRAME) + if(vo_->stage() == svo::FrameHandlerMono::STAGE_DEFAULT_FRAME) tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); } } @@ -216,7 +216,7 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) // Add image to VO vo_->addImage(img, it->timestamp_); - if(vo_->stage() != svo::FrameHandlerMono::DEFAULT_FRAME) + if(vo_->stage() != svo::FrameHandlerMono::STAGE_DEFAULT_FRAME) continue; // Compute pose error and trace to file diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index d8aa72f..eda01c6 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -110,7 +110,7 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono cv::cvtColor(frame->img_pyr_[img_pub_level_], img_rgb, CV_GRAY2RGB); // during initialization, draw lines - if(slam.stage() == FrameHandlerBase::SECOND_FRAME) + if(slam.stage() == FrameHandlerBase::STAGE_SECOND_FRAME) { const vector& px_ref(slam.initFeatureTrackRefPx()); const vector& px_cur(slam.initFeatureTrackCurPx()); @@ -148,7 +148,7 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono img_msg.encoding = sensor_msgs::image_encodings::BGR8; pub_images_.publish(img_msg.toImageMsg()); } - else if(frame == NULL && pub_images_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::PAUSED) + else if(frame == NULL && pub_images_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_PAUSED) { // display image when slam is not running cv_bridge::CvImage img_msg; diff --git a/svo_ros/src/vo_node.cpp b/svo_ros/src/vo_node.cpp index 27b7ef0..9dc31dd 100644 --- a/svo_ros/src/vo_node.cpp +++ b/svo_ros/src/vo_node.cpp @@ -110,13 +110,13 @@ imgCb(const sensor_msgs::ImageConstPtr& msg) vo_->addImage(img, msg->header.stamp.toSec()); visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, msg->header.stamp.toSec()); - if(publish_markers_ && vo_->stage() != FrameHandlerBase::PAUSED) + if(publish_markers_ && vo_->stage() != FrameHandlerBase::STAGE_PAUSED) visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); if(publish_dense_input_) visualizer_.exportToDense(vo_->lastFrame()); - if(vo_->stage() == FrameHandlerMono::PAUSED) + if(vo_->stage() == FrameHandlerMono::STAGE_PAUSED) usleep(100000); // avoid busy loop when paused } From ce0e6543aa9a8bc04da2e071aeea8dcfa8f93113 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 27 Mar 2014 13:45:47 +0100 Subject: [PATCH 034/215] trace more detailed timings for reprojection --- svo/src/frame_handler_base.cpp | 3 +++ svo/src/reprojection.cpp | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index ac7aaf3..3a8bad7 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -53,6 +53,9 @@ FrameHandlerBase() : g_permon->addTimer("pyramid_creation"); g_permon->addTimer("sparse_img_align"); g_permon->addTimer("reproject"); + g_permon->addTimer("reproject_kfs"); + g_permon->addTimer("reproject_candidates"); + g_permon->addTimer("feature_align"); g_permon->addTimer("pose_optimizer"); g_permon->addTimer("point_optimizer"); g_permon->addTimer("local_ba"); diff --git a/svo/src/reprojection.cpp b/svo/src/reprojection.cpp index 26de82c..3e27c8b 100644 --- a/svo/src/reprojection.cpp +++ b/svo/src/reprojection.cpp @@ -70,6 +70,7 @@ void reprojectMap( resetGrid(grid); // Identify those Keyframes which share a common field of view. + SVO_START_TIMER("reproject_kfs"); list< pair > close_kfs; map.getCloseKeyframes(frame, close_kfs); @@ -103,8 +104,10 @@ void reprojectMap( overlap_kfs.back().second++; } } + SVO_STOP_TIMER("reproject_kfs"); // Now project all point candidates + SVO_START_TIMER("reproject_candidates"); { boost::unique_lock lock(candidate_points.mut_); auto it=candidate_points.candidates_.begin(); @@ -122,10 +125,12 @@ void reprojectMap( } ++it; } - } + } // unlock the mutex when out of scope + SVO_STOP_TIMER("reproject_candidates"); // Now we go through each grid cell and select one point to match. // At the end, we should have at maximum one reprojected point per cell. + SVO_START_TIMER("feature_align"); n_matches=0; n_trials=0; for(size_t i=0; i (size_t) Config::maxFts()) break; } + SVO_STOP_TIMER("feature_align"); } bool pointQualityComparator(Candidate& lhs, Candidate& rhs) From 674cf55ad309eda25fa16f1e13e08b2afdedb471 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 27 Mar 2014 13:46:15 +0100 Subject: [PATCH 035/215] refactored benchmarking --- svo_analysis/scripts/benchmark.py | 5 +- svo_analysis/scripts/evaluate.py | 41 +++--- svo_analysis/src/svo_analysis/analyse_logs.py | 136 +++++------------- .../src/svo_analysis/analyse_timing.py | 109 ++++++-------- 4 files changed, 100 insertions(+), 191 deletions(-) diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index 4cebf88..326a4d7 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -10,9 +10,9 @@ import yaml import rospkg import argparse import time -import svo_analysis.analyse_trajectory as analyse_trajectory import vikit_py.cpu_info as cpu_info import vikit_py.ros_node as ros_node +import evaluate if __name__=="__main__": @@ -67,8 +67,7 @@ if __name__=="__main__": node.run(params) # TODO: check if it is a synthetic dataset - # plot trajectory error - analyse_trajectory.analyse_trajectory(params['trace_dir']) + evaluate.evaluate_dataset(params['trace_dir']) diff --git a/svo_analysis/scripts/evaluate.py b/svo_analysis/scripts/evaluate.py index 4cff109..eb9fe60 100755 --- a/svo_analysis/scripts/evaluate.py +++ b/svo_analysis/scripts/evaluate.py @@ -5,26 +5,19 @@ Created on Sat Aug 10 18:21:47 2013 @author: Christian Forster """ -import argparse +import os import csv import numpy as np -from matplotlib import rc +import rospkg +import argparse import svo_analysis.analyse_logs as analyse_logs import svo_analysis.analyse_timing as analyse_timing +import svo_analysis.analyse_trajectory as analyse_trajectory -if __name__=="__main__": +def evaluate_dataset(trace_dir): - # parse command line - parser = argparse.ArgumentParser() - parser.add_argument('--trace_name', help='svo tracefile with timings and logs', default='20131121_0930_px7') - args = parser.parse_args() - - # config - results_dir = 'results/'+args.trace_name - trace_file = results_dir+'/'+args.trace_name+'.csv' - - # tracefile - data = csv.reader(open(trace_file)) + # read tracefile + data = csv.reader(open(os.path.join(trace_dir, 'trace.csv'))) fields = data.next() D = dict() for field in fields: @@ -39,9 +32,19 @@ if __name__=="__main__": for field, value in D.items(): D[field] = np.array(D[field]) - # tell matplotlib to use latex font - rc('font',**{'family':'serif','serif':['Cardo']}) - rc('text', usetex=True) + # generate plots + analyse_logs.analyse_logs(D, trace_dir) + analyse_timing.analyse_timing(D, trace_dir) + analyse_trajectory.analyse_trajectory(trace_dir) - analyse_logs.analyse_logs(D, results_dir+'/'+args.trace_name) - analyse_timing.analyse_timing(D, results_dir+'/'+args.trace_name) \ No newline at end of file +if __name__=="__main__": + parser = argparse.ArgumentParser(description=''' + Evaluates tracefiles of SVO and generates the plots. + ''') + parser.add_argument('experiment_name', help='directory name of the tracefiles') + args = parser.parse_args() + + trace_dir = os.path.join(rospkg.RosPack().get_path('svo_analysis'), + 'results', + args.experiment_name) + evaluate_dataset(trace_dir) \ No newline at end of file diff --git a/svo_analysis/src/svo_analysis/analyse_logs.py b/svo_analysis/src/svo_analysis/analyse_logs.py index 2f368ec..4e40bfe 100755 --- a/svo_analysis/src/svo_analysis/analyse_logs.py +++ b/svo_analysis/src/svo_analysis/analyse_logs.py @@ -1,16 +1,10 @@ #!/usr/bin/python -import argparse -import csv +import os import numpy as np import matplotlib.pyplot as plt -from matplotlib import rc - -# tell matplotlib to use latex font -rc('font',**{'family':'serif','serif':['Cardo']}) -rc('text', usetex=True) -def analyse_logs(D, trace_name): +def analyse_logs(D, trace_dir): # identify measurements which result from normal frames and which from keyframes is_kf = np.argwhere( (D['dropout'] == 1) & (D['repr_n_mps'] >= 0)) @@ -19,114 +13,56 @@ def analyse_logs(D, trace_name): n_frames = len(is_frame) n_kfs = len(is_kf) n_nokf = len(is_nokf) - fps = 25.0 + # set initial time to zero + D['timestamp'] = D['timestamp'] - D['timestamp'][0] + + # ---------------------------------------------------------------------------- # plot number of reprojected points mean_n_reproj_points = np.mean(D['repr_n_mps'][is_frame]); mean_n_reproj_matches = np.mean(D['repr_n_new_references'][is_frame]); + mean_n_edges_final = np.mean(D['sfba_n_edges_final'][is_frame]); - plt.figure() - plt.plot(np.arange(n_frames), D['repr_n_mps'][is_frame], 'r-', label='reprojected points, avg = %(i).2f'%{'i':mean_n_reproj_points}) - plt.plot(np.arange(n_frames), D['repr_n_new_references'][is_frame], 'b-', label='reprojected matches, avg = %(i).2f'%{'i':mean_n_reproj_matches}) - plt.legend() - plt.tight_layout() - plt.title('Reprojected points asdf') - plt.savefig(trace_name+'_reprojection.pdf', bbox_inches="tight") - - # plot number of triangulations -# plt.figure(3) -# plt.plot(np.arange(n_kfs), D['triang_n_points'][is_kf], 'g-', label='triangulated points, avg %0.2f'%np.mean(D['triang_n_points'][is_kf])) -# plt.plot(np.arange(n_kfs), D['triang_n_refs'][is_kf], 'b-', label='new references, avg %0.2f'%np.mean(D['triang_n_refs'][is_kf])) -# plt.plot(np.arange(n_kfs), D['triang_n_fails'][is_kf], 'r-', label='failures, avg %0.2f'%np.mean(D['triang_n_fails'][is_kf])) -# plt.plot(np.arange(n_kfs), D['triang_n_add_refs'][is_kf], 'm-', label='additional refs, avg %0.2f'%np.mean(D['triang_n_add_refs'][is_kf])) -# plt.legend() -# plt.title('Triangulation') -# plt.savefig(trace_name+'_img_triangulation.png', bbox_inches="tight") - - # plot number of klt tracked and matched points - fig = plt.figure(figsize=(8,2)) - ax = fig.add_subplot(111, xlabel='time [s]', ylabel='no. features') - ax.plot(np.arange(n_frames)/fps, D['repr_n_new_references'][is_frame], 'b-', label='number of successful matches') + fig = plt.figure(figsize=(8,3)) + ax = fig.add_subplot(111, xlabel='time [s]') + ax.plot(D['timestamp'][is_frame], D['repr_n_mps'][is_frame], 'r-', + label='Reprojected Points, avg = %.2f'%mean_n_reproj_points) + ax.plot(D['timestamp'][is_frame], D['repr_n_new_references'][is_frame], 'b-', + label='Feature Matches, avg = %.2f'%mean_n_reproj_matches) + ax.plot(D['timestamp'][is_frame], D['sfba_n_edges_final'][is_frame], 'g-', + label='Points after Optimization, avg = %.2f'%mean_n_edges_final) + ax.set_ylim(bottom=0) + ax.legend(loc='lower right') fig.tight_layout() - fig.savefig(trace_name+'number_of_features.pdf', bbox_inches="tight") + fig.savefig(os.path.join(trace_dir,'num_reprojected.pdf'), bbox_inches="tight") + # ---------------------------------------------------------------------------- # plot median error before and after pose-optimzation and bundle adjustment init_error_avg = np.mean(D['sfba_error_init'][is_frame]) opt1_avg = np.mean(D['sfba_error_final'][is_frame]) fig = plt.figure(figsize=(8,2)) ax = fig.add_subplot(111, xlabel='time [s]', ylabel='error [px]') - t_max = n_frames - ax.plot(np.arange(n_frames)[0:t_max]/fps, D['sfba_error_init'][is_frame][0:t_max], 'r-', label='Initial error') - ax.plot(np.arange(n_frames)[0:t_max]/fps, D['sfba_error_final'][is_frame][0:t_max], 'b-', label='Final error') + ax.plot(D['timestamp'][is_frame], D['sfba_error_init'][is_frame], 'r-', label='Initial error') + ax.plot(D['timestamp'][is_frame], D['sfba_error_final'][is_frame], 'b-', label='Final error') ax.legend(ncol=2) - ax.set_xlim([0, t_max/fps+4]) - #ax.set_ylim([0, 0.8]) fig.tight_layout() - fig.savefig(trace_name+'reprojection_error.pdf', bbox_inches="tight") + fig.savefig(os.path.join(trace_dir,'reprojection_error.pdf'), bbox_inches="tight") print 'average reprojection error improvement: ' + str(init_error_avg - opt1_avg) - # plot number of references - plt.figure() - plt.fill(np.arange(n_frames+1), np.append(D['repr_n_new_references'][is_frame]+D['klt_n_matches'][is_frame],0), 'g-', label='Reprojection') - plt.fill(np.arange(n_frames+1), np.append(D['klt_n_tracked'][is_frame],0), 'b-', label='KLT Matches') - plt.plot(np.arange(n_frames), D['sfba_n_edges_final'][is_frame], 'r-', label='References after Optimization', linewidth=2.0) - plt.legend() - plt.tight_layout() - plt.title('Pose Optimization') - plt.savefig(trace_name+'_img_n_references.pdf', bbox_inches="tight") + # ---------------------------------------------------------------------------- + # plot number of candidate points + fig = plt.figure(figsize=(8,3)) + ax = fig.add_subplot(111, xlabel='time [s]') + ax.plot(D['timestamp'][is_frame], D['n_candidates'][is_frame], 'r-', label='Candidate Points') + fig.tight_layout() + fig.savefig(os.path.join(trace_dir,'candidate_points.pdf'), bbox_inches="tight") - # plot number of seeds - plt.figure() - has_seed = np.argwhere(D['seeds_n_tot'] >= 0) - plt.fill(np.arange(len(has_seed)+1), np.append(D['seeds_n_tot'][has_seed],0), label='nSeeds', edgecolor='none') - plt.fill(np.arange(len(has_seed)+1), np.append(D['seeds_n_updates'][has_seed]+D['seeds_n_failed_matches'][has_seed],0), label='nFailedMatches', edgecolor='none') - plt.fill(np.arange(len(has_seed)+1), np.append(D['seeds_n_updates'][has_seed],0), label='nUpdates', edgecolor='none') - plt.legend() - plt.tight_layout() - plt.title('Seeds') - plt.savefig(trace_name+'_seeds.pdf', bbox_inches="tight") - - - plt.figure() - plt.plot(D['n_candidates']) - plt.title('Candidates') - plt.show() - -# plt.figure() -# plt.plot()) - -if __name__=="__main__": - - dataset='20131003_1937_nslam_i7_asl2_fast' - n_align_frames = 10 - save = True - results_dir = '../results/'+dataset - logfile = results_dir+'/'+dataset+'_0.csv' - - # parse command line - parser = argparse.ArgumentParser(description=''' - This script computes the absolute trajectory error from the ground truth trajectory and the estimated trajectory. - ''') - parser.add_argument('--trace_file', help='nanoslam tracefile with timings and logs', default=logfile) - parser.add_argument('--trace_name', help='name of the tracefile, used for saving figures etc.', default=results_dir+'/') - args = parser.parse_args() - - # tracefile - data = csv.reader(open(args.trace_file)) - fields = data.next() - D = dict() - for field in fields: - D[field] = list() - - # fill dictionary with column values - for row in data: - for (field, value) in zip(fields, row): - D[field].append(float(value)) - - # change dictionary values from list to numpy array for easier manipulation - for field, value in D.items(): - D[field] = np.array(D[field]) - - analyse_logs(D, args.trace_name) + # ---------------------------------------------------------------------------- + # plot number of candidate points + fig = plt.figure(figsize=(8,2)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='px') + ax.plot(D['timestamp'][is_frame], D['sfba_thresh'][is_frame], 'r-', label='Threshold') + fig.tight_layout() + fig.savefig(os.path.join(trace_dir,'optimization_thresh.pdf'), bbox_inches="tight") diff --git a/svo_analysis/src/svo_analysis/analyse_timing.py b/svo_analysis/src/svo_analysis/analyse_timing.py index b0d2199..0dfc1bc 100755 --- a/svo_analysis/src/svo_analysis/analyse_timing.py +++ b/svo_analysis/src/svo_analysis/analyse_timing.py @@ -1,97 +1,68 @@ #!/usr/bin/python -import argparse -import csv +import os import numpy as np import matplotlib.pyplot as plt -from matplotlib import rc -def analyse_timing(D, trace_name): +def analyse_timing(D, trace_dir): # identify measurements which result from normal frames and which from keyframes is_frame = np.argwhere(D['repr_n_mps'] >= 0) n_frames = len(is_frame) + + # set initial time to zero + D['timestamp'] = D['timestamp'] - D['timestamp'][0] + # ---------------------------------------------------------------------------- # plot total time for frame processing - avg_time = np.mean(D['t_tot_time'][is_frame])*1000; - + avg_time = np.mean(D['tot_time'][is_frame])*1000; fig = plt.figure(figsize=(8, 3)) ax = fig.add_subplot(111, ylabel='processing time [ms]', xlabel='time [s]') - ax.plot(np.arange(n_frames), D['t_tot_time'][is_frame]*1000, 'g-', label='total time [ms]') - ax.plot(np.arange(n_frames), np.ones(n_frames)*avg_time, 'b--', label=str('%(time).1fms mean time' % {'time': avg_time})) + ax.plot(D['timestamp'][is_frame], D['tot_time'][is_frame]*1000, 'g-', label='total time [ms]') + ax.plot(D['timestamp'][is_frame], np.ones(n_frames)*avg_time, 'b--', label=str('%(time).1fms mean time' % {'time': avg_time})) ax.legend() fig.tight_layout() - fig.savefig(trace_name+'_img_tot_processing_time.pdf', bbox_inches="tight") + fig.savefig(os.path.join(trace_dir,'timing.pdf'), bbox_inches="tight") + # ---------------------------------------------------------------------------- + # plot boxplot fig = plt.figure(figsize=(6,2)) ax = fig.add_subplot(111, xlabel='Processing time [ms]') ax.boxplot([ - D['t_tot_time'][is_frame]*1000, + D['tot_time'][is_frame]*1000, # D['t_local_ba'][is_kf]*1000, - D['t_pose_optimizer'][is_frame]*1000 + D['t_point_optimizer'][is_frame]*1000, - D['t_reproject'][is_frame]*1000, - D['t_sparse_img_align'][is_frame]*1000, - D['t_pyramid_creation'][is_frame]*1000 - ], 0,'', vert=0) # + D['pose_optimizer'][is_frame]*1000 + D['point_optimizer'][is_frame]*1000, + D['reproject'][is_frame]*1000, + D['sparse_img_align'][is_frame]*1000, + D['pyramid_creation'][is_frame]*1000 + ], 0,'', vert=0) boxplot_labels = [ - r'\textbf{Total Motion Estimation: %2.2fms}' % np.median(D['t_tot_time'][is_frame]*1000), -# 'Local BA (KF only): %.2fms ' % np.median(D['t_local_ba'][is_kf]*1000), - 'Refinement: %2.2fms' % np.median(D['t_pose_optimizer'][is_frame]*1000 + D['t_point_optimizer'][is_frame]*1000), - 'Feature Alignment: %2.2fms' % np.median(D['t_reproject'][is_frame]*1000), - 'Sparse Image Alignment: %2.2fms' % np.median(D['t_sparse_img_align'][is_frame]*1000), - 'Pyramid Creation: %2.2fms' % np.median(D['t_pyramid_creation'][is_frame]*1000) ] + r'\textbf{Total Motion Estimation: %2.2fms}' % np.median(D['tot_time'][is_frame]*1000), +# 'Local BA (KF only): %.2fms ' % np.median(D['local_ba'][is_kf]*1000), + 'Refinement: %2.2fms' % np.median(D['pose_optimizer'][is_frame]*1000 + D['point_optimizer'][is_frame]*1000), + 'Feature Alignment: %2.2fms' % np.median(D['reproject'][is_frame]*1000), + 'Sparse Image Alignment: %2.2fms' % np.median(D['sparse_img_align'][is_frame]*1000), + 'Pyramid Creation: %2.2fms' % np.median(D['pyramid_creation'][is_frame]*1000) ] ax.set_yticks(np.arange(len(boxplot_labels))+1) ax.set_yticklabels(boxplot_labels) fig.tight_layout() - fig.savefig(trace_name+'_timing_boxplot.pdf', bbox_inches="tight") + fig.savefig(os.path.join(trace_dir,'timing_boxplot.pdf'), bbox_inches="tight") - fig = plt.figure(figsize=(8, 5)) - ax = fig.add_subplot(111, ylabel='time [ms]') - ax.plot(D['t_reproject']*1000, 'r', label='reproject') - ax.plot(D['t_reproject_find_pts']*1000, 'g', label='reproject find pts') # ok! - ax.plot(D['t_reproject_best']*1000, 'm', label='reproject best') - ax.plot(D['t_reproject_candidates']*1000, 'b', label='reproject candidates') - ax.legend() + # ---------------------------------------------------------------------------- + # plot boxplot reprojection + fig = plt.figure(figsize=(6,2)) + ax = fig.add_subplot(111, xlabel='Processing time [ms]') + ax.boxplot([ D['reproject'][is_frame]*1000, + D['feature_align'][is_frame]*1000, + D['reproject_candidates'][is_frame]*1000, + D['reproject_kfs'][is_frame]*1000 ], 0, '', vert=0) + boxplot_labels = [r'\textbf{Total Reprojection: %2.2fms}' % np.median(D['reproject'][is_frame]*1000), + 'Feature Alignment: %2.2fms' % np.median(D['feature_align'][is_frame]*1000), + 'Reproject Candidates: %2.2fms' % np.median(D['reproject_candidates'][is_frame]*1000), + 'Reproject Keyframes: %2.2fms' % np.median(D['reproject_kfs'][is_frame]*1000) ] + ax.set_yticks(np.arange(len(boxplot_labels))+1) + ax.set_yticklabels(boxplot_labels) fig.tight_layout() - fig.savefig(trace_name+'_reprojection.pdf', bbox_inches="tight") - - -if __name__=="__main__": - - # config - dataset='20131003_1937_nslam_i7_asl2_fast' - results_dir = '../results/'+dataset - tracefile = results_dir + '/'+dataset+'_0.csv' - - # parse command line - parser = argparse.ArgumentParser(description=''' - This script computes the absolute trajectory error from the ground truth trajectory and the estimated trajectory. - ''') - parser.add_argument('--trace_file', help='nanoslam tracefile with timings and logs', default=tracefile) - parser.add_argument('--trace_name', help='name of the tracefile, used for saving figures etc.', default=results_dir) - args = parser.parse_args() - results_dir = args.trace_name - - # tracefile - data = csv.reader(open(args.trace_file)) - fields = data.next() - D = dict() - for field in fields: - D[field] = list() - - # fill dictionary with column values - for row in data: - for (field, value) in zip(fields, row): - D[field].append(float(value)) - - # change dictionary values from list to numpy array for easier manipulation - for field, value in D.items(): - D[field] = np.array(D[field]) - - # tell matplotlib to use latex font - rc('font',**{'family':'serif','serif':['Cardo']}) - rc('text', usetex=True) - - \ No newline at end of file + fig.savefig(os.path.join(trace_dir,'timing_reprojection.pdf'), bbox_inches="tight") \ No newline at end of file From 575d6dae2a52460532784187a9a10572f2ae2a30 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 28 Mar 2014 12:20:31 +0100 Subject: [PATCH 036/215] fixed reference --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 36cf767..ec47e5e 100644 --- a/README.md +++ b/README.md @@ -165,9 +165,9 @@ Citing If you use SVO in an academic context, please cite the following publication: - @article{Forster2014ICRA, + @inproceedings{Forster2014ICRA, author = {Forster, Christian and Pizzoli, Matia and Scaramuzza, Davide}, - title = {{SVO: Fast Semi-Direct Monocular Visual Odometry}}, - journal = {IEEE International Conference on Robotics and Automation (ICRA)}, + title = {{SVO}: Fast Semi-Direct Monocular Visual Odometry}, + booktitle = {IEEE International Conference on Robotics and Automation (ICRA)}, year = {2014} } From 183493c7ce35bb11e8dbb38d87b96f8ce3d7c266 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 28 Mar 2014 17:23:25 +0100 Subject: [PATCH 037/215] bug in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ec47e5e..f8e5dae 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ Now we are ready to build SVO. Clone it into your catkin workspace cd catkin_ws/src - git clone https://github.com/uzh-rpg/rpg_slam.git + git clone https://github.com/uzh-rpg/rpg_svo.git If you installed g2o then set `HAVE_G2O` in `svo/CMakeLists.txt` to TRUE. Then build From cf4782a63de1111b03dbc7928542dc3928880f8f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 31 Mar 2014 10:27:25 +0200 Subject: [PATCH 038/215] make benchmark work with other svo versions --- svo_analysis/scripts/benchmark.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index 326a4d7..19688ce 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -23,6 +23,8 @@ if __name__=="__main__": parser.add_argument('experiment_file', help='experiment file in svo_analysis/experiments folder') parser.add_argument('--name', help='experiment name') parser.add_argument('--evaluate', help='evaluate tracefile after running SVO', action='store_true') + parser.add_argument('--version', help='version of svo to evaluate', default='svo_ros') + parser.add_argument('--executable', help='the executable to be called', default='benchmark') args = parser.parse_args() # load experiment parameters @@ -33,7 +35,7 @@ if __name__=="__main__": expParams['platform'] = cpu_info.get_cpu_info() expParams['experiment_name'] = args.name if(expParams['experiment_name'] == None): - expParams['experiment_name'] = expParams['time']+'_svo_' + args.experiment_file + expParams['experiment_name'] = expParams['time']+'_'+args.version+'_' + args.experiment_file # load dataset parameters expParams['dataset_directory'] = os.path.join(rospkg.RosPack().get_path('Datasets'), expParams['dataset']) @@ -63,7 +65,7 @@ if __name__=="__main__": outfile.write(yaml.dump(params, default_flow_style=False)) # execute ros node - node = ros_node.RosNode('svo_ros','benchmark') + node = ros_node.RosNode(args.version, args.executable) node.run(params) # TODO: check if it is a synthetic dataset From 6a0e376e9089496cf2b161bca27ae35ce048d321 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 31 Mar 2014 11:16:47 +0200 Subject: [PATCH 039/215] added utility function to get trace and dataset dir --- svo/CMakeLists.txt | 11 ++----- svo/package.xml | 2 ++ svo/test/test_depth_filter.cpp | 10 +++--- svo/test/test_feature_alignment.cpp | 4 ++- svo/test/test_feature_detection.cpp | 3 +- svo/test/test_matcher.cpp | 20 ++++++------ svo/test/test_pipeline.cpp | 12 ++++---- svo/test/test_pose_optimizer.cpp | 3 +- svo/test/test_sparse_img_align.cpp | 8 +++-- svo/test/test_utils.h | 47 +++++++++++++++++++++++++++++ 10 files changed, 86 insertions(+), 34 deletions(-) create mode 100644 svo/test/test_utils.h diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 7612a94..08aafe3 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -49,7 +49,7 @@ ELSE() ENDIF() # Add catkin and required ROS packages -FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp vikit_common vikit_ros) +FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib vikit_common vikit_ros) # Add plain cmake packages FIND_PACKAGE(G2O REQUIRED) @@ -62,7 +62,7 @@ FIND_PACKAGE(Boost REQUIRED COMPONENTS system thread signals) # Describe catkin Project catkin_package( DEPENDS Eigen OpenCV Sophus Boost fast - CATKIN_DEPENDS roscpp vikit_common vikit_ros + CATKIN_DEPENDS roscpp roslib vikit_common vikit_ros INCLUDE_DIRS include LIBRARIES svo ) @@ -127,13 +127,6 @@ TARGET_LINK_LIBRARIES(svo ${LINK_LIBS}) ################################################################################ # TESTS -IF(DEFINED ENV{SVO_DATASET_DIR}) - ADD_DEFINITIONS(-DTEST_DATA_DIR=\"$ENV{SVO_DATASET_DIR}\") -ELSE() - ADD_DEFINITIONS(-DTEST_DATA_DIR=\"${PROJECT_SOURCE_DIR}/test/data\") -ENDIF() -ADD_DEFINITIONS(-DTEST_TRACE_DIR=\"${PROJECT_SOURCE_DIR}/test/results\") - ADD_EXECUTABLE(test_feature_align test/test_feature_alignment.cpp) TARGET_LINK_LIBRARIES(test_feature_align svo) diff --git a/svo/package.xml b/svo/package.xml index c2997c2..d51d015 100644 --- a/svo/package.xml +++ b/svo/package.xml @@ -14,11 +14,13 @@ roscpp + roslib vikit_common vikit_ros roscpp + roslib vikit_common vikit_ros \ No newline at end of file diff --git a/svo/test/test_depth_filter.cpp b/svo/test/test_depth_filter.cpp index 545d9bc..a53947d 100644 --- a/svo/test/test_depth_filter.cpp +++ b/svo/test/test_depth_filter.cpp @@ -32,6 +32,7 @@ #include #include #include +#include "test_utils.h" namespace { @@ -151,14 +152,15 @@ void DepthFilterTest::testReconstruction( } // trace error - std::string trace_name(std::string(TEST_TRACE_DIR) + "/depth_filter_" + experiment_name + ".txt"); + std::string trace_dir(svo::test_utils::getTraceDir()); + std::string trace_name(trace_dir + "/depth_filter_" + experiment_name + ".txt"); std::ofstream ofs(trace_name.c_str()); for(std::list::iterator i=results_.begin(); i!=results_.end(); ++i) ofs << i->x_ << ", " << i->y_ << ", " << fabs(i->error_) << std::endl; ofs.close(); // trace convergence rate - trace_name = std::string(TEST_TRACE_DIR) + "/depth_filter_" + experiment_name + "_convergence.txt"; + trace_name = trace_dir + "/depth_filter_" + experiment_name + "_convergence.txt"; ofs.open(trace_name.c_str()); for(std::list::iterator it=n_converged_per_iteration.begin(); it!=n_converged_per_iteration.end(); ++it) @@ -166,7 +168,7 @@ void DepthFilterTest::testReconstruction( ofs.close(); // write ply file for pointcloud visualization in Meshlab - trace_name = std::string(TEST_TRACE_DIR) + "/depth_filter_" + experiment_name + ".ply"; + trace_name = trace_dir + "/depth_filter_" + experiment_name + ".ply"; ofs.open(trace_name.c_str()); ofs << "ply" << std::endl << "format ascii 1.0" << std::endl @@ -193,7 +195,7 @@ void DepthFilterTest::testReconstruction( int main(int argc, char** argv) { DepthFilterTest test; - std::string dataset_dir(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1"); + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1"); std::string experiment_name("synth_fast_2d"); test.testReconstruction(dataset_dir, experiment_name); return 0; diff --git a/svo/test/test_feature_alignment.cpp b/svo/test/test_feature_alignment.cpp index 04bddf7..a7352e0 100644 --- a/svo/test/test_feature_alignment.cpp +++ b/svo/test/test_feature_alignment.cpp @@ -19,6 +19,7 @@ #include #include #include +#include "test_utils.h" #if __ARM_NEON__ #include #endif @@ -52,7 +53,8 @@ void generateRefPatchNoWarpInterpolate(const cv::Mat& img, const Vector2d& px, int main(int argc, char **argv) { - std::string img_name(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1/img/frame_000001_0.png"); + + std::string img_name(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1/img/frame_000001_0.png"); printf("Loading image '%s'\n", img_name.c_str()); cv::Mat img(cv::imread(img_name, 0)); assert(img.type() == CV_8UC1); diff --git a/svo/test/test_feature_detection.cpp b/svo/test/test_feature_detection.cpp index 00e21a2..6fa3723 100644 --- a/svo/test/test_feature_detection.cpp +++ b/svo/test/test_feature_detection.cpp @@ -23,6 +23,7 @@ #include #include #include +#include "test_utils.h" namespace { @@ -31,7 +32,7 @@ using namespace std; void testCornerDetector() { - std::string img_name(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1/img/frame_000001_0.png"); + std::string img_name(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1/img/frame_000001_0.png"); printf("Loading image '%s'\n", img_name.c_str()); cv::Mat img(cv::imread(img_name, 0)); assert(img.type() == CV_8UC1 && !img.empty()); diff --git a/svo/test/test_matcher.cpp b/svo/test/test_matcher.cpp index 3138d48..c81c1fe 100644 --- a/svo/test/test_matcher.cpp +++ b/svo/test/test_matcher.cpp @@ -22,6 +22,7 @@ #include #include #include +#include "test_utils.h" namespace { @@ -33,7 +34,7 @@ class MatcherTest { cam_ = new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240); // load images - std::string dataset_dir(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1"); + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1"); std::string img_name(dataset_dir+"/img/frame_000071_0.png"); printf("Loading image '%s'\n", img_name.c_str()); cv::Mat img_ref(cv::imread(img_name, 0)); @@ -112,31 +113,32 @@ void MatcherTest::testEpipolarSearchFullImg() } // compute mean, median and variance of error in converged area - printf("n converged: \t %zu (ref: 194472)\n", n_converged); - printf("mean error: \t %f (ref: 1.0848)\n", sum_error*100/n_converged); + printf("n converged: \t %zu mm (ref: 169936)\n", n_converged); + printf("mean error: \t %f mm (ref: 1.912410)\n", sum_error*100/n_converged); std::vector::iterator it = errors.begin()+0.5*errors.size(); std::nth_element(errors.begin(), it, errors.end()); - printf("50-percentile: \t %f (ref: 0.1343)\n", *it*100); + printf("50-percentile: \t %f mm (ref: 1.462241)\n", *it*100); it = errors.begin()+0.8*errors.size(); std::nth_element(errors.begin(), it, errors.end()); - printf("80-percentile: \t %f (ref: 0.3151)\n", *it*100); + printf("80-percentile: \t %f mm (ref: 2.620957)\n", *it*100); it = errors.begin()+0.95*errors.size(); std::nth_element(errors.begin(), it, errors.end()); - printf("95-percentile: \t %f (ref: 1.3753)\n", *it*100); + printf("95-percentile: \t %f mm (ref: 4.154051)\n", *it*100); // save results to file std::ofstream output_stream; - std::string output_filename(std::string(TEST_TRACE_DIR) + "/depthmap.bin"); + std::string trace_dir(svo::test_utils::getTraceDir()); + std::string output_filename(trace_dir + "/depthmap.bin"); output_stream.open(output_filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); output_stream.write((const char *)depthmap.data, depthmap.rows*depthmap.cols*sizeof(float)); output_stream.close(); - output_filename.assign(std::string(TEST_TRACE_DIR) + "/depthmap_error.bin"); + output_filename.assign(trace_dir + "/depthmap_error.bin"); output_stream.open(output_filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); output_stream.write((const char *)error_map.data, error_map.rows*error_map.cols*sizeof(float)); output_stream.close(); - output_filename.assign(std::string(TEST_TRACE_DIR) + "/depthmap_mask.bin"); + output_filename.assign(trace_dir + "/depthmap_mask.bin"); output_stream.open(output_filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); output_stream.write((const char *)mask.data, mask.rows*mask.cols*sizeof(uint8_t)); output_stream.close(); diff --git a/svo/test/test_pipeline.cpp b/svo/test/test_pipeline.cpp index d328bf1..364b089 100644 --- a/svo/test/test_pipeline.cpp +++ b/svo/test/test_pipeline.cpp @@ -28,6 +28,7 @@ #include #include #include +#include "test_utils.h" namespace svo { @@ -44,8 +45,6 @@ public: BenchmarkNode::BenchmarkNode() { - Config::traceName() = "benchmark"; - Config::traceDir() = std::string(TEST_TRACE_DIR)+"/.."; cam_ = new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240); vo_ = new svo::FrameHandlerMono(cam_); vo_->start(); @@ -62,8 +61,9 @@ void BenchmarkNode::runFromFolder() for(int img_id = 1; img_id < 310; ++img_id) { // load image - std::stringstream ss; - ss << std::string(TEST_DATA_DIR) << "/flying_room_1_rig_1/img/frame_" << std::setw( 6 ) << std::setfill( '0' ) << img_id << "_0.png"; + std::stringstream ss; + ss << svo::test_utils::getDatasetDir() << "/flying_room_1_rig_1/img/frame_" + << std::setw( 6 ) << std::setfill( '0' ) << img_id << "_0.png"; if(img_id == 1) std::cout << "reading image " << ss.str() << std::endl; cv::Mat img(cv::imread(ss.str().c_str(), 0)); @@ -75,8 +75,8 @@ void BenchmarkNode::runFromFolder() // display tracking quality if(vo_->lastFrame() != NULL) std::cout << "Frame-Id: " << vo_->lastFrame()->id_ << " \t" - << "#Features: " << vo_->lastNumObservations() << " \t" - << "Proc. Time: " << vo_->lastProcessingTime()*1000 << "ms \n"; + << "#Features: " << vo_->lastNumObservations() << " \t" + << "Proc. Time: " << vo_->lastProcessingTime()*1000 << "ms \n"; } } diff --git a/svo/test/test_pose_optimizer.cpp b/svo/test/test_pose_optimizer.cpp index 0c9a63f..0f1ea31 100644 --- a/svo/test/test_pose_optimizer.cpp +++ b/svo/test/test_pose_optimizer.cpp @@ -25,6 +25,7 @@ #include #include #include +#include "test_utils.h" namespace { @@ -39,7 +40,7 @@ class PoseOptimizerTest { cam_ = new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240); // load image - std::string dataset_dir(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1"); + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1"); std::string img_name(dataset_dir+"/img/frame_000001_0.png"); printf("Loading image '%s'\n", img_name.c_str()); cv::Mat img(cv::imread(img_name, 0)); diff --git a/svo/test/test_sparse_img_align.cpp b/svo/test/test_sparse_img_align.cpp index 51950a8..dbb4c20 100644 --- a/svo/test/test_sparse_img_align.cpp +++ b/svo/test/test_sparse_img_align.cpp @@ -26,6 +26,7 @@ #include #include #include +#include "test_utils.h" namespace { @@ -68,7 +69,8 @@ void SparseImgAlignTest::testSequence( std::list translation_error; Sophus::SE3 T_prev_w, T_prevgt_w; - std::string trace_name(std::string(TEST_TRACE_DIR) + "/sparse_img_align_" + experiment_name + "_trans_estimate.txt"); + std::string trace_dir(svo::test_utils::getTraceDir()); + std::string trace_name(trace_dir + "/sparse_img_align_" + experiment_name + "_trans_estimate.txt"); std::ofstream ofs(trace_name.c_str()); for(int i=0; iter != sequence.end() && i<30; ++iter, ++i) { @@ -142,7 +144,7 @@ void SparseImgAlignTest::testSequence( ofs.close(); // trace error - trace_name = std::string(TEST_TRACE_DIR) + "/sparse_img_align_" + experiment_name + "_trans_error.txt"; + trace_name = trace_dir + "/sparse_img_align_" + experiment_name + "_trans_error.txt"; ofs.open(trace_name.c_str()); for(std::list::iterator it=translation_error.begin(); it!=translation_error.end(); ++it) ofs << *it << std::endl; @@ -155,7 +157,7 @@ void SparseImgAlignTest::testSequence( int main(int argc, char** argv) { std::string experiment_name("flying_room_1_rig_1_fast_minlev0"); - std::string dataset_dir(std::string(TEST_DATA_DIR) + "/flying_room_1_rig_1"); + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1"); svo::feature_detection::FastDetector detector; svo::Config::triangMinCornerScore() = 20; svo::Config::kltMinLevel() = 0; diff --git a/svo/test/test_utils.h b/svo/test/test_utils.h new file mode 100644 index 0000000..5793bb7 --- /dev/null +++ b/svo/test/test_utils.h @@ -0,0 +1,47 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef TEST_UTILS_H_ +#define TEST_UTILS_H_ + +#include +#include // for getenv +#include +#include + +namespace svo { +namespace test_utils { + +std::string getDatasetDir() +{ + std::string dataset_dir(ros::package::getPath("svo")+"/test/data"); + const char* env_dir = std::getenv("SVO_DATASET_DIR"); + if(env_dir != NULL) + dataset_dir = std::string(env_dir); + return dataset_dir; +} + +std::string getTraceDir() +{ + std::string default_dir(ros::package::getPath("svo")+"/test/results"); + return vk::getParam("svo/trace_dir", default_dir); +} + +} // namespace test_utils +} // namespace svo + + +#endif // TEST_UTILS_H_ From f7c5e4ab76e05bee3d875d3923b6dcd5bf163947 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 31 Mar 2014 11:38:06 +0200 Subject: [PATCH 040/215] added README to svo_analysis --- svo_analysis/README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 svo_analysis/README.md diff --git a/svo_analysis/README.md b/svo_analysis/README.md new file mode 100644 index 0000000..a6cc2a7 --- /dev/null +++ b/svo_analysis/README.md @@ -0,0 +1,27 @@ +## SVO Analysis + +#### Download Test Data + +Create a folder where you will store all datasets, e.g.: + + mkdir Datasets + +In your `.bashrc` script, create a new environment variable pointing to the dataset folder: + + export SVO_DATASET_DIR=${HOME}/Datasets + +Source your new `.bashrc` script, go to the new dataset folder and download the test data: + + source `~/.bashrc` + cd ${SVO_DATASET_DIR} + wget http://rpg.ifi.uzh.ch/datasets/flying_room_1_rig_1.tar.gz -O - | tar -xz + + +#### Run Benchmark + +In SVO you need to set the `TRACE` flag to `TRUE` and recompile SVO. +Afterwards run + + rosrun svo_analysis benchmark.py flying_room_1_fast + +The script will create a new folder in `svo_analysis/results/`, run svo on the dataset and save the tracefile in this folder and at the end it will run some scripts to generate plots from the tracefile. \ No newline at end of file From ac8b7be117ee6ee0d623c7a06b5fafa256207d92 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 31 Mar 2014 11:38:32 +0200 Subject: [PATCH 041/215] set trace flag to FALSE --- svo/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 08aafe3..3c55cef 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -2,7 +2,7 @@ # user build settings SET(DEBUG FALSE) -SET(TRACE TRUE) +SET(TRACE FALSE) SET(HAVE_G2O FALSE) ################################################################################ From 9f355624d6fe8df0d887aeb8ed4d2dc83f34ffdf Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 31 Mar 2014 11:40:29 +0200 Subject: [PATCH 042/215] Update README.md --- svo_analysis/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/svo_analysis/README.md b/svo_analysis/README.md index a6cc2a7..0a4deeb 100644 --- a/svo_analysis/README.md +++ b/svo_analysis/README.md @@ -19,9 +19,9 @@ Source your new `.bashrc` script, go to the new dataset folder and download the #### Run Benchmark -In SVO you need to set the `TRACE` flag to `TRUE` and recompile SVO. +In the _CMakeLists.txt_ of SVO you need to set the `TRACE` flag to `TRUE` and recompile SVO. Afterwards run rosrun svo_analysis benchmark.py flying_room_1_fast -The script will create a new folder in `svo_analysis/results/`, run svo on the dataset and save the tracefile in this folder and at the end it will run some scripts to generate plots from the tracefile. \ No newline at end of file +The script will create a new folder in `svo_analysis/results/`, run svo on the dataset and save the tracefile in this folder and at the end it will run some scripts to generate plots from the tracefile. From 8cf1504f7cca7be288b3d455a5638083a3c21ac1 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 31 Mar 2014 19:31:11 +0200 Subject: [PATCH 043/215] combined reprojection functions in new reprojector class --- svo/CMakeLists.txt | 4 +- svo/include/svo/frame_handler_mono.h | 4 +- svo/include/svo/reprojection.h | 98 --------------- svo/include/svo/reprojector.h | 98 +++++++++++++++ svo/src/frame_handler_base.cpp | 1 - svo/src/frame_handler_mono.cpp | 14 +-- svo/src/{reprojection.cpp => reprojector.cpp} | 115 ++++++++---------- 7 files changed, 160 insertions(+), 174 deletions(-) delete mode 100644 svo/include/svo/reprojection.h create mode 100644 svo/include/svo/reprojector.h rename svo/src/{reprojection.cpp => reprojector.cpp} (63%) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 3c55cef..ae995f4 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -2,7 +2,7 @@ # user build settings SET(DEBUG FALSE) -SET(TRACE FALSE) +SET(TRACE TRUE) SET(HAVE_G2O FALSE) ################################################################################ @@ -109,7 +109,7 @@ LIST(APPEND SOURCEFILES src/pose_optimizer.cpp src/initialization.cpp src/matcher.cpp - src/reprojection.cpp + src/reprojector.cpp src/feature_alignment.cpp src/feature_detection.cpp src/depth_filter.cpp diff --git a/svo/include/svo/frame_handler_mono.h b/svo/include/svo/frame_handler_mono.h index f15afaf..2887713 100644 --- a/svo/include/svo/frame_handler_mono.h +++ b/svo/include/svo/frame_handler_mono.h @@ -19,7 +19,7 @@ #include #include -#include +#include #include namespace svo { @@ -49,7 +49,7 @@ public: protected: vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit). - reprojection::Grid reprojection_grid_; //!< Grid used for reprojection to make sure we have evenly distributed features. + Reprojector reprojector_; //!< Projects points from other keyframes into the current frame FramePtr new_frame_; //!< Current frame. FramePtr last_frame_; //!< Last frame, not necessarily a keyframe. set core_kfs_; //!< Keyframes in the closer neighbourhood. diff --git a/svo/include/svo/reprojection.h b/svo/include/svo/reprojection.h deleted file mode 100644 index a6ce153..0000000 --- a/svo/include/svo/reprojection.h +++ /dev/null @@ -1,98 +0,0 @@ -// This file is part of SVO - Semi-direct Visual Odometry. -// -// Copyright (C) 2014 Christian Forster -// (Robotics and Perception Group, University of Zurich, Switzerland). -// -// SVO is free software: you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the Free Software -// Foundation, either version 3 of the License, or any later version. -// -// SVO is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#ifndef SVO_REPROJECTION_H_ -#define SVO_REPROJECTION_H_ - -#include -#include - -namespace vk { - class AbstractCamera; -} - -namespace svo { - -class Map; -class Point; -class MapPointCandidates; - -/// Project points from the map into the image and find the corresponding -/// feature (corner). We don't search a match for every point but only for one -/// point per cell. Thereby, we achieve a homogeneously distributed set of -/// matched features and at the same time we can save processing time by not -/// projecting all points. -namespace reprojection { - -/// A candidate is a point that projects into the image plane and for which we -/// will search a maching feature in the image. -struct Candidate { - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - - Point* pt; //!< 3D point. - Vector2d px; //!< projected 2D pixel location. - Candidate(Point* pt, Vector2d& px) - : pt(pt), - px(px) - {} -}; - -typedef std::list > Cell; -typedef std::vector CandidateGrid; - -/// The grid stores a set of candidate matches. For every grid cell we try to find one match. -struct Grid -{ - CandidateGrid cells; - vector cell_order; - int cell_size; - int grid_n_cols; - int grid_n_rows; - Grid(); - void initialize(vk::AbstractCamera* cam); - ~Grid(); -}; - -/// Reset the grid -void resetGrid(Grid& grid); - -/// Project points from the map into the image. First finds keyframes with -/// overlapping field of view and projects only those map-points. -void reprojectMap( - Map& map, - FramePtr frame, - Grid& grid, - MapPointCandidates& candidate_points, - std::vector< std::pair >& overlap_kfs, - size_t& n_matches, - size_t& n_trials); - -bool reprojectCell( - Cell& cell, - FramePtr frame, - Map& map, - MapPointCandidates& candidate_points, - size_t& n_trials); - -bool reprojectPoint( - Grid& grid, - FramePtr frame, - Point* point); - -} // namespace reprojection -} // namespace svo - -#endif // SVO_REPROJECTION_H_ diff --git a/svo/include/svo/reprojector.h b/svo/include/svo/reprojector.h new file mode 100644 index 0000000..b2f4a20 --- /dev/null +++ b/svo/include/svo/reprojector.h @@ -0,0 +1,98 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_REPROJECTION_H_ +#define SVO_REPROJECTION_H_ + +#include +#include + +namespace vk { +class AbstractCamera; +} + +namespace svo { + +class Map; +class Point; + +/// Project points from the map into the image and find the corresponding +/// feature (corner). We don't search a match for every point but only for one +/// point per cell. Thereby, we achieve a homogeneously distributed set of +/// matched features and at the same time we can save processing time by not +/// projecting all points. +class Reprojector +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + /// Reprojector config parameters + struct Options { + size_t max_n_kfs; //!< max number of keyframes to reproject from + Options() + : max_n_kfs(10) + {} + } options_; + + size_t n_matches_; + size_t n_trials_; + + Reprojector(vk::AbstractCamera* cam, Map& map); + + ~Reprojector(); + + /// Project points from the map into the image. First finds keyframes with + /// overlapping field of view and projects only those map-points. + void reprojectMap( + FramePtr frame, + std::vector< std::pair >& overlap_kfs); + +private: + + /// A candidate is a point that projects into the image plane and for which we + /// will search a maching feature in the image. + struct Candidate { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + Point* pt; //!< 3D point. + Vector2d px; //!< projected 2D pixel location. + Candidate(Point* pt, Vector2d& px) : pt(pt), px(px) {} + }; + typedef std::list > Cell; + typedef std::vector CandidateGrid; + + /// The grid stores a set of candidate matches. For every grid cell we try to find one match. + struct Grid + { + CandidateGrid cells; + vector cell_order; + int cell_size; + int grid_n_cols; + int grid_n_rows; + }; + + Grid grid_; + Map& map_; + + static bool pointQualityComparator(Candidate& lhs, Candidate& rhs); + void initializeGrid(vk::AbstractCamera* cam); + void resetGrid(); + bool reprojectCell(Cell& cell, FramePtr frame); + bool reprojectPoint(FramePtr frame, Point* point); +}; + +} // namespace svo + +#endif // SVO_REPROJECTION_H_ diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index 3a8bad7..5a36bbc 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include namespace svo diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index b0846c0..441a262 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -33,10 +33,9 @@ namespace svo { FrameHandlerMono:: FrameHandlerMono(vk::AbstractCamera* cam) : FrameHandlerBase(), - cam_(cam) -{ - reprojection_grid_.initialize(cam_); -} + cam_(cam), + reprojector_(cam_, map_) +{} FrameHandlerMono:: ~FrameHandlerMono() @@ -141,11 +140,10 @@ processFrame() // map reprojection & feature alignment SVO_START_TIMER("reproject"); - size_t repr_n_new_references, repr_n_mps; - reprojection::reprojectMap( - map_, new_frame_, reprojection_grid_, map_.point_candidates_, - overlap_kfs_, repr_n_new_references, repr_n_mps); + reprojector_.reprojectMap(new_frame_, overlap_kfs_); SVO_STOP_TIMER("reproject"); + const size_t repr_n_new_references = reprojector_.n_matches_; + const size_t repr_n_mps = reprojector_.n_trials_; SVO_LOG2(repr_n_mps, repr_n_new_references); SVO_DEBUG_STREAM("Reprojection:\t nPoints = "< > close_kfs; - map.getCloseKeyframes(frame, close_kfs); + map_.getCloseKeyframes(frame, close_kfs); - // Sort KFs with overlap according to their closeness // TODO is this still necessary? + // Sort KFs with overlap according to their closeness close_kfs.sort(boost::bind(&std::pair::second, _1) < boost::bind(&std::pair::second, _2)); // Reproject all mappoints of the closest N kfs with overlap. We only store // in which grid cell the points fall. - size_t n = 0, max_n = 10; - overlap_kfs.reserve(max_n); + size_t n = 0; + overlap_kfs.reserve(options_.max_n_kfs); for(auto it_frame=close_kfs.begin(), ite_frame=close_kfs.end(); - it_frame!=ite_frame && nfirst; overlap_kfs.push_back(pair(ref_frame,0)); @@ -100,7 +98,7 @@ void reprojectMap( if((*it_ftr)->point->last_projected_kf_id_ == frame->id_) continue; (*it_ftr)->point->last_projected_kf_id_ = frame->id_; - if(reprojectPoint(grid, frame, (*it_ftr)->point)) + if(reprojectPoint(frame, (*it_ftr)->point)) overlap_kfs.back().second++; } } @@ -109,17 +107,17 @@ void reprojectMap( // Now project all point candidates SVO_START_TIMER("reproject_candidates"); { - boost::unique_lock lock(candidate_points.mut_); - auto it=candidate_points.candidates_.begin(); - while(it!=candidate_points.candidates_.end()) + boost::unique_lock lock(map_.point_candidates_.mut_); + auto it=map_.point_candidates_.candidates_.begin(); + while(it!=map_.point_candidates_.candidates_.end()) { - if(!reprojectPoint(grid, frame, it->first)) + if(!reprojectPoint(frame, it->first)) { it->first->n_failed_reproj_ += 3; if(it->first->n_failed_reproj_ > 30) { - candidate_points.deleteCandidate(*it); - it = candidate_points.candidates_.erase(it); + map_.point_candidates_.deleteCandidate(*it); + it = map_.point_candidates_.candidates_.erase(it); continue; } } @@ -131,38 +129,32 @@ void reprojectMap( // Now we go through each grid cell and select one point to match. // At the end, we should have at maximum one reprojected point per cell. SVO_START_TIMER("feature_align"); - n_matches=0; n_trials=0; - for(size_t i=0; i (size_t) Config::maxFts()) + if(reprojectCell(*grid_.cells.at(grid_.cell_order[i]), frame)) + ++n_matches_; + if(n_matches_ > (size_t) Config::maxFts()) break; } SVO_STOP_TIMER("feature_align"); } -bool pointQualityComparator(Candidate& lhs, Candidate& rhs) +bool Reprojector::pointQualityComparator(Candidate& lhs, Candidate& rhs) { if(lhs.pt->type_ > rhs.pt->type_) return true; return false; } -bool reprojectCell( - Cell& cell, - FramePtr frame, - Map& map, - MapPointCandidates& candidate_points, - size_t& n_trials) +bool Reprojector::reprojectCell(Cell& cell, FramePtr frame) { - cell.sort(boost::bind(&pointQualityComparator, _1, _2)); + cell.sort(boost::bind(&Reprojector::pointQualityComparator, _1, _2)); Cell::iterator it=cell.begin(); while(it!=cell.end()) { - ++n_trials; + ++n_trials_; if(it->pt->type_ == Point::DELETED) { @@ -176,9 +168,9 @@ bool reprojectCell( { it->pt->n_failed_reproj_++; if(it->pt->type_ == Point::UNKNOWN_QUALITY && it->pt->n_failed_reproj_ > 15) - map.safeDeletePoint(it->pt); + map_.safeDeletePoint(it->pt); if(it->pt->type_ == Point::CANDIDATE && it->pt->n_failed_reproj_ > 30) - candidate_points.deleteCandidatePoint(it->pt); + map_.point_candidates_.deleteCandidatePoint(it->pt); it = cell.erase(it); continue; } @@ -201,20 +193,17 @@ bool reprojectCell( return false; } -bool reprojectPoint( - Grid& grid, - FramePtr frame, - Point* point) +bool Reprojector::reprojectPoint(FramePtr frame, Point* point) { Vector2d px(frame->w2c(point->pos_)); if(frame->cam_->isInFrame(px.cast(), 8)) // 8px is the patch size in the matcher { - const int k = static_cast(px[1]/grid.cell_size)*grid.grid_n_cols + static_cast(px[0]/grid.cell_size); - grid.cells.at(k)->push_back(Candidate(point, px)); + const int k = static_cast(px[1]/grid_.cell_size)*grid_.grid_n_cols + + static_cast(px[0]/grid_.cell_size); + grid_.cells.at(k)->push_back(Candidate(point, px)); return true; } return false; } -} // namespace reprojection } // namespace svo From 6308c10fa2692be457d8c9336ba6f9af9da632ee Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 31 Mar 2014 19:47:12 +0200 Subject: [PATCH 044/215] added reprojector option to not use feature alignment --- svo/include/svo/reprojector.h | 4 +++- svo/src/reprojector.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/svo/include/svo/reprojector.h b/svo/include/svo/reprojector.h index b2f4a20..cc6df72 100644 --- a/svo/include/svo/reprojector.h +++ b/svo/include/svo/reprojector.h @@ -42,8 +42,10 @@ public: /// Reprojector config parameters struct Options { size_t max_n_kfs; //!< max number of keyframes to reproject from + bool find_match_direct; Options() - : max_n_kfs(10) + : max_n_kfs(10), + find_match_direct(true) {} } options_; diff --git a/svo/src/reprojector.cpp b/svo/src/reprojector.cpp index 94645a6..3604d1a 100644 --- a/svo/src/reprojector.cpp +++ b/svo/src/reprojector.cpp @@ -163,7 +163,9 @@ bool Reprojector::reprojectCell(Cell& cell, FramePtr frame) } int feature_level; - bool found_match = matcher::findMatchDirect(*it->pt, *frame, it->px, feature_level); + bool found_match = true; + if(options_.find_match_direct) + found_match = matcher::findMatchDirect(*it->pt, *frame, it->px, feature_level); if(!found_match) { it->pt->n_failed_reproj_++; From 74a6d3d699caa8f2bfaf404bb9d6216f85f2db71 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 31 Mar 2014 21:21:24 +0200 Subject: [PATCH 045/215] refactoring --- svo/src/frame_handler_base.cpp | 24 ++++++++++-------------- svo/src/frame_handler_mono.cpp | 30 ++++++++++-------------------- 2 files changed, 20 insertions(+), 34 deletions(-) diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index 5a36bbc..504890a 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -35,8 +35,7 @@ namespace svo vk::PerformanceMonitor* g_permon = NULL; #endif -FrameHandlerBase:: -FrameHandlerBase() : +FrameHandlerBase::FrameHandlerBase() : stage_(STAGE_PAUSED), set_reset_(false), set_start_(false), @@ -85,16 +84,14 @@ FrameHandlerBase() : SVO_INFO_STREAM("NanoSlam initialized"); } -FrameHandlerBase:: -~FrameHandlerBase() +FrameHandlerBase::~FrameHandlerBase() { SVO_INFO_STREAM("SVO destructor invoked."); delete depth_filter_; SVO_INFO_STREAM("SVO destructed."); } -bool FrameHandlerBase:: -startFrameProcessingCommon(const double timestamp) +bool FrameHandlerBase::startFrameProcessingCommon(const double timestamp) { if(set_start_) { @@ -115,8 +112,7 @@ startFrameProcessingCommon(const double timestamp) return true; } -int FrameHandlerBase:: -finishFrameProcessingCommon( +int FrameHandlerBase::finishFrameProcessingCommon( const size_t update_id, const UpdateResult dropout, const size_t num_observations) @@ -146,8 +142,7 @@ finishFrameProcessingCommon( return 0; } -void FrameHandlerBase:: -resetCommon() +void FrameHandlerBase::resetCommon() { map_.reset(); stage_ = STAGE_PAUSED; @@ -159,8 +154,7 @@ resetCommon() SVO_INFO_STREAM("RESET"); } -void FrameHandlerBase:: -setTrackingQuality(const size_t num_observations) +void FrameHandlerBase::setTrackingQuality(const size_t num_observations) { tracking_quality_ = TRACKING_GOOD; if(num_observations < Config::qualityMinFts()) @@ -186,8 +180,10 @@ bool ptLastOptimComparator(Point* lhs, Point* rhs) return (lhs->last_structure_optim_ < rhs->last_structure_optim_); } -void FrameHandlerBase:: -optimizeStructure(FramePtr frame, size_t max_n_pts, int max_iter) +void FrameHandlerBase::optimizeStructure( + FramePtr frame, + size_t max_n_pts, + int max_iter) { deque pts; for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 441a262..641bb14 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -30,19 +30,16 @@ namespace svo { -FrameHandlerMono:: -FrameHandlerMono(vk::AbstractCamera* cam) : +FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam) : FrameHandlerBase(), cam_(cam), reprojector_(cam_, map_) {} -FrameHandlerMono:: -~FrameHandlerMono() +FrameHandlerMono::~FrameHandlerMono() {} -void FrameHandlerMono:: -addImage(const cv::Mat& img, const double timestamp) +void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) { if(!startFrameProcessingCommon(timestamp)) return; @@ -73,8 +70,7 @@ addImage(const cv::Mat& img, const double timestamp) finishFrameProcessingCommon(last_frame_->id_, res, last_frame_->nObs()); } -void FrameHandlerMono:: -setFirstFrame(const FramePtr& first_frame) +void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame) { resetAll(); last_frame_ = first_frame; @@ -83,8 +79,7 @@ setFirstFrame(const FramePtr& first_frame) stage_ = STAGE_DEFAULT_FRAME; } -FrameHandlerMono::UpdateResult FrameHandlerMono:: -processFirstFrame() +FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() { new_frame_->T_f_w_ = T_f_w_init_; if(klt_homography_init_.addFirstFrame(new_frame_) == initialization::FAILURE) @@ -96,8 +91,7 @@ processFirstFrame() return RESULT_IS_KEYFRAME; } -FrameHandlerMono::UpdateResult FrameHandlerMono:: -processSecondFrame() +FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() { initialization::InitResult res = klt_homography_init_.addSecondFrame(new_frame_); if(res == initialization::FAILURE) @@ -123,8 +117,7 @@ processSecondFrame() return RESULT_IS_KEYFRAME; } -FrameHandlerMono::UpdateResult FrameHandlerMono:: -processFrame() +FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() { // Set initial pose TODO use prior new_frame_->T_f_w_ = last_frame_->T_f_w_; @@ -225,8 +218,7 @@ processFrame() return RESULT_IS_KEYFRAME; } -void FrameHandlerMono:: -resetAll() +void FrameHandlerMono::resetAll() { resetCommon(); last_frame_.reset(); @@ -235,8 +227,7 @@ resetAll() overlap_kfs_.clear(); } -bool FrameHandlerMono:: -needNewKf(double scene_depth_mean) +bool FrameHandlerMono::needNewKf(double scene_depth_mean) { for(auto it=overlap_kfs_.begin(), ite=overlap_kfs_.end(); it!=ite; ++it) { @@ -249,8 +240,7 @@ needNewKf(double scene_depth_mean) return true; } -void FrameHandlerMono:: -setCoreKfs(size_t n_closest) +void FrameHandlerMono::setCoreKfs(size_t n_closest) { size_t n = min(n_closest, overlap_kfs_.size()-1); std::partial_sort(overlap_kfs_.begin(), overlap_kfs_.begin()+n, overlap_kfs_.end(), From d0a240604174a0c016b876b5334e3cb2c5547b4a Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 31 Mar 2014 21:21:34 +0200 Subject: [PATCH 046/215] updated trajectory comparison --- svo_analysis/experiments/.gitignore | 2 + svo_analysis/experiments/asl2_acc.yaml | 3 +- svo_analysis/experiments/asl2_fast.yaml | 3 +- svo_analysis/scripts/comparison.py | 160 +++++++++++------------- 4 files changed, 78 insertions(+), 90 deletions(-) create mode 100644 svo_analysis/experiments/.gitignore mode change 100644 => 100755 svo_analysis/scripts/comparison.py diff --git a/svo_analysis/experiments/.gitignore b/svo_analysis/experiments/.gitignore new file mode 100644 index 0000000..5b74354 --- /dev/null +++ b/svo_analysis/experiments/.gitignore @@ -0,0 +1,2 @@ +*.yaml +!.gitignore diff --git a/svo_analysis/experiments/asl2_acc.yaml b/svo_analysis/experiments/asl2_acc.yaml index 0b5bf3b..9e05b2e 100644 --- a/svo_analysis/experiments/asl2_acc.yaml +++ b/svo_analysis/experiments/asl2_acc.yaml @@ -1,2 +1,3 @@ dataset: asl_vicon_d2 -param_settings: vo_accurate \ No newline at end of file +param_settings: vo_accurate +experiment_label: 'svo acc' \ No newline at end of file diff --git a/svo_analysis/experiments/asl2_fast.yaml b/svo_analysis/experiments/asl2_fast.yaml index 34285b5..529b6bf 100644 --- a/svo_analysis/experiments/asl2_fast.yaml +++ b/svo_analysis/experiments/asl2_fast.yaml @@ -1,2 +1,3 @@ dataset: asl_vicon_d2 -param_settings: vo_fast \ No newline at end of file +param_settings: vo_fast +experiment_label: 'svo fast' \ No newline at end of file diff --git a/svo_analysis/scripts/comparison.py b/svo_analysis/scripts/comparison.py old mode 100644 new mode 100755 index 1bc219e..5605fe3 --- a/svo_analysis/scripts/comparison.py +++ b/svo_analysis/scripts/comparison.py @@ -1,32 +1,32 @@ -# -*- coding: utf-8 -*- +#!/usr/bin/python +import os +import sys +import time +import rospkg import numpy as np import matplotlib.pyplot as plt import yaml +import argparse from matplotlib import rc + +# tell matplotlib to use latex font +rc('font',**{'family':'serif','serif':['Cardo']}) +rc('text', usetex=True) + from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes from mpl_toolkits.axes_grid1.inset_locator import mark_inset - -def plotTrajectory(ax, filename, label, color, linewidth): +def plot_trajectory(ax, filename, label, color, linewidth): file = open(filename) data = file.read() lines = data.replace(","," ").replace("\t"," ").split("\n") trajectory = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) ax.plot(trajectory[:,1], trajectory[:,2], label=label, color=color, linewidth=linewidth) - -if __name__ == '__main__': +def compare_results(experiments, results_dir, comparison_dir, + plot_scale_drift = False): - results_dir = '../results' - experiments = ['20130911_2113_nslam_i7_asl2_acc', - '20130911_2229_nslam_i7_asl2_fast', - '20130906_2149_ptam_i7_asl2'] - - # tell matplotlib to use latex font - rc('font',**{'family':'serif','serif':['Cardo']}) - rc('text', usetex=True) - # ------------------------------------------------------------------------------ # position error fig_poserr = plt.figure(figsize=(8,6)) @@ -37,28 +37,25 @@ if __name__ == '__main__': for exp in experiments: # load dataset parameters - params_stream = open(results_dir+'/'+exp+'/params.yaml') + params_stream = open(os.path.join(results_dir, exp, 'params.yaml')) params = yaml.load(params_stream) # plot translation error - trans_error_filename = results_dir+'/'+exp+'/translation_error.txt' - file = open(trans_error_filename) - data = file.read() - lines = data.replace(","," ").replace("\t"," ").split("\n") - trans_error = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) + trans_error = np.loadtxt(os.path.join(results_dir, exp, 'translation_error.txt')) + trans_error[:,0] = trans_error[:,0]-trans_error[0,0] ax_poserr_x.plot(trans_error[:,0], trans_error[:,1], label=params['experiment_label']) ax_poserr_y.plot(trans_error[:,0], trans_error[:,2]) ax_poserr_z.plot(trans_error[:,0], trans_error[:,3]) ax_poserr_x.set_xlim([0, trans_error[-1,0]+4]) - ax_poserr_y.set_xlim([0, trans_error[-1,0]+4]) + ax_poserr_y.set_xlim([0, trans_error[-1,0]+4]) ax_poserr_z.set_xlim([0, trans_error[-1,0]+4]) ax_poserr_x.legend(bbox_to_anchor=[0, 0], loc='lower left', ncol=3) ax_poserr_x.grid() ax_poserr_y.grid() ax_poserr_z.grid() fig_poserr.tight_layout() - fig_poserr.savefig('../results/translation_error.pdf') + fig_poserr.savefig(os.path.join(comparison_dir, 'translation_error.pdf')) # ------------------------------------------------------------------------------ # orientation error @@ -70,15 +67,12 @@ if __name__ == '__main__': for exp in experiments: # load dataset parameters - params_stream = open(results_dir+'/'+exp+'/params.yaml') + params_stream = open(os.path.join(results_dir, exp, 'params.yaml')) params = yaml.load(params_stream) # plot translation error - rot_error_filename = results_dir+'/'+exp+'/orientation_error.txt' - file = open(rot_error_filename) - data = file.read() - lines = data.replace(","," ").replace("\t"," ").split("\n") - rot_error = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) + rot_error = np.loadtxt(os.path.join(results_dir, exp, 'orientation_error.txt')) + rot_error[:,0] = rot_error[:,0]-rot_error[0,0] ax_roterr_r.plot(rot_error[:,0], rot_error[:,3], label=params['experiment_label']) ax_roterr_p.plot(rot_error[:,0], rot_error[:,2]) ax_roterr_y.plot(rot_error[:,0], rot_error[:,1]) @@ -91,76 +85,66 @@ if __name__ == '__main__': ax_roterr_p.grid() ax_roterr_y.grid() fig_roterr.tight_layout() - fig_roterr.savefig('../results/orientation_error.pdf') + fig_roterr.savefig(os.path.join(comparison_dir, 'orientation_error.pdf')) # ------------------------------------------------------------------------------ # scale error - fig_scale = plt.figure(figsize=(8,2.5)) - ax_scale = fig_scale.add_subplot(111, xlabel='time [s]', ylabel='scale change [\%]') - - for exp in experiments: + if plot_scale_drift: + fig_scale = plt.figure(figsize=(8,2.5)) + ax_scale = fig_scale.add_subplot(111, xlabel='time [s]', ylabel='scale change [\%]') - # load dataset parameters - params_stream = open(results_dir+'/'+exp+'/params.yaml') - params = yaml.load(params_stream) + for exp in experiments: + + # load dataset parameters + params = yaml.load(open(os.path.join(results_dir, exp, 'params.yaml'))) + + # plot translation error + scale_drift = open(os.path.join(results_dir, exp, 'scale_drift.txt')) + scale_drift[:,0] = scale_drift[:,0]-scale_drift[0,0] + ax_scale.plot(scale_drift[:,0], scale_drift[:,1], label=params['experiment_label']) - # plot translation error - scale_drift_filename = results_dir+'/'+exp+'/scale_drift.txt' - file = open(scale_drift_filename) - data = file.read() - lines = data.replace(","," ").replace("\t"," ").split("\n") - scale_drift = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) - ax_scale.plot(scale_drift[:,0], scale_drift[:,1], label=params['experiment_label']) - - ax_scale.set_xlim([0, rot_error[-1,0]+4]) - ax_scale.legend(bbox_to_anchor=[0, 1], loc='upper left', ncol=3) - ax_scale.grid() - fig_scale.tight_layout() - fig_scale.savefig('../results/scale_drift.pdf') + ax_scale.set_xlim([0, rot_error[-1,0]+4]) + ax_scale.legend(bbox_to_anchor=[0, 1], loc='upper left', ncol=3) + ax_scale.grid() + fig_scale.tight_layout() + fig_scale.savefig(os.path.join(comparison_dir, 'scale_drift.pdf')) # ------------------------------------------------------------------------------ # trajectory - - fig_traj = plt.figure(figsize=(8,4.8)) - ax_traj = fig_traj.add_subplot(111, xlabel='x [m]', ylabel='y [m]', aspect='equal', xlim=[-3.1, 4], ylim=[-1.5, 2.6]) - - plotTrajectory(ax_traj, '/home/cforster/Datasets/asl_vicon_d2/groundtruth_filtered.txt', 'Groundtruth', 'k', 1.5) - plotTrajectory(ax_traj, results_dir+'/20130911_2229_nslam_i7_asl2_fast/traj_estimate_rotated.txt', 'Fast', 'g', 1) - plotTrajectory(ax_traj, results_dir+'/20130906_2149_ptam_i7_asl2/traj_estimate_rotated.txt', 'PTAM', 'r', 1) - - # show detail: - axins = zoomed_inset_axes(ax_traj, 5.0, loc=1) # zoom = 6 - plotTrajectory(axins, '/home/cforster/Datasets/asl_vicon_d2/groundtruth_filtered.txt', 'Groundtruth', 'k', 1.5) - plotTrajectory(axins, results_dir+'/20130911_2229_nslam_i7_asl2_fast/traj_estimate_rotated.txt', 'Fast', 'g', 1) - plotTrajectory(axins, results_dir+'/20130906_2149_ptam_i7_asl2/traj_estimate_rotated.txt', 'PTAM', 'r', 1) - axins.set_xlim(1.2, 1.70) - axins.set_ylim(-0.8, -0.3) - axins.patch.set_facecolor('0.9') - plt.xticks(visible=False) - plt.yticks(visible=False) - - mark_inset(ax_traj, axins, loc1=2, loc2=4, fc="none", ec='b') - plt.draw() - plt.show() - ax_traj.legend(bbox_to_anchor=[1, 0], loc='lower right', ncol=3) - ax_traj.grid() - fig_traj.tight_layout() - fig_traj.savefig('../results/trajectory_asl.pdf') +# fig_traj = plt.figure(figsize=(8,4.8)) +# ax_traj = fig_traj.add_subplot(111, xlabel='x [m]', ylabel='y [m]', aspect='equal', xlim=[-3.1, 4], ylim=[-1.5, 2.6]) +# +# plotTrajectory(ax_traj, '/home/cforster/Datasets/asl_vicon_d2/groundtruth_filtered.txt', 'Groundtruth', 'k', 1.5) +# plotTrajectory(ax_traj, results_dir+'/20130911_2229_nslam_i7_asl2_fast/traj_estimate_rotated.txt', 'Fast', 'g', 1) +# plotTrajectory(ax_traj, results_dir+'/20130906_2149_ptam_i7_asl2/traj_estimate_rotated.txt', 'PTAM', 'r', 1) +# +# mark_inset(ax_traj, axins, loc1=2, loc2=4, fc="none", ec='b') +# plt.draw() +# plt.show() +# ax_traj.legend(bbox_to_anchor=[1, 0], loc='lower right', ncol=3) +# ax_traj.grid() +# fig_traj.tight_layout() +# fig_traj.savefig('../results/trajectory_asl.pdf') - # ------------------------------------------------------------------------------ - # number of matches +if __name__ == '__main__': - # plot number of klt tracked and matched points -# fig = plt.figure(figsize=(8,2)) -# ax = fig.add_subplot(111, xlabel='time [s]', ylabel='no. features', ylim=[0,220]) -# ax.plot(np.arange(len(n_fts_1))/25.0, n_fts_1, 'b-', label='Accurate') -# ax.plot(np.arange(len(n_fts_2))/25.0, n_fts_2, 'g-', label='Fast') -# ax.legend(bbox_to_anchor=[1, 0], loc='lower right', ncol=2) -# fig.tight_layout() -# fig.savefig('../results/number_of_features2.pdf', bbox_inches="tight") -# + default_name = time.strftime("%Y%m%d_%H%M", time.localtime())+'_comparison' + parser = argparse.ArgumentParser(description='Compare results.') + parser.add_argument('result_directories', nargs='+', help='list of result directories to compare') + parser.add_argument('--name', help='name of the comparison', default=default_name) + args = parser.parse_args() + + # create folder for comparison results + results_dir = os.path.join(rospkg.RosPack().get_path('svo_analysis'), 'results') + comparison_dir = os.path.join(results_dir, args.name) + if not os.path.exists(comparison_dir): + os.makedirs(comparison_dir) + + # run comparison + compare_results(args.result_directories, results_dir, comparison_dir) - - \ No newline at end of file + + + From 4c722969a9255ad71dce2a1c8f8d0c0a1e9dc479 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 31 Mar 2014 21:44:31 +0200 Subject: [PATCH 047/215] move depth filter ownership to frame handler mono --- svo/include/svo/frame_handler_base.h | 4 ---- svo/include/svo/frame_handler_mono.h | 4 ++++ svo/src/frame_handler_base.cpp | 15 ++------------- svo/src/frame_handler_mono.cpp | 16 +++++++++++++--- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/svo/include/svo/frame_handler_base.h b/svo/include/svo/frame_handler_base.h index 50afc14..66d4595 100644 --- a/svo/include/svo/frame_handler_base.h +++ b/svo/include/svo/frame_handler_base.h @@ -87,9 +87,6 @@ public: /// Get the number of feature observations of the last frame. size_t lastNumObservations() const { return num_obs_last_; } - /// Access the depth filter. - DepthFilter* depthFilter() const { return depth_filter_; } - protected: Stage stage_; //!< Current stage of the algorithm. bool set_reset_; //!< Flag that the user can set. Will reset the system before the next iteration. @@ -101,7 +98,6 @@ protected: vk::RingBuffer acc_num_obs_; //!< Number of observed features of the last 10 frames, used to give some user feedback on the tracking performance. size_t num_obs_last_; //!< Number of observations in the previous frame. TrackingQuality tracking_quality_; //!< An estimate of the tracking quality based on the number of tracked features. - DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. /// Before a frame is processed, this function is called. bool startFrameProcessingCommon(const double timestamp); diff --git a/svo/include/svo/frame_handler_mono.h b/svo/include/svo/frame_handler_mono.h index 2887713..9024394 100644 --- a/svo/include/svo/frame_handler_mono.h +++ b/svo/include/svo/frame_handler_mono.h @@ -47,6 +47,9 @@ public: const vector& initFeatureTrackRefPx() const { return klt_homography_init_.px_ref_; } const vector& initFeatureTrackCurPx() const { return klt_homography_init_.px_cur_; } + /// Access the depth filter. + DepthFilter* depthFilter() const { return depth_filter_; } + protected: vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit). Reprojector reprojector_; //!< Projects points from other keyframes into the current frame @@ -55,6 +58,7 @@ protected: set core_kfs_; //!< Keyframes in the closer neighbourhood. vector< pair > overlap_kfs_; //!< All keyframes with overlapping field of view. the paired number specifies how many common mappoints are observed TODO: why vector!? initialization::KltHomographyInit klt_homography_init_; //!< Used to estimate pose of the first two keyframes by estimating a homography. + DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. /// Processes the first frame and sets it as a keyframe. UpdateResult processFirstFrame(); diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index 504890a..c3568d5 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -25,8 +25,7 @@ #include #include #include -#include - + namespace svo { @@ -42,8 +41,7 @@ FrameHandlerBase::FrameHandlerBase() : acc_frame_timings_(10), acc_num_obs_(10), num_obs_last_(0), - tracking_quality_(TRACKING_BAD), - depth_filter_(NULL) + tracking_quality_(TRACKING_BAD) { #ifdef SVO_TRACE // Initialize Performance Monitor @@ -75,20 +73,12 @@ FrameHandlerBase::FrameHandlerBase() : g_permon->init(Config::traceName(), Config::traceDir()); #endif - // create depth filter and set callback - feature_detection::DetectorPtr feature_detector(new feature_detection::FastDetector()); - DepthFilter::callback_t depth_filter_cb = boost::bind(&MapPointCandidates::newCandidatePoint, &map_.point_candidates_, _1, _2); - depth_filter_ = new DepthFilter(feature_detector, depth_filter_cb); - depth_filter_->startThread(); - SVO_INFO_STREAM("NanoSlam initialized"); } FrameHandlerBase::~FrameHandlerBase() { SVO_INFO_STREAM("SVO destructor invoked."); - delete depth_filter_; - SVO_INFO_STREAM("SVO destructed."); } bool FrameHandlerBase::startFrameProcessingCommon(const double timestamp) @@ -149,7 +139,6 @@ void FrameHandlerBase::resetCommon() set_reset_ = false; set_start_ = false; tracking_quality_ = TRACKING_BAD; - depth_filter_->reset(); num_obs_last_ = 0; SVO_INFO_STREAM("RESET"); } diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 641bb14..5804057 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -33,11 +33,20 @@ namespace svo { FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam) : FrameHandlerBase(), cam_(cam), - reprojector_(cam_, map_) -{} + reprojector_(cam_, map_), + depth_filter_(NULL) +{ + // create depth filter and set callback + feature_detection::DetectorPtr feature_detector(new feature_detection::FastDetector()); + DepthFilter::callback_t depth_filter_cb = boost::bind(&MapPointCandidates::newCandidatePoint, &map_.point_candidates_, _1, _2); + depth_filter_ = new DepthFilter(feature_detector, depth_filter_cb); + depth_filter_->startThread(); +} FrameHandlerMono::~FrameHandlerMono() -{} +{ + delete depth_filter_; +} void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) { @@ -225,6 +234,7 @@ void FrameHandlerMono::resetAll() new_frame_.reset(); core_kfs_.clear(); overlap_kfs_.clear(); + depth_filter_->reset(); } bool FrameHandlerMono::needNewKf(double scene_depth_mean) From cc382954052925f3726a29f0233f31159e27c97e Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 1 Apr 2014 16:32:14 +0200 Subject: [PATCH 048/215] refactor --- svo/include/svo/sparse_img_align.h | 2 +- svo/src/sparse_img_align.cpp | 49 ++++++++++++++---------------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/svo/include/svo/sparse_img_align.h b/svo/include/svo/sparse_img_align.h index 7df0456..17cb3a1 100644 --- a/svo/include/svo/sparse_img_align.h +++ b/svo/include/svo/sparse_img_align.h @@ -60,7 +60,7 @@ protected: int min_level_; //!< finest pyramid level for the alignment. // cache: - Matrix jacobian_cache_; //!< the first row is a flag whether the jacobian has been computed. + Matrix jacobian_cache_; bool have_ref_patch_cache_; cv::Mat ref_patch_cache_; std::vector visible_fts_; diff --git a/svo/src/sparse_img_align.cpp b/svo/src/sparse_img_align.cpp index c4a2afd..8a64833 100644 --- a/svo/src/sparse_img_align.cpp +++ b/svo/src/sparse_img_align.cpp @@ -26,12 +26,12 @@ namespace svo { -SparseImgAlign:: -SparseImgAlign(int max_level, int min_level, int n_iter, - Method method, bool display, bool verbose) : - display_(display), - max_level_(max_level), - min_level_(min_level) +SparseImgAlign::SparseImgAlign( + int max_level, int min_level, int n_iter, + Method method, bool display, bool verbose) : + display_(display), + max_level_(max_level), + min_level_(min_level) { n_iter_ = n_iter; n_iter_init_ = n_iter_; @@ -40,8 +40,7 @@ SparseImgAlign(int max_level, int min_level, int n_iter, eps_ = 0.000001; } -size_t SparseImgAlign:: -run(FramePtr ref_frame, FramePtr cur_frame) +size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) { reset(); @@ -55,7 +54,7 @@ run(FramePtr ref_frame, FramePtr cur_frame) cur_frame_ = cur_frame; ref_patch_cache_ = cv::Mat(ref_frame_->fts_.size(), patch_area_, CV_32F); jacobian_cache_.resize(Eigen::NoChange, ref_patch_cache_.rows*patch_area_); - visible_fts_.resize(ref_patch_cache_.rows, false); + visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? SE3 T_cur_from_ref(cur_frame_->T_f_w_ * ref_frame_->T_f_w_.inverse()); @@ -74,9 +73,7 @@ run(FramePtr ref_frame, FramePtr cur_frame) } // TODO take jacobian from Frame Class! -void -frameJac(const Vector3d & xyz, - Matrix & J) +void frameJac(const Vector3d & xyz, Matrix & J) { const double x = xyz[0]; const double y = xyz[1]; @@ -98,8 +95,7 @@ frameJac(const Vector3d & xyz, J(1,5) = x*z_inv; // x/z } -void SparseImgAlign:: -precomputeReferencePatches() +void SparseImgAlign::precomputeReferencePatches() { const int border = patch_halfsize_+1; const cv::Mat& ref_img = ref_frame_->img_pyr_.at(level_); @@ -162,15 +158,16 @@ precomputeReferencePatches() have_ref_patch_cache_ = true; } -double SparseImgAlign:: -computeResiduals(const SE3& T_cur_from_ref, bool linearize_system, bool compute_weight_scale) +double SparseImgAlign::computeResiduals( + const SE3& T_cur_from_ref, + bool linearize_system, + bool compute_weight_scale) { // Warp the (cur)rent image such that it aligns with the (ref)erence image - const cv::Mat& ref_img = ref_frame_->img_pyr_.at(level_); const cv::Mat& cur_img = cur_frame_->img_pyr_.at(level_); if(linearize_system && display_) - resimg_ = cv::Mat(ref_img.size(), CV_32F, cv::Scalar(0)); + resimg_ = cv::Mat(cur_img.size(), CV_32F, cv::Scalar(0)); if(have_ref_patch_cache_ == false) precomputeReferencePatches(); @@ -179,7 +176,7 @@ computeResiduals(const SE3& T_cur_from_ref, bool linearize_system, bool compute_ std::vector errors; if(compute_weight_scale) errors.reserve(visible_fts_.size()); - const int stride = ref_img.cols; + const int stride = cur_img.cols; const int border = patch_halfsize_+1; const float scale = 1.0f/(1<pos()); @@ -259,8 +256,7 @@ computeResiduals(const SE3& T_cur_from_ref, bool linearize_system, bool compute_ return chi2/n_meas_; } -int SparseImgAlign:: -solve() +int SparseImgAlign::solve() { x_ = H_.ldlt().solve(Jres_); if((bool) std::isnan((double) x_[0])) @@ -268,8 +264,9 @@ solve() return 1; } -void SparseImgAlign:: -update(const ModelType& T_curold_from_ref, ModelType& T_curnew_from_ref) +void SparseImgAlign::update( + const ModelType& T_curold_from_ref, + ModelType& T_curnew_from_ref) { // the jacobian is computed in the coordinate frame of the reference image // T_ref_from_curnew = T_ref_from_curold * SE3::exp(x_).inverse(); @@ -277,12 +274,10 @@ update(const ModelType& T_curold_from_ref, ModelType& T_curnew_from_ref) T_curnew_from_ref = SE3::exp(x_) * T_curold_from_ref; } -void SparseImgAlign:: -startIteration() +void SparseImgAlign::startIteration() {} -void SparseImgAlign:: -finishIteration() +void SparseImgAlign::finishIteration() { if(display_) { From 231cdf5b3d534854015d8196f7255eb9a3722f51 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 1 Apr 2014 18:04:25 +0200 Subject: [PATCH 049/215] changed update formula to correspond with the paper --- svo/src/sparse_img_align.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/svo/src/sparse_img_align.cpp b/svo/src/sparse_img_align.cpp index 8a64833..3278237 100644 --- a/svo/src/sparse_img_align.cpp +++ b/svo/src/sparse_img_align.cpp @@ -151,7 +151,7 @@ void SparseImgAlign::precomputeReferencePatches() // cache the jacobian jacobian_cache_.col(feature_counter*patch_area_ + pixel_counter) = - (dx*frame_jac.row(0) + dy*frame_jac.row(1))*(focal_length / (1< Date: Tue, 1 Apr 2014 18:04:47 +0200 Subject: [PATCH 050/215] added experiment label --- svo_analysis/experiments/flying_room_1_fast.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/svo_analysis/experiments/flying_room_1_fast.yaml b/svo_analysis/experiments/flying_room_1_fast.yaml index 018e1fe..20a9f9d 100644 --- a/svo_analysis/experiments/flying_room_1_fast.yaml +++ b/svo_analysis/experiments/flying_room_1_fast.yaml @@ -1,2 +1,3 @@ dataset: flying_room_1_rig_1 -param_settings: vo_fast \ No newline at end of file +param_settings: vo_fast +experiment_label: 'svo fast' \ No newline at end of file From 1f446108587a473370e61fae40ee679363dd11cd Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 1 Apr 2014 18:52:46 +0200 Subject: [PATCH 051/215] exp(x).inverse is the same as exp(-x) --- svo/src/sparse_img_align.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/src/sparse_img_align.cpp b/svo/src/sparse_img_align.cpp index 3278237..6dc97c8 100644 --- a/svo/src/sparse_img_align.cpp +++ b/svo/src/sparse_img_align.cpp @@ -268,7 +268,7 @@ void SparseImgAlign::update( const ModelType& T_curold_from_ref, ModelType& T_curnew_from_ref) { - T_curnew_from_ref = T_curold_from_ref * SE3::exp(x_).inverse(); + T_curnew_from_ref = T_curold_from_ref * SE3::exp(-x_); } void SparseImgAlign::startIteration() From a1e014c77cbfda1aaed33407daedd0404bfecd17 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 3 Apr 2014 10:08:18 +0200 Subject: [PATCH 052/215] refactoring Point, added point normal as member --- svo/include/svo/point.h | 15 +++++++++------ svo/src/initialization.cpp | 2 +- svo/src/map.cpp | 12 ++++++------ svo/src/point.cpp | 6 +++--- svo/src/reprojection.cpp | 10 +++++----- svo/test/test_pose_optimizer.cpp | 2 +- svo/test/test_sparse_img_align.cpp | 2 +- svo_ros/src/benchmark_node.cpp | 2 +- 8 files changed, 27 insertions(+), 24 deletions(-) diff --git a/svo/include/svo/point.h b/svo/include/svo/point.h index 1fa26f0..933b8bc 100644 --- a/svo/include/svo/point.h +++ b/svo/include/svo/point.h @@ -36,24 +36,27 @@ class Point : boost::noncopyable { public: - enum PointType {DELETED, CANDIDATE, UNKNOWN_QUALITY, GOOD_QUALITY }; - enum PointOrigin { TRIANGULATION, DEPTH, VOGIATZIS, IDFILTER }; + enum PointType { + TYPE_DELETED, + TYPE_CANDIDATE, + TYPE_UNKNOWN, + TYPE_GOOD }; static int point_counter_; //!< Counts the number of created points. Used to set the unique id. int id_; //!< Unique ID of the point. Vector3d pos_; //!< 3d pos of the point in the world coordinate frame. + Vector3d normal_; //!< Normal of the point list obs_; //!< References to keyframes which observe the point. - size_t n_obs_; //!< Number of obervations, not only keyframes. + size_t n_obs_; //!< Number of obervations: Keyframes AND successful reprojections in intermediate frames. g2oPoint* v_pt_; //!< Temporary pointer to the point-vertex in g2o during bundle adjustment. int last_published_ts_; //!< Timestamp of last publishing. int last_projected_kf_id_; //!< Flag for the reprojection: don't reproject a pt twice. PointType type_; //!< Quality of the point. - PointOrigin origin_; //!< What is the source of the point, i.e. DEPTH if a kinect is used. int n_failed_reproj_; //!< Number of failed reprojections. Used to assess the quality of the point. int n_succeeded_reproj_; //!< Number of succeeded reprojections. Used to assess the quality of the point. - int last_structure_optim_; + int last_structure_optim_; //!< Timestamp of last point optimization - Point(Vector3d pos, PointOrigin origin); + Point(Vector3d pos); ~Point(); /// Add a reference to a frame. diff --git a/svo/src/initialization.cpp b/svo/src/initialization.cpp index 1087e61..2aa3931 100644 --- a/svo/src/initialization.cpp +++ b/svo/src/initialization.cpp @@ -84,7 +84,7 @@ InitResult KltHomographyInit::addSecondFrame(FramePtr frame_cur) if(frame_ref_->cam_->isInFrame(px_cur.cast(), 10) && frame_ref_->cam_->isInFrame(px_ref.cast(), 10) && xyz_in_cur_[*it].z() > 0) { Vector3d pos = T_world_cur * (xyz_in_cur_[*it]*scale); - Point* new_point = new Point(pos, Point::TRIANGULATION); + Point* new_point = new Point(pos); Feature* ftr_cur(new Feature(frame_cur.get(), new_point, px_cur, f_cur_[*it], 0)); frame_cur->addFeature(ftr_cur); diff --git a/svo/src/map.cpp b/svo/src/map.cpp index 808917c..1decc22 100644 --- a/svo/src/map.cpp +++ b/svo/src/map.cpp @@ -94,7 +94,7 @@ void Map::safeDeletePoint(Point* pt) void Map::deletePoint(Point* pt) { - pt->type_ = Point::DELETED; + pt->type_ = Point::TYPE_DELETED; trash_points_.push_back(pt); } @@ -196,9 +196,9 @@ MapPointCandidates::~MapPointCandidates() void MapPointCandidates::newCandidatePoint(const Seed& seed, const Vector3d& xyz_world) { // initalize a new point - Point* point = new Point(xyz_world, Point::VOGIATZIS); + Point* point = new Point(xyz_world); point->addFrameRef(seed.ftr); - point->type_ = Point::CANDIDATE; + point->type_ = Point::TYPE_CANDIDATE; seed.ftr->point = point; // add candidate to list @@ -215,7 +215,7 @@ void MapPointCandidates::addCandidatePointToFrame(FramePtr frame) if(it->first->obs_.front()->frame == frame.get()) { // insert feature in the frame - it->first->type_ = Point::UNKNOWN_QUALITY; + it->first->type_ = Point::TYPE_UNKNOWN; it->first->n_failed_reproj_ = 0; it->second->frame->addFeature(it->second); it = candidates_.erase(it); @@ -271,7 +271,7 @@ void MapPointCandidates::deleteCandidate(PointCandidate& c) // camera-rig: another frame might still be pointing to the candidate point // therefore, we can't delete it right now. delete c.second; c.second=NULL; - c.first->type_ = Point::DELETED; + c.first->type_ = Point::TYPE_DELETED; trash_points_.push_back(c.first); } @@ -298,7 +298,7 @@ void frameValidation(Frame* frame, int id) if((*it)->point==NULL) continue; - if((*it)->point->type_ == Point::DELETED) + if((*it)->point->type_ == Point::TYPE_DELETED) printf("ERROR DataValidation %i: Referenced point was deleted.\n", id); if(!(*it)->point->findFrameRef(frame)) diff --git a/svo/src/point.cpp b/svo/src/point.cpp index 40aced9..75f14a0 100644 --- a/svo/src/point.cpp +++ b/svo/src/point.cpp @@ -24,15 +24,15 @@ namespace svo { int Point::point_counter_ = 0; -Point::Point(Vector3d pos, PointOrigin origin) : +Point::Point(Vector3d pos) : id_(point_counter_++), pos_(pos), + normal_(Vector3d::Zero()), n_obs_(0), v_pt_(NULL), last_published_ts_(0), last_projected_kf_id_(-1), - type_(UNKNOWN_QUALITY), - origin_(origin), + type_(TYPE_UNKNOWN), n_failed_reproj_(0), n_succeeded_reproj_(0), last_structure_optim_(0) diff --git a/svo/src/reprojection.cpp b/svo/src/reprojection.cpp index 26de82c..61de512 100644 --- a/svo/src/reprojection.cpp +++ b/svo/src/reprojection.cpp @@ -158,7 +158,7 @@ bool reprojectCell( { ++n_trials; - if(it->pt->type_ == Point::DELETED) + if(it->pt->type_ == Point::TYPE_DELETED) { it = cell.erase(it); continue; @@ -169,16 +169,16 @@ bool reprojectCell( if(!found_match) { it->pt->n_failed_reproj_++; - if(it->pt->type_ == Point::UNKNOWN_QUALITY && it->pt->n_failed_reproj_ > 15) + if(it->pt->type_ == Point::TYPE_UNKNOWN && it->pt->n_failed_reproj_ > 15) map.safeDeletePoint(it->pt); - if(it->pt->type_ == Point::CANDIDATE && it->pt->n_failed_reproj_ > 30) + if(it->pt->type_ == Point::TYPE_CANDIDATE && it->pt->n_failed_reproj_ > 30) candidate_points.deleteCandidatePoint(it->pt); it = cell.erase(it); continue; } it->pt->n_succeeded_reproj_++; - if(it->pt->type_ == Point::UNKNOWN_QUALITY && it->pt->n_succeeded_reproj_ > 10) - it->pt->type_ = Point::GOOD_QUALITY; + if(it->pt->type_ == Point::TYPE_UNKNOWN && it->pt->n_succeeded_reproj_ > 10) + it->pt->type_ = Point::TYPE_GOOD; Feature* new_feature = new Feature(frame.get(), it->px, feature_level); frame->addFeature(new_feature); diff --git a/svo/test/test_pose_optimizer.cpp b/svo/test/test_pose_optimizer.cpp index 0c9a63f..16f3dfc 100644 --- a/svo/test/test_pose_optimizer.cpp +++ b/svo/test/test_pose_optimizer.cpp @@ -69,7 +69,7 @@ class PoseOptimizerTest { if(it->score > Config::triangMinCornerScore()) { Feature* ftr(new Feature(frame_.get(), Vector2d(it->x, it->y), it->level)); - Point* point(new Point(frame_->f2w(ftr->f*depthmap_.at(it->y, it->x)), Point::DEPTH)); + Point* point(new Point(frame_->f2w(ftr->f*depthmap_.at(it->y, it->x)))); ftr->point = point; ftr->frame = frame_.get(); frame_->addFeature(ftr); diff --git a/svo/test/test_sparse_img_align.cpp b/svo/test/test_sparse_img_align.cpp index 51950a8..b4f5f3b 100644 --- a/svo/test/test_sparse_img_align.cpp +++ b/svo/test/test_sparse_img_align.cpp @@ -104,7 +104,7 @@ void SparseImgAlignTest::testSequence( svo::Feature* ftr = new svo::Feature(frame_ref_.get(), Eigen::Vector2d(corner->x, corner->y), corner->level); Eigen::Vector3d pt_pos_cur = ftr->f*depthmap.at(corner->y, corner->x); Eigen::Vector3d pt_pos_w = frame_ref_->T_f_w_.inverse()*pt_pos_cur; - svo::Point* pt = new svo::Point(pt_pos_w, svo::Point::DEPTH); + svo::Point* pt = new svo::Point(pt_pos_w); ftr->point = pt; frame_ref_->addFeature(ftr); } diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index 561f131..13ee94b 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -202,7 +202,7 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) svo::Feature* ftr = new svo::Feature(frame_ref.get(), Eigen::Vector2d(corner->x, corner->y), corner->level); Eigen::Vector3d pt_pos_cur = ftr->f*depthmap.at(corner->y, corner->x); Eigen::Vector3d pt_pos_world = frame_ref->T_f_w_.inverse()*pt_pos_cur; - svo::Point* point = new svo::Point(pt_pos_world, svo::Point::DEPTH); + svo::Point* point = new svo::Point(pt_pos_world); ftr->point = point; ftr->point->addFrameRef(ftr); frame_ref->addFeature(ftr); From c6b308ca14ecee1fc2a28f1f9e00aa5bc36ec4af Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 4 Apr 2014 20:10:39 +0200 Subject: [PATCH 053/215] changed compile-flag name USE_ROS to SVO_USE_ROS because PCL uses the same flag --- svo/CMakeLists.txt | 2 +- svo/include/svo/global.h | 2 +- svo/src/config.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index ae995f4..066b751 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -32,7 +32,7 @@ ENDIF() IF(HAVE_G2O) ADD_DEFINITIONS(-DUSE_BUNDLE_ADJUSTMENT) ENDIF() -ADD_DEFINITIONS(-DUSE_ROS) +ADD_DEFINITIONS(-DSVO_USE_ROS) # Set build flags SET(CMAKE_CXX_FLAGS "-Wall -Werror -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") diff --git a/svo/include/svo/global.h b/svo/include/svo/global.h index 01d8d52..c118377 100644 --- a/svo/include/svo/global.h +++ b/svo/include/svo/global.h @@ -30,7 +30,7 @@ #include #include -#ifdef USE_ROS +#ifdef SVO_USE_ROS #include #define SVO_DEBUG_STREAM(x) ROS_DEBUG_STREAM(x) #define SVO_INFO_STREAM(x) ROS_INFO_STREAM(x) diff --git a/svo/src/config.cpp b/svo/src/config.cpp index c8593c4..f6820f4 100644 --- a/svo/src/config.cpp +++ b/svo/src/config.cpp @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#ifdef USE_ROS +#ifdef SVO_USE_ROS #include #endif #include @@ -22,7 +22,7 @@ namespace svo { Config::Config() : -#ifdef USE_ROS +#ifdef SVO_USE_ROS trace_name(vk::getParam("svo/trace_name", "svo")), trace_dir(vk::getParam("svo/trace_dir", "/tmp")), n_pyr_levels(vk::getParam("svo/n_pyr_levels", 3)), From 2e46802a5b29eacf6a83679def0442676cd9b673 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 4 Apr 2014 21:04:30 +0200 Subject: [PATCH 054/215] set trace flag to false --- svo/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 066b751..70a5583 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -2,7 +2,7 @@ # user build settings SET(DEBUG FALSE) -SET(TRACE TRUE) +SET(TRACE FALSE) SET(HAVE_G2O FALSE) ################################################################################ From c460e3bf853085c076f77772ffef4ef787ee27e4 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 8 Apr 2014 20:13:57 +0200 Subject: [PATCH 055/215] adapt for new datasets --- svo_analysis/scripts/benchmark.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index 19688ce..3be6916 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -38,7 +38,7 @@ if __name__=="__main__": expParams['experiment_name'] = expParams['time']+'_'+args.version+'_' + args.experiment_file # load dataset parameters - expParams['dataset_directory'] = os.path.join(rospkg.RosPack().get_path('Datasets'), expParams['dataset']) + expParams['dataset_directory'] = os.path.join(os.environ['SVO_DATASET_DIR'], expParams['dataset']) if not os.path.exists(expParams['dataset_directory']): raise Exception("Provided dataset folder does not exist.") datasetParamsFile = os.path.join(expParams['dataset_directory'], 'dataset_params.yaml') @@ -50,10 +50,12 @@ if __name__=="__main__": algoParams = yaml.load(open(algoParamsFile,'r')) # combine all parameters - params = dict(expParams.items() + datasetParams.items() + algoParams.items()) + params = dict(expParams.items() + datasetParams.items() + datasetParams['rig']['cam0'].items() + algoParams.items()) params['trace_name'] = 'trace' params['trace_dir'] = os.path.join(rospkg.RosPack().get_path('svo_analysis'), 'results', params['experiment_name']) + + # create folder for tracing if not os.path.exists(params['trace_dir']): From 225f2ea71c2cc7884c2fc71441bfc10eefaa6977 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 9 Apr 2014 11:29:14 +0200 Subject: [PATCH 056/215] use SVO_WARN_STREAM() instead of ROS_WARN_STREAM() --- svo/src/frame_handler_base.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index c3568d5..c478a8a 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -148,18 +148,18 @@ void FrameHandlerBase::setTrackingQuality(const size_t num_observations) tracking_quality_ = TRACKING_GOOD; if(num_observations < Config::qualityMinFts()) { - ROS_WARN_STREAM_THROTTLE(0.5, "Tracking less than "<< Config::qualityMinFts() <<" features!"); + SVO_WARN_STREAM_THROTTLE(0.5, "Tracking less than "<< Config::qualityMinFts() <<" features!"); tracking_quality_ = TRACKING_BAD; } const int feature_drop = static_cast(num_obs_last_) - num_observations; if(feature_drop > Config::qualityMaxFtsDrop()) { - ROS_WARN_STREAM("Lost "<< feature_drop <<" features!"); + SVO_WARN_STREAM("Lost "<< feature_drop <<" features!"); tracking_quality_ = TRACKING_BAD; } if(num_observations < 20) { - ROS_ERROR_STREAM("Tracking less than 20 features!"); + SVO_ERROR_STREAM("Tracking less than 20 features!"); tracking_quality_ = TRACKING_INSUFFICIENT; } } From c7e87f188e946edfa082b06b8af5373162399f83 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 9 Apr 2014 17:59:19 +0200 Subject: [PATCH 057/215] using fabs() instead of abs() --- svo/src/frame_handler_mono.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 5804057..34417f5 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -183,6 +183,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() depth_filter_->addFrame(new_frame_); return RESULT_NO_KEYFRAME; } + SVO_DEBUG_STREAM("New keyframe selected."); // new keyframe selected for(Features::iterator it=new_frame_->fts_.begin(); it!=new_frame_->fts_.end(); ++it) @@ -242,9 +243,10 @@ bool FrameHandlerMono::needNewKf(double scene_depth_mean) for(auto it=overlap_kfs_.begin(), ite=overlap_kfs_.end(); it!=ite; ++it) { Vector3d relpos = new_frame_->w2f(it->first->pos()); - if(abs(relpos.x())/scene_depth_mean < Config::kfSelectMinDist() && - abs(relpos.y())/scene_depth_mean < Config::kfSelectMinDist()*0.8 && - abs(relpos.z())/scene_depth_mean < Config::kfSelectMinDist()*1.3) + std::cout << relpos.transpose() << std::endl; + if(fabs(relpos.x())/scene_depth_mean < Config::kfSelectMinDist() && + fabs(relpos.y())/scene_depth_mean < Config::kfSelectMinDist()*0.8 && + fabs(relpos.z())/scene_depth_mean < Config::kfSelectMinDist()*1.3) return false; } return true; From bc4ad77fe5e167baa6541872f980d8e4a091b628 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 9 Apr 2014 18:00:26 +0200 Subject: [PATCH 058/215] publish markers and images also in benchmark node --- svo_ros/src/benchmark_node.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index d8cc31e..4083bf2 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -134,13 +134,10 @@ void BenchmarkNode::runBenchmark(const std::string& dataset_dir) return; } - // Add image to VO vo_->addImage(img, it->timestamp_); - // Visualize visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->timestamp_); - // write pose to tracefile if(vo_->stage() == svo::FrameHandlerMono::STAGE_DEFAULT_FRAME) tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); } @@ -213,17 +210,20 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) continue; } - // Add image to VO + SVO_DEBUG_STREAM("Processing image "<image_name_<<"."); vo_->addImage(img, it->timestamp_); + visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->timestamp_); + visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); if(vo_->stage() != svo::FrameHandlerMono::STAGE_DEFAULT_FRAME) - continue; + { + SVO_ERROR_STREAM("SVO failed before entire dataset could be processed."); + break; + } // Compute pose error and trace to file Sophus::SE3 T_f_gt(vo_->lastFrame()->T_f_w_*T_w_gt); tracePoseError(T_f_gt, it->timestamp_); - - // write pose to tracefile tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); } } From 42a5535fdcd1aa16fda686dcd6f9bd873abec178 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 9 Apr 2014 18:04:57 +0200 Subject: [PATCH 059/215] changed output level of debug msgs --- svo/src/depth_filter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 8acd71d..ce34e69 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -238,7 +238,7 @@ void DepthFilter::updateSeeds(FramePtr frame) if(!it->ftr->frame->cam_->isInFrame(px.cast())) { ++it; if(options_.verbose) - SVO_INFO_STREAM("not visible"); + SVO_DEBUG_STREAM("not visible"); continue; } @@ -263,11 +263,11 @@ void DepthFilter::updateSeeds(FramePtr frame) px_noise = fmax(2.0*options_.sigma_i_sq*h_inv, 1.0); px_error_angle = atan(px_noise/(2.0*focal_length))*2.0; // law of chord (sehnensatz) if(options_.verbose) - SVO_INFO_STREAM("Photometric disparity error "<ftr->f, z, px_error_angle); @@ -285,7 +285,7 @@ void DepthFilter::updateSeeds(FramePtr frame) Vector3d xyz_world(it->ftr->frame->T_f_w_.inverse() * (it->ftr->f * (1.0/it->mu))); seed_converged_cb_(*it, xyz_world); if(options_.verbose) - SVO_INFO_STREAM("seed converged"); + SVO_DEBUG_STREAM("seed converged"); } it = seeds_.erase(it); } From 0137f64c229da9ebb75e1a5bbeb168412c6d0ec5 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 9 Apr 2014 19:52:16 +0200 Subject: [PATCH 060/215] remove cout --- svo/src/frame_handler_mono.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 34417f5..fbd8638 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -243,7 +243,6 @@ bool FrameHandlerMono::needNewKf(double scene_depth_mean) for(auto it=overlap_kfs_.begin(), ite=overlap_kfs_.end(); it!=ite; ++it) { Vector3d relpos = new_frame_->w2f(it->first->pos()); - std::cout << relpos.transpose() << std::endl; if(fabs(relpos.x())/scene_depth_mean < Config::kfSelectMinDist() && fabs(relpos.y())/scene_depth_mean < Config::kfSelectMinDist()*0.8 && fabs(relpos.z())/scene_depth_mean < Config::kfSelectMinDist()*1.3) From 8be2d1cb353ade9f7b2e473153fb1a7a597924ea Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 9 Apr 2014 20:09:01 +0200 Subject: [PATCH 061/215] benchmark multiple scenes in one go --- svo_analysis/experiments/synthetic.yaml | 7 ++ svo_analysis/scripts/benchmark.py | 115 ++++++++++++------------ 2 files changed, 66 insertions(+), 56 deletions(-) create mode 100644 svo_analysis/experiments/synthetic.yaml diff --git a/svo_analysis/experiments/synthetic.yaml b/svo_analysis/experiments/synthetic.yaml new file mode 100644 index 0000000..5eb0402 --- /dev/null +++ b/svo_analysis/experiments/synthetic.yaml @@ -0,0 +1,7 @@ +experiment_label: 'svo fast' +param_settings: vo_fast +datasets: + - 1404091756_fr1_straight + - 1404091807_fr1_straight_rot + - 1404091819_fr1_sine_2d + - 1404091831_fr1_sine_3d \ No newline at end of file diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index 3be6916..9611350 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -14,67 +14,70 @@ import vikit_py.cpu_info as cpu_info import vikit_py.ros_node as ros_node import evaluate +def run_experiment(dataset, params): + # load dataset parameters + params['dataset_directory'] = os.path.join(os.environ['SVO_DATASET_DIR'], dataset) + if not os.path.exists(params['dataset_directory']): + raise Exception("Provided dataset folder does not exist.") + dataset_params_file = os.path.join(params['dataset_directory'], 'dataset_params.yaml') + dataset_params = yaml.load(open(dataset_params_file,'r')) + + # load algorithm parameters + algo_params_file = os.path.join(rospkg.RosPack().get_path('svo_ros'), + 'param', params['param_settings']+'.yaml') + algo_params = yaml.load(open(algo_params_file,'r')) + + # combine all parameters + params = dict(params.items() + algo_params.items() + dataset_params['rig']['cam0'].items()) + + # dump experiment params to file: + params_dump_file = params['trace_dir']+'/params.yaml' + with open(params_dump_file,'w') as outfile: + outfile.write(yaml.dump(params, default_flow_style=False)) + + # execute ros node + node = ros_node.RosNode(args.version, args.executable) + node.run(params) + if __name__=="__main__": - # parse command line - parser = argparse.ArgumentParser(description=''' - Runs SVO with the dataset and parameters specified in the provided experiment file. - ''') - parser.add_argument('experiment_file', help='experiment file in svo_analysis/experiments folder') - parser.add_argument('--name', help='experiment name') - parser.add_argument('--evaluate', help='evaluate tracefile after running SVO', action='store_true') - parser.add_argument('--version', help='version of svo to evaluate', default='svo_ros') - parser.add_argument('--executable', help='the executable to be called', default='benchmark') - args = parser.parse_args() - - # load experiment parameters - expParamsFile = os.path.join(rospkg.RosPack().get_path('svo_analysis'), + # parse command line + parser = argparse.ArgumentParser(description=''' + Runs SVO with the dataset and parameters specified in the provided experiment file. + ''') + parser.add_argument('experiment_file', help='experiment file in svo_analysis/experiments folder') + parser.add_argument('--evaluate', help='evaluate tracefile after running SVO', action='store_true') + parser.add_argument('--version', help='version of svo to evaluate', default='svo_ros') + parser.add_argument('--executable', help='the executable to be called', default='benchmark') + args = parser.parse_args() + + # load experiment parameters + experiment_params_file = os.path.join(rospkg.RosPack().get_path('svo_analysis'), 'experiments', args.experiment_file+'.yaml') - expParams = yaml.load(open(expParamsFile, 'r')) - expParams['time'] = time.strftime("%Y%m%d_%H%M", time.localtime()) - expParams['platform'] = cpu_info.get_cpu_info() - expParams['experiment_name'] = args.name - if(expParams['experiment_name'] == None): - expParams['experiment_name'] = expParams['time']+'_'+args.version+'_' + args.experiment_file - - # load dataset parameters - expParams['dataset_directory'] = os.path.join(os.environ['SVO_DATASET_DIR'], expParams['dataset']) - if not os.path.exists(expParams['dataset_directory']): - raise Exception("Provided dataset folder does not exist.") - datasetParamsFile = os.path.join(expParams['dataset_directory'], 'dataset_params.yaml') - datasetParams = yaml.load(open(datasetParamsFile,'r')) - - # load algorithm parameters - algoParamsFile = os.path.join(rospkg.RosPack().get_path('svo_ros'), - 'param', expParams['param_settings']+'.yaml') - algoParams = yaml.load(open(algoParamsFile,'r')) - - # combine all parameters - params = dict(expParams.items() + datasetParams.items() + datasetParams['rig']['cam0'].items() + algoParams.items()) - params['trace_name'] = 'trace' - params['trace_dir'] = os.path.join(rospkg.RosPack().get_path('svo_analysis'), - 'results', params['experiment_name']) - + experiment_params = yaml.load(open(experiment_params_file, 'r')) + params = dict() + params['experiment_label'] = experiment_params['experiment_label'] + params['param_settings'] = experiment_params['param_settings'] + params['time'] = time.strftime("%Y%m%d_%H%M", time.localtime()) + params['platform'] = cpu_info.get_cpu_info() + params['trace_name'] = 'trace' + + trace_dirs = list() + for dataset in experiment_params['datasets']: + params['experiment_name'] = params['time']+'_'+args.version+'_'+args.experiment_file+'_'+dataset + params['trace_dir'] = os.path.join(rospkg.RosPack().get_path('svo_analysis'), + 'results', params['experiment_name']) + if not os.path.exists(params['trace_dir']): + os.makedirs(params['trace_dir']) + trace_dirs.append(params['trace_dir']) + run_experiment(dataset, params) + + # TODO: check if it is a synthetic dataset + for trace in trace_dirs: + evaluate.evaluate_dataset(trace) + - # create folder for tracing - if not os.path.exists(params['trace_dir']): - os.makedirs(params['trace_dir']) - - # dump experiment params to file: - params_dump_file = params['trace_dir']+'/params.yaml' - with open(params_dump_file,'w') as outfile: - outfile.write(yaml.dump(params, default_flow_style=False)) - - # execute ros node - node = ros_node.RosNode(args.version, args.executable) - node.run(params) - - # TODO: check if it is a synthetic dataset - evaluate.evaluate_dataset(params['trace_dir']) - - - From fedd9f250e0135bf7b6c4deba8909022922a4c86 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 9 Apr 2014 20:10:51 +0200 Subject: [PATCH 062/215] delete heap variable --- svo/src/frame_handler_base.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index c478a8a..8b18872 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -79,6 +79,9 @@ FrameHandlerBase::FrameHandlerBase() : FrameHandlerBase::~FrameHandlerBase() { SVO_INFO_STREAM("SVO destructor invoked."); +#ifdef SVO_TRACE + delete g_permon; +#endif } bool FrameHandlerBase::startFrameProcessingCommon(const double timestamp) From 415ada6d2bae8af908e5ded4945f318ba1c6e21a Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 10 Apr 2014 22:49:24 +0200 Subject: [PATCH 063/215] copy dataset parameters to the trace folder --- svo_analysis/scripts/benchmark.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index 9611350..4b11148 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -13,6 +13,7 @@ import time import vikit_py.cpu_info as cpu_info import vikit_py.ros_node as ros_node import evaluate +import shutil def run_experiment(dataset, params): # load dataset parameters @@ -29,11 +30,14 @@ def run_experiment(dataset, params): # combine all parameters params = dict(params.items() + algo_params.items() + dataset_params['rig']['cam0'].items()) - - # dump experiment params to file: - params_dump_file = params['trace_dir']+'/params.yaml' + if 'dataset_is_blender' in dataset_params: + params['dataset_is_blender'] = True + + # dump experiment params to file and copy the other parameter files: + params_dump_file = os.path.join(params['trace_dir'],'params.yaml') with open(params_dump_file,'w') as outfile: outfile.write(yaml.dump(params, default_flow_style=False)) + shutil.copyfile(dataset_params_file, os.path.join(params['trace_dir'], 'dataset_params.yaml')) # execute ros node node = ros_node.RosNode(args.version, args.executable) From 0fe457265da75bb833dc5fce3c3c2de8c023c479 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sun, 13 Apr 2014 19:22:24 +0200 Subject: [PATCH 064/215] remove necessity to create experiment file for every dataset --- svo_analysis/scripts/benchmark.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index 4b11148..a544ba2 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -29,7 +29,10 @@ def run_experiment(dataset, params): algo_params = yaml.load(open(algo_params_file,'r')) # combine all parameters - params = dict(params.items() + algo_params.items() + dataset_params['rig']['cam0'].items()) + if dataset_params['rig_size'] == 1: + params = dict(params.items() + algo_params.items() + dataset_params['cam0'].items()) + else: + params = dict(params.items() + algo_params.items() + dataset_params.items()) if 'dataset_is_blender' in dataset_params: params['dataset_is_blender'] = True @@ -56,9 +59,15 @@ if __name__=="__main__": args = parser.parse_args() # load experiment parameters + args.experiment_file = args.experiment_file.replace('.yaml','') experiment_params_file = os.path.join(rospkg.RosPack().get_path('svo_analysis'), 'experiments', args.experiment_file+'.yaml') - experiment_params = yaml.load(open(experiment_params_file, 'r')) + if os.path.exists(experiment_params_file): + experiment_params = yaml.load(open(experiment_params_file, 'r')) + else: + print('experiment file does not exist. run with default setttings') + experiment_params = dict({'experiment_label':'default','param_settings':'vo_fast', + 'datasets':list([args.experiment_file])}) params = dict() params['experiment_label'] = experiment_params['experiment_label'] params['param_settings'] = experiment_params['param_settings'] From d150ef56159cc79afd8d3e592fed89ef8347004d Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sun, 13 Apr 2014 19:29:06 +0200 Subject: [PATCH 065/215] changed project name in output message --- svo/src/frame_handler_base.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index 8b18872..91bf5f0 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -73,12 +73,12 @@ FrameHandlerBase::FrameHandlerBase() : g_permon->init(Config::traceName(), Config::traceDir()); #endif - SVO_INFO_STREAM("NanoSlam initialized"); + SVO_INFO_STREAM("SVO initialized"); } FrameHandlerBase::~FrameHandlerBase() { - SVO_INFO_STREAM("SVO destructor invoked."); + SVO_INFO_STREAM("SVO destructor invoked"); #ifdef SVO_TRACE delete g_permon; #endif From 38b7d0b9bcf101fda1ea08c22730d390b7bb53da Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sun, 13 Apr 2014 22:04:16 +0200 Subject: [PATCH 066/215] changed interface of feature extractor --- svo/CMakeLists.txt | 4 +- svo/include/svo/feature_detection.h | 42 +++++++++---- svo/src/depth_filter.cpp | 4 +- svo/src/feature_detection.cpp | 81 ++++++++++++++++++------- svo/src/frame_handler_mono.cpp | 5 +- svo/src/initialization.cpp | 7 +-- svo/test/test_depth_filter.cpp | 5 +- svo/test/test_feature_detection.cpp | 6 +- svo/test/test_pose_optimizer.cpp | 6 +- svo/test/test_sparse_img_align.cpp | 6 +- svo_analysis/experiments/synthetic.yaml | 5 +- svo_ros/src/benchmark_node.cpp | 6 +- 12 files changed, 119 insertions(+), 58 deletions(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 70a5583..678cd96 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -1,8 +1,8 @@ ################################################################################ # user build settings -SET(DEBUG FALSE) -SET(TRACE FALSE) +SET(DEBUG TRUE) +SET(TRACE TRUE) SET(HAVE_G2O FALSE) ################################################################################ diff --git a/svo/include/svo/feature_detection.h b/svo/include/svo/feature_detection.h index a84586a..85e57c6 100644 --- a/svo/include/svo/feature_detection.h +++ b/svo/include/svo/feature_detection.h @@ -26,7 +26,6 @@ namespace svo { namespace feature_detection { /// Temporary container used for corner detection. Features are initialized from these. -// TODO: why not use feature struct? struct Corner { int x; //!< x-coordinate of corner in the image. @@ -44,14 +43,31 @@ typedef vector Corners; class AbstractDetector { public: + AbstractDetector( + const int img_width, + const int img_height, + const int cell_size, + const int n_pyr_levels); + virtual ~AbstractDetector() {}; + virtual void detect( const ImgPyr& img_pyr, const Features& fts, - const int cell_size, - const int n_levels, const double detection_threshold, - Corners* corners) const = 0; + Corners* corners) = 0; + + /// Notify the detector that a cell already has a feature before detection. + void setGridOccpuancy(const Vector2d& px); + +protected: + const int cell_size_; + const int n_pyr_levels_; + const int grid_n_cols_; + const int grid_n_rows_; + vector grid_occupancy_; + void resetGrid(); + void setExistingFeatures(const Features& fts); }; typedef boost::shared_ptr DetectorPtr; @@ -59,15 +75,19 @@ typedef boost::shared_ptr DetectorPtr; class FastDetector : public AbstractDetector { public: - FastDetector() {} + FastDetector( + const int img_width, + const int img_height, + const int cell_size, + const int n_pyr_levels); + virtual ~FastDetector() {} + virtual void detect( - const ImgPyr& img_pyr, - const Features& fts, - const int cell_size, - const int n_levels, - const double detection_threshold, - Corners* corners) const; + const ImgPyr& img_pyr, + const Features& fts, + const double detection_threshold, + Corners* corners); }; } // namespace feature_detection diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index ce34e69..5e26a5e 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -114,9 +114,7 @@ void DepthFilter::addKeyframe(FramePtr frame, double depth_mean, double depth_mi void DepthFilter::initializeSeeds(FramePtr frame) { feature_detection::Corners corners; - feature_detector_->detect(frame->img_pyr_, frame->fts_, svo::Config::gridSize(), - svo::Config::nPyrLevels(), Config::triangMinCornerScore(), - &corners); + feature_detector_->detect(frame->img_pyr_, frame->fts_, Config::triangMinCornerScore(), &corners); seeds_updating_halt_ = true; lock_t lock(seeds_mut_); // by locking the updateSeeds function stops diff --git a/svo/src/feature_detection.cpp b/svo/src/feature_detection.cpp index be0ca02..dff5da8 100644 --- a/svo/src/feature_detection.cpp +++ b/svo/src/feature_detection.cpp @@ -22,54 +22,91 @@ namespace svo { namespace feature_detection { +AbstractDetector::AbstractDetector( + const int img_width, + const int img_height, + const int cell_size, + const int n_pyr_levels) : + cell_size_(cell_size), + n_pyr_levels_(n_pyr_levels), + grid_n_cols_(ceil(static_cast(img_width)/cell_size_)), + grid_n_rows_(ceil(static_cast(img_height)/cell_size_)), + grid_occupancy_(grid_n_cols_*grid_n_rows_, false) +{} + +void AbstractDetector::resetGrid() +{ + std::fill(grid_occupancy_.begin(), grid_occupancy_.end(), false); +} + +void AbstractDetector::setExistingFeatures(const Features& fts) +{ + std::for_each(fts.begin(), fts.end(), [&](Feature* i){ + grid_occupancy_.at( + static_cast(i->px[1]/cell_size_)*grid_n_cols_ + + static_cast(i->px[0]/cell_size_)) = true; + }); +} + +void AbstractDetector::setGridOccpuancy(const Vector2d& px) +{ + grid_occupancy_.at( + static_cast(px[1]/cell_size_)*grid_n_cols_ + + static_cast(px[0]/cell_size_)) = true; +} + +FastDetector::FastDetector( + const int img_width, + const int img_height, + const int cell_size, + const int n_pyr_levels) : + AbstractDetector(img_width, img_height, cell_size, n_pyr_levels) +{} + void FastDetector::detect( const ImgPyr& img_pyr, const Features& existing_fts, - const int cell_size, - const int n_levels, const double detection_threshold, - Corners* corners) const + Corners* corners) { - // first, find which parts of the image already have a matched feature - const int grid_n_cols = ceil(static_cast(img_pyr[0].cols)/cell_size); - const int grid_n_rows = ceil(static_cast(img_pyr[0].rows)/cell_size); - vector occupancy(grid_n_cols*grid_n_rows, false); - for(Features::const_iterator it=existing_fts.begin(); it!=existing_fts.end(); ++it) - { - if((*it)->point == false) - continue; - const int k = static_cast((*it)->px[1]/cell_size)*grid_n_cols + static_cast((*it)->px[0]/cell_size); - occupancy.at(k) = true; - } + setExistingFeatures(existing_fts); // now, detect features and perform nonmax suppression - corners->resize(grid_n_cols*grid_n_rows, Corner(0,0,detection_threshold,0,0.0f)); - for(int L=0; Lresize(grid_n_cols_*grid_n_rows_, Corner(0,0,detection_threshold,0,0.0f)); + for(int L=0; L fast_corners; #if __SSE2__ - fast::fast_corner_detect_10_sse2((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); + fast::fast_corner_detect_10_sse2( + (fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, + img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); #elif HAVE_FAST_NEON - fast::fast_corner_detect_9_neon((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); + fast::fast_corner_detect_9_neon( + (fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, + img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); #else - fast::fast_corner_detect_10((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); + fast::fast_corner_detect_10( + (fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, + img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); #endif vector scores, nm_corners; fast::fast_corner_score_10((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, fast_corners, 20, scores); fast::fast_nonmax_3x3(fast_corners, scores, nm_corners); - for(vector::iterator it=nm_corners.begin(); it!=nm_corners.end(); ++it) + for(auto it=nm_corners.begin(), ite=nm_corners.end(); it!=ite; ++it) { fast::fast_xy& xy = fast_corners.at(*it); - const int k = static_cast((xy.y*scale)/cell_size)*grid_n_cols + static_cast((xy.x*scale)/cell_size); - if(occupancy[k]) + const int k = static_cast((xy.y*scale)/cell_size_)*grid_n_cols_ + + static_cast((xy.x*scale)/cell_size_); + if(grid_occupancy_[k]) continue; const float score = vk::shiTomasiScore(img_pyr[L], xy.x, xy.y); if(score > corners->at(k).score) corners->at(k) = Corner(xy.x*scale, xy.y*scale, score, L, 0.0f); } } + resetGrid(); } } // namespace feature_detection diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index fbd8638..d3ce965 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -37,7 +37,8 @@ FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam) : depth_filter_(NULL) { // create depth filter and set callback - feature_detection::DetectorPtr feature_detector(new feature_detection::FastDetector()); + feature_detection::DetectorPtr feature_detector( + new feature_detection::FastDetector(cam_->width(), cam_->height(), Config::gridSize(), Config::nPyrLevels())); DepthFilter::callback_t depth_filter_cb = boost::bind(&MapPointCandidates::newCandidatePoint, &map_.point_candidates_, _1, _2); depth_filter_ = new DepthFilter(feature_detector, depth_filter_cb); depth_filter_->startThread(); @@ -183,6 +184,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() depth_filter_->addFrame(new_frame_); return RESULT_NO_KEYFRAME; } + new_frame_->setKeyframe(); SVO_DEBUG_STREAM("New keyframe selected."); // new keyframe selected @@ -222,7 +224,6 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() } // add keyframe to map - new_frame_->setKeyframe(); map_.addKeyframe(new_frame_); return RESULT_IS_KEYFRAME; diff --git a/svo/src/initialization.cpp b/svo/src/initialization.cpp index 2aa3931..49a7640 100644 --- a/svo/src/initialization.cpp +++ b/svo/src/initialization.cpp @@ -110,10 +110,9 @@ void detectFeatures( vector& f_vec) { feature_detection::Corners corners; - feature_detection::FastDetector detector; - detector.detect(frame->img_pyr_, frame->fts_, Config::gridSize(), - Config::nPyrLevels(), Config::triangMinCornerScore(), - &corners); + feature_detection::FastDetector detector( + frame->img().cols, frame->img().rows, Config::gridSize(), Config::nPyrLevels()); + detector.detect(frame->img_pyr_, frame->fts_, Config::triangMinCornerScore(), &corners); // now for all maximum corners, initialize a new seed px_vec.clear(); px_vec.reserve(corners.size()); diff --git a/svo/test/test_depth_filter.cpp b/svo/test/test_depth_filter.cpp index a53947d..6072218 100644 --- a/svo/test/test_depth_filter.cpp +++ b/svo/test/test_depth_filter.cpp @@ -90,6 +90,7 @@ void DepthFilterTest::depthFilterCb( void DepthFilterTest::testReconstruction( std::string dataset_dir, + std::string experiment_name) { vk::FileReader sequence_file_reader(dataset_dir+"/trajectory.txt"); @@ -103,7 +104,9 @@ void DepthFilterTest::testReconstruction( vk::Timer t; std::list n_converged_per_iteration; - svo::feature_detection::DetectorPtr feature_detector(new svo::feature_detection::FastDetector()); + svo::feature_detection::DetectorPtr feature_detector( + new svo::feature_detection::FastDetector( + cam_->width(), cam_->height(), svo::Config::gridSize(), svo::Config::nPyrLevels())); svo::DepthFilter::callback_t depth_filter_cb = boost::bind(&DepthFilterTest::depthFilterCb, this, _1, _2); depth_filter_ = new svo::DepthFilter(feature_detector, depth_filter_cb); diff --git a/svo/test/test_feature_detection.cpp b/svo/test/test_feature_detection.cpp index 6fa3723..df28508 100644 --- a/svo/test/test_feature_detection.cpp +++ b/svo/test/test_feature_detection.cpp @@ -45,11 +45,11 @@ void testCornerDetector() // Corner detection vk::Timer t; svo::feature_detection::Corners corners; - svo::feature_detection::FastDetector fast_detector; + svo::feature_detection::FastDetector fast_detector( + img.cols, img.rows, svo::Config::gridSize(), svo::Config::nPyrLevels()); for(int i=0; i<100; ++i) { - fast_detector.detect(img_pyr, fts, svo::Config::gridSize(), svo::Config::nPyrLevels(), - svo::Config::triangMinCornerScore(), &corners); + fast_detector.detect(img_pyr, fts, svo::Config::triangMinCornerScore(), &corners); } printf("Fast corner detection took %f ms, %zu corners detected (ref i7-W520: 8.06878ms, 416)\n", t.stop()*10, corners.size()); diff --git a/svo/test/test_pose_optimizer.cpp b/svo/test/test_pose_optimizer.cpp index 8e98eac..88035b4 100644 --- a/svo/test/test_pose_optimizer.cpp +++ b/svo/test/test_pose_optimizer.cpp @@ -59,9 +59,9 @@ class PoseOptimizerTest { // detect features feature_detection::Corners corners; - feature_detection::FastDetector detector; - detector.detect(frame_->img_pyr_, frame_->fts_, Config::gridSize(), - Config::nPyrLevels(), Config::triangMinCornerScore(), &corners); + feature_detection::FastDetector detector( + cam_->width(), cam_->height(), Config::gridSize(), Config::nPyrLevels()); + detector.detect(frame_->img_pyr_, frame_->fts_, Config::triangMinCornerScore(), &corners); size_t n_fts = 0; for(feature_detection::Corners::iterator it=corners.begin(); it!=corners.end(); ++it) { diff --git a/svo/test/test_sparse_img_align.cpp b/svo/test/test_sparse_img_align.cpp index f719f72..9b7fa9e 100644 --- a/svo/test/test_sparse_img_align.cpp +++ b/svo/test/test_sparse_img_align.cpp @@ -99,8 +99,7 @@ void SparseImgAlignTest::testSequence( // extract features, generate features with 3D points svo::feature_detection::Corners corners; feature_detector->detect( - frame_ref_->img_pyr_, frame_ref_->fts_, svo::Config::gridSize(), - svo::Config::nPyrLevels(), svo::Config::triangMinCornerScore(), &corners); + frame_ref_->img_pyr_, frame_ref_->fts_, svo::Config::triangMinCornerScore(), &corners); for(svo::feature_detection::Corners::iterator corner=corners.begin(); corner!=corners.end(); ++corner) { svo::Feature* ftr = new svo::Feature(frame_ref_.get(), Eigen::Vector2d(corner->x, corner->y), corner->level); @@ -158,10 +157,11 @@ int main(int argc, char** argv) { std::string experiment_name("flying_room_1_rig_1_fast_minlev0"); std::string dataset_dir(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1"); - svo::feature_detection::FastDetector detector; svo::Config::triangMinCornerScore() = 20; svo::Config::kltMinLevel() = 0; SparseImgAlignTest test; + svo::feature_detection::FastDetector detector( + test.cam_->width(), test.cam_->height(), svo::Config::gridSize(), svo::Config::nPyrLevels()); test.testSequence(dataset_dir, experiment_name, &detector); return 0; } diff --git a/svo_analysis/experiments/synthetic.yaml b/svo_analysis/experiments/synthetic.yaml index 5eb0402..e58ff7a 100644 --- a/svo_analysis/experiments/synthetic.yaml +++ b/svo_analysis/experiments/synthetic.yaml @@ -1,7 +1,10 @@ experiment_label: 'svo fast' param_settings: vo_fast datasets: + - 1404102247_fr1_straight + - 1404102220_fr1_straight + - 1404102129_fr1_straight - 1404091756_fr1_straight - 1404091807_fr1_straight_rot - 1404091819_fr1_sine_2d - - 1404091831_fr1_sine_3d \ No newline at end of file + - 1404091831_fr1_sine_3d diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index 4083bf2..e4df4ad 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -188,10 +188,10 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) dataset_dir+"/depth/"+it->image_name_+"_0.depth", *cam_, depthmap); // extract features, generate features with 3D points - svo::feature_detection::FastDetector detector; + svo::feature_detection::FastDetector detector( + cam_->width(), cam_->height(), svo::Config::gridSize(), svo::Config::nPyrLevels()); svo::feature_detection::Corners corners; - detector.detect(frame_ref->img_pyr_, frame_ref->fts_, svo::Config::gridSize(), - svo::Config::nPyrLevels(), svo::Config::triangMinCornerScore(), &corners); + detector.detect(frame_ref->img_pyr_, frame_ref->fts_, svo::Config::triangMinCornerScore(), &corners); for(auto corner=corners.begin(); corner!=corners.end(); ++corner) { if(corner->score < Config::triangMinCornerScore()) From cf2b1888946d1413962a5116ae521c1d9bb815ee Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 16 Apr 2014 10:26:10 +0200 Subject: [PATCH 067/215] return fisher information --- svo/include/svo/sparse_img_align.h | 4 ++++ svo/src/sparse_img_align.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/svo/include/svo/sparse_img_align.h b/svo/include/svo/sparse_img_align.h index 17cb3a1..c9da479 100644 --- a/svo/include/svo/sparse_img_align.h +++ b/svo/include/svo/sparse_img_align.h @@ -51,6 +51,10 @@ public: FramePtr ref_frame, FramePtr cur_frame); + /// Return fisher information matrix, i.e. the Hessian of the log-likelihood + /// at the converged state. + Matrix getFisherInformation(); + protected: FramePtr ref_frame_; //!< reference frame, has depth for gradient pixels. FramePtr cur_frame_; //!< only the image is known! diff --git a/svo/src/sparse_img_align.cpp b/svo/src/sparse_img_align.cpp index 6dc97c8..fc765cb 100644 --- a/svo/src/sparse_img_align.cpp +++ b/svo/src/sparse_img_align.cpp @@ -69,9 +69,19 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) optimize(T_cur_from_ref); } cur_frame_->T_f_w_ = T_cur_from_ref * ref_frame_->T_f_w_; + + + return n_meas_/patch_area_; } +Matrix SparseImgAlign::getFisherInformation() +{ + double sigma_i_sq = 5e-4*255*255; // image noise + Matrix I = H_/sigma_i_sq; + return I; +} + // TODO take jacobian from Frame Class! void frameJac(const Vector3d & xyz, Matrix & J) { From 7d59376358e4f54e329228599998aa203208e19d Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 16 Apr 2014 10:26:29 +0200 Subject: [PATCH 068/215] publish markers in benchmark node --- svo_ros/src/benchmark_node.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index e4df4ad..187c5c5 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -137,6 +137,7 @@ void BenchmarkNode::runBenchmark(const std::string& dataset_dir) vo_->addImage(img, it->timestamp_); visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->timestamp_); + visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); if(vo_->stage() == svo::FrameHandlerMono::STAGE_DEFAULT_FRAME) tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); From 814336e5fffdfb614feda8df2e7a595de389d1a7 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 16 Apr 2014 10:26:55 +0200 Subject: [PATCH 069/215] fix for non-synthetic datasets in benchmark script --- svo_analysis/scripts/benchmark.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index a544ba2..272cbce 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -34,7 +34,7 @@ def run_experiment(dataset, params): else: params = dict(params.items() + algo_params.items() + dataset_params.items()) if 'dataset_is_blender' in dataset_params: - params['dataset_is_blender'] = True + params['dataset_is_blender'] = dataset_params['dataset_is_blender'] # dump experiment params to file and copy the other parameter files: params_dump_file = os.path.join(params['trace_dir'],'params.yaml') From 5fc8ef36a3d0fa70e38e6373113ea492592cf9bd Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 16 Apr 2014 12:13:25 +0200 Subject: [PATCH 070/215] write associated measurements to file --- .../tum_benchmark_tools/associate.py | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py b/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py index 554314a..01bea59 100755 --- a/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py +++ b/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py @@ -108,7 +108,6 @@ if __name__ == '__main__': ''') parser.add_argument('first_file', help='first text file (format: timestamp data)') parser.add_argument('second_file', help='second text file (format: timestamp data)') - parser.add_argument('--first_only', help='only output associated lines from first file', action='store_true') parser.add_argument('--offset', help='time offset added to the timestamps of the second file (default: 0.0)',default=0.0) parser.add_argument('--max_difference', help='maximally allowed time difference for matching entries (default: 0.02)',default=0.02) args = parser.parse_args() @@ -117,12 +116,15 @@ if __name__ == '__main__': second_list = read_file_list(args.second_file) matches = associate(first_list, second_list,float(args.offset),float(args.max_difference)) - - if args.first_only: - for a,b in matches: - print("%f %s"%(a," ".join(first_list[a]))) - else: - for a,b in matches: - print("%f %s %f %s"%(a," ".join(first_list[a]),b-float(args.offset)," ".join(second_list[b]))) - + + filename = 'groundtruth_matched.txt' + associates_file = open(filename, 'w') + for a,b in matches: + img = first_list[a] + pos = second_list[b] + associates_file.write('%.6f %s %s %s %s %s %s %s %s\n' % + (a, img[0], + pos[0], pos[1], pos[2], + pos[3], pos[4], pos[5], pos[6])) + print('Wrote matches to file: ' + filename) From e67ea76d1ecf9808fa97e57369d9b0a43289decb Mon Sep 17 00:00:00 2001 From: Flavio Fontana Date: Thu, 17 Apr 2014 10:20:21 +0200 Subject: [PATCH 071/215] the namespace is now saved in the gui --- rqt_svo/src/rqt_svo/svo.py | 15 +++++++++++++++ rqt_svo/src/rqt_svo/svo_widget.py | 6 +++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/rqt_svo/src/rqt_svo/svo.py b/rqt_svo/src/rqt_svo/svo.py index 88acaf7..bbbb8c6 100644 --- a/rqt_svo/src/rqt_svo/svo.py +++ b/rqt_svo/src/rqt_svo/svo.py @@ -39,6 +39,21 @@ class Svo(Plugin): group.add_argument('topic', type=argparse.FileType('r'), nargs='*', default=[], help='Svo Info Topic to display') return parser.parse_args(argv) + def save_settings(self, plugin_settings, instance_settings): + # TODO save intrinsic configuration, usually using: + # instance_settings.set_value(k, v) + print('Saving namespace') + namespace = self._widget._svo_namespace + instance_settings.set_value('namespace', namespace) + pass +# + def restore_settings(self, plugin_settings, instance_settings): + # TODO restore intrinsic configuration, usually using: + # v = instance_settings.value(k) + namespace = instance_settings.value('namespace', 'default') + self._widget.topic_line_edit.setText(namespace) + pass + # def shutdown_plugin(self): # # self._unregister_publisher() # pass diff --git a/rqt_svo/src/rqt_svo/svo_widget.py b/rqt_svo/src/rqt_svo/svo_widget.py index fd8303b..57b88f3 100644 --- a/rqt_svo/src/rqt_svo/svo_widget.py +++ b/rqt_svo/src/rqt_svo/svo_widget.py @@ -14,7 +14,7 @@ class SvoWidget(QWidget): _publisher = None _subscriber = None _num_received_msgs = 0 - + _svo_namespace = None def __init__(self, svo_namespace='svo'): # Init QWidget @@ -44,9 +44,9 @@ class SvoWidget(QWidget): @Slot(str) def _on_topic_changed(self, topic): - topic = str(topic) + self._svo_namespace = str(topic) self.unregister() - self.register(topic) + self.register(self._svo_namespace) def register(self, svo_namespace): # Load parameters From b49e43635671575e7fc8a0ae68df0766718d40d3 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 22 Apr 2014 18:35:45 +0200 Subject: [PATCH 072/215] plotting trajectory error --- svo_analysis/scripts/benchmark.py | 14 +- .../src/svo_analysis/analyse_trajectory.py | 317 +++++++++--------- 2 files changed, 171 insertions(+), 160 deletions(-) mode change 100644 => 100755 svo_analysis/src/svo_analysis/analyse_trajectory.py diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index 272cbce..c66f115 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -29,18 +29,28 @@ def run_experiment(dataset, params): algo_params = yaml.load(open(algo_params_file,'r')) # combine all parameters - if dataset_params['rig_size'] == 1: + if 'rig_size' not in dataset_params or dataset_params['rig_size'] == 1: params = dict(params.items() + algo_params.items() + dataset_params['cam0'].items()) else: params = dict(params.items() + algo_params.items() + dataset_params.items()) if 'dataset_is_blender' in dataset_params: params['dataset_is_blender'] = dataset_params['dataset_is_blender'] + params['dataset_first_frame'] = dataset_params['dataset_first_frame'] # dump experiment params to file and copy the other parameter files: params_dump_file = os.path.join(params['trace_dir'],'params.yaml') with open(params_dump_file,'w') as outfile: outfile.write(yaml.dump(params, default_flow_style=False)) - shutil.copyfile(dataset_params_file, os.path.join(params['trace_dir'], 'dataset_params.yaml')) + shutil.copyfile(dataset_params_file, + os.path.join(params['trace_dir'], 'dataset_params.yaml')) + + # copy the groundtruth trajectory to the trace dir for later evaluation + if params['dataset_is_blender']: + shutil.copyfile(os.path.join(params['dataset_directory'], 'trajectory.txt'), + os.path.join(params['trace_dir'], 'groundtruth_matched.txt')) + else: + shutil.copyfile(os.path.join(params['dataset_directory'], 'groundtruth_matched.txt'), + os.path.join(params['trace_dir'], 'groundtruth_matched.txt')) # execute ros node node = ros_node.RosNode(args.version, args.executable) diff --git a/svo_analysis/src/svo_analysis/analyse_trajectory.py b/svo_analysis/src/svo_analysis/analyse_trajectory.py old mode 100644 new mode 100755 index f2a800e..a024b79 --- a/svo_analysis/src/svo_analysis/analyse_trajectory.py +++ b/svo_analysis/src/svo_analysis/analyse_trajectory.py @@ -1,179 +1,180 @@ -# -*- coding: utf-8 -*- +#!/usr/bin/python import os import yaml -from .tum_benchmark_tools import associate +import argparse +import numpy as np import matplotlib.pyplot as plt +import svo_analysis.tum_benchmark_tools.associate as associate import vikit_py.transformations as transformations import vikit_py.align_trajectory as align_trajectory -import numpy as np - -# plot options from matplotlib import rc rc('font',**{'family':'serif','serif':['Cardo']}) rc('text', usetex=True) def plot_translation_error(timestamps, translation_error, results_dir): - fig = plt.figure(figsize=(8, 2.5)) - ax = fig.add_subplot(111, xlabel='time [s]', ylabel='position drift [mm]', xlim=[0,timestamps[-1]-timestamps[0]+4]) - ax.plot(timestamps-timestamps[0], translation_error[:,0]*1000, 'r-', label='x') - ax.plot(timestamps-timestamps[0], translation_error[:,1]*1000, 'g-', label='y') - ax.plot(timestamps-timestamps[0], translation_error[:,2]*1000, 'b-', label='z') - ax.legend() - fig.tight_layout() - fig.savefig(results_dir+'/translation_error.pdf') + fig = plt.figure(figsize=(8, 2.5)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='position drift [mm]', xlim=[0,timestamps[-1]-timestamps[0]+4]) + ax.plot(timestamps-timestamps[0], translation_error[:,0]*1000, 'r-', label='x') + ax.plot(timestamps-timestamps[0], translation_error[:,1]*1000, 'g-', label='y') + ax.plot(timestamps-timestamps[0], translation_error[:,2]*1000, 'b-', label='z') + ax.legend() + fig.tight_layout() + fig.savefig(results_dir+'/translation_error.pdf') def plot_rotation_error(timestamps, rotation_error, results_dir): - fig = plt.figure(figsize=(8, 2.5)) - ax = fig.add_subplot(111, xlabel='time [s]', ylabel='orientation drift [rad]', xlim=[0,timestamps[-1]-timestamps[0]+4]) - ax.plot(timestamps-timestamps[0], rotation_error[:,0], 'r-', label='yaw') - ax.plot(timestamps-timestamps[0], rotation_error[:,1], 'g-', label='pitch') - ax.plot(timestamps-timestamps[0], rotation_error[:,2], 'b-', label='roll') - ax.legend() - fig.tight_layout() - fig.savefig(results_dir+'/orientation_error.pdf') + fig = plt.figure(figsize=(8, 2.5)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='orientation drift [rad]', xlim=[0,timestamps[-1]-timestamps[0]+4]) + ax.plot(timestamps-timestamps[0], rotation_error[:,0], 'r-', label='yaw') + ax.plot(timestamps-timestamps[0], rotation_error[:,1], 'g-', label='pitch') + ax.plot(timestamps-timestamps[0], rotation_error[:,2], 'b-', label='roll') + ax.legend() + fig.tight_layout() + fig.savefig(results_dir+'/orientation_error.pdf') -def analyse_trajectory(results_dir): - # plot translation error - data = np.loadtxt(os.path.join(results_dir, 'translation_error.txt')) - timestamps = data[:,0] - translation_error = data[:,1:4] - plot_translation_error(timestamps, translation_error, results_dir) +def analyse_trajectory(results_dir, n_align_frames = 20, use_hand_eye_calib = True): - # plot orientation error - data = np.loadtxt(os.path.join(results_dir, 'orientation_error.txt')) - timestamps = data[:,0] - orientation_error = data[:,1:4] - plot_rotation_error(timestamps, orientation_error, results_dir) + if not os.path.isfile(os.path.join(results_dir, 'translation_error.txt')): + + T_cm, T_mc = load_hand_eye_calib(results_dir) + print('loading datasets.') + t_es, p_es, q_es, t_gt, p_gt, q_gt = load_dataset(results_dir) + + # align Sim3 to get scale + print('align Sim3 using '+str(n_align_frames)+' first frames.') + scale,rot,trans = align_trajectory.align_sim3(p_gt[0:n_align_frames,:], p_es[0:n_align_frames,:]) + print 'scale = '+str(scale) + # get trafo between (v)ision and (o)ptitrack frame + p_es_aligned = np.zeros(np.shape(p_es)) + if use_hand_eye_calib: + print q_gt[0,:] + print p_gt[0,:] + T_om = get_rigid_body_trafo(q_gt[0,:], p_gt[0,:]) + T_vc = get_rigid_body_trafo(q_es[0,:], scale*p_es[0,:]) + T_cv = transformations.inverse_matrix(T_vc) + T_ov = np.dot(T_om, np.dot(T_mc, T_cv)) + print 'T_ov = ' + str(T_ov) + + # apply transformation to estimated trajectory + q_es_aligned = np.zeros(np.shape(q_es)) + rpy_es_aligned = np.zeros(np.shape(p_es)) + rpy_gt = np.zeros(np.shape(p_es)) + for i in range(np.shape(p_es)[0]): + T_vc = get_rigid_body_trafo(q_es[i,:],p_es[i,:]) + T_vc[0:3,3] *= scale + T_om = np.dot(T_ov, np.dot(T_vc, T_cm)) + p_es_aligned[i,:] = T_om[0:3,3] + q_es_aligned[i,:] = transformations.quaternion_from_matrix(T_om) + rpy_es_aligned[i,:] = transformations.euler_from_quaternion(q_es_aligned[i,:], 'rzyx') + rpy_gt[i,:] = transformations.euler_from_quaternion(q_gt[i,:], 'rzyx') + + # plot position error (drift) + translation_error = (p_gt-p_es_aligned) + plot_translation_error(t_es, translation_error, results_dir) + + # plot orientation error (drift) + orientation_error = (rpy_gt - rpy_es_aligned) + plot_rotation_error(t_es, orientation_error, results_dir) + + # plot scale drift + motion_gt = np.diff(p_gt, 0) + motion_es = np.diff(p_es_aligned, 0) + dist_gt = np.sqrt(np.sum(np.multiply(motion_gt,motion_gt),1)) + dist_es = np.sqrt(np.sum(np.multiply(motion_es,motion_es),1)) + fig = plt.figure(figsize=(8,2.5)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='scale change [\%]', xlim=[0,t_es[-1]+4]) + scale_drift = np.divide(dist_es,dist_gt)*100-100 + ax.plot(t_es, scale_drift, 'b-') + fig.tight_layout() + + else: + for i in range(np.shape(p_es)[0]): + p_es_aligned[i,:] = scale*rot.dot(p_es[i,:]) + trans + + # plot trajectory + fig = plt.figure() + ax = fig.add_subplot(111, title='trajectory', aspect='equal', xlabel='x [m]', ylabel='y [m]') + ax.plot(p_es_aligned[:,0], p_es_aligned[:,1], 'b-', label='estimate') + ax.plot(p_gt[:,0], p_gt[:,1], 'r-', label='groundtruth') + #ax.plot(p_es_aligned[0:n_align_frames,0], p_es_aligned[0:n_align_frames,1], 'g-', linewidth=2, label='aligned') + ax.legend() + fig.tight_layout() + fig.savefig(results_dir+'/trajectory.pdf') + + + + else: + data = np.loadtxt(os.path.join(results_dir, 'translation_error.txt')) + timestamps = data[:,0] + translation_error = data[:,1:4] + plot_translation_error(timestamps, translation_error, results_dir) + + # plot orientation error + data = np.loadtxt(os.path.join(results_dir, 'orientation_error.txt')) + timestamps = data[:,0] + orientation_error = data[:,1:4] + plot_rotation_error(timestamps, orientation_error, results_dir) + + def get_rigid_body_trafo(quat,trans): - T = transformations.quaternion_matrix(quat) - T[0:3,3] = trans - return T + T = transformations.quaternion_matrix(quat) + T[0:3,3] = trans + return T + +def load_hand_eye_calib(results_dir): + P = yaml.load(open(os.path.join(results_dir, 'dataset_params.yaml'),'r'))['hand_eye_calib'] + + T_cm_quat = np.array([P['Tcm_qx'], P['Tcm_qy'], P['Tcm_qz'], P['Tcm_qw']]) + T_cm_tran = np.array([P['Tcm_tx'], P['Tcm_ty'], P['Tcm_tz']]) + T_cm = get_rigid_body_trafo(T_cm_quat, T_cm_tran) + T_mc = transformations.inverse_matrix(T_cm) + return T_cm, T_mc + +def load_dataset(results_dir): + """ + Assumes that groundtruth measurements are already matched with the + images. + """ + data_gt = open(os.path.join(results_dir, 'groundtruth_matched.txt')).read() + lines = data_gt.replace(","," ").replace("\t"," ").split("\n") + data_gt = np.array([[np.float(v.strip()) for i,v in enumerate(line.split(" ")) if i != 1 and v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"]) + data_gt = [(float(l[0]),l[1:]) for l in data_gt] + data_gt = dict(data_gt) + + data_es = open(os.path.join(results_dir, 'traj_estimate.txt')).read() + lines = data_es.replace(","," ").replace("\t"," ").split("\n") + data_es = np.array([[np.float(v.strip()) for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"]) + data_es = [(float(l[0]),l[1:]) for l in data_es] + data_es = dict(data_es) + + matches = associate.associate(data_gt, data_es, 0.0, 0.0001) + p_gt = np.array([[np.float(value) for value in data_gt[a][0:3]] for a,b in matches]) + q_gt = np.array([[np.float(value) for value in data_gt[a][3:7]] for a,b in matches]) + p_es = np.array([[np.float(value) for value in data_es[b][0:3]] for a,b in matches]) + q_es = np.array([[np.float(value) for value in data_es[b][3:7]] for a,b in matches]) + t_gt = np.array([np.float(a) for a,b in matches]) + t_es = np.array([np.float(b) for a,b in matches]) + + # set start time to zero + start_time = min(t_es[0], t_gt[0]) + t_es -= start_time + t_gt -= start_time + return t_es, p_es, q_es, t_gt, p_gt, q_gt + if __name__ == '__main__': - # config - dataset='20131003_1937_nslam_i7_asl2_fast' - n_align_frames = 100 - save = True - results_dir = '../results/'+dataset - - # load dataset parameters - params_stream = open(results_dir+'/params.yaml') - params = yaml.load(params_stream) - - # set trajectory groundtruth and estimate file - traj_groundtruth = params['dataset_directory']+'/groundtruth_filtered.txt' - traj_estimate = results_dir+'/traj_estimate.txt' - traj_estimate_rotated_filename = results_dir+'/traj_estimate_rotated.txt' - translation_error_filename = results_dir+'/translation_error.txt' - orientation_error_filename = results_dir+'/orientation_error.txt' - scale_drift_filename = results_dir+'/scale_drift.txt' - - # load hand-eye calib: trafo between (m)arker and (c)amera. - dataset_param_file = params['dataset_directory']+'/dataset_params.yaml' - dataset_param_file_stream = open(dataset_param_file,'r') - P = yaml.load(dataset_param_file_stream) - T_cm_quat = np.array([P['calib_Tcm_qx'], P['calib_Tcm_qy'], P['calib_Tcm_qz'], P['calib_Tcm_qw']]) - T_cm_tran = np.array([P['calib_Tcm_tx'], P['calib_Tcm_ty'], P['calib_Tcm_tz']]) - T_cm = get_rigid_body_trafo(T_cm_quat, T_cm_tran) - T_mc = transformations.inverse_matrix(T_cm) - - # load data - data_gt = associate.read_file_list(traj_groundtruth) - data_es = associate.read_file_list(traj_estimate) - - # find matches - matches = associate.associate(data_gt, data_es, -P['cam_delay'], 0.02) - p_gt = np.array([[float(value) for value in data_gt[a][0:3]] for a,b in matches]) - q_gt = np.array([[float(value) for value in data_gt[a][3:7]] for a,b in matches]) - p_es = np.array([[float(value) for value in data_es[b][0:3]] for a,b in matches]) - q_es = np.array([[float(value) for value in data_es[b][3:7]] for a,b in matches]) - t_gt = np.array([float(a) for a,b in matches]) - t_es = np.array([float(b) for a,b in matches]) - start_time = min(t_es[0], t_gt[0]) - t_es -= start_time - t_gt -= start_time - - # align Sim3 to get scale - if(n_align_frames > np.shape(matches)[0]): - raise NameError('n_matches_for_scale is too large') - scale,rot,trans = align_trajectory.align_sim3(p_gt, p_es, n_align_frames) - print 'scale = '+str(scale) - - # get trafo between (v)ision and (o)ptitrack frame - T_om = get_rigid_body_trafo(q_gt[0,:], p_gt[0,:]) - T_vc = get_rigid_body_trafo(q_es[0,:], scale*p_es[0,:]) - T_cv = transformations.inverse_matrix(T_vc) - T_ov = np.dot(T_om, np.dot(T_mc, T_cv)) - print 'T_ov = ' + str(T_ov) - - p_es_aligned = np.zeros(np.shape(p_es)) - q_es_aligned = np.zeros(np.shape(q_es)) - rpy_es_aligned = np.zeros(np.shape(p_es)) - rpy_gt = np.zeros(np.shape(p_es)) - - # rotate trajectory - for i in range(np.shape(matches)[0]): - T_vc = get_rigid_body_trafo(q_es[i,:],p_es[i,:]) - T_vc[0:3,3] *= scale - T_om = np.dot(T_ov, np.dot(T_vc, T_cm)) - p_es_aligned[i,:] = T_om[0:3,3] - q_es_aligned[i,:] = transformations.quaternion_from_matrix(T_om) - rpy_es_aligned[i,:] = transformations.euler_from_quaternion(q_es_aligned[i,:], 'rzyx') - rpy_gt[i,:] = transformations.euler_from_quaternion(q_gt[i,:], 'rzyx') - - if save: - f = open(traj_estimate_rotated_filename,'w') - for i in range(np.shape(p_es_aligned)[0]): - f.write('%.7f %.5f %.5f %.5f %.5f %.5f %.5f %.5f\n' % (matches[i][1]-P['cam_delay'], p_es_aligned[i,0], p_es_aligned[i,1], p_es_aligned[i,2], q_es_aligned[i,0], q_es_aligned[i,1], q_es_aligned[i,2], q_es_aligned[i,3])) - f.close() - - # plot trajectory - fig = plt.figure() - ax = fig.add_subplot(111, title='trajectory', aspect='equal', xlabel='x [m]', ylabel='Y [m]') - ax.plot(p_es_aligned[:,0], p_es_aligned[:,1], 'b-', label='estimate') - ax.plot(p_gt[:,0], p_gt[:,1], 'r-', label='groundtruth') - ax.plot(p_es_aligned[0:n_align_frames,0], p_es_aligned[0:n_align_frames,1], 'g-', linewidth=2, label='aligned') - fig.tight_layout() - fig.savefig(results_dir+'/trajectory.pdf') - - # plot position error (drift) - translation_error = (p_gt-p_es_aligned) - plot_translation_error(t_es, translation_error, results_dir) - - if save: - f = open(translation_error_filename,'w') - for i in range(translation_error.shape[0]): - f.write('%.7f %.5f %.5f %.5f\n'%(t_es[i], translation_error[i,0], translation_error[i,1], translation_error[i,2])) - f.close() - - # plot orientation error (drift) - orientation_error = (rpy_gt - rpy_es_aligned) - plot_rotation_error(t_es, orientation_error, results_dir) - - if save: - f = open(orientation_error_filename,'w') - for i in range(orientation_error.shape[0]): - f.write('%.7f %.5f %.5f %.5f\n'%(t_es[i], orientation_error[i,0], orientation_error[i,1], orientation_error[i,2])) - f.close() - - # plot scale drift - motion_gt = np.diff(p_gt, 0) - motion_es = np.diff(p_es_aligned, 0) - dist_gt = np.sqrt(np.sum(np.multiply(motion_gt,motion_gt),1)) - dist_es = np.sqrt(np.sum(np.multiply(motion_es,motion_es),1)) - fig = plt.figure(figsize=(8,2.5)) - ax = fig.add_subplot(111, xlabel='time [s]', ylabel='scale change [\%]', xlim=[0,t_es[-1]+4]) - scale_drift = np.divide(dist_es,dist_gt)*100-100 - ax.plot(t_es, scale_drift, 'b-') - fig.tight_layout() - - if save: - fig.savefig(results_dir+'/scale_drift.pdf') - f = open(scale_drift_filename,'w') - for i in range(orientation_error.shape[0]): - f.write('%.7f %.5f\n'%(t_es[i], scale_drift[i])) - f.close() + # parse command line + parser = argparse.ArgumentParser(description=''' + Analyse trajectory + ''') + parser.add_argument('results_dir', help='folder with the results') + parser.add_argument('--use_hand_eye_calib', help='', action='store_true') + parser.add_argument('--n_align_frames', help='', default=20) + args = parser.parse_args() + print('analyse trajectory for dataset: '+str(args.results_dir)) + analyse_trajectory(args.results_dir, + n_align_frames = int(args.n_align_frames), + use_hand_eye_calib = args.use_hand_eye_calib) \ No newline at end of file From 0cbe4a6ca1a4c173209881d1bba783eb5708e8ad Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 22 Apr 2014 18:36:18 +0200 Subject: [PATCH 073/215] can set start frame idx of dataset --- svo_ros/src/benchmark_node.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index 187c5c5..bc94653 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -124,21 +124,20 @@ void BenchmarkNode::runBenchmark(const std::string& dataset_dir) dataset_reader.readAllEntries(dataset); // process dataset + int first_frame = vk::getParam("svo/dataset_first_frame", 0); for(auto it = dataset.begin(); it != dataset.end() && ros::ok(); ++it, ++frame_count_) { - // Read image + if(frame_count_ < first_frame) + continue; std::string img_filename(dataset_dir + "/" + it->image_name_); cv::Mat img(cv::imread(img_filename, 0)); if(img.empty()) { SVO_ERROR_STREAM("Reading image "<addImage(img, it->timestamp_); - visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->timestamp_); visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); - if(vo_->stage() == svo::FrameHandlerMono::STAGE_DEFAULT_FRAME) tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); } @@ -208,13 +207,14 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) SVO_INFO_STREAM("Added "<setFirstFrame(frame_ref); SVO_INFO_STREAM("Set reference frame."); - continue; } - - SVO_DEBUG_STREAM("Processing image "<image_name_<<"."); - vo_->addImage(img, it->timestamp_); - visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->timestamp_); - visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); + else + { + SVO_DEBUG_STREAM("Processing image "<image_name_<<"."); + vo_->addImage(img, it->timestamp_); + visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->timestamp_); + visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); + } if(vo_->stage() != svo::FrameHandlerMono::STAGE_DEFAULT_FRAME) { From 482b5c0f56ec9f316849ba5893ab249686d608b9 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 22 Apr 2014 18:37:40 +0200 Subject: [PATCH 074/215] added more info to readme --- svo_analysis/README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/svo_analysis/README.md b/svo_analysis/README.md index 0a4deeb..07ae6eb 100644 --- a/svo_analysis/README.md +++ b/svo_analysis/README.md @@ -25,3 +25,27 @@ Afterwards run rosrun svo_analysis benchmark.py flying_room_1_fast The script will create a new folder in `svo_analysis/results/`, run svo on the dataset and save the tracefile in this folder and at the end it will run some scripts to generate plots from the tracefile. + + +#### Dataset file + +A dataset with motion-capture-system ground-truth should contain the following files + +* _images.txt_ + + # timestamp img/imagename + 1329330952.725747585296631 img/00000.png + 1329330952.765715122222900 img/00001.png + 1329330952.805604219436646 img/00002.png + ... + +* _groundtruth.txt_: groundtruth poses as acquired from a motion capture system + + # timestamp tx ty tz qx qy qz qw + +* _groundtruth_matched.txt_: the groundtruth pose associated to the images in images.txt. This file can be generated by the command: + + cd my_dataset + rosrun svo_analysis associate.py images.txt groundtruth.txt + + From 669b65cbebfe628835dbc4424844145cc88c74a8 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sun, 27 Apr 2014 15:41:11 +0200 Subject: [PATCH 075/215] added edglet feature type --- svo/include/svo/feature.h | 43 +++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/svo/include/svo/feature.h b/svo/include/svo/feature.h index a0a30f4..142d232 100644 --- a/svo/include/svo/feature.h +++ b/svo/include/svo/feature.h @@ -26,34 +26,47 @@ struct Feature { EIGEN_MAKE_ALIGNED_OPERATOR_NEW + enum FeatureType { + CORNER, + EDGELET + }; + + FeatureType type; //!< Type can be corner or edgelet. Frame* frame; //!< Pointer to frame in which the feature was detected. Vector2d px; //!< Coordinates in pixels on pyramid level 0. Vector3d f; //!< Unit-bearing vector of the feature. int level; //!< Image pyramid level where feature was extracted. Point* point; //!< Pointer to 3D point which corresponds to the feature. + Vector2d grad; //!< Dominant gradient direction for edglets, normalized. - Feature(Frame* _frame, const Vector2d& _px, int _level) - : frame(_frame), - px(_px), - f(frame->cam_->cam2world(px)), - level(_level), - point(NULL) + Feature(Frame* _frame, const Vector2d& _px, int _level) : + type(CORNER), + frame(_frame), + px(_px), + f(frame->cam_->cam2world(px)), + level(_level), + point(NULL), + grad(0.0,0.0) {} - Feature(Frame* _frame, const Vector2d& _px, const Vector3d& _f, int _level) - : frame(_frame), + Feature(Frame* _frame, const Vector2d& _px, const Vector3d& _f, int _level) : + type(CORNER), + frame(_frame), px(_px), f(_f), level(_level), - point(NULL) + point(NULL), + grad(0.0,0.0) {} - Feature(Frame* _frame, Point* _point, const Vector2d& _px, const Vector3d& _f, int _level) - : frame(_frame), - px(_px), - f(_f), - level(_level), - point(_point) + Feature(Frame* _frame, Point* _point, const Vector2d& _px, const Vector3d& _f, int _level) : + type(CORNER), + frame(_frame), + px(_px), + f(_f), + level(_level), + point(_point), + grad(0.0,0.0) {} }; From 272ef797f96742578840e07fc163cbcc596bde8a Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sun, 27 Apr 2014 15:44:16 +0200 Subject: [PATCH 076/215] formatting --- svo/src/matcher.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/svo/src/matcher.cpp b/svo/src/matcher.cpp index 9587608..1a7dfff 100644 --- a/svo/src/matcher.cpp +++ b/svo/src/matcher.cpp @@ -69,7 +69,9 @@ void getWarpMatrixAffine( A_cur_ref.col(1) = (px_dv - px_cur)/halfpatch_size; } -int getBestSearchLevel(const Matrix2d& A_cur_ref, const int max_level) +int getBestSearchLevel( + const Matrix2d& A_cur_ref, + const int max_level) { // Compute patch level in other image int level_cur = 0; @@ -127,8 +129,7 @@ void warpAffine( } // namespace warp -bool -findMatchDirect( +bool findMatchDirect( const Point& pt, const Frame& cur_frame, Vector2d& px_cur, @@ -160,8 +161,7 @@ findMatchDirect( return success; } -bool -depthFromTriangulation( +bool depthFromTriangulation( const SE3& T_search_ref, const Vector3d& f_ref, const Vector3d& f_cur, @@ -176,8 +176,7 @@ depthFromTriangulation( return true; } -bool -findEpipolarMatchDirect( +bool findEpipolarMatchDirect( const Frame& ref_frame, const Frame& cur_frame, const Feature& ref_ftr, From d905a9ff7216540bf1c118eff87f42b1c9f0b4af Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sun, 27 Apr 2014 23:34:31 +0200 Subject: [PATCH 077/215] refactor --- svo/include/svo/feature.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/svo/include/svo/feature.h b/svo/include/svo/feature.h index 142d232..37be2b7 100644 --- a/svo/include/svo/feature.h +++ b/svo/include/svo/feature.h @@ -32,11 +32,11 @@ struct Feature }; FeatureType type; //!< Type can be corner or edgelet. - Frame* frame; //!< Pointer to frame in which the feature was detected. + Frame* frame; //!< Pointer to frame in which the feature was detected. Vector2d px; //!< Coordinates in pixels on pyramid level 0. Vector3d f; //!< Unit-bearing vector of the feature. - int level; //!< Image pyramid level where feature was extracted. - Point* point; //!< Pointer to 3D point which corresponds to the feature. + int level; //!< Image pyramid level where feature was extracted. + Point* point; //!< Pointer to 3D point which corresponds to the feature. Vector2d grad; //!< Dominant gradient direction for edglets, normalized. Feature(Frame* _frame, const Vector2d& _px, int _level) : From 692cb1b47f821e98a9b6f598feeeb14e648804ab Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sun, 27 Apr 2014 23:34:59 +0200 Subject: [PATCH 078/215] added helper function to abstract feature extractor class --- svo/include/svo/feature_detection.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/svo/include/svo/feature_detection.h b/svo/include/svo/feature_detection.h index 85e57c6..a5f5d26 100644 --- a/svo/include/svo/feature_detection.h +++ b/svo/include/svo/feature_detection.h @@ -61,13 +61,23 @@ public: void setGridOccpuancy(const Vector2d& px); protected: + static const int border_ = 8; //!< no feature should be within 8px of border. const int cell_size_; const int n_pyr_levels_; const int grid_n_cols_; const int grid_n_rows_; vector grid_occupancy_; + void resetGrid(); + void setExistingFeatures(const Features& fts); + + inline int getCellIndex(int x, int y, int level) + { + const int scale = (1< DetectorPtr; From 3ad948a0f12e4b35c0071453d5d1c030dadbad81 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sun, 27 Apr 2014 23:35:38 +0200 Subject: [PATCH 079/215] commenting --- svo/src/matcher.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/svo/src/matcher.cpp b/svo/src/matcher.cpp index 1a7dfff..550d25b 100644 --- a/svo/src/matcher.cpp +++ b/svo/src/matcher.cpp @@ -101,7 +101,7 @@ void warpAffine( return; } - // Perform the Warp on a larger patch + // Perform the warp on a larger patch. uint8_t* ref_patch_ptr = ref_patch.patch_with_border; const Vector2f px_ref_pyr = px_ref.cast() / (1< Date: Mon, 28 Apr 2014 14:23:39 +0200 Subject: [PATCH 080/215] CRITICAL: Now publishing camera in world frame. before it was the opposite. --- svo/include/svo/frame_handler_base.h | 4 ---- svo/src/frame_handler_base.cpp | 16 +++++++-------- svo/src/frame_handler_mono.cpp | 2 +- svo_ros/include/svo_ros/visualizer.h | 1 + svo_ros/src/visualizer.cpp | 30 +++++++++++++++++----------- svo_ros/src/vo_node.cpp | 11 +++++----- 6 files changed, 33 insertions(+), 31 deletions(-) diff --git a/svo/include/svo/frame_handler_base.h b/svo/include/svo/frame_handler_base.h index 66d4595..bbde3ce 100644 --- a/svo/include/svo/frame_handler_base.h +++ b/svo/include/svo/frame_handler_base.h @@ -63,9 +63,6 @@ public: virtual ~FrameHandlerBase(); - /// Set initial pose of the camera. - void setInitialPose(const SE3& T_frame_from_world) { T_f_w_init_ = T_frame_from_world; } - /// Get the current map. const Map& map() const { return map_; } @@ -92,7 +89,6 @@ protected: bool set_reset_; //!< Flag that the user can set. Will reset the system before the next iteration. bool set_start_; //!< Flag the user can set to start the system when the next image is received. Map map_; //!< Map of keyframes created by the slam system. - SE3 T_f_w_init_; //!< Initial pose of the camera. vk::Timer timer_; //!< Stopwatch to measure time to process frame. vk::RingBuffer acc_frame_timings_; //!< Total processing time of the last 10 frames, used to give some user feedback on the performance. vk::RingBuffer acc_num_obs_; //!< Number of observed features of the last 10 frames, used to give some user feedback on the tracking performance. diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index 91bf5f0..f526cb3 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -120,14 +120,14 @@ int FrameHandlerBase::finishFrameProcessingCommon( num_obs_last_ = num_observations; SVO_STOP_TIMER("tot_time"); - #ifdef SVO_TRACE - g_permon->writeToFile(); - { - boost::unique_lock lock(map_.point_candidates_.mut_); - size_t n_candidates = map_.point_candidates_.candidates_.size(); - SVO_LOG(n_candidates); - } - #endif +#ifdef SVO_TRACE + g_permon->writeToFile(); + { + boost::unique_lock lock(map_.point_candidates_.mut_); + size_t n_candidates = map_.point_candidates_.candidates_.size(); + SVO_LOG(n_candidates); + } +#endif // reset if failure or requested if(dropout == RESULT_FAILURE || set_reset_) diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index d3ce965..e588ce9 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -91,7 +91,7 @@ void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame) FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() { - new_frame_->T_f_w_ = T_f_w_init_; + new_frame_->T_f_w_ = SE3(Matrix3d::Identity(), Vector3d::Zero()); if(klt_homography_init_.addFirstFrame(new_frame_) == initialization::FAILURE) return RESULT_NO_KEYFRAME; new_frame_->setKeyframe(); diff --git a/svo_ros/include/svo_ros/visualizer.h b/svo_ros/include/svo_ros/visualizer.h index 1a7df1f..5cffa0e 100644 --- a/svo_ros/include/svo_ros/visualizer.h +++ b/svo_ros/include/svo_ros/visualizer.h @@ -59,6 +59,7 @@ public: ros::Publisher pub_dense_; image_transport::Publisher pub_images_; tf::TransformBroadcaster br_; + SE3 T_world_from_vision_; Visualizer(); ~Visualizer() {}; diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index eda01c6..f952fa8 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -43,7 +43,8 @@ Visualizer() : trace_id_(0), img_pub_level_(vk::getParam("svo/image_publishing_level", 0)), img_pub_nth_(vk::getParam("svo/publish_every_nth_img", 1)), - dense_pub_nth_(vk::getParam("svo/publish_every_nth_dense_input", 1)) + dense_pub_nth_(vk::getParam("svo/publish_every_nth_dense_input", 1)), + T_world_from_vision_(Matrix3d::Identity(), Vector3d::Zero()) { // Init ROS Marker Publishers pub_frames_ = pnh_.advertise("keyframes", 10); @@ -159,22 +160,27 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono pub_images_.publish(img_msg.toImageMsg()); } - // publish pose (world in camera frame) + // publish pose (camera in world frame) if(pub_pose_.getNumSubscribers() > 0 && frame != NULL) { + // transform from vision-frame to world-frame + SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse()); + Quaterniond q_world_from_cam(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); + const Vector3d& p_cam_in_world(T_world_from_cam.translation()); + Matrix Cov_in_world = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj(); + + // publish message geometry_msgs::PoseWithCovarianceStampedPtr msg_pose(new geometry_msgs::PoseWithCovarianceStamped); - Quaterniond q(frame->T_f_w_.rotation_matrix()); - Vector3d p(frame->T_f_w_.translation()); msg_pose->header = header_msg; - msg_pose->pose.pose.position.x = p[0]; - msg_pose->pose.pose.position.y = p[1]; - msg_pose->pose.pose.position.z = p[2]; - msg_pose->pose.pose.orientation.x = q.x(); - msg_pose->pose.pose.orientation.y = q.y(); - msg_pose->pose.pose.orientation.z = q.z(); - msg_pose->pose.pose.orientation.w = q.w(); + msg_pose->pose.pose.position.x = p_cam_in_world[0]; + msg_pose->pose.pose.position.y = p_cam_in_world[1]; + msg_pose->pose.pose.position.z = p_cam_in_world[2]; + msg_pose->pose.pose.orientation.x = q_world_from_cam.x(); + msg_pose->pose.pose.orientation.y = q_world_from_cam.y(); + msg_pose->pose.pose.orientation.z = q_world_from_cam.z(); + msg_pose->pose.pose.orientation.w = q_world_from_cam.w(); for(size_t i=0; i<36; ++i) - msg_pose->pose.covariance[i] = frame->Cov_(i%6, i/6); + msg_pose->pose.covariance[i] = Cov_in_world(i%6, i/6); pub_pose_.publish(msg_pose); } } diff --git a/svo_ros/src/vo_node.cpp b/svo_ros/src/vo_node.cpp index 9dc31dd..3dfdc92 100644 --- a/svo_ros/src/vo_node.cpp +++ b/svo_ros/src/vo_node.cpp @@ -74,18 +74,17 @@ VoNode() : if(!vk::camera_loader::loadFromRosNs("svo", cam_)) throw std::runtime_error("Camera model not correctly specified."); - // Init camera - vo_ = new svo::FrameHandlerMono(cam_); - - // Set initial position and orientation - Sophus::SE3 T_cam_from_world( + // Get initial position and orientation + visualizer_.T_world_from_vision_ = Sophus::SE3( vk::rpy2dcm(Vector3d(vk::getParam("svo/init_rx", 0.0), vk::getParam("svo/init_ry", 0.0), vk::getParam("svo/init_rz", 0.0))), Eigen::Vector3d(vk::getParam("svo/init_tx", 0.0), vk::getParam("svo/init_ty", 0.0), vk::getParam("svo/init_tz", 0.0))); - vo_->setInitialPose(T_cam_from_world); + + // Init VO and start + vo_ = new svo::FrameHandlerMono(cam_); vo_->start(); } From 42a7222b430d19eb63fd3df663a25e02951ccaf6 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 28 Apr 2014 16:43:00 +0200 Subject: [PATCH 081/215] changed interface of feature detector. now it returns directly a list of features instead of only corners --- svo/include/svo/depth_filter.h | 2 +- svo/include/svo/feature_detection.h | 17 +++++++------ svo/include/svo/frame.h | 2 +- svo/include/svo/point.h | 3 ++- svo/src/depth_filter.cpp | 27 ++++++++------------ svo/src/feature_detection.cpp | 20 +++++++++------ svo/src/frame.cpp | 7 ------ svo/src/initialization.cpp | 23 +++++++---------- svo/src/point.cpp | 18 ++++++++++++- svo/test/test_feature_detection.cpp | 39 ++++++++++++----------------- svo/test/test_pose_optimizer.cpp | 22 +++++----------- svo/test/test_sparse_img_align.cpp | 18 ++++++------- svo_ros/src/benchmark_node.cpp | 19 +++++--------- 13 files changed, 96 insertions(+), 121 deletions(-) diff --git a/svo/include/svo/depth_filter.h b/svo/include/svo/depth_filter.h index d943764..4ad2e29 100644 --- a/svo/include/svo/depth_filter.h +++ b/svo/include/svo/depth_filter.h @@ -46,7 +46,7 @@ struct Seed float z_range; //!< Max range of the possible depth. float sigma2; //!< Variance of normal distribution. Matrix2d patch_cov; //!< Patch covariance in reference image. - Seed(Feature* ftr, float angle, float depth_mean, float depth_min); + Seed(Feature* ftr, float depth_mean, float depth_min); }; /// Depth filter implements the Bayesian Update proposed in: diff --git a/svo/include/svo/feature_detection.h b/svo/include/svo/feature_detection.h index a5f5d26..d0990a8 100644 --- a/svo/include/svo/feature_detection.h +++ b/svo/include/svo/feature_detection.h @@ -52,15 +52,19 @@ public: virtual ~AbstractDetector() {}; virtual void detect( + Frame* frame, const ImgPyr& img_pyr, - const Features& fts, const double detection_threshold, - Corners* corners) = 0; + Features& fts) = 0; - /// Notify the detector that a cell already has a feature before detection. + /// Flag the grid cell as occupied void setGridOccpuancy(const Vector2d& px); + /// Set grid cells of existing features as occupied + void setExistingFeatures(const Features& fts); + protected: + static const int border_ = 8; //!< no feature should be within 8px of border. const int cell_size_; const int n_pyr_levels_; @@ -70,14 +74,11 @@ protected: void resetGrid(); - void setExistingFeatures(const Features& fts); - inline int getCellIndex(int x, int y, int level) { const int scale = (1< DetectorPtr; @@ -94,10 +95,10 @@ public: virtual ~FastDetector() {} virtual void detect( + Frame* frame, const ImgPyr& img_pyr, - const Features& fts, const double detection_threshold, - Corners* corners); + Features& fts); }; } // namespace feature_detection diff --git a/svo/include/svo/frame.h b/svo/include/svo/frame.h index f4413e7..8fcfd2c 100644 --- a/svo/include/svo/frame.h +++ b/svo/include/svo/frame.h @@ -79,7 +79,7 @@ public: void removeKeyPoint(Feature* ftr); /// Return number of point observations. - size_t nObs() const; + inline size_t nObs() const { return fts_.size(); } /// Check if a point in (w)orld coordinate frame is visible in the image. bool isVisible(const Vector3d& xyz_w) const; diff --git a/svo/include/svo/point.h b/svo/include/svo/point.h index 933b8bc..72a7221 100644 --- a/svo/include/svo/point.h +++ b/svo/include/svo/point.h @@ -56,7 +56,8 @@ public: int n_succeeded_reproj_; //!< Number of succeeded reprojections. Used to assess the quality of the point. int last_structure_optim_; //!< Timestamp of last point optimization - Point(Vector3d pos); + Point(const Vector3d& pos); + Point(const Vector3d& pos, Feature* ftr); ~Point(); /// Add a reference to a frame. diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 5e26a5e..9278cca 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -34,7 +34,7 @@ namespace svo { int Seed::batch_counter = 0; int Seed::seed_counter = 0; -Seed::Seed(Feature* ftr, float angle, float depth_mean, float depth_min) : +Seed::Seed(Feature* ftr, float depth_mean, float depth_min) : batch_id(batch_counter), id(seed_counter++), ftr(ftr), @@ -113,29 +113,22 @@ void DepthFilter::addKeyframe(FramePtr frame, double depth_mean, double depth_mi void DepthFilter::initializeSeeds(FramePtr frame) { - feature_detection::Corners corners; - feature_detector_->detect(frame->img_pyr_, frame->fts_, Config::triangMinCornerScore(), &corners); + Features new_features; + feature_detector_->setExistingFeatures(frame->fts_); + feature_detector_->detect(frame.get(), frame->img_pyr_, + Config::triangMinCornerScore(), new_features); seeds_updating_halt_ = true; lock_t lock(seeds_mut_); // by locking the updateSeeds function stops - size_t new_seeds = 0; ++Seed::batch_counter; - // now for all maximum corners, initialize a new seed - for(feature_detection::Corners::iterator it=corners.begin(); it!=corners.end(); ++it) - { - // we must check again if the score is above the threshold because the Corners - // vector is initialized with dummy corners - if(it->score > Config::triangMinCornerScore()) - { - Feature* new_feature(new Feature(frame.get(), Vector2d(it->x, it->y), it->level)); - seeds_.push_back(Seed(new_feature, it->angle, new_keyframe_mean_depth_, new_keyframe_min_depth_)); - ++new_seeds; - } - } + // initialize a seed for every new feature + std::for_each(new_features.begin(), new_features.end(), [&](Feature* ftr){ + seeds_.push_back(Seed(ftr, new_keyframe_mean_depth_, new_keyframe_min_depth_)); + }); if(options_.verbose) - SVO_INFO_STREAM("DepthFilter: Initialized "<resize(grid_n_cols_*grid_n_rows_, Corner(0,0,detection_threshold,0,0.0f)); + Corners corners(grid_n_cols_*grid_n_rows_, Corner(0,0,detection_threshold,0,0.0f)); for(int L=0; L corners->at(k).score) - corners->at(k) = Corner(xy.x*scale, xy.y*scale, score, L, 0.0f); + if(score > corners.at(k).score) + corners.at(k) = Corner(xy.x*scale, xy.y*scale, score, L, 0.0f); } } + + // Create feature for every corner that has high enough corner score + std::for_each(corners.begin(), corners.end(), [&](Corner& c) { + if(c.score > detection_threshold) + fts.push_back(new Feature(frame, Vector2d(c.x, c.y), c.level)); + }); + resetGrid(); } diff --git a/svo/src/frame.cpp b/svo/src/frame.cpp index e5f4501..6234d0b 100644 --- a/svo/src/frame.cpp +++ b/svo/src/frame.cpp @@ -137,13 +137,6 @@ void Frame::removeKeyPoint(Feature* ftr) setKeyPoints(); } -size_t Frame::nObs() const -{ - size_t n=0; - std::for_each(fts_.begin(), fts_.end(), [&](Feature* i){if(i->point != NULL) ++n; }); - return n; -} - bool Frame::isVisible(const Vector3d& xyz_w) const { Vector3d xyz_f = T_f_w_*xyz_w; diff --git a/svo/src/initialization.cpp b/svo/src/initialization.cpp index 49a7640..16d1c80 100644 --- a/svo/src/initialization.cpp +++ b/svo/src/initialization.cpp @@ -109,24 +109,19 @@ void detectFeatures( vector& px_vec, vector& f_vec) { - feature_detection::Corners corners; + Features new_features; feature_detection::FastDetector detector( frame->img().cols, frame->img().rows, Config::gridSize(), Config::nPyrLevels()); - detector.detect(frame->img_pyr_, frame->fts_, Config::triangMinCornerScore(), &corners); + detector.detect(frame.get(), frame->img_pyr_, Config::triangMinCornerScore(), new_features); // now for all maximum corners, initialize a new seed - px_vec.clear(); px_vec.reserve(corners.size()); - f_vec.clear(); f_vec.reserve(corners.size()); - for(feature_detection::Corners::iterator it=corners.begin(); it!=corners.end(); ++it) - { - // we must check again if the score is above the threshold because the Corners - // vector is initialized with dummy corners - if(it->score > Config::triangMinCornerScore()) - { - px_vec.push_back(cv::Point2f(it->x, it->y)); - f_vec.push_back(frame->c2f(it->x, it->y)); - } - } + px_vec.clear(); px_vec.reserve(new_features.size()); + f_vec.clear(); f_vec.reserve(new_features.size()); + std::for_each(new_features.begin(), new_features.end(), [&](Feature* ftr){ + px_vec.push_back(cv::Point2f(ftr->px[0], ftr->px[1])); + f_vec.push_back(ftr->f); + delete ftr; + }); } void trackKlt( diff --git a/svo/src/point.cpp b/svo/src/point.cpp index 75f14a0..bdb14c5 100644 --- a/svo/src/point.cpp +++ b/svo/src/point.cpp @@ -24,7 +24,7 @@ namespace svo { int Point::point_counter_ = 0; -Point::Point(Vector3d pos) : +Point::Point(const Vector3d& pos) : id_(point_counter_++), pos_(pos), normal_(Vector3d::Zero()), @@ -38,6 +38,22 @@ Point::Point(Vector3d pos) : last_structure_optim_(0) {} +Point::Point(const Vector3d& pos, Feature* ftr) : + id_(point_counter_++), + pos_(pos), + normal_(Vector3d::Zero()), + n_obs_(1), + v_pt_(NULL), + last_published_ts_(0), + last_projected_kf_id_(-1), + type_(TYPE_UNKNOWN), + n_failed_reproj_(0), + n_succeeded_reproj_(0), + last_structure_optim_(0) +{ + obs_.push_front(ftr); +} + Point::~Point() {} diff --git a/svo/test/test_feature_detection.cpp b/svo/test/test_feature_detection.cpp index df28508..b91e97a 100644 --- a/svo/test/test_feature_detection.cpp +++ b/svo/test/test_feature_detection.cpp @@ -17,8 +17,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -37,38 +39,29 @@ void testCornerDetector() cv::Mat img(cv::imread(img_name, 0)); assert(img.type() == CV_8UC1 && !img.empty()); - svo::ImgPyr img_pyr; - svo::frame_utils::createImgPyramid( - img, max(svo::Config::nPyrLevels(), svo::Config::kltMaxLevel()+1), img_pyr); - svo::Features fts; + vk::AbstractCamera* cam = new vk::ATANCamera(752, 480, 0.511496, 0.802603, 0.530199, 0.496011, 0.934092); + svo::FramePtr frame(new svo::Frame(cam, img, 0.0)); // Corner detection vk::Timer t; - svo::feature_detection::Corners corners; + svo::Features fts; svo::feature_detection::FastDetector fast_detector( img.cols, img.rows, svo::Config::gridSize(), svo::Config::nPyrLevels()); for(int i=0; i<100; ++i) { - fast_detector.detect(img_pyr, fts, svo::Config::triangMinCornerScore(), &corners); + fast_detector.detect(frame.get(), frame->img_pyr_, svo::Config::triangMinCornerScore(), fts); } - printf("Fast corner detection took %f ms, %zu corners detected (ref i7-W520: 8.06878ms, 416)\n", t.stop()*10, corners.size()); + printf("Fast corner detection took %f ms, %zu corners detected (ref i7-W520: 8.06878ms, 416)\n", t.stop()*10, fts.size()); + printf("Note, in this case, feature detection also contains the cam2world projection of the feature.\n"); + cv::Mat img_rgb = cv::Mat(img.size(), CV_8UC3); + cv::cvtColor(img, img_rgb, CV_GRAY2RGB); + std::for_each(fts.begin(), fts.end(), [&](svo::Feature* i){ + cv::circle(img_rgb, cv::Point2f(i->px[0], i->px[1]), 4*(i->level+1), cv::Scalar(0,255,0), 1); + }); + cv::imshow("ref_img", img_rgb); + cv::waitKey(0); - if(false) - { - cv::Mat img_rgb = cv::Mat(img.size(), CV_8UC3); - cv::cvtColor(img, img_rgb, CV_GRAY2RGB); - for(svo::feature_detection::Corners::iterator it=corners.begin(); it!=corners.end(); ++it) - { - // we must check again if the score is above the threshold because the Corners - // vector is initialized with dummy corners - if(it->score > svo::Config::triangMinCornerScore()) - { - cv::circle(img_rgb, cv::Point2f(it->x, it->y), 4*(it->level+1), cv::Scalar(0,255,0), 1); - } - } - cv::imshow("ref_img", img_rgb); - cv::waitKey(0); - } + std::for_each(fts.begin(), fts.end(), [&](svo::Feature* i){ delete i; }); } } // namespace diff --git a/svo/test/test_pose_optimizer.cpp b/svo/test/test_pose_optimizer.cpp index 88035b4..7dd79f8 100644 --- a/svo/test/test_pose_optimizer.cpp +++ b/svo/test/test_pose_optimizer.cpp @@ -58,25 +58,15 @@ class PoseOptimizerTest { vk::blender_utils::loadBlenderDepthmap(dataset_dir + "/depth/frame_000001_0.depth", *cam_, depthmap_); // detect features - feature_detection::Corners corners; feature_detection::FastDetector detector( cam_->width(), cam_->height(), Config::gridSize(), Config::nPyrLevels()); - detector.detect(frame_->img_pyr_, frame_->fts_, Config::triangMinCornerScore(), &corners); + detector.detect(frame_.get(), frame_->img_pyr_, Config::triangMinCornerScore(), frame_->fts_); size_t n_fts = 0; - for(feature_detection::Corners::iterator it=corners.begin(); it!=corners.end(); ++it) - { - // we must check again if the score is above the threshold because the Corners - // vector is initialized with dummy corners - if(it->score > Config::triangMinCornerScore()) - { - Feature* ftr(new Feature(frame_.get(), Vector2d(it->x, it->y), it->level)); - Point* point(new Point(frame_->f2w(ftr->f*depthmap_.at(it->y, it->x)))); - ftr->point = point; - ftr->frame = frame_.get(); - frame_->addFeature(ftr); - ++n_fts; - } - } + std::for_each(frame_->fts_.begin(), frame_->fts_.end(), [&](Feature* i){ + Point* point(new Point(frame_->f2w(i->f*depthmap_.at(i->px[1], i->px[0])), i)); + i->point = point; + ++n_fts; + }); printf("Added %zu features to frame.\n", n_fts); } diff --git a/svo/test/test_sparse_img_align.cpp b/svo/test/test_sparse_img_align.cpp index 9b7fa9e..fe1ece5 100644 --- a/svo/test/test_sparse_img_align.cpp +++ b/svo/test/test_sparse_img_align.cpp @@ -97,20 +97,16 @@ void SparseImgAlignTest::testSequence( dataset_dir+"/depth/"+iter->image_name_+"_0.depth", *cam_, depthmap); // extract features, generate features with 3D points - svo::feature_detection::Corners corners; feature_detector->detect( - frame_ref_->img_pyr_, frame_ref_->fts_, svo::Config::triangMinCornerScore(), &corners); - for(svo::feature_detection::Corners::iterator corner=corners.begin(); corner!=corners.end(); ++corner) - { - svo::Feature* ftr = new svo::Feature(frame_ref_.get(), Eigen::Vector2d(corner->x, corner->y), corner->level); - Eigen::Vector3d pt_pos_cur = ftr->f*depthmap.at(corner->y, corner->x); + frame_ref_.get(), frame_ref_->img_pyr_, svo::Config::triangMinCornerScore(), frame_ref_->fts_); + std::for_each(frame_ref_->fts_.begin(), frame_ref_->fts_.end(), [&](svo::Feature* i) { + Eigen::Vector3d pt_pos_cur = i->f*depthmap.at(i->px[1], i->px[0]); Eigen::Vector3d pt_pos_w = frame_ref_->T_f_w_.inverse()*pt_pos_cur; - svo::Point* pt = new svo::Point(pt_pos_w); - ftr->point = pt; - frame_ref_->addFeature(ftr); - } + svo::Point* pt = new svo::Point(pt_pos_w, i); + i->point = pt; + }); - printf("Added %zu 3d pts to the reference frame.\n", corners.size()); + printf("Added %zu 3d pts to the reference frame.\n", frame_ref_->nObs()); T_prev_w = frame_ref_->T_f_w_; T_prevgt_w = T_gt_w; continue; diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index bc94653..0c643eb 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -190,21 +190,14 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) // extract features, generate features with 3D points svo::feature_detection::FastDetector detector( cam_->width(), cam_->height(), svo::Config::gridSize(), svo::Config::nPyrLevels()); - svo::feature_detection::Corners corners; - detector.detect(frame_ref->img_pyr_, frame_ref->fts_, svo::Config::triangMinCornerScore(), &corners); - for(auto corner=corners.begin(); corner!=corners.end(); ++corner) - { - if(corner->score < Config::triangMinCornerScore()) - continue; - svo::Feature* ftr = new svo::Feature(frame_ref.get(), Eigen::Vector2d(corner->x, corner->y), corner->level); - Eigen::Vector3d pt_pos_cur = ftr->f*depthmap.at(corner->y, corner->x); + detector.detect(frame_ref.get(), frame_ref->img_pyr_, svo::Config::triangMinCornerScore(), frame_ref->fts_); + std::for_each(frame_ref->fts_.begin(), frame_ref->fts_.end(), [&](Feature* ftr) { + Eigen::Vector3d pt_pos_cur = ftr->f*depthmap.at(ftr->px[1], ftr->px[0]); Eigen::Vector3d pt_pos_world = frame_ref->T_f_w_.inverse()*pt_pos_cur; - svo::Point* point = new svo::Point(pt_pos_world); + svo::Point* point = new svo::Point(pt_pos_world, ftr); ftr->point = point; - ftr->point->addFrameRef(ftr); - frame_ref->addFeature(ftr); - } - SVO_INFO_STREAM("Added "<nObs()<<" 3d pts to the reference frame."); vo_->setFirstFrame(frame_ref); SVO_INFO_STREAM("Set reference frame."); } From 5a628bbc9b6b09f317e1c749b642c927fcc3e788 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 28 Apr 2014 23:16:53 +0200 Subject: [PATCH 082/215] removed some debug output from depth filter --- svo/include/svo/depth_filter.h | 11 +++++++---- svo/src/depth_filter.cpp | 24 ++++-------------------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/svo/include/svo/depth_filter.h b/svo/include/svo/depth_filter.h index 4ad2e29..3e14212 100644 --- a/svo/include/svo/depth_filter.h +++ b/svo/include/svo/depth_filter.h @@ -83,8 +83,11 @@ public: {} } options_; - DepthFilter(feature_detection::DetectorPtr feature_detector, callback_t seed_converged_cb); - ~DepthFilter(); + DepthFilter( + feature_detection::DetectorPtr feature_detector, + callback_t seed_converged_cb); + + virtual ~DepthFilter(); /// Start this thread when seed updating should be in a parallel thread. void startThread(); @@ -129,7 +132,7 @@ public: const double z, const double px_error_angle); -private: +protected: feature_detection::DetectorPtr feature_detector_; callback_t seed_converged_cb_; std::list > seeds_; @@ -149,7 +152,7 @@ private: void initializeSeeds(FramePtr frame); /// Update all seeds with a new measurement frame. - void updateSeeds(FramePtr frame); + virtual void updateSeeds(FramePtr frame); /// When a new keyframe arrives, the frame queue should be cleared. void clearFrameQueue(); diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 9278cca..c9e4789 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -118,18 +118,15 @@ void DepthFilter::initializeSeeds(FramePtr frame) feature_detector_->detect(frame.get(), frame->img_pyr_, Config::triangMinCornerScore(), new_features); + // initialize a seed for every new feature seeds_updating_halt_ = true; lock_t lock(seeds_mut_); // by locking the updateSeeds function stops ++Seed::batch_counter; - - // initialize a seed for every new feature std::for_each(new_features.begin(), new_features.end(), [&](Feature* ftr){ seeds_.push_back(Seed(ftr, new_keyframe_mean_depth_, new_keyframe_min_depth_)); }); - if(options_.verbose) - SVO_INFO_STREAM("DepthFilter: Initialized "<ftr->frame->f2c(xyz_f)); if(!it->ftr->frame->cam_->isInFrame(px.cast())) { ++it; - if(options_.verbose) - SVO_DEBUG_STREAM("not visible"); continue; } @@ -241,8 +235,6 @@ void DepthFilter::updateSeeds(FramePtr frame) *it->ftr->frame, *frame, *it->ftr, 1.0/it->mu, 1.0/z_inv_min, 1.0/z_inv_max, options_.epi_search_1d, z, h_inv)) { - if(options_.verbose) - SVO_INFO_STREAM("no match found"); it->b++; // increase outlier probability when no match was found ++it; ++n_failed_matches; @@ -253,13 +245,8 @@ void DepthFilter::updateSeeds(FramePtr frame) { px_noise = fmax(2.0*options_.sigma_i_sq*h_inv, 1.0); px_error_angle = atan(px_noise/(2.0*focal_length))*2.0; // law of chord (sehnensatz) - if(options_.verbose) - SVO_DEBUG_STREAM("Photometric disparity error "<ftr->f, z, px_error_angle); double tau_inverse = 0.5 * (1.0/max(0.0000001, z-tau) - 1.0/(z+tau)); @@ -275,8 +262,6 @@ void DepthFilter::updateSeeds(FramePtr frame) { Vector3d xyz_world(it->ftr->frame->T_f_w_.inverse() * (it->ftr->f * (1.0/it->mu))); seed_converged_cb_(*it, xyz_world); - if(options_.verbose) - SVO_DEBUG_STREAM("seed converged"); } it = seeds_.erase(it); } @@ -290,8 +275,7 @@ void DepthFilter::updateSeeds(FramePtr frame) } } -void DepthFilter:: -clearFrameQueue() +void DepthFilter::clearFrameQueue() { while(!frame_queue_.empty()) frame_queue_.pop(); From 69fb4828c2ebcdc808e0102b03da0f29a3c3ea13 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 29 Apr 2014 11:43:01 +0200 Subject: [PATCH 083/215] refactor --- svo/include/svo/depth_filter.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/svo/include/svo/depth_filter.h b/svo/include/svo/depth_filter.h index 3e14212..955799a 100644 --- a/svo/include/svo/depth_filter.h +++ b/svo/include/svo/depth_filter.h @@ -64,7 +64,8 @@ public: typedef boost::function callback_t; /// Depth-filter config parameters - struct Options { + struct Options + { bool check_ftr_angle; //!< gradient features are only updated if the epipolar line is orthogonal to the gradient. bool epi_search_1d; //!< restrict Gauss Newton in the epipolar search to the epipolar line. bool verbose; //!< display output. From 922d73236bb6a2bfd153bbff73784676c28af07f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 29 Apr 2014 11:43:49 +0200 Subject: [PATCH 084/215] refactor --- svo/include/svo/config.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/svo/include/svo/config.h b/svo/include/svo/config.h index 3ad547b..d4f50df 100644 --- a/svo/include/svo/config.h +++ b/svo/include/svo/config.h @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#ifndef NSLAM_CONFIG_H_ -#define NSLAM_CONFIG_H_ +#ifndef SVO_CONFIG_H_ +#define SVO_CONFIG_H_ #include #include @@ -23,7 +23,7 @@ namespace svo { -using namespace std; +using std::string; /// Global configuration file of SVO. /// Implements the Singleton design pattern to allow global access and to ensure @@ -154,6 +154,6 @@ private: int quality_max_drop_fts; }; -} // namespace nslam +} // namespace svo -#endif // NSLAM_CONFIG_H_ +#endif // SVO_CONFIG_H_ From 6ba28f50cfe1d5f52559f4517b6a19c4aa966090 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 29 Apr 2014 11:44:45 +0200 Subject: [PATCH 085/215] removed unused disparity uncertainty computation --- svo/src/depth_filter.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index c9e4789..2cbafe2 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -221,9 +221,8 @@ void DepthFilter::updateSeeds(FramePtr frame) ++it; // behind the camera continue; } - const Vector2d px(it->ftr->frame->f2c(xyz_f)); - if(!it->ftr->frame->cam_->isInFrame(px.cast())) { - ++it; + if(!it->ftr->frame->cam_->isInFrame(it->ftr->frame->f2c(xyz_f).cast())) { + ++it; // point does not project in image continue; } @@ -241,12 +240,6 @@ void DepthFilter::updateSeeds(FramePtr frame) continue; } - if(options_.use_photometric_disparity_error && h_inv > 0) - { - px_noise = fmax(2.0*options_.sigma_i_sq*h_inv, 1.0); - px_error_angle = atan(px_noise/(2.0*focal_length))*2.0; // law of chord (sehnensatz) - } - // compute tau double tau = computeTau(T_ref_cur, it->ftr->f, z, px_error_angle); double tau_inverse = 0.5 * (1.0/max(0.0000001, z-tau) - 1.0/(z+tau)); From 39bd1347f3174c47a2a39a835dddcaa3019f8b6c Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 29 Apr 2014 13:51:07 +0200 Subject: [PATCH 086/215] can now choose in which coordinate frame to publish the pose. by default the pose of the world origin is published in the camera frame of reference --- svo_ros/include/svo_ros/visualizer.h | 22 +++- svo_ros/src/visualizer.cpp | 157 ++++++++++++++++----------- 2 files changed, 109 insertions(+), 70 deletions(-) diff --git a/svo_ros/include/svo_ros/visualizer.h b/svo_ros/include/svo_ros/visualizer.h index 5cffa0e..aa6146a 100644 --- a/svo_ros/include/svo_ros/visualizer.h +++ b/svo_ros/include/svo_ros/visualizer.h @@ -42,8 +42,7 @@ class FrameHandlerMono; typedef boost::shared_ptr FramePtr; -/// This class bundles all functions to publish visualisation messages, -/// trace data and output debugging information. +/// This class bundles all functions to publish visualisation messages. class Visualizer { public: @@ -59,15 +58,30 @@ public: ros::Publisher pub_dense_; image_transport::Publisher pub_images_; tf::TransformBroadcaster br_; + bool publish_world_in_cam_frame_; SE3 T_world_from_vision_; Visualizer(); + ~Visualizer() {}; - void visualizeMarkers(const FramePtr& frame, const set& core_kfs, const Map& map); - void publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono& slam, const double timestamp); + + void publishMinimal( + const cv::Mat& img, + const FramePtr& frame, + const FrameHandlerMono& slam, + const double timestamp); + + void visualizeMarkers( + const FramePtr& frame, + const set& core_kfs, + const Map& map); + void publishMapRegion(set frames); + void removeDeletedPts(const Map& map); + void displayKeyframeWithMps(const FramePtr& frame, int ts); + void exportToDense(const FramePtr& frame); }; diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index f952fa8..32ac3e1 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -44,7 +44,8 @@ Visualizer() : img_pub_level_(vk::getParam("svo/image_publishing_level", 0)), img_pub_nth_(vk::getParam("svo/publish_every_nth_img", 1)), dense_pub_nth_(vk::getParam("svo/publish_every_nth_dense_input", 1)), - T_world_from_vision_(Matrix3d::Identity(), Vector3d::Zero()) + T_world_from_vision_(Matrix3d::Identity(), Vector3d::Zero()), + publish_world_in_cam_frame_(vk::getParam("svo/publish_world_in_cam_frame", true)) { // Init ROS Marker Publishers pub_frames_ = pnh_.advertise("keyframes", 10); @@ -58,25 +59,11 @@ Visualizer() : pub_images_ = it.advertise("image", 10); } -void Visualizer:: -visualizeMarkers(const FramePtr& frame, const set& core_kfs, const Map& map) -{ - if(frame != NULL) - { - // publish camera pose tf - vk::output_helper::publishTfTransform(frame->T_f_w_, ros::Time(frame->timestamp_), "cam_pos", "world", br_); - if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) - { - vk::output_helper::publishHexacopterMarker(pub_frames_, "cam_pos", "cams", ros::Time(frame->timestamp_), 1, 0, 0.3, Vector3d(0.,0.,1.)); - vk::output_helper::publishPointMarker(pub_points_, frame->pos(), "trajectory", ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5)); - publishMapRegion(core_kfs); - removeDeletedPts(map); - } - } -} - -void Visualizer:: -publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono& slam, const double timestamp) +void Visualizer::publishMinimal( + const cv::Mat& img, + const FramePtr& frame, + const FrameHandlerMono& slam, + const double timestamp) { ++trace_id_; std_msgs::Header header_msg; @@ -84,7 +71,7 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono header_msg.seq = trace_id_; header_msg.stamp = ros::Time(timestamp); - // publish svo info msgs + // publish info msg. if(pub_info_.getNumSubscribers() > 0) { svo_msgs::Info msg_info; @@ -102,17 +89,31 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono pub_info_.publish(msg_info); } - // publish pyramid-image every nth-frame - if(frame != NULL && img_pub_nth_ > 0 - && trace_id_%img_pub_nth_ == 0 && pub_images_.getNumSubscribers() > 0) + if(frame == 0) + { + if(pub_images_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_PAUSED) + { + // Display image when slam is not running. + cv_bridge::CvImage img_msg; + img_msg.header.stamp = ros::Time::now(); + img_msg.header.frame_id = "/image"; + img_msg.image = img; + img_msg.encoding = sensor_msgs::image_encodings::MONO8; + pub_images_.publish(img_msg.toImageMsg()); + } + return; + } + + // Publish pyramid-image every nth-frame. + if(img_pub_nth_ > 0 && trace_id_%img_pub_nth_ == 0 && pub_images_.getNumSubscribers() > 0) { const int scale = (1<img_pyr_[img_pub_level_].size(), CV_8UC3); cv::cvtColor(frame->img_pyr_[img_pub_level_], img_rgb, CV_GRAY2RGB); - // during initialization, draw lines if(slam.stage() == FrameHandlerBase::STAGE_SECOND_FRAME) { + // During initialization, draw lines. const vector& px_ref(slam.initFeatureTrackRefPx()); const vector& px_cur(slam.initFeatureTrackCurPx()); for(vector::const_iterator it_ref=px_ref.begin(), it_cur=px_cur.begin(); @@ -122,7 +123,6 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono cv::Point2f(it_ref->x/scale, it_ref->y/scale), cv::Scalar(0,255,0), 2); } - // draw features on frame if(img_pub_level_ == 0) for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) cv::rectangle(img_rgb, @@ -142,51 +142,74 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono cv::Point2f((*it)->px[0]/scale, (*it)->px[1]/scale), cv::Scalar(0,255,0), CV_FILLED); - // publish image cv_bridge::CvImage img_msg; img_msg.header = header_msg; img_msg.image = img_rgb; img_msg.encoding = sensor_msgs::image_encodings::BGR8; pub_images_.publish(img_msg.toImageMsg()); } - else if(frame == NULL && pub_images_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_PAUSED) - { - // display image when slam is not running - cv_bridge::CvImage img_msg; - img_msg.header.stamp = ros::Time::now(); - img_msg.header.frame_id = "/image"; - img_msg.image = img; - img_msg.encoding = sensor_msgs::image_encodings::MONO8; - pub_images_.publish(img_msg.toImageMsg()); - } - // publish pose (camera in world frame) - if(pub_pose_.getNumSubscribers() > 0 && frame != NULL) + if(pub_pose_.getNumSubscribers() > 0) { - // transform from vision-frame to world-frame - SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse()); - Quaterniond q_world_from_cam(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); - const Vector3d& p_cam_in_world(T_world_from_cam.translation()); - Matrix Cov_in_world = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj(); - - // publish message + Quaterniond q; + Vector3d p; + Matrix Cov; + if(publish_world_in_cam_frame_) + { + // publish world in cam frame + SE3 T_cam_from_world(frame->T_f_w_* T_world_from_vision_); + q = Quaterniond(T_cam_from_world.rotation_matrix()); + p = T_cam_from_world.translation(); + Cov = frame->Cov_; + } + else + { + // publish cam in world frame + SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse()); + q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); + p = T_world_from_cam.translation(); + Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj(); + } geometry_msgs::PoseWithCovarianceStampedPtr msg_pose(new geometry_msgs::PoseWithCovarianceStamped); msg_pose->header = header_msg; - msg_pose->pose.pose.position.x = p_cam_in_world[0]; - msg_pose->pose.pose.position.y = p_cam_in_world[1]; - msg_pose->pose.pose.position.z = p_cam_in_world[2]; - msg_pose->pose.pose.orientation.x = q_world_from_cam.x(); - msg_pose->pose.pose.orientation.y = q_world_from_cam.y(); - msg_pose->pose.pose.orientation.z = q_world_from_cam.z(); - msg_pose->pose.pose.orientation.w = q_world_from_cam.w(); + msg_pose->pose.pose.position.x = p[0]; + msg_pose->pose.pose.position.y = p[1]; + msg_pose->pose.pose.position.z = p[2]; + msg_pose->pose.pose.orientation.x = q.x(); + msg_pose->pose.pose.orientation.y = q.y(); + msg_pose->pose.pose.orientation.z = q.z(); + msg_pose->pose.pose.orientation.w = q.w(); for(size_t i=0; i<36; ++i) - msg_pose->pose.covariance[i] = Cov_in_world(i%6, i/6); + msg_pose->pose.covariance[i] = Cov(i%6, i/6); pub_pose_.publish(msg_pose); } } -void Visualizer:: -publishMapRegion(set frames) +void Visualizer::visualizeMarkers( + const FramePtr& frame, + const set& core_kfs, + const Map& map) +{ + if(frame != NULL) + { + vk::output_helper::publishTfTransform( + frame->T_f_w_*T_world_from_vision_.inverse(), + ros::Time(frame->timestamp_), "cam_pos", "world", br_); + if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) + { + vk::output_helper::publishHexacopterMarker( + pub_frames_, "cam_pos", "cams", ros::Time(frame->timestamp_), + 1, 0, 0.3, Vector3d(0.,0.,1.)); + vk::output_helper::publishPointMarker( + pub_points_, T_world_from_vision_*frame->pos(), "trajectory", + ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5)); + publishMapRegion(core_kfs); + removeDeletedPts(map); + } + } +} + +void Visualizer::publishMapRegion(set frames) { if(pub_points_.getNumSubscribers() > 0) { @@ -196,8 +219,7 @@ publishMapRegion(set frames) } } -void Visualizer:: -removeDeletedPts(const Map& map) +void Visualizer::removeDeletedPts(const Map& map) { if(pub_points_.getNumSubscribers() > 0) { @@ -206,11 +228,13 @@ removeDeletedPts(const Map& map) } } -void Visualizer:: -displayKeyframeWithMps(const FramePtr& frame, int ts) +void Visualizer::displayKeyframeWithMps(const FramePtr& frame, int ts) { // publish keyframe - vk::output_helper::publishFrameMarker(pub_frames_, frame->T_f_w_.inverse().rotation_matrix(), frame->pos(), "kfs", ros::Time::now(), frame->id_*10, 0, 0.015); + SE3 T_world_cam(T_world_from_vision_*frame->T_f_w_.inverse()); + vk::output_helper::publishFrameMarker( + pub_frames_, T_world_cam.rotation_matrix(), + T_world_cam.translation(), "kfs", ros::Time::now(), frame->id_*10, 0, 0.015); // publish point cloud and links for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) @@ -221,13 +245,14 @@ displayKeyframeWithMps(const FramePtr& frame, int ts) if((*it)->point->last_published_ts_ == ts) continue; - vk::output_helper::publishPointMarker(pub_points_, (*it)->point->pos_, "pts", ros::Time::now(), (*it)->point->id_, 0, 0.005, Vector3d(1.0, 0., 1.0)); + vk::output_helper::publishPointMarker( + pub_points_, T_world_from_vision_*(*it)->point->pos_, "pts", + ros::Time::now(), (*it)->point->id_, 0, 0.005, Vector3d(1.0, 0., 1.0)); (*it)->point->last_published_ts_ = ts; } } -void Visualizer:: -exportToDense(const FramePtr& frame) +void Visualizer::exportToDense(const FramePtr& frame) { // publish air_ground_msgs if(frame != NULL && dense_pub_nth_ > 0 @@ -252,8 +277,8 @@ exportToDense(const FramePtr& frame) if((*it)->point==NULL) continue; Vector3d pos = frame->T_f_w_*(*it)->point->pos_; - min_z = min(pos[2], min_z); - max_z = max(pos[2], max_z); + min_z = fmin(pos[2], min_z); + max_z = fmax(pos[2], max_z); } msg.min_depth = (float) min_z; msg.max_depth = (float) max_z; From 406c4231bf6f5acb547f96bfad5c1a13716cf96d Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 29 Apr 2014 13:58:06 +0200 Subject: [PATCH 087/215] set trace flags to false --- svo/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 678cd96..70a5583 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -1,8 +1,8 @@ ################################################################################ # user build settings -SET(DEBUG TRUE) -SET(TRACE TRUE) +SET(DEBUG FALSE) +SET(TRACE FALSE) SET(HAVE_G2O FALSE) ################################################################################ From cdecc6325f521316a7a295f2ac6b01910b927b15 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 29 Apr 2014 21:42:53 +0200 Subject: [PATCH 088/215] plot trajectory error also when no hand-eye-calib is available --- svo_analysis/src/svo_analysis/analyse_trajectory.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/svo_analysis/src/svo_analysis/analyse_trajectory.py b/svo_analysis/src/svo_analysis/analyse_trajectory.py index a024b79..4b11363 100755 --- a/svo_analysis/src/svo_analysis/analyse_trajectory.py +++ b/svo_analysis/src/svo_analysis/analyse_trajectory.py @@ -32,7 +32,7 @@ def plot_rotation_error(timestamps, rotation_error, results_dir): fig.tight_layout() fig.savefig(results_dir+'/orientation_error.pdf') -def analyse_trajectory(results_dir, n_align_frames = 20, use_hand_eye_calib = True): +def analyse_trajectory(results_dir, n_align_frames = 200, use_hand_eye_calib = True): if not os.path.isfile(os.path.join(results_dir, 'translation_error.txt')): @@ -91,6 +91,9 @@ def analyse_trajectory(results_dir, n_align_frames = 20, use_hand_eye_calib = Tr else: for i in range(np.shape(p_es)[0]): p_es_aligned[i,:] = scale*rot.dot(p_es[i,:]) + trans + # plot position error (drift) + translation_error = (p_gt-p_es_aligned) + plot_translation_error(t_es, translation_error, results_dir) # plot trajectory fig = plt.figure() From 44f87b860b49c4863a89ae3f09241944f0b91705 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 29 Apr 2014 21:43:24 +0200 Subject: [PATCH 089/215] refactored matcher class --- svo/include/svo/depth_filter.h | 2 + svo/include/svo/feature.h | 6 +- svo/include/svo/matcher.h | 100 ++++++++------ svo/include/svo/reprojector.h | 1 + svo/src/depth_filter.cpp | 7 +- svo/src/frame_handler_base.cpp | 4 +- svo/src/matcher.cpp | 230 ++++++++++++++------------------- svo/src/reprojector.cpp | 15 ++- svo/test/test_matcher.cpp | 23 ++-- 9 files changed, 192 insertions(+), 196 deletions(-) diff --git a/svo/include/svo/depth_filter.h b/svo/include/svo/depth_filter.h index 955799a..8effbfd 100644 --- a/svo/include/svo/depth_filter.h +++ b/svo/include/svo/depth_filter.h @@ -23,6 +23,7 @@ #include #include #include +#include namespace svo { @@ -148,6 +149,7 @@ protected: double new_keyframe_min_depth_; //!< Minimum depth in the new keyframe. Used for range in new seeds. double new_keyframe_mean_depth_; //!< Maximum depth in the new keyframe. Used for range in new seeds. vk::PerformanceMonitor permon_; //!< Separate performance monitor since the DepthFilter runs in a parallel thread. + Matcher matcher_; /// Initialize new seeds from a frame. void initializeSeeds(FramePtr frame); diff --git a/svo/include/svo/feature.h b/svo/include/svo/feature.h index 37be2b7..6f90a9a 100644 --- a/svo/include/svo/feature.h +++ b/svo/include/svo/feature.h @@ -46,7 +46,7 @@ struct Feature f(frame->cam_->cam2world(px)), level(_level), point(NULL), - grad(0.0,0.0) + grad(1.0,0.0) {} Feature(Frame* _frame, const Vector2d& _px, const Vector3d& _f, int _level) : @@ -56,7 +56,7 @@ struct Feature f(_f), level(_level), point(NULL), - grad(0.0,0.0) + grad(1.0,0.0) {} Feature(Frame* _frame, Point* _point, const Vector2d& _px, const Vector3d& _f, int _level) : @@ -66,7 +66,7 @@ struct Feature f(_f), level(_level), point(_point), - grad(0.0,0.0) + grad(1.0,0.0) {} }; diff --git a/svo/include/svo/matcher.h b/svo/include/svo/matcher.h index b79340b..ddd6e6c 100644 --- a/svo/include/svo/matcher.h +++ b/svo/include/svo/matcher.h @@ -21,6 +21,9 @@ namespace vk { class AbstractCamera; + namespace patch_score { + template class ZMSSD; + } } namespace svo { @@ -29,22 +32,6 @@ class Point; class Frame; class Feature; -/// Patch-matcher for reprojection-matching and epipolar search in triangulation. -namespace matcher { - -const int g_halfpatch_size = 4; // do not change, because of sse instructions alignment. -const int g_patch_size = 8; // do not change, because of sse instructions alignment. - -/// Manages the aligned memory of a patch. Aligned for SIMD instructions. -struct PatchData -{ - const int patch_size; - uint8_t* patch; - uint8_t* patch_with_border; - PatchData(int patch_size); - ~PatchData(); -}; - /// Warp a patch from the reference view to the current view. namespace warp { @@ -68,38 +55,67 @@ void warpAffine( const Vector2d& px_ref, const int level_ref, const int level_cur, - PatchData& ref_patch); + const int halfpatch_size, + uint8_t* patch); } // namespace warp -// TODO take function from vikit -bool depthFromTriangulation( - const SE3& T_cur_ref, - const Vector3d& f_ref, - const Vector3d& f_cur, - double& depth); +/// Patch-matcher for reprojection-matching and epipolar search in triangulation. +class Matcher +{ +public: + static const int halfpatch_size_ = 4; + static const int patch_size_ = 8; -/// Find a match by directly applying subpix refinement. -/// IMPORTANT! This function assumes that px_cur is already set to an estimate that is within ~2-3 pixel of the final result! -bool findMatchDirect( - const Point& pt, - const Frame& frame, - Vector2d& px_cur, - int& level_cur); + typedef vk::patch_score::ZMSSD PatchScore; -/// Find a match by searching along the epipolar line without using any features. -bool findEpipolarMatchDirect( - const Frame& ref_frame, - const Frame& cur_frame, - const Feature& ref_ftr, - const double d_estimate, - const double d_min, - const double d_max, - const bool align_1d, - double& depth, - double& h_inv); + struct Options + { + bool align_1d; //!< in epipolar search: align patch 1D along epipolar line + int align_max_iter; //!< number of iterations for aligning the feature patches in gauss newton + double max_epi_length_optim;//!< max length of epipolar line to skip epipolar search and directly go to img align + size_t max_epi_search_steps;//!< max number of evaluations along epipolar line + bool subpix_refinement; //!< do gauss newton feature patch alignment after epipolar search + Options() : + align_1d(false), + align_max_iter(10), + max_epi_length_optim(2.0), + max_epi_search_steps(1000), + subpix_refinement(true) + {} + } options_; + + uint8_t* patch_; + uint8_t* patch_with_border_; + Matrix2d A_cur_ref_; //!< affine warp matrix + double epi_length_; //!< length of epipolar line segment in pixels (only used for epipolar search) + double h_inv_; //!< hessian of 1d image alignment along epipolar line + int search_level_; + Feature* ref_ftr_; + + Matcher(); + ~Matcher(); + + /// Find a match by directly applying subpix refinement. + /// IMPORTANT! This function assumes that px_cur is already set to an estimate that is within ~2-3 pixel of the final result! + bool findMatchDirect( + const Point& pt, + const Frame& frame, + Vector2d& px_cur); + + /// Find a match by searching along the epipolar line without using any features. + bool findEpipolarMatchDirect( + const Frame& ref_frame, + const Frame& cur_frame, + const Feature& ref_ftr, + const double d_estimate, + const double d_min, + const double d_max, + double& depth); + + void createPatchFromPatchWithBorder(); +}; -} // namespace matcher } // namespace svo #endif // SVO_MATCHER_H_ diff --git a/svo/include/svo/reprojector.h b/svo/include/svo/reprojector.h index cc6df72..7207b54 100644 --- a/svo/include/svo/reprojector.h +++ b/svo/include/svo/reprojector.h @@ -86,6 +86,7 @@ private: }; Grid grid_; + Matcher matcher_; Map& map_; static bool pointQualityComparator(Candidate& lhs, Candidate& rhs); diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 2cbafe2..0aba62a 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -229,10 +229,9 @@ void DepthFilter::updateSeeds(FramePtr frame) // we are using inverse depth coordinates float z_inv_min = it->mu + sqrt(it->sigma2); float z_inv_max = max(it->mu - sqrt(it->sigma2), 0.00000001f); - double z, h_inv = -1.0; - if(!matcher::findEpipolarMatchDirect( - *it->ftr->frame, *frame, *it->ftr, 1.0/it->mu, 1.0/z_inv_min, 1.0/z_inv_max, - options_.epi_search_1d, z, h_inv)) + double z; + if(!matcher_.findEpipolarMatchDirect( + *it->ftr->frame, *frame, *it->ftr, 1.0/it->mu, 1.0/z_inv_min, 1.0/z_inv_max, z)) { it->b++; // increase outlier probability when no match was found ++it; diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index f526cb3..41b03ce 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -41,7 +41,7 @@ FrameHandlerBase::FrameHandlerBase() : acc_frame_timings_(10), acc_num_obs_(10), num_obs_last_(0), - tracking_quality_(TRACKING_BAD) + tracking_quality_(TRACKING_INSUFFICIENT) { #ifdef SVO_TRACE // Initialize Performance Monitor @@ -141,7 +141,7 @@ void FrameHandlerBase::resetCommon() stage_ = STAGE_PAUSED; set_reset_ = false; set_start_ = false; - tracking_quality_ = TRACKING_BAD; + tracking_quality_ = TRACKING_INSUFFICIENT; num_obs_last_ = 0; SVO_INFO_STREAM("RESET"); } diff --git a/svo/src/matcher.cpp b/svo/src/matcher.cpp index 550d25b..9ccc000 100644 --- a/svo/src/matcher.cpp +++ b/svo/src/matcher.cpp @@ -28,20 +28,6 @@ #include namespace svo { -namespace matcher { - -PatchData::PatchData(int patch_size) : - patch_size(patch_size) -{ - patch = vk::aligned_mem::aligned_alloc(patch_size*patch_size, 16); - patch_with_border = vk::aligned_mem::aligned_alloc((patch_size+2)*(patch_size+2), 16); -} - -PatchData::~PatchData() -{ - free(patch); - free(patch_with_border); -} namespace warp { @@ -74,14 +60,14 @@ int getBestSearchLevel( const int max_level) { // Compute patch level in other image - int level_cur = 0; + int search_level = 0; double D = A_cur_ref.determinant(); - while(D > 3.0 && level_cur < max_level) + while(D > 3.0 && search_level < max_level) { - level_cur += 1; + search_level += 1; D *= 0.25; } - return level_cur; + return search_level; } void warpAffine( @@ -89,12 +75,12 @@ void warpAffine( const cv::Mat& img_ref, const Vector2d& px_ref, const int level_ref, - const int level_cur, - PatchData& ref_patch) + const int search_level, + const int halfpatch_size, + uint8_t* patch) { - const int halfpatch_size = ref_patch.patch_size/2+1; const int patch_size = halfpatch_size*2 ; - Matrix2f A_ref_cur = A_cur_ref.inverse().cast(); + const Matrix2f A_ref_cur = A_cur_ref.inverse().cast(); if(isnan(A_ref_cur(0,0))) { printf("Affine warp is NaN, probably camera has no translation\n"); // TODO @@ -102,64 +88,36 @@ void warpAffine( } // Perform the warp on a larger patch. - uint8_t* ref_patch_ptr = ref_patch.patch_with_border; + uint8_t* patch_ptr = patch; const Vector2f px_ref_pyr = px_ref.cast() / (1<=img_ref.cols-1 || px[1]>=img_ref.rows-1) - *ref_patch_ptr = 0; + *patch_ptr = 0; else - *ref_patch_ptr = (uint8_t) vk::interpolateMat_8u(img_ref, px[0], px[1]); + *patch_ptr = (uint8_t) vk::interpolateMat_8u(img_ref, px[0], px[1]); } } - - // Remove border from large patch. - ref_patch_ptr = ref_patch.patch; - for(int y=1; y(patch_size_*patch_size_, 16); + patch_with_border_ = vk::aligned_mem::aligned_alloc((patch_size_+2)*(patch_size_+2), 16); +} - if(!ref_ftr->frame->cam_->isInFrame( - ref_ftr->px.cast()/(1<level), g_halfpatch_size+2, ref_ftr->level)) - return false; - - // warp affine - PatchData ref_patch(g_patch_size); - Matrix2d A_cur_ref; - warp::getWarpMatrixAffine( - *ref_ftr->frame->cam_, *cur_frame.cam_, ref_ftr->px, ref_ftr->f, - (ref_ftr->frame->pos() - pt.pos_).norm(), cur_frame.T_f_w_ * ref_ftr->frame->T_f_w_.inverse(), ref_ftr->level, A_cur_ref); - level_cur = warp::getBestSearchLevel(A_cur_ref, Config::nPyrLevels()-1); - warp::warpAffine( - A_cur_ref, ref_ftr->frame->img_pyr_[ref_ftr->level], ref_ftr->px, ref_ftr->level, level_cur, ref_patch); - - // px_cur should be set - Vector2d px_scaled(px_cur/(1<frame->cam_->isInFrame( + ref_ftr_->px.cast()/(1<level), halfpatch_size_+2, ref_ftr_->level)) + return false; + + // warp affine + warp::getWarpMatrixAffine( + *ref_ftr_->frame->cam_, *cur_frame.cam_, ref_ftr_->px, ref_ftr_->f, + (ref_ftr_->frame->pos() - pt.pos_).norm(), + cur_frame.T_f_w_ * ref_ftr_->frame->T_f_w_.inverse(), ref_ftr_->level, A_cur_ref_); + search_level_ = warp::getBestSearchLevel(A_cur_ref_, Config::nPyrLevels()-1); + warp::warpAffine(A_cur_ref_, ref_ftr_->frame->img_pyr_[ref_ftr_->level], ref_ftr_->px, + ref_ftr_->level, search_level_, halfpatch_size_+1, patch_with_border_); + createPatchFromPatchWithBorder(); + + // px_cur should be set + Vector2d px_scaled(px_cur/(1< PatchScore; - - PatchData ref_patch(g_patch_size); SE3 T_cur_ref = cur_frame.T_f_w_ * ref_frame.T_f_w_.inverse(); int zmssd_best = PatchScore::threshold(); Vector2d uv_best; @@ -201,64 +196,57 @@ bool findEpipolarMatchDirect( Vector2d epi_dir = A - B; // Compute affine warp matrix - Matrix2d A_cur_ref; warp::getWarpMatrixAffine( *ref_frame.cam_, *cur_frame.cam_, ref_ftr.px, ref_ftr.f, - d_estimate, T_cur_ref, ref_ftr.level, A_cur_ref); - int level_cur = warp::getBestSearchLevel(A_cur_ref, Config::nPyrLevels()-1); + d_estimate, T_cur_ref, ref_ftr.level, A_cur_ref_); + search_level_ = warp::getBestSearchLevel(A_cur_ref_, Config::nPyrLevels()-1); // Find length of search range on epipolar line Vector2d px_A(cur_frame.cam_->world2cam(A)); Vector2d px_B(cur_frame.cam_->world2cam(B)); - double px_length = (px_A-px_B).norm() / (1<().normalized(), - ref_patch.patch_with_border, ref_patch.patch, 10, px_scaled, h_inv); + cur_frame.img_pyr_[search_level_], (px_A-px_B).cast().normalized(), + patch_with_border_, patch_, options_.align_max_iter, px_scaled, h_inv_); else res = feature_alignment::align2D( - cur_frame.img_pyr_[level_cur], ref_patch.patch_with_border, - ref_patch.patch, 10, px_scaled); + cur_frame.img_pyr_[search_level_], patch_with_border_, patch_, + options_.align_max_iter, px_scaled); if(res) { - px = px_scaled*(1<cam2world(px), depth)) return true; } return false; } - size_t n_steps = px_length/0.7; // one step per pixel + size_t n_steps = epi_length_/0.7; // one step per pixel Vector2d step = epi_dir/n_steps; - if(n_steps > 1000) + if(n_steps > options_.max_epi_search_steps) { printf("WARNING: skip epipolar search: %zu evaluations, px_lenght=%f, d_min=%f, d_max=%f.\n", - n_steps, px_length, d_min, d_max); + n_steps, epi_length_, d_min, d_max); return false; } // for matching, precompute sum and sum2 of warped reference patch int pixel_sum = 0; int pixel_sum_square = 0; - PatchScore patch_score(ref_patch.patch); + PatchScore patch_score(patch_); // now we sample along the epipolar line Vector2d uv = B-step; @@ -267,24 +255,22 @@ bool findEpipolarMatchDirect( for(size_t i=0; iworld2cam(uv)); - Vector2i pxi(px[0]/(1<isInFrame(pxi, g_patch_size, level_cur)) + if(!cur_frame.cam_->isInFrame(pxi, patch_size_, search_level_)) continue; // TODO interpolation would probably be a good idea - uint8_t* cur_patch_ptr = cur_frame.img_pyr_[level_cur].data + (pxi[1]-g_halfpatch_size)*cur_frame.img_pyr_[level_cur].cols + (pxi[0]-g_halfpatch_size); - int zmssd = patch_score.computeScore(cur_patch_ptr, cur_frame.img_pyr_[level_cur].cols); + uint8_t* cur_patch_ptr = cur_frame.img_pyr_[search_level_].data + + (pxi[1]-halfpatch_size_)*cur_frame.img_pyr_[search_level_].cols + + (pxi[0]-halfpatch_size_); + int zmssd = patch_score.computeScore(cur_patch_ptr, cur_frame.img_pyr_[search_level_].cols); if(zmssd < zmssd_best) { zmssd_best = zmssd; @@ -292,41 +278,24 @@ bool findEpipolarMatchDirect( } } -#ifdef DEBUG_MATCHER_EPISEARCH - if(zmssd_best < g_zmssd_thresh) { - Vector2d px(cur_frame.cam_->world2cam(uv_best)); - Vector2i pxi(px[0]/(1<world2cam(uv_best)); - Vector2d px_scaled(px/(1<().normalized(), - ref_patch.patch_with_border, ref_patch.patch, 10, px_scaled, h_inv); + cur_frame.img_pyr_[search_level_], (px_A-px_B).cast().normalized(), + patch_with_border_, patch_, options_.align_max_iter, px_scaled, h_inv_); else res = feature_alignment::align2D( - cur_frame.img_pyr_[level_cur], ref_patch.patch_with_border, - ref_patch.patch, 10, px_scaled); + cur_frame.img_pyr_[search_level_], patch_with_border_, patch_, + options_.align_max_iter, px_scaled); if(res) { - px = px_scaled*(1<cam2world(px), depth)) return true; } @@ -339,5 +308,4 @@ bool findEpipolarMatchDirect( return false; } -} // namespace matcher } // namespace svo diff --git a/svo/src/reprojector.cpp b/svo/src/reprojector.cpp index c0a0bc1..6081620 100644 --- a/svo/src/reprojector.cpp +++ b/svo/src/reprojector.cpp @@ -162,10 +162,9 @@ bool Reprojector::reprojectCell(Cell& cell, FramePtr frame) continue; } - int feature_level; bool found_match = true; if(options_.find_match_direct) - found_match = matcher::findMatchDirect(*it->pt, *frame, it->px, feature_level); + found_match = matcher_.findMatchDirect(*it->pt, *frame, it->px); if(!found_match) { it->pt->n_failed_reproj_++; @@ -180,10 +179,18 @@ bool Reprojector::reprojectCell(Cell& cell, FramePtr frame) if(it->pt->type_ == Point::TYPE_UNKNOWN && it->pt->n_succeeded_reproj_ > 10) it->pt->type_ = Point::TYPE_GOOD; - Feature* new_feature = new Feature(frame.get(), it->px, feature_level); + Feature* new_feature = new Feature(frame.get(), it->px, matcher_.search_level_); frame->addFeature(new_feature); + + // Here we add a reference in the feature to the 3D point, the other way + // round is only done if this frame is selected as keyframe. new_feature->point = it->pt; - // note, we add a reference to the point only if the frame is selected as a keyframe + + if(matcher_.ref_ftr_->type == Feature::EDGELET) + { + new_feature->type = Feature::EDGELET; + new_feature->grad = matcher_.A_cur_ref_*matcher_.ref_ftr_->grad; + } // If the keyframe is selected and we reproject the rest, we don't have to // check this point anymore. diff --git a/svo/test/test_matcher.cpp b/svo/test/test_matcher.cpp index c81c1fe..37ad1f1 100644 --- a/svo/test/test_matcher.cpp +++ b/svo/test/test_matcher.cpp @@ -82,6 +82,7 @@ class MatcherTest { void MatcherTest::testEpipolarSearchFullImg() { + svo::Matcher matcher; cv::Mat depthmap(frame_ref_->cam_->height(), frame_ref_->cam_->width(), CV_32FC1, cv::Scalar(0)); cv::Mat error_map(depthmap.rows, depthmap.cols, CV_32FC1, cv::Scalar(0)); cv::Mat mask(depthmap.rows, depthmap.cols, CV_8UC1, cv::Scalar(1)); @@ -95,10 +96,10 @@ void MatcherTest::testEpipolarSearchFullImg() { svo::Feature ftr(frame_ref_, Eigen::Vector2d(x,y), 0); double depth_gt = depth_ref_.at(y, x); - double depth_estimate, h_inv; - int res = svo::matcher::findEpipolarMatchDirect( - *frame_ref_, *frame_cur_, ftr, - depth_gt, fmax(depth_gt-depth_range,0.0), depth_gt+depth_range, false, depth_estimate, h_inv); + double depth_estimate; + int res = matcher.findEpipolarMatchDirect( + *frame_ref_, *frame_cur_, ftr, depth_gt, fmax(depth_gt-depth_range,0.0), + depth_gt+depth_range, depth_estimate); if(res) { depthmap.at(y,x) = depth_estimate; @@ -148,21 +149,23 @@ void MatcherTest::testWarpAffine() { const int halfpatch_size = 15; const int patch_size=halfpatch_size*2; - svo::matcher::PatchData md(patch_size); + svo::Matcher matcher; double depth = 1.0; Sophus::SE3 T_cur_ref(frame_cur_->T_f_w_*frame_ref_->T_f_w_.inverse()); Eigen::Vector2d px_cur(frame_cur_->cam_->world2cam(T_cur_ref*(ref_ftr_->f*depth))); // compute reference patch - cv::Mat ref_patch(patch_size, patch_size, CV_8U, md.patch_with_border); + cv::Mat ref_patch(matcher.halfpatch_size_+1, matcher.halfpatch_size_+1, + CV_8U, matcher.patch_with_border_); Eigen::Matrix2d A_cur_ref; - svo::matcher::warp::getWarpMatrixAffine( + svo::warp::getWarpMatrixAffine( *cam_, *cam_, ref_ftr_->px, ref_ftr_->f, 1.0, T_cur_ref, ref_ftr_->level, A_cur_ref); - int level_cur = svo::matcher::warp::getBestSearchLevel(A_cur_ref, svo::Config::nPyrLevels()-1); - svo::matcher::warp::warpAffine( - A_cur_ref, ref_ftr_->frame->img_pyr_[ref_ftr_->level], ref_ftr_->px, ref_ftr_->level, level_cur, md); + int level_cur = svo::warp::getBestSearchLevel(A_cur_ref, svo::Config::nPyrLevels()-1); + svo::warp::warpAffine( + A_cur_ref, ref_ftr_->frame->img_pyr_[ref_ftr_->level], ref_ftr_->px, + ref_ftr_->level, level_cur, matcher.halfpatch_size_+1, matcher.patch_with_border_); // copy current patch Eigen::Vector2i pxi(px_cur[0]/(1< Date: Wed, 30 Apr 2014 12:41:01 +0200 Subject: [PATCH 090/215] FrameHandlerMono member functions are now virtual to allow specialization --- svo/include/svo/frame_handler_mono.h | 16 ++++++++++------ svo/src/frame_handler_mono.cpp | 12 +++++++++--- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/svo/include/svo/frame_handler_mono.h b/svo/include/svo/frame_handler_mono.h index 9024394..01f7b45 100644 --- a/svo/include/svo/frame_handler_mono.h +++ b/svo/include/svo/frame_handler_mono.h @@ -29,7 +29,7 @@ class FrameHandlerMono : public FrameHandlerBase { public: FrameHandlerMono(vk::AbstractCamera* cam); - ~FrameHandlerMono(); + virtual ~FrameHandlerMono(); /// Provide an image. void addImage(const cv::Mat& img, double timestamp); @@ -60,21 +60,25 @@ protected: initialization::KltHomographyInit klt_homography_init_; //!< Used to estimate pose of the first two keyframes by estimating a homography. DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. + /// Initialize the visual odometry algorithm. + virtual void initialize(); + /// Processes the first frame and sets it as a keyframe. - UpdateResult processFirstFrame(); + virtual UpdateResult processFirstFrame(); /// Processes all frames after the first frame until a keyframe is selected. - UpdateResult processSecondFrame(); + virtual UpdateResult processSecondFrame(); /// Processes all frames after the first two keyframes. - UpdateResult processFrame(); + virtual UpdateResult processFrame(); /// Reset the frame handler. Implement in derived class. virtual void resetAll(); - void setCoreKfs(size_t n_closest); + /// Keyframe selection criterion. + virtual bool needNewKf(double scene_depth_mean); - bool needNewKf(double scene_depth_mean); + void setCoreKfs(size_t n_closest); }; } // namespace svo diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index e588ce9..1e7bac5 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -36,10 +36,16 @@ FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam) : reprojector_(cam_, map_), depth_filter_(NULL) { - // create depth filter and set callback + initialize(); +} + +void FrameHandlerMono::initialize() +{ feature_detection::DetectorPtr feature_detector( - new feature_detection::FastDetector(cam_->width(), cam_->height(), Config::gridSize(), Config::nPyrLevels())); - DepthFilter::callback_t depth_filter_cb = boost::bind(&MapPointCandidates::newCandidatePoint, &map_.point_candidates_, _1, _2); + new feature_detection::FastDetector( + cam_->width(), cam_->height(), Config::gridSize(), Config::nPyrLevels())); + DepthFilter::callback_t depth_filter_cb = boost::bind( + &MapPointCandidates::newCandidatePoint, &map_.point_candidates_, _1, _2); depth_filter_ = new DepthFilter(feature_detector, depth_filter_cb); depth_filter_->startThread(); } From 5578939b84cb266f62423f3fee5f5da96219fc5e Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 30 Apr 2014 15:20:01 +0200 Subject: [PATCH 091/215] depth filter now also updates old seeds with new keyframes. previously a keyframe was only used to initialize new seeds. --- svo/include/svo/depth_filter.h | 2 +- svo/include/svo/map.h | 2 +- svo/include/svo/matcher.h | 1 + svo/src/depth_filter.cpp | 35 +++++++++++++++++++++++++++------- svo/src/map.cpp | 11 ++--------- svo/src/matcher.cpp | 18 ++++++++--------- svo/test/test_depth_filter.cpp | 17 +++++++++-------- 7 files changed, 51 insertions(+), 35 deletions(-) diff --git a/svo/include/svo/depth_filter.h b/svo/include/svo/depth_filter.h index 8effbfd..7c4ab19 100644 --- a/svo/include/svo/depth_filter.h +++ b/svo/include/svo/depth_filter.h @@ -62,7 +62,7 @@ public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef boost::unique_lock lock_t; - typedef boost::function callback_t; + typedef boost::function callback_t; /// Depth-filter config parameters struct Options diff --git a/svo/include/svo/map.h b/svo/include/svo/map.h index 076ee01..d8e5a71 100644 --- a/svo/include/svo/map.h +++ b/svo/include/svo/map.h @@ -48,7 +48,7 @@ public: ~MapPointCandidates(); /// Add a candidate point. - void newCandidatePoint(const Seed& seed, const Vector3d& xyz_world); + void newCandidatePoint(Point* point, double depth_sigma2); /// Adds the feature to the frame and deletes candidate from list. void addCandidatePointToFrame(FramePtr frame); diff --git a/svo/include/svo/matcher.h b/svo/include/svo/matcher.h index ddd6e6c..368e182 100644 --- a/svo/include/svo/matcher.h +++ b/svo/include/svo/matcher.h @@ -92,6 +92,7 @@ public: double h_inv_; //!< hessian of 1d image alignment along epipolar line int search_level_; Feature* ref_ftr_; + Vector2d px_cur_; Matcher(); ~Matcher(); diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 0aba62a..5a56bb2 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -178,13 +178,17 @@ void DepthFilter::updateSeedsLoop() { new_keyframe_set_ = false; clearFrameQueue(); - initializeSeeds(new_keyframe_); - continue; + frame = new_keyframe_; + } + else + { + frame = frame_queue_.front(); + frame_queue_.pop(); } - frame = frame_queue_.front(); - frame_queue_.pop(); } updateSeeds(frame); + if(frame->isKeyframe()) + initializeSeeds(frame); } } @@ -247,13 +251,30 @@ void DepthFilter::updateSeeds(FramePtr frame) updateSeed(1./z, tau_inverse*tau_inverse, &*it); ++n_updates; + if(frame->isKeyframe()) + { + // The feature detector should not initialize new seeds close to this location + feature_detector_->setGridOccpuancy(matcher_.px_cur_); + } + // if the seed has converged, we initialize a new candidate point and remove the seed if(sqrt(it->sigma2) < it->z_range/options_.seed_convergence_sigma2_thresh) { - if(it->ftr->point == NULL) + assert(it->ftr->point == NULL); // TODO this should not happen anymore + Vector3d xyz_world(it->ftr->frame->T_f_w_.inverse() * (it->ftr->f * (1.0/it->mu))); + Point* point = new Point(xyz_world, it->ftr); + it->ftr->point = point; + if(frame->isKeyframe()) { - Vector3d xyz_world(it->ftr->frame->T_f_w_.inverse() * (it->ftr->f * (1.0/it->mu))); - seed_converged_cb_(*it, xyz_world); + Feature* ftr = new Feature(frame.get(), matcher_.px_cur_, matcher_.search_level_); + ftr->point = point; + point->addFrameRef(ftr); + frame->addFeature(ftr); + it->ftr->frame->addFeature(it->ftr); + } + else + { + seed_converged_cb_(point, it->sigma2); // put in candidate list } it = seeds_.erase(it); } diff --git a/svo/src/map.cpp b/svo/src/map.cpp index 1decc22..69839ad 100644 --- a/svo/src/map.cpp +++ b/svo/src/map.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include namespace svo { @@ -193,17 +192,11 @@ MapPointCandidates::~MapPointCandidates() reset(); } -void MapPointCandidates::newCandidatePoint(const Seed& seed, const Vector3d& xyz_world) +void MapPointCandidates::newCandidatePoint(Point* point, double depth_sigma2) { - // initalize a new point - Point* point = new Point(xyz_world); - point->addFrameRef(seed.ftr); point->type_ = Point::TYPE_CANDIDATE; - seed.ftr->point = point; - - // add candidate to list boost::unique_lock lock(mut_); - candidates_.push_back(PointCandidate(point, seed.ftr)); + candidates_.push_back(PointCandidate(point, point->obs_.front())); } void MapPointCandidates::addCandidatePointToFrame(FramePtr frame) diff --git a/svo/src/matcher.cpp b/svo/src/matcher.cpp index 9ccc000..bced525 100644 --- a/svo/src/matcher.cpp +++ b/svo/src/matcher.cpp @@ -213,8 +213,8 @@ bool Matcher::findEpipolarMatchDirect( if(epi_length_ < 2.0) { - Vector2d px = (px_A+px_B)/2.0; - Vector2d px_scaled(px/(1<cam2world(px), depth)) + px_cur_ = px_scaled*(1<cam2world(px_cur_), depth)) return true; } return false; @@ -282,8 +282,8 @@ bool Matcher::findEpipolarMatchDirect( { if(options_.subpix_refinement) { - Vector2d px(cur_frame.cam_->world2cam(uv_best)); - Vector2d px_scaled(px/(1<world2cam(uv_best); + Vector2d px_scaled(px_cur_/(1<cam2world(px), depth)) + px_cur_ = px_scaled*(1<cam2world(px_cur_), depth)) return true; } return false; } - + px_cur_ = cur_frame.cam_->world2cam(uv_best); if(depthFromTriangulation(T_cur_ref, ref_ftr.f, vk::unproject2d(uv_best).normalized(), depth)) return true; } diff --git a/svo/test/test_depth_filter.cpp b/svo/test/test_depth_filter.cpp index 6072218..4127338 100644 --- a/svo/test/test_depth_filter.cpp +++ b/svo/test/test_depth_filter.cpp @@ -49,7 +49,7 @@ class DepthFilterTest { public: DepthFilterTest(); virtual ~DepthFilterTest(); - void depthFilterCb(const svo::Seed& seed, const Eigen::Vector3d& xyz_world); + void depthFilterCb(svo::Point* point, double depth_sigma2); void testReconstruction(std::string dataset_dir, std::string experiment_name); std::list results_; @@ -76,15 +76,16 @@ DepthFilterTest::~DepthFilterTest() delete cam_; } -void DepthFilterTest::depthFilterCb( - const svo::Seed& seed, - const Eigen::Vector3d& xyz_world) +void DepthFilterTest::depthFilterCb(svo::Point* point, double depth_sigma2) { - double depth = (frame_ref_->pos() - xyz_world).norm(); - double error = fabs(depth - depth_ref_.at(seed.ftr->px[1], seed.ftr->px[0])); - results_.push_back(ConvergedSeed(seed.ftr->px[0], seed.ftr->px[1], depth, error)); + double depth = (frame_ref_->pos() - point->pos_).norm(); + double error = fabs(depth - depth_ref_.at(point->obs_.front()->px[1], + point->obs_.front()->px[0])); + results_.push_back(ConvergedSeed( + point->obs_.front()->px[0], point->obs_.front()->px[1], depth, error)); errors_.push_back(error); - delete seed.ftr; + delete point->obs_.front(); + delete point; ++n_converged_seeds_; } From 15c45f58e66ca308e93bbac3801559894930813d Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 30 Apr 2014 15:26:04 +0200 Subject: [PATCH 092/215] remove unused variable --- svo/src/depth_filter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 5a56bb2..3e9fdfd 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -197,7 +197,6 @@ void DepthFilter::updateSeeds(FramePtr frame) // update only a limited number of seeds, because we don't have time to do it // for all the seeds in every frame! size_t n_updates=0, n_failed_matches=0, n_seeds = seeds_.size(); - double reproj_thresh = Config::lobaThresh() / frame->cam_->errorMultiplier2(); lock_t lock(seeds_mut_); list::iterator it=seeds_.begin(); From 465f04d1e34e858d553bba5314b6e47aeb37f06f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 30 Apr 2014 22:25:54 +0200 Subject: [PATCH 093/215] refactor --- svo_ros/src/vo_node.cpp | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/svo_ros/src/vo_node.cpp b/svo_ros/src/vo_node.cpp index 3dfdc92..d903b3b 100644 --- a/svo_ros/src/vo_node.cpp +++ b/svo_ros/src/vo_node.cpp @@ -37,9 +37,6 @@ namespace svo { -using namespace std; -using namespace vk; - /// SVO Interface class VoNode { @@ -50,7 +47,7 @@ public: bool publish_dense_input_; vk::UserInputThread* user_input_thread_; ros::Subscriber sub_remote_key_; - string remote_input_; + std::string remote_input_; vk::AbstractCamera* cam_; bool quit_; VoNode(); @@ -60,8 +57,7 @@ public: void remoteKeyCb(const std_msgs::StringConstPtr& key_input); }; -VoNode:: -VoNode() : +VoNode::VoNode() : vo_(NULL), publish_markers_(vk::getParam("svo/publish_markers", true)), publish_dense_input_(vk::getParam("svo/publish_dense_input", false)), @@ -88,16 +84,14 @@ VoNode() : vo_->start(); } -VoNode:: -~VoNode() +VoNode::~VoNode() { delete vo_; delete user_input_thread_; delete cam_; } -void VoNode:: -imgCb(const sensor_msgs::ImageConstPtr& msg) +void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) { cv::Mat img; try { @@ -116,7 +110,7 @@ imgCb(const sensor_msgs::ImageConstPtr& msg) visualizer_.exportToDense(vo_->lastFrame()); if(vo_->stage() == FrameHandlerMono::STAGE_PAUSED) - usleep(100000); // avoid busy loop when paused + usleep(100000); } void VoNode::processUserActions() @@ -132,15 +126,15 @@ void VoNode::processUserActions() { case 'q': quit_ = true; - printf("Svo User Input: QUIT\n"); + printf("SVO user input: QUIT\n"); break; case 'r': vo_->reset(); - printf("Svo User Input: RESET\n"); + printf("SVO user input: RESET\n"); break; case 's': vo_->start(); - printf("Svo User Input: START\n"); + printf("SVO user input: START\n"); break; default: ; } @@ -175,6 +169,6 @@ int main(int argc, char **argv) // TODO check when last image was processed. when too long ago. publish warning that no msgs are received! } - printf("Svo terminated.\n"); + printf("SVO terminated.\n"); return 0; } From 68e1e05048b226f371d4a745d3ed4c73c392df71 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 30 Apr 2014 22:27:11 +0200 Subject: [PATCH 094/215] fixed locking problem --- svo/src/depth_filter.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 3e9fdfd..8ce79da 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -127,7 +127,6 @@ void DepthFilter::initializeSeeds(FramePtr frame) }); SVO_DEBUG_STREAM("DepthFilter: Initialized "<ftr->frame->T_f_w_ * frame->T_f_w_.inverse(); - // check if point is visible in the current image + SE3 T_ref_cur = it->ftr->frame->T_f_w_ * frame->T_f_w_.inverse(); const Vector3d xyz_f(T_ref_cur.inverse()*(1.0/it->mu * it->ftr->f) ); if(xyz_f.z() < 0.0) { ++it; // behind the camera From 8d3ed5078c3d24417e825f4e7b5dc7ab105e124f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 30 Apr 2014 22:28:56 +0200 Subject: [PATCH 095/215] set second frame as keyframe before it is handed to depth filter. otherwise no new seeds are initialized for this frame. --- svo/src/frame_handler_mono.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 1e7bac5..419f21f 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -120,12 +120,12 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() ba::twoViewBA(new_frame_.get(), map_.lastKeyframe().get(), Config::lobaThresh(), map_); #endif + new_frame_->setKeyframe(); double depth_mean, depth_min; frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min); // add frame to map - new_frame_->setKeyframe(); map_.addKeyframe(new_frame_); stage_ = STAGE_DEFAULT_FRAME; klt_homography_init_.reset(); From 6d592b3aa4ba15ba286961ee6e3940af8017c64b Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 30 Apr 2014 22:29:41 +0200 Subject: [PATCH 096/215] normalized edglet dir --- svo/src/reprojector.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/svo/src/reprojector.cpp b/svo/src/reprojector.cpp index 6081620..81a7835 100644 --- a/svo/src/reprojector.cpp +++ b/svo/src/reprojector.cpp @@ -190,6 +190,7 @@ bool Reprojector::reprojectCell(Cell& cell, FramePtr frame) { new_feature->type = Feature::EDGELET; new_feature->grad = matcher_.A_cur_ref_*matcher_.ref_ftr_->grad; + new_feature->grad.normalize(); } // If the keyframe is selected and we reproject the rest, we don't have to From a895a99fd1943805fa93c2e8d7949ab20da9779a Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 1 May 2014 12:42:23 +0200 Subject: [PATCH 097/215] comment changes that are not thread-safe --- svo/src/depth_filter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 8ce79da..7f8f3c3 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -261,6 +261,7 @@ void DepthFilter::updateSeeds(FramePtr frame) Vector3d xyz_world(it->ftr->frame->T_f_w_.inverse() * (it->ftr->f * (1.0/it->mu))); Point* point = new Point(xyz_world, it->ftr); it->ftr->point = point; + /* FIXME it is not threadsafe to add a feature to the frame here. if(frame->isKeyframe()) { Feature* ftr = new Feature(frame.get(), matcher_.px_cur_, matcher_.search_level_); @@ -270,6 +271,7 @@ void DepthFilter::updateSeeds(FramePtr frame) it->ftr->frame->addFeature(it->ftr); } else + */ { seed_converged_cb_(point, it->sigma2); // put in candidate list } From 060eca8bfe84ee1792a685d3ff60f445fa4041ba Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 1 May 2014 12:43:15 +0200 Subject: [PATCH 098/215] visualization --- svo_ros/src/visualizer.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index 32ac3e1..4800c21 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -124,11 +124,21 @@ void Visualizer::publishMinimal( } if(img_pub_level_ == 0) + { for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) - cv::rectangle(img_rgb, - cv::Point2f((*it)->px[0]-2, (*it)->px[1]-2), - cv::Point2f((*it)->px[0]+2, (*it)->px[1]+2), - cv::Scalar(0,255,0), CV_FILLED); + { + if((*it)->type == Feature::EDGELET) + cv::line(img_rgb, + cv::Point2f((*it)->px[0]+3*(*it)->grad[1], (*it)->px[1]-3*(*it)->grad[0]), + cv::Point2f((*it)->px[0]-3*(*it)->grad[1], (*it)->px[1]+3*(*it)->grad[0]), + cv::Scalar(255,255,0), 2); + else + cv::rectangle(img_rgb, + cv::Point2f((*it)->px[0]-2, (*it)->px[1]-2), + cv::Point2f((*it)->px[0]+2, (*it)->px[1]+2), + cv::Scalar(0,255,0), CV_FILLED); + } + } if(img_pub_level_ == 1) for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) cv::rectangle(img_rgb, From 59544182499f5a6ae375dbd1cb3c7044759d02f8 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 1 May 2014 18:28:28 +0200 Subject: [PATCH 099/215] visualization of edgelets --- svo_ros/src/visualizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index 4800c21..e207bbe 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -131,7 +131,7 @@ void Visualizer::publishMinimal( cv::line(img_rgb, cv::Point2f((*it)->px[0]+3*(*it)->grad[1], (*it)->px[1]-3*(*it)->grad[0]), cv::Point2f((*it)->px[0]-3*(*it)->grad[1], (*it)->px[1]+3*(*it)->grad[0]), - cv::Scalar(255,255,0), 2); + cv::Scalar(255,0,255), 2); else cv::rectangle(img_rgb, cv::Point2f((*it)->px[0]-2, (*it)->px[1]-2), From d0ce9ae3c4a6fdc5f147c92263933499aed055a7 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 1 May 2014 18:28:47 +0200 Subject: [PATCH 100/215] 1D alignment for edgelets seems to work better --- svo/src/matcher.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/svo/src/matcher.cpp b/svo/src/matcher.cpp index bced525..f3098e7 100644 --- a/svo/src/matcher.cpp +++ b/svo/src/matcher.cpp @@ -170,9 +170,22 @@ bool Matcher::findMatchDirect( // px_cur should be set Vector2d px_scaled(px_cur/(1<type == Feature::EDGELET) + { + Vector2d dir_cur(A_cur_ref_*ref_ftr_->grad); + dir_cur.normalize(); + success = feature_alignment::align1D( + cur_frame.img_pyr_[search_level_], dir_cur.cast(), + patch_with_border_, patch_, options_.align_max_iter, px_scaled, h_inv_); + } + else + { + success = feature_alignment::align2D( cur_frame.img_pyr_[search_level_], patch_with_border_, patch_, options_.align_max_iter, px_scaled); + } px_cur = px_scaled * (1< Date: Thu, 1 May 2014 18:29:24 +0200 Subject: [PATCH 101/215] implementation of a relocalizer that tries to relocalize at the last keyframe. an interface is available for more elaborated relocalizers --- svo/include/svo/frame_handler_base.h | 3 +- svo/include/svo/frame_handler_mono.h | 12 +++++ svo/include/svo/map.h | 2 + svo/src/frame_handler_base.cpp | 12 ++++- svo/src/frame_handler_mono.cpp | 67 +++++++++++++++++++++++----- svo/src/map.cpp | 12 +++++ 6 files changed, 94 insertions(+), 14 deletions(-) diff --git a/svo/include/svo/frame_handler_base.h b/svo/include/svo/frame_handler_base.h index bbde3ce..ad8dd56 100644 --- a/svo/include/svo/frame_handler_base.h +++ b/svo/include/svo/frame_handler_base.h @@ -46,7 +46,8 @@ public: STAGE_PAUSED, STAGE_FIRST_FRAME, STAGE_SECOND_FRAME, - STAGE_DEFAULT_FRAME + STAGE_DEFAULT_FRAME, + STAGE_RELOCALIZING }; enum TrackingQuality { TRACKING_INSUFFICIENT, diff --git a/svo/include/svo/frame_handler_mono.h b/svo/include/svo/frame_handler_mono.h index 01f7b45..546e501 100644 --- a/svo/include/svo/frame_handler_mono.h +++ b/svo/include/svo/frame_handler_mono.h @@ -50,6 +50,13 @@ public: /// Access the depth filter. DepthFilter* depthFilter() const { return depth_filter_; } + /// An external place recognition module may know where to relocalize. + bool relocalizeFrameAtPose( + const int keyframe_id, + const SE3& T_kf_f, + const cv::Mat& img, + const double timestamp); + protected: vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit). Reprojector reprojector_; //!< Projects points from other keyframes into the current frame @@ -72,6 +79,11 @@ protected: /// Processes all frames after the first two keyframes. virtual UpdateResult processFrame(); + /// Try relocalizing the frame at relative position to provided keyframe. + virtual UpdateResult relocalizeFrame( + const SE3& T_cur_ref, + FramePtr ref_keyframe); + /// Reset the frame handler. Implement in derived class. virtual void resetAll(); diff --git a/svo/include/svo/map.h b/svo/include/svo/map.h index d8e5a71..458622b 100644 --- a/svo/include/svo/map.h +++ b/svo/include/svo/map.h @@ -105,6 +105,8 @@ public: /// Return the keyframe which is furthest apart from pos. FramePtr getFurthestKeyframe(const Vector3d& pos) const; + bool getKeyframeById(const int id, FramePtr& frame) const; + /// Transform the whole map with rotation R, translation t and scale s. void transform(const Matrix3d& R, const Vector3d& t, const double& s); diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index 41b03ce..fb6d490 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -129,9 +129,17 @@ int FrameHandlerBase::finishFrameProcessingCommon( } #endif - // reset if failure or requested - if(dropout == RESULT_FAILURE || set_reset_) + if(dropout == RESULT_FAILURE && + (stage_ == STAGE_DEFAULT_FRAME || stage_ == STAGE_RELOCALIZING )) + { + stage_ = STAGE_RELOCALIZING; + tracking_quality_ = TRACKING_INSUFFICIENT; + } + else if (dropout == RESULT_FAILURE) resetAll(); + if(set_reset_) + resetAll(); + return 0; } diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 419f21f..3fd1a7a 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -77,6 +77,9 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) res = processSecondFrame(); else if(stage_ == STAGE_FIRST_FRAME) res = processFirstFrame(); + else if(stage_ == STAGE_RELOCALIZING) + res = relocalizeFrame(SE3(Matrix3d::Identity(), Vector3d::Zero()), + map_.getClosestKeyframe(last_frame_)); // set last frame last_frame_ = new_frame_; @@ -86,15 +89,6 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) finishFrameProcessingCommon(last_frame_->id_, res, last_frame_->nObs()); } -void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame) -{ - resetAll(); - last_frame_ = first_frame; - last_frame_->setKeyframe(); - map_.addKeyframe(last_frame_); - stage_ = STAGE_DEFAULT_FRAME; -} - FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() { new_frame_->T_f_w_ = SE3(Matrix3d::Identity(), Vector3d::Zero()); @@ -155,7 +149,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() const size_t repr_n_mps = reprojector_.n_trials_; SVO_LOG2(repr_n_mps, repr_n_new_references); SVO_DEBUG_STREAM("Reprojection:\t nPoints = "< 30) + { + last_frame_ = ref_keyframe; + FrameHandlerMono::UpdateResult res = processFrame(); + if(res != RESULT_FAILURE) + { + stage_ = STAGE_DEFAULT_FRAME; + SVO_INFO_STREAM("Relocalization successful."); + } + else + new_frame_->T_f_w_ = ref_keyframe->T_f_w_; + return res; + } + return RESULT_FAILURE; +} + +bool FrameHandlerMono::relocalizeFrameAtPose( + const int keyframe_id, + const SE3& T_f_kf, + const cv::Mat& img, + const double timestamp) +{ + FramePtr ref_keyframe; + if(!map_.getKeyframeById(keyframe_id, ref_keyframe)) + return false; + new_frame_.reset(new Frame(cam_, img.clone(), timestamp)); + UpdateResult res = relocalizeFrame(T_f_kf, ref_keyframe); + if(res != RESULT_FAILURE) { + last_frame_ = new_frame_; + return true; + } + return false; +} + void FrameHandlerMono::resetAll() { resetCommon(); @@ -245,6 +281,15 @@ void FrameHandlerMono::resetAll() depth_filter_->reset(); } +void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame) +{ + resetAll(); + last_frame_ = first_frame; + last_frame_->setKeyframe(); + map_.addKeyframe(last_frame_); + stage_ = STAGE_DEFAULT_FRAME; +} + bool FrameHandlerMono::needNewKf(double scene_depth_mean) { for(auto it=overlap_kfs_.begin(), ite=overlap_kfs_.end(); it!=ite; ++it) diff --git a/svo/src/map.cpp b/svo/src/map.cpp index 69839ad..aa63648 100644 --- a/svo/src/map.cpp +++ b/svo/src/map.cpp @@ -155,6 +155,18 @@ FramePtr Map::getFurthestKeyframe(const Vector3d& pos) const return furthest_kf; } +bool Map::getKeyframeById(const int id, FramePtr& frame) const +{ + bool found = false; + for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) + if((*it)->id_ == id) { + found = true; + frame = *it; + break; + } + return found; +} + void Map::transform(const Matrix3d& R, const Vector3d& t, const double& s) { for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) From 08f3cb4b0a812118c0125a778d32862d42d3a24f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 2 May 2014 11:22:01 +0200 Subject: [PATCH 102/215] fix in benchmark script --- svo_analysis/scripts/benchmark.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index c66f115..1ef0d7e 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -35,7 +35,10 @@ def run_experiment(dataset, params): params = dict(params.items() + algo_params.items() + dataset_params.items()) if 'dataset_is_blender' in dataset_params: params['dataset_is_blender'] = dataset_params['dataset_is_blender'] - params['dataset_first_frame'] = dataset_params['dataset_first_frame'] + if 'dataset_first_frame' in dataset_params: + params['dataset_first_frame'] = dataset_params['dataset_first_frame'] + else: + params['dataset_first_frame'] = 0 # dump experiment params to file and copy the other parameter files: params_dump_file = os.path.join(params['trace_dir'],'params.yaml') From 7ab1632d4aa5cba5ce3b853eab8ee10cf03009d8 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 5 May 2014 00:19:03 +0200 Subject: [PATCH 103/215] fixes to build on ROS Indigo --- svo/CMakeLists.txt | 2 +- svo/package.xml | 1 + svo_ros/CMakeLists.txt | 14 +++++++++++++- svo_ros/package.xml | 1 + 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 70a5583..6bd0db1 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -49,7 +49,7 @@ ELSE() ENDIF() # Add catkin and required ROS packages -FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib vikit_common vikit_ros) +FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros) # Add plain cmake packages FIND_PACKAGE(G2O REQUIRED) diff --git a/svo/package.xml b/svo/package.xml index d51d015..4d71cb3 100644 --- a/svo/package.xml +++ b/svo/package.xml @@ -13,6 +13,7 @@ catkin + cmake_modules roscpp roslib vikit_common diff --git a/svo_ros/CMakeLists.txt b/svo_ros/CMakeLists.txt index 192de3c..a490881 100644 --- a/svo_ros/CMakeLists.txt +++ b/svo_ros/CMakeLists.txt @@ -14,7 +14,19 @@ ENDIF() # Add catkin and required ROS packages FIND_PACKAGE(catkin REQUIRED COMPONENTS - roscpp nav_msgs std_msgs visualization_msgs sensor_msgs image_transport cv_bridge tf svo svo_msgs vikit_common vikit_ros + roscpp + cmake_modules + nav_msgs + std_msgs + visualization_msgs + sensor_msgs + image_transport + cv_bridge + tf + svo + svo_msgs + vikit_common + vikit_ros ) # Add plain cmake packages diff --git a/svo_ros/package.xml b/svo_ros/package.xml index efc72e0..aaa8fd3 100644 --- a/svo_ros/package.xml +++ b/svo_ros/package.xml @@ -14,6 +14,7 @@ roscpp + cmake_modules nav_msgs std_msgs visualization_msgs From 1a1302ba5e5709d636cdd0e543c63e2917314b51 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 5 May 2014 10:01:34 +0200 Subject: [PATCH 104/215] fix in benchmark script --- svo_analysis/scripts/benchmark.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index 1ef0d7e..ed97040 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -35,6 +35,8 @@ def run_experiment(dataset, params): params = dict(params.items() + algo_params.items() + dataset_params.items()) if 'dataset_is_blender' in dataset_params: params['dataset_is_blender'] = dataset_params['dataset_is_blender'] + else: + params['dataset_is_blender'] = False if 'dataset_first_frame' in dataset_params: params['dataset_first_frame'] = dataset_params['dataset_first_frame'] else: From bee16e2d0322377c436c989b0d070bdfa4d9a959 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 5 May 2014 15:35:13 +0200 Subject: [PATCH 105/215] moved jacobians to point and frame class --- svo/include/svo/frame.h | 26 ++++++++++++++++++++++++++ svo/include/svo/frame_handler_base.h | 4 ++-- svo/include/svo/point.h | 20 +++++++++++++++++--- svo/include/svo/pose_optimizer.h | 27 --------------------------- svo/src/point.cpp | 19 +------------------ svo/src/pose_optimizer.cpp | 8 ++++---- svo/src/sparse_img_align.cpp | 27 ++------------------------- 7 files changed, 52 insertions(+), 79 deletions(-) diff --git a/svo/include/svo/frame.h b/svo/include/svo/frame.h index 8fcfd2c..c926277 100644 --- a/svo/include/svo/frame.h +++ b/svo/include/svo/frame.h @@ -110,6 +110,32 @@ public: /// Return the pose of the frame in the (w)orld coordinate frame. inline Vector3d pos() const { return T_f_w_.inverse().translation(); } + + /// Frame jacobian for projection of 3D point in (f)rame coordinate to + /// unit plane coordinates uv (focal length = 1). + inline static void jacobian_xyz2uv( + const Vector3d& xyz_in_f, + Matrix& J) + { + const double x = xyz_in_f[0]; + const double y = xyz_in_f[1]; + const double z_inv = 1./xyz_in_f[2]; + const double z_inv_2 = z_inv*z_inv; + + J(0,0) = -z_inv; // -1/z + J(0,1) = 0.0; // 0 + J(0,2) = x*z_inv_2; // x/z^2 + J(0,3) = y*J(0,2); // x*y/z^2 + J(0,4) = -(1.0 + x*J(0,2)); // -(1.0 + x^2/z^2) + J(0,5) = y*z_inv; // y/z + + J(1,0) = 0.0; // 0 + J(1,1) = -z_inv; // -1/z + J(1,2) = y*z_inv_2; // y/z^2 + J(1,3) = 1.0 + y*J(1,2); // 1.0 + y^2/z^2 + J(1,4) = -J(0,3); // -x*y/z^2 + J(1,5) = -x*z_inv; // x/z + } }; diff --git a/svo/include/svo/frame_handler_base.h b/svo/include/svo/frame_handler_base.h index ad8dd56..9a78639 100644 --- a/svo/include/svo/frame_handler_base.h +++ b/svo/include/svo/frame_handler_base.h @@ -112,10 +112,10 @@ protected: virtual void resetAll() { resetCommon(); } /// Set the tracking quality based on the number of tracked features. - void setTrackingQuality(const size_t num_observations); + virtual void setTrackingQuality(const size_t num_observations); /// Optimize some of the observed 3D points. - void optimizeStructure(FramePtr frame, size_t max_n_pts, int max_iter); + virtual void optimizeStructure(FramePtr frame, size_t max_n_pts, int max_iter); }; } // namespace nslam diff --git a/svo/include/svo/point.h b/svo/include/svo/point.h index 72a7221..291f79f 100644 --- a/svo/include/svo/point.h +++ b/svo/include/svo/point.h @@ -75,11 +75,25 @@ public: /// Get number of observations. inline size_t nRefs() const { return obs_.size(); } - /// Point jacobian w.r.t frame f. - void pointJacobian(const Vector3d& p_in_f, const Matrix3d& R_f_w, Matrix23d& point_jac) const; - /// Optimize point position through minimizing the reprojection error. void optimize(const size_t n_iter); + + /// Jacobian of point projection on unit plane (focal length = 1) in frame (f). + inline static void jacobian_xyz2uv( + const Vector3d& p_in_f, + const Matrix3d& R_f_w, + Matrix23d& point_jac) + { + const double z_inv = 1.0/p_in_f[2]; + const double z_inv_sq = z_inv*z_inv; + point_jac(0, 0) = z_inv; + point_jac(0, 1) = 0.0; + point_jac(0, 2) = -p_in_f[0] * z_inv_sq; + point_jac(1, 0) = 0.0; + point_jac(1, 1) = z_inv; + point_jac(1, 2) = -p_in_f[1] * z_inv_sq; + point_jac = - point_jac * R_f_w; + } }; } // namespace svo diff --git a/svo/include/svo/pose_optimizer.h b/svo/include/svo/pose_optimizer.h index 575da32..ca048ae 100644 --- a/svo/include/svo/pose_optimizer.h +++ b/svo/include/svo/pose_optimizer.h @@ -34,33 +34,6 @@ class Point; /// Motion-only bundle adjustment. Minimize the reprojection error of a single frame. namespace pose_optimizer { -inline Matrix26d -frameJac(const SE3 & T, - const Vector3d & xyz, - const Vector2d & focal_length) -{ - const Vector3d & xyz_trans = T*xyz; - double x = xyz_trans[0]; - double y = xyz_trans[1]; - double z = xyz_trans[2]; - double z_2 = z*z; - Matrix26d frame_jac; - frame_jac(0,0) = -1./z *focal_length[0]; - frame_jac(0,1) = 0; - frame_jac(0,2) = x/z_2 *focal_length[0]; - frame_jac(0,3) = x*y/z_2 * focal_length[0]; - frame_jac(0,4) = -(1+(x*x/z_2)) *focal_length[0]; - frame_jac(0,5) = y/z *focal_length[0]; - - frame_jac(1,0) = 0; - frame_jac(1,1) = -1./z *focal_length[1]; - frame_jac(1,2) = y/z_2 *focal_length[1]; - frame_jac(1,3) = (1+y*y/z_2) *focal_length[1]; - frame_jac(1,4) = -x*y/z_2 *focal_length[1]; - frame_jac(1,5) = -x/z *focal_length[1]; - return frame_jac; -} - void optimizeGaussNewton( const double reproj_thresh, const size_t n_iter, diff --git a/svo/src/point.cpp b/svo/src/point.cpp index bdb14c5..c79053e 100644 --- a/svo/src/point.cpp +++ b/svo/src/point.cpp @@ -106,23 +106,6 @@ bool Point::getCloseViewObs(const Vector3d& framepos, Feature*& ftr) const return true; } -void Point::pointJacobian( - const Vector3d& p_in_f, - const Matrix3d& R_f_w, - Matrix23d& point_jac) const -{ - // we work on the unit plane, therefore focal lenght = 1 - const double z_inv = 1.0/p_in_f[2]; - const double z_inv_sq = z_inv*z_inv; - point_jac(0, 0) = z_inv; - point_jac(0, 1) = 0.0; - point_jac(0, 2) = -p_in_f[0] * z_inv_sq; - point_jac(1, 0) = 0.0; - point_jac(1, 1) = z_inv; - point_jac(1, 2) = -p_in_f[1] * z_inv_sq; - point_jac = - point_jac * R_f_w; -} - void Point::optimize(const size_t n_iter) { Vector3d old_point = pos_; @@ -141,7 +124,7 @@ void Point::optimize(const size_t n_iter) { Matrix23d J; const Vector3d p_in_f((*it)->frame->T_f_w_ * pos_); - pointJacobian(p_in_f, (*it)->frame->T_f_w_.rotation_matrix(), J); + Point::jacobian_xyz2uv(p_in_f, (*it)->frame->T_f_w_.rotation_matrix(), J); const Vector2d e(vk::project2d((*it)->f) - vk::project2d(p_in_f)); new_chi2 += e.squaredNorm(); A.noalias() += J.transpose() * J; diff --git a/svo/src/pose_optimizer.cpp b/svo/src/pose_optimizer.cpp index 180bb1c..5b9d25f 100644 --- a/svo/src/pose_optimizer.cpp +++ b/svo/src/pose_optimizer.cpp @@ -37,7 +37,6 @@ void optimizeGaussNewton( { // init double chi2(0.0); - Vector2d focal_length(1,1); vector chi2_vec_init, chi2_vec_final; vk::robust_cost::TukeyWeightFunction weight_function; SE3 T_old(frame->T_f_w_); @@ -79,9 +78,10 @@ void optimizeGaussNewton( { if((*it)->point == NULL) continue; - Matrix26d J = frameJac(frame->T_f_w_, (*it)->point->pos_, focal_length); - Vector2d e = vk::project2d((*it)->f) - - vk::project2d(frame->T_f_w_ * (*it)->point->pos_); + Matrix26d J; + Vector3d xyz_f(frame->T_f_w_ * (*it)->point->pos_); + Frame::jacobian_xyz2uv(xyz_f, J); + Vector2d e = vk::project2d((*it)->f) - vk::project2d(xyz_f); double sqrt_inv_cov = 1.0 / (1<<(*it)->level); e *= sqrt_inv_cov; if(iter == 0) diff --git a/svo/src/sparse_img_align.cpp b/svo/src/sparse_img_align.cpp index fc765cb..1e91fa9 100644 --- a/svo/src/sparse_img_align.cpp +++ b/svo/src/sparse_img_align.cpp @@ -82,29 +82,6 @@ Matrix SparseImgAlign::getFisherInformation() return I; } -// TODO take jacobian from Frame Class! -void frameJac(const Vector3d & xyz, Matrix & J) -{ - const double x = xyz[0]; - const double y = xyz[1]; - const double z_inv = 1./xyz[2]; - const double z_inv_2 = z_inv*z_inv; - - J(0,0) = z_inv; // 1/z - J(0,1) = 0.0; // 0 - J(0,2) = -x*z_inv_2; // -x/z^2 - J(0,3) = J(0,2)*y; // -x*y/z^2 - J(0,4) = 1.0 - J(0,2)*x; // 1.0 + x^2/z^2 - J(0,5) = -y*z_inv; // -y/z - - J(1,0) = 0.0; // 0 - J(1,1) = z_inv; // 1/z - J(1,2) = -y*z_inv_2; // -y/z^2 - J(1,3) = -1.0 + J(1,2)*y; // -1.0 - y^2/z^2 - J(1,4) = -J(0,3); // x*y/^2 - J(1,5) = x*z_inv; // x/z -} - void SparseImgAlign::precomputeReferencePatches() { const int border = patch_halfsize_+1; @@ -157,11 +134,11 @@ void SparseImgAlign::precomputeReferencePatches() // evaluate jacobian and cache Matrix frame_jac; - frameJac(xyz_ref, frame_jac); + Frame::jacobian_xyz2uv(xyz_ref, frame_jac); // cache the jacobian jacobian_cache_.col(feature_counter*patch_area_ + pixel_counter) = - - (dx*frame_jac.row(0) + dy*frame_jac.row(1))*(focal_length / (1< Date: Fri, 9 May 2014 15:05:33 +0200 Subject: [PATCH 106/215] moved feature selection to matcher --- svo/include/svo/matcher.h | 8 +++++++- svo/src/matcher.cpp | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/svo/include/svo/matcher.h b/svo/include/svo/matcher.h index 368e182..d0d1134 100644 --- a/svo/include/svo/matcher.h +++ b/svo/include/svo/matcher.h @@ -76,21 +76,27 @@ public: double max_epi_length_optim;//!< max length of epipolar line to skip epipolar search and directly go to img align size_t max_epi_search_steps;//!< max number of evaluations along epipolar line bool subpix_refinement; //!< do gauss newton feature patch alignment after epipolar search + bool epi_search_edgelet_filtering; + double epi_search_edgelet_max_angle; Options() : align_1d(false), align_max_iter(10), max_epi_length_optim(2.0), max_epi_search_steps(1000), - subpix_refinement(true) + subpix_refinement(true), + epi_search_edgelet_filtering(true), + epi_search_edgelet_max_angle(0.7) {} } options_; uint8_t* patch_; uint8_t* patch_with_border_; Matrix2d A_cur_ref_; //!< affine warp matrix + Vector2d epi_dir_; double epi_length_; //!< length of epipolar line segment in pixels (only used for epipolar search) double h_inv_; //!< hessian of 1d image alignment along epipolar line int search_level_; + bool reject_; Feature* ref_ftr_; Vector2d px_cur_; diff --git a/svo/src/matcher.cpp b/svo/src/matcher.cpp index f3098e7..0ec7714 100644 --- a/svo/src/matcher.cpp +++ b/svo/src/matcher.cpp @@ -206,12 +206,25 @@ bool Matcher::findEpipolarMatchDirect( // Compute start and end of epipolar line in old_kf for match search, on unit plane! Vector2d A = vk::project2d(T_cur_ref * (ref_ftr.f*d_min)); Vector2d B = vk::project2d(T_cur_ref * (ref_ftr.f*d_max)); - Vector2d epi_dir = A - B; + epi_dir_ = A - B; // Compute affine warp matrix warp::getWarpMatrixAffine( *ref_frame.cam_, *cur_frame.cam_, ref_ftr.px, ref_ftr.f, d_estimate, T_cur_ref, ref_ftr.level, A_cur_ref_); + + // feature pre-selection + reject_ = false; + if(ref_ftr.type == Feature::EDGELET && options_.epi_search_edgelet_filtering) + { + const Vector2d grad_cur = (A_cur_ref_ * ref_ftr.grad).normalized(); + const double cosangle = fabs(grad_cur.dot(epi_dir_.normalized())); + if(cosangle < options_.epi_search_edgelet_max_angle) { + reject_ = true; + return false; + } + } + search_level_ = warp::getBestSearchLevel(A_cur_ref_, Config::nPyrLevels()-1); // Find length of search range on epipolar line @@ -247,7 +260,7 @@ bool Matcher::findEpipolarMatchDirect( } size_t n_steps = epi_length_/0.7; // one step per pixel - Vector2d step = epi_dir/n_steps; + Vector2d step = epi_dir_/n_steps; if(n_steps > options_.max_epi_search_steps) { From 713f35697bc6fde9c507e1fa3114c9b6a1356634 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 9 May 2014 15:06:03 +0200 Subject: [PATCH 107/215] refactoring --- svo/src/pose_optimizer.cpp | 2 +- svo/src/sparse_img_align.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/svo/src/pose_optimizer.cpp b/svo/src/pose_optimizer.cpp index 5b9d25f..00ca321 100644 --- a/svo/src/pose_optimizer.cpp +++ b/svo/src/pose_optimizer.cpp @@ -138,7 +138,7 @@ void optimizeGaussNewton( chi2_vec_final.push_back(e.squaredNorm()); if(e.norm() > reproj_thresh_scaled) { - // (*it)->point->deleteFrameRef(frame); + // we don't need to delete a reference in the point since it was not created yet (*it)->point = NULL; ++n_deleted_refs; } diff --git a/svo/src/sparse_img_align.cpp b/svo/src/sparse_img_align.cpp index 1e91fa9..78323e7 100644 --- a/svo/src/sparse_img_align.cpp +++ b/svo/src/sparse_img_align.cpp @@ -60,7 +60,6 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) for(level_=max_level_; level_>=min_level_; --level_) { - setInitialChi2(1.0); mu_ = 0.1; jacobian_cache_.setZero(); have_ref_patch_cache_ = false; @@ -227,8 +226,8 @@ double SparseImgAlign::computeResiduals( { // compute Jacobian, weighted Hessian and weighted "steepest descend images" (times error) const Vector6d J(jacobian_cache_.col(feature_counter*patch_area_ + pixel_counter)); - H_ += J*J.transpose()*weight; - Jres_ -= J*res*weight; + H_.noalias() += J*J.transpose()*weight; + Jres_.noalias() -= J*res*weight; if(display_) resimg_.at((int) v_cur+y-patch_halfsize_, (int) u_cur+x-patch_halfsize_) = res/255.0; } From c66484560ca10f0c232bf7cabd3a8626ab3857ce Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 9 May 2014 19:03:44 +0200 Subject: [PATCH 108/215] Update README.md --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f8e5dae..81ad4d5 100644 --- a/README.md +++ b/README.md @@ -94,10 +94,17 @@ Clone it into your catkin workspace git clone https://github.com/uzh-rpg/rpg_svo.git If you installed g2o then set `HAVE_G2O` in `svo/CMakeLists.txt` to TRUE. -Then build + +Install missing ros dependencies. Sometimes `cmake-modules` is missing (required for including Eigen in ROS Indigo): + + sudo apt-get install ros-hydro-cmake-modules + +(replace `hydro` with your distribution). + +Finally, build: catkin_make - + Run SVO on a Dataset ------------------------- From 8a2bef49f7616c60a8f93d0b95f7b4566a06dff0 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sun, 11 May 2014 22:10:12 +0200 Subject: [PATCH 109/215] removed unused dependency of boost signals and system --- svo/CMakeLists.txt | 2 +- svo/include/svo/point.h | 2 +- svo/src/point.cpp | 2 -- svo_ros/CMakeLists.txt | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 6bd0db1..7433d71 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -57,7 +57,7 @@ FIND_PACKAGE(OpenCV REQUIRED) FIND_PACKAGE(Eigen REQUIRED) FIND_PACKAGE(Sophus REQUIRED) FIND_PACKAGE(fast REQUIRED) -FIND_PACKAGE(Boost REQUIRED COMPONENTS system thread signals) +FIND_PACKAGE(Boost REQUIRED COMPONENTS thread) # Describe catkin Project catkin_package( diff --git a/svo/include/svo/point.h b/svo/include/svo/point.h index 291f79f..9adb91d 100644 --- a/svo/include/svo/point.h +++ b/svo/include/svo/point.h @@ -45,7 +45,7 @@ public: static int point_counter_; //!< Counts the number of created points. Used to set the unique id. int id_; //!< Unique ID of the point. Vector3d pos_; //!< 3d pos of the point in the world coordinate frame. - Vector3d normal_; //!< Normal of the point + Matrix3d R_w_p_; //!< Orientation of surface patch. Z-axis is the normal. Rotation from (p)oint frame to (w)orld frame. list obs_; //!< References to keyframes which observe the point. size_t n_obs_; //!< Number of obervations: Keyframes AND successful reprojections in intermediate frames. g2oPoint* v_pt_; //!< Temporary pointer to the point-vertex in g2o during bundle adjustment. diff --git a/svo/src/point.cpp b/svo/src/point.cpp index c79053e..eadd88a 100644 --- a/svo/src/point.cpp +++ b/svo/src/point.cpp @@ -27,7 +27,6 @@ int Point::point_counter_ = 0; Point::Point(const Vector3d& pos) : id_(point_counter_++), pos_(pos), - normal_(Vector3d::Zero()), n_obs_(0), v_pt_(NULL), last_published_ts_(0), @@ -41,7 +40,6 @@ Point::Point(const Vector3d& pos) : Point::Point(const Vector3d& pos, Feature* ftr) : id_(point_counter_++), pos_(pos), - normal_(Vector3d::Zero()), n_obs_(1), v_pt_(NULL), last_published_ts_(0), diff --git a/svo_ros/CMakeLists.txt b/svo_ros/CMakeLists.txt index a490881..cb1b286 100644 --- a/svo_ros/CMakeLists.txt +++ b/svo_ros/CMakeLists.txt @@ -33,7 +33,7 @@ FIND_PACKAGE(catkin REQUIRED COMPONENTS FIND_PACKAGE(OpenCV REQUIRED) FIND_PACKAGE(Eigen REQUIRED) FIND_PACKAGE(Sophus REQUIRED) -FIND_PACKAGE(Boost REQUIRED COMPONENTS thread signals) +FIND_PACKAGE(Boost REQUIRED COMPONENTS thread) # Describe catkin Project catkin_package( From 240bed866575ccd4c296ec0e4b59da10f70cf40e Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 12 May 2014 18:00:31 +0200 Subject: [PATCH 110/215] added flag if patch normal is set --- svo/include/svo/point.h | 11 ++++++++--- svo/src/point.cpp | 11 +++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/svo/include/svo/point.h b/svo/include/svo/point.h index 9adb91d..3af92d6 100644 --- a/svo/include/svo/point.h +++ b/svo/include/svo/point.h @@ -31,7 +31,7 @@ class Feature; typedef Matrix Matrix23d; -/// A 3D point that was triangulated from at least two corresponding image features. +/// A 3D point on the surface of the scene. class Point : boost::noncopyable { public: @@ -40,12 +40,14 @@ public: TYPE_DELETED, TYPE_CANDIDATE, TYPE_UNKNOWN, - TYPE_GOOD }; + TYPE_GOOD + }; static int point_counter_; //!< Counts the number of created points. Used to set the unique id. int id_; //!< Unique ID of the point. Vector3d pos_; //!< 3d pos of the point in the world coordinate frame. - Matrix3d R_w_p_; //!< Orientation of surface patch. Z-axis is the normal. Rotation from (p)oint frame to (w)orld frame. + Vector3d normal_; //!< Surface normal at point. + bool normal_set_; //!< Flag whether the surface normal was estimated or not. list obs_; //!< References to keyframes which observe the point. size_t n_obs_; //!< Number of obervations: Keyframes AND successful reprojections in intermediate frames. g2oPoint* v_pt_; //!< Temporary pointer to the point-vertex in g2o during bundle adjustment. @@ -66,6 +68,9 @@ public: /// Remove reference to a frame. bool deleteFrameRef(Frame* frame); + /// Initialize point normal. The inital estimate will point towards the frame. + void initNormal(); + /// Check whether mappoint has reference to a frame. Feature* findFrameRef(Frame* frame); diff --git a/svo/src/point.cpp b/svo/src/point.cpp index eadd88a..48c084d 100644 --- a/svo/src/point.cpp +++ b/svo/src/point.cpp @@ -27,6 +27,7 @@ int Point::point_counter_ = 0; Point::Point(const Vector3d& pos) : id_(point_counter_++), pos_(pos), + normal_set_(false), n_obs_(0), v_pt_(NULL), last_published_ts_(0), @@ -40,6 +41,7 @@ Point::Point(const Vector3d& pos) : Point::Point(const Vector3d& pos, Feature* ftr) : id_(point_counter_++), pos_(pos), + normal_set_(false), n_obs_(1), v_pt_(NULL), last_published_ts_(0), @@ -82,6 +84,15 @@ bool Point::deleteFrameRef(Frame* frame) return false; } +void Point::initNormal() +{ + assert(!obs_.empty()); + const Feature* ftr = obs_.back(); + assert(ftr->frame != NULL); + normal_ = ftr->frame->T_f_w_.rotation_matrix().transpose()*(-ftr->f); + normal_set_ = true; +} + bool Point::getCloseViewObs(const Vector3d& framepos, Feature*& ftr) const { // TODO: get frame with same point of view AND same pyramid level! From 6a34b59f723639350d48a1a2b1272b8ec339a40c Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 12 May 2014 22:26:12 +0200 Subject: [PATCH 111/215] added uncertainty for patch normal --- svo/include/svo/point.h | 1 + svo/src/point.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/svo/include/svo/point.h b/svo/include/svo/point.h index 3af92d6..f7706be 100644 --- a/svo/include/svo/point.h +++ b/svo/include/svo/point.h @@ -47,6 +47,7 @@ public: int id_; //!< Unique ID of the point. Vector3d pos_; //!< 3d pos of the point in the world coordinate frame. Vector3d normal_; //!< Surface normal at point. + Matrix3d normal_information_; //!< Inverse covariance matrix of normal estimation. bool normal_set_; //!< Flag whether the surface normal was estimated or not. list obs_; //!< References to keyframes which observe the point. size_t n_obs_; //!< Number of obervations: Keyframes AND successful reprojections in intermediate frames. diff --git a/svo/src/point.cpp b/svo/src/point.cpp index 48c084d..2e45e06 100644 --- a/svo/src/point.cpp +++ b/svo/src/point.cpp @@ -90,6 +90,7 @@ void Point::initNormal() const Feature* ftr = obs_.back(); assert(ftr->frame != NULL); normal_ = ftr->frame->T_f_w_.rotation_matrix().transpose()*(-ftr->f); + normal_information_ = DiagonalMatrix(pow(20/(pos_-ftr->frame->pos()).norm(),2), 1.0, 1.0); normal_set_ = true; } From ba687d3dd97050daa79fae18491acf84a71cf41a Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 13 May 2014 19:27:17 +0200 Subject: [PATCH 112/215] plotting comparison of tracefiles from different runs --- svo_analysis/comparisons/speed.yaml | 14 ++ svo_analysis/scripts/benchmark.py | 2 +- svo_analysis/scripts/compare_results.py | 150 +++++++++++++++++ svo_analysis/scripts/comparison.py | 212 ++++++++++-------------- 4 files changed, 257 insertions(+), 121 deletions(-) create mode 100644 svo_analysis/comparisons/speed.yaml create mode 100755 svo_analysis/scripts/compare_results.py diff --git a/svo_analysis/comparisons/speed.yaml b/svo_analysis/comparisons/speed.yaml new file mode 100644 index 0000000..2f706d4 --- /dev/null +++ b/svo_analysis/comparisons/speed.yaml @@ -0,0 +1,14 @@ +comparison_name: speed +experiment_sets: +- label: 'old' + experiments: + - 20140415_1028_svo_ros_synthetic_speed_1404150920_plane_straight_speed4 + - 20140415_1028_svo_ros_synthetic_speed_1404150928_plane_straight_speed5 + - 20140415_1028_svo_ros_synthetic_speed_1404150935_plane_straight_speed6 + - 20140415_1028_svo_ros_synthetic_speed_1404150940_plane_straight_speed7 +- label: 'new' + experiments: + - 20140513_0949_svo_ros_synthetic_speed_1404150920_plane_straight_speed4 + - 20140513_0949_svo_ros_synthetic_speed_1404150928_plane_straight_speed5 + - 20140513_0949_svo_ros_synthetic_speed_1404150935_plane_straight_speed6 + - 20140513_0949_svo_ros_synthetic_speed_1404150940_plane_straight_speed7 \ No newline at end of file diff --git a/svo_analysis/scripts/benchmark.py b/svo_analysis/scripts/benchmark.py index ed97040..a3733ea 100755 --- a/svo_analysis/scripts/benchmark.py +++ b/svo_analysis/scripts/benchmark.py @@ -51,7 +51,7 @@ def run_experiment(dataset, params): # copy the groundtruth trajectory to the trace dir for later evaluation if params['dataset_is_blender']: - shutil.copyfile(os.path.join(params['dataset_directory'], 'trajectory.txt'), + shutil.copyfile(os.path.join(params['dataset_directory'], 'trajectory_nominal.txt'), os.path.join(params['trace_dir'], 'groundtruth_matched.txt')) else: shutil.copyfile(os.path.join(params['dataset_directory'], 'groundtruth_matched.txt'), diff --git a/svo_analysis/scripts/compare_results.py b/svo_analysis/scripts/compare_results.py new file mode 100755 index 0000000..5605fe3 --- /dev/null +++ b/svo_analysis/scripts/compare_results.py @@ -0,0 +1,150 @@ +#!/usr/bin/python + +import os +import sys +import time +import rospkg +import numpy as np +import matplotlib.pyplot as plt +import yaml +import argparse +from matplotlib import rc + +# tell matplotlib to use latex font +rc('font',**{'family':'serif','serif':['Cardo']}) +rc('text', usetex=True) + +from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes +from mpl_toolkits.axes_grid1.inset_locator import mark_inset + +def plot_trajectory(ax, filename, label, color, linewidth): + file = open(filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + trajectory = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) + ax.plot(trajectory[:,1], trajectory[:,2], label=label, color=color, linewidth=linewidth) + +def compare_results(experiments, results_dir, comparison_dir, + plot_scale_drift = False): + + # ------------------------------------------------------------------------------ + # position error + fig_poserr = plt.figure(figsize=(8,6)) + ax_poserr_x = fig_poserr.add_subplot(311, ylabel='x-error [m]') + ax_poserr_y = fig_poserr.add_subplot(312, ylabel='y-error [m]') + ax_poserr_z = fig_poserr.add_subplot(313, ylabel='z-error [m]', xlabel='time [s]') + + for exp in experiments: + + # load dataset parameters + params_stream = open(os.path.join(results_dir, exp, 'params.yaml')) + params = yaml.load(params_stream) + + # plot translation error + trans_error = np.loadtxt(os.path.join(results_dir, exp, 'translation_error.txt')) + trans_error[:,0] = trans_error[:,0]-trans_error[0,0] + ax_poserr_x.plot(trans_error[:,0], trans_error[:,1], label=params['experiment_label']) + ax_poserr_y.plot(trans_error[:,0], trans_error[:,2]) + ax_poserr_z.plot(trans_error[:,0], trans_error[:,3]) + + ax_poserr_x.set_xlim([0, trans_error[-1,0]+4]) + ax_poserr_y.set_xlim([0, trans_error[-1,0]+4]) + ax_poserr_z.set_xlim([0, trans_error[-1,0]+4]) + ax_poserr_x.legend(bbox_to_anchor=[0, 0], loc='lower left', ncol=3) + ax_poserr_x.grid() + ax_poserr_y.grid() + ax_poserr_z.grid() + fig_poserr.tight_layout() + fig_poserr.savefig(os.path.join(comparison_dir, 'translation_error.pdf')) + + # ------------------------------------------------------------------------------ + # orientation error + fig_roterr = plt.figure(figsize=(8,6)) + ax_roterr_r = fig_roterr.add_subplot(311, ylabel='roll-error [rad]') + ax_roterr_p = fig_roterr.add_subplot(312, ylabel='pitch-error [rad]') + ax_roterr_y = fig_roterr.add_subplot(313, ylabel='yaw-error [rad]', xlabel='time [s]') + + for exp in experiments: + + # load dataset parameters + params_stream = open(os.path.join(results_dir, exp, 'params.yaml')) + params = yaml.load(params_stream) + + # plot translation error + rot_error = np.loadtxt(os.path.join(results_dir, exp, 'orientation_error.txt')) + rot_error[:,0] = rot_error[:,0]-rot_error[0,0] + ax_roterr_r.plot(rot_error[:,0], rot_error[:,3], label=params['experiment_label']) + ax_roterr_p.plot(rot_error[:,0], rot_error[:,2]) + ax_roterr_y.plot(rot_error[:,0], rot_error[:,1]) + + ax_roterr_r.set_xlim([0, rot_error[-1,0]+4]) + ax_roterr_p.set_xlim([0, rot_error[-1,0]+4]) + ax_roterr_y.set_xlim([0, rot_error[-1,0]+4]) + ax_roterr_r.legend(bbox_to_anchor=[0, 1], loc='upper left', ncol=3) + ax_roterr_r.grid() + ax_roterr_p.grid() + ax_roterr_y.grid() + fig_roterr.tight_layout() + fig_roterr.savefig(os.path.join(comparison_dir, 'orientation_error.pdf')) + + # ------------------------------------------------------------------------------ + # scale error + if plot_scale_drift: + fig_scale = plt.figure(figsize=(8,2.5)) + ax_scale = fig_scale.add_subplot(111, xlabel='time [s]', ylabel='scale change [\%]') + + for exp in experiments: + + # load dataset parameters + params = yaml.load(open(os.path.join(results_dir, exp, 'params.yaml'))) + + # plot translation error + scale_drift = open(os.path.join(results_dir, exp, 'scale_drift.txt')) + scale_drift[:,0] = scale_drift[:,0]-scale_drift[0,0] + ax_scale.plot(scale_drift[:,0], scale_drift[:,1], label=params['experiment_label']) + + ax_scale.set_xlim([0, rot_error[-1,0]+4]) + ax_scale.legend(bbox_to_anchor=[0, 1], loc='upper left', ncol=3) + ax_scale.grid() + fig_scale.tight_layout() + fig_scale.savefig(os.path.join(comparison_dir, 'scale_drift.pdf')) + + # ------------------------------------------------------------------------------ + # trajectory + +# fig_traj = plt.figure(figsize=(8,4.8)) +# ax_traj = fig_traj.add_subplot(111, xlabel='x [m]', ylabel='y [m]', aspect='equal', xlim=[-3.1, 4], ylim=[-1.5, 2.6]) +# +# plotTrajectory(ax_traj, '/home/cforster/Datasets/asl_vicon_d2/groundtruth_filtered.txt', 'Groundtruth', 'k', 1.5) +# plotTrajectory(ax_traj, results_dir+'/20130911_2229_nslam_i7_asl2_fast/traj_estimate_rotated.txt', 'Fast', 'g', 1) +# plotTrajectory(ax_traj, results_dir+'/20130906_2149_ptam_i7_asl2/traj_estimate_rotated.txt', 'PTAM', 'r', 1) +# +# mark_inset(ax_traj, axins, loc1=2, loc2=4, fc="none", ec='b') +# plt.draw() +# plt.show() +# ax_traj.legend(bbox_to_anchor=[1, 0], loc='lower right', ncol=3) +# ax_traj.grid() +# fig_traj.tight_layout() +# fig_traj.savefig('../results/trajectory_asl.pdf') + + +if __name__ == '__main__': + + default_name = time.strftime("%Y%m%d_%H%M", time.localtime())+'_comparison' + parser = argparse.ArgumentParser(description='Compare results.') + parser.add_argument('result_directories', nargs='+', help='list of result directories to compare') + parser.add_argument('--name', help='name of the comparison', default=default_name) + args = parser.parse_args() + + # create folder for comparison results + results_dir = os.path.join(rospkg.RosPack().get_path('svo_analysis'), 'results') + comparison_dir = os.path.join(results_dir, args.name) + if not os.path.exists(comparison_dir): + os.makedirs(comparison_dir) + + # run comparison + compare_results(args.result_directories, results_dir, comparison_dir) + + + + diff --git a/svo_analysis/scripts/comparison.py b/svo_analysis/scripts/comparison.py index 5605fe3..1651247 100755 --- a/svo_analysis/scripts/comparison.py +++ b/svo_analysis/scripts/comparison.py @@ -18,133 +18,105 @@ from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes from mpl_toolkits.axes_grid1.inset_locator import mark_inset def plot_trajectory(ax, filename, label, color, linewidth): - file = open(filename) - data = file.read() - lines = data.replace(","," ").replace("\t"," ").split("\n") - trajectory = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) - ax.plot(trajectory[:,1], trajectory[:,2], label=label, color=color, linewidth=linewidth) + file = open(filename) + data = file.read() + lines = data.replace(","," ").replace("\t"," ").split("\n") + trajectory = np.array([[v.strip() for v in line.split(" ") if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"], dtype=np.float64) + ax.plot(trajectory[:,1], trajectory[:,2], label=label, color=color, linewidth=linewidth) -def compare_results(experiments, results_dir, comparison_dir, - plot_scale_drift = False): - - # ------------------------------------------------------------------------------ - # position error - fig_poserr = plt.figure(figsize=(8,6)) - ax_poserr_x = fig_poserr.add_subplot(311, ylabel='x-error [m]') - ax_poserr_y = fig_poserr.add_subplot(312, ylabel='y-error [m]') - ax_poserr_z = fig_poserr.add_subplot(313, ylabel='z-error [m]', xlabel='time [s]') - - for exp in experiments: +def save_figure(fig, name, directory): + fig.tight_layout() + fig.savefig(os.path.join(directory, name+'.pdf'), bbox_inches="tight") + +def distances_along_trajectory(traj): + keys = traj.keys() + keys.sort() + motion = [ominus(traj[keys[i+1]],traj[keys[i]]) for i in range(len(keys)-1)] + distances = [0] + sum = 0 + for t in motion: + sum += compute_distance(t) + distances.append(sum) + return distances - # load dataset parameters - params_stream = open(os.path.join(results_dir, exp, 'params.yaml')) - params = yaml.load(params_stream) - - # plot translation error - trans_error = np.loadtxt(os.path.join(results_dir, exp, 'translation_error.txt')) - trans_error[:,0] = trans_error[:,0]-trans_error[0,0] - ax_poserr_x.plot(trans_error[:,0], trans_error[:,1], label=params['experiment_label']) - ax_poserr_y.plot(trans_error[:,0], trans_error[:,2]) - ax_poserr_z.plot(trans_error[:,0], trans_error[:,3]) +def compare_results(comp_params, results_dir, comparison_dir): + print('run comparison: '+comp_params['comparison_name']) + - ax_poserr_x.set_xlim([0, trans_error[-1,0]+4]) - ax_poserr_y.set_xlim([0, trans_error[-1,0]+4]) - ax_poserr_z.set_xlim([0, trans_error[-1,0]+4]) - ax_poserr_x.legend(bbox_to_anchor=[0, 0], loc='lower left', ncol=3) - ax_poserr_x.grid() - ax_poserr_y.grid() - ax_poserr_z.grid() - fig_poserr.tight_layout() - fig_poserr.savefig(os.path.join(comparison_dir, 'translation_error.pdf')) - - # ------------------------------------------------------------------------------ - # orientation error - fig_roterr = plt.figure(figsize=(8,6)) - ax_roterr_r = fig_roterr.add_subplot(311, ylabel='roll-error [rad]') - ax_roterr_p = fig_roterr.add_subplot(312, ylabel='pitch-error [rad]') - ax_roterr_y = fig_roterr.add_subplot(313, ylabel='yaw-error [rad]', xlabel='time [s]') - - for exp in experiments: + # ------------------------------------------------------------------------- + # plot trajectory: + fig = plt.figure(figsize=(6,2)) + ax = fig.add_subplot(111, xlabel='x [m]', ylabel='y [m]') + for exp_set in comp_params['experiment_sets']: + print('processing experiment set: ' + exp_set['label']) + + for i, exp in enumerate(exp_set['experiments']): + data = np.loadtxt(os.path.join(results_dir, exp, 'traj_estimate.txt')) + if i == 0: + base_plot, = ax.plot(data[:,1], data[:,2], label=exp_set['label']) + else: + ax.plot(data[:,1], data[:,2], color=base_plot.get_color()) + ax.legend(loc='upper left') + save_figure(fig, 'trajectory', comparison_dir) - # load dataset parameters - params_stream = open(os.path.join(results_dir, exp, 'params.yaml')) - params = yaml.load(params_stream) - - # plot translation error - rot_error = np.loadtxt(os.path.join(results_dir, exp, 'orientation_error.txt')) - rot_error[:,0] = rot_error[:,0]-rot_error[0,0] - ax_roterr_r.plot(rot_error[:,0], rot_error[:,3], label=params['experiment_label']) - ax_roterr_p.plot(rot_error[:,0], rot_error[:,2]) - ax_roterr_y.plot(rot_error[:,0], rot_error[:,1]) - ax_roterr_r.set_xlim([0, rot_error[-1,0]+4]) - ax_roterr_p.set_xlim([0, rot_error[-1,0]+4]) - ax_roterr_y.set_xlim([0, rot_error[-1,0]+4]) - ax_roterr_r.legend(bbox_to_anchor=[0, 1], loc='upper left', ncol=3) - ax_roterr_r.grid() - ax_roterr_p.grid() - ax_roterr_y.grid() - fig_roterr.tight_layout() - fig_roterr.savefig(os.path.join(comparison_dir, 'orientation_error.pdf')) - - # ------------------------------------------------------------------------------ - # scale error - if plot_scale_drift: - fig_scale = plt.figure(figsize=(8,2.5)) - ax_scale = fig_scale.add_subplot(111, xlabel='time [s]', ylabel='scale change [\%]') - - for exp in experiments: - - # load dataset parameters - params = yaml.load(open(os.path.join(results_dir, exp, 'params.yaml'))) - - # plot translation error - scale_drift = open(os.path.join(results_dir, exp, 'scale_drift.txt')) - scale_drift[:,0] = scale_drift[:,0]-scale_drift[0,0] - ax_scale.plot(scale_drift[:,0], scale_drift[:,1], label=params['experiment_label']) - - ax_scale.set_xlim([0, rot_error[-1,0]+4]) - ax_scale.legend(bbox_to_anchor=[0, 1], loc='upper left', ncol=3) - ax_scale.grid() - fig_scale.tight_layout() - fig_scale.savefig(os.path.join(comparison_dir, 'scale_drift.pdf')) - - # ------------------------------------------------------------------------------ - # trajectory - -# fig_traj = plt.figure(figsize=(8,4.8)) -# ax_traj = fig_traj.add_subplot(111, xlabel='x [m]', ylabel='y [m]', aspect='equal', xlim=[-3.1, 4], ylim=[-1.5, 2.6]) -# -# plotTrajectory(ax_traj, '/home/cforster/Datasets/asl_vicon_d2/groundtruth_filtered.txt', 'Groundtruth', 'k', 1.5) -# plotTrajectory(ax_traj, results_dir+'/20130911_2229_nslam_i7_asl2_fast/traj_estimate_rotated.txt', 'Fast', 'g', 1) -# plotTrajectory(ax_traj, results_dir+'/20130906_2149_ptam_i7_asl2/traj_estimate_rotated.txt', 'PTAM', 'r', 1) -# -# mark_inset(ax_traj, axins, loc1=2, loc2=4, fc="none", ec='b') -# plt.draw() -# plt.show() -# ax_traj.legend(bbox_to_anchor=[1, 0], loc='lower right', ncol=3) -# ax_traj.grid() -# fig_traj.tight_layout() -# fig_traj.savefig('../results/trajectory_asl.pdf') - + # ------------------------------------------------------------------------- + # plot translation error: + fig = plt.figure(figsize=(6,2)) + ax = fig.add_subplot(111, xlabel='distance [m]', ylabel='translation drift [mm]') + for exp_set in comp_params['experiment_sets']: + print('processing experiment set: ' + exp_set['label']) + + for i, exp in enumerate(exp_set['experiments']): + gt = np.loadtxt(os.path.join(results_dir, exp, 'groundtruth_matched.txt')) + distances = np.diff(gt[:,1:4],axis=0) + distances = np.sqrt(np.sum(np.multiply(distances,distances),1)) + distances = np.cumsum(distances) + distances = np.concatenate(([0], distances)) + data = np.loadtxt(os.path.join(results_dir, exp, 'translation_error.txt')) + e = np.sqrt(np.sum(np.multiply(data[:,1:4],data[:,1:4]),1)) + + if np.shape(e)[0] > np.shape(distances)[0]: + print('WARNING: estimate has more measurement than groundtruth: ' + +str(np.shape(e)[0]-np.shape(distances)[0])) + e = e[0:np.shape(distances)[0]] + + distances = distances[0:np.shape(e)[0]+1] + + + if i == 0: + base_plot, = ax.plot(distances, e*1000, label=exp_set['label']) + else: + ax.plot(distances, e*1000, color=base_plot.get_color()) + + ax.legend(loc='upper left') + save_figure(fig, 'translation_error', comparison_dir) if __name__ == '__main__': - default_name = time.strftime("%Y%m%d_%H%M", time.localtime())+'_comparison' - parser = argparse.ArgumentParser(description='Compare results.') - parser.add_argument('result_directories', nargs='+', help='list of result directories to compare') - parser.add_argument('--name', help='name of the comparison', default=default_name) - args = parser.parse_args() - - # create folder for comparison results - results_dir = os.path.join(rospkg.RosPack().get_path('svo_analysis'), 'results') - comparison_dir = os.path.join(results_dir, args.name) - if not os.path.exists(comparison_dir): - os.makedirs(comparison_dir) + parser = argparse.ArgumentParser(description='Compare results of a VO pipeline.') + parser.add_argument('comparison_file', help='A YAML file that contains the details of the comparison') + args = parser.parse_args() + + # load comparison file + args.experiment_file = args.comparison_file.replace('.yaml','') + comparison_params_file = os.path.join(rospkg.RosPack().get_path('svo_analysis'), + 'comparisons', args.comparison_file+'.yaml') + if os.path.exists(comparison_params_file): + comp_params = yaml.load(open(comparison_params_file, 'r')) + else: + raise Exception("Provided comparison file does not exist.") + + # create folder for comparison results + comparison_dir = os.path.join(rospkg.RosPack().get_path('svo_analysis'), + 'comparisons', comp_params['comparison_name']) + if not os.path.exists(comparison_dir): + os.makedirs(comparison_dir) + + # folder where the results of previous experiments are saved + results_dir = os.path.join(rospkg.RosPack().get_path('svo_analysis'), 'results') - # run comparison - compare_results(args.result_directories, results_dir, comparison_dir) - - - + # run comparison + compare_results(comp_params, results_dir, comparison_dir) + From 196b29757aa17bc04cb0742bb74b412a8d730bc5 Mon Sep 17 00:00:00 2001 From: Quim Sanchez Date: Thu, 15 May 2014 16:03:19 +0200 Subject: [PATCH 113/215] Update frame.cpp Image seemed to be ok but still exception was being thrown. --- svo/src/frame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/src/frame.cpp b/svo/src/frame.cpp index 6234d0b..2d40b96 100644 --- a/svo/src/frame.cpp +++ b/svo/src/frame.cpp @@ -48,7 +48,7 @@ void Frame::initFrame(const cv::Mat& img) { // check image if(img.empty() || img.type() != CV_8UC1 || img.cols != cam_->width() || img.rows != cam_->height()) - throw std::runtime_error("Frame: provided image has not the same size as the camera model"); + throw std::runtime_error("Frame: provided image has not the same size as the camera model or image is not grayscale"); // Set keypoints to NULL std::for_each(key_pts_.begin(), key_pts_.end(), [&](Feature* ftr){ ftr=NULL; }); From 11b5b62c9ee3f42a2ebd0ed49b9424c80c9f8507 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 16 May 2014 14:38:13 +0200 Subject: [PATCH 114/215] worked on visualization --- svo/src/frame_handler_mono.cpp | 2 +- svo_analysis/scripts/comparison.py | 20 ++++++++------ svo_ros/include/svo_ros/visualizer.h | 2 ++ svo_ros/src/benchmark_node.cpp | 39 ++++++++++++++++++-------- svo_ros/src/visualizer.cpp | 41 ++++++++++++++++------------ 5 files changed, 65 insertions(+), 39 deletions(-) diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 3fd1a7a..b06db86 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -174,6 +174,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() SVO_STOP_TIMER("point_optimizer"); // select keyframe + core_kfs_.insert(new_frame_); setTrackingQuality(sfba_n_edges_final); if(tracking_quality_ == TRACKING_INSUFFICIENT) return RESULT_FAILURE; @@ -194,7 +195,6 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() map_.point_candidates_.addCandidatePointToFrame(new_frame_); // optional bundle adjustment - core_kfs_.insert(new_frame_); #ifdef USE_BUNDLE_ADJUSTMENT if(Config::lobaNumIter() > 0) { diff --git a/svo_analysis/scripts/comparison.py b/svo_analysis/scripts/comparison.py index 1651247..8f99f01 100755 --- a/svo_analysis/scripts/comparison.py +++ b/svo_analysis/scripts/comparison.py @@ -42,6 +42,7 @@ def distances_along_trajectory(traj): def compare_results(comp_params, results_dir, comparison_dir): print('run comparison: '+comp_params['comparison_name']) + line_styles = ['-','--',':'] # ------------------------------------------------------------------------- # plot trajectory: @@ -53,10 +54,10 @@ def compare_results(comp_params, results_dir, comparison_dir): for i, exp in enumerate(exp_set['experiments']): data = np.loadtxt(os.path.join(results_dir, exp, 'traj_estimate.txt')) if i == 0: - base_plot, = ax.plot(data[:,1], data[:,2], label=exp_set['label']) + base_plot, = ax.plot(data[:,1], data[:,2], label=exp_set['label'], linestyle=line_styles[np.mod(i, len(line_styles))]) else: - ax.plot(data[:,1], data[:,2], color=base_plot.get_color()) - ax.legend(loc='upper left') + ax.plot(data[:,1], data[:,2], color=base_plot.get_color(), linestyle= line_styles[np.mod(i, len(line_styles))]) + ax.legend(loc='upper left', ncol=2) save_figure(fig, 'trajectory', comparison_dir) @@ -81,15 +82,18 @@ def compare_results(comp_params, results_dir, comparison_dir): +str(np.shape(e)[0]-np.shape(distances)[0])) e = e[0:np.shape(distances)[0]] - distances = distances[0:np.shape(e)[0]+1] - + distances = distances[0:np.shape(e)[0]] + + print '--' + print np.shape(e) + print np.shape(distances) if i == 0: - base_plot, = ax.plot(distances, e*1000, label=exp_set['label']) + base_plot, = ax.plot(distances, e*1000, label=exp_set['label'], linestyle= line_styles[np.mod(i, len(line_styles))]) else: - ax.plot(distances, e*1000, color=base_plot.get_color()) + ax.plot(distances, e*1000, color=base_plot.get_color(), linestyle= line_styles[np.mod(i, len(line_styles))]) - ax.legend(loc='upper left') + ax.legend(loc='upper left', ncol=2) save_figure(fig, 'translation_error', comparison_dir) if __name__ == '__main__': diff --git a/svo_ros/include/svo_ros/visualizer.h b/svo_ros/include/svo_ros/visualizer.h index aa6146a..dc8936d 100644 --- a/svo_ros/include/svo_ros/visualizer.h +++ b/svo_ros/include/svo_ros/visualizer.h @@ -59,6 +59,8 @@ public: image_transport::Publisher pub_images_; tf::TransformBroadcaster br_; bool publish_world_in_cam_frame_; + bool publish_map_every_frame_; + ros::Duration publish_points_display_time_; SE3 T_world_from_vision_; Visualizer(); diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index 0c643eb..d14f703 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -46,6 +46,7 @@ class BenchmarkNode std::ofstream trace_est_pose_; std::ofstream trace_trans_error_; std::ofstream trace_rot_error_; + std::ofstream trace_depth_error_; vk::AbstractCamera* cam_; public: @@ -53,6 +54,7 @@ public: ~BenchmarkNode(); void tracePose(const SE3& T_w_f, const double timestamp); void tracePoseError(const SE3& T_f_gt, const double timestamp); + void traceDepthError(const FramePtr& frame, const cv::Mat& depthmap); void runBenchmark(const std::string& dataset_dir); void runBlenderBenchmark(const std::string& dataset_dir); }; @@ -91,7 +93,7 @@ void BenchmarkNode::tracePose(const SE3& T_w_f, const double timestamp) trace_est_pose_ << timestamp << " "; trace_est_pose_.precision(6); trace_est_pose_ << p.x() << " " << p.y() << " " << p.z() << " " - << q.x() << " " << q.y() << " " << q.z() << " " << q.w() << endl; + << q.x() << " " << q.y() << " " << q.z() << " " << q.w() << std::endl; } void BenchmarkNode::tracePoseError(const SE3& T_f_gt, const double timestamp) @@ -101,13 +103,27 @@ void BenchmarkNode::tracePoseError(const SE3& T_f_gt, const double timestamp) trace_trans_error_.setf(std::ios::fixed, std::ios::floatfield ); trace_trans_error_ << timestamp << " "; trace_trans_error_.precision(6); - trace_trans_error_ << et.x() << " " << et.y() << " " << et.z() << " " << endl; + trace_trans_error_ << et.x() << " " << et.y() << " " << et.z() << " " << std::endl; Vector3d er(vk::dcm2rpy(T_f_gt.rotation_matrix())); // rotation error in roll-pitch-yaw trace_rot_error_.precision(15); trace_rot_error_.setf(std::ios::fixed, std::ios::floatfield ); trace_rot_error_ << timestamp << " "; trace_rot_error_.precision(6); - trace_rot_error_ << er.x() << " " << er.y() << " " << er.z() << " " << endl; + trace_rot_error_ << er.x() << " " << er.y() << " " << er.z() << " " << std::endl; +} + +void BenchmarkNode::traceDepthError(const FramePtr& frame, const cv::Mat& depthmap) +{ + trace_depth_error_.precision(6); + std::for_each(frame->fts_.begin(), frame->fts_.end(), [&](Feature* ftr){ + if(ftr->point != NULL) + { + double depth_estimated = (ftr->point->pos_-frame->pos()).norm(); + double depth_measured = depthmap.at((int) ftr->px[1], (int) ftr->px[0]); + trace_depth_error_ << frame->id_ << " " + << depth_estimated-depth_estimated << std::endl; + } + }); } void BenchmarkNode::runBenchmark(const std::string& dataset_dir) @@ -156,23 +172,26 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) std::vector dataset; dataset_reader.readAllEntries(dataset); + // create tracefiles trace_trans_error_.open(Config::traceDir() + "/translation_error.txt"); trace_rot_error_.open(Config::traceDir() + "/orientation_error.txt"); - if(trace_trans_error_.fail() || trace_rot_error_.fail()) + trace_depth_error_.open(Config::traceDir() + "/depth_error.txt"); + if(trace_trans_error_.fail() || trace_rot_error_.fail() || trace_depth_error_.fail()) throw std::runtime_error("Could not create tracefile. Does folder exist?"); // process dataset for(auto it = dataset.begin(); it != dataset.end() && ros::ok(); ++it, ++frame_count_) { - // Read image + // Read image, ground-truth depth-map and ground-truth pose std::string img_filename(dataset_dir + "/img/" + it->image_name_ + "_0.png"); cv::Mat img(cv::imread(img_filename, 0)); if(img.empty()) { SVO_ERROR_STREAM("Reading image "<image_name_+"_0.depth", *cam_, depthmap); Sophus::SE3 T_w_gt(it->q_, it->t_); // Set reference frame with depth @@ -182,11 +201,6 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) FramePtr frame_ref(new Frame(cam_, img, it->timestamp_)); frame_ref->T_f_w_ = T_w_gt.inverse(); - // load ground-truth depth - cv::Mat depthmap; - vk::blender_utils::loadBlenderDepthmap( - dataset_dir+"/depth/"+it->image_name_+"_0.depth", *cam_, depthmap); - // extract features, generate features with 3D points svo::feature_detection::FastDetector detector( cam_->width(), cam_->height(), svo::Config::gridSize(), svo::Config::nPyrLevels()); @@ -219,6 +233,7 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) Sophus::SE3 T_f_gt(vo_->lastFrame()->T_f_w_*T_w_gt); tracePoseError(T_f_gt, it->timestamp_); tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); + traceDepthError(vo_->lastFrame(), depthmap); } } diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index e207bbe..117165a 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -44,8 +44,10 @@ Visualizer() : img_pub_level_(vk::getParam("svo/image_publishing_level", 0)), img_pub_nth_(vk::getParam("svo/publish_every_nth_img", 1)), dense_pub_nth_(vk::getParam("svo/publish_every_nth_dense_input", 1)), - T_world_from_vision_(Matrix3d::Identity(), Vector3d::Zero()), - publish_world_in_cam_frame_(vk::getParam("svo/publish_world_in_cam_frame", true)) + publish_world_in_cam_frame_(vk::getParam("svo/publish_world_in_cam_frame", true)), + publish_map_every_frame_(vk::getParam("svo/publish_map_every_frame", false)), + publish_points_display_time_(vk::getParam("svo/publish_point_display_time", 0)), + T_world_from_vision_(Matrix3d::Identity(), Vector3d::Zero()) { // Init ROS Marker Publishers pub_frames_ = pnh_.advertise("keyframes", 10); @@ -89,7 +91,7 @@ void Visualizer::publishMinimal( pub_info_.publish(msg_info); } - if(frame == 0) + if(frame == NULL) { if(pub_images_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_PAUSED) { @@ -200,22 +202,24 @@ void Visualizer::visualizeMarkers( const set& core_kfs, const Map& map) { - if(frame != NULL) + if(frame == NULL) + return; + + vk::output_helper::publishTfTransform( + frame->T_f_w_*T_world_from_vision_.inverse(), + ros::Time(frame->timestamp_), "cam_pos", "world", br_); + + if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) { - vk::output_helper::publishTfTransform( - frame->T_f_w_*T_world_from_vision_.inverse(), - ros::Time(frame->timestamp_), "cam_pos", "world", br_); - if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) - { - vk::output_helper::publishHexacopterMarker( - pub_frames_, "cam_pos", "cams", ros::Time(frame->timestamp_), - 1, 0, 0.3, Vector3d(0.,0.,1.)); - vk::output_helper::publishPointMarker( - pub_points_, T_world_from_vision_*frame->pos(), "trajectory", - ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5)); + vk::output_helper::publishHexacopterMarker( + pub_frames_, "cam_pos", "cams", ros::Time(frame->timestamp_), + 1, 0, 0.3, Vector3d(0.,0.,1.)); + vk::output_helper::publishPointMarker( + pub_points_, T_world_from_vision_*frame->pos(), "trajectory", + ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5)); + if(frame->isKeyframe() || publish_map_every_frame_) publishMapRegion(core_kfs); - removeDeletedPts(map); - } + removeDeletedPts(map); } } @@ -257,7 +261,8 @@ void Visualizer::displayKeyframeWithMps(const FramePtr& frame, int ts) vk::output_helper::publishPointMarker( pub_points_, T_world_from_vision_*(*it)->point->pos_, "pts", - ros::Time::now(), (*it)->point->id_, 0, 0.005, Vector3d(1.0, 0., 1.0)); + ros::Time::now(), (*it)->point->id_, 0, 0.005, Vector3d(1.0, 0., 1.0), + publish_points_display_time_); (*it)->point->last_published_ts_ = ts; } } From bb4c671568acc1e23f735aee49d8da51018213fc Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 16 May 2014 14:48:02 +0200 Subject: [PATCH 115/215] fix in depth error tracing --- svo_ros/src/benchmark_node.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index d14f703..fac59e0 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -119,9 +119,9 @@ void BenchmarkNode::traceDepthError(const FramePtr& frame, const cv::Mat& depthm if(ftr->point != NULL) { double depth_estimated = (ftr->point->pos_-frame->pos()).norm(); - double depth_measured = depthmap.at((int) ftr->px[1], (int) ftr->px[0]); + double depth_true = depthmap.at((int) ftr->px[1], (int) ftr->px[0]); trace_depth_error_ << frame->id_ << " " - << depth_estimated-depth_estimated << std::endl; + << depth_estimated-depth_true << std::endl; } }); } From e0207e7365c4dc2557fb0829e3b755329d06d622 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 16 May 2014 14:51:14 +0200 Subject: [PATCH 116/215] rename ros-parameter for image pyramid publishing level --- svo_ros/src/visualizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index 117165a..a06827e 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -41,7 +41,7 @@ Visualizer:: Visualizer() : pnh_("~"), trace_id_(0), - img_pub_level_(vk::getParam("svo/image_publishing_level", 0)), + img_pub_level_(vk::getParam("svo/publish_img_pyr_level", 0)), img_pub_nth_(vk::getParam("svo/publish_every_nth_img", 1)), dense_pub_nth_(vk::getParam("svo/publish_every_nth_dense_input", 1)), publish_world_in_cam_frame_(vk::getParam("svo/publish_world_in_cam_frame", true)), From 450cbc096e2f0b94663c0ff527867641004124b4 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 16 May 2014 14:53:21 +0200 Subject: [PATCH 117/215] changed parameter name in launchfile --- svo_ros/launch/live.launch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo_ros/launch/live.launch b/svo_ros/launch/live.launch index 738d97a..92f4b9b 100644 --- a/svo_ros/launch/live.launch +++ b/svo_ros/launch/live.launch @@ -8,7 +8,7 @@ - + From 0f322b208a5c5cbbbcfff911ede92442d479ecb3 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 16 May 2014 19:25:51 +0200 Subject: [PATCH 118/215] evaluation scripts --- svo_analysis/scripts/comparison.py | 26 +++++++- svo_analysis/scripts/evaluate.py | 60 +++++++++++-------- svo_analysis/src/svo_analysis/analyse_logs.py | 14 +++-- .../src/svo_analysis/analyse_trajectory.py | 2 +- 4 files changed, 68 insertions(+), 34 deletions(-) diff --git a/svo_analysis/scripts/comparison.py b/svo_analysis/scripts/comparison.py index 8f99f01..f2ac8a7 100755 --- a/svo_analysis/scripts/comparison.py +++ b/svo_analysis/scripts/comparison.py @@ -8,6 +8,7 @@ import numpy as np import matplotlib.pyplot as plt import yaml import argparse +import svo_analysis.analyse_depth as analyse_depth from matplotlib import rc # tell matplotlib to use latex font @@ -43,6 +44,7 @@ def compare_results(comp_params, results_dir, comparison_dir): print('run comparison: '+comp_params['comparison_name']) line_styles = ['-','--',':'] + line_colors = ['b','g','r','m','c'] # ------------------------------------------------------------------------- # plot trajectory: @@ -57,10 +59,9 @@ def compare_results(comp_params, results_dir, comparison_dir): base_plot, = ax.plot(data[:,1], data[:,2], label=exp_set['label'], linestyle=line_styles[np.mod(i, len(line_styles))]) else: ax.plot(data[:,1], data[:,2], color=base_plot.get_color(), linestyle= line_styles[np.mod(i, len(line_styles))]) - ax.legend(loc='upper left', ncol=2) + ax.legend(loc='upper left', ncol=3) save_figure(fig, 'trajectory', comparison_dir) - # ------------------------------------------------------------------------- # plot translation error: fig = plt.figure(figsize=(6,2)) @@ -93,8 +94,27 @@ def compare_results(comp_params, results_dir, comparison_dir): else: ax.plot(distances, e*1000, color=base_plot.get_color(), linestyle= line_styles[np.mod(i, len(line_styles))]) - ax.legend(loc='upper left', ncol=2) + ax.legend(loc='upper left', ncol=3) save_figure(fig, 'translation_error', comparison_dir) + + # ------------------------------------------------------------------------- + # plot depth estimation error: + fig = plt.figure(figsize=(6,5)) + ax = fig.add_subplot(111, xlabel='Error [m]', ylabel='Precision [\%]') + for k, exp_set in enumerate(comp_params['experiment_sets']): + print('plot depth error for experiment: ' + exp_set['label']) + + for i, exp in enumerate(exp_set['experiments']): + + D = np.loadtxt(os.path.join(results_dir, exp, 'depth_error.txt'), delimiter=' ') + D = D[np.logical_and(D[:,0] > 1, D[:,0] < D[-1,0]/4),:] + errors = np.abs(D[:,1]) + if i == 0: + base_plot = analyse_depth.precision_plot(ax, errors, 0.05, line_colors[k], line_styles[np.mod(i, len(line_styles))]) + else: + base_plot = analyse_depth.precision_plot(ax, errors, 0.05, base_plot.get_color(), line_styles[np.mod(i, len(line_styles))]) + + save_figure(fig, 'depth_error', comparison_dir) if __name__ == '__main__': diff --git a/svo_analysis/scripts/evaluate.py b/svo_analysis/scripts/evaluate.py index eb9fe60..726544c 100755 --- a/svo_analysis/scripts/evaluate.py +++ b/svo_analysis/scripts/evaluate.py @@ -10,41 +10,49 @@ import csv import numpy as np import rospkg import argparse +import yaml import svo_analysis.analyse_logs as analyse_logs import svo_analysis.analyse_timing as analyse_timing import svo_analysis.analyse_trajectory as analyse_trajectory +import svo_analysis.analyse_depth as analyse_depth def evaluate_dataset(trace_dir): - # read tracefile - data = csv.reader(open(os.path.join(trace_dir, 'trace.csv'))) - fields = data.next() - D = dict() - for field in fields: - D[field] = list() + # read tracefile + data = csv.reader(open(os.path.join(trace_dir, 'trace.csv'))) + fields = data.next() + D = dict() + for field in fields: + D[field] = list() - # fill dictionary with column values - for row in data: - for (field, value) in zip(fields, row): - D[field].append(float(value)) + # fill dictionary with column values + for row in data: + for (field, value) in zip(fields, row): + D[field].append(float(value)) - # change dictionary values from list to numpy array for easier manipulation - for field, value in D.items(): - D[field] = np.array(D[field]) + # change dictionary values from list to numpy array for easier manipulation + for field, value in D.items(): + D[field] = np.array(D[field]) + + # generate plots + analyse_logs.analyse_logs(D, trace_dir) + analyse_timing.analyse_timing(D, trace_dir) + analyse_trajectory.analyse_trajectory(trace_dir) + + param = yaml.load(open(os.path.join(trace_dir, 'dataset_params.yaml'), 'r')) + if param['dataset_is_blender']: + analyse_depth.analyse_depth(trace_dir) + analyse_depth.analyse_depth_over_time(trace_dir) - # generate plots - analyse_logs.analyse_logs(D, trace_dir) - analyse_timing.analyse_timing(D, trace_dir) - analyse_trajectory.analyse_trajectory(trace_dir) if __name__=="__main__": - parser = argparse.ArgumentParser(description=''' - Evaluates tracefiles of SVO and generates the plots. - ''') - parser.add_argument('experiment_name', help='directory name of the tracefiles') - args = parser.parse_args() + parser = argparse.ArgumentParser(description=''' + Evaluates tracefiles of SVO and generates the plots. + ''') + parser.add_argument('experiment_name', help='directory name of the tracefiles') + args = parser.parse_args() - trace_dir = os.path.join(rospkg.RosPack().get_path('svo_analysis'), - 'results', - args.experiment_name) - evaluate_dataset(trace_dir) \ No newline at end of file + trace_dir = os.path.join(rospkg.RosPack().get_path('svo_analysis'), + 'results', + args.experiment_name) + evaluate_dataset(trace_dir) \ No newline at end of file diff --git a/svo_analysis/src/svo_analysis/analyse_logs.py b/svo_analysis/src/svo_analysis/analyse_logs.py index 4e40bfe..7dc2acc 100755 --- a/svo_analysis/src/svo_analysis/analyse_logs.py +++ b/svo_analysis/src/svo_analysis/analyse_logs.py @@ -1,6 +1,7 @@ #!/usr/bin/python import os +import yaml import numpy as np import matplotlib.pyplot as plt @@ -10,10 +11,7 @@ def analyse_logs(D, trace_dir): is_kf = np.argwhere( (D['dropout'] == 1) & (D['repr_n_mps'] >= 0)) is_frame = np.argwhere(D['repr_n_mps'] >= 0) is_nokf = np.argwhere( (D['dropout'] == 0) & (D['repr_n_mps'] >= 0)) - n_frames = len(is_frame) - n_kfs = len(is_kf) - n_nokf = len(is_nokf) - + # set initial time to zero D['timestamp'] = D['timestamp'] - D['timestamp'][0] @@ -65,4 +63,12 @@ def analyse_logs(D, trace_dir): ax.plot(D['timestamp'][is_frame], D['sfba_thresh'][is_frame], 'r-', label='Threshold') fig.tight_layout() fig.savefig(os.path.join(trace_dir,'optimization_thresh.pdf'), bbox_inches="tight") + + # ---------------------------------------------------------------------------- + # write other statistics to file + stat = {'num_frames': len(is_frame), + 'num_kfs': len(is_kf), + 'reproj_error_avg_improvement': float(init_error_avg - opt1_avg)} + with open(os.path.join(trace_dir,'dataset_stats.yaml'),'w') as outfile: + outfile.write(yaml.dump(stat, default_flow_style=False)) diff --git a/svo_analysis/src/svo_analysis/analyse_trajectory.py b/svo_analysis/src/svo_analysis/analyse_trajectory.py index 4b11363..15823d0 100755 --- a/svo_analysis/src/svo_analysis/analyse_trajectory.py +++ b/svo_analysis/src/svo_analysis/analyse_trajectory.py @@ -100,7 +100,7 @@ def analyse_trajectory(results_dir, n_align_frames = 200, use_hand_eye_calib = T ax = fig.add_subplot(111, title='trajectory', aspect='equal', xlabel='x [m]', ylabel='y [m]') ax.plot(p_es_aligned[:,0], p_es_aligned[:,1], 'b-', label='estimate') ax.plot(p_gt[:,0], p_gt[:,1], 'r-', label='groundtruth') - #ax.plot(p_es_aligned[0:n_align_frames,0], p_es_aligned[0:n_align_frames,1], 'g-', linewidth=2, label='aligned') + ax.plot(p_es_aligned[0:n_align_frames,0], p_es_aligned[0:n_align_frames,1], 'g-', linewidth=2, label='aligned') ax.legend() fig.tight_layout() fig.savefig(results_dir+'/trajectory.pdf') From 0abe8164521451c86ed3718e947f83fd90089dae Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 19 May 2014 10:58:16 +0200 Subject: [PATCH 119/215] plot depth error percentiles --- .../src/svo_analysis/analyse_depth.py | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 svo_analysis/src/svo_analysis/analyse_depth.py diff --git a/svo_analysis/src/svo_analysis/analyse_depth.py b/svo_analysis/src/svo_analysis/analyse_depth.py new file mode 100755 index 0000000..41a9c21 --- /dev/null +++ b/svo_analysis/src/svo_analysis/analyse_depth.py @@ -0,0 +1,68 @@ +#!/usr/bin/python + +import os +import yaml +import argparse +import numpy as np +import matplotlib.pyplot as plt +import svo_analysis.tum_benchmark_tools.associate as associate +import vikit_py.transformations as transformations +import vikit_py.align_trajectory as align_trajectory +from matplotlib import rc + +rc('font',**{'family':'serif','serif':['Cardo']}) +rc('text', usetex=True) + +def precision_plot(ax, errors, max_error, color, linestyle): + number_of_error_ranges = 500 + error_step = max_error / number_of_error_ranges + precision_array = np.zeros(number_of_error_ranges) + error_array = np.zeros(number_of_error_ranges) + n_measurements = len(errors) + for error_ind in range(0, number_of_error_ranges): + precision_array[error_ind] = np.sum(errors < error_step*error_ind) / float(n_measurements) * 100.0 + error_array[error_ind] = error_step*error_ind + plot_obj, = ax.plot(error_array, precision_array, label='error', linestyle=linestyle, color=color) + return plot_obj + +def analyse_depth(results_dir): + D = np.loadtxt(os.path.join(results_dir, 'depth_error.txt'), delimiter=' ') + D = D[D[:,0] > 1,:] + + fig = plt.figure(figsize=(6,5)) + ax = fig.add_subplot(111, xlabel='depth error [m]', ylabel='Precision [\%]') + errors = np.abs(D[:,1]) + precision_plot(ax, errors, 0.05, 'r', '-') + fig.tight_layout() + fig.savefig(os.path.join(results_dir,'depth_error.pdf'), bbox_inches="tight") + +def analyse_depth_over_time(results_dir): + D = np.loadtxt(os.path.join(results_dir, 'depth_error.txt'), delimiter=' ') + D = D[D[:,0] > 1,:] + + fig = plt.figure(figsize=(6,5)) + ax = fig.add_subplot(111, xlabel='Measurement', ylabel='Scale-Drift') + + idxs = np.unique(D[:,0]) + percentile_20 = np.zeros(len(idxs)) + percentile_50 = np.zeros(len(idxs)) + percentile_80 = np.zeros(len(idxs)) + for i in range(len(idxs)): + errors = np.abs(D[D[:,0]==idxs[i],1]) + percentile_20[i] = np.percentile(errors, 20) + percentile_50[i] = np.percentile(errors, 50) + percentile_80[i] = np.percentile(errors, 80) + + base_plot, = ax.plot(idxs, percentile_50, linewidth=2) + ax.fill_between(idxs, percentile_20, percentile_80, alpha=0.25, color=base_plot.get_color()) + fig.tight_layout() + fig.savefig(os.path.join(results_dir,'scale_drift.pdf'), bbox_inches="tight") + + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Analyse depth estimate') + parser.add_argument('results_dir', help='folder with the results') + args = parser.parse_args() + analyse_depth(args.results_dir) + analyse_depth_over_time(args.results_dir) \ No newline at end of file From 81f5c329fc922aaa6cf85a8788cc96eb20e082a5 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 19 May 2014 10:59:25 +0200 Subject: [PATCH 120/215] remove unused includes --- svo_analysis/src/svo_analysis/analyse_depth.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/svo_analysis/src/svo_analysis/analyse_depth.py b/svo_analysis/src/svo_analysis/analyse_depth.py index 41a9c21..4ce2b5c 100755 --- a/svo_analysis/src/svo_analysis/analyse_depth.py +++ b/svo_analysis/src/svo_analysis/analyse_depth.py @@ -1,13 +1,9 @@ #!/usr/bin/python import os -import yaml import argparse import numpy as np import matplotlib.pyplot as plt -import svo_analysis.tum_benchmark_tools.associate as associate -import vikit_py.transformations as transformations -import vikit_py.align_trajectory as align_trajectory from matplotlib import rc rc('font',**{'family':'serif','serif':['Cardo']}) From 0f259084cdc246892b8d068e434a9958e97eee00 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 19 May 2014 12:00:54 +0200 Subject: [PATCH 121/215] add noise to image in benchmarking synthetic datasets --- svo_ros/src/benchmark_node.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp index fac59e0..a1c96e1 100644 --- a/svo_ros/src/benchmark_node.cpp +++ b/svo_ros/src/benchmark_node.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ class BenchmarkNode std::ofstream trace_rot_error_; std::ofstream trace_depth_error_; vk::AbstractCamera* cam_; + double img_noise_sigma_; public: BenchmarkNode(ros::NodeHandle& nh); @@ -55,13 +57,15 @@ public: void tracePose(const SE3& T_w_f, const double timestamp); void tracePoseError(const SE3& T_f_gt, const double timestamp); void traceDepthError(const FramePtr& frame, const cv::Mat& depthmap); + void addNoiseToImage(cv::Mat& img, double sigma); void runBenchmark(const std::string& dataset_dir); void runBlenderBenchmark(const std::string& dataset_dir); }; BenchmarkNode::BenchmarkNode(ros::NodeHandle& nh) : vo_(NULL), - frame_count_(0) + frame_count_(0), + img_noise_sigma_(vk::getParam("svo/dataset_noise_sigma", 0.0)) { // Create Camera if(!vk::camera_loader::loadFromRosNs("svo", cam_)) @@ -159,6 +163,18 @@ void BenchmarkNode::runBenchmark(const std::string& dataset_dir) } } +void BenchmarkNode::addNoiseToImage(cv::Mat& img, double sigma) +{ + uint8_t* p = (uint8_t*) img.data; + uint8_t* p_end = img.ptr(img.rows, img.cols); + while(p != p_end) + { + int val = *p + vk::Sample::gaussian(sigma) + 0.5; + *p = std::max(std::min(val, 255), 0); + ++p; + } +} + void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) { // create image reader and load dataset @@ -189,6 +205,8 @@ void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) SVO_ERROR_STREAM("Reading image "< 0) + addNoiseToImage(img, img_noise_sigma_); cv::Mat depthmap; vk::blender_utils::loadBlenderDepthmap( dataset_dir+"/depth/"+it->image_name_+"_0.depth", *cam_, depthmap); From d6927c0bbeac76250020a5039885f7a208d69806 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 19 May 2014 12:02:16 +0200 Subject: [PATCH 122/215] new comparison file --- svo_analysis/comparisons/textures.yaml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 svo_analysis/comparisons/textures.yaml diff --git a/svo_analysis/comparisons/textures.yaml b/svo_analysis/comparisons/textures.yaml new file mode 100644 index 0000000..7279f6e --- /dev/null +++ b/svo_analysis/comparisons/textures.yaml @@ -0,0 +1,22 @@ +comparison_name: textures +experiment_sets: +- label: 'T1' + experiments: + - 20140516_1449_svo_ros_synthetic_all_str_tex1_h1_v6_d + - 20140516_1449_svo_ros_synthetic_all_str_tex1_h1_v9_d + - 20140516_1449_svo_ros_synthetic_all_str_tex1_h1_v12_d +- label: 'T2' + experiments: + - 20140516_1449_svo_ros_synthetic_all_str_tex2_h1_v6_d + - 20140516_1449_svo_ros_synthetic_all_str_tex2_h1_v9_d + - 20140516_1449_svo_ros_synthetic_all_str_tex2_h1_v12_d +- label: 'T3' + experiments: + - 20140516_1449_svo_ros_synthetic_all_str_tex3_h1_v6_d + - 20140516_1449_svo_ros_synthetic_all_str_tex3_h1_v9_d + - 20140516_1449_svo_ros_synthetic_all_str_tex3_h1_v12_d +# - label: 'T4' +# experiments: +# - 20140516_1449_svo_ros_synthetic_all_str_tex4_h1_v6_d +# - 20140516_1449_svo_ros_synthetic_all_str_tex4_h1_v9_d +# - 20140516_1449_svo_ros_synthetic_all_str_tex4_h1_v12_d \ No newline at end of file From e8d6757e9e83e222d75e780e5bd804f66e831126 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 22 May 2014 19:48:02 +0200 Subject: [PATCH 123/215] comparison of depth estimates in synthetic scenes --- svo_analysis/scripts/comparison.py | 49 +++-- .../src/svo_analysis/analyse_depth.py | 38 ++-- .../src/svo_analysis/analyse_trajectory.py | 206 +++++++++--------- .../src/svo_analysis/hand_eye_calib.py | 91 ++++---- .../tum_benchmark_tools/associate.py | 4 +- 5 files changed, 210 insertions(+), 178 deletions(-) diff --git a/svo_analysis/scripts/comparison.py b/svo_analysis/scripts/comparison.py index f2ac8a7..a502ad1 100755 --- a/svo_analysis/scripts/comparison.py +++ b/svo_analysis/scripts/comparison.py @@ -40,6 +40,13 @@ def distances_along_trajectory(traj): distances.append(sum) return distances +def get_distance_from_start(gt): + distances = np.diff(gt[:,1:4],axis=0) + distances = np.sqrt(np.sum(np.multiply(distances,distances),1)) + distances = np.cumsum(distances) + distances = np.concatenate(([0], distances)) + return distances + def compare_results(comp_params, results_dir, comparison_dir): print('run comparison: '+comp_params['comparison_name']) @@ -71,10 +78,7 @@ def compare_results(comp_params, results_dir, comparison_dir): for i, exp in enumerate(exp_set['experiments']): gt = np.loadtxt(os.path.join(results_dir, exp, 'groundtruth_matched.txt')) - distances = np.diff(gt[:,1:4],axis=0) - distances = np.sqrt(np.sum(np.multiply(distances,distances),1)) - distances = np.cumsum(distances) - distances = np.concatenate(([0], distances)) + distances = get_distance_from_start(gt) data = np.loadtxt(os.path.join(results_dir, exp, 'translation_error.txt')) e = np.sqrt(np.sum(np.multiply(data[:,1:4],data[:,1:4]),1)) @@ -100,21 +104,30 @@ def compare_results(comp_params, results_dir, comparison_dir): # ------------------------------------------------------------------------- # plot depth estimation error: fig = plt.figure(figsize=(6,5)) - ax = fig.add_subplot(111, xlabel='Error [m]', ylabel='Precision [\%]') + ax = fig.add_subplot(111, xlabel='Travelled distance [m]', ylabel='Error [m]') for k, exp_set in enumerate(comp_params['experiment_sets']): - print('plot depth error for experiment: ' + exp_set['label']) - - for i, exp in enumerate(exp_set['experiments']): - - D = np.loadtxt(os.path.join(results_dir, exp, 'depth_error.txt'), delimiter=' ') - D = D[np.logical_and(D[:,0] > 1, D[:,0] < D[-1,0]/4),:] - errors = np.abs(D[:,1]) - if i == 0: - base_plot = analyse_depth.precision_plot(ax, errors, 0.05, line_colors[k], line_styles[np.mod(i, len(line_styles))]) - else: - base_plot = analyse_depth.precision_plot(ax, errors, 0.05, base_plot.get_color(), line_styles[np.mod(i, len(line_styles))]) - - save_figure(fig, 'depth_error', comparison_dir) + print('plot depth error for experiment: ' + exp) + exp = exp_set['experiments'][0] + gt = np.loadtxt(os.path.join(results_dir, exp, 'groundtruth_matched.txt')) + x_axis_data = get_distance_from_start(gt) + analyse_depth.plot_depth_over_time(os.path.join(results_dir, exp), ax, + x_axis_data[1:], line_colors[k], exp_set['label']) + ax.legend(loc='upper left', ncol=3) + save_figure(fig, 'depth_error_textures', comparison_dir) + + fig = plt.figure(figsize=(6,5)) + ax = fig.add_subplot(111, xlabel='Travelled distance [m]', ylabel='Error [m]') + exp_set = comp_params['experiment_sets'][0] + for i, exp in enumerate(exp_set['experiments']): + print('plot depth error for speed: ' + exp) + gt = np.loadtxt(os.path.join(results_dir, exp, 'groundtruth_matched.txt')) + x_axis_data = get_distance_from_start(gt) + params = yaml.load(open(os.path.join(results_dir, exp, 'dataset_params.yaml'))) + analyse_depth.plot_depth_over_time(os.path.join(results_dir, exp), ax, + x_axis_data[1:], line_colors[i], + str(params['trajectory_modifiers']['speed'])+' m/s') + ax.legend(loc='upper left', ncol=3) + save_figure(fig, 'depth_error_speed', comparison_dir) if __name__ == '__main__': diff --git a/svo_analysis/src/svo_analysis/analyse_depth.py b/svo_analysis/src/svo_analysis/analyse_depth.py index 4ce2b5c..8a21b53 100755 --- a/svo_analysis/src/svo_analysis/analyse_depth.py +++ b/svo_analysis/src/svo_analysis/analyse_depth.py @@ -32,33 +32,35 @@ def analyse_depth(results_dir): fig.tight_layout() fig.savefig(os.path.join(results_dir,'depth_error.pdf'), bbox_inches="tight") -def analyse_depth_over_time(results_dir): + +def plot_depth_over_time(results_dir, ax, x_axis_data, color, label=''): D = np.loadtxt(os.path.join(results_dir, 'depth_error.txt'), delimiter=' ') D = D[D[:,0] > 1,:] - - fig = plt.figure(figsize=(6,5)) - ax = fig.add_subplot(111, xlabel='Measurement', ylabel='Scale-Drift') - idxs = np.unique(D[:,0]) - percentile_20 = np.zeros(len(idxs)) + percentile_10 = np.zeros(len(idxs)) percentile_50 = np.zeros(len(idxs)) - percentile_80 = np.zeros(len(idxs)) + percentile_90 = np.zeros(len(idxs)) for i in range(len(idxs)): errors = np.abs(D[D[:,0]==idxs[i],1]) - percentile_20[i] = np.percentile(errors, 20) + percentile_10[i] = np.percentile(errors, 10) percentile_50[i] = np.percentile(errors, 50) - percentile_80[i] = np.percentile(errors, 80) - - base_plot, = ax.plot(idxs, percentile_50, linewidth=2) - ax.fill_between(idxs, percentile_20, percentile_80, alpha=0.25, color=base_plot.get_color()) - fig.tight_layout() - fig.savefig(os.path.join(results_dir,'scale_drift.pdf'), bbox_inches="tight") - - - + percentile_90[i] = np.percentile(errors, 90) + if len(x_axis_data) == 0: + x_axis_data = idxs + print np.shape(x_axis_data) + print np.shape(idxs) + print '--' + ax.plot(x_axis_data, percentile_50, linewidth=2, color=color, label=label) + ax.plot(x_axis_data, percentile_10, linewidth=0.5, color=color, alpha=0.5) + ax.plot(x_axis_data, percentile_90, linewidth=0.5, color=color, alpha=0.5) + ax.fill_between(x_axis_data, percentile_10, percentile_90, color=color, alpha=0.1) + if __name__ == '__main__': parser = argparse.ArgumentParser(description='Analyse depth estimate') parser.add_argument('results_dir', help='folder with the results') args = parser.parse_args() analyse_depth(args.results_dir) - analyse_depth_over_time(args.results_dir) \ No newline at end of file + + fig = plt.figure(figsize=(6,5)) + ax = fig.add_subplot(111, xlabel='Measurement', ylabel='Scale-Drift') + plot_depth_over_time(args.results_dir, [], ax) \ No newline at end of file diff --git a/svo_analysis/src/svo_analysis/analyse_trajectory.py b/svo_analysis/src/svo_analysis/analyse_trajectory.py index 15823d0..c2c93de 100755 --- a/svo_analysis/src/svo_analysis/analyse_trajectory.py +++ b/svo_analysis/src/svo_analysis/analyse_trajectory.py @@ -32,117 +32,119 @@ def plot_rotation_error(timestamps, rotation_error, results_dir): fig.tight_layout() fig.savefig(results_dir+'/orientation_error.pdf') -def analyse_trajectory(results_dir, n_align_frames = 200, use_hand_eye_calib = True): - - if not os.path.isfile(os.path.join(results_dir, 'translation_error.txt')): - - T_cm, T_mc = load_hand_eye_calib(results_dir) - print('loading datasets.') - t_es, p_es, q_es, t_gt, p_gt, q_gt = load_dataset(results_dir) - - # align Sim3 to get scale - print('align Sim3 using '+str(n_align_frames)+' first frames.') - scale,rot,trans = align_trajectory.align_sim3(p_gt[0:n_align_frames,:], p_es[0:n_align_frames,:]) - print 'scale = '+str(scale) - - # get trafo between (v)ision and (o)ptitrack frame - p_es_aligned = np.zeros(np.shape(p_es)) - if use_hand_eye_calib: - print q_gt[0,:] - print p_gt[0,:] - T_om = get_rigid_body_trafo(q_gt[0,:], p_gt[0,:]) - T_vc = get_rigid_body_trafo(q_es[0,:], scale*p_es[0,:]) - T_cv = transformations.inverse_matrix(T_vc) - T_ov = np.dot(T_om, np.dot(T_mc, T_cv)) - print 'T_ov = ' + str(T_ov) +def analyse_synthetic_trajectory(results_dir): + data = np.loadtxt(os.path.join(results_dir, 'translation_error.txt')) + timestamps = data[:,0] + translation_error = data[:,1:4] + plot_translation_error(timestamps, translation_error, results_dir) - # apply transformation to estimated trajectory - q_es_aligned = np.zeros(np.shape(q_es)) - rpy_es_aligned = np.zeros(np.shape(p_es)) - rpy_gt = np.zeros(np.shape(p_es)) - for i in range(np.shape(p_es)[0]): - T_vc = get_rigid_body_trafo(q_es[i,:],p_es[i,:]) - T_vc[0:3,3] *= scale - T_om = np.dot(T_ov, np.dot(T_vc, T_cm)) - p_es_aligned[i,:] = T_om[0:3,3] - q_es_aligned[i,:] = transformations.quaternion_from_matrix(T_om) - rpy_es_aligned[i,:] = transformations.euler_from_quaternion(q_es_aligned[i,:], 'rzyx') - rpy_gt[i,:] = transformations.euler_from_quaternion(q_gt[i,:], 'rzyx') - - # plot position error (drift) - translation_error = (p_gt-p_es_aligned) - plot_translation_error(t_es, translation_error, results_dir) - - # plot orientation error (drift) - orientation_error = (rpy_gt - rpy_es_aligned) - plot_rotation_error(t_es, orientation_error, results_dir) + # plot orientation error + data = np.loadtxt(os.path.join(results_dir, 'orientation_error.txt')) + timestamps = data[:,0] + orientation_error = data[:,1:4] + plot_rotation_error(timestamps, orientation_error, results_dir) - # plot scale drift - motion_gt = np.diff(p_gt, 0) - motion_es = np.diff(p_es_aligned, 0) - dist_gt = np.sqrt(np.sum(np.multiply(motion_gt,motion_gt),1)) - dist_es = np.sqrt(np.sum(np.multiply(motion_es,motion_es),1)) - fig = plt.figure(figsize=(8,2.5)) - ax = fig.add_subplot(111, xlabel='time [s]', ylabel='scale change [\%]', xlim=[0,t_es[-1]+4]) - scale_drift = np.divide(dist_es,dist_gt)*100-100 - ax.plot(t_es, scale_drift, 'b-') - fig.tight_layout() - - else: - for i in range(np.shape(p_es)[0]): - p_es_aligned[i,:] = scale*rot.dot(p_es[i,:]) + trans - # plot position error (drift) - translation_error = (p_gt-p_es_aligned) - plot_translation_error(t_es, translation_error, results_dir) - - # plot trajectory - fig = plt.figure() - ax = fig.add_subplot(111, title='trajectory', aspect='equal', xlabel='x [m]', ylabel='y [m]') - ax.plot(p_es_aligned[:,0], p_es_aligned[:,1], 'b-', label='estimate') - ax.plot(p_gt[:,0], p_gt[:,1], 'r-', label='groundtruth') - ax.plot(p_es_aligned[0:n_align_frames,0], p_es_aligned[0:n_align_frames,1], 'g-', linewidth=2, label='aligned') - ax.legend() - fig.tight_layout() - fig.savefig(results_dir+'/trajectory.pdf') - +def analyse_optitrack_trajectory_with_hand_eye_calib(results_dir, params, n_align_frames = 200): + print('loading hand-eye-calib') + T_cm_quat = np.array([params['hand_eye_calib']['Tcm_qx'], + params['hand_eye_calib']['Tcm_qy'], + params['hand_eye_calib']['Tcm_qz'], + params['hand_eye_calib']['Tcm_qw']]) + T_cm_tran = np.array([params['hand_eye_calib']['Tcm_tx'], + params['hand_eye_calib']['Tcm_ty'], + params['hand_eye_calib']['Tcm_tz']]) + T_cm = get_rigid_body_trafo(T_cm_quat, T_cm_tran) + T_mc = transformations.inverse_matrix(T_cm) - - else: - data = np.loadtxt(os.path.join(results_dir, 'translation_error.txt')) - timestamps = data[:,0] - translation_error = data[:,1:4] - plot_translation_error(timestamps, translation_error, results_dir) - - # plot orientation error - data = np.loadtxt(os.path.join(results_dir, 'orientation_error.txt')) - timestamps = data[:,0] - orientation_error = data[:,1:4] - plot_rotation_error(timestamps, orientation_error, results_dir) + t_es, p_es, q_es, t_gt, p_gt, q_gt = load_dataset(results_dir, params['cam_delay']) + + # align Sim3 to get scale + print('align Sim3 using '+str(n_align_frames)+' first frames.') + scale,rot,trans = align_trajectory.align_sim3(p_gt[0:n_align_frames,:], p_es[0:n_align_frames,:]) + print 'scale = '+str(scale) + # get trafo between (v)ision and (o)ptitrack frame + print q_gt[0,:] + print p_gt[0,:] + T_om = get_rigid_body_trafo(q_gt[0,:], p_gt[0,:]) + T_vc = get_rigid_body_trafo(q_es[0,:], scale*p_es[0,:]) + T_cv = transformations.inverse_matrix(T_vc) + T_ov = np.dot(T_om, np.dot(T_mc, T_cv)) + print 'T_ov = ' + str(T_ov) + + # apply transformation to estimated trajectory + q_es_aligned = np.zeros(np.shape(q_es)) + rpy_es_aligned = np.zeros(np.shape(p_es)) + rpy_gt = np.zeros(np.shape(p_es)) + p_es_aligned = np.zeros(np.shape(p_es)) + for i in range(np.shape(p_es)[0]): + T_vc = get_rigid_body_trafo(q_es[i,:],p_es[i,:]) + T_vc[0:3,3] *= scale + T_om = np.dot(T_ov, np.dot(T_vc, T_cm)) + p_es_aligned[i,:] = T_om[0:3,3] + q_es_aligned[i,:] = transformations.quaternion_from_matrix(T_om) + rpy_es_aligned[i,:] = transformations.euler_from_quaternion(q_es_aligned[i,:], 'rzyx') + rpy_gt[i,:] = transformations.euler_from_quaternion(q_gt[i,:], 'rzyx') + + # plot position error (drift) + translation_error = (p_gt-p_es_aligned) + plot_translation_error(t_es, translation_error, results_dir) + + # plot orientation error (drift) + orientation_error = (rpy_gt - rpy_es_aligned) + plot_rotation_error(t_es, orientation_error, results_dir) + # plot scale drift + motion_gt = np.diff(p_gt, 0) + motion_es = np.diff(p_es_aligned, 0) + dist_gt = np.sqrt(np.sum(np.multiply(motion_gt,motion_gt),1)) + dist_es = np.sqrt(np.sum(np.multiply(motion_es,motion_es),1)) + fig = plt.figure(figsize=(8,2.5)) + ax = fig.add_subplot(111, xlabel='time [s]', ylabel='scale change [\%]', xlim=[0,t_es[-1]+4]) + scale_drift = np.divide(dist_es,dist_gt)*100-100 + ax.plot(t_es, scale_drift, 'b-') + fig.tight_layout() + fig.savefig(results_dir+'/scale_drift.pdf') + + # plot trajectory + fig = plt.figure() + ax = fig.add_subplot(111, title='trajectory', aspect='equal', xlabel='x [m]', ylabel='y [m]') + ax.plot(p_es_aligned[:,0], p_es_aligned[:,1], 'b-', label='estimate') + ax.plot(p_gt[:,0], p_gt[:,1], 'r-', label='groundtruth') + ax.plot(p_es_aligned[0:n_align_frames,0], p_es_aligned[0:n_align_frames,1], 'g-', linewidth=2, label='aligned') + ax.legend() + fig.tight_layout() + fig.savefig(results_dir+'/trajectory.pdf') + +def analyse_trajectory(results_dir, n_align_frames = 200, use_hand_eye_calib = True): + params = yaml.load(open(os.path.join(results_dir, 'dataset_params.yaml'),'r')) + if params['dataset_is_blender']: + analyse_synthetic_trajectory(results_dir) + elif use_hand_eye_calib: + analyse_optitrack_trajectory_with_hand_eye_calib(results_dir, params, n_align_frames) + else: + t_es, p_es, q_es, t_gt, p_gt, q_gt = load_dataset(results_dir, params['cam_delay']) + scale,rot,trans = align_trajectory.align_sim3(p_gt[0:n_align_frames,:], p_es[0:n_align_frames,:]) + p_es_aligned = np.zeros(np.shape(p_es)) + for i in range(np.shape(p_es)[0]): + p_es_aligned[i,:] = scale*rot.dot(p_es[i,:]) + trans + # plot position error (drift) + translation_error = (p_gt-p_es_aligned) + plot_translation_error(t_es, translation_error, results_dir) + def get_rigid_body_trafo(quat,trans): T = transformations.quaternion_matrix(quat) T[0:3,3] = trans return T - -def load_hand_eye_calib(results_dir): - P = yaml.load(open(os.path.join(results_dir, 'dataset_params.yaml'),'r'))['hand_eye_calib'] - - T_cm_quat = np.array([P['Tcm_qx'], P['Tcm_qy'], P['Tcm_qz'], P['Tcm_qw']]) - T_cm_tran = np.array([P['Tcm_tx'], P['Tcm_ty'], P['Tcm_tz']]) - T_cm = get_rigid_body_trafo(T_cm_quat, T_cm_tran) - T_mc = transformations.inverse_matrix(T_cm) - return T_cm, T_mc - -def load_dataset(results_dir): - """ - Assumes that groundtruth measurements are already matched with the - images. - """ + +def load_dataset(results_dir, cam_delay): + print('loading dataset in '+results_dir) + print('cam_delay = '+str(cam_delay)) - data_gt = open(os.path.join(results_dir, 'groundtruth_matched.txt')).read() + data_gt = open(os.path.join(results_dir, 'groundtruth.txt')).read() lines = data_gt.replace(","," ").replace("\t"," ").split("\n") - data_gt = np.array([[np.float(v.strip()) for i,v in enumerate(line.split(" ")) if i != 1 and v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"]) + data_gt = np.array([[np.float(v.strip()) for i,v in enumerate(line.split(" ")) if v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"]) + #data_gt = np.array([[np.float(v.strip()) for i,v in enumerate(line.split(" ")) if i != 1 and v.strip()!=""] for line in lines if len(line)>0 and line[0]!="#"]) data_gt = [(float(l[0]),l[1:]) for l in data_gt] data_gt = dict(data_gt) @@ -152,7 +154,7 @@ def load_dataset(results_dir): data_es = [(float(l[0]),l[1:]) for l in data_es] data_es = dict(data_es) - matches = associate.associate(data_gt, data_es, 0.0, 0.0001) + matches = associate.associate(data_gt, data_es, -cam_delay, 0.02) p_gt = np.array([[np.float(value) for value in data_gt[a][0:3]] for a,b in matches]) q_gt = np.array([[np.float(value) for value in data_gt[a][3:7]] for a,b in matches]) p_es = np.array([[np.float(value) for value in data_es[b][0:3]] for a,b in matches]) @@ -174,7 +176,7 @@ if __name__ == '__main__': ''') parser.add_argument('results_dir', help='folder with the results') parser.add_argument('--use_hand_eye_calib', help='', action='store_true') - parser.add_argument('--n_align_frames', help='', default=20) + parser.add_argument('--n_align_frames', help='', default=200) args = parser.parse_args() print('analyse trajectory for dataset: '+str(args.results_dir)) diff --git a/svo_analysis/src/svo_analysis/hand_eye_calib.py b/svo_analysis/src/svo_analysis/hand_eye_calib.py index f0eae14..a54b4f8 100644 --- a/svo_analysis/src/svo_analysis/hand_eye_calib.py +++ b/svo_analysis/src/svo_analysis/hand_eye_calib.py @@ -4,41 +4,37 @@ Created on Sun Aug 4 15:47:55 2013 @author: cforster """ - +import os import yaml import numpy as np -import associate -import rotation_utils as ru +import svo_analysis.tum_benchmark_tools.associate as associate +import vikit_py.align_trajectory as align_trajectory +import vikit_py.transformations as transformations import matplotlib.pyplot as plt # user config display = True -dataset = '20130906_2149_ptam_i7_asl2' -n_measurements = 1000 -delta = 20 +dataset_dir = '/home/cforster/catkin_ws/src/rpg_svo/svo_analysis/results/rpg_circle_1' +n_measurements = 400 +n_align_sim3 = 600 +delta = 50 # load dataset parameters -dataset_dir = '../results/'+dataset -params_stream = open(dataset_dir+'/params.yaml') -params = yaml.load(params_stream) +params = yaml.load(open(os.path.join(dataset_dir, 'dataset_params.yaml'))) # set trajectory groundtruth and estimate file -traj_groundtruth = params['dataset_directory']+'/groundtruth_filtered.txt' -traj_estimate = dataset_dir+'/traj_estimate.txt' - -# load dataset params -dataset_param_file_stream = open(params['dataset_directory']+'/dataset_params.yaml','r') -dataset_param = yaml.load(dataset_param_file_stream) +traj_groundtruth = os.path.join(dataset_dir, 'groundtruth.txt') +traj_estimate = os.path.join(dataset_dir,'traj_estimate.txt') # load data data_gt = associate.read_file_list(traj_groundtruth) data_es = associate.read_file_list(traj_estimate) # select matches -#offset = -dataset_param['cam_delay'] -offset = -0.03 +offset = -params['cam_delay'] +print ('offset = '+str(offset)) matches = associate.associate(data_gt, data_es, offset, 0.02) -#matches = matches[0:470] +#matches = matches[500:] p_gt = np.array([[float(value) for value in data_gt[a][0:3]] for a,b in matches]) q_gt = np.array([[float(value) for value in data_gt[a][3:7]] for a,b in matches]) p_es = np.array([[float(value) for value in data_es[b][0:3]] for a,b in matches]) @@ -46,30 +42,49 @@ q_es = np.array([[float(value) for value in data_es[b][3:7]] for a,b in matches] # -------------------------------------------------------------------------------- # align Sim3 to get scale -scale,rot,trans = align_sim3(p_gt, p_es, np.shape(matches)[0]) -p_es = scale*p_es -#p_es = np.transpose(scale*np.dot(rot,np.transpose(p_es)))+trans +scale,rot,trans = align_trajectory.align_sim3(p_gt[0:n_align_sim3,:], p_es[0:n_align_sim3,:]) +#model_aligned = s * R * model + t +#alignment_error = model_aligned - data +#t_error = np.sqrt(np.sum(np.multiply(alignment_error,alignment_error),0)).A[0] + +p_es_aligned = np.transpose(scale*np.dot(rot,np.transpose(p_es)))+trans +p_es = scale*p_es + + print 's='+str(scale) -#print 't='+str(trans) -#print 'R='+str(rot) +print 't='+str(trans) +print 'R='+str(rot) # plot sim3 aligned trajectory -if display: - fig = plt.figure() - ax = fig.add_subplot(111, aspect='equal') - ax.plot(p_es[:,0], p_es[:,1], 'r-', label='estimate') - ax.plot(p_gt[:,0], p_gt[:,1], 'b-', label='groundtruth') - ax.legend() +fig = plt.figure() +ax = fig.add_subplot(111, aspect='equal') +ax.plot(p_es_aligned[:,0], p_es_aligned[:,1], 'r-', label='estimate', alpha=0.2) +ax.plot(p_gt[:,0], p_gt[:,1], 'b-', label='groundtruth', alpha=0.2) +ax.plot(p_es_aligned[:n_align_sim3,0], p_es_aligned[:n_align_sim3,1], 'g-', label='aligned', linewidth=2) +ax.plot(p_gt[:n_align_sim3,0], p_gt[:n_align_sim3,1], 'm-', label='aligned', linewidth=2) +ax.legend() +for (x1,y1,z1),(x2,y2,z2) in zip(p_es_aligned[:n_align_sim3:10],p_gt[:n_align_sim3:10]): + ax.plot([x1,x2],[y1,y2],'-',color="red") + +fig = plt.figure() +ax = fig.add_subplot(111) +ax.plot(p_gt[:,0], 'r-') +ax.plot(p_gt[:,1], 'g-') +ax.plot(p_gt[:,2], 'b-') +ax.plot(p_es_aligned[:,0], 'r--') +ax.plot(p_es_aligned[:,1], 'g--') +ax.plot(p_es_aligned[:,2], 'b--') + # -------------------------------------------------------------------------------- # hand-eye-calib # select random measurements -I = np.array(rand(n_measurements,1)*(np.shape(matches)[0]-delta), dtype=int)[:,0] -R,b = hand_eye_calib(q_gt, q_es, p_gt, p_es, I, delta, True) +I = np.array(np.random.rand(n_measurements,1)*(np.shape(matches)[0]-delta), dtype=int)[:,0] +R,b = align_trajectory.hand_eye_calib(q_gt, q_es, p_gt, p_es, I, delta, True) -print 'quat = ' + str(ru.dcm2quat(R)) +print 'quat = ' + str(transformations.quaternion_from_matrix(transformations.convert_3x3_to_4x4(R))) print 'b = ' + str(b) rpy_es = np.zeros([q_es.shape[0]-1, 3]) @@ -78,15 +93,15 @@ t_gt = np.zeros([q_es.shape[0]-1,3]) t_es = np.zeros([q_es.shape[0]-1,3]) for i in range(delta,np.shape(q_es)[0]): - A1 = ru.quat2dcm(q_es[i-delta,:]) - A2 = ru.quat2dcm(q_es[i,:]) + A1 = transformations.quaternion_matrix(q_es[i-delta,:])[:3,:3] + A2 = transformations.quaternion_matrix(q_es[i,:])[:3,:3] A = np.dot(A1.transpose(), A2) - B1 = ru.quat2dcm(q_gt[i-delta,:]) - B2 = ru.quat2dcm(q_gt[i,:]) + B1 = transformations.quaternion_matrix(q_gt[i-delta,:])[:3,:3] + B2 = transformations.quaternion_matrix(q_gt[i,:])[:3,:3] B = np.dot(B1.transpose(), B2) B_es = np.dot(np.transpose(R), np.dot(A, R)) - rpy_gt[i-delta,:] = ru.dcm2rpy(B) - rpy_es[i-delta,:] = ru.dcm2rpy(B_es) + rpy_gt[i-delta,:] = transformations.euler_from_matrix(B, 'rzyx') + rpy_es[i-delta,:] = transformations.euler_from_matrix(B_es, 'rzyx') t_B = np.dot(np.transpose(B1),(p_gt[i,:]-p_gt[i-delta,:])) t_A = np.dot(np.transpose(A1),(p_es[i,:]-p_es[i-delta,:])) t_gt[i-delta,:] = t_B diff --git a/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py b/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py index 01bea59..361cdd5 100755 --- a/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py +++ b/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py @@ -106,8 +106,8 @@ if __name__ == '__main__': parser = argparse.ArgumentParser(description=''' This script takes two data files with timestamps and associates them ''') - parser.add_argument('first_file', help='first text file (format: timestamp data)') - parser.add_argument('second_file', help='second text file (format: timestamp data)') + parser.add_argument('first_file', help='estimated trajectory (format: timestamp data)') + parser.add_argument('second_file', help='groundtruth (format: timestamp data)') parser.add_argument('--offset', help='time offset added to the timestamps of the second file (default: 0.0)',default=0.0) parser.add_argument('--max_difference', help='maximally allowed time difference for matching entries (default: 0.02)',default=0.02) args = parser.parse_args() From 4bc234e49060f24e8aa7d22250d417930b728c41 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 23 May 2014 15:31:48 +0200 Subject: [PATCH 124/215] apply rotation to dense-input-msgs --- svo_ros/src/visualizer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index a06827e..6f50461 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -298,8 +298,11 @@ void Visualizer::exportToDense(const FramePtr& frame) msg.min_depth = (float) min_z; msg.max_depth = (float) max_z; - Quaterniond q(frame->T_f_w_.inverse().rotation_matrix()); - Vector3d p(frame->T_f_w_.inverse().translation()); + // publish cam in world frame + SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse()); + Quaterniond q(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); + Vector3d p(T_world_from_cam.translation()); + msg.pose.position.x = p[0]; msg.pose.position.y = p[1]; msg.pose.position.z = p[2]; From ab121434e406dd86c8b1436a605a6893c17a324f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 23 May 2014 15:32:15 +0200 Subject: [PATCH 125/215] fixed relocalizer and state machine. pose doesn't jump around anymore when flashed with a camera. --- svo/src/frame_handler_base.cpp | 9 ++------- svo/src/frame_handler_mono.cpp | 15 +++++++++++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/svo/src/frame_handler_base.cpp b/svo/src/frame_handler_base.cpp index fb6d490..175ee01 100644 --- a/svo/src/frame_handler_base.cpp +++ b/svo/src/frame_handler_base.cpp @@ -160,17 +160,12 @@ void FrameHandlerBase::setTrackingQuality(const size_t num_observations) if(num_observations < Config::qualityMinFts()) { SVO_WARN_STREAM_THROTTLE(0.5, "Tracking less than "<< Config::qualityMinFts() <<" features!"); - tracking_quality_ = TRACKING_BAD; + tracking_quality_ = TRACKING_INSUFFICIENT; } - const int feature_drop = static_cast(num_obs_last_) - num_observations; + const int feature_drop = static_cast(std::min(num_obs_last_, Config::maxFts())) - num_observations; if(feature_drop > Config::qualityMaxFtsDrop()) { SVO_WARN_STREAM("Lost "<< feature_drop <<" features!"); - tracking_quality_ = TRACKING_BAD; - } - if(num_observations < 20) - { - SVO_ERROR_STREAM("Tracking less than 20 features!"); tracking_quality_ = TRACKING_INSUFFICIENT; } } diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index b06db86..46bcd45 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -149,8 +149,11 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() const size_t repr_n_mps = reprojector_.n_trials_; SVO_LOG2(repr_n_mps, repr_n_new_references); SVO_DEBUG_STREAM("Reprojection:\t nPoints = "<T_f_w_ = last_frame_->T_f_w_; // reset to avoid crazy pose jumps + tracking_quality_ = TRACKING_INSUFFICIENT; return RESULT_FAILURE; } @@ -177,7 +180,10 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() core_kfs_.insert(new_frame_); setTrackingQuality(sfba_n_edges_final); if(tracking_quality_ == TRACKING_INSUFFICIENT) + { + new_frame_->T_f_w_ = last_frame_->T_f_w_; // reset to avoid crazy pose jumps return RESULT_FAILURE; + } double depth_mean, depth_min; frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); if(!needNewKf(depth_mean) || tracking_quality_ == TRACKING_BAD) @@ -233,12 +239,13 @@ FrameHandlerMono::UpdateResult FrameHandlerMono::relocalizeFrame( const SE3& T_cur_ref, FramePtr ref_keyframe) { - SVO_WARN_STREAM_THROTTLE(0.5, "Relocalizing frame"); + SVO_WARN_STREAM_THROTTLE(1.0, "Relocalizing frame"); SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), 30, SparseImgAlign::GaussNewton, false, false); size_t img_align_n_tracked = img_align.run(ref_keyframe, new_frame_); if(img_align_n_tracked > 30) { + SE3 T_f_w_last = last_frame_->T_f_w_; last_frame_ = ref_keyframe; FrameHandlerMono::UpdateResult res = processFrame(); if(res != RESULT_FAILURE) @@ -247,7 +254,7 @@ FrameHandlerMono::UpdateResult FrameHandlerMono::relocalizeFrame( SVO_INFO_STREAM("Relocalization successful."); } else - new_frame_->T_f_w_ = ref_keyframe->T_f_w_; + new_frame_->T_f_w_ = T_f_w_last; // reset to last well localized pose return res; } return RESULT_FAILURE; From 4001f6a736d80097974069d6cec261cf7fef6d8d Mon Sep 17 00:00:00 2001 From: Flavio Fontana Date: Fri, 23 May 2014 17:02:43 +0200 Subject: [PATCH 126/215] not publishing pose in relocalization mode and fix in dense input message --- svo_ros/src/visualizer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index 6f50461..a17589f 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -161,7 +161,7 @@ void Visualizer::publishMinimal( pub_images_.publish(img_msg.toImageMsg()); } - if(pub_pose_.getNumSubscribers() > 0) + if(pub_pose_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) { Quaterniond q; Vector3d p; @@ -300,7 +300,7 @@ void Visualizer::exportToDense(const FramePtr& frame) // publish cam in world frame SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse()); - Quaterniond q(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); + Quaterniond q(T_world_from_cam.rotation_matrix()); Vector3d p(T_world_from_cam.translation()); msg.pose.position.x = p[0]; From b49d2f85731c959268fb587358ce4785d5292391 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 27 May 2014 20:38:23 +0200 Subject: [PATCH 127/215] compiles again with g2o. --- svo/include/svo/bundle_adjustment.h | 10 ++++-- svo/src/bundle_adjustment.cpp | 50 ++++++++++++++--------------- svo/src/frame_handler_mono.cpp | 8 ++--- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/svo/include/svo/bundle_adjustment.h b/svo/include/svo/bundle_adjustment.h index 215d563..f3c3501 100644 --- a/svo/include/svo/bundle_adjustment.h +++ b/svo/include/svo/bundle_adjustment.h @@ -22,16 +22,22 @@ namespace g2o { class EdgeProjectXYZ2UV; class SparseOptimizer; +class VertexSE3Expmap; +class VertexSBAPointXYZ; } -typedef g2o::EdgeProjectXYZ2UV g2oEdgeSE3; namespace svo { +typedef g2o::EdgeProjectXYZ2UV g2oEdgeSE3; +typedef g2o::VertexSE3Expmap g2oFrameSE3; +typedef g2o::VertexSBAPointXYZ g2oPoint; + +class Frame; class Point; class Feature; class Map; -/// Local, global and 2-view bundle adjustment with g2o. +/// Local, global and 2-view bundle adjustment with g2o namespace ba { /// Temporary container to hold the g2o edge with reference to frame and point. diff --git a/svo/src/bundle_adjustment.cpp b/svo/src/bundle_adjustment.cpp index a2075f4..eaba2b0 100644 --- a/svo/src/bundle_adjustment.cpp +++ b/svo/src/bundle_adjustment.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -37,10 +38,11 @@ namespace svo { namespace ba { -void -twoViewBA(Frame* frame1, Frame* frame2, - double reproj_thresh, - Map* map) +void twoViewBA( + Frame* frame1, + Frame* frame2, + double reproj_thresh, + Map* map) { // scale reprojection threshold in pixels to unit plane reproj_thresh /= frame1->cam_->errorMultiplier2(); @@ -104,12 +106,12 @@ twoViewBA(Frame* frame1, Frame* frame2, const double reproj_thresh_squared = reproj_thresh*reproj_thresh; size_t n_incorrect_edges = 0; for(list::iterator it_e = edges.begin(); it_e != edges.end(); ++it_e) - if(it_e->edge_->chi2() > reproj_thresh_squared) + if(it_e->edge->chi2() > reproj_thresh_squared) { - if(it_e->feature_->point != NULL) + if(it_e->feature->point != NULL) { - map->safeDeletePoint(it_e->feature_->point); - it_e->feature_->point = NULL; + map->safeDeletePoint(it_e->feature->point); + it_e->feature->point = NULL; } ++n_incorrect_edges; } @@ -117,14 +119,14 @@ twoViewBA(Frame* frame1, Frame* frame2, printf("2-View BA: Wrong edges = %zu\n", n_incorrect_edges); } -void -localBA(Frame* center_kf, - set* core_kfs, - Map* map, - size_t& n_incorrect_edges_1, - size_t& n_incorrect_edges_2, - double& init_error, - double& final_error) +void localBA( + Frame* center_kf, + set* core_kfs, + Map* map, + size_t& n_incorrect_edges_1, + size_t& n_incorrect_edges_2, + double& init_error, + double& final_error) { // init g2o @@ -170,7 +172,7 @@ localBA(Frame* center_kf, ++n_mps; // Add edges - Observations::iterator it_obs=(*it_pt)->obs_.begin(); + list::iterator it_obs=(*it_pt)->obs_.begin(); while(it_obs!=(*it_pt)->obs_.end()) { Vector2d error = vk::project2d((*it_obs)->f) - vk::project2d((*it_obs)->frame->w2f((*it_pt)->pos_)); @@ -236,9 +238,9 @@ localBA(Frame* center_kf, double reproj_thresh_2_squared = reproj_thresh_2*reproj_thresh_2; for(list::iterator it = edges.begin(); it != edges.end(); ++it) { - if(it->edge_->chi2() > reproj_thresh_2_squared) //*(1<feature_->level)) + if(it->edge->chi2() > reproj_thresh_2_squared) //*(1<feature_->level)) { - map->removePtFrameRef(it->frame_, it->feature_); + map->removePtFrameRef(it->frame, it->feature); ++n_incorrect_edges_2; } } @@ -248,8 +250,7 @@ localBA(Frame* center_kf, final_error = sqrt(final_error)*center_kf->cam_->errorMultiplier2(); } -void -globalBA(Map* map) +void globalBA(Map* map) { // init g2o g2o::SparseOptimizer optimizer; @@ -334,15 +335,14 @@ globalBA(Map* map) double reproj_thresh_2_squared = reproj_thresh_2*reproj_thresh_2; for(list::iterator it = edges.begin(); it != edges.end(); ++it) { - if(it->edge_->chi2() > reproj_thresh_2_squared) + if(it->edge->chi2() > reproj_thresh_2_squared) { - map->removePtFrameRef(it->frame_, it->feature_); + map->removePtFrameRef(it->frame, it->feature); } } } -void -setupG2o(g2o::SparseOptimizer * optimizer) +void setupG2o(g2o::SparseOptimizer * optimizer) { // TODO: What's happening with all this HEAP stuff? Memory Leak? optimizer->setVerbose(false); diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 46bcd45..3de6f7f 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -111,7 +111,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() // two-frame bundle adjustment #ifdef USE_BUNDLE_ADJUSTMENT - ba::twoViewBA(new_frame_.get(), map_.lastKeyframe().get(), Config::lobaThresh(), map_); + ba::twoViewBA(new_frame_.get(), map_.lastKeyframe().get(), Config::lobaThresh(), &map_); #endif new_frame_->setKeyframe(); @@ -207,10 +207,10 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() SVO_START_TIMER("local_ba"); setCoreKfs(Config::coreNKfs()); size_t loba_n_erredges_init, loba_n_erredges_fin; - double loba_err_init, ba_final_error; + double loba_err_init, loba_err_fin; ba::localBA(new_frame_.get(), &core_kfs_, &map_, - loba_n_erredges_init, ba_incorrect_edges_2, - ba_init_error, loba_err_fin); + loba_n_erredges_init, loba_n_erredges_fin, + loba_err_init, loba_err_fin); SVO_STOP_TIMER("local_ba"); SVO_LOG4(loba_n_erredges_init, loba_n_erredges_fin, loba_err_init, loba_err_fin); SVO_DEBUG_STREAM("Local BA:\t RemovedEdges {"< Date: Wed, 28 May 2014 16:12:38 +0200 Subject: [PATCH 128/215] updated readme --- README.md | 22 ++++++++++++++++------ svo/test/README.md | 9 +-------- svo_analysis/README.md | 1 + 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 81ad4d5..574214f 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,14 @@ vikit is a catkin project, therefore, download it into your catkin workspace sou cd catkin_ws/src git clone https://github.com/uzh-rpg/rpg_vikit.git +#### ROS dependencies + +Sometimes `cmake-modules` is missing (required for including Eigen in ROS Indigo): + + sudo apt-get install ros-hydro-cmake-modules + +(replace `hydro` with your distribution). + #### SVO Now we are ready to build SVO. @@ -95,12 +103,6 @@ Clone it into your catkin workspace If you installed g2o then set `HAVE_G2O` in `svo/CMakeLists.txt` to TRUE. -Install missing ros dependencies. Sometimes `cmake-modules` is missing (required for including Eigen in ROS Indigo): - - sudo apt-get install ros-hydro-cmake-modules - -(replace `hydro` with your distribution). - Finally, build: catkin_make @@ -160,6 +162,14 @@ Parameter Settings A description of all parameters which can be set via the launchfile is provided in `svo/include/config.h`. The default parameters can be viewed in `svo/src/config.cpp`. Moreover, some additional parameters (mainly rostopic names etc.) are read from the ros parameter server in `svo_ros/vo_node.cpp`. +#### Forward motions + +The current keyframe selection criterion is designed for downward looking cameras. This is one reason why SVO does not work well for forward motions (e.g., to be used on a car). + +#### Image resolution + +The current parameters are tuned for WVGA resolution. If you use a higher resolution camera, then the pyramid levels should be increased as well as the reprojection error thresholds. + Contributing ------------ diff --git a/svo/test/README.md b/svo/test/README.md index ce9f1fd..a968f2a 100644 --- a/svo/test/README.md +++ b/svo/test/README.md @@ -1,11 +1,4 @@ Download Synthetic Test Data: ----------------------------- -Downloads and extracts the test data in the folder `data`: - - cd rpg_slam/svo/test/data - wget http://rpg.ifi.uzh.ch/datasets/flying_room_1_rig_1.tar.gz -O - | tar -xz - -If you want to store the data in another location (for instance, if you maintain a special folder with all datasets), then you can move the dataset there and set the environment variable `TEST_DATA_DIR` in your `.bashrc` like this: - - export SVO_DATASET_DIR=${HOME}/Datasets +TODO \ No newline at end of file diff --git a/svo_analysis/README.md b/svo_analysis/README.md index 07ae6eb..3fe3ea6 100644 --- a/svo_analysis/README.md +++ b/svo_analysis/README.md @@ -16,6 +16,7 @@ Source your new `.bashrc` script, go to the new dataset folder and download the cd ${SVO_DATASET_DIR} wget http://rpg.ifi.uzh.ch/datasets/flying_room_1_rig_1.tar.gz -O - | tar -xz +TODO: replace this dataset with new ones. #### Run Benchmark From 09ceff33e2bc327ce9a65354161e09a5ffe2c57c Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 28 May 2014 16:12:49 +0200 Subject: [PATCH 129/215] cleanup cmake --- svo/CMakeLists.txt | 49 ++++++++++++++-------------------------- svo/include/svo/global.h | 6 +---- 2 files changed, 18 insertions(+), 37 deletions(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 7433d71..a74caf2 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -1,9 +1,8 @@ ################################################################################ # user build settings -SET(DEBUG FALSE) -SET(TRACE FALSE) -SET(HAVE_G2O FALSE) +SET(TRACE TRUE) +SET(HAVE_G2O TRUE) ################################################################################ @@ -14,18 +13,7 @@ SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo SET(CMAKE_VERBOSE_MAKEFILE OFF) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") -# Set ARM_ARCHITECTURE environment variable on Odroid -IF(DEFINED ENV{ARM_ARCHITECTURE}) - SET(IS_ARM TRUE) -# ADD_DEFINITIONS(-DHAVE_FAST_NEON) -ELSE() - SET(IS_ARM FALSE) -ENDIF() - # Set definitions -IF(DEBUG) - ADD_DEFINITIONS(-DSVO_DEBUG) -ENDIF() IF(TRACE) ADD_DEFINITIONS(-DSVO_TRACE) ENDIF() @@ -34,10 +22,9 @@ IF(HAVE_G2O) ENDIF() ADD_DEFINITIONS(-DSVO_USE_ROS) -# Set build flags +# Set build flags, set ARM_ARCHITECTURE environment variable on Odroid SET(CMAKE_CXX_FLAGS "-Wall -Werror -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -g") -IF(IS_ARM) +IF(DEFINED ENV{ARM_ARCHITECTURE}) SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -mfpu=neon -march=armv7-a -fomit-frame-pointer -fsee -funsafe-loop-optimizations -fno-signed-zeros -fno-math-errno -funroll-loops") ELSE() SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -mmmx -msse -msse -msse2 -msse3 -mssse3 -fomit-frame-pointer -fsee -funsafe-loop-optimizations -fno-signed-zeros -fno-math-errno -funroll-loops") @@ -48,11 +35,10 @@ ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") ENDIF() -# Add catkin and required ROS packages +# Add catkin and required ROS packages FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros) # Add plain cmake packages -FIND_PACKAGE(G2O REQUIRED) FIND_PACKAGE(OpenCV REQUIRED) FIND_PACKAGE(Eigen REQUIRED) FIND_PACKAGE(Sophus REQUIRED) @@ -74,15 +60,9 @@ INCLUDE_DIRECTORIES( ${OpenCV_INCLUDE_DIRS} ${Sophus_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} - ${catkin_INCLUDE_DIRS} + ${catkin_INCLUDE_DIRS} ${fast_INCLUDE_DIRS} ) -IF(HAVE_G2O) - INCLUDE_DIRECTORIES( - ${G2O_ROOT}/include - /usr/include/suitesparse # for cholmod - ) -ENDIF() # Set link libraries LIST(APPEND LINK_LIBS @@ -92,12 +72,6 @@ LIST(APPEND LINK_LIBS ${catkin_LIBRARIES} ${fast_LIBRARIES} ) -IF(HAVE_G2O) - LIST(APPEND LINK_LIBS - g2o_core g2o_stuff g2o_solver_cholmod g2o_solver_csparse g2o_solver_dense g2o_solver_pcg g2o_types_sba - cholmod cxsparse - ) -ENDIF() # Set sourcefiles LIST(APPEND SOURCEFILES @@ -115,7 +89,18 @@ LIST(APPEND SOURCEFILES src/depth_filter.cpp src/config.cpp src/sparse_img_align.cpp) + +# Add g2o if available IF(HAVE_G2O) + FIND_PACKAGE(G2O REQUIRED) + INCLUDE_DIRECTORIES( + ${G2O_ROOT}/include + /usr/include/suitesparse # for cholmod + ) + LIST(APPEND LINK_LIBS + g2o_core g2o_stuff g2o_solver_cholmod g2o_solver_csparse g2o_solver_dense + g2o_solver_pcg g2o_types_sba cholmod cxsparse + ) LIST(APPEND SOURCEFILES src/bundle_adjustment.cpp) ENDIF(HAVE_G2O) diff --git a/svo/include/svo/global.h b/svo/include/svo/global.h index c118377..6fe6c4f 100644 --- a/svo/include/svo/global.h +++ b/svo/include/svo/global.h @@ -39,11 +39,7 @@ #define SVO_ERROR_STREAM(x) ROS_ERROR_STREAM(x) #else #define SVO_INFO_STREAM(x) std::cerr<<"\033[0;0m[INFO] "< // Adapted from rosconsole. Copyright (c) 2008, Willow Garage, Inc. From efcb7c1295cee5cad804a50b25bbeb2ef7e8a260 Mon Sep 17 00:00:00 2001 From: Pierre Moulon Date: Mon, 2 Jun 2014 10:37:59 +0200 Subject: [PATCH 130/215] Update README.md Fix a typo error --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 574214f..75e4f2d 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ Camera Calibration You need a calibrated camera to run SVO. We use the Matrix Vision Bluefox cameras in our lab, which have VGA resolution and global shutter. SVO supports three camera models: -1. The `ATAN` model - our preference - which is also used by _PTAM_. This model uses the _FOV_ distortion model of "Deverneay and Faugeras, Straight lines have to be straight, 2001". You can calibrate your camera with this model by using the calibration tool in this package: https://github.com/ethz-asl/ethzasl_ptam We prefer this model because the projection and unprojection can be computed faster than with the other models. Further, the industral cameras that we use have neglectable tangential distortion. +1. The `ATAN` model - our preference - which is also used by _PTAM_. This model uses the _FOV_ distortion model of "Devernay and Faugeras, Straight lines have to be straight, 2001". You can calibrate your camera with this model by using the calibration tool in this package: https://github.com/ethz-asl/ethzasl_ptam We prefer this model because the projection and unprojection can be computed faster than with the other models. Further, the industrial cameras that we use have neglectable tangential distortion. 2. The `Pinhole` model with three radial and two tangential distortion parameters. This model is standard in OpenCV and ROS. You can use the ROS camera calibration tool: http://wiki.ros.org/camera_calibration 3. The `Ocam` model by Davide Scaramuzza which can be used to model cameras with high field of view or even omnidirectional cameras. Use the OCamCalib toolbox to calibrate your camera: http://rpg.ifi.uzh.ch/software_datasets.html Although SVO can be used with this camera model, the algorithm does not work yet with omnidirectional cameras. From e69e934fe7f054e8757de0a5855383c084e58d49 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 3 Jun 2014 09:08:23 +0800 Subject: [PATCH 131/215] Update README.md --- README.md | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 75e4f2d..859a90e 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,34 @@ SVO === -This code implements a semi-direct visual odometry pipeline that is described in the paper - -* C. Forster, M. Pizzoli, D. Scaramuzza, - "__SVO: Fast Semi-Direct Monocular Visual Odometry__," - IEEE International Conference on Robotics and Automation (ICRA), 2014. +This code implements a semi-direct monocular visual odometry pipeline. Video: http://youtu.be/2YnIMfw6bJY -Disclaimer ----------- +Paper: http://rpg.ifi.uzh.ch/docs/ICRA14_Forster.pdf -SVO has been tested under ROS Groovy and Hydro and Ubuntu 12.04 and 13.04. This is research code, any fitness for a particular purpose is disclaimed. +#### Disclaimer + +SVO has been tested under ROS Groovy, Hydro and Indigo with Ubuntu 12.04, 13.04 and 14.04. This is research code, any fitness for a particular purpose is disclaimed. -Licence -------- +#### Licence -The source code is released under a GPLv3 licence. A professional edition license for closed-source projects is also available. Please contact `forster at ifi dot uzh dot ch` for further information. +The source code is released under a GPLv3 licence. A professional edition license for closed-source projects is also available. For commercial use, please contact the authors. + +#### Citing + +If you use SVO in an academic context, please cite the following publication: + + @inproceedings{Forster2014ICRA, + author = {Forster, Christian and Pizzoli, Matia and Scaramuzza, Davide}, + title = {{SVO}: Fast Semi-Direct Monocular Visual Odometry}, + booktitle = {IEEE International Conference on Robotics and Automation (ICRA)}, + year = {2014} + } + + Documentation ------------- @@ -176,15 +185,3 @@ Contributing You are very welcome to contribute to SVO by opening a pull request via Github. I try to follow the ROS C++ style guide http://wiki.ros.org/CppStyleGuide - -Citing ------- - -If you use SVO in an academic context, please cite the following publication: - - @inproceedings{Forster2014ICRA, - author = {Forster, Christian and Pizzoli, Matia and Scaramuzza, Davide}, - title = {{SVO}: Fast Semi-Direct Monocular Visual Odometry}, - booktitle = {IEEE International Conference on Robotics and Automation (ICRA)}, - year = {2014} - } From 2d2b949c7e26877af7d0445c94d8e14597fcdc7c Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 10 Jun 2014 20:46:12 +0800 Subject: [PATCH 132/215] default camera model is now loaded from svo_ros and not from rpg_calib --- svo_ros/launch/live.launch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo_ros/launch/live.launch b/svo_ros/launch/live.launch index 92f4b9b..8cdf322 100644 --- a/svo_ros/launch/live.launch +++ b/svo_ros/launch/live.launch @@ -3,7 +3,7 @@ - + From 166cd1c75e4fe02285172bda619e4c914ced263e Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 10:37:40 +0200 Subject: [PATCH 133/215] added ros parameter to disable user input thread. --- svo_ros/src/vo_node.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/svo_ros/src/vo_node.cpp b/svo_ros/src/vo_node.cpp index d903b3b..8a6f88c 100644 --- a/svo_ros/src/vo_node.cpp +++ b/svo_ros/src/vo_node.cpp @@ -45,7 +45,7 @@ public: svo::Visualizer visualizer_; bool publish_markers_; //!< publish only the minimal amount of info (choice for embedded devices) bool publish_dense_input_; - vk::UserInputThread* user_input_thread_; + boost::shared_ptr user_input_thread_; ros::Subscriber sub_remote_key_; std::string remote_input_; vk::AbstractCamera* cam_; @@ -61,11 +61,14 @@ VoNode::VoNode() : vo_(NULL), publish_markers_(vk::getParam("svo/publish_markers", true)), publish_dense_input_(vk::getParam("svo/publish_dense_input", false)), - user_input_thread_(new vk::UserInputThread()), remote_input_(""), cam_(NULL), quit_(false) { + // Start user input thread in parallel thread that listens to console keys + if(vk::getParam("svo/accept_console_user_input", true)) + user_input_thread_ = boost::make_shared(); + // Create Camera if(!vk::camera_loader::loadFromRosNs("svo", cam_)) throw std::runtime_error("Camera model not correctly specified."); @@ -87,8 +90,9 @@ VoNode::VoNode() : VoNode::~VoNode() { delete vo_; - delete user_input_thread_; delete cam_; + if(user_input_thread_ != NULL) + user_input_thread_->stop(); } void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) @@ -118,9 +122,12 @@ void VoNode::processUserActions() char input = remote_input_.c_str()[0]; remote_input_ = ""; - char console_input = user_input_thread_->getInput(); - if(console_input != 0) - input = console_input; + if(user_input_thread_ != NULL) + { + char console_input = user_input_thread_->getInput(); + if(console_input != 0) + input = console_input; + } switch(input) { From 0b1f9d7bb75be8e2ec333ff7e87b0780be93acde Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 11:36:22 +0200 Subject: [PATCH 134/215] new flag to display debug output for plain cmake-projects --- svo/include/svo/global.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/svo/include/svo/global.h b/svo/include/svo/global.h index 6fe6c4f..9f7cc97 100644 --- a/svo/include/svo/global.h +++ b/svo/include/svo/global.h @@ -39,7 +39,11 @@ #define SVO_ERROR_STREAM(x) ROS_ERROR_STREAM(x) #else #define SVO_INFO_STREAM(x) std::cerr<<"\033[0;0m[INFO] "< // Adapted from rosconsole. Copyright (c) 2008, Willow Garage, Inc. From c58503ae867397e92153acabcf11839000ae117d Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 11:37:02 +0200 Subject: [PATCH 135/215] added missing include --- svo/src/frame.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/svo/src/frame.cpp b/svo/src/frame.cpp index 2d40b96..f9b2bd0 100644 --- a/svo/src/frame.cpp +++ b/svo/src/frame.cpp @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include #include #include #include From 956a21f4f2d14e49f8e4d4341c0267b3f555268b Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 11:37:13 +0200 Subject: [PATCH 136/215] use environment variable for plain cmake projects to locate dataset folder --- svo/test/test_utils.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/svo/test/test_utils.h b/svo/test/test_utils.h index 5793bb7..5647879 100644 --- a/svo/test/test_utils.h +++ b/svo/test/test_utils.h @@ -20,24 +20,34 @@ #include #include // for getenv #include -#include +#ifdef SVO_USE_ROS + #include +#endif namespace svo { namespace test_utils { std::string getDatasetDir() { - std::string dataset_dir(ros::package::getPath("svo")+"/test/data"); const char* env_dir = std::getenv("SVO_DATASET_DIR"); +#ifdef SVO_USE_ROS + std::string dataset_dir(ros::package::getPath("svo")+"/test/data"); if(env_dir != NULL) dataset_dir = std::string(env_dir); return dataset_dir; +#else + return std::string(env_dir); +#endif } std::string getTraceDir() { +#ifdef SVO_USE_ROS std::string default_dir(ros::package::getPath("svo")+"/test/results"); return vk::getParam("svo/trace_dir", default_dir); +#else + return "/tmp"; +#endif } } // namespace test_utils From d4c5568c426a8d275259fa7c458552a59a3a5472 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 11:37:42 +0200 Subject: [PATCH 137/215] added flag to build without ROS as plain cmake project --- svo/CMakeLists.txt | 49 ++++++++++++------- svo/CMakeModules/FindEigen.cmake | 81 ++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 17 deletions(-) create mode 100644 svo/CMakeModules/FindEigen.cmake diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index a74caf2..d45f8aa 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -3,6 +3,8 @@ SET(TRACE TRUE) SET(HAVE_G2O TRUE) +SET(USE_ROS FALSE) # Set False if you want to build this package without Catkin +SET(DEBUG_OUTPUT FALSE) # Only relevant if build without ROS ################################################################################ @@ -20,7 +22,12 @@ ENDIF() IF(HAVE_G2O) ADD_DEFINITIONS(-DUSE_BUNDLE_ADJUSTMENT) ENDIF() -ADD_DEFINITIONS(-DSVO_USE_ROS) +IF(USE_ROS) + ADD_DEFINITIONS(-DSVO_USE_ROS) +ENDIF() +IF(DEBUG_OUTPUT) + ADD_DEFINITIONS(-DSVO_DEBUG_OUTPUT) +ENDIF() # Set build flags, set ARM_ARCHITECTURE environment variable on Odroid SET(CMAKE_CXX_FLAGS "-Wall -Werror -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") @@ -35,9 +42,6 @@ ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") ENDIF() -# Add catkin and required ROS packages -FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros) - # Add plain cmake packages FIND_PACKAGE(OpenCV REQUIRED) FIND_PACKAGE(Eigen REQUIRED) @@ -45,13 +49,19 @@ FIND_PACKAGE(Sophus REQUIRED) FIND_PACKAGE(fast REQUIRED) FIND_PACKAGE(Boost REQUIRED COMPONENTS thread) -# Describe catkin Project -catkin_package( - DEPENDS Eigen OpenCV Sophus Boost fast - CATKIN_DEPENDS roscpp roslib vikit_common vikit_ros - INCLUDE_DIRS include - LIBRARIES svo -) +IF(USE_ROS) + FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros) + catkin_package( + DEPENDS Eigen OpenCV Sophus Boost fast + CATKIN_DEPENDS roscpp roslib vikit_common vikit_ros + INCLUDE_DIRS include + LIBRARIES svo + ) +ELSE() + FIND_PACKAGE(vikit_common REQUIRED) + SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) + SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) +ENDIF() # Include dirs INCLUDE_DIRECTORIES( @@ -60,7 +70,6 @@ INCLUDE_DIRECTORIES( ${OpenCV_INCLUDE_DIRS} ${Sophus_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} - ${catkin_INCLUDE_DIRS} ${fast_INCLUDE_DIRS} ) @@ -69,10 +78,17 @@ LIST(APPEND LINK_LIBS ${OpenCV_LIBRARIES} ${Sophus_LIBRARIES} ${Boost_LIBRARIES} - ${catkin_LIBRARIES} ${fast_LIBRARIES} ) +IF(USE_ROS) + INCLUDE_DIRECTORIES(${catkin_INCLUDE_DIRS}) + LIST(APPEND LINK_LIBS ${catkin_LIBRARIES}) +ELSE() + INCLUDE_DIRECTORIES(${vikit_common_INCLUDE_DIRS}) + LIST(APPEND LINK_LIBS ${vikit_common_LIBRARIES}) +ENDIF() + # Set sourcefiles LIST(APPEND SOURCEFILES src/frame_handler_mono.cpp @@ -94,12 +110,12 @@ LIST(APPEND SOURCEFILES IF(HAVE_G2O) FIND_PACKAGE(G2O REQUIRED) INCLUDE_DIRECTORIES( - ${G2O_ROOT}/include + ${G2O_INCLUDE_DIR} /usr/include/suitesparse # for cholmod ) LIST(APPEND LINK_LIBS - g2o_core g2o_stuff g2o_solver_cholmod g2o_solver_csparse g2o_solver_dense - g2o_solver_pcg g2o_types_sba cholmod cxsparse + ${G2O_CORE_LIBRARY} ${G2O_STUFF_LIBRARY} ${G2O_SOLVER_CHOLMOD} ${G2O_SOLVER_CSPARSE} ${G2O_SOLVER_DENSE} + ${G2O_SOLVER_PCG} ${G2O_TYPES_SBA} cholmod cxsparse ) LIST(APPEND SOURCEFILES src/bundle_adjustment.cpp) ENDIF(HAVE_G2O) @@ -108,7 +124,6 @@ ENDIF(HAVE_G2O) ADD_LIBRARY(svo SHARED ${SOURCEFILES}) TARGET_LINK_LIBRARIES(svo ${LINK_LIBS}) - ################################################################################ # TESTS diff --git a/svo/CMakeModules/FindEigen.cmake b/svo/CMakeModules/FindEigen.cmake new file mode 100644 index 0000000..8587367 --- /dev/null +++ b/svo/CMakeModules/FindEigen.cmake @@ -0,0 +1,81 @@ +############################################################################### +# +# CMake script for finding the Eigen library. +# +# http://eigen.tuxfamily.org/index.php?title=Main_Page +# +# Copyright (c) 2006, 2007 Montel Laurent, +# Copyright (c) 2008, 2009 Gael Guennebaud, +# Copyright (c) 2009 Benoit Jacob +# Redistribution and use is allowed according to the terms of the 2-clause BSD +# license. +# +# +# Input variables: +# +# - Eigen_ROOT_DIR (optional): When specified, header files and libraries +# will be searched for in `${Eigen_ROOT_DIR}/include` and +# `${Eigen_ROOT_DIR}/libs` respectively, and the default CMake search order +# will be ignored. When unspecified, the default CMake search order is used. +# This variable can be specified either as a CMake or environment variable. +# If both are set, preference is given to the CMake variable. +# Use this variable for finding packages installed in a nonstandard location, +# or for enforcing that one of multiple package installations is picked up. +# +# Cache variables (not intended to be used in CMakeLists.txt files) +# +# - Eigen_INCLUDE_DIR: Absolute path to package headers. +# +# +# Output variables: +# +# - Eigen_FOUND: Boolean that indicates if the package was found +# - Eigen_INCLUDE_DIRS: Paths to the necessary header files +# - Eigen_VERSION: Version of Eigen library found +# - Eigen_DEFINITIONS: Definitions to be passed on behalf of eigen +# +# +# Example usage: +# +# # Passing the version means Eigen_FOUND will only be TRUE if a +# # version >= the provided version is found. +# find_package(Eigen 3.1.2) +# if(NOT Eigen_FOUND) +# # Error handling +# endif() +# ... +# add_definitions(${Eigen_DEFINITIONS}) +# ... +# include_directories(${Eigen_INCLUDE_DIRS} ...) +# +############################################################################### + +find_package(PkgConfig) +pkg_check_modules(PC_EIGEN eigen3) +set(EIGEN_DEFINITIONS ${PC_EIGEN_CFLAGS_OTHER}) + + +find_path(EIGEN_INCLUDE_DIR Eigen/Core + HINTS ${PC_EIGEN_INCLUDEDIR} ${PC_EIGEN_INCLUDE_DIRS} + "${Eigen_ROOT_DIR}" "$ENV{EIGEN_ROOT_DIR}" + "${EIGEN_ROOT}" "$ENV{EIGEN_ROOT}" # Backwards Compatibility + PATHS "$ENV{PROGRAMFILES}/Eigen" "$ENV{PROGRAMW6432}/Eigen" + "$ENV{PROGRAMFILES}/Eigen 3.0.0" "$ENV{PROGRAMW6432}/Eigen 3.0.0" + PATH_SUFFIXES eigen3 include/eigen3 include) + +set(EIGEN_INCLUDE_DIRS ${EIGEN_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Eigen DEFAULT_MSG EIGEN_INCLUDE_DIR) + +mark_as_advanced(EIGEN_INCLUDE_DIR) + +if(EIGEN_FOUND) + message(STATUS "Eigen found (include: ${EIGEN_INCLUDE_DIRS})") +endif(EIGEN_FOUND) + + +set(Eigen_INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS}) +set(Eigen_FOUND ${EIGEN_FOUND}) +set(Eigen_VERSION ${EIGEN_VERSION}) +set(Eigen_DEFINITIONS ${EIGEN_DEFINITIONS}) From 2e559e58b67e0cd20d23e75ae6deed798ae5e628 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 11:47:20 +0200 Subject: [PATCH 138/215] default is to build with ROS/Catkin --- svo/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index d45f8aa..8ae6b8d 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -3,7 +3,7 @@ SET(TRACE TRUE) SET(HAVE_G2O TRUE) -SET(USE_ROS FALSE) # Set False if you want to build this package without Catkin +SET(USE_ROS TRUE) # Set FALSE if you want to build this package without Catkin SET(DEBUG_OUTPUT FALSE) # Only relevant if build without ROS ################################################################################ From ec20452f2feb3e2a45915cbc8a24d5f82b628c0a Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 11:51:37 +0200 Subject: [PATCH 139/215] remove rviz node from test launchfile since it doesn't work with everyone (different ROS versions, screen resolutions) --- svo_ros/launch/test_rig3.launch | 2 -- 1 file changed, 2 deletions(-) diff --git a/svo_ros/launch/test_rig3.launch b/svo_ros/launch/test_rig3.launch index fc0671d..e49f9e2 100644 --- a/svo_ros/launch/test_rig3.launch +++ b/svo_ros/launch/test_rig3.launch @@ -18,6 +18,4 @@ - - From 021e747005f200e4c50d39d0181c57d466de63c3 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 11:54:18 +0200 Subject: [PATCH 140/215] cleanup launchfile for live camera --- svo_ros/launch/live.launch | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/svo_ros/launch/live.launch b/svo_ros/launch/live.launch index 8cdf322..7cd0ad8 100644 --- a/svo_ros/launch/live.launch +++ b/svo_ros/launch/live.launch @@ -2,24 +2,15 @@ + + + + + - - - - - + - - - - - - From c364fe9cfaeac524e0ecb8294579b6773acb90f5 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 12:04:47 +0200 Subject: [PATCH 141/215] set default compile flag for HAVE_G2O to FALSE --- svo/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 8ae6b8d..91c5603 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -2,7 +2,7 @@ # user build settings SET(TRACE TRUE) -SET(HAVE_G2O TRUE) +SET(HAVE_G2O FALSE) SET(USE_ROS TRUE) # Set FALSE if you want to build this package without Catkin SET(DEBUG_OUTPUT FALSE) # Only relevant if build without ROS From ae10fe8e233d8e285de7e48f8a2618837fb113de Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 14:12:13 +0200 Subject: [PATCH 142/215] Update README.md --- README.md | 152 ++---------------------------------------------------- 1 file changed, 4 insertions(+), 148 deletions(-) diff --git a/README.md b/README.md index 859a90e..aaf8b86 100644 --- a/README.md +++ b/README.md @@ -29,159 +29,15 @@ If you use SVO in an academic context, please cite the following publication: } -Documentation -------------- +#### Documentation The API is documented here: http://uzh-rpg.github.io/rpg_svo/doc/ -Installation Instructions -------------------------- +#### Instructions -SVO can be used conveniently with ROS (www.ros.org). -We use two workspaces, one for the plain CMake projects `Sophus`, `Fast` and optionally `g2o` and another workspace for the ROS-Catkin projects `rpg_vikit` and `rpg_svo`. Make sure to clone in the right folder. +See the Wiki for more instructions. https://github.com/uzh-rpg/rpg_svo/wiki -#### Sophus - Lie groups - -Sophus by Hauke Strasdat implements Lie groups that we need to describe rigid body transformations. Checkout in your workspace for plain CMake projects. - - cd workspace - git clone https://github.com/strasdat/Sophus.git - cd Sophus - git checkout a621ff - mkdir build - cd build - cmake .. - make - -You don't need to install the library since `cmake ..` writes the package location to `~.cmake/packages/` where CMake can later find it. - -#### Fast - Corner Detector - -The Fast detector by Edward Rosten is used to detect corners. -To simplify installation we provide a CMake package that contains the fast detector from the libCVD library (http://www.edwardrosten.com/cvd/). - - cd workspace - git clone https://github.com/uzh-rpg/fast.git - cd fast - mkdir build - cd build - cmake .. - make - -#### g2o - General Graph Optimization _OPTIONAL_ - -Only required if you want to run bundle adjustment. It is not necessary for visual odometry. In fact, we don't run it on our MAVs. -g2o requires the following system dependencies: `cmake, libeigen3-dev, libsuitesparse-dev, libqt4-dev, qt4-qmake, libqglviewer-qt4-dev`, install them with `apt-get` - -I suggest an out-of-source build of g2o: - - cd workspace - git clone https://github.com/RainerKuemmerle/g2o.git - cd g2o - mkdir build - cd build - cmake .. - make - sudo make install - -If you don't want to make a system install, then you can replace the cmake command with `cmake .. -DCMAKE_INSTALL_PREFIX:PATH=$HOME/installdir` - -#### vikit - Some useful tools that we need - -vikit for contains camera models, some math and interpolation functions that SVO needs. -vikit is a catkin project, therefore, download it into your catkin workspace source folder. - - cd catkin_ws/src - git clone https://github.com/uzh-rpg/rpg_vikit.git - -#### ROS dependencies - -Sometimes `cmake-modules` is missing (required for including Eigen in ROS Indigo): - - sudo apt-get install ros-hydro-cmake-modules - -(replace `hydro` with your distribution). - -#### SVO - -Now we are ready to build SVO. -Clone it into your catkin workspace - - cd catkin_ws/src - git clone https://github.com/uzh-rpg/rpg_svo.git - -If you installed g2o then set `HAVE_G2O` in `svo/CMakeLists.txt` to TRUE. - -Finally, build: - - catkin_make - - -Run SVO on a Dataset -------------------------- - -Download this example dataset: [rpg.ifi.uzh.ch/datasets/airground_rig_s3_2013-03-18_21-38-48.bag](http://rpg.ifi.uzh.ch/datasets/airground_rig_s3_2013-03-18_21-38-48.bag) - -Open a new console and start SVO with the prepared launchfile: - - roslaunch svo_ros test_rig3.launch - -Now you are ready to start the rosbag. Open a new console and change to the directory where you have downloaded the example dataset. Then type: - - rosbag play airground_rig_s3_2013-03-18_21-38-48.bag - -Now you should see the video with tracked features (green) and in RViz how the camera moves. -If you want to see the number of tracked features, fps and tracking quality, run the GUI. - -SVO GUI -------- - -Type `rosrun rqt_svo rqt_svo` to run the SVO widget that displays the number of tracked features, the frame rate and provides some interface buttons. - -If the widget is not found, try this: - - rm ~/.config/ros.org/rqt_gui.ini - rosrun rqt_svo rqt_svo - - -Keyboard Shortcuts ------------------- - -Make sure to active the console window when pressing the keys. - -* `s` Start/Restart -* `q` Quit -* `r` Reset - -Camera Calibration ------------------- - -You need a calibrated camera to run SVO. We use the Matrix Vision Bluefox cameras in our lab, which have VGA resolution and global shutter. -SVO supports three camera models: - -1. The `ATAN` model - our preference - which is also used by _PTAM_. This model uses the _FOV_ distortion model of "Devernay and Faugeras, Straight lines have to be straight, 2001". You can calibrate your camera with this model by using the calibration tool in this package: https://github.com/ethz-asl/ethzasl_ptam We prefer this model because the projection and unprojection can be computed faster than with the other models. Further, the industrial cameras that we use have neglectable tangential distortion. -2. The `Pinhole` model with three radial and two tangential distortion parameters. This model is standard in OpenCV and ROS. You can use the ROS camera calibration tool: http://wiki.ros.org/camera_calibration -3. The `Ocam` model by Davide Scaramuzza which can be used to model cameras with high field of view or even omnidirectional cameras. Use the OCamCalib toolbox to calibrate your camera: http://rpg.ifi.uzh.ch/software_datasets.html -Although SVO can be used with this camera model, the algorithm does not work yet with omnidirectional cameras. - -We save the calibration in _YAML_ format (see examples in `svo_ros/param`) and include it in the launchfiles (see examples in `svo_ros/launch`). - -Parameter Settings ------------------- - -A description of all parameters which can be set via the launchfile is provided in `svo/include/config.h`. The default parameters can be viewed in `svo/src/config.cpp`. Moreover, some additional parameters (mainly rostopic names etc.) are read from the ros parameter server in `svo_ros/vo_node.cpp`. - -#### Forward motions - -The current keyframe selection criterion is designed for downward looking cameras. This is one reason why SVO does not work well for forward motions (e.g., to be used on a car). - -#### Image resolution - -The current parameters are tuned for WVGA resolution. If you use a higher resolution camera, then the pyramid levels should be increased as well as the reprojection error thresholds. - - -Contributing ------------- +#### Contributing You are very welcome to contribute to SVO by opening a pull request via Github. I try to follow the ROS C++ style guide http://wiki.ros.org/CppStyleGuide From 9b22a4c627666f31b43f24f649c46df1b575cdff Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 14:47:01 +0200 Subject: [PATCH 143/215] added figures to illustrate notation --- svo/doc/notation.ipe | 312 +++++++++++++++++++++++++++++++++++++++++++ svo/doc/notation.pdf | Bin 0 -> 50379 bytes svo/doc/notation.png | Bin 0 -> 27376 bytes 3 files changed, 312 insertions(+) create mode 100644 svo/doc/notation.ipe create mode 100644 svo/doc/notation.pdf create mode 100644 svo/doc/notation.png diff --git a/svo/doc/notation.ipe b/svo/doc/notation.ipe new file mode 100644 index 0000000..f8c1efe --- /dev/null +++ b/svo/doc/notation.ipe @@ -0,0 +1,312 @@ + + + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + +0.6 0 0 0.6 0 0 e + + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + +0.4 0 0 0.4 0 0 e + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + + + +-0.43 -0.57 m +0.57 0.43 l +0.43 0.57 l +-0.57 -0.43 l +h + + +-0.43 0.57 m +0.57 -0.43 l +0.43 -0.57 l +-0.57 0.43 l +h + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +-1 0.333 m +0 0 l +-1 -0.333 l + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$_w\mathtt{p}$ +$\overrightarrow{\mathcal{F}}_w$ + +64 576 m +96 576 l + + +64 576 m +64 608 l + + +64 576 m +80 592 l + + +144 688 m +176 688 l + + +144 688 m +144 720 l + + +144 688 m +160 704 l + + +285.262 759.615 m +162.017 735.456 +129.232 628.801 s + + +$\mathtt{T}_{f,w}$ + +128.441 626.745 m +320.625 647.224 l + + +331.681 587.399 m +331.681 587.399 l + +$x$ +$z$ +$y$ + +256 736 m +224 704 l +320 704 l +352 736 l +h + + +285.262 759.265 m +322.176 651.119 l + +$\mathtt{px}$ + +285.612 758.915 m +315.723 669.632 l + +$\mathtt{f}$ +$\overrightarrow{\mathcal{F}}_f$ + +255.668 719.918 m +274.728 719.957 l + + +256.107 720.028 m +246.655 710.527 l + +$v$ +$u$ + +$\mathbf{p}$ +$_f\mathtt{p}$ + + diff --git a/svo/doc/notation.pdf b/svo/doc/notation.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3bc3fcd1e26432ecb0bbd75ccac1399691cf3da1 GIT binary patch literal 50379 zcmc$`Ram9J_UDPaYvCJrcXxMpcPQK)3Wvho-QC@xkiy;F-MwI_-|6%3)6+fEb20PG z#m>%JNmjCw_r2Kr`*}jDARR zfZo{ftK{Q@;o}3C+M0azgkkxQ5h@<`rT}^cLuY4GM_ZVGSN`!b{xvOao&PbIVCYpW zzgyax|JxE0vU3M$e??*dd`$>o0qDZeYbZOL+5xor=s4Ke7?@ZA|55oe01RKjWK3<%oh<-NUnz)Le*aqD*Y|fr zXHyYVV>=VmzpU z|6|twmGD35|7Yg^pJdJUA6b8$GAHZTNihJF{yAw*Ho)IaQTmTZgZ)3c|LXu40gNn6 zU#I^siwVHS#LoV2>+8|`cNM_S#KQW&KdC5ZaFu!MC3?!RAPK1vB;jE=-C4j!**pUr z!yp_ZOBf(3D3^t3V?#oM9cnfgfT9#nG{Jt#dG#{sb*1%Gt$D^jb@|8Z(T-n0%!U_V z)4C8{20C2e#@|D57svx19vvA7ili470$lqA>>o1z5qw4a^@L$iUE{HjD!bY#TCQ@WWN4JpvRBfNyW@4?!=09`4_U40I4T zxmj(m&5hPRz9kOCod^nqfr`5Gfrk+5@}sRk4+%^F^hbRlXCAc>VKfjg2^xa1$0s#- zM0C-w;oD(beMl5&C;M=M?gPlpKsc?$aJfZ=laaSV4xj+2GyP~Jadr|e{9WJxZlTI) zgdXltphOcFAS9OFp6xb4-JMAac0KmiJ^C>3p4nVGO=Lsb7-z>HgbKD`J+I3C9sRk- z)=!6T%$ks3v#2|7DF&e88f)($h8LIP=KlU2tph4(AC7_*P#-fZ{R%*Yv87@D6#PJk zAYbQl@$6f)^yC`yhwX=7*$mXXPgdL{5Dp7eD*rk}$OrMYOQ3r%5QVy1YR}at+q*Uq zP$2N4Jq3&bctbET)W>MF+Q9dZk>j0?{w^SS0gKB3;9UKl&&=`Z`+6}V+^$cDPhNdK zPCQy;c;agQuutQJ1Yu8LZ;xIed|yH&AUF(QP?2fKPe1b)#E+i3&qXWYZNCSISMofV zeh6rwzz+if{mm^7o{xO+H+|{>;Ab~zS(5bM3_x%E^X%Zz0lCMB&!1kvzM=11?w{1Z zKO3&ZgQSL_LWlMcyCIp6Z3Aj*|E(_b5*CxP>CZ5QfX_76Q^| z@U*Ei)a!Xc*xnNbC>|pLVK?yiLYzolTaOzc@%vx3T*g3QfL?oiV0@}VoL-(rT<)=R zPxHRhe)<9%FwlQXG_b{nPJ(K#L9pelN-TQV*ThL0+>qvDJv_piU>z2Jppet>4qy5$ zk)uwnmVO37own9uJ=T`l{leq4-=Q_2a7OFiKahJrk=#dR`+5lG#MJjhjyK05Ni3GE zn7`kj!|5pJR6R6S$UkF zUitd46ck;y!la&Ql;h`Ph#gm$HdaWs;wpx8rRm_-W>@PM*O<{wOr@|uY+;i_iY8i4 zF(Y3B2vav~O_lXd)7-Ah@|;>aMNZ3P8cu+Y4(e}hYQ!(F$@H&{5G;8(c6q`LpEQ45 z8%jB;&-r0}5-gcHN9z*ewbZ?&f(K4lj?cUfr(_JdX%$Y3xt!v0XF&d>&;~A|zO$?= z1jnF}=T+(!4HQXGvYBmo&A1(7NRx$C3DCf?&A%ELUn4}U`gIVROE|!@Q@?_Z-7wLX-$Ii=n(;h1 z*yzCQjPvc11Alp6$Le>iKo?FIH7UI-TDW)$I6OyehacZ zZN>_oUi+xG@vwXpvtsq9nhNITVTUHk!={a6GXuMF<>B2_9SL5udhevp9j4o_h*P5F zvCAsMj?S5qR^GA?;Y(76LKJ#jUxR&#x+SWbgy4N8bCLIfL02Qv3ea8pq919`mgzp-RG8ls{C7~t`mWlG zgMO%x(T}NO6ttF){0U12IyY#ez|&PTu{5^#cd@Lq9J^~L)ejb9Cjc^&W1BIzc(my! zNN1}`UkRl>ZxiGcHhMl=PQg_Z)g-w# ze$ktT9_OcC#e1DcLY5l)y=aORg9eX7=-IvIYdl8iaebgys9)Ec2NK=79kC;7nnM2j zhjfT*F-~KilM^#>B>=TlL&HeA6h`U0F?rrLR({5A@%umtbzUG9!m zugCLR0GWLXJ!9r2KDe9?!;5uOWQEO)?NwiuX7P(&VCC7Gj-^k{(a>+LK+yV}SZQOO z_~JKs4oL|*%j*gGH6gvrb7aDcS!kufD4q~&NQ^XFsR~Js^MnR6XDzk@`baX~Go^-a zhO)?tD6H-cQmgy@V++{sGjcKbI9p*S?gpA2I(A_r{FEr?@_xo9zY=YdfTCqWt@Omo zb#8z?x_k1p`&(m)sx76A@wm$DEam)|;_U;f^z0*at(lmvv+J@%vRa}vZeYiWv_E8f zsP83$EweR8Ru~h5TTPpYf36(YM>2hXJ9RHE;aQ7K_(`^rc~n=QrMbSM+A5av@XflY z1pfBLYGV%@wkFZD>byOsBqlZlTHpT~OOfC=`+mGn9&Mh9=Wi9Cx9;;t<4&t~GJ4-e zeI+3>2b4M#l;iwbMlw6t zi=LX-G!Q#9q?{R#<3}4J!CgfFEU=r;GJzBm=RSUjgqPCq$>3vmr_ zo(`79W2MxE4lty8I%Pj*Izwf<=u1zqgg0(Q!AM8;9;BovVp58gRXL$K;)%wsKbb|a zqLsaya!3y>-m)G%CmWdj=y^LM3ofuwqFdNM}FEzgnlx5bOU;HTG1HQ zzQhh1%C@_nk-o)8;ibKZ)i?vGh?Yd^(?qh>N_a90(sn`3MFi2 zeKV73MG;3g#d6Tv14JmCD4XgpT9%@p3-|uMU$(4Tt6rLi4Ms#3Q8lFuL+mUR#h#!| zeXgO_Fj9F?ir8hjsPEBHLweAfdMGj?&AP|=?IeC(7dynnaL%pJf)X802_5AMYH7N( zNe}6RV2y}GX@Rei{k_zYOfO;dRS6}ey={OMOBo4O@wV|#*mFf2V20bad|$EH;Lrrj zSobWZlh6kwjC6r$Jd|(8v)KEGE(X8!l6i0)va%Y!xmM7GYjR# zY=K!r8Wr3=X6ZgDM;J*x z%F&-zlVbe)(xqAs-_{|Cqpd0uvj);QKnWhMv{w5~=-54Dm-r8c$wUTnB4MgfSbB=^ zhHc+iENQ|f2MGOiG09}A)}@HV6hZ|y#EcCwk@cEhnad< z+3p3%)h0`Y?j+$Hw>CWx@z;{zYjvBA>}Nccq>A`-qgeu zYL6`m%ezfoZhNONvn}K2Wp)n1R>d<*!YzL4k;Ru;h+1h3@<*+wsjL%^i0|VyV*+)zVutNZ%tOO9Fl^ zc)WD8G|8#?c#SjpG@su9vu$QfJ4~vYkvH;e2%|i}$BW_(nqRnvA2a3=FC>y6gZmWL zNa_sHvrhdx9RJY!xDDz#9tRrOH^|0eRmXX6j_v-2gFdYE0{rxf-JkZayHogf0=RA! zHsghFMFB5^{%F8UZ#)Z-Qj5^@#=XtyBPg#s@He4r7q$aV*?T0$H+kMp3M}=4eU{pY{jU&i$diY_V=E zU>%QoDU+>#xRo-c3@4Mb6B@rdAL-mC{hi~IVH>@ckl$p;Qjn3QNb19Vqxf-IP$A`Z zdN@IeH6D9E3P~DY6ijO(ud&N#8UIF%eOCkgD2m-Y*GmK=yp6Cp=JLz2m+4 zWHbH<-CQWgs5`zyvxf*eRl&_Dv6NH4VDfCNjSsD}=lmUCuD+(`hjcOKw`^D2SDDk* z-=5j+DZ(OYis^w#bedkRdxPMDZ8UC-{5`&MA4>Ane*!T?ACt#_*FToFyERs97T$Mn z>lS6l8+Hy>AK}IwN?8R=y{mf2^N&m;!o0@POa!j!`KTfp^f|Up;X$oVl^jb{Ck9Os7vW{Et)I*4PZ8h{QP~N;~wCl%kf*RVH-ogg0*KG7k z6Uygdp`vPpOB$sR-SIYC6F!Rz+3oX3px`GEVQ?=iIe6e8M#rdZ6HqNgsPNSX4PWRZ zG+%7!RNOpbQ`B0jH@r<(E{w!;zPyFulkaFX%pG8Lhk>%P%k+lS$7k8!TQ`Y#+Z_vJ z*wDoQwCR#`iSz>L*QKgwY7jBrpa!HlxSZ9<@8D=euUvcE`7XoGL@9`2aPJZ`OXqG zAc*oz&%HzKrPA>d_^qiMOC|~iG-#!~Iirs#JL<}nbN}(+>NTR#UMmqdUpBOX9zIws zga{>+LYp@07HoS+C|#Xbq-A5quAqS;?f>4~o~7$OC4JXanfIfamrABYu9+!W#ZS%| zrJf+0D?(m{M!bq+1FhZ+n09y}sx9N!Rh~!9lH!R|IxwjAUU|#bYc7%4B=kxq&;_Ya zQaH+Om1#*@1CAhx;-Iy`@0;HAsUIMU84P9`m&3CG`&kF-F?E|6uWIae)Ylx=@Djg% zvWEtF-^#z_in-0z3|I-IcC2p6dql?6T1xeEKe4mMryLfHjul+aw*vbC`c6%IbmgW|w1Y#F47O~zsEuPO3V50)GqP|JmQ=Vl`HWuP-oU{!Z@mLEnlG*!woXk*VXpa4`m zZiL4^`0zk-l-t%nppZBeVuyxg^ zjh<@EA0yh#pGDcd)lR*<&HM4f0)jeLdOPgoeFdn5<)Y${@{LI2AxcP;i?2s0hQef5qEi81H-DxUq+Vmmvm(k2!)%3(ah5K>g*EvR#Io>up z3+AG(rI`AU=f0eX8p3$nM5xDlkT}=aHD*5$Mk%jfF#b8sfn9IKd87YD5bcbST)3Gq zmCG`vS4ZBip|7S@SH)*>&x*z4R2eAib?rgN`4sf}u}rYhjO%suNk^-xkQ*&nR?sf( z?}HMG(a)kql$CaeR8QaVP0Mi!?kf|Mm4;6UN`a?EL80WLpqeEmVmB$3$cpCoMRORY!NeSZr|wXWLB+n@Moa zv~M1;BS^5+h*PV_5*tW9Oeox592+^If?oJ~G~yNx@zu283a;F--!#S~7*eCDFxw!fk&P7t%XTgH48(kmcmJ);P*5vQAm|Ib)d5{&o zd>DaU#$BZ(0p-~Qt!pHWO~g3&g?r|S`nslrT* z96uF{bCluiv$=<}L9OhIAu zuV~;zQKTp#4KuaJhavf!p0a*dx+kL2=z)3SAuKfOCPYF6UpXsI1@{XVO7{X@R|^j0*619T$!lbKl;1X=~Ax+^!>I6qs$>QV=udWyEIiSUS3 zk$P`}mLsBXd~_w>rr)o_os_t!^K<1m{3+t1vRh^JhVu7GLj9oEFX(QVZCSLT?nbS) zVf0+9ktZ&%Vvqh0C(p45GSP2y{(xz9-!;s$k>(POjCN=~S_gT4>A+DTlt^{WIRQ!! zHo|iQn$8aH_Xi>gX3?z3sk)O*^{l)srW7{gTdW_aT`W_3H^@!}HdB|s{}|zcGoLnA zmoVkaujn)C@@Ka)jpQPoN~jw5XCf(0_wW(ygxME#q3^to|yE5Nq++Fm^!%+T9IdO=g_`hzRZpuq{XN z34LH9nb}RFsVS%T`*<5`Cr}1AD5lYqC_7q(VrTDY=jwrlO?{PcOMXhk>)10DSLyq~ z0=Y3X-=rP`dNgTgln=w9#AIf7QWUvZ8sJH0pnHMi+NU?US7gQ8^mCL==*HK{zv!b` zdncjYvp()+9MSoCAst;>S(4!mT`$;9_-P$B?DE?B1T04A(j0$H_#wV34c2-pR({+y zjq9=H&)ykGhu&_4UFf;PrBeKoM_^d<+MgbByQ|H1IwgiZG4W<^T{$Low5a)1KJW|Z7;RhkS<~!^A^ul%R3&r-O41fUu7k~@E!~6BRN2Dd#!a0J22=PK3(^; z^8%x9gUHehe@9PxyupTj}rISFiSxUK2vID4pE%XTfe^1eA?)t#Wt z$v5wd6TwQB?;Lq4&8d_rHEQI=gwurpU>ruh8dO~p7@7DQI4tQB-U-a6%JoQ^<;lWd zus@uSw_El(u__%dg|Qy|*aFhVOp*Qg#4pup;v^+srx>?kNe9w=Z0lB1G|%}Vg4n9svYULR1x2+wuiigUJ1IjvamKdVJK2 z7;=5RnIllebynj1K3rFq2yI-mECjh_QL5SS4Sbd|Z8`MF*`FpDP49)}#R-D5(WKbM z3R>^rZ4o{t*77Lr*rgm|kQ`^vQ@(2q&9`MetM+9Z6;b~EUHz$}aF1>XC0^O)qRKS- z+tyX1Sv;J6qa{PyQ`7ec6%+A(X#MH^y(bC@8&Jl+GuPtY2^QCwTDavces#6Qg%1VC8 znP0-Pxf9?^uKwHMU&=NuBY>8P^-J7lWM>4hv;I}21)YpdZJhyZoL?P<4ecdNEzK>y zOb%uk`oEL>ZKGxU+bHR5_}$W2(ANCB>6hor@uh~_r~x>>6m^aNHj0J$%Mi9ObW}EV z22jwO(YsOpYxXa#+Z6CuhW$@jmh*p^*;iZ_Bjnn8~R6p#w32eGdsnFK)3!Cn%uF@c!{rVt`t2l8NB1Umxakb0x~kgdQ2@@$oK z3>J|{wu`w1)HUIA!~J_dpw!-o{Xwsf4uAx7az7K_nBUY1DbC%Pmd9W&gMbEjav8M! z;pdS-rd1U7ggOd1feca~Y6NPDVSE!1UBQL%`jXj!dtwkEC?u>wd)eVW_e1N2gpe)J zFkw!gBZ;4CnAn$S5F3(%xj6+5EYSLD?nVXUkSa2~p0+=nS`ippamLT+O+bS+*WU9D zFMez&KueyyiMeKfBKO#}Jn#sX@P_%EA2G^e5SIwoyZZ;g z_P5udzyLrFlEC$0-_e%KhZCq@-KWh0i0~)R20s09ypE z6jH#a2z84;@~h52kmmH~T2FSMf(0A5DUNF}r(`jZp7pykHX0mTJ=$_@%^pKxf3|Ci z++W>%^v7nXzCCg78>-o#>2r?`&;tPx#~C30z>!=B`1)fWn|V|bUiPpeZXf>Wn_;K) z$C=~mA1p;b@6ewCYn4;eVm!^68pIn63&Du3KO^SP0QJE@Zvdsv3a9?{Hc>b-OV?` z$(WE{2}uR|`;3K64ULp~K`uJm^M@$phRI6FQ_`pZt-~T_NvVI5eS*3qc3F(dkd{2O z(FRpmis#$gp+x&JSO2@Jj=uMXDU49UNaW+p*v*dGxA6lcT@&%7H=w7z={_%0NOVT!;> zw9?tP;Cgyz1ggG(FC`l_t3Vo)u3U2L7cnorCg;5IP>qy&&)Ym>Po#YlbpLl>oivGh zs?Q*zEStGuGC)b_D5LRZ7^{7M?63yKO0}qbzJc7cX+sV&H2syXx`ksKAF|ssxrRTUEr^CY@qE!3?2R8czT)qLlYIXB=Eu}O_mb*DbtR_?d>Ci>;?VyiB> zYwsMUDGc(Diz3VT5&Kpsf4;j3GwtKwP*T;0>M>(x>g_@Z1j$BX+Qw*>CMlVC&&qHQ zz1j@!&^nRt15?dB^eqg^z}R46TJq;cRd4wa#x~6$U7Q<1sVF&|)qYYe*&qi>yBIr|DMHSsVBG>}5N-O;7PHC9p^4R<>v8KzO4Z$ET8=naV3s5(VG zPjV@#f7*0Lm>IpvNyoMF&-S=v$n_>|<9vvWR2G5l zDkFb2m|89l;J=cF{cY`sFw_p z<#O9(_J&yXVB!*H@;%#h8)&!6_66h7z2xcIM^~%p5b2p{RGLU*>?+HCR}A$jm(wq$ ze@bxbUr>#Z6|iEu=`5HoFPYJy$$te<(+Y?8ZM#oywP)vT%Fn0MldIEzZkqcdM<+3> zJBm>+P&~F#&X8vlKRHD8Q%mq(aRK4)TgK40yGZ+IdC`D({~$`7N)J&D*90LYBp{D5 z9u#J?Nk1KOy-=km8cxH-#*4v7oj}Y?l?hi4Qs?LZsqf*l2daSQDaq!RUBsCI@$k7P zFCYsw?TN@7S4q98pZ8*4HVQ<&H|6daKTBF&#*miq;uh>t47rx_>ziG2q zdcj$sPq&i!(wI;k^{YV@0(xU{0gGMg+FgJuIlBCyPJWujS`)#7%*?h2wJ2u>w{@SC z5xFl*SL;S>5xV;sonu_*^bVWxt@kw}1rIz&gu;@dIxRz|uNqC{tv9_C)*2PA$(PHj znPfqYJUp}&^Z>o6>M`ZSHoiD8Gl&12m!mU~^|e%H!OD0d(|=oFcXuEd-&=(zCM&t} zW}r7sJbTMr3=9iFIpTwXwzaorl|E2E;|Qw;%2W(gHfLFRNRfVev?(coNtHAisDe}J z&&(*bb8b_Pey?}kFEyl?GIX>~@4*&7+HPU?AQ_LdQ$}q=^Iw~Jg|BU6Yx~=CbLzGx zF7v0_ZJoI1F1mTu?|eE#Fa6+%R1Nsh{@PZOVE}n{C7=8{u+8h|QV1ZwR2&s0xE}c7 zEWCX>G>a!Zckp$m*l_rhHph3u9gGfxM#@Lg6H5`(DH}KSSvM0t-wK#a8OxYino%r` zGakJCMi-iyeAX@zoJWr+T`Yv43Tzc|Z__;v?-EMLNLHt%$JujBjArA$)gje|=SuJ` z5y*GyrmNGroysU@&)p+B%zeVvETC6MrkJwArAst zNsQUj-9umr7}X={BXr~f?uHqW5!UMtXwct7-S~c@XD!P5_CM9^>Zo{GT~{vOa_1-( z-vFjfr?Z8GeEaiOYts8lJ9KH=n?Ckk?0)(x9Vo8C2=Ff7$jFB`BeJ<3#4Uo)T%ELa z3xG>)WlJLlL*C9JdS%RlQpqT*Em`nnydSZSX`+3C7;Qc&8hHZM$o}%93@xQA?UVpD|R4XKGu~tYq$>SmZokM0LU3A^(_9 zwYX*3;Q%e;_?5tG)~$xl8m;)9RP2vWqM$f262o+2@vTfDS!t%?>Xy%dknb<))vq%o z&gQq5KSe;0C8tIlMwYns{ch{!*O;+g%|>isszMnrqP(t5nOG=-=pGS6*z^?b#!H97 z)A`A37v)qG&C2cM&b?QMU&G`3C5Jt-&N~-(9oUqMXDb8C9p8 zDSj3QD?T;GZg_}ewdy!YBIgpcRiUyfP^pL#kYta~*Ux-2-r+4j&dc_3UDVkH+^i09 zyufF{AW%cqCvf5Tb8A3hVQtRtyC13Ll2C!5GX?K?O4F*^k;&@Auoq zLxcuahUr7{ab!;4zwHwNv50CuqYmPexRf@1ry;*gBYdE}dRpLP)!-MLc3(90v(-iRn>vuC~@qR)ljGocS zyf2DPXgoR^usdm~(qQ$=8Kkbi<|F8Wy->&gh$90*X8lQ*iRrX|H z$v$cNUQ;33xKMly=-*aP?RaI~@WzVMD+R&^Pq z%`RH0iM`x;b3^`fYBjWxheIvC%>x6FD=>w#akcEc@4MDccYJ9aFPfbG+p6-5*?ZuK z)wG+BXR%vw&Fj#6v9xZRS0>QyEJSNcld@-N65UbW=1kh3A48#M^haDst-;pkj?A;K zz(TigBO)H6?GuIP*FKr$?8>qs%i>|V;XaU=nf^O`C*M7d7N?3&D^%u4p02}3V-E8t z-hYdcv!a&c9*OgLhRxxlrFq=`4t-PhVAAdSR=cVPgurneLX^KLd1bVUPNWzVa3w@j zs~WOfjoYu44uO7fL8h@tdIbpv;y9W-W=Vs>q*fR-@GX9aOv%c@po>Hqk7eh{E87M= zrfh{f`av|1<3PNu2jW-X)~V*#&%!$DTGL@~#5!}=sP3s7fbUK=YS@Bo(;|xS3$jq}Q;3ejw z*eh?G(DOvJWW6j!lHA8Yw^XIMnitfx;}WX%3@r`_2p9ye9nIM}XL3j6*XP%}7?X_z zp&gu35RTUMyD%Ks#P)V92Ubkz3qm|=)w+*hDVY*Fh2UDemrpGfJ}H^9?IAk6r%Z~@ zT0{q?6mT&!qo&9!0_UQK)^Njad`w9a4#Wxbt&)Z2lf+Yo2O%kxi%t#cP)qIp4l6<0`hLe^+vbrV5+&yXFTqB|H?4?U}DbPA6JxfT31G_>E143jFNw$U{pKO7-dY zi0#7fg=v*CkB-Zpq;1bUOrG;Z4lz6%Gi^VUhMl`Jte#AR`~7j{eTsw+N3^c@>aqOZhCiNB|XjB@H(8IsL4^V-5`CBT9244@{({x+^1 z9DDI9FuKnMkI;rF{+?RVU6}bTV@qH++EQ=TbTcNXrK7G$AA=2z|1sWq(9oEr@RYHN zx`Ke#E6A`AM)BIAV$MUIt&!0zTpLQ^$-vlXIQJ?Z9+vZ-Kj^S>FHAF=tk9fwgGggE zAI{@eLFL_c)n;hrXo@#D4BRCSDmmAxSREm>LRg8~-35Hq(7>f9_9+~31naGWaPw#s zG8tVTzZhv#umT)5N)0&SRk&097rQnqK|L*(-@8<0tp6|h`SJd7bhnyGyUSk)8EtQ6 zz1~&Y?_AN(w~|Ujsm0ez0LvV~u_dyg-}q)v9D^GZ1Kd*gbz5Rh^xYWKgRsphX`0CK zaEab87ZtdVYfwMGY3+@GBDOtG*|f@qfFJ&>OE%m-6R~4wLotmk@-od*U|7ak5A+-! zEsDAripHFVGxG&etMqAOt$!Dzmlc!?$5lzy8jrw z3)LonFjq{FtwxCoiB6pPU12;&4njGyvdF3|oI0f0(9TwuFm$M`;Qtm_D|1zao@D6Bq23yNqph$RGT@KW_V9S;!SfMb(CB7nlA6_Ei$4DR=?2;8>(0rV zxX_O@U)cgzF+38EIQ`=1ea$z4WEuAbBa5|ScVc|*-?=^62H~++ciR@f_UnqW*@lCj zgzlftPAWRKSXaw3+0mR$<_>FD#dWlOO-qoT#6sunHKK-qB|8G5;klEVgee#U&Dej= z>P>6B-&lLPzEXgf`*)E{=1;DqE5{#Y+kg0XzqiF>pDEE8y&O3l{h`U)r{~+bM?1{o zQMcZW2V0zUlB*s+)*9LDb0<88n~|O)sFTleZCt2_c%SHlL>vZ|(WZlS~ zG@k58_=)9zVwcrRLw*ldK_8v)1G4`1Ua}3D{qOwpUs74*_WQB4=GL#?s&$5UNSM}3Ox7q#B z>X5MMGo6Ux<`#AsjGKE>%w;ulXPPweDf8_ec;C@8lsphO^>$C6mG~Q0V`!<(d+fFw zL3Gu)m@;juneAN>Io2lb6!dx@bL}k7$qKi@cAs%PDSn4T{ zH(M=Xl+|Geh!-&XR>^qrDwoU~m&f`Bz(WjFk^a~@W`22l;2o3Y1|i2i8uP@H=|ff@ zz_-i^^c&nzk`fWfSgeMxJZF-n#M3mx)TefyjAZE|UmRaEFgk}FGLA*1?1v)mgEBE2 z7$k*Mt}ZO=7}kA!;A2vk=1M5^v6CJ1B}3r>U*BOwcQ*gCIUWk2SwgWgEIDYu7?V#4 z$F4=={#nVWI)?yqS(`IoVM{KmEN#BsN1G+*Uw#U@o}rGqSlQv-D!c={UJLoB(y>m-@UeR56NLLGa` zRmB3jGZA(N?wKMfp$xixm-O`b2b-vh=dg4m0*Ws4D}HxoTqjEh5hrZd+6{9?hc7sefeGK=O~j zC}b4Im%lmeETWP$mf~eIdN;zS+sMnSb|02@w3|y-kXOH$R;@p+RCy&a>C$A{~c~rSL9LrHsV2O&eKL&M4Q#eP7 zW?5mVNU&#KP{ZM#l19_!M{%1>jYYE71?SqFbKaqXb*6HDCEhQRwM-JL-}tNNiMbWz zUAJb)9L3r^#0e_irp2cYZb_8RS85g0VZI(H3H?P|br%t@m2v!-s!j|@Z7+}g{NA44 zi*n=!%3hesJ#(cpI)?~p+G^U|dhVYi?5G{wVpcOD!sBj6-vf-S*olt=9LN_$?mb84 zU(TJ)4#MR8Z~&=oTzeix?M%_`nrWuSkQI4dwsKneSW;K#eBGUpc>zFfg8tcO(a7$}dwW$i{vciU~!=3Vvi-NNn{tqj2uJ3{=As4MFH z9yj7PC8<3kUV#em_z)6JeMFogKT(-&kMZ#baxd#2CCZ>uB(QUuAj-nqob&XN_r%rt zlMuh*cI>vz`)HC_72y=!!-o}*;JbScwwi7tfF9fk^9jb3V<$~5)1khJ-Cglu7Yt>N z-VoBxrr}4&gu_8sax>d8YHfz6j0pRI>?^v`f;Wo~5>y9rdNJ5hFGfypnv#2jeqC{|@C zvGwtrnprQDjd7v4B^PL|xTsn$;JQz~UG=8ZORCb9GMvd!=@MdX3vsKLIS8UA;lv$| z8LhEjAX@Y^1g~hbJ(!|6qFI5z;Y@;M>1&^zAyjmxr6S+lz<{wu1@RFrC__Fz&`!Cd zvT--1dZnlw?ALv_`Jn_FbrEm5G8C(1TiDtxM~IazeG|d*pgv5zzDV2f&UdfrDy%q; zbS!*(a{1$YEv^)%WQ=fERCHa{RhGu4Fy(X(lo>OTN?7RK7$?SN)DnI-JeX`9FQ3{h zV}l)|nYPs6Ai^lEheZXfdd9u((F0Y097{UOa*Dm-GL%KWZaFN-_@l}(c}AxwBf zma4;|<*JX7gOvgItqx4clLZe>L_~)0i;o$Lk}0aX@n$-{Au>-pKzN%K`D zCDiVQk`NOvz0zSmg>_myLEY3hal~4+6zwZi`Efh1Y&ZwHpZ+i56rG)L<9sO_9(9c9 zEbD!>uNQl|$B@ihk2yYZA$e7ixa1_o1B`@|1P4mD!cG`Mnw9q5g7eh)J&I%LwCIb~ zaN-K7%IsXagFO4c=M;4vOJYlY*2e&Lk$sjlW*gax?)fN_*D3sUYbgh2Y(|?lB(TZI zNv)O!_)%Fvacf#Ui=mJ(H#1=ksyD{mHIf*af-LO9XczNyF~&DA5V#i4@l)z?=|>Jz~{3FJR#Z zbKdjCm~L(gma-X?5-5a;Z#P?}5+LDcg5M-Zh);Q6<3%%5?LU}rMh9uKv5;j`9B%(` z#*PL%773{U-Kzy-*THz}Avv}uCAv5e0vQw_^q)Bb=RU_li=Zz=Pa;uKEi0EC;;%N~ zIdXniG>kU!v7r2XU-Yj0Endyo(S(YHepZ-@RP0|in0iG`zBc*?dMWbqh%$lzjgOhj zZR0dGbFh&xic*=I$XCK`Fq z4~TTY+x&m#X&4#*1Ht&;0W}(O>SBV@{{S_NU$+AMuZS9ErvHZ2FtBj^zl7AVf6*-e z7f6k(KVcZc^g)iul^h?oL?R`4u&reCp*JePYwp=zj4@@zGh@& zVFIvo{%vDt{ioj-!SluLaIkz4Icyw%d$4jae~ss4`Rn0e`nv+we`5V@Wdkt(!}t7W z`Oh^Y{}e2YY+oy7{TjmtU}5?f_47|eroWebu&}ZIAB??aRGd$qzm3y4B)Ge~6Wrb1 z-Q5Z9?gV#-;O_43?jAh2!=KDNJM){}oqgs_9q#JtuByBHoIdpTs_XNopZ(8Dnb|(a zvHhWjm_FzEe2jtN&&;3WSn(M-*#FGT_PJJi`ak5*=h{9;f9`<+pPBiS8N&a>eg5?S z4Ndw3B7MS2pJ>wOtNd*w8w1N90_l@6`t14K>F3?~oSET&l16{~SpUmA{|OKMPt=Hs z;~#L*=dEL4{qvUoO-b@Es1XAr<9~n}eOfPmoG-HG_T%G=Nkj!Y!Dh~G5NIoQ&EkaPlSC1cNBz#de95}Wy!o(v`$%iZ`hL+-)$!nU-cc2D?w3VS z#RUuQSC$itu7jBEODre9HVhyJLPkW~{fdYPR$YTZKri##=M0F|kbM=-Pe9_GE|3rt zesF#HM|TQV4l6X&yqznEf1oeEym)L%fiIAp93S5<9zHY;loE&sz8;@7PYwh$lq+a8 zMV?ms48Q|&TsqT7#}8Xh2474-Ao56-U2YR2T7<7hEQb|+56HE%6adZ%3@0xKhQ0TO zN5NizLywLo?(HorE6Y<|hlK}i{Sle~`75lO9SCmQ#;zU`8{$@tpR31={rBK@pl@%S4I9CQ7&QFU&A}dZ=eqwc*K6l zXVuoOd>=9a{132zT)7{0FzCloe5;`6h%$CLmEov(gD`!dU_|;|etKkV^U_?)ppkYU zf;K=tmGBThhfhI!K4GK7BM4z4EqWVI8$j_E_LEO>i+LU6m!ePymtZ0W8{e%5MS+~1 z>GV#In-A`FGO-_Ivk%z`I3Q4UFVdig7rh_oVRp_TWmIobEeyc#)^#C!6vLw&;v9X816`kn1{ zD)eb067Lk<-0nmANmm9O{0G`}vMTy86*(~&GSU~&aEVZmw-2VVuE&qQw-{xF$j29( z531~Mv+&?Q9wU0CFW+-_t{!ykUTH98wtZBl`8TYXu!pZM51Nn>k$g9~_&&D2Jbu0Q zS$o}5f6pHK*kV(#cXfE)J9>oq?eo|(2_U=dLSkDxi*At*W<3$X8~zAR>;8zZW5o`( zbA7k1`Uc^dkNCZyW3CG`%ubQttw-M-06V`kHTcRDoPH()Al5=S2!4F)0R9wXfW42o z5^?-WNVg4No2Y(o-ewDbo(dloBZt1%boVFB;si&CE9XmR9Z|dgcPx zsHN&^|D{9qL5AByspG_5k{2#yqVm*MDa_)Fc9P7s2yb*PEM=O>SU`J5uKr-(Z$?DB zIG+c?OrCF9gi{!8CbOYO5RaF_Fer~{bTES%6OYtMSWvCb)3vi{bM)J|aR{B zGdWo|G_;W#@u_2|+xvYQm>0&^SQb9Nm1hMcGcz>0q2A;LoKqIM3Zr?4>tEpY7h7{H zU{ou{Xh*Q&nlg)v!%wI-nu53&vEFt9$&k!!QW{06JENN}2Sro|x-rq4VV8 zKE`U#j30zv5XRq+l8T;wtUCO0z)pM|#}#J4@l*#|n8p%cOznV~t(WNVm4?z|nP_z< zoh*~J@H-kkBdW*6>Wy~lV1;N~TvO46Zg2qTCTmgJwCD-8ywK0El&h&K@${wp1KWe6 zpa)U|#TkkiWHs0*p7AIZvXd{HX&fA+(a-+L0up=M*Zq|Y0z-L(5m6F54tl?x_{?EYSu@pkLIg_#{<}-*<#$(;gXrt#cM34VjrOc z(W?7V{S=dno(acwYII+KG(wWCaz@ zS7mE>Z^J#$Vqu8uCLRPOOPRfIrW`n$bX?5pfCBHD$IaxLtAz*MNlNYqw1+WtoyFqD zxrwO)1i(P48IN)?G!Iwa;T1_d+(fS%8wN4Ub7$JF z5+e7{l07OgE4{EkY1_x9f`oC6zl=9ba zR9PyQ!x<^M>5_JFol!a!LJu@ey4xWI^?}zuaIGMp4SzkP8=v@2HBYPBXrWGXcms7- z#{`_Wb?CV{+?4VDCOQpcT&2f!fA~I|fD;EmG4q9;t&z67+koAq{$W5h`PGT+`P#`% zk{mHU-v%WMW##y-QH9au5vFFtN@t{ZGNS)3GoUxZfb)gB(IvSZ#=IXmftCoe%~t$O z>Krl5bR}^on1CxmTkH5)&&=PZLB`Ii-mowGN~n-fPQM791!V*K<1Xv2B6f1#_ArRU zO{fj8Y9(QhvRACy*^5kRHp?|Yl~MXRfL3OxKnS(&`Yz+3_@%`$>IlLM6;hYXNT4*O z*W46`25UWE)SETbd}46?1dYS?SM-V?=#bCBkJM=$N^VXwy| zPD`N12qFB}dpO*6yK<@^orPJ>`u1Oe`uXkE`xul=LfbU6a^P8HboLQ!c$;wOG>RsZ zPP}GMW{sXY25ldqR=ul9NM%_>Ee7E@Qygy@eqsrkN{-IqDR1)d>PgqNS@1Ch_er(| zxv@WUfWtCMj3;ZUFCQ>0Dd)`YyJa;+fhmS#TJ7Gt{PKMN9b zgz9%T5J`(9NsP_dG&;^FjWuLE<%riL`vdLf@;GaY6{LEFXFdM`?jUF8EOB3PT`KUJm(?k38{*0 z*h3}a$uE4_aStT~+r75d7<$&us?-IUUh|g~bDtV+xV@o)ojy@7uhE4Y+91!umMEuc z9GM-5Z}UJvUS)TpaS#>;=k^6>FQZ#{u5&tu)rsKo8zVO8*To&DqTVUO(ZV`b+#I_7 z_6!IX55qHqtR1iTm*@}OkBc#}WQ2^IUI#1kPqsL zEy_0>?rSO}M#`YN5B#DliL$zzFBeOro*BDU2X*v~>!tZ6nK7K=V2LRGegr(ojaUe; zl^~SeT8Tu}6GKAwO}{yw=ud9pE3X_?ks`G~np-NjK+-Ki%5bfNPvkm%q?W1XhvxCx zs6|%4lIKQzHze3cd(#G^@qNi3DZK1k7=W~YEi_7Cc2^~-*mSL6=!DU=wxsy-qMs%1 zPmg?3}5K6B{WYQx>15abL6W;5xPZ zr9UO%9QSE-F`)-MH+H(iiAd?akZ@M_Q9l2PrL}9d30!*PY57${poQ7gMWexCfLlk+ z;C-f+CVa8MI*^y$=irz%Y{^2Re21xvniHz1#bE`04wUD?`}5~i<&foj z5L$8QXWt;YU?Vz^LI|;+R6?A%ypWL-Yt+rITdK~WyB_x%u6i@$nQ>gXY{E{zE9f)S zqHX>x!2YVODk<4Nz~8Tp6E}{+6HrD>zCoK#+~rX6gwhcs@GcUnmH$15YtCS8r55{< zWu3}66P^&O=_&O44@Qg^cc88Ey_NT-a`ls=HIblu=sTIF3$Mr|w^vDH(R_)d)b-wh zpAly7_c>!Fg7YDh>od`Ty8+ch?7M!3Okq6V)3ev=dyP&(rtH6z(ve`W=!z-hW*((# z)xo8c2H|cPydlzx!(qhQsh6qN1RIk_GEQ2c+v!DU{KmBRLh+78;oh+hHXf_o_#FY7 zT;iW|a+-7B!N~nRiKp$6kI01cnfy?*_IJWO)m&Z(6ofVR=%s5|c{q3jh-AA}QcgE$mg#nI*ln$y@XhLZ4U>BeX{P&?T|pM{T3kOkew&)fRpL<|sxe_>VOTXLX?Bs-v0=2zSJ~>desN*D)g|+Ci-WVH9 zUttOnm|E3;ILNHq?j)S3-5(8jNtT*4Z~_@^LE|dX8MoDO@uN8;C;%CafV z?+p)e^UA<~5qQi?M%+miCMjLNjF{VpVeCMY)KuF&g1kT2f?2xH|M?F3uN0+qQ0}8>a^icCMPy-QjGQg(@^1!Na3# z{~3K*sI!y#Esh?JZ5vG{H}oYw5+Z+Q=euy81{g`BTg{3D5z6&>#}&iY80IGa?BblG zzt#9%LD%Mi&X=N)Yvs6LRqfhGt&bnTZ^bA)7Lr^1nhyh(Fr$EPMZtO5R%_A%nMgIs zQ~j;frqjdQ^f+)u!I@=fh9SpY4$72SKbF2MZ17mkIa|qkxpq02dk3`PZh?9Gn5<{vg>9mF?(_-xzQYLR*oLrD-V*u zZ51u>4j4aHb#B2+gMC-9sfb7U3jfD4`TjXffWjh07RccCF8BL74S4x$$3jlXsJYv2 zrt|S7T>}(1UbfLWRIzu;<<5wP2y$@x3N4F$53gFPy=dF}eDu_jh38X!YGt2kuKIJG z>+~MnfPG7~Qr*(0*i=GgLQrz@g04?QnC{iN$vp8X5+Cl+h)G(OY1k@|FiLm9Cx2p~ ztoSSIvPraY&S({m?ebHnfPjFOKlGef6vMISvdqf9sllW@YAaJ^kuW=c6A}+4#N4@e z2Lt+v#Wf);wvU)*gB*V*&9TTt@MX{NKsgO} z#dW!qy{TOWGuWV^nA3hp>Ms^cUOQnpj~7T~*wce&&WqRJp~P%eHqknfB;xKZe<0ay zQsk}jBSWKgS$>7YZ6M7vtR)C6bl^(i>XYDYQBSOa2x} zy>e6R(Xg+4D&={e?oLhaVOI4RCBRz}=|2FzZCeywWsc;zh}AR4>P(p3Xq&?}9$57N zM&M;&5ZIBGf+yPEZi(fGu@EITeL7}`8O_aleNc-`Pl%~+bgG)7JGC&oqJeq>*>f()*awRU&k|$wVJVYruQPoRdQ`Sn_jx_8r zzZJcubNl8Ln%imSRo9wd7*juQp0Hn%bV2O}x9p?fiEcqIA>fSKa)p!iQBn8ihv?9O=_iOGp93OEwR>`rNe!q^5&WJ9UUDYa`dO9^_MXaCjkD)p6o6Eb9VF~!F$uvU0J|FK%QtjJjo?7jFFiCDfM3CD z!)Q@_vOx3em(pYd)+z(u5l|vR``E7@fEnT&s72v(2hHqxF9O~tH@rj?rX9ntuL!}n z76Im%RKhE38M0Lr%eCS7sOLtlwHuHf3O_g?vUVh;FB7SRbjBD>)5~ALB_@=9MtDaI ziZc%AHw6mYm}k9xeho+F-7O>^-L_ZN1oW_JN9PIwT0}8oVRq1sTf_SWU(vHKvdF}2 zVRW2AX9V`&vcV4uw&xK9dK!oQ4RTsda<1ojXqR@X|hhl z1(X(*8(d2SayVNETM@FlxI%86k+||kY+ybIKu50>w|cvMb1=kb+X0Pl{5&DNKpJCa z>j4}lDttE{nRDJ-m4xzp#^H|56?S770(m|PGvB0$8-9ehw+Zt)1pud!<;Gs~tc)*n z52mHv*#-K`Lti>a-qPae8Oiw=mj^OEwS!=52MG@$(9k+!3!zUEpUixs)_CwtS+DBy zN2F_Ovx-OwVCzV~iOVauqq5}jX5nVEfXGkW#0er(^ROh>-~b|8YN_C1I};}2IKtfW z7_vPGf6)S|qF`#($mpa!rn1B&e!ffJuUDU1eIN777H(15&@PW*DRA`N>JW8@pF;zA ztiB_fsvK=e%ID$J)ptV(lZ#_S?)AZK=$J_9lJcmI`>#ljN(dHlyD(n%GTOrh+BWDH ziYJ9tKec0u=y;jWqJ@6%uTRj(YS#HM>ILOfdsoS$ve6s`(69@HY%PLUg*rJpIcv%x z`e}MbV-W6dH~os!yh%`?*6OVV$roNSk%|cwl-|7FuBYq_?eCo}{N$>-9@fVj-R4yK zL~<=sXL8L}@AO`>9y1{oKs`eYFOOGS+*cdwWke6UmoZ65n%?C zPI3d0&OJo`Ji4SRPWYreaQ1CCt6&w$>T!KE9#`IXnEz02y-Bg~g#?%?Y+HbivXr5Y zlcCXh(pAPn*a8mKlox-DmSW<{PB@qlt0RA3vynVz?e!d z*m-KZ{OVirjz#Y4tBW!`=f%%p;`th-68dEs#GHg_e2Rh+bh1JZ*XaQDZ@xdfWOP&n zioCvIXV44JT}s+}S8~sPc{+T|?OKGGeKXbvlJ@&ujBOaPV{Fr@$~uM5IZ&RmSIa&P zzlHVTxALHvIUP1exkYC@`&qX4AcL_@E(!KB@d=j9{u-r+Q*ay8rPCjeF0$uUWDYQx z^anHCEI=r#akq_0o;<|31g?-$Fl#j-E5_^4(fZmwLCOiOH#?>(X2!f@K(C7ZYbS3@LKAK@SBQu4dWu( z{1!4PUTUKe5*Ana8jmn&Dy%0q0&Sm(>KN}&Q}voio|ZCo=5r3ECMY-WZWNxHyeXgF zdMV59?#3j1$!nJOlXJbJPHy;mfcef-^m?TL!$SL;)!|R-)aeME2?tYLDwQ(>g%^$$ zhFtd$&L7KZOj)KjfyoK%yB7kp1U#B6XZElIJVJBh8s=qXE&JL6uSU?3dfzR3|zs)#=7RquoU$DxJ;aD z8HOdRjvg<9JbP9jzKGST)b0+athF7=Is?n^VsD+no^Z#?4J!T~eAs?^#Xrjwd-OsQ z8Ff}tQT_7}=aO_*{1e4fwi270#^OZgQN_puTAWT-tZSPuQ9-}wmv)Z|I?lJ!ElA9N z^Qld$6*NU{=&r~>QcB?YLEcCl@Am*t@Su_9eGdR<4`MJe`O#VCAZu62vn?X9duXR4|> z1#dg~h#h!Lgx@Jf2Txjp1PErLvqZrM?E^XBt3lNFq;Cel6E-7CKu(I!aoK-J2PRpb zk1~#Z2$f3P??@wsy>EhEuvPOp4kcZ+;ZX~3 zH|Rc<^wX8xd#ClgD&5r9)~5=WLO+)zcQ&8^Yah%tBJVwMBoqu&9S*JtntAC0Il z)O6u+(G)*~<%@B65!P(Qt({tsltOc=t*#uinCM+IsD1F*wR2=>gq(}KoI{04 zYa&VLmkQPx#JK={hdObK4I?ky6KuR;Ym$moHK8zIQoUmC*SkMi%?>g2D!#vTiy+6e zH{sU2ibjL?pv-I>=mnBmj~{|RTR`+sH=4O^v1lftlG@4pJmbZkK++@o>D(`WdE+_! zDxIspOr3p8<`!bjN?Dkd%|pV}(JA;5$lS0f-NGDrQg^`(6vuWVEn-V&v$KrFL95$MSG zjE)0G&3Eb;t6+@r`m#Vk3t(VJu@Ni~`T(o60OP?4Z`*e7?mdu+vh8+B07#&hHhuVJ z<*Y%H@iQk$Z$mBCrG#WrG#JMWe1(E?WE^jg97m;DZET*ecpN8i?{!|uXrMZ_isxRi z{2_i*-O_d9mNC-W-pECCb#b*t5=2HgI-%wp&chNk9pI<9D|``pyw>Ov@9f1pdaq9* zUb~A4YZQE`c)9BI5Vi*ruNi^%jOyN##>N0pt!+$Om4AiRg3)UYH*|KB^?uHcI^0+j zo=O}=$Z<)we9|EdQnvsiY?{c&>(C~MS;=+?l`f7fWS=4&nQ6^Ekk`=hJBEbi84yl8Bu(Z=2q`ek4{2pC}~VkOV5-9F-7)K;`dT6J_LGwUzj9G6w7u znk10J#Xi{lAIf=lrWu335{$`mfZS8^NSv$ewd)Q%sK<_XgjZtyb7t~(J$2b+Ytyb? zfZ(uv%{-q&&3cx74FIN?hPey%qb3F}1+U^3=XIN{a2PjCMVjr2 z4xlVr0TBpfLi=qx)M#{i4J8QMYv#i;Bxt{*aej~P@KQc*_P%GSl;mEOfNe5GsM~{E zPY#oh=)BJ!QL95UYS$LWg%3o^c-xE}UfX^rysW6u%>BlG6GgP`@q?~Rhp>kK+p1fu zZld1t-u*02GYu5gBv3kDL|1vC_NWY6$b}biMhpiOHj&e==50SLyn7AfxLNyEbEL#{(>B zU+h6@wQ=Y?7k1Ss+?szKEmz2+7iQ78^O%RRe%0!gOG16{pn_^9idWlwMYzoxs{db* zm_O+m|79il|3hNbRg`6vBtDTCC8d9d#4vvnF-%OKu9Q!~3J2?795W1`@WEdkGk-4s z;h16k1C;#LG4sjW{M|6~2U7SqIE>xDz%PG@hkrpJ{%1PMA3w|g1;70F-Tec8VPN=I z#mrym7ZygA|Aoi+b5H+eF@Fs$`8#v*CxwKG{l5r|PZWlU`5#w**d4JYim?vq|G!db!95c)TOq!$3l-fXFt@*w}c1@9ax_~hnY`!X;}ds00bfo z?#G8@01y8a9RmJoO=esl;)<^?7I6H*SK`LUhh8p?64(Rsc`l>dOO~Ba4H=)BmWG-D z4h%%dm#?(TPYl7_mvR{95HO7bwk}GDZ)O0GLOi+zdbl6iv-tFa)D3qC43HET|NQ|E zN#4TGrKg7ok^|GrF1TKe(u2?5jSdyePv7|=)F60NLG-5&S-;9~o%S&X0=-vH>LpXZHaEV4y#!HnKm%Nc29#Nbu>=kAp!7JoN!&K*$gw zK(`CdU<^Fy-avqzM;L&Ae%!KKEE)g;l0y%;s|g;YgbD+MPc7KzF}DYo9vOlrG`Ppd z9{D*D!eiV5Ac|6ujs@n&|Mg=vn{pf!WH76(YC8L{l`wV_@X@9EnUaF^91)yPCNYc* z?D!C9R{GwfC*A+i$iYt!#E|o&xjBU%Xcyl1(Kj>58-@N#nBSYzC%pz6U){hj|zVq}$C+;1ijcyP86&siyBnf*1tC#+RW7yXvYloIw1gYiaett;Yjo ziLc__3$$Ie)Rkpb4ecmIxZU{?{9#iQTi6*NSHrl4H~Qf~Nk!xZ^bSI(00c~7kI$#3 zriP7AKmY-FHO=zL?A|)_(S+lx=52e4iPQj)f5E>)gE~8YlkPu_VQl`0ghSZQM!Ahu z;}!&3|48}(%|SfT15hT7n7p z_XFc2AjHx!r~oe~qIc_}bCyLTW^a9g1V9nSqFVug#uyNRgxwK8EXu(U@eAI^ZaqjS zp%Hrz`P@Gi+PfyyBC%k1!rrYPMZZ@Uhd{ar_?&{ZHFYg@Re=KfAwfv9(nb7@d$o0f zn=%*38QfqzF?w{hPC~`&&!SNK>?XOcTo(z37u}93tuED^P09Q88o3+{zWMq+oUW8i z1+cXcz#ON6qhmL0q8xbn_4-|k+GgO7M~k@^GlWH^pp1493z9l`SaMlbBHtWG0K#Zz z?$9i!XgQ}(RTS2M*!V`Ez%9RllIl=&8Dc%ekx;#SF`2#w9@x{wT};g))hIGdZjRB5 zkxg9N{nhzWsm42r`FeY7ZKG=&{7XO1#kIjrnHUA9VasdrHFw|pTUx>TOVu=c#;5@q z<$-yamD7MtTn5b2ISHz_6zW|A>0N|7EBkS2;QG7|`}!~S5ajfvu}ckhqk7E=h9_Df z_hJf;!PG9&0PWQLRiq;$ddDgaWS!|K*K`bD-6aN}Le4O18qS9Kp0{aq(ckn^^Dfq} zlc`>wF7ef&(rMUQwI4T%#`d7>Ocnr(_Zd+^Q}DNT=K5@!tjEm7qjUr9qSL8 zt)MeWDLQ2G4`#U9d`geU93ae(y{o3Xz2FWIn8H>wDmN*MqqZEBw&Fgia}}=`3?|)} zOQ$Bs!ipC&){N}!b43nV3$cf~AhbRztgrnVN<4Qn{V5s`eom{==>YE5;M}O8E%Cq# zS>ua};2bM9%-ef8Udr`EW#Fda789ZZA=RHw0UU*|S7Lb+{z~Fq;+urvQEY+XQbb_( z8M#sYWp?1_2u%@<6)Siw0}6|omO1ybtr)!W4fBl981d2NYu4L|?Lk`=`!t_=B7zi?+2s9E4@cF18}$ zIT`fx&EJd);^{PlV=PL}q(wyOO7(kFmtEXHBsVYIPhHwUkvl63oK5s1H06^IxRa%o zcS~4uj*mv+cu?SOp5lhFIT33Oxy&qblp*hyaB1-P=R{*YacatKsMb+duiO*pO|+L^ z4U<~LLj=3z>^UWws2LBE&isLw_FiN|4g=cbiymK=PggReC7n^CPa9E^6y)0HcE0Es zG1WWVK=l6VMuEFV9x!zuF=%|rGiM;xJt5Aei34)i?Tas|Hu1{(?LK?N7dF!1ifx1> zw1Y`JHJK3gnx%k)!_W4XKWI&%oXLwjR*Cv#YD_~_3}-D3nbmcXJ|-H$*P;~diI!w} z_N*(_DOV57Bv~|1_={w{rT5ojrMal?y5mA}{>GbnDZ4ea80`z-=)=fY$)ldH?J)d> zCn8zOfBLQU4pQYcbM8hpzYZ$_A+{p7k?E|8eXkQ6XH`z3ckYXdZf-h9U*8shgqCjY z+Ndtg^B4*u4tIx^`{Ns%PLmU7!A44j9H~ChdG8$R5PPti_!+&VmU^^9=P(RIwsEb1 zT4JIc=i(qLgT01~F;O5dAtLfGJnk8`95wpX$%jw|ED@LUT5MQMVFHLl)e|ya*(cT5 zlf;nSGY-d`E>)|GBT&0E)1=$14S4Oh>-Dp~6Ehz*vJ$SfLpMSF@N6*GhiPC%fb57< z5u$ACY|Q;hE!6w83AYY!qtEz`u#nU$s!mNDuB ziCxL3N0$JTS~`hf9cMig@Yr2}CaMfh+74S}o10g~=z#3ta1bm}GoXFN8n#mr>*r9n zSGk(F9*CFKGLz%7`v)%2^O%K;NgHHN2ky)F*%AEdb+Ky|FwxLlv~K&~?DQ6u2?RFx zL^NS*azYIY;9jzE@TvRDr+Y1Kzo+Ft1qAN!58th#qfM?}P|stAM5CU#Qnvu>H%}&q zJxQJB9Yhra;2cY#rDskdd$i}^$fp3`rt#l&7|qd+Ll#4_qYQ(_pi{#*C_D=q)7$d) zA?m@xw;8P`scdSUo66aV8*=dFl3Pv{>6fHx%&Q0Q^eiS+jAQ)3{mQM)>-I3V17TPs zTY-?xK?G!57eBW0nOgzWJALlN$fZHCr)Sc9pT|EDD zF6WzmYe!USRI_(3)JSv&lU(W6?d(hIWDxvlgXpw>#W} zMcvALk3qS}ies}-3G0uZj8)s7{B9f7ix7x(Ue$q)Trn7JJ}B3t%!~TfVeW6dxiQXB zj^39}trfkXX@*Kw3=bP$@jp7jl-7h<24^)fve|Gb?&yTM$s#K~+JxBF3hL8VUyE=+ zFH3M1+NtXY8KAECV@^;RgwgwdFY@~FjeeELA;Dqati;Q^pwBjkz7a!ABI#b<9cp_J zSn-pp;}txiYMVgT%WSe4c*LoYyuX8RLLKAOX?aXD8VYe@OKG{QGNztsNrvYvg`FkA zAvvGuv>E9nJ#fvxix96L6^NBXIMkO^ur=9_QXu|%X%noZl|8ilV=-T#K(gVu@*XNN zMp8clABp#U7$ZBtZsK+fG~T8HyZPs2R_=oHOzfNpC@|P{^Lcfqq|17(7ZM&}H4(Lw z2&yVR(wCt!QWv&9hLdfKYx~x&D2X7hm#NbeA#a)Ty_t5|I2!f@HZ6lKm|t&z6&woO zQUP2E(pw7;tZ!c7q6gQ|YYK5e&@w|JM^P@;OYy%_2DrGqJ)G?iMI_)LqvBWX5Kl z{y0nH1H1CE;+#=J0SK_^m_~s;@VPG$9^++!)^aT^JES4HkNcS~bm^uvSu<$PVFvY{ ze%v^+;8&!VgSQ&R>t2J%MeeHSUS^EY$`zBE>h~2c1ap>Cf=;5ek@7h+t}O-hVp@E2V8B>8@1$ z0&Os^o8@t1wv#7jYGKEq2uQo9Bg+%56bX$=qZj4<-!o@~YhTtpLed+5R@X|N#(SC9 zTWt=J#?dZAiJ zn_f|XEF6ykRqZPH{e|g@Blm~@ljY;qFnF_4c&PkO*g%PW&vZiZP01>o;S}Qnz?XGo z1v*1LbTeEK)I!5Zhhz-{d+-(X4g%uITc=DTh#pz|vN@ZQzN&}(*t>9+hOuJ;RhJh{ ziA#SW$z(WlR?fuKiD56ahGAonBgnH!>a^Sw=wtG&cV ztVmg|tV9hmFZVs;kJN&S+X+sZxj+Wne+KtHl&OJ^hX51Tz_uzshd~T{DyB(1?<99c;*r=hld#xlbuLEpgw5%l2XbWb_!A+ zD%k0H6X`hSO|?dTs)d0=Y~Z z(xy~@EyT7=i^QD+^Ugz(jqzZ_&SOkOr)_zDO8`4eV|a`1Rxw3!11@QfGopF%!WZ8- z{K2)@xq3gzG(BN|!)=~{eplm=$~{;sn!E1_0N@Fq(K;rSmb=rj;i>zMDm6P9D^_>@ z*sn{IYEs?&66ZRMy`g|wh|d|dGTX|;P5RJ3mAJ8xxN*4Y!UDI+gTAWdrXxM`)890! z(v98eR*?CU7<2%Ht=v1_pg9R8;HX+jgedS^>!RIl;0*CVhoG0hm#K@RA76|e$PCg) ze{=UJ$EDvJ`pEENtdvfAz9KgDp;)H$|6V?SK3^|})M{^{+o186t|WkGsD)LuuM80g zggzj&apHOsG@RZ$JlUu(Jji3(YFnpTxW~qOr9vl{P+x;hbqw;&_$8cuX!xtufn@83 zB1Y81BEn-aB@994c{TDXSaxMQ6Cgjr2FE;nT^ zvPWLWbG2HE2sex3=JYAYa4egXlSV|g`JjZ>hwt{RDhQuvM!k_1`poBR1eU(1qq{wm zZHP2AL@s1t?DOt^9WJA!WA^$XU-mw6JMLSd?7_?!UsZdaX$&dkF9EDJlIbDLg>EK&m?8uLD0c|)hfA0&aC!|J(xMK-*_$W$ya#iAd0$E{q;eaG2y9Nkr&D$~)W7w=z8%@eHCl}dhi zs`SA)6DOdj2vtOCoBnO5!8&l6i-=_+8#)@g2U{X;_A8RaGv!`9-@sXgk=HPyz8X_^ z>2!>+35KSK*~%D+&z)W+kbQZg2BYDar5}g2>uWA=x)9#E2r2r*t^EQ|T%0rHxf`j1 z?Bc-%=8kOT^j#L~4&_hv+9gIm>iria1gC)O?z#2Zy4XOCpoGw26w0!4kMY$R8F{x) zl4`1TbZMj%dCx&Qs~DuHnUBm0+iMm0K6uqHJ7TjE+x@4=VNri9IIcZ}?!A}|NOTnWHE?-i9C)Sg(1`li0eH-u^}PNowIomt<;GXVP{S0J9%@=xUkT` zMC+qtVP~LcXxUSXrM>)j&Wl)K7S-jkDk+jC#}V^ZBWX$9$zKzaC-^wphciq@dC2nD z#OkgXzYu20=(SMIqnQ;vExt6oxR*T!sz=+$zjv^P*xO8e7m#;idx0mv)-=VPL*|_I znBlJNkLqud;(Z#~jS`Z_u{EhNDZNAA7cZg0zl^+VMvs-G!BeR@Xt$S;kDiFYI?rT! ze123DSy`m#@8S}^^&qRdmY!*)mlZm7zE_RV@G{a=1$TLVjLp8k3{z)Z(WP4rfq)j9 zL5IFW_L->&06U@@?>xp^c2}LVi%K;Z`hM3cZ57t%O*V62a;j3ekraB?zar+2hle`= zA6!$GH|S2?#F}>Dy))(DHDHR}Dz1?WlU|S#AFNLIT0L9}c{?EhPxW;pq}AkvIe@RG zOrA%zf{yS|;d=VE`&tz!{HiW%&`@4V$?!l~GFMXANZb`j)BJ7qYN_9R*Z&>ZGEF>F z?FeLjD5=Tp#LXnm;7cWQ1h3+S0~nGSDR1|V&jk~vU1X)m%NeTW;n+`0#maJ#iB0qs zXWEVxD-s@WGLWGtAN}4HweIy36_Ay?nHSe)orMhe(ZmYx+r^i7RY-qTv7zeh;|Lne z@?a0wwWy&IU_!$F-tYoFO#U2|n7=kC5_8XE z6V(XcE+NkfCUPvP|hpdUutU+iPB(cmJcc9$bamuK@y^z+?w8WPzIp)0^ zzhPIoE<{EVF13q=zD;(eFw9dRac4MamCdGlO;BT3pZE2uY| z+Q7>Fl}+y2x1`nS$m_2B&QoKIOF$&F7!qkfx+yYW5ON9-Qth-sKW{pDjxB zZ5Gg%Ag(QweA z@=i`h%afd0jaW;rOEk16DEm0vyZA)tio-ILG?d_`ll~~PW57;t5V8OjfLT1f8mEj( zDRqbHqIM9hKoI8O?)SobR8SqGun!DzMHG*7V_+QJ8={uW(xvhc{R#>q6SIhZas%k3 zUw;=ltD16;JXKg&dg$Hb-dY_36;ZB*d$v;KY~^4AO+;K0j>%z*hRB9Wj~IQqmXnCy zsC@cP$t~0;y*B7dT!07%l2N)cQ37!NISHH~?J4*~w>6J#=T)GUjKNnLwmMIa*PXCrz*+p{WIpXZXLGuIK ztu^i?c_(*+2CuYkL%YleL2(?44b97lZdho^?{gkf1J!Q=1HOS9qhu;rxZlh%RyuH$ z+Sk7M8{#Rpa05(B4$nrsGuDw^*F`rFzJ-d1Ho59f2#$6+WsGmlkUZ;*RdJoMP8#1j z4mifgA5`DIX}3JjL)8xKu`zMRF?$9o7VkP?X{I0AiXmDO-rwd$e)9&?BRy~tIf9-N zk)|YlT)LW4;5A&5fD{t@$`F5Zho=YzgA;0YEHN)L$dzkScC}K27U9rrx4^7>H!^ke ziZ8ravt&dx@I+^3Lw`OXZ+moV4UjC3L<_?p#u?mP1xq|F6e|ZIM!UUQRX3y>F*_-+Vh=;%>mhFv0C!m&}x+f13LWroX_T$4g_k!Nzwe zc;jme`?I|fo^Ebp@J1z^#wOlEMbu)(6`}3RcdFes#<&qlEN*0Dza8GQ*3w^N^l
cFcI@?P-Q$nHG^QAf!MJpB|BgOQah`hzH2rp1$Wz0jOmrY8^4~wdP*{g2|yr%3* z|4YsJPa4R7TyvJ?S5OrAtT`*H|GSzqBL_YW2kW0?6NXP40NbC6?EjZ+@+lwqm#XuB zoNU7U`MiHqcNU@3cW|(Eb@-E<7DmcIPpPT(Z3(@~=%l{}u ze=h1D5(c){AKVzJ6S*73JmyvZ~xi*m!XVoET2g(pNnT@{o`-=d&~Ye&%@u_KM5=>EPw0` ze{cUj;%{4JWc)NSu>HOLi_zlmv$1`e99ZyKSy=z(c3}Pdo9%DOFD#!fi%<6j13N9- z|3U%$_skoHzlPrYg#uvtCk4R3&iD^U!(S-?MmA=K|G>(i1jDX$iYfC&+Nv$e<#<=N z1?8|85owRHMMNylf{w{@{AbN#in`&r2#W%xbt_`xEVpK!QCmSQYnWnOe0=2vMPXQh z)1uUTrDN7nhG~}R#B=B68|~#s*A`>S-l^@No?$NiS3!HGpBw|I>>iL{a^}7QHT1=D zX2hTYKww8bhTie~_|%Am=oT*sfptK^cD+X+J7CjTf_@>PkR_ zpavkC+aSV(R@>I_T=dAO@vs>TokG5W_V#&G%T)9xsX#xYq8dsGap-&XfqVVsw&8ZP z*fV|&`@41H84}RbK2-*OCbtbeH5%2bQL~2h1|6p0Th)Y7AQG{oJ@yEwAwt#pWiYBi z2leI8kBdX#`$hn|z+M^PX@kM&@v*rA!Se+Og#&B#f$>{GeO&3b`$A^u^s4B96zSdB zeJy0(G;EkPbpZS*BZv_}K{o_S{yF--0l)RO`)(PB^6eCXa;-QJccB;v@xlWUagil} zkn;t7N7Nwj{ddTD2_$`g+vm0*?u>B69~g%kx(KgKs=2X8?h3?v@}LO;)rC4H$BNRq za)*b_{9=d*$gzsffY9tGqZ5q-Ae~(>h7)KN*mlyRLpnhR)lT<EVjXRAzaWPMWz{7|G-VSZa!^7W%$GC->Ab8) zCYpx@-Lu_A$epI3-sOMmQss-g-ugjTbrou5-r#t{QtUp%Ye9=WnCBz8a%i=!QI{6-GV!VySoH; zf(0j7aCe8`?!n#Nzv12I?(@pN=bqo+`Z3c}t5^4Q&zjX$T~9s5Fu|}kA1D$eLkes9 zM9dLcs_<)p6=~KT8urOhNaVE*)Kmp_Cls^Fq3ouYT~tCRnHT~U=f+!HJu$dyr&K&o z8&rbOkCYVlJ3V$LLT*WKboB;ha4qN}Zl4`7B+{`VC=_b!wtDjfN-X#`U9f1u1W4M| zC~2?gt}n9%nn1Kt>iTFW3JgTA$7f?9cn(wQc1Q+X$Qp^eZwzy}_s$O&DQnqA!0b77 z>-n0NDtBkGCFSOhnfQxMG-Hdl`{jKXy{2M)nbE!9DLPtnOuXr|IvhTmyrd5>KB3wa ztX zEqfHKFG0CQw z4V@t>n+#)|M=bSLNSaS|R(~wK{iN#eXuPv~i0Cw);&wggL$^Fv#4}(ewGk>jK8B~0 z#!j*^SDP$}4D;03Ar4W=U6O})K!q8s!%V8(JDE!0Ajdz$ zxLUlWsx>Xqv+3xFb;VQCE_F}UwM=`F0e*p;z`kl^!@c`9SSUTs=GM9YW$2(k8(Sl$ zj>0+F{m%9IM$&~#;r!H~MWS4Co_g9eNd=9YWWX)nAU?-DLA_c<4XJ5=dK$H_Y66Vv zbMlA#gnm3LHxnVgmCf79^DHY+$43bv_5{2iNfzloWn=(F6%ps97DW7kA{sK#csFl= z#V}Y6nayLc3s;lyve(q0@a*#sGx2;PkNG7m)e@YiDW|)cB)rc%n0)m&x!D~0vlo}u z%3L*r50>&fih(Tr-*1Z=BO-6F)@zuThRV0qMmbtI#dbn})I6ng>n&xvmXC0crL0|z z$k@|Iew99L{>9<#;@CbJadk(p%H*zrv923d4ZmU zTNF7J@8+Ct8vDk%;ttNxT?`Hx`TVbEZvbF-c1jhotk6|ngVDz-%V>CM*SU`IfY;_k zx->o_LT-XnWmOZ4YvgKNX1!P2)&!NgYE_lrV1?d z);$t;Bj(w>lqR9s)N)^%q>6-DuE$3E4McY~mrA;_2d`YXec3(&7VDjEkVsh zCDGN)vtfQ<`fjlBE*D~B@Rvr-%FdcUB=TUQzBNhGwn$^853jOqbRJu=VR=%_mFOVW zWAEQs>)B;L?tjfYi!KXj_mH!t^g&if+!;?t551u?aH)`dNpNbJ@NcqnyHK@w#ov*r zS@SY@!5)1vpDQSvz&??7hN~aXL~nKJ4|Fi8Z!1!$XO#C1Rq{SctPWzTIqG}5Yj1uQ zao!Q1NlRg-9$)gnrppnnvO-PD)JKg?CgG+VO^B&I5R|$#FlvZx{{)$XIoBk zp)mZNuVVXo~{X-TYw6z z!&X0Q)<=7V7|}N+R@TfmDzT?t;1h-9tVZ8#={5;x)Cr-Xb%$Yfe2^+E1(o6=<|}^F zx+bnZ=g`ujVAazTt!t(9a1H+1I%NiLm7~z2(9yo~w4!O?S|{I&?n+FcD*G5>Mn}!@ zRTpx9L5Xb=|Ef`m6gaq4MF?eS`e?=~IyXnPn0RpWm}HM}gMs}15_P!Z=^1BYNn3b9=fMlSy{(mtHRe;=lcJyw4 zu?F8&{y$rTO#hjI@PD!f|31clTZ0_$nIr$5_>$>Q_8=>eX%A@Q{QvXypO)4ix6EH= z`OnOU|F*Q4Ip1O2e=yzwi2^w}->vC?@ZYg<0!ba|fjLW^OdNpk)&@={A|^%vV-rF? zK3GR52NMGuShuC9cm6x8dA6{iTBqR&JYn`J6ycQo9te1NW(Ig#JSmAV!tYANABk6U zrlM-Yf`W*NsK73x@WOXDlurOk%hUR7(aG9g2p;3~5 zhn|42SO6gdML|(AL_vwqZ*4_~ra`%F$V{Av4Y?4@QH*$l`yTG^U&Zka9WxReM-~Xso)6E|!G6`$=tm`#bfp_~|EtihV&`Ah0ydZv}x<54zJwaAd(fg6i)C z;Q&Vg_5a>#PsB$_2@l?>3YB_<1@@KKptz$m#1~Wq#5WxrBm(qJ@{ZzBofzWKl>rk> z(9F8r#8AVx3>xHXz$;il+?u%#&jQ9*fq+bVzjbveaHknr&@Z?> z{LigKm_ZbC+P`r8pZgS_)vvy1`2Wo*7;0SvDpEu0pZr| z!|mVkivyucFw0yX1Xmm!{i|P(oo~M2+82FHkjM*vNT?UUK!<$303k?(-xts^1`LRZ zYyL%hQ_SZ|X4_ZHApTA{FbaM`fzA1|Y<8%O?i_P8rr-SM>m=w6Qxhz+^(e2x4+KRa zAC?G^NI#Q6A|)k)g82zhLHcEUg&@3NcYi(j18gnZ8OGm`a4#>$i-!AA;XV?g!qXS^ z;w2B>pWliE`rZ|ighg(g!LQSI8$eG)0@}sv_qHy5&b|Fs_@WOazq@=p!#TJojO%y- z^96lHglJ-9S|Q7NXVjs%8F>1?6#_kCz6sf#{GDW1HVb#O;Xi z*+2mm0)6u_CG0f|jE)lp7=NDAhTOr&0iu`_)a(0T#|>pa;H}bXU-Nhpu%ULiPFAOg z#Bx1RXMs#IV|(ZwIca^<~Co( z3?Ul0%V5LDPZ>T9QJN*<)r(tNbkk9&r!kAp(abq+k6b&eBJEYlIa|APeA=WOv3Rcq zcW{g;JidQLdy{T^Yh|5_&OU#p=eAl0>q=qXeKxT-dUF|9#4=R$a(bsW-%;3d{i5*e zI{m;SsSI?{{UB%`d<5d@JXdm!XRky1)h0$8gDVxtGVwo;*HV(5-M!#ED;tzb2;{Im#rjKxxThwvHNX@45-s!Lzo(nWmu zlX3QURqTmS*MS?U0he3==i@4rqH1zfcVk_xi@*Fxewi{Hmr-9xKLXcvAEvR{XNtun zW|~yN7yYI~l{^L+uwOf3$Zgl-Q$y;+O*N`G)~n6Yx>rv}LCiG1kE*&p+GM;Ww_$LeXoB4@s)d{^XjPC#vSE8AoF|b@=l3;1hcBsORSgIhmR5Q zJe<6xCFgM62X#6}BZbz?P!Y`(umBhvo0>)5Qz6Vr#k(H~Jx?Up$GnDL&kcnX(qh`n zY!V3en4}k&^*cWf)iA1?6;&42h2V6w!4svuF|=l;>P|`q%jX0UkTG=fcZ?ywHp1!Q zN!rutL09?UmLyGjcInW>5OALNl!n%`xZD&TUFL{C&by>C#z=P?3?7^g z!R!~2apGe)ln`tTwNWmh!IJQ)N_V%D6`eSSYtrR=OlhX{6#c&2F21J4VuV_OtE#D- z);LbS=bUQX**5#!Ua-b}2HL4C4qz7KKzW!`zGqRWbJ5FTYMg`}8kLV;#>ojavX})9 zF2A2iHKEDJnRta<3vJBnv9NE%wLOqf=IUAD{#30=&QsgP+j6;WnHKIw?(UOusgcj?6ml`;N>KNyFqXa*q;k;Wv(|vNr!EAD5{v@|frn&KEHo zliLSerDA)BFx3k-?aboO-^@Bz?6vX?t~71V%1&zZMq|_UwkHo1-En2%SWxf1G!%KB zp*n+=gDO&LZHVp#@e2;Z&he`P5>=6Mct@{69XzBPsw;egg%Dzt!?$34{8G*@Jr>y` zU|yDL6>eySa;=WqDQq`Wt4bay;_8pdX9A|^H>SJ$v)JVBs)#_+oLWekwed~nbw))y zzOqFF%%;c>Yh#{uGP#8SnNmcxfqBG-$HlO`?H{u8(oz;+{3Zvz-{#eq zrZMX82=O+)Oq=l~m|(k|jLCfCI6Xv|}sG?}l5T5w9bfm139pe&_Pd;DOA zsF?QK0^Nr+4Jo4KsGRTWo_Zxm{Qf7{AeP=m4&^Ma^JA+gYtWNm@wD@IOsHEk=i4w| zxku#}gWd$t$}V_BZ$H70AZy8<`~ri|XxU8n9O&Pz$c~_FJI!=3cs0LxZsQV%AQFQji$An$eVbEOhlWpa?YXku--VFefQ_>)M2)jn-|K2c)r{0fBD zQ{lwfF<86Cvk+0MD9iA7XtQYa-YpZ;-BhFcp4Y)iE+A$Ob_&3N>BU6vWL)}Dkkv%Z zPs4glWcvYjyAzF9AuBtEKR=Gsu&>;r+YDTcTZns&=~EnTqBMItHU!LA3H+9*wpE>w zs`doUPx`C+#Vkh)nlMU5%vsrl(2$fdN!O8>CSI5(V{UkS1#E}Z1$ZBLr$VndBOLHF z4w!cMb@Xi$mJC)u9BC!*Vt9Q`FlbEKIW2Pa@VRcfWrpvZFi(8jrY5qWFzBZeA7)Ko z3)CCx*W>6ve-#hoL*Y5$xGEt(xkfG&o)e1UlbrXqg{Sey^jMcRxwri;Z(JmyamwB8 zfZvvtV~S^W&5JKWKO=K76^2yRVg$|acO(;mQ4;s*_eWkKdx3`#YY_AhwR zU?j)Om^CmX7zAnIW`_CM02^CIKOeLrW|<9>@%{VY+mmkNdsMtzVJjPM*${x+?FPlz zubGZcm6Dq@(!jjO5;1t?2T>S}7D;iU>v`!d47q%#Kseg-H1_+N-K%(o%oXqGAL{Ys z4n+@+qBS^`A+#a1`(A)Ma4c<7bqn_+Gx+psw)xln2zcUl7xXpLs)aQ>N==Kt3?+;0 z7klCh>+H|9nd&4CYpe!uyok$R2QU3C#~yi;!LQ8%2d;D)vZB=#<&<{7ut!M6S&AcR zLwD|PN+AzjwHG{V2JWZ{1yI`%hejw22X&?;y&8P*^cpe@6SS0m%Sq?d82g&kIWG`P zEcE0M{U|BIpzE$9r2C|FUN3cU%%MxCuTxPfWP(K7Y|xK`-q0Q-Wi~xuY}OL4HPDf$ znsWcVRF^O&Bfeo0-N)jtP%Xfx-;X~&u)nR)*CjlUkeo1*M>v-+bK4sqDbX(~0H4b@=}&!|Vp;ZsR_Xa%Kl$_Cjsf{#MGw_)g^r;fh; zLW>)jePqz-s?yV?Q~onX76IOh4nsWSr*tY;7p7alxu~0po`;gq7@;PatfUBSQ#e7X zOQz7|BxQ`E^h~S6tLVj!Hyt}pH#!a=01hd{*=^W~ET4N~Tt>9?nzY3vao~kFa|BGPJvAxm61X zCpg(;RocusJuYF}u5>&kocy+b`=Jtup07J%lh^3$(nh$cY}lo(1$;s{*q~mwSdv6j zUFLL9K;d05B%J!lw$}vOF6~ndWNayMz1vv787XWp_P|AoF1jKkv7Ee;E#LmwTsYIv z^%{1`J`#i{1|v529Fqt~}|S@%$X`x))I8_fh5&WGSiPsypkQO2~E2=w~K66&G7fxLD^@aJ}@s zADfVekuoi48~3^o5B2;ebnC>kzehLZzSu8i($*Gz7Pq5rp&}XjwPT za$c47K@z(@{wCaE{`08ve8YWjGFD#R2m2Itn0I4z7_0+>^e ziw4ww=1-Cii4Qx`WeNA5M}+f>8?UQA7Yi3<^uo3{th-&P{0%o}knvHT1HH1dz7g74 zE=H|tts1B(sWzC~1-3C}Y#YNQn3b63#ub2jBEQkmi^XN}HpIoF^90WYTWC3rufboj z7Ep?(-x%TuWg-Zt*bShO6+S9zYrwneHkPj_+b9RBHB+50r~J2D zYTHBDqOo?}))69Rf9xcaKjD{rf}pE%Rkr*s_(@3^%HcjV^kePN^aHQ*{9xCaEiOHW zg`Qb2l${O;ed0;`bqW;faPZK@7@L`GP*bGz;cUymr8?RJG6yxH zMgAo2`iW|DTfC6kqW|#>3@`!FcYdF0y& zTcuUGn64-d&5-1{Hfz$hzx+vZ^^kUsNX`mbYEo~+-A0SpT9k5Sk7VPiQ+QAQD?JI5 zUbStKfo%++!_5Tkj;Sc??n}mEFa)3@rf(`_-1)xU`m)UaslO|xK=KHA$a28F@NDQl z(Z5-Bc@HE=@w8WBu}>7Fb#&-C-b(I9=GV>`V`NC#>4yW+^<=T7s4KqWQ8@>^RYk*u zC>I93n}n17edknG*~n>A1QZJ`A!<*-AOQ^VVE!4!3Q5zr^j|y;WcLpSePJmElZk_q zfS?0m*pFmWP&E^1_*4TZsA3a>*rX?JO3U_Nte}5o@c6}2Pn3DUF zBCbo~cbqvB)0B=BW8IMO^T1#aIwtq(vb7ycE^ytvC};R}F&)gh@{jMf${6>9TSz zH!b$&zG&ggyADTt1SF&AX`|UO%Z&BYrDSm7XWug?_NVLDi|V)C%iKxmd!>A(5J}*T zt8pRYNHJtR{ydlyBGcBTcEOR-)D}rh28k!bu2N!@-cXDQ$m)z;`m$*$_lu#L?`+vA z&P3C%xGRO;D1E&=$=Qy_y|#$`y0DIibt?3;7UhUc)6v$e6z_aRE@qe7pv0~#N_#|2 zY7X)0pPQp$0< z5S$RAIjwHjHmIDr=IW$MFu&e06Q^Fbsh|(d!Ih2cr-M-d3E6N%%;FN|{3Zo7lEZ^X zC`Xnu5sMMrYbisbdr7Si%J+eA`_Ri6MpBSIW3N!<+VF81dy19ieY{h8h)&l(`R4R2 zAq|1C3@ljQcoGGhg36xV(bW_+c@!1n&C8rtqrx}I@U+KWZ%i?GRsg( zn>^OLnx-)FX6k8BJvG{=$;b%cb%6KJnUKO4)xuO(&b(ym!Ico+tbg#D$_KN@?|zr*PN${Iw{(F#6m<0?qcO9}U6 z2F)q^_Po>?UT%SMARMsFnR%V9S`!Y--*$3q%Qh~rQ0sXHl4nPnY3wFVGaW_uV)3Ji zhg^f!4U>6C_NA5j7E-YHid-aM>{}`mf%)3DHke?3D%GK}WRw6mg^lPt#VHF==2cD_#HA411KB2}gFe6Rii`Iy*IUT8)-+2^M87)r8`}X|2dn zeD5Kd6Xg~-dlhP$)ZM^bEr7q}0UyQ#g6q)(n73Swq?qJ$XCS_cKUL3yFJV0BA*;V3 z9Db$u#;OWF`i<9Zg{_)^@YbWC9M4Da$*K;{o$}60f|%0zzJph&2TNU!|KP}dr)2sk z@b#Va$-%?gcU{AfR0=tjsKe?mz5dl$z=udCNVPqkyY%! zQNC=PKu_qOxTQGQ{=_ZC_A4Tk?;?f^dDs=LZFlUUCzfxXku#&{Ow?YF=V6frd_ zDW&o$+r=#dJ@*D**u1*UIte&UZ-|FrFtR_lJQZyvdK-rM@)?ph?hS0P+;5!NDYZ_= zSLuA`Z{>quZ~y+gS3Rl^5C5k`q#L<&sD20mfN%Zv7~xEYs^zfsXKMU?;t!JJ_~xa7 z3iJ$3Z*DJN%(e07LIFNBd!bFq;fi(djTPxpy*k`Bjm7A?OBR9+LKh zir5&UmX=LvOy@P+7@?Xxg=?a?79;sI3^P4E^7~D`o~{9Zq*o2N3Q+sO&8!dcKVzTy zygDP~Pc)7=&G&euA}B&GC1YFF0=Cuf9zT_}cUZf}Z&%l~rZd|_Y6g);FQEk@GNtGM zxC-bbTUp!E16|7Wq(UG*#Cb79HTfAwAF}qP(255LQOPm83}SgQqG(9l#G|IE z$4M-f#O{Hape70^DC%F0gpA5WOx1su6zeez0qu=_KKMZG3h?9u@j9c8x55we!LlVj3RQIaDrCiQ zaslC`eVBX0OXzktxJ^Vuw%1elKJeQ7hgVys;3LYnI-p_ZYuMDo8@tyFRsoao% zc8Yd31d!I?a7)@@Zo5J>Qgetiu|^G6jmK^#?oq?p?^3t%qQP(5iwpb|(Vv8A8QFSoO zAPglfi!QfkQ|PWi+t(hCov&P)9&1EtbqU~#x@xtvE5)O26%9&D5qdwRV#I8h1#qv( za(qRabMSyW)L#az`Y4DpKr@8PqgJ5jPe?t(AK-I7!ja_g`*0#Eh+n~y8Vi1ISHhpn zS&&dTCmoB-q4o4xp}Zywz@}HTDi(!Zv6K*XZK4e-63`q(HYm-1dO0+A*uA77%Jd^A60JCzg`N+q@P7>*d)QdnIW3CYfOZX1_eZ%E>zKg7+)<1-vzgQLs7T7z zYRFRnefIF3hcJ(YPOF`N(Xm6+MI$z7fwVoz4X*KwX| zJdwaBXb?{u5ywQ0grGubW=NZ)4_!@6{U93O&WvhR3BMXrxy}ecpmWP?+2&R5qpY~^ zCr-NxxYqrg9H=+EG@MFp&2Z7kGAeS8G=Lc2Jo_l6juIe&Nuz8wzqH z?*PrI$HP_$mR`xk5#a1#Wa3E3!vjl5NUz`kFnV8>w1GttF+zG36E`P9-S;!^3n(Ge z9}o8TkD_i);>u1y$O_@V773t87+?)>P_{ELG66OQyk1zDP@7)CzzGO%u_XjDFuGV6 znJ9@1>Au5T-n;s*GyjTWA$*t8%bFNl7zhE}fc^gwK*9N*nv)5*{0ch&?Ea85GBDCH zaIgVmGuY@D**FN9S^tQp;9#WVe6J_y;Pk(#reNRzoCd@!|T_|e1_#LF+$c4tStjLtXca0lmk*%>3&AYpmyfgyqkGsD@lgFd>ImjED%1E@@vqCHq4kZtf{e?d z(b)#$mR~>QFE%|c_xNG^Aro{u0ma)v*43ibGE0C6tg$Ag^w0z>g!Mkrhm3w>92+2^ zhpq~#Bbqi3;Iz8-H0qMaGeh*@*{aI(5r+RP*FiRdY5a79`AdYg*Vb ziaw$-dsKBm*&j1_l|ChQ;uuACYQsJ zbDd4APnnq822a_o5no&tWqxC@+fmCGOWlXCp4xfo6ZgpwFS_S2ytBhX?&iT83%`nt zi)M9j?K72T!X(J!S{ffcsY^vTUpJL(y?tV~DGTAGT!+2aqhq#3lxTfN56^4(YXHG{ z3x^j*%JM!_?iqdeS{M5EoXWiYb!_iL5Rb?K{#qB6PJz1sO zq2^1KLy*P}BaNYzUN>(l_x+qd$UgKXZjr_9LfQxgMPTcsDo#yqHJ_5^(v~bZ{I&Sc zRlfBCJkuFy_-h^W`;VXQC~2|d*S4ixLVC%l%Z!}EyIF7T$+N5$6rdywR zVrxc~jD+k$YxPckQKUpvC=)`M%2R6^_gyuUoMa827_&te|M2XV97-y^Rn1J8NSCrn zX^y{vp@4?_;7_s>JeHkTq0V|d@H;S=Q7pRiaSV1BI(UE)sU=+PqW&wF5?(O7gxiX8 zshxI#ZamM8-xKRkV5`%?>DI4|oI|I3}l{vA~ z0Hx}Przw1=DT*uEuNMs+PIjlWf!b#+n=9X-ZX6MBuAqNpbJzka*`}H7uu*fPe8Y!$ z5WAilE%&ri#CsYy*fW@Fk5q?Agl#x|P`YWClW5fypm?s=JIisg7qfrD(2sH*Wv_2Y?5`e7kd_Mm1Kduu zm#H+vtf@C{I$3C|1`bX$Wlb^8J1?*V7T37!7raugM}wd(ZLap3&O)m%5-TaW{U~=) zB3DfA`%we5>Vn_&s>6qQ+<%nHg*Cv+m zNf0v~q}{``p&=qbHq-CMS?GEtAZ@J~=pbjzmqmh_3s1fov!Sna`YCAu^{67LOswKy zhXLCjLWLu_e3#_Q5Du7bZX$%0l~lHF!B)8OFgxeg*F7L`ZHE9~ABu4_fp*LRTmz$k zkOexB9pYzz((hR?^CFs0LYeTNm2D|C@Q0@Dv3*LNy6m_ecjKV%_I;CIOwp!bS0y)n8D2)PimVaO5&);pir}n;} zH-Lpma(}!|nmNlv81`@`1q1WcAVHOyBIQpIysf?2Qli5CZ=eSxj92AtaF7yT=;7`W zi*RL?EH+{pf`>m^c;P#bY@5v7K^0T{tg76WBSWU- z<|*gAV4zB`_w|;wPj*RXeJgzfyL7mU{|{Q_pX~F0q2=F|O2>Dt(ix~s0Wt2<7RHW1 z)s5+oa8#h$_$TB3pP|XZ22KXn05e#iA_#2dAG#PY()z!*1B8KKXy7&uAtg{BBV?xo z2Im5y??7GE*x3k(o&JmTkE#{`TakC&lv0F?iGh)cftisB_{zz`47^MhVEm_ZEDS(& zJ|hb-Jvt}VpT4h~gNZ3D10gd5EHKFTzYfAb-U&?!|0QE#2kuV%m(2G6$T(TpfJ){2 zLHK`U?;n6;c|ZOvWBsR$nE|L?|E(S?a2x6$GS0vE%fQab`j2Zl7}fd&-v1_JX8!v)n3>tx z|6Y%og@FNh^ZeynW){}>d*QD#c4m&he?Mk+wtvhYGdm~S-|MjegRuWTf50x@Z`!}~ z!NST6v@iZHV`2OII9S*?{xPR4oWKVEek~^}`=4Y^4h9z1CJwMbyNh1g!UJeW0fPjT v005v>0_+vI?M5$YYYHIz<8Sc32M3G@04~*k+?OnzY@8ghWMrc9VzB=oQ?ZD{ literal 0 HcmV?d00001 diff --git a/svo/doc/notation.png b/svo/doc/notation.png new file mode 100644 index 0000000000000000000000000000000000000000..d613b70c287aff422211aaede98b677578c69bda GIT binary patch literal 27376 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 Date: Wed, 11 Jun 2014 15:43:55 +0200 Subject: [PATCH 144/215] Update README.md --- svo_analysis/README.md | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/svo_analysis/README.md b/svo_analysis/README.md index 3fe3ea6..84fd11e 100644 --- a/svo_analysis/README.md +++ b/svo_analysis/README.md @@ -14,39 +14,14 @@ Source your new `.bashrc` script, go to the new dataset folder and download the source `~/.bashrc` cd ${SVO_DATASET_DIR} - wget http://rpg.ifi.uzh.ch/datasets/flying_room_1_rig_1.tar.gz -O - | tar -xz - -TODO: replace this dataset with new ones. + wget http://rpg.ifi.uzh.ch/datasets/sin2_tex2_h1_v8_d.tar.gz -O - | tar -xz #### Run Benchmark In the _CMakeLists.txt_ of SVO you need to set the `TRACE` flag to `TRUE` and recompile SVO. Afterwards run - rosrun svo_analysis benchmark.py flying_room_1_fast + rosrun svo_analysis benchmark.py sin2_tex2_h1_v8_d The script will create a new folder in `svo_analysis/results/`, run svo on the dataset and save the tracefile in this folder and at the end it will run some scripts to generate plots from the tracefile. - - -#### Dataset file - -A dataset with motion-capture-system ground-truth should contain the following files - -* _images.txt_ - - # timestamp img/imagename - 1329330952.725747585296631 img/00000.png - 1329330952.765715122222900 img/00001.png - 1329330952.805604219436646 img/00002.png - ... - -* _groundtruth.txt_: groundtruth poses as acquired from a motion capture system - - # timestamp tx ty tz qx qy qz qw - -* _groundtruth_matched.txt_: the groundtruth pose associated to the images in images.txt. This file can be generated by the command: - - cd my_dataset - rosrun svo_analysis associate.py images.txt groundtruth.txt - From ab867a3047908afa40b9fc1884693f00bbf1b9c3 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 11 Jun 2014 17:41:10 +0200 Subject: [PATCH 145/215] added instructions on how to download test data. updated all tests for new dataset. --- svo/src/depth_filter.cpp | 7 ++++-- svo/test/README.md | 26 +++++++++++++++++++--- svo/test/test_depth_filter.cpp | 34 ++++++++++++++--------------- svo/test/test_feature_alignment.cpp | 8 +++---- svo/test/test_feature_detection.cpp | 4 ++-- svo/test/test_matcher.cpp | 32 +++++++++++++-------------- svo/test/test_pipeline.cpp | 12 ++++++---- svo/test/test_pose_optimizer.cpp | 14 ++++++------ svo/test/test_sparse_img_align.cpp | 6 ++--- 9 files changed, 84 insertions(+), 59 deletions(-) diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 7f8f3c3..1fdd342 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -126,7 +126,9 @@ void DepthFilter::initializeSeeds(FramePtr frame) seeds_.push_back(Seed(ftr, new_keyframe_mean_depth_, new_keyframe_min_depth_)); }); - SVO_DEBUG_STREAM("DepthFilter: Initialized "< results_; std::vector errors_; - double error_sum_; size_t n_converged_seeds_; vk::PinholeCamera* cam_; svo::DepthFilter* depth_filter_; @@ -65,7 +64,7 @@ class DepthFilterTest { DepthFilterTest::DepthFilterTest() : n_converged_seeds_(0), - cam_(new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240)), + cam_(new vk::PinholeCamera(752, 480, 315.5, 315.5, 376.0, 240.0)), depth_filter_(NULL) { errors_.reserve(1000); @@ -91,7 +90,6 @@ void DepthFilterTest::depthFilterCb(svo::Point* point, double depth_sigma2) void DepthFilterTest::testReconstruction( std::string dataset_dir, - std::string experiment_name) { vk::FileReader sequence_file_reader(dataset_dir+"/trajectory.txt"); @@ -110,28 +108,28 @@ void DepthFilterTest::testReconstruction( cam_->width(), cam_->height(), svo::Config::gridSize(), svo::Config::nPyrLevels())); svo::DepthFilter::callback_t depth_filter_cb = boost::bind(&DepthFilterTest::depthFilterCb, this, _1, _2); depth_filter_ = new svo::DepthFilter(feature_detector, depth_filter_cb); + depth_filter_->options_.verbose = true; - for(int i=0; it != sequence.end() && i<50; ++it, ++i) + for(int i=0; it != sequence.end() && i<20; ++it, ++i) { std::string img_name(dataset_dir+"/img/" + (*it).image_name_ + "_0.png"); - if(i==0) - printf("reading image: '%s'\n", img_name.c_str()); + printf("reading image: '%s'\n", img_name.c_str()); cv::Mat img(cv::imread(img_name, 0)); assert(!img.empty()); - Sophus::SE3 T_w_f = Sophus::SE3(it->q_.toRotationMatrix(), it->t_); + Sophus::SE3 T_w_f(it->q_, it->t_); if(i == 0) { // create reference frame and load ground truth depthmap - frame_ref_.reset(new svo::Frame(cam_, img, 0.0)); + frame_ref_ = boost::make_shared(cam_, img, 0.0); frame_ref_->T_f_w_ = T_w_f.inverse(); - depth_filter_->addKeyframe(frame_ref_, 3, 1); + depth_filter_->addKeyframe(frame_ref_, 2, 0.5); vk::blender_utils::loadBlenderDepthmap(dataset_dir+"/depth/" + (*it).image_name_ + "_0.depth", *cam_, depth_ref_); continue; } - n_converged_seeds_=0; - frame_cur_ = svo::FramePtr(new svo::Frame(cam_, img, 0.0)); + n_converged_seeds_ = 0; + frame_cur_ = boost::make_shared(cam_, img, 0.0); frame_cur_->T_f_w_ = T_w_f.inverse(); depth_filter_->addFrame(frame_cur_); n_converged_per_iteration.push_back(n_converged_seeds_); @@ -140,19 +138,19 @@ void DepthFilterTest::testReconstruction( // compute mean, median and variance of error in converged area { - printf("# converged: \t %zu (ref: 349)\n", errors_.size()); + printf("# converged: \t %zu (ref: 287)\n", errors_.size()); double sum_error = 0; std::for_each(errors_.begin(), errors_.end(), [&](double& e){sum_error+=e;}); - printf("mean error: \t %f cm (ref: 1.510507)\n", sum_error*100/errors_.size()); + printf("mean error: \t %f cm (ref: 0.080357)\n", sum_error*100/errors_.size()); std::vector::iterator it = errors_.begin()+0.5*errors_.size(); std::nth_element(errors_.begin(), it, errors_.end()); - printf("50-percentile: \t %f cm (ref: 0.809308)\n", *it*100); + printf("50-percentile: \t %f cm (ref: 0.062042)\n", *it*100); it = errors_.begin()+0.8*errors_.size(); std::nth_element(errors_.begin(), it, errors_.end()); - printf("80-percentile: \t %f cm (ref: 1.580725)\n", *it*100); + printf("80-percentile: \t %f cm (ref: 0.124526)\n", *it*100); it = errors_.begin()+0.95*errors_.size(); std::nth_element(errors_.begin(), it, errors_.end()); - printf("95-percentile: \t %f cm (ref: 2.557531)\n", *it*100); + printf("95-percentile: \t %f cm (ref: 0.200417)\n", *it*100); } // trace error @@ -199,8 +197,8 @@ void DepthFilterTest::testReconstruction( int main(int argc, char** argv) { DepthFilterTest test; - std::string dataset_dir(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1"); - std::string experiment_name("synth_fast_2d"); + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d"); + std::string experiment_name("sin2_tex2_h1_v8_d"); test.testReconstruction(dataset_dir, experiment_name); return 0; } diff --git a/svo/test/test_feature_alignment.cpp b/svo/test/test_feature_alignment.cpp index a7352e0..dac8911 100644 --- a/svo/test/test_feature_alignment.cpp +++ b/svo/test/test_feature_alignment.cpp @@ -54,7 +54,7 @@ void generateRefPatchNoWarpInterpolate(const cv::Mat& img, const Vector2d& px, int main(int argc, char **argv) { - std::string img_name(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1/img/frame_000001_0.png"); + std::string img_name(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d/img/frame_000002_0.png"); printf("Loading image '%s'\n", img_name.c_str()); cv::Mat img(cv::imread(img_name, 0)); assert(img.type() == CV_8UC1); @@ -86,7 +86,7 @@ int main(int argc, char **argv) svo::feature_alignment::align1D(img, dir, ref_patch_with_border.data, ref_patch, 3, px_est, h_inv); } Vector2d e = px_est-px_true; - printf("1000Xalign 1D took %fms, error = %fpx \t (ref i7-W520: 1.637000ms, Odroid-U2: ?, 0.008788px) \n", t.stop()*1000, e.norm()); + printf("1000Xalign 1D took %fms, error = %fpx \t (ref i7-W520: 1.982000ms, 0.000033px) \n", t.stop()*1000, e.norm()); t.start(); for(int i=0; i<1000; ++i) @@ -95,7 +95,7 @@ int main(int argc, char **argv) svo::feature_alignment::align2D(img, ref_patch_with_border.data, ref_patch, 3, px_est, true); } e = px_est-px_true; - printf("1000Xalign 2D took %fms, error = %fpx \t (ref i7-W520: 2.147000ms, Odroid-U2: ?, 0.009632px)\n", t.stop()*1000, e.norm()); + printf("1000Xalign 2D took %fms, error = %fpx \t (ref i7-W520: 2.306000ms, 0.015102px)\n", t.stop()*1000, e.norm()); #ifdef __SSE2__ // Note, this KLT implementation is not invariant to illuminatino changes! @@ -106,7 +106,7 @@ int main(int argc, char **argv) svo::feature_alignment::align2D_SSE2(img, ref_patch_with_border.data, ref_patch, 3, px_est); } e = px_est-px_true; - printf("1000Xalign 2D SSE2 %fms, error = %fpx \t (ref i7-W520: 0.548000ms, 0.023032px)\n", t.stop()*1000, e.norm()); + printf("1000Xalign 2D SSE2 %fms, error = %fpx \t (ref i7-W520: 0.460000ms, 0.021881px)\n", t.stop()*1000, e.norm()); #endif #ifdef __ARM_NEON__ diff --git a/svo/test/test_feature_detection.cpp b/svo/test/test_feature_detection.cpp index b91e97a..3ba2b2f 100644 --- a/svo/test/test_feature_detection.cpp +++ b/svo/test/test_feature_detection.cpp @@ -34,7 +34,7 @@ using namespace std; void testCornerDetector() { - std::string img_name(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1/img/frame_000001_0.png"); + std::string img_name(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d/img/frame_000002_0.png"); printf("Loading image '%s'\n", img_name.c_str()); cv::Mat img(cv::imread(img_name, 0)); assert(img.type() == CV_8UC1 && !img.empty()); @@ -51,7 +51,7 @@ void testCornerDetector() { fast_detector.detect(frame.get(), frame->img_pyr_, svo::Config::triangMinCornerScore(), fts); } - printf("Fast corner detection took %f ms, %zu corners detected (ref i7-W520: 8.06878ms, 416)\n", t.stop()*10, fts.size()); + printf("Fast corner detection took %f ms, %zu corners detected (ref i7-W520: 7.166360ms, 40000)\n", t.stop()*10, fts.size()); printf("Note, in this case, feature detection also contains the cam2world projection of the feature.\n"); cv::Mat img_rgb = cv::Mat(img.size(), CV_8UC3); cv::cvtColor(img, img_rgb, CV_GRAY2RGB); diff --git a/svo/test/test_matcher.cpp b/svo/test/test_matcher.cpp index 37ad1f1..0b65cb9 100644 --- a/svo/test/test_matcher.cpp +++ b/svo/test/test_matcher.cpp @@ -31,14 +31,14 @@ class MatcherTest { public: MatcherTest() { - cam_ = new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240); + cam_ = new vk::PinholeCamera(752, 480, 315.5, 315.5, 376.0, 240.0); // load images - std::string dataset_dir(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1"); - std::string img_name(dataset_dir+"/img/frame_000071_0.png"); + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d"); + std::string img_name(dataset_dir+"/img/frame_000002_0.png"); printf("Loading image '%s'\n", img_name.c_str()); cv::Mat img_ref(cv::imread(img_name, 0)); - img_name = std::string(dataset_dir+"/img/frame_000097_0.png"); + img_name = std::string(dataset_dir+"/img/frame_000006_0.png"); printf("Loading image '%s'\n", img_name.c_str()); cv::Mat img_cur(cv::imread(img_name, 0)); assert(!img_ref.empty() && !img_cur.empty()); @@ -49,15 +49,15 @@ class MatcherTest { ref_ftr_ = new svo::Feature(frame_ref_, Eigen::Vector2d(300, 260), 0); // set poses - Eigen::Vector3d t_w_ref(1.0054399967193604, 1.75655996799469, 4.610799789428711); - Eigen::Vector3d t_w_cur(-0.046640001237392426, 2.163439989089966, 4.6279802322387695); - Eigen::Quaterniond q_w_ref(0.015279541723430157, 0.7095794081687927, 0.7044594287872314, 0.0006494877743534744); - Eigen::Quaterniond q_w_cur(0.004395846277475357, -0.7776520252227783, -0.6286740899085999, -0.0026246386114507914); - frame_ref_->T_f_w_ = Sophus::SE3(q_w_ref.toRotationMatrix(), t_w_ref).inverse(); - frame_cur_->T_f_w_ = Sophus::SE3(q_w_cur.toRotationMatrix(), t_w_cur).inverse(); + Eigen::Vector3d t_w_ref(0.1131, 0.1131, 2.0000); + Eigen::Vector3d t_w_cur(0.5673, 0.5641, 2.0000); + Eigen::Quaterniond q_w_ref(0.0, 0.8227, 0.2149, 0.0); + Eigen::Quaterniond q_w_cur(0.0, 0.8235, 0.2130, 0.0); + frame_ref_->T_f_w_ = Sophus::SE3(q_w_ref, t_w_ref).inverse(); + frame_cur_->T_f_w_ = Sophus::SE3(q_w_cur, t_w_cur).inverse(); // load ground-truth depth - vk::blender_utils::loadBlenderDepthmap(dataset_dir+"/depth/frame_000071_0.depth", *cam_, depth_ref_); + vk::blender_utils::loadBlenderDepthmap(dataset_dir+"/depth/frame_000002_0.depth", *cam_, depth_ref_); } virtual ~MatcherTest() @@ -114,17 +114,17 @@ void MatcherTest::testEpipolarSearchFullImg() } // compute mean, median and variance of error in converged area - printf("n converged: \t %zu mm (ref: 169936)\n", n_converged); - printf("mean error: \t %f mm (ref: 1.912410)\n", sum_error*100/n_converged); + printf("n converged: \t %zu mm (ref: 216114)\n", n_converged); + printf("mean error: \t %f mm (ref: 0.410084)\n", sum_error*100/n_converged); std::vector::iterator it = errors.begin()+0.5*errors.size(); std::nth_element(errors.begin(), it, errors.end()); - printf("50-percentile: \t %f mm (ref: 1.462241)\n", *it*100); + printf("50-percentile: \t %f mm (ref: 0.083203)\n", *it*100); it = errors.begin()+0.8*errors.size(); std::nth_element(errors.begin(), it, errors.end()); - printf("80-percentile: \t %f mm (ref: 2.620957)\n", *it*100); + printf("80-percentile: \t %f mm (ref: 0.161824)\n", *it*100); it = errors.begin()+0.95*errors.size(); std::nth_element(errors.begin(), it, errors.end()); - printf("95-percentile: \t %f mm (ref: 4.154051)\n", *it*100); + printf("95-percentile: \t %f mm (ref: 0.263539)\n", *it*100); // save results to file std::ofstream output_stream; diff --git a/svo/test/test_pipeline.cpp b/svo/test/test_pipeline.cpp index 364b089..ede3b25 100644 --- a/svo/test/test_pipeline.cpp +++ b/svo/test/test_pipeline.cpp @@ -45,7 +45,7 @@ public: BenchmarkNode::BenchmarkNode() { - cam_ = new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240); + cam_ = new vk::PinholeCamera(752, 480, 315.5, 315.5, 376.0, 240.0); vo_ = new svo::FrameHandlerMono(cam_); vo_->start(); } @@ -58,13 +58,13 @@ BenchmarkNode::~BenchmarkNode() void BenchmarkNode::runFromFolder() { - for(int img_id = 1; img_id < 310; ++img_id) + for(int img_id = 2; img_id < 188; ++img_id) { // load image std::stringstream ss; - ss << svo::test_utils::getDatasetDir() << "/flying_room_1_rig_1/img/frame_" + ss << svo::test_utils::getDatasetDir() << "/sin2_tex2_h1_v8_d/img/frame_" << std::setw( 6 ) << std::setfill( '0' ) << img_id << "_0.png"; - if(img_id == 1) + if(img_id == 2) std::cout << "reading image " << ss.str() << std::endl; cv::Mat img(cv::imread(ss.str().c_str(), 0)); assert(!img.empty()); @@ -74,9 +74,13 @@ void BenchmarkNode::runFromFolder() // display tracking quality if(vo_->lastFrame() != NULL) + { std::cout << "Frame-Id: " << vo_->lastFrame()->id_ << " \t" << "#Features: " << vo_->lastNumObservations() << " \t" << "Proc. Time: " << vo_->lastProcessingTime()*1000 << "ms \n"; + + // access the pose of the camera via vo_->lastFrame()->T_f_w_. + } } } diff --git a/svo/test/test_pose_optimizer.cpp b/svo/test/test_pose_optimizer.cpp index 7dd79f8..59e0b46 100644 --- a/svo/test/test_pose_optimizer.cpp +++ b/svo/test/test_pose_optimizer.cpp @@ -37,11 +37,11 @@ class PoseOptimizerTest { public: PoseOptimizerTest() { - cam_ = new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240); + cam_ = new vk::PinholeCamera(752, 480, 315.5, 315.5, 376.0, 240.0); // load image - std::string dataset_dir(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1"); - std::string img_name(dataset_dir+"/img/frame_000001_0.png"); + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d"); + std::string img_name(dataset_dir+"/img/frame_000002_0.png"); printf("Loading image '%s'\n", img_name.c_str()); cv::Mat img(cv::imread(img_name, 0)); assert(!img.empty()); @@ -50,12 +50,12 @@ class PoseOptimizerTest { frame_.reset(new svo::Frame(cam_, img, 1.0)); // set pose - Eigen::Vector3d t_w_ref(2.139359951019287, -1.9544399976730347, 2.8595199584960938 ); - Eigen::Quaterniond q_w_ref(0.0027939670253545046, 0.8382523059844971, 0.5443645715713501, -0.03150530532002449); - frame_->T_f_w_ = Sophus::SE3(q_w_ref.toRotationMatrix(), t_w_ref).inverse(); + Eigen::Vector3d t_w_ref(0.1131, 0.1131, 2.0000); + Eigen::Quaterniond q_w_ref(0.0, 0.8227, 0.2149, 0.0); + frame_->T_f_w_ = Sophus::SE3(q_w_ref, t_w_ref).inverse(); // load ground-truth depth - vk::blender_utils::loadBlenderDepthmap(dataset_dir + "/depth/frame_000001_0.depth", *cam_, depthmap_); + vk::blender_utils::loadBlenderDepthmap(dataset_dir + "/depth/frame_000002_0.depth", *cam_, depthmap_); // detect features feature_detection::FastDetector detector( diff --git a/svo/test/test_sparse_img_align.cpp b/svo/test/test_sparse_img_align.cpp index fe1ece5..1312da0 100644 --- a/svo/test/test_sparse_img_align.cpp +++ b/svo/test/test_sparse_img_align.cpp @@ -47,7 +47,7 @@ class SparseImgAlignTest { }; SparseImgAlignTest::SparseImgAlignTest() : - cam_(new vk::PinholeCamera(752, 480, 217.083701215, 217.083701215, 376, 240)) + cam_(new vk::PinholeCamera(752, 480, 315.5, 315.5, 376.0, 240.0)) {} SparseImgAlignTest::~SparseImgAlignTest() @@ -82,7 +82,7 @@ void SparseImgAlignTest::testSequence( assert(!img.empty()); // load pose - Sophus::SE3 T_w_gt = Sophus::SE3(iter->q_.toRotationMatrix(), iter->t_); + Sophus::SE3 T_w_gt(iter->q_, iter->t_); Sophus::SE3 T_gt_w = T_w_gt.inverse(); // ground-truth if(i==0) @@ -152,7 +152,7 @@ void SparseImgAlignTest::testSequence( int main(int argc, char** argv) { std::string experiment_name("flying_room_1_rig_1_fast_minlev0"); - std::string dataset_dir(svo::test_utils::getDatasetDir() + "/flying_room_1_rig_1"); + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d"); svo::Config::triangMinCornerScore() = 20; svo::Config::kltMinLevel() = 0; SparseImgAlignTest test; From f9fa33aef28a318c1185981fbd414670d6eefa9e Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 12 Jun 2014 10:56:54 +0200 Subject: [PATCH 146/215] Update README.md --- svo_analysis/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo_analysis/README.md b/svo_analysis/README.md index 84fd11e..b3201b1 100644 --- a/svo_analysis/README.md +++ b/svo_analysis/README.md @@ -12,7 +12,7 @@ In your `.bashrc` script, create a new environment variable pointing to the data Source your new `.bashrc` script, go to the new dataset folder and download the test data: - source `~/.bashrc` + source ~/.bashrc cd ${SVO_DATASET_DIR} wget http://rpg.ifi.uzh.ch/datasets/sin2_tex2_h1_v8_d.tar.gz -O - | tar -xz From c5dda65e17df3cd2cb45e56b9fe9cace23ae2539 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 12 Jun 2014 10:57:13 +0200 Subject: [PATCH 147/215] Update README.md --- svo/test/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/test/README.md b/svo/test/README.md index 444bd6b..c70f832 100644 --- a/svo/test/README.md +++ b/svo/test/README.md @@ -10,7 +10,7 @@ In your `.bashrc` script, create a new environment variable pointing to the data Source your new `.bashrc` script, go to the new dataset folder and download the test data: - source `~/.bashrc` + source ~/.bashrc cd ${SVO_DATASET_DIR} wget http://rpg.ifi.uzh.ch/datasets/sin2_tex2_h1_v8_d.tar.gz -O - | tar -xz From 08fb6d2f146cf0a808e046609477ccbfd37f61bc Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 12 Jun 2014 11:08:59 +0200 Subject: [PATCH 148/215] added EIGEN_MAKE_ALIGNED_OPERATOR_NEW to Reprojector class. --- svo/include/svo/matcher.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/svo/include/svo/matcher.h b/svo/include/svo/matcher.h index d0d1134..7e823bc 100644 --- a/svo/include/svo/matcher.h +++ b/svo/include/svo/matcher.h @@ -64,6 +64,8 @@ void warpAffine( class Matcher { public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + static const int halfpatch_size_ = 4; static const int patch_size_ = 8; From 79f4d03672e1cdc4d976586994156d0bb00b4c16 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 12 Jun 2014 11:48:36 +0200 Subject: [PATCH 149/215] added EIGEN_MAKE_ALIGNED_OPERATOR_NEW to sparseImgAlign class. --- svo/include/svo/sparse_img_align.h | 1 + 1 file changed, 1 insertion(+) diff --git a/svo/include/svo/sparse_img_align.h b/svo/include/svo/sparse_img_align.h index c9da479..1bedfed 100644 --- a/svo/include/svo/sparse_img_align.h +++ b/svo/include/svo/sparse_img_align.h @@ -36,6 +36,7 @@ class SparseImgAlign : public vk::NLLSSolver<6, SE3> static const int patch_size_ = 2*patch_halfsize_; static const int patch_area_ = patch_size_*patch_size_; public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW cv::Mat resimg_; From 8fa5d9796a8af00c142d9dcfdbbdaf043f628528 Mon Sep 17 00:00:00 2001 From: Ketill Gunnarsson Date: Mon, 16 Jun 2014 21:42:01 +0200 Subject: [PATCH 150/215] added eigen align operator to frame_handler_mono.h and point.h --- svo/include/svo/frame_handler_mono.h | 2 ++ svo/include/svo/point.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/svo/include/svo/frame_handler_mono.h b/svo/include/svo/frame_handler_mono.h index 546e501..cfeb433 100644 --- a/svo/include/svo/frame_handler_mono.h +++ b/svo/include/svo/frame_handler_mono.h @@ -28,6 +28,8 @@ namespace svo { class FrameHandlerMono : public FrameHandlerBase { public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + FrameHandlerMono(vk::AbstractCamera* cam); virtual ~FrameHandlerMono(); diff --git a/svo/include/svo/point.h b/svo/include/svo/point.h index f7706be..e1bb81b 100644 --- a/svo/include/svo/point.h +++ b/svo/include/svo/point.h @@ -35,7 +35,8 @@ typedef Matrix Matrix23d; class Point : boost::noncopyable { public: - + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + enum PointType { TYPE_DELETED, TYPE_CANDIDATE, From ac5453efee96228efbaf8a1c51d52ba04e83240f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 17 Jun 2014 12:05:44 +0200 Subject: [PATCH 151/215] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aaf8b86..1e098a9 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ SVO has been tested under ROS Groovy, Hydro and Indigo with Ubuntu 12.04, 13.04 #### Licence -The source code is released under a GPLv3 licence. A professional edition license for closed-source projects is also available. For commercial use, please contact the authors. +The source code is released under a GPLv3 licence. A closed-source professional edition is available for commercial purposes. In this case, please contact the authors for further info. #### Citing From 90d64a9a893ba78b84d070257eb6da8274ee7668 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 18 Jun 2014 23:26:11 +0200 Subject: [PATCH 152/215] fixes #17 - building without ROS --- svo/test/test_depth_filter.cpp | 2 ++ svo/test/test_utils.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/svo/test/test_depth_filter.cpp b/svo/test/test_depth_filter.cpp index 7bbb1e9..4d22493 100644 --- a/svo/test/test_depth_filter.cpp +++ b/svo/test/test_depth_filter.cpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/svo/test/test_utils.h b/svo/test/test_utils.h index 5647879..2759fe0 100644 --- a/svo/test/test_utils.h +++ b/svo/test/test_utils.h @@ -19,9 +19,9 @@ #include #include // for getenv -#include #ifdef SVO_USE_ROS - #include +# include +# include #endif namespace svo { From 1720c393eadb20057f2cf7952f729d1933ae13be Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 19 Jun 2014 18:37:01 +0200 Subject: [PATCH 153/215] fixed compile flags for debug build --- svo/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 91c5603..9161027 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -30,17 +30,18 @@ IF(DEBUG_OUTPUT) ENDIF() # Set build flags, set ARM_ARCHITECTURE environment variable on Odroid -SET(CMAKE_CXX_FLAGS "-Wall -Werror -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") +SET(CMAKE_CXX_FLAGS "-Wall -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") IF(DEFINED ENV{ARM_ARCHITECTURE}) - SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -mfpu=neon -march=armv7-a -fomit-frame-pointer -fsee -funsafe-loop-optimizations -fno-signed-zeros -fno-math-errno -funroll-loops") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -march=armv7-a") ELSE() - SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -mmmx -msse -msse -msse2 -msse3 -mssse3 -fomit-frame-pointer -fsee -funsafe-loop-optimizations -fno-signed-zeros -fno-math-errno -funroll-loops") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse -msse2 -msse3 -mssse3") ENDIF() IF(CMAKE_COMPILER_IS_GNUCC) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") ENDIF() +SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -fsee -fomit-frame-pointer -fno-signed-zeros -fno-math-errno -funroll-loops") # Add plain cmake packages FIND_PACKAGE(OpenCV REQUIRED) From 8b32cd8d88acb65611415d5a3d2b3c83d710232b Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Thu, 19 Jun 2014 23:12:40 +0200 Subject: [PATCH 154/215] add boost system dependency. fixes #19 --- svo/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 9161027..2feb414 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -48,7 +48,7 @@ FIND_PACKAGE(OpenCV REQUIRED) FIND_PACKAGE(Eigen REQUIRED) FIND_PACKAGE(Sophus REQUIRED) FIND_PACKAGE(fast REQUIRED) -FIND_PACKAGE(Boost REQUIRED COMPONENTS thread) +FIND_PACKAGE(Boost REQUIRED COMPONENTS thread system) IF(USE_ROS) FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros) From 7d2263aeda72bbaa550525a5a29adea58ae42d60 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Tue, 24 Jun 2014 13:02:50 +0200 Subject: [PATCH 155/215] include , fixes #22 --- svo/include/svo/frame_handler_mono.h | 1 + 1 file changed, 1 insertion(+) diff --git a/svo/include/svo/frame_handler_mono.h b/svo/include/svo/frame_handler_mono.h index cfeb433..aed73be 100644 --- a/svo/include/svo/frame_handler_mono.h +++ b/svo/include/svo/frame_handler_mono.h @@ -17,6 +17,7 @@ #ifndef SVO_FRAME_HANDLER_H_ #define SVO_FRAME_HANDLER_H_ +#include #include #include #include From d6da40f6a0341dc4951715bfc1986c9cbc801603 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 25 Jun 2014 14:11:21 +0200 Subject: [PATCH 156/215] added include , fixes #23 --- svo/src/map.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/svo/src/map.cpp b/svo/src/map.cpp index aa63648..bb3bcf9 100644 --- a/svo/src/map.cpp +++ b/svo/src/map.cpp @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include #include #include #include @@ -342,7 +343,7 @@ void mapStatistics(Map* map) // compute average number of observations that each point has size_t n_frame_obs(0); size_t n_pts(0); - set points; + std::set points; for(auto it=map->keyframes_.begin(); it!=map->keyframes_.end(); ++it) { for(auto ftr=(*it)->fts_.begin(); ftr!=(*it)->fts_.end(); ++ftr) From ec351f478f2523cd0cf0b927bd4fc0630efb0812 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Fri, 27 Jun 2014 14:57:03 +0200 Subject: [PATCH 157/215] moved proj. jacobian out of loop. --- svo/src/sparse_img_align.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/svo/src/sparse_img_align.cpp b/svo/src/sparse_img_align.cpp index 78323e7..ce1570b 100644 --- a/svo/src/sparse_img_align.cpp +++ b/svo/src/sparse_img_align.cpp @@ -107,6 +107,10 @@ void SparseImgAlign::precomputeReferencePatches() const double depth(((*it)->point->pos_ - ref_pos).norm()); const Vector3d xyz_ref((*it)->f*depth); + // evaluate projection jacobian + Matrix frame_jac; + Frame::jacobian_xyz2uv(xyz_ref, frame_jac); + // compute bilateral interpolation weights for reference image const float subpix_u_ref = u_ref-u_ref_i; const float subpix_v_ref = v_ref-v_ref_i; @@ -131,10 +135,6 @@ void SparseImgAlign::precomputeReferencePatches() float dy = 0.5f * ((w_ref_tl*ref_img_ptr[stride] + w_ref_tr*ref_img_ptr[1+stride] + w_ref_bl*ref_img_ptr[stride*2] + w_ref_br*ref_img_ptr[stride*2+1]) -(w_ref_tl*ref_img_ptr[-stride] + w_ref_tr*ref_img_ptr[1-stride] + w_ref_bl*ref_img_ptr[0] + w_ref_br*ref_img_ptr[1])); - // evaluate jacobian and cache - Matrix frame_jac; - Frame::jacobian_xyz2uv(xyz_ref, frame_jac); - // cache the jacobian jacobian_cache_.col(feature_counter*patch_area_ + pixel_counter) = (dx*frame_jac.row(0) + dy*frame_jac.row(1))*(focal_length / (1< Date: Mon, 30 Jun 2014 19:35:30 +0200 Subject: [PATCH 158/215] using ${OpenCV_LIBS} instead of ${OpenCV_LIBRARIES}, fixes #24. thanks Jamaslab & pablospe --- svo/CMakeLists.txt | 2 +- svo_ros/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 2feb414..703e379 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -76,7 +76,7 @@ INCLUDE_DIRECTORIES( # Set link libraries LIST(APPEND LINK_LIBS - ${OpenCV_LIBRARIES} + ${OpenCV_LIBS} ${Sophus_LIBRARIES} ${Boost_LIBRARIES} ${fast_LIBRARIES} diff --git a/svo_ros/CMakeLists.txt b/svo_ros/CMakeLists.txt index cb1b286..32df703 100644 --- a/svo_ros/CMakeLists.txt +++ b/svo_ros/CMakeLists.txt @@ -55,7 +55,7 @@ INCLUDE_DIRECTORIES( # Set link libraries LIST(APPEND LINK_LIBS - ${OpenCV_LIBRARIES} + ${OpenCV_LIBS} ${Sophus_LIBRARIES} ${Boost_LIBRARIES} ${catkin_LIBRARIES} From b4696fda0a286a1e13532e8be8c4d6dd7065020f Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 30 Jun 2014 20:43:15 +0200 Subject: [PATCH 159/215] using std::isnan instead of isnanf --- svo/src/depth_filter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 1fdd342..1f70be8 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -309,7 +309,7 @@ void DepthFilter::getSeedsCopy(const FramePtr& frame, std::list& seeds) void DepthFilter::updateSeed(const float x, const float tau2, Seed* seed) { float norm_scale = sqrt(seed->sigma2 + tau2); - if(isnanf(norm_scale)) + if(std::isnan(norm_scale)) return; boost::math::normal_distribution nd(seed->mu, norm_scale); float s2 = 1./(1./seed->sigma2 + 1./tau2); From 2eabd6d4b415635c45d6e91278cb9b1f06439da7 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 7 Jul 2014 17:08:06 +0200 Subject: [PATCH 160/215] changed memory allocation in matcher (#27) --- svo/include/svo/matcher.h | 8 ++++---- svo/src/matcher.cpp | 14 -------------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/svo/include/svo/matcher.h b/svo/include/svo/matcher.h index 7e823bc..b53340e 100644 --- a/svo/include/svo/matcher.h +++ b/svo/include/svo/matcher.h @@ -91,8 +91,8 @@ public: {} } options_; - uint8_t* patch_; - uint8_t* patch_with_border_; + uint8_t patch_[patch_size_*patch_size_] __attribute__ ((aligned (16))); + uint8_t patch_with_border_[(patch_size_+2)*(patch_size_+2)] __attribute__ ((aligned (16))); Matrix2d A_cur_ref_; //!< affine warp matrix Vector2d epi_dir_; double epi_length_; //!< length of epipolar line segment in pixels (only used for epipolar search) @@ -102,8 +102,8 @@ public: Feature* ref_ftr_; Vector2d px_cur_; - Matcher(); - ~Matcher(); + Matcher() = default; + ~Matcher() = default; /// Find a match by directly applying subpix refinement. /// IMPORTANT! This function assumes that px_cur is already set to an estimate that is within ~2-3 pixel of the final result! diff --git a/svo/src/matcher.cpp b/svo/src/matcher.cpp index 0ec7714..38a89fb 100644 --- a/svo/src/matcher.cpp +++ b/svo/src/matcher.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -107,19 +106,6 @@ void warpAffine( } // namespace warp - -Matcher::Matcher() -{ - patch_ = vk::aligned_mem::aligned_alloc(patch_size_*patch_size_, 16); - patch_with_border_ = vk::aligned_mem::aligned_alloc((patch_size_+2)*(patch_size_+2), 16); -} - -Matcher::~Matcher() -{ - free(patch_); - free(patch_with_border_); -} - bool depthFromTriangulation( const SE3& T_search_ref, const Vector3d& f_ref, From 6f6c4c9930d9662b129ab24063bcc3abec1d373d Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Wed, 13 Aug 2014 17:54:43 +0200 Subject: [PATCH 161/215] speeding up initialization by using previous flow estimate in klt tracking. --- svo/src/initialization.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/src/initialization.cpp b/svo/src/initialization.cpp index 16d1c80..84b9baf 100644 --- a/svo/src/initialization.cpp +++ b/svo/src/initialization.cpp @@ -144,7 +144,7 @@ void trackKlt( px_ref, px_cur, status, error, cv::Size2i(klt_win_size, klt_win_size), - 4, termcrit); + 4, termcrit, cv::OPTFLOW_USE_INITIAL_FLOW); vector::iterator px_ref_it = px_ref.begin(); vector::iterator px_cur_it = px_cur.begin(); From 3ba099372ff9a5ecb849ad824eab7df893fee0ad Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 1 Sep 2014 14:42:41 +0200 Subject: [PATCH 162/215] Fixes #44, bug in KeyPoint selection --- svo/src/frame.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/svo/src/frame.cpp b/svo/src/frame.cpp index f9b2bd0..0779891 100644 --- a/svo/src/frame.cpp +++ b/svo/src/frame.cpp @@ -87,8 +87,8 @@ void Frame::checkKeyPoints(Feature* ftr) // center pixel if(key_pts_[0] == NULL) key_pts_[0] = ftr; - else if(max(abs(ftr->px[0]-cu), abs(ftr->px[1]-cv)) - < max(abs(key_pts_[0]->px[0]-cu), abs(key_pts_[0]->px[1]-cv))) + else if(std::max(std::fabs(ftr->px[0]-cu), std::fabs(ftr->px[1]-cv)) + < std::max(std::fabs(key_pts_[0]->px[0]-cu), std::fabs(key_pts_[0]->px[1]-cv))) key_pts_[0] = ftr; if(ftr->px[0] >= cu && ftr->px[1] >= cv) @@ -96,7 +96,7 @@ void Frame::checkKeyPoints(Feature* ftr) if(key_pts_[1] == NULL) key_pts_[1] = ftr; else if((ftr->px[0]-cu) * (ftr->px[1]-cv) - > (key_pts_[1]->px[0]-cu) * (key_pts_[1]->px[0]-cv)) + > (key_pts_[1]->px[0]-cu) * (key_pts_[1]->px[1]-cv)) key_pts_[1] = ftr; } if(ftr->px[0] >= cu && ftr->px[1] < cv) @@ -104,7 +104,7 @@ void Frame::checkKeyPoints(Feature* ftr) if(key_pts_[2] == NULL) key_pts_[2] = ftr; else if((ftr->px[0]-cu) * (ftr->px[1]-cv) - < (key_pts_[2]->px[0]-cu) * (key_pts_[2]->px[0]-cv)) + > (key_pts_[2]->px[0]-cu) * (key_pts_[2]->px[1]-cv)) key_pts_[2] = ftr; } if(ftr->px[0] < cv && ftr->px[1] < cv) @@ -112,7 +112,7 @@ void Frame::checkKeyPoints(Feature* ftr) if(key_pts_[3] == NULL) key_pts_[3] = ftr; else if((ftr->px[0]-cu) * (ftr->px[1]-cv) - > (key_pts_[3]->px[0]-cu) * (key_pts_[3]->px[0]-cv)) + > (key_pts_[3]->px[0]-cu) * (key_pts_[3]->px[1]-cv)) key_pts_[3] = ftr; } if(ftr->px[0] < cv && ftr->px[1] >= cv) @@ -120,7 +120,7 @@ void Frame::checkKeyPoints(Feature* ftr) if(key_pts_[4] == NULL) key_pts_[4] = ftr; else if((ftr->px[0]-cu) * (ftr->px[1]-cv) - < (key_pts_[4]->px[0]-cu) * (key_pts_[4]->px[0]-cv)) + > (key_pts_[4]->px[0]-cu) * (key_pts_[4]->px[1]-cv)) key_pts_[4] = ftr; } } From 3ab81e54c2edfd5ce2968c7e1f32293d0acde971 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Sat, 8 Nov 2014 17:08:39 +0100 Subject: [PATCH 163/215] bugfix in getCloseKeyframes(). fixes #52 --- svo/src/map.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/svo/src/map.cpp b/svo/src/map.cpp index bb3bcf9..39aab50 100644 --- a/svo/src/map.cpp +++ b/svo/src/map.cpp @@ -103,23 +103,23 @@ void Map::addKeyframe(FramePtr new_keyframe) keyframes_.push_back(new_keyframe); } -void Map::getCloseKeyframes(const FramePtr& frame, list< pair >& close_kfs) const +void Map::getCloseKeyframes( + const FramePtr& frame, + std::list< std::pair >& close_kfs) const { - const Vector3d frame_pos(frame->pos()); - for(auto it_kf=keyframes_.begin(), ite_kf=keyframes_.end(); it_kf!=ite_kf; ++it_kf) + for(auto kf : keyframes_) { - // check first if Point is visible in the Keyframe, use therefore KeyPoints - for(auto it=(*it_kf)->key_pts_.begin(), ite=(*it_kf)->key_pts_.end(); it!=ite; ++it) + // check if kf has overlaping field of view with frame, use therefore KeyPoints + for(auto keypoint : kf->key_pts_) { - if(*it == NULL) + if(keypoint == nullptr) continue; - assert((*it)->point != NULL); - - if((*it_kf)->isVisible((*it)->point->pos_)) + if(frame->isVisible(keypoint->point->pos_)) { - close_kfs.push_back(pair(*it_kf, - (frame->T_f_w_.translation()-(*it_kf)->T_f_w_.translation()).norm())); + close_kfs.push_back( + std::make_pair( + kf, (frame->T_f_w_.translation()-kf->T_f_w_.translation()).norm())); break; // this keyframe has an overlapping field of view -> add to close_kfs } } From 1282a95dde9ada71f8b9521063d1d0b6bd7a4e94 Mon Sep 17 00:00:00 2001 From: Christian Forster Date: Mon, 10 Nov 2014 11:01:06 -0500 Subject: [PATCH 164/215] removed check if error increased in feature alignment. result is more feature matches and equal results to NEON version. --- svo/src/feature_alignment.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/svo/src/feature_alignment.cpp b/svo/src/feature_alignment.cpp index 15dcee3..faa4027 100644 --- a/svo/src/feature_alignment.cpp +++ b/svo/src/feature_alignment.cpp @@ -197,7 +197,7 @@ bool align2D( // termination condition const float min_update_squared = 0.03*0.03; const int cur_step = cur_img.step.p[0]; - float chi2 = 0; +// float chi2 = 0; Vector3f update; update.setZero(); for(int iter = 0; iter 0 && new_chi2 > chi2) { #if SUBPIX_VERBOSE @@ -248,8 +248,8 @@ bool align2D( v -= update[1]; break; } - chi2 = new_chi2; +*/ update = Hinv * Jres; u += update[0]; v += update[1]; @@ -259,7 +259,7 @@ bool align2D( cout << "Iter " << iter << ":" << "\t u=" << u << ", v=" << v << "\t update = " << update[0] << ", " << update[1] - << "\t new chi2 = " << new_chi2 << endl; +// << "\t new chi2 = " << new_chi2 << endl; #endif if(update[0]*update[0]+update[1]*update[1] < min_update_squared) From 30a43ccec6877781c0c0361637922d8a8685b2d0 Mon Sep 17 00:00:00 2001 From: Andre Phu-Van Nguyen Date: Tue, 3 Feb 2015 20:14:17 -0500 Subject: [PATCH 165/215] fix relocalization segfault --- svo/src/frame_handler_mono.cpp | 5 +++++ svo/src/map.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 3de6f7f..cd1865b 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -240,6 +240,11 @@ FrameHandlerMono::UpdateResult FrameHandlerMono::relocalizeFrame( FramePtr ref_keyframe) { SVO_WARN_STREAM_THROTTLE(1.0, "Relocalizing frame"); + if(ref_keyframe == nullptr) + { + SVO_INFO_STREAM("Relocalization successful."); + return RESULT_FAILURE; + } SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), 30, SparseImgAlign::GaussNewton, false, false); size_t img_align_n_tracked = img_align.run(ref_keyframe, new_frame_); diff --git a/svo/src/map.cpp b/svo/src/map.cpp index 39aab50..2ecad1c 100644 --- a/svo/src/map.cpp +++ b/svo/src/map.cpp @@ -130,6 +130,11 @@ FramePtr Map::getClosestKeyframe(const FramePtr& frame) const { list< pair > close_kfs; getCloseKeyframes(frame, close_kfs); + if(close_kfs.empty()) + { + return nullptr; + } + // Sort KFs with overlap according to their closeness close_kfs.sort(boost::bind(&std::pair::second, _1) < From 7e7cb6e909b47dbcadc662540bd29aabb4599a6a Mon Sep 17 00:00:00 2001 From: Zichao Zhang Date: Thu, 12 Feb 2015 12:12:06 +0100 Subject: [PATCH 166/215] fixed info output in relocalization function --- svo/src/frame_handler_mono.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index cd1865b..3050ba7 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -242,7 +242,7 @@ FrameHandlerMono::UpdateResult FrameHandlerMono::relocalizeFrame( SVO_WARN_STREAM_THROTTLE(1.0, "Relocalizing frame"); if(ref_keyframe == nullptr) { - SVO_INFO_STREAM("Relocalization successful."); + SVO_INFO_STREAM("No reference keyframe."); return RESULT_FAILURE; } SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), From 56ae1884faa75697f204236ac67ea83cd69b2d37 Mon Sep 17 00:00:00 2001 From: MengwenTan <810684547@qq.com> Date: Wed, 8 Jul 2015 06:16:47 -0700 Subject: [PATCH 167/215] fixed the bug of checking if point is visible in the current image in DepthFilter::updateSeeds function --- svo/src/depth_filter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 1f70be8..bf3a686 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -225,7 +225,7 @@ void DepthFilter::updateSeeds(FramePtr frame) ++it; // behind the camera continue; } - if(!it->ftr->frame->cam_->isInFrame(it->ftr->frame->f2c(xyz_f).cast())) { + if(!frame->cam_->isInFrame(frame->f2c(xyz_f).cast())) { ++it; // point does not project in image continue; } From 4691e302a95b2d274f01d80c84a7813d368014e4 Mon Sep 17 00:00:00 2001 From: Zichao Zhang Date: Thu, 3 Dec 2015 10:58:53 +0100 Subject: [PATCH 168/215] use pyramid camera marker for visualization --- svo_ros/src/visualizer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index a17589f..951f713 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -211,9 +211,9 @@ void Visualizer::visualizeMarkers( if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) { - vk::output_helper::publishHexacopterMarker( + vk::output_helper::publishCameraMarker( pub_frames_, "cam_pos", "cams", ros::Time(frame->timestamp_), - 1, 0, 0.3, Vector3d(0.,0.,1.)); + 1, 0.3, Vector3d(0.,0.,1.)); vk::output_helper::publishPointMarker( pub_points_, T_world_from_vision_*frame->pos(), "trajectory", ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5)); From 245547da88676fadbf6a1e7505da205c3f6f9624 Mon Sep 17 00:00:00 2001 From: Kartik Mohta Date: Fri, 19 Feb 2016 04:37:08 -0500 Subject: [PATCH 169/215] visualizer: Use reserve not resize for keyframes vector in msg_info --- svo_ros/src/visualizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index 951f713..6662969 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -79,7 +79,7 @@ void Visualizer::publishMinimal( svo_msgs::Info msg_info; msg_info.header = header_msg; msg_info.processing_time = slam.lastProcessingTime(); - msg_info.keyframes.resize(slam.map().keyframes_.size()); + msg_info.keyframes.reserve(slam.map().keyframes_.size()); for(list::const_iterator it=slam.map().keyframes_.begin(); it!=slam.map().keyframes_.end(); ++it) msg_info.keyframes.push_back((*it)->id_); msg_info.stage = static_cast(slam.stage()); From 63a848c45800ff4a8429f77427d976b323d911da Mon Sep 17 00:00:00 2001 From: Quim Sanchez Date: Fri, 29 Apr 2016 13:16:35 +0200 Subject: [PATCH 170/215] Update initialization.h Forgotten renaming :) --- svo/include/svo/initialization.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/svo/include/svo/initialization.h b/svo/include/svo/initialization.h index 4513086..cb562e5 100644 --- a/svo/include/svo/initialization.h +++ b/svo/include/svo/initialization.h @@ -78,6 +78,6 @@ void computeHomography( SE3& T_cur_from_ref); } // namespace initialization -} // namespace nslam +} // namespace svo -#endif // NSLAM_INITIALIZATION_H +#endif // SVO_INITIALIZATION_H From ec240827b1b284fb3269e2b39d5871d92fd5d19f Mon Sep 17 00:00:00 2001 From: akira_you Date: Sat, 25 Mar 2017 05:57:53 +0900 Subject: [PATCH 171/215] Eigen alignment fix --- svo/include/svo/depth_filter.h | 2 +- svo/include/svo/global.h | 4 ++++ svo/include/svo/initialization.h | 18 +++++++++--------- svo/include/svo/reprojector.h | 2 +- svo/src/depth_filter.cpp | 8 ++++---- svo/src/frame_handler_mono.cpp | 1 - svo/src/initialization.cpp | 18 +++++++++--------- svo_ros/src/visualizer.cpp | 17 ++++++++--------- svo_ros/src/vo_node.cpp | 1 - 9 files changed, 36 insertions(+), 35 deletions(-) diff --git a/svo/include/svo/depth_filter.h b/svo/include/svo/depth_filter.h index 7c4ab19..6333e54 100644 --- a/svo/include/svo/depth_filter.h +++ b/svo/include/svo/depth_filter.h @@ -116,7 +116,7 @@ public: /// Can be used to compute the Next-Best-View in parallel. /// IMPORTANT! Make sure you hold a valid reference counting pointer to frame /// so it is not being deleted while you use it. - void getSeedsCopy(const FramePtr& frame, std::list& seeds); + void getSeedsCopy(const FramePtr& frame, std::list >& seeds); /// Return a reference to the seeds. This is NOT THREAD SAFE! std::list >& getSeeds() { return seeds_; } diff --git a/svo/include/svo/global.h b/svo/include/svo/global.h index 9f7cc97..7a3989b 100644 --- a/svo/include/svo/global.h +++ b/svo/include/svo/global.h @@ -25,6 +25,10 @@ #include #include +template > > +using vectorA = std::vector< T, Allocator > ; +template > > +using listA = std::list< T, Allocator > ; #include #include #include diff --git a/svo/include/svo/initialization.h b/svo/include/svo/initialization.h index cb562e5..ec74ccd 100644 --- a/svo/include/svo/initialization.h +++ b/svo/include/svo/initialization.h @@ -44,11 +44,11 @@ public: protected: vector px_ref_; //!< keypoints to be tracked in reference frame. vector px_cur_; //!< tracked keypoints in current frame. - vector f_ref_; //!< bearing vectors corresponding to the keypoints in the reference image. - vector f_cur_; //!< bearing vectors corresponding to the keypoints in the current image. + vectorA f_ref_; //!< bearing vectors corresponding to the keypoints in the reference image. + vectorA f_cur_; //!< bearing vectors corresponding to the keypoints in the current image. vector disparities_; //!< disparity between first and second frame. vector inliers_; //!< inliers after the geometric check (e.g., Homography). - vector xyz_in_cur_; //!< 3D points computed during the geometric check. + vectorA xyz_in_cur_; //!< 3D points computed during the geometric check. SE3 T_cur_from_ref_; //!< computed transformation between the first two frames. }; @@ -56,7 +56,7 @@ protected: void detectFeatures( FramePtr frame, vector& px_vec, - vector& f_vec); + vectorA& f_vec); /// Compute optical flow (Lucas Kanade) for selected keypoints. void trackKlt( @@ -64,17 +64,17 @@ void trackKlt( FramePtr frame_cur, vector& px_ref, vector& px_cur, - vector& f_ref, - vector& f_cur, + vectorA& f_ref, + vectorA& f_cur, vector& disparities); void computeHomography( - const vector& f_ref, - const vector& f_cur, + const vectorA& f_ref, + const vectorA& f_cur, double focal_length, double reprojection_threshold, vector& inliers, - vector& xyz_in_cur, + vectorA& xyz_in_cur, SE3& T_cur_from_ref); } // namespace initialization diff --git a/svo/include/svo/reprojector.h b/svo/include/svo/reprojector.h index 7207b54..e345f0d 100644 --- a/svo/include/svo/reprojector.h +++ b/svo/include/svo/reprojector.h @@ -72,7 +72,7 @@ private: Vector2d px; //!< projected 2D pixel location. Candidate(Point* pt, Vector2d& px) : pt(pt), px(px) {} }; - typedef std::list > Cell; + typedef std::list Cell; typedef std::vector CandidateGrid; /// The grid stores a set of candidate matches. For every grid cell we try to find one match. diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index bf3a686..4eb6249 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -135,7 +135,7 @@ void DepthFilter::removeKeyframe(FramePtr frame) { seeds_updating_halt_ = true; lock_t lock(seeds_mut_); - list::iterator it=seeds_.begin(); + std::list >::iterator it=seeds_.begin(); size_t n_removed = 0; while(it!=seeds_.end()) { @@ -200,7 +200,7 @@ void DepthFilter::updateSeeds(FramePtr frame) // for all the seeds in every frame! size_t n_updates=0, n_failed_matches=0, n_seeds = seeds_.size(); lock_t lock(seeds_mut_); - list::iterator it=seeds_.begin(); + std::list >::iterator it=seeds_.begin(); const double focal_length = frame->cam_->errorMultiplier2(); double px_noise = 1.0; @@ -296,10 +296,10 @@ void DepthFilter::clearFrameQueue() frame_queue_.pop(); } -void DepthFilter::getSeedsCopy(const FramePtr& frame, std::list& seeds) +void DepthFilter::getSeedsCopy(const FramePtr& frame, std::list >& seeds) { lock_t lock(seeds_mut_); - for(std::list::iterator it=seeds_.begin(); it!=seeds_.end(); ++it) + for(std::list >::iterator it=seeds_.begin(); it!=seeds_.end(); ++it) { if (it->ftr->frame == frame.get()) seeds.push_back(*it); diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 3050ba7..4facc51 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -84,7 +84,6 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) // set last frame last_frame_ = new_frame_; new_frame_.reset(); - // finish processing finishFrameProcessingCommon(last_frame_->id_, res, last_frame_->nObs()); } diff --git a/svo/src/initialization.cpp b/svo/src/initialization.cpp index 84b9baf..d8f947a 100644 --- a/svo/src/initialization.cpp +++ b/svo/src/initialization.cpp @@ -107,7 +107,7 @@ void KltHomographyInit::reset() void detectFeatures( FramePtr frame, vector& px_vec, - vector& f_vec) + vectorA& f_vec) { Features new_features; feature_detection::FastDetector detector( @@ -129,8 +129,8 @@ void trackKlt( FramePtr frame_cur, vector& px_ref, vector& px_cur, - vector& f_ref, - vector& f_cur, + vectorA& f_ref, + vectorA& f_cur, vector& disparities) { const double klt_win_size = 30.0; @@ -148,7 +148,7 @@ void trackKlt( vector::iterator px_ref_it = px_ref.begin(); vector::iterator px_cur_it = px_cur.begin(); - vector::iterator f_ref_it = f_ref.begin(); + vectorA::iterator f_ref_it = f_ref.begin(); f_cur.clear(); f_cur.reserve(px_cur.size()); disparities.clear(); disparities.reserve(px_cur.size()); for(size_t i=0; px_ref_it != px_ref.end(); ++i) @@ -169,16 +169,16 @@ void trackKlt( } void computeHomography( - const vector& f_ref, - const vector& f_cur, + const vectorA& f_ref, + const vectorA& f_cur, double focal_length, double reprojection_threshold, vector& inliers, - vector& xyz_in_cur, + vectorA& xyz_in_cur, SE3& T_cur_from_ref) { - vector > uv_ref(f_ref.size()); - vector > uv_cur(f_cur.size()); + vectorA uv_ref(f_ref.size()); + vectorA uv_cur(f_cur.size()); for(size_t i=0, i_max=f_ref.size(); ipx[0]+3*(*it)->grad[1], (*it)->px[1]-3*(*it)->grad[0]), cv::Point2f((*it)->px[0]-3*(*it)->grad[1], (*it)->px[1]+3*(*it)->grad[0]), cv::Scalar(255,0,255), 2); - else + else//point size 5x5 cv::rectangle(img_rgb, cv::Point2f((*it)->px[0]-2, (*it)->px[1]-2), cv::Point2f((*it)->px[0]+2, (*it)->px[1]+2), cv::Scalar(0,255,0), CV_FILLED); } } - if(img_pub_level_ == 1) + else if(img_pub_level_ == 1){//point size 3x3 for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) cv::rectangle(img_rgb, cv::Point2f((*it)->px[0]/scale-1, (*it)->px[1]/scale-1), cv::Point2f((*it)->px[0]/scale+1, (*it)->px[1]/scale+1), cv::Scalar(0,255,0), CV_FILLED); - else - for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) - cv::rectangle(img_rgb, - cv::Point2f((*it)->px[0]/scale, (*it)->px[1]/scale), - cv::Point2f((*it)->px[0]/scale, (*it)->px[1]/scale), - cv::Scalar(0,255,0), CV_FILLED); - + }else{ //point size 1x1 + for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it){ + cv::Vec3b &p= img_rgb.at((*it)->px[1]/scale, (*it)->px[0]/scale); + p[0]=0;p[1]=255;p[2]=0; + } + } cv_bridge::CvImage img_msg; img_msg.header = header_msg; img_msg.image = img_rgb; diff --git a/svo_ros/src/vo_node.cpp b/svo_ros/src/vo_node.cpp index 8a6f88c..c9fbb84 100644 --- a/svo_ros/src/vo_node.cpp +++ b/svo_ros/src/vo_node.cpp @@ -13,7 +13,6 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . - #include #include #include From 0e36dabb6fb29ba947039c0ce96d3cf4f783b6ff Mon Sep 17 00:00:00 2001 From: akira_you Date: Sun, 26 Mar 2017 07:57:52 +0900 Subject: [PATCH 172/215] use EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION and use same CXX_FLAGS for rpg_svo rpg_vikit --- svo/CMakeLists.txt | 1 + svo/include/svo/depth_filter.h | 6 +++--- svo/include/svo/global.h | 10 ++++++---- svo/include/svo/initialization.h | 18 +++++++++--------- svo/src/depth_filter.cpp | 8 ++++---- svo/src/initialization.cpp | 18 +++++++++--------- svo_ros/CMakeLists.txt | 9 ++++++++- 7 files changed, 40 insertions(+), 30 deletions(-) diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 703e379..15257be 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -30,6 +30,7 @@ IF(DEBUG_OUTPUT) ENDIF() # Set build flags, set ARM_ARCHITECTURE environment variable on Odroid +# Set build flags. Set IS_ARM on odroid board as environment variable SET(CMAKE_CXX_FLAGS "-Wall -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") IF(DEFINED ENV{ARM_ARCHITECTURE}) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -march=armv7-a") diff --git a/svo/include/svo/depth_filter.h b/svo/include/svo/depth_filter.h index 6333e54..70f6df3 100644 --- a/svo/include/svo/depth_filter.h +++ b/svo/include/svo/depth_filter.h @@ -116,10 +116,10 @@ public: /// Can be used to compute the Next-Best-View in parallel. /// IMPORTANT! Make sure you hold a valid reference counting pointer to frame /// so it is not being deleted while you use it. - void getSeedsCopy(const FramePtr& frame, std::list >& seeds); + void getSeedsCopy(const FramePtr& frame, std::list& seeds); /// Return a reference to the seeds. This is NOT THREAD SAFE! - std::list >& getSeeds() { return seeds_; } + std::list& getSeeds() { return seeds_; } /// Bayes update of the seed, x is the measurement, tau2 the measurement uncertainty static void updateSeed( @@ -137,7 +137,7 @@ public: protected: feature_detection::DetectorPtr feature_detector_; callback_t seed_converged_cb_; - std::list > seeds_; + std::list seeds_; boost::mutex seeds_mut_; bool seeds_updating_halt_; //!< Set this value to true when seeds updating should be interrupted. boost::thread* thread_; diff --git a/svo/include/svo/global.h b/svo/include/svo/global.h index 7a3989b..03aff4e 100644 --- a/svo/include/svo/global.h +++ b/svo/include/svo/global.h @@ -25,14 +25,16 @@ #include #include -template > > -using vectorA = std::vector< T, Allocator > ; -template > > -using listA = std::list< T, Allocator > ; #include #include #include #include +#include +#ifndef RPG_SVO_VIKIT_IS_VECTOR_SPECIALIZED //Guard for rpg_vikit +#define RPG_SVO_VIKIT_IS_VECTOR_SPECIALIZED +EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector3d) +EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector2d) +#endif #ifdef SVO_USE_ROS #include diff --git a/svo/include/svo/initialization.h b/svo/include/svo/initialization.h index ec74ccd..cb562e5 100644 --- a/svo/include/svo/initialization.h +++ b/svo/include/svo/initialization.h @@ -44,11 +44,11 @@ public: protected: vector px_ref_; //!< keypoints to be tracked in reference frame. vector px_cur_; //!< tracked keypoints in current frame. - vectorA f_ref_; //!< bearing vectors corresponding to the keypoints in the reference image. - vectorA f_cur_; //!< bearing vectors corresponding to the keypoints in the current image. + vector f_ref_; //!< bearing vectors corresponding to the keypoints in the reference image. + vector f_cur_; //!< bearing vectors corresponding to the keypoints in the current image. vector disparities_; //!< disparity between first and second frame. vector inliers_; //!< inliers after the geometric check (e.g., Homography). - vectorA xyz_in_cur_; //!< 3D points computed during the geometric check. + vector xyz_in_cur_; //!< 3D points computed during the geometric check. SE3 T_cur_from_ref_; //!< computed transformation between the first two frames. }; @@ -56,7 +56,7 @@ protected: void detectFeatures( FramePtr frame, vector& px_vec, - vectorA& f_vec); + vector& f_vec); /// Compute optical flow (Lucas Kanade) for selected keypoints. void trackKlt( @@ -64,17 +64,17 @@ void trackKlt( FramePtr frame_cur, vector& px_ref, vector& px_cur, - vectorA& f_ref, - vectorA& f_cur, + vector& f_ref, + vector& f_cur, vector& disparities); void computeHomography( - const vectorA& f_ref, - const vectorA& f_cur, + const vector& f_ref, + const vector& f_cur, double focal_length, double reprojection_threshold, vector& inliers, - vectorA& xyz_in_cur, + vector& xyz_in_cur, SE3& T_cur_from_ref); } // namespace initialization diff --git a/svo/src/depth_filter.cpp b/svo/src/depth_filter.cpp index 4eb6249..db24408 100644 --- a/svo/src/depth_filter.cpp +++ b/svo/src/depth_filter.cpp @@ -135,7 +135,7 @@ void DepthFilter::removeKeyframe(FramePtr frame) { seeds_updating_halt_ = true; lock_t lock(seeds_mut_); - std::list >::iterator it=seeds_.begin(); + std::list::iterator it=seeds_.begin(); size_t n_removed = 0; while(it!=seeds_.end()) { @@ -200,7 +200,7 @@ void DepthFilter::updateSeeds(FramePtr frame) // for all the seeds in every frame! size_t n_updates=0, n_failed_matches=0, n_seeds = seeds_.size(); lock_t lock(seeds_mut_); - std::list >::iterator it=seeds_.begin(); + std::list::iterator it=seeds_.begin(); const double focal_length = frame->cam_->errorMultiplier2(); double px_noise = 1.0; @@ -296,10 +296,10 @@ void DepthFilter::clearFrameQueue() frame_queue_.pop(); } -void DepthFilter::getSeedsCopy(const FramePtr& frame, std::list >& seeds) +void DepthFilter::getSeedsCopy(const FramePtr& frame, std::list& seeds) { lock_t lock(seeds_mut_); - for(std::list >::iterator it=seeds_.begin(); it!=seeds_.end(); ++it) + for(std::list::iterator it=seeds_.begin(); it!=seeds_.end(); ++it) { if (it->ftr->frame == frame.get()) seeds.push_back(*it); diff --git a/svo/src/initialization.cpp b/svo/src/initialization.cpp index d8f947a..571a0bc 100644 --- a/svo/src/initialization.cpp +++ b/svo/src/initialization.cpp @@ -107,7 +107,7 @@ void KltHomographyInit::reset() void detectFeatures( FramePtr frame, vector& px_vec, - vectorA& f_vec) + vector& f_vec) { Features new_features; feature_detection::FastDetector detector( @@ -129,8 +129,8 @@ void trackKlt( FramePtr frame_cur, vector& px_ref, vector& px_cur, - vectorA& f_ref, - vectorA& f_cur, + vector& f_ref, + vector& f_cur, vector& disparities) { const double klt_win_size = 30.0; @@ -148,7 +148,7 @@ void trackKlt( vector::iterator px_ref_it = px_ref.begin(); vector::iterator px_cur_it = px_cur.begin(); - vectorA::iterator f_ref_it = f_ref.begin(); + vector::iterator f_ref_it = f_ref.begin(); f_cur.clear(); f_cur.reserve(px_cur.size()); disparities.clear(); disparities.reserve(px_cur.size()); for(size_t i=0; px_ref_it != px_ref.end(); ++i) @@ -169,16 +169,16 @@ void trackKlt( } void computeHomography( - const vectorA& f_ref, - const vectorA& f_cur, + const vector& f_ref, + const vector& f_cur, double focal_length, double reprojection_threshold, vector& inliers, - vectorA& xyz_in_cur, + vector& xyz_in_cur, SE3& T_cur_from_ref) { - vectorA uv_ref(f_ref.size()); - vectorA uv_cur(f_cur.size()); + vector uv_ref(f_ref.size()); + vector uv_cur(f_cur.size()); for(size_t i=0, i_max=f_ref.size(); i Date: Wed, 31 Mar 2021 14:16:57 +0200 Subject: [PATCH 173/215] fix bug 238 --- svo/include/svo/depth_filter.h | 6 ++++-- svo_ros/CMakeLists.txt | 4 ++-- .../launch/{test_rig3.launch => test.launch} | 6 +++--- svo_ros/launch/usb_cam.launch | 21 +++++++++++++++++++ svo_ros/param/camera_pinhole.yaml | 18 ++++++++-------- svo_ros/src/vo_node.cpp | 1 + 6 files changed, 40 insertions(+), 16 deletions(-) rename svo_ros/launch/{test_rig3.launch => test.launch} (96%) create mode 100644 svo_ros/launch/usb_cam.launch diff --git a/svo/include/svo/depth_filter.h b/svo/include/svo/depth_filter.h index 70f6df3..1612d0e 100644 --- a/svo/include/svo/depth_filter.h +++ b/svo/include/svo/depth_filter.h @@ -119,7 +119,8 @@ public: void getSeedsCopy(const FramePtr& frame, std::list& seeds); /// Return a reference to the seeds. This is NOT THREAD SAFE! - std::list& getSeeds() { return seeds_; } + //std::list& getSeeds() { return seeds_; } Bug 238 + std::list>& getSeeds() { return seeds_; } /// Bayes update of the seed, x is the measurement, tau2 the measurement uncertainty static void updateSeed( @@ -137,7 +138,8 @@ public: protected: feature_detection::DetectorPtr feature_detector_; callback_t seed_converged_cb_; - std::list seeds_; + //std::list seeds_; + std::list> seeds_; boost::mutex seeds_mut_; bool seeds_updating_halt_; //!< Set this value to true when seeds updating should be interrupted. boost::thread* thread_; diff --git a/svo_ros/CMakeLists.txt b/svo_ros/CMakeLists.txt index f55b7fa..d0ce982 100644 --- a/svo_ros/CMakeLists.txt +++ b/svo_ros/CMakeLists.txt @@ -75,5 +75,5 @@ TARGET_LINK_LIBRARIES(svo_visualizer ${LINK_LIBS}) # Create Executables ADD_EXECUTABLE(vo src/vo_node.cpp) TARGET_LINK_LIBRARIES(vo svo_visualizer) -ADD_EXECUTABLE(benchmark src/benchmark_node.cpp) -TARGET_LINK_LIBRARIES(benchmark svo_visualizer) +#ADD_EXECUTABLE(benchmark src/benchmark_node.cpp) +#TARGET_LINK_LIBRARIES(benchmark svo_visualizer) diff --git a/svo_ros/launch/test_rig3.launch b/svo_ros/launch/test.launch similarity index 96% rename from svo_ros/launch/test_rig3.launch rename to svo_ros/launch/test.launch index e49f9e2..f83d479 100644 --- a/svo_ros/launch/test_rig3.launch +++ b/svo_ros/launch/test.launch @@ -4,13 +4,13 @@ - + - + @@ -18,4 +18,4 @@ - + \ No newline at end of file diff --git a/svo_ros/launch/usb_cam.launch b/svo_ros/launch/usb_cam.launch new file mode 100644 index 0000000..ad34684 --- /dev/null +++ b/svo_ros/launch/usb_cam.launch @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/svo_ros/param/camera_pinhole.yaml b/svo_ros/param/camera_pinhole.yaml index 4898bcd..506a856 100644 --- a/svo_ros/param/camera_pinhole.yaml +++ b/svo_ros/param/camera_pinhole.yaml @@ -1,11 +1,11 @@ cam_model: Pinhole -cam_width: 752 +cam_width: 640 cam_height: 480 -cam_fx: 414.536145 -cam_fy: 414.284429 -cam_cx: 348.804988 -cam_cy: 240.076451 -cam_d0: -0.283076 -cam_d1: 0.066674 -cam_d2: 0.000896 -cam_d3: 0.000778 \ No newline at end of file +cam_fx: 789.860721 +cam_fy: 790.097440 +cam_cx: 305.323524 +cam_cy: 260.464072 +cam_d0: 0.027470 +cam_d1: -0.051518 +cam_d2: 0.004375 +cam_d3: -0.004028 \ No newline at end of file diff --git a/svo_ros/src/vo_node.cpp b/svo_ros/src/vo_node.cpp index c9fbb84..3417b4d 100644 --- a/svo_ros/src/vo_node.cpp +++ b/svo_ros/src/vo_node.cpp @@ -116,6 +116,7 @@ void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) usleep(100000); } + void VoNode::processUserActions() { char input = remote_input_.c_str()[0]; From e9256c9903b304ee05c03df4f25b4259b98caeb5 Mon Sep 17 00:00:00 2001 From: gfuse Date: Mon, 5 Apr 2021 18:41:37 +0200 Subject: [PATCH 174/215] optimize the visualizer --- svo_ros/include/svo_ros/visualizer.h | 13 -- .../launch/{usb_cam.launch => Px30.launch} | 2 +- svo_ros/param/px30.yaml | 8 + svo_ros/src/visualizer.cpp | 198 +----------------- svo_ros/src/vo_node.cpp | 149 +++++-------- 5 files changed, 62 insertions(+), 308 deletions(-) rename svo_ros/launch/{usb_cam.launch => Px30.launch} (91%) create mode 100644 svo_ros/param/px30.yaml diff --git a/svo_ros/include/svo_ros/visualizer.h b/svo_ros/include/svo_ros/visualizer.h index dc8936d..4a09a8d 100644 --- a/svo_ros/include/svo_ros/visualizer.h +++ b/svo_ros/include/svo_ros/visualizer.h @@ -48,19 +48,11 @@ class Visualizer public: ros::NodeHandle pnh_; size_t trace_id_; - size_t img_pub_level_; - size_t img_pub_nth_; - size_t dense_pub_nth_; ros::Publisher pub_frames_; ros::Publisher pub_points_; ros::Publisher pub_pose_; ros::Publisher pub_info_; - ros::Publisher pub_dense_; - image_transport::Publisher pub_images_; tf::TransformBroadcaster br_; - bool publish_world_in_cam_frame_; - bool publish_map_every_frame_; - ros::Duration publish_points_display_time_; SE3 T_world_from_vision_; Visualizer(); @@ -78,13 +70,8 @@ public: const set& core_kfs, const Map& map); - void publishMapRegion(set frames); - void removeDeletedPts(const Map& map); - void displayKeyframeWithMps(const FramePtr& frame, int ts); - - void exportToDense(const FramePtr& frame); }; } // end namespace svo diff --git a/svo_ros/launch/usb_cam.launch b/svo_ros/launch/Px30.launch similarity index 91% rename from svo_ros/launch/usb_cam.launch rename to svo_ros/launch/Px30.launch index ad34684..53f9317 100644 --- a/svo_ros/launch/usb_cam.launch +++ b/svo_ros/launch/Px30.launch @@ -9,7 +9,7 @@ - + diff --git a/svo_ros/param/px30.yaml b/svo_ros/param/px30.yaml new file mode 100644 index 0000000..10fa932 --- /dev/null +++ b/svo_ros/param/px30.yaml @@ -0,0 +1,8 @@ +cam_model: ATAN +cam_width: 640 +cam_height: 480 +cam_fx: 0.463632 +cam_fy: 0.823661 +cam_cx: 0.497465 +cam_cy: 0.498443 +cam_d0: 1.01687 \ No newline at end of file diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp index c4ea47f..3cda024 100644 --- a/svo_ros/src/visualizer.cpp +++ b/svo_ros/src/visualizer.cpp @@ -22,18 +22,9 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include -#include #include -#include -#include namespace svo { @@ -41,12 +32,6 @@ Visualizer:: Visualizer() : pnh_("~"), trace_id_(0), - img_pub_level_(vk::getParam("svo/publish_img_pyr_level", 0)), - img_pub_nth_(vk::getParam("svo/publish_every_nth_img", 1)), - dense_pub_nth_(vk::getParam("svo/publish_every_nth_dense_input", 1)), - publish_world_in_cam_frame_(vk::getParam("svo/publish_world_in_cam_frame", true)), - publish_map_every_frame_(vk::getParam("svo/publish_map_every_frame", false)), - publish_points_display_time_(vk::getParam("svo/publish_point_display_time", 0)), T_world_from_vision_(Matrix3d::Identity(), Vector3d::Zero()) { // Init ROS Marker Publishers @@ -54,11 +39,6 @@ Visualizer() : pub_points_ = pnh_.advertise("points", 1000); pub_pose_ = pnh_.advertise("pose",10); pub_info_ = pnh_.advertise("info", 10); - pub_dense_ = pnh_.advertise("dense_input",10); - - // create video publisher - image_transport::ImageTransport it(pnh_); - pub_images_ = it.advertise("image", 10); } void Visualizer::publishMinimal( @@ -90,97 +70,16 @@ void Visualizer::publishMinimal( msg_info.num_matches = 0; pub_info_.publish(msg_info); } - - if(frame == NULL) - { - if(pub_images_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_PAUSED) - { - // Display image when slam is not running. - cv_bridge::CvImage img_msg; - img_msg.header.stamp = ros::Time::now(); - img_msg.header.frame_id = "/image"; - img_msg.image = img; - img_msg.encoding = sensor_msgs::image_encodings::MONO8; - pub_images_.publish(img_msg.toImageMsg()); - } - return; - } - - // Publish pyramid-image every nth-frame. - if(img_pub_nth_ > 0 && trace_id_%img_pub_nth_ == 0 && pub_images_.getNumSubscribers() > 0) - { - const int scale = (1<img_pyr_[img_pub_level_].size(), CV_8UC3); - cv::cvtColor(frame->img_pyr_[img_pub_level_], img_rgb, CV_GRAY2RGB); - - if(slam.stage() == FrameHandlerBase::STAGE_SECOND_FRAME) - { - // During initialization, draw lines. - const vector& px_ref(slam.initFeatureTrackRefPx()); - const vector& px_cur(slam.initFeatureTrackCurPx()); - for(vector::const_iterator it_ref=px_ref.begin(), it_cur=px_cur.begin(); - it_ref != px_ref.end(); ++it_ref, ++it_cur) - cv::line(img_rgb, - cv::Point2f(it_cur->x/scale, it_cur->y/scale), - cv::Point2f(it_ref->x/scale, it_ref->y/scale), cv::Scalar(0,255,0), 2); - } - - if(img_pub_level_ == 0) - { - for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) - { - if((*it)->type == Feature::EDGELET) - cv::line(img_rgb, - cv::Point2f((*it)->px[0]+3*(*it)->grad[1], (*it)->px[1]-3*(*it)->grad[0]), - cv::Point2f((*it)->px[0]-3*(*it)->grad[1], (*it)->px[1]+3*(*it)->grad[0]), - cv::Scalar(255,0,255), 2); - else//point size 5x5 - cv::rectangle(img_rgb, - cv::Point2f((*it)->px[0]-2, (*it)->px[1]-2), - cv::Point2f((*it)->px[0]+2, (*it)->px[1]+2), - cv::Scalar(0,255,0), CV_FILLED); - } - } - else if(img_pub_level_ == 1){//point size 3x3 - for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) - cv::rectangle(img_rgb, - cv::Point2f((*it)->px[0]/scale-1, (*it)->px[1]/scale-1), - cv::Point2f((*it)->px[0]/scale+1, (*it)->px[1]/scale+1), - cv::Scalar(0,255,0), CV_FILLED); - }else{ //point size 1x1 - for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it){ - cv::Vec3b &p= img_rgb.at((*it)->px[1]/scale, (*it)->px[0]/scale); - p[0]=0;p[1]=255;p[2]=0; - } - } - cv_bridge::CvImage img_msg; - img_msg.header = header_msg; - img_msg.image = img_rgb; - img_msg.encoding = sensor_msgs::image_encodings::BGR8; - pub_images_.publish(img_msg.toImageMsg()); - } - if(pub_pose_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) { Quaterniond q; Vector3d p; Matrix Cov; - if(publish_world_in_cam_frame_) - { - // publish world in cam frame - SE3 T_cam_from_world(frame->T_f_w_* T_world_from_vision_); - q = Quaterniond(T_cam_from_world.rotation_matrix()); - p = T_cam_from_world.translation(); - Cov = frame->Cov_; - } - else - { - // publish cam in world frame - SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse()); - q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); - p = T_world_from_cam.translation(); - Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj(); - } + // publish cam in world frame (Estimated odometry in the worls frame) + SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse());// do not confused with inverse. the T_f_w_ is the from camera to initial position with reference of camera + q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); + p = T_world_from_cam.translation(); + Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj(); geometry_msgs::PoseWithCovarianceStampedPtr msg_pose(new geometry_msgs::PoseWithCovarianceStamped); msg_pose->header = header_msg; msg_pose->pose.pose.position.x = p[0]; @@ -210,28 +109,13 @@ void Visualizer::visualizeMarkers( if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) { - vk::output_helper::publishCameraMarker( - pub_frames_, "cam_pos", "cams", ros::Time(frame->timestamp_), - 1, 0.3, Vector3d(0.,0.,1.)); vk::output_helper::publishPointMarker( pub_points_, T_world_from_vision_*frame->pos(), "trajectory", ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5)); - if(frame->isKeyframe() || publish_map_every_frame_) - publishMapRegion(core_kfs); removeDeletedPts(map); } } -void Visualizer::publishMapRegion(set frames) -{ - if(pub_points_.getNumSubscribers() > 0) - { - int ts = vk::Timer::getCurrentTime(); - for(set::iterator it=frames.begin(); it!=frames.end(); ++it) - displayKeyframeWithMps(*it, ts); - } -} - void Visualizer::removeDeletedPts(const Map& map) { if(pub_points_.getNumSubscribers() > 0) @@ -241,76 +125,4 @@ void Visualizer::removeDeletedPts(const Map& map) } } -void Visualizer::displayKeyframeWithMps(const FramePtr& frame, int ts) -{ - // publish keyframe - SE3 T_world_cam(T_world_from_vision_*frame->T_f_w_.inverse()); - vk::output_helper::publishFrameMarker( - pub_frames_, T_world_cam.rotation_matrix(), - T_world_cam.translation(), "kfs", ros::Time::now(), frame->id_*10, 0, 0.015); - - // publish point cloud and links - for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) - { - if((*it)->point == NULL) - continue; - - if((*it)->point->last_published_ts_ == ts) - continue; - - vk::output_helper::publishPointMarker( - pub_points_, T_world_from_vision_*(*it)->point->pos_, "pts", - ros::Time::now(), (*it)->point->id_, 0, 0.005, Vector3d(1.0, 0., 1.0), - publish_points_display_time_); - (*it)->point->last_published_ts_ = ts; - } -} - -void Visualizer::exportToDense(const FramePtr& frame) -{ - // publish air_ground_msgs - if(frame != NULL && dense_pub_nth_ > 0 - && trace_id_%dense_pub_nth_ == 0 && pub_dense_.getNumSubscribers() > 0) - { - svo_msgs::DenseInput msg; - msg.header.stamp = ros::Time(frame->timestamp_); - msg.header.frame_id = "/world"; - msg.frame_id = frame->id_; - - cv_bridge::CvImage img_msg; - img_msg.header.stamp = msg.header.stamp; - img_msg.header.frame_id = "camera"; - img_msg.image = frame->img(); - img_msg.encoding = sensor_msgs::image_encodings::MONO8; - msg.image = *img_msg.toImageMsg(); - - double min_z = std::numeric_limits::max(); - double max_z = std::numeric_limits::min(); - for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) - { - if((*it)->point==NULL) - continue; - Vector3d pos = frame->T_f_w_*(*it)->point->pos_; - min_z = fmin(pos[2], min_z); - max_z = fmax(pos[2], max_z); - } - msg.min_depth = (float) min_z; - msg.max_depth = (float) max_z; - - // publish cam in world frame - SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse()); - Quaterniond q(T_world_from_cam.rotation_matrix()); - Vector3d p(T_world_from_cam.translation()); - - msg.pose.position.x = p[0]; - msg.pose.position.y = p[1]; - msg.pose.position.z = p[2]; - msg.pose.orientation.w = q.w(); - msg.pose.orientation.x = q.x(); - msg.pose.orientation.y = q.y(); - msg.pose.orientation.z = q.z(); - pub_dense_.publish(msg); - } -} - } // end namespace svo diff --git a/svo_ros/src/vo_node.cpp b/svo_ros/src/vo_node.cpp index 3417b4d..b7cdde4 100644 --- a/svo_ros/src/vo_node.cpp +++ b/svo_ros/src/vo_node.cpp @@ -17,15 +17,12 @@ #include #include #include -#include #include #include #include #include #include -#include #include -#include #include #include #include @@ -34,124 +31,78 @@ #include #include + namespace svo { /// SVO Interface class VoNode { public: - svo::FrameHandlerMono* vo_; - svo::Visualizer visualizer_; - bool publish_markers_; //!< publish only the minimal amount of info (choice for embedded devices) - bool publish_dense_input_; - boost::shared_ptr user_input_thread_; - ros::Subscriber sub_remote_key_; - std::string remote_input_; - vk::AbstractCamera* cam_; - bool quit_; - VoNode(); - ~VoNode(); - void imgCb(const sensor_msgs::ImageConstPtr& msg); - void processUserActions(); - void remoteKeyCb(const std_msgs::StringConstPtr& key_input); + svo::FrameHandlerMono* vo_; + svo::Visualizer visualizer_; + bool publish_markers_; //!< publish only the minimal amount of info (choice for embedded devices) + vk::AbstractCamera* cam_; + FILE* logtime; + bool quit_; + VoNode(); + ~VoNode(); + void imgCb(const sensor_msgs::ImageConstPtr& msg); }; VoNode::VoNode() : - vo_(NULL), - publish_markers_(vk::getParam("svo/publish_markers", true)), - publish_dense_input_(vk::getParam("svo/publish_dense_input", false)), - remote_input_(""), - cam_(NULL), - quit_(false) + vo_(NULL), + publish_markers_(vk::getParam("svo/publish_markers", true)), + cam_(NULL), + quit_(false) { - // Start user input thread in parallel thread that listens to console keys - if(vk::getParam("svo/accept_console_user_input", true)) - user_input_thread_ = boost::make_shared(); + // Create Camera + if(!vk::camera_loader::loadFromRosNs("svo", cam_)) + throw std::runtime_error("Camera model not correctly specified."); - // Create Camera - if(!vk::camera_loader::loadFromRosNs("svo", cam_)) - throw std::runtime_error("Camera model not correctly specified."); + // Get initial position and orientation + visualizer_.T_world_from_vision_ = Sophus::SE3( + vk::rpy2dcm(Vector3d(vk::getParam("svo/init_rx", 0.0), + vk::getParam("svo/init_ry", 0.0), + vk::getParam("svo/init_rz", 0.0))), + Eigen::Vector3d(vk::getParam("svo/init_tx", 0.0), + vk::getParam("svo/init_ty", 0.0), + vk::getParam("svo/init_tz", 0.0))); - // Get initial position and orientation - visualizer_.T_world_from_vision_ = Sophus::SE3( - vk::rpy2dcm(Vector3d(vk::getParam("svo/init_rx", 0.0), - vk::getParam("svo/init_ry", 0.0), - vk::getParam("svo/init_rz", 0.0))), - Eigen::Vector3d(vk::getParam("svo/init_tx", 0.0), - vk::getParam("svo/init_ty", 0.0), - vk::getParam("svo/init_tz", 0.0))); + // Init VO and start + vo_ = new svo::FrameHandlerMono(cam_); + vo_->start(); + logtime = fopen((std::string(getenv("HOME"))+"/Project/time.txt").c_str(), "w+"); - // Init VO and start - vo_ = new svo::FrameHandlerMono(cam_); - vo_->start(); } VoNode::~VoNode() { - delete vo_; - delete cam_; - if(user_input_thread_ != NULL) - user_input_thread_->stop(); + fclose(logtime); + delete logtime; + delete vo_; + delete cam_; } void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) { - cv::Mat img; - try { - img = cv_bridge::toCvShare(msg, "mono8")->image; - } catch (cv_bridge::Exception& e) { - ROS_ERROR("cv_bridge exception: %s", e.what()); - } - processUserActions(); - vo_->addImage(img, msg->header.stamp.toSec()); - visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, msg->header.stamp.toSec()); + auto start=std::chrono::steady_clock::now(); + try { + cv::Mat img; + img = cv_bridge::toCvShare(msg, "mono8")->image; + vo_->addImage(img, msg->header.stamp.toSec()); + visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, msg->header.stamp.toSec()); - if(publish_markers_ && vo_->stage() != FrameHandlerBase::STAGE_PAUSED) - visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); - if(publish_dense_input_) - visualizer_.exportToDense(vo_->lastFrame()); + if(publish_markers_ && vo_->stage() != FrameHandlerBase::STAGE_PAUSED) + visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); - if(vo_->stage() == FrameHandlerMono::STAGE_PAUSED) - usleep(100000); + if(vo_->stage() == FrameHandlerMono::STAGE_PAUSED) + usleep(100000); + fprintf(logtime, "%s\n",std::to_string(std::chrono::duration(std::chrono::steady_clock::now()-start).count()).c_str()); + } catch (cv_bridge::Exception& e) { + ROS_ERROR("cv_bridge exception: %s", e.what()); + } } - - -void VoNode::processUserActions() -{ - char input = remote_input_.c_str()[0]; - remote_input_ = ""; - - if(user_input_thread_ != NULL) - { - char console_input = user_input_thread_->getInput(); - if(console_input != 0) - input = console_input; - } - - switch(input) - { - case 'q': - quit_ = true; - printf("SVO user input: QUIT\n"); - break; - case 'r': - vo_->reset(); - printf("SVO user input: RESET\n"); - break; - case 's': - vo_->start(); - printf("SVO user input: START\n"); - break; - default: ; - } -} - -void VoNode::remoteKeyCb(const std_msgs::StringConstPtr& key_input) -{ - remote_input_ = key_input->data; -} - } // namespace svo int main(int argc, char **argv) @@ -162,12 +113,8 @@ int main(int argc, char **argv) svo::VoNode vo_node; // subscribe to cam msgs - std::string cam_topic(vk::getParam("svo/cam_topic", "camera/image_raw")); image_transport::ImageTransport it(nh); - image_transport::Subscriber it_sub = it.subscribe(cam_topic, 5, &svo::VoNode::imgCb, &vo_node); - - // subscribe to remote input - vo_node.sub_remote_key_ = nh.subscribe("svo/remote_key", 5, &svo::VoNode::remoteKeyCb, &vo_node); + image_transport::Subscriber it_sub = it.subscribe(vk::getParam("svo/cam_topic", "camera/image_raw"), 5, &svo::VoNode::imgCb, &vo_node); // start processing callbacks while(ros::ok() && !vo_node.quit_) From 651dcdfb2f3e867f234f074950a669103c091109 Mon Sep 17 00:00:00 2001 From: gfuse Date: Wed, 7 Apr 2021 19:19:35 +0200 Subject: [PATCH 175/215] add imu sub --- svo/.idea/.gitignore | 8 + svo/.idea/misc.xml | 4 + svo/.idea/modules.xml | 8 + svo/.idea/svo.iml | 2 + svo/.idea/vcs.xml | 6 + svo/src/frame_handler_mono.cpp | 2 +- svo_msgs/.idea/.gitignore | 8 + svo_msgs/.idea/misc.xml | 4 + svo_msgs/.idea/modules.xml | 8 + svo_msgs/.idea/svo_msgs.iml | 2 + svo_msgs/.idea/vcs.xml | 6 + svo_ros/.idea/modules.xml | 8 + svo_ros/.idea/svo_ros.iml | 8 + svo_ros/.idea/vcs.xml | 6 + svo_ros/.idea/workspace.xml | 627 ++++++++++++++++++ svo_ros/src/benchmark_node.cpp | 272 -------- vio_svo/.idea/.gitignore | 8 + vio_svo/.idea/misc.xml | 4 + vio_svo/.idea/modules.xml | 8 + vio_svo/.idea/svo_ros.iml | 2 + vio_svo/.idea/vcs.xml | 6 + {svo_ros => vio_svo}/CMakeLists.txt | 2 +- .../include/vio_svo}/dataset_img.h | 0 .../include/vio_svo}/visualizer.h | 0 {svo_ros => vio_svo}/launch/Px30.launch | 7 +- {svo_ros => vio_svo}/launch/live.launch | 0 {svo_ros => vio_svo}/launch/test.launch | 6 +- {svo_ros => vio_svo}/package.xml | 2 +- {svo_ros => vio_svo}/param/camera_atan.yaml | 0 .../param/camera_pinhole.yaml | 0 {svo_ros => vio_svo}/param/px30.yaml | 0 {svo_ros => vio_svo}/param/vo_accurate.yaml | 0 {svo_ros => vio_svo}/param/vo_fast.yaml | 0 {svo_ros => vio_svo}/rqt.perspective | 0 {svo_ros => vio_svo}/rviz_config.rviz | 0 {svo_ros => vio_svo}/src/visualizer.cpp | 2 +- {svo_ros => vio_svo}/src/vo_node.cpp | 70 +- 37 files changed, 786 insertions(+), 310 deletions(-) create mode 100644 svo/.idea/.gitignore create mode 100644 svo/.idea/misc.xml create mode 100644 svo/.idea/modules.xml create mode 100644 svo/.idea/svo.iml create mode 100644 svo/.idea/vcs.xml create mode 100644 svo_msgs/.idea/.gitignore create mode 100644 svo_msgs/.idea/misc.xml create mode 100644 svo_msgs/.idea/modules.xml create mode 100644 svo_msgs/.idea/svo_msgs.iml create mode 100644 svo_msgs/.idea/vcs.xml create mode 100644 svo_ros/.idea/modules.xml create mode 100644 svo_ros/.idea/svo_ros.iml create mode 100644 svo_ros/.idea/vcs.xml create mode 100644 svo_ros/.idea/workspace.xml delete mode 100644 svo_ros/src/benchmark_node.cpp create mode 100644 vio_svo/.idea/.gitignore create mode 100644 vio_svo/.idea/misc.xml create mode 100644 vio_svo/.idea/modules.xml create mode 100644 vio_svo/.idea/svo_ros.iml create mode 100644 vio_svo/.idea/vcs.xml rename {svo_ros => vio_svo}/CMakeLists.txt (98%) rename {svo_ros/include/svo_ros => vio_svo/include/vio_svo}/dataset_img.h (100%) rename {svo_ros/include/svo_ros => vio_svo/include/vio_svo}/visualizer.h (100%) rename {svo_ros => vio_svo}/launch/Px30.launch (65%) rename {svo_ros => vio_svo}/launch/live.launch (100%) rename {svo_ros => vio_svo}/launch/test.launch (71%) rename {svo_ros => vio_svo}/package.xml (98%) rename {svo_ros => vio_svo}/param/camera_atan.yaml (100%) rename {svo_ros => vio_svo}/param/camera_pinhole.yaml (100%) rename {svo_ros => vio_svo}/param/px30.yaml (100%) rename {svo_ros => vio_svo}/param/vo_accurate.yaml (100%) rename {svo_ros => vio_svo}/param/vo_fast.yaml (100%) rename {svo_ros => vio_svo}/rqt.perspective (100%) rename {svo_ros => vio_svo}/rviz_config.rviz (100%) rename {svo_ros => vio_svo}/src/visualizer.cpp (99%) rename {svo_ros => vio_svo}/src/vo_node.cpp (64%) diff --git a/svo/.idea/.gitignore b/svo/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/svo/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/svo/.idea/misc.xml b/svo/.idea/misc.xml new file mode 100644 index 0000000..79b3c94 --- /dev/null +++ b/svo/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/svo/.idea/modules.xml b/svo/.idea/modules.xml new file mode 100644 index 0000000..4c8cf2b --- /dev/null +++ b/svo/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/svo/.idea/svo.iml b/svo/.idea/svo.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/svo/.idea/svo.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/svo/.idea/vcs.xml b/svo/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/svo/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 4facc51..b8bba92 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -156,7 +156,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() return RESULT_FAILURE; } - // pose optimization + // pose optimization subject to change for adding IMU SVO_START_TIMER("pose_optimizer"); size_t sfba_n_edges_final; double sfba_thresh, sfba_error_init, sfba_error_final; diff --git a/svo_msgs/.idea/.gitignore b/svo_msgs/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/svo_msgs/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/svo_msgs/.idea/misc.xml b/svo_msgs/.idea/misc.xml new file mode 100644 index 0000000..79b3c94 --- /dev/null +++ b/svo_msgs/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/svo_msgs/.idea/modules.xml b/svo_msgs/.idea/modules.xml new file mode 100644 index 0000000..668cc83 --- /dev/null +++ b/svo_msgs/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/svo_msgs/.idea/svo_msgs.iml b/svo_msgs/.idea/svo_msgs.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/svo_msgs/.idea/svo_msgs.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/svo_msgs/.idea/vcs.xml b/svo_msgs/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/svo_msgs/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/svo_ros/.idea/modules.xml b/svo_ros/.idea/modules.xml new file mode 100644 index 0000000..eb3cacf --- /dev/null +++ b/svo_ros/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/svo_ros/.idea/svo_ros.iml b/svo_ros/.idea/svo_ros.iml new file mode 100644 index 0000000..bc2cd87 --- /dev/null +++ b/svo_ros/.idea/svo_ros.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/svo_ros/.idea/vcs.xml b/svo_ros/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/svo_ros/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/svo_ros/.idea/workspace.xml b/svo_ros/.idea/workspace.xml new file mode 100644 index 0000000..09c1504 --- /dev/null +++ b/svo_ros/.idea/workspace.xml @@ -0,0 +1,627 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1615974669888 + + + 1617193017745 + + + 1617640897291 + + + + + + + + + + + + \ No newline at end of file diff --git a/svo_ros/src/benchmark_node.cpp b/svo_ros/src/benchmark_node.cpp deleted file mode 100644 index a1c96e1..0000000 --- a/svo_ros/src/benchmark_node.cpp +++ /dev/null @@ -1,272 +0,0 @@ -// This file is part of SVO - Semi-direct Visual Odometry. -// -// Copyright (C) 2014 Christian Forster -// (Robotics and Perception Group, University of Zurich, Switzerland). -// -// SVO is free software: you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the Free Software -// Foundation, either version 3 of the License, or any later version. -// -// SVO is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace svo { - -class BenchmarkNode -{ - svo::FrameHandlerMono* vo_; - svo::Visualizer visualizer_; - int frame_count_; - std::ofstream trace_est_pose_; - std::ofstream trace_trans_error_; - std::ofstream trace_rot_error_; - std::ofstream trace_depth_error_; - vk::AbstractCamera* cam_; - double img_noise_sigma_; - -public: - BenchmarkNode(ros::NodeHandle& nh); - ~BenchmarkNode(); - void tracePose(const SE3& T_w_f, const double timestamp); - void tracePoseError(const SE3& T_f_gt, const double timestamp); - void traceDepthError(const FramePtr& frame, const cv::Mat& depthmap); - void addNoiseToImage(cv::Mat& img, double sigma); - void runBenchmark(const std::string& dataset_dir); - void runBlenderBenchmark(const std::string& dataset_dir); -}; - -BenchmarkNode::BenchmarkNode(ros::NodeHandle& nh) : - vo_(NULL), - frame_count_(0), - img_noise_sigma_(vk::getParam("svo/dataset_noise_sigma", 0.0)) -{ - // Create Camera - if(!vk::camera_loader::loadFromRosNs("svo", cam_)) - throw std::runtime_error("Camera model not correctly specified."); - - // create pose tracefile - std::string trace_est_name(Config::traceDir() + "/traj_estimate.txt"); - trace_est_pose_.open(trace_est_name.c_str()); - if(trace_est_pose_.fail()) - throw std::runtime_error("Could not create tracefile. Does folder exist?"); - - // Initialize VO - vo_ = new svo::FrameHandlerMono(cam_); - vo_->start(); -} - -BenchmarkNode::~BenchmarkNode() -{ - delete vo_; - delete cam_; -} - -void BenchmarkNode::tracePose(const SE3& T_w_f, const double timestamp) -{ - Quaterniond q(T_w_f.unit_quaternion()); - Vector3d p(T_w_f.translation()); - trace_est_pose_.precision(15); - trace_est_pose_.setf(std::ios::fixed, std::ios::floatfield ); - trace_est_pose_ << timestamp << " "; - trace_est_pose_.precision(6); - trace_est_pose_ << p.x() << " " << p.y() << " " << p.z() << " " - << q.x() << " " << q.y() << " " << q.z() << " " << q.w() << std::endl; -} - -void BenchmarkNode::tracePoseError(const SE3& T_f_gt, const double timestamp) -{ - Vector3d et(T_f_gt.translation()); // translation error - trace_trans_error_.precision(15); - trace_trans_error_.setf(std::ios::fixed, std::ios::floatfield ); - trace_trans_error_ << timestamp << " "; - trace_trans_error_.precision(6); - trace_trans_error_ << et.x() << " " << et.y() << " " << et.z() << " " << std::endl; - Vector3d er(vk::dcm2rpy(T_f_gt.rotation_matrix())); // rotation error in roll-pitch-yaw - trace_rot_error_.precision(15); - trace_rot_error_.setf(std::ios::fixed, std::ios::floatfield ); - trace_rot_error_ << timestamp << " "; - trace_rot_error_.precision(6); - trace_rot_error_ << er.x() << " " << er.y() << " " << er.z() << " " << std::endl; -} - -void BenchmarkNode::traceDepthError(const FramePtr& frame, const cv::Mat& depthmap) -{ - trace_depth_error_.precision(6); - std::for_each(frame->fts_.begin(), frame->fts_.end(), [&](Feature* ftr){ - if(ftr->point != NULL) - { - double depth_estimated = (ftr->point->pos_-frame->pos()).norm(); - double depth_true = depthmap.at((int) ftr->px[1], (int) ftr->px[0]); - trace_depth_error_ << frame->id_ << " " - << depth_estimated-depth_true << std::endl; - } - }); -} - -void BenchmarkNode::runBenchmark(const std::string& dataset_dir) -{ - // create image reader and load dataset - std::string filename_benchmark(dataset_dir + "/images.txt"); - vk::FileReader dataset_reader(filename_benchmark); - dataset_reader.skipComments(); - if(!dataset_reader.next()) { - SVO_ERROR_STREAM("Failed opening dataset: "< dataset; - dataset_reader.readAllEntries(dataset); - - // process dataset - int first_frame = vk::getParam("svo/dataset_first_frame", 0); - for(auto it = dataset.begin(); it != dataset.end() && ros::ok(); ++it, ++frame_count_) - { - if(frame_count_ < first_frame) - continue; - std::string img_filename(dataset_dir + "/" + it->image_name_); - cv::Mat img(cv::imread(img_filename, 0)); - if(img.empty()) { - SVO_ERROR_STREAM("Reading image "<addImage(img, it->timestamp_); - visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->timestamp_); - visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); - if(vo_->stage() == svo::FrameHandlerMono::STAGE_DEFAULT_FRAME) - tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); - } -} - -void BenchmarkNode::addNoiseToImage(cv::Mat& img, double sigma) -{ - uint8_t* p = (uint8_t*) img.data; - uint8_t* p_end = img.ptr(img.rows, img.cols); - while(p != p_end) - { - int val = *p + vk::Sample::gaussian(sigma) + 0.5; - *p = std::max(std::min(val, 255), 0); - ++p; - } -} - -void BenchmarkNode::runBlenderBenchmark(const std::string& dataset_dir) -{ - // create image reader and load dataset - std::string filename_benchmark(dataset_dir + "/trajectory.txt"); - vk::FileReader dataset_reader(filename_benchmark); - dataset_reader.skipComments(); - if(!dataset_reader.next()) { - SVO_ERROR_STREAM("Failed opening dataset: "< dataset; - dataset_reader.readAllEntries(dataset); - - // create tracefiles - trace_trans_error_.open(Config::traceDir() + "/translation_error.txt"); - trace_rot_error_.open(Config::traceDir() + "/orientation_error.txt"); - trace_depth_error_.open(Config::traceDir() + "/depth_error.txt"); - if(trace_trans_error_.fail() || trace_rot_error_.fail() || trace_depth_error_.fail()) - throw std::runtime_error("Could not create tracefile. Does folder exist?"); - - // process dataset - for(auto it = dataset.begin(); it != dataset.end() && ros::ok(); ++it, ++frame_count_) - { - // Read image, ground-truth depth-map and ground-truth pose - std::string img_filename(dataset_dir + "/img/" + it->image_name_ + "_0.png"); - cv::Mat img(cv::imread(img_filename, 0)); - if(img.empty()) { - SVO_ERROR_STREAM("Reading image "< 0) - addNoiseToImage(img, img_noise_sigma_); - cv::Mat depthmap; - vk::blender_utils::loadBlenderDepthmap( - dataset_dir+"/depth/"+it->image_name_+"_0.depth", *cam_, depthmap); - Sophus::SE3 T_w_gt(it->q_, it->t_); - - // Set reference frame with depth - if(frame_count_ == 0) - { - // set reference frame at ground-truth pose - FramePtr frame_ref(new Frame(cam_, img, it->timestamp_)); - frame_ref->T_f_w_ = T_w_gt.inverse(); - - // extract features, generate features with 3D points - svo::feature_detection::FastDetector detector( - cam_->width(), cam_->height(), svo::Config::gridSize(), svo::Config::nPyrLevels()); - detector.detect(frame_ref.get(), frame_ref->img_pyr_, svo::Config::triangMinCornerScore(), frame_ref->fts_); - std::for_each(frame_ref->fts_.begin(), frame_ref->fts_.end(), [&](Feature* ftr) { - Eigen::Vector3d pt_pos_cur = ftr->f*depthmap.at(ftr->px[1], ftr->px[0]); - Eigen::Vector3d pt_pos_world = frame_ref->T_f_w_.inverse()*pt_pos_cur; - svo::Point* point = new svo::Point(pt_pos_world, ftr); - ftr->point = point; - }); - SVO_INFO_STREAM("Added "<nObs()<<" 3d pts to the reference frame."); - vo_->setFirstFrame(frame_ref); - SVO_INFO_STREAM("Set reference frame."); - } - else - { - SVO_DEBUG_STREAM("Processing image "<image_name_<<"."); - vo_->addImage(img, it->timestamp_); - visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, it->timestamp_); - visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); - } - - if(vo_->stage() != svo::FrameHandlerMono::STAGE_DEFAULT_FRAME) - { - SVO_ERROR_STREAM("SVO failed before entire dataset could be processed."); - break; - } - - // Compute pose error and trace to file - Sophus::SE3 T_f_gt(vo_->lastFrame()->T_f_w_*T_w_gt); - tracePoseError(T_f_gt, it->timestamp_); - tracePose(vo_->lastFrame()->T_f_w_.inverse(), it->timestamp_); - traceDepthError(vo_->lastFrame(), depthmap); - } -} - -} // namespace svo - -int main(int argc, char** argv) -{ - ros::init(argc, argv, "svo"); - ros::NodeHandle nh; - svo::BenchmarkNode benchmark(nh); - std::string benchmark_dir(vk::getParam("svo/dataset_directory")); - if(vk::getParam("svo/dataset_is_blender", false)) - benchmark.runBlenderBenchmark(benchmark_dir); - else - benchmark.runBenchmark(benchmark_dir); - printf("BenchmarkNode finished.\n"); - return 0; -} diff --git a/vio_svo/.idea/.gitignore b/vio_svo/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/vio_svo/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/vio_svo/.idea/misc.xml b/vio_svo/.idea/misc.xml new file mode 100644 index 0000000..79b3c94 --- /dev/null +++ b/vio_svo/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/vio_svo/.idea/modules.xml b/vio_svo/.idea/modules.xml new file mode 100644 index 0000000..eb3cacf --- /dev/null +++ b/vio_svo/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/vio_svo/.idea/svo_ros.iml b/vio_svo/.idea/svo_ros.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/vio_svo/.idea/svo_ros.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/vio_svo/.idea/vcs.xml b/vio_svo/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/vio_svo/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/svo_ros/CMakeLists.txt b/vio_svo/CMakeLists.txt similarity index 98% rename from svo_ros/CMakeLists.txt rename to vio_svo/CMakeLists.txt index d0ce982..059a8bf 100644 --- a/svo_ros/CMakeLists.txt +++ b/vio_svo/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(PROJECT_NAME svo_ros) +SET(PROJECT_NAME vio_svo) PROJECT(${PROJECT_NAME}) CMAKE_MINIMUM_REQUIRED (VERSION 2.8.3) SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo diff --git a/svo_ros/include/svo_ros/dataset_img.h b/vio_svo/include/vio_svo/dataset_img.h similarity index 100% rename from svo_ros/include/svo_ros/dataset_img.h rename to vio_svo/include/vio_svo/dataset_img.h diff --git a/svo_ros/include/svo_ros/visualizer.h b/vio_svo/include/vio_svo/visualizer.h similarity index 100% rename from svo_ros/include/svo_ros/visualizer.h rename to vio_svo/include/vio_svo/visualizer.h diff --git a/svo_ros/launch/Px30.launch b/vio_svo/launch/Px30.launch similarity index 65% rename from svo_ros/launch/Px30.launch rename to vio_svo/launch/Px30.launch index 53f9317..6ff3dab 100644 --- a/svo_ros/launch/Px30.launch +++ b/vio_svo/launch/Px30.launch @@ -1,15 +1,16 @@ - + + - + - + diff --git a/svo_ros/launch/live.launch b/vio_svo/launch/live.launch similarity index 100% rename from svo_ros/launch/live.launch rename to vio_svo/launch/live.launch diff --git a/svo_ros/launch/test.launch b/vio_svo/launch/test.launch similarity index 71% rename from svo_ros/launch/test.launch rename to vio_svo/launch/test.launch index f83d479..388b536 100644 --- a/svo_ros/launch/test.launch +++ b/vio_svo/launch/test.launch @@ -1,15 +1,15 @@ - + - + - + diff --git a/svo_ros/package.xml b/vio_svo/package.xml similarity index 98% rename from svo_ros/package.xml rename to vio_svo/package.xml index aaa8fd3..ff9eab3 100644 --- a/svo_ros/package.xml +++ b/vio_svo/package.xml @@ -1,6 +1,6 @@ - svo_ros + vio_svo 0.1.0 Monocular Visual Odometry - ROS Nodes diff --git a/svo_ros/param/camera_atan.yaml b/vio_svo/param/camera_atan.yaml similarity index 100% rename from svo_ros/param/camera_atan.yaml rename to vio_svo/param/camera_atan.yaml diff --git a/svo_ros/param/camera_pinhole.yaml b/vio_svo/param/camera_pinhole.yaml similarity index 100% rename from svo_ros/param/camera_pinhole.yaml rename to vio_svo/param/camera_pinhole.yaml diff --git a/svo_ros/param/px30.yaml b/vio_svo/param/px30.yaml similarity index 100% rename from svo_ros/param/px30.yaml rename to vio_svo/param/px30.yaml diff --git a/svo_ros/param/vo_accurate.yaml b/vio_svo/param/vo_accurate.yaml similarity index 100% rename from svo_ros/param/vo_accurate.yaml rename to vio_svo/param/vo_accurate.yaml diff --git a/svo_ros/param/vo_fast.yaml b/vio_svo/param/vo_fast.yaml similarity index 100% rename from svo_ros/param/vo_fast.yaml rename to vio_svo/param/vo_fast.yaml diff --git a/svo_ros/rqt.perspective b/vio_svo/rqt.perspective similarity index 100% rename from svo_ros/rqt.perspective rename to vio_svo/rqt.perspective diff --git a/svo_ros/rviz_config.rviz b/vio_svo/rviz_config.rviz similarity index 100% rename from svo_ros/rviz_config.rviz rename to vio_svo/rviz_config.rviz diff --git a/svo_ros/src/visualizer.cpp b/vio_svo/src/visualizer.cpp similarity index 99% rename from svo_ros/src/visualizer.cpp rename to vio_svo/src/visualizer.cpp index 3cda024..511c167 100644 --- a/svo_ros/src/visualizer.cpp +++ b/vio_svo/src/visualizer.cpp @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include +#include #include #include #include diff --git a/svo_ros/src/vo_node.cpp b/vio_svo/src/vo_node.cpp similarity index 64% rename from svo_ros/src/vo_node.cpp rename to vio_svo/src/vo_node.cpp index b7cdde4..8fd503f 100644 --- a/svo_ros/src/vo_node.cpp +++ b/vio_svo/src/vo_node.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -44,40 +44,45 @@ public: vk::AbstractCamera* cam_; FILE* logtime; bool quit_; + boost::thread* vio_th; VoNode(); ~VoNode(); void imgCb(const sensor_msgs::ImageConstPtr& msg); + void imuCb(const sensor_msgs::ImuPtr& imu); + void vio(); }; VoNode::VoNode() : vo_(NULL), - publish_markers_(vk::getParam("svo/publish_markers", true)), + publish_markers_(vk::getParam("vio/publish_markers", true)), cam_(NULL), quit_(false) { // Create Camera - if(!vk::camera_loader::loadFromRosNs("svo", cam_)) + if(!vk::camera_loader::loadFromRosNs("vio", cam_)) throw std::runtime_error("Camera model not correctly specified."); - // Get initial position and orientation visualizer_.T_world_from_vision_ = Sophus::SE3( - vk::rpy2dcm(Vector3d(vk::getParam("svo/init_rx", 0.0), - vk::getParam("svo/init_ry", 0.0), - vk::getParam("svo/init_rz", 0.0))), - Eigen::Vector3d(vk::getParam("svo/init_tx", 0.0), - vk::getParam("svo/init_ty", 0.0), - vk::getParam("svo/init_tz", 0.0))); - + vk::rpy2dcm(Vector3d(vk::getParam("vio/init_rx", 0.0), + vk::getParam("vio/init_ry", 0.0), + vk::getParam("vio/init_rz", 0.0))), + Eigen::Vector3d(vk::getParam("vio/init_tx", 0.0), + vk::getParam("vio/init_ty", 0.0), + vk::getParam("vio/init_tz", 0.0))); // Init VO and start vo_ = new svo::FrameHandlerMono(cam_); vo_->start(); logtime = fopen((std::string(getenv("HOME"))+"/Project/time.txt").c_str(), "w+"); + vio_th=new boost::thread(&VoNode::vio,this); } VoNode::~VoNode() { + quit_=true; fclose(logtime); + vio_th->join(); + delete vio_th; delete logtime; delete vo_; delete cam_; @@ -85,44 +90,53 @@ VoNode::~VoNode() void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) { - auto start=std::chrono::steady_clock::now(); try { - cv::Mat img; - img = cv_bridge::toCvShare(msg, "mono8")->image; + ROS_INFO("image back"); + auto start=std::chrono::steady_clock::now(); + cv::Mat img=cv_bridge::toCvShare(msg, "mono8")->image; vo_->addImage(img, msg->header.stamp.toSec()); visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, msg->header.stamp.toSec()); - - if(publish_markers_ && vo_->stage() != FrameHandlerBase::STAGE_PAUSED) visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); - if(vo_->stage() == FrameHandlerMono::STAGE_PAUSED) usleep(100000); fprintf(logtime, "%s\n",std::to_string(std::chrono::duration(std::chrono::steady_clock::now()-start).count()).c_str()); + } catch (cv_bridge::Exception& e) { ROS_ERROR("cv_bridge exception: %s", e.what()); } } +void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { + ROS_INFO("imu back"); +} +void VoNode::vio(){ + ros::NodeHandle nh; + std::cout << "create vo_node" << std::endl; + // subscribe to cam msgs + image_transport::ImageTransport it(nh); + image_transport::Subscriber it_sub = it.subscribe(vk::getParam("vio/cam_topic", "camera/image_raw"), 5, &svo::VoNode::imgCb, this); + // start processing callbacks + while(ros::ok() && !quit_) + { + ros::spinOnce(); + // TODO check when last image was processed. when too long ago. publish warning that no msgs are received! + } + +} } // namespace svo int main(int argc, char **argv) { - ros::init(argc, argv, "svo"); - ros::NodeHandle nh; - std::cout << "create vo_node" << std::endl; + ros::init(argc, argv, "vio"); svo::VoNode vo_node; - - // subscribe to cam msgs - image_transport::ImageTransport it(nh); - image_transport::Subscriber it_sub = it.subscribe(vk::getParam("svo/cam_topic", "camera/image_raw"), 5, &svo::VoNode::imgCb, &vo_node); - + ros::NodeHandle nh; + ros::Subscriber imu_sub=nh.subscribe(vk::getParam("vio/imu_topic", "imu/raw"),10,&svo::VoNode::imuCb, &vo_node); // start processing callbacks while(ros::ok() && !vo_node.quit_) { - ros::spinOnce(); - // TODO check when last image was processed. when too long ago. publish warning that no msgs are received! + ros::spinOnce(); + // TODO check when last image was processed. when too long ago. publish warning that no msgs are received! } - printf("SVO terminated.\n"); return 0; } From 56c7f230882a300829a512b089ffa67536de954a Mon Sep 17 00:00:00 2001 From: gfuse Date: Mon, 12 Apr 2021 12:43:04 +0200 Subject: [PATCH 176/215] edit svo --- svo/CMakeLists.txt | 17 +++++--- svo/include/svo/frame_handler_mono.h | 5 ++- svo/include/svo/imu_integration.h | 39 +++++++++++++++++++ svo/src/frame_handler_mono.cpp | 7 +++- svo/src/imu_integration.cpp | 58 ++++++++++++++++++++++++++++ svo/src/pose_optimizer.cpp | 1 + vio_svo/launch/test.launch | 3 +- vio_svo/src/vo_node.cpp | 29 ++++++++------ 8 files changed, 139 insertions(+), 20 deletions(-) create mode 100644 svo/include/svo/imu_integration.h create mode 100644 svo/src/imu_integration.cpp diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 15257be..19beebd 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -14,6 +14,8 @@ CMAKE_MINIMUM_REQUIRED (VERSION 2.8.3) SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo SET(CMAKE_VERBOSE_MAKEFILE OFF) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") +set(CMAKE_C_STANDARD 14) +set(CMAKE_CXX_STANDARD 14) # Set definitions IF(TRACE) @@ -33,7 +35,7 @@ ENDIF() # Set build flags. Set IS_ARM on odroid board as environment variable SET(CMAKE_CXX_FLAGS "-Wall -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") IF(DEFINED ENV{ARM_ARCHITECTURE}) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -march=armv7-a") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ") ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse -msse2 -msse3 -mssse3") ENDIF() @@ -50,11 +52,13 @@ FIND_PACKAGE(Eigen REQUIRED) FIND_PACKAGE(Sophus REQUIRED) FIND_PACKAGE(fast REQUIRED) FIND_PACKAGE(Boost REQUIRED COMPONENTS thread system) +FIND_PACKAGE(GTSAM REQUIRED) +set(GTSAM_INCLUDE_DIRS "${GTSAM_INCLUDE_DIR}") IF(USE_ROS) FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros) catkin_package( - DEPENDS Eigen OpenCV Sophus Boost fast + DEPENDS Eigen OpenCV Sophus Boost fast GTSAM CATKIN_DEPENDS roscpp roslib vikit_common vikit_ros INCLUDE_DIRS include LIBRARIES svo @@ -72,7 +76,7 @@ INCLUDE_DIRECTORIES( ${OpenCV_INCLUDE_DIRS} ${Sophus_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} - ${fast_INCLUDE_DIRS} + ${fast_INCLUDE_DIRS} ${GTSAM_INCLUDE_DIR} ) # Set link libraries @@ -82,7 +86,6 @@ LIST(APPEND LINK_LIBS ${Boost_LIBRARIES} ${fast_LIBRARIES} ) - IF(USE_ROS) INCLUDE_DIRECTORIES(${catkin_INCLUDE_DIRS}) LIST(APPEND LINK_LIBS ${catkin_LIBRARIES}) @@ -106,7 +109,7 @@ LIST(APPEND SOURCEFILES src/feature_detection.cpp src/depth_filter.cpp src/config.cpp - src/sparse_img_align.cpp) + src/sparse_img_align.cpp src/imu_integration.cpp) # Add g2o if available IF(HAVE_G2O) @@ -124,7 +127,9 @@ ENDIF(HAVE_G2O) # Create svo library ADD_LIBRARY(svo SHARED ${SOURCEFILES}) -TARGET_LINK_LIBRARIES(svo ${LINK_LIBS}) +TARGET_LINK_LIBRARIES(svo ${LINK_LIBS} gtsam) +set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14) +set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) ################################################################################ # TESTS diff --git a/svo/include/svo/frame_handler_mono.h b/svo/include/svo/frame_handler_mono.h index aed73be..58789c8 100644 --- a/svo/include/svo/frame_handler_mono.h +++ b/svo/include/svo/frame_handler_mono.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace svo { @@ -31,7 +32,7 @@ class FrameHandlerMono : public FrameHandlerBase public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW - FrameHandlerMono(vk::AbstractCamera* cam); + FrameHandlerMono(vk::AbstractCamera* cam,Sophus::SE3& SE_init); virtual ~FrameHandlerMono(); /// Provide an image. @@ -59,6 +60,7 @@ public: const SE3& T_kf_f, const cv::Mat& img, const double timestamp); + std::unique_ptr imu_integPtr_; //Integration of IMU protected: vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit). @@ -70,6 +72,7 @@ protected: initialization::KltHomographyInit klt_homography_init_; //!< Used to estimate pose of the first two keyframes by estimating a homography. DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. + /// Initialize the visual odometry algorithm. virtual void initialize(); diff --git a/svo/include/svo/imu_integration.h b/svo/include/svo/imu_integration.h new file mode 100644 index 0000000..7f05e20 --- /dev/null +++ b/svo/include/svo/imu_integration.h @@ -0,0 +1,39 @@ +// +// Created by gufe on 4/9/21. +// + +#ifndef SVO_IMU_INTEGRATION_H +#define SVO_IMU_INTEGRATION_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using gtsam::symbol_shorthand::B; // Bias (ax,ay,az,gx,gy,gz) +using gtsam::symbol_shorthand::V; // Vel (xdot,ydot,zdot) +using gtsam::symbol_shorthand::P; // Pose3 (x,y,z,r,p,y) + +class Imu_Integration{ +public: + Imu_Integration(Sophus::SE3& SE_init); + ~Imu_Integration(); + bool reset(); + bool update(float* imu= nullptr); + bool predict(boost::shared_ptr&,std::size_t&); +private: + std::shared_ptr statePtr; + std::shared_ptr imu_biasPtr; + std::unique_ptr valuesPtr; + std::unique_ptr graphPtr; + boost::shared_ptr parameterPtr; + std::shared_ptr preintegratedPtr; + std::uint32_t t_1=1e-18; + std::uint32_t imu_factor_id=0; +}; +#endif //SVO_IMU_INTEGRATION_H diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index b8bba92..e4a3140 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -30,13 +30,14 @@ namespace svo { -FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam) : +FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam,Sophus::SE3& SE_init) : FrameHandlerBase(), cam_(cam), reprojector_(cam_, map_), depth_filter_(NULL) { initialize(); + imu_integPtr_=std::make_unique(SE_init); } void FrameHandlerMono::initialize() @@ -159,6 +160,9 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() // pose optimization subject to change for adding IMU SVO_START_TIMER("pose_optimizer"); size_t sfba_n_edges_final; + if(!imu_integPtr_->predict(new_frame_,sfba_n_edges_final)) + return RESULT_FAILURE; + /* double sfba_thresh, sfba_error_init, sfba_error_final; pose_optimizer::optimizeGaussNewton( Config::poseOptimThresh(), Config::poseOptimNumIter(), false, @@ -167,6 +171,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() SVO_LOG4(sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final); SVO_DEBUG_STREAM("PoseOptimizer:\t ErrInit = "< +#include + +Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ + statePtr=std::make_shared(gtsam::Pose3(gtsam::Rot3(SE_init.rotation_matrix()),SE_init.translation()), + gtsam::Vector3(0.0,0.0,0.0)); + imu_biasPtr=std::make_shared(); + valuesPtr=std::make_unique(); + valuesPtr->insert(P(0),statePtr->pose()); + valuesPtr->insert(V(0),statePtr->v()); + valuesPtr->insert(B(0),*imu_biasPtr.get()); + graphPtr=std::make_unique(); + graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 0.01, 0.01, 0.01, 0.5, 0.5, 0.5).finished())); + graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 0.1)); + graphPtr->addPrior(B(0),*imu_biasPtr.get(),gtsam::noiseModel::Isotropic::Sigma(6, 1e-3)); + parameterPtr = gtsam::PreintegratedCombinedMeasurements::Params::MakeSharedD(); + parameterPtr->accelerometerCovariance=gtsam::I_3x3 * pow(0.0003924, 2); // acc white noise in continuous + parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * pow(0.00020568902491,2); // gyro white noise in continuous + parameterPtr->integrationCovariance=gtsam::I_3x3 * 1e-8; // integration uncertainty continuous + // PreintegrationCombinedMeasurements params: + parameterPtr->biasAccCovariance = gtsam::I_3x3 * pow(0.004905, 2);; // acc bias in continuous + parameterPtr->biasOmegaCovariance = gtsam::I_3x3 * pow(0.000001454441043, 2); // gyro bias in continuous + parameterPtr->biasAccOmegaInt = gtsam::I_6x6 * 1e-5; // error in the bias used for preintegration + preintegratedPtr = std::make_shared(parameterPtr,*imu_biasPtr.get()); + assert(preintegratedPtr); +} +Imu_Integration::~Imu_Integration(){ + +} +bool Imu_Integration::update(float* imu){ + if(t_1<1e-4){ + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),0.005); + t_1=imu[6]; + }else{ + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),imu[6]-t_1); + t_1=imu[6]; + } + return true; +} +bool Imu_Integration::reset(){ + preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr.get()); + return true; +} +bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size_t& num_obs){ + // Adding IMU factor and GPS factor and optimizing. + auto preint_imu_combined =dynamic_cast(*preintegratedPtr); + ++imu_factor_id; + gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), + preint_imu_combined); + graphPtr->add(imu_factor); + if(!reset())return false; + return true; +} \ No newline at end of file diff --git a/svo/src/pose_optimizer.cpp b/svo/src/pose_optimizer.cpp index 00ca321..1c491b0 100644 --- a/svo/src/pose_optimizer.cpp +++ b/svo/src/pose_optimizer.cpp @@ -49,6 +49,7 @@ void optimizeGaussNewton( { if((*it)->point == NULL) continue; + //Reprojection error Vector2d e = vk::project2d((*it)->f) - vk::project2d(frame->T_f_w_ * (*it)->point->pos_); e *= 1.0 / (1<<(*it)->level); diff --git a/vio_svo/launch/test.launch b/vio_svo/launch/test.launch index 388b536..4bcd965 100644 --- a/vio_svo/launch/test.launch +++ b/vio_svo/launch/test.launch @@ -4,6 +4,7 @@ + @@ -18,4 +19,4 @@ - \ No newline at end of file + diff --git a/vio_svo/src/vo_node.cpp b/vio_svo/src/vo_node.cpp index 8fd503f..908abb8 100644 --- a/vio_svo/src/vo_node.cpp +++ b/vio_svo/src/vo_node.cpp @@ -30,6 +30,7 @@ #include #include #include +#include namespace svo { @@ -44,12 +45,12 @@ public: vk::AbstractCamera* cam_; FILE* logtime; bool quit_; - boost::thread* vio_th; + boost::thread* imu_th; VoNode(); ~VoNode(); void imgCb(const sensor_msgs::ImageConstPtr& msg); void imuCb(const sensor_msgs::ImuPtr& imu); - void vio(); + void imu(); }; VoNode::VoNode() : @@ -70,10 +71,10 @@ VoNode::VoNode() : vk::getParam("vio/init_ty", 0.0), vk::getParam("vio/init_tz", 0.0))); // Init VO and start - vo_ = new svo::FrameHandlerMono(cam_); + vo_ = new svo::FrameHandlerMono(cam_,visualizer_.T_world_from_vision_); vo_->start(); - logtime = fopen((std::string(getenv("HOME"))+"/Project/time.txt").c_str(), "w+"); - vio_th=new boost::thread(&VoNode::vio,this); + imu_th=new boost::thread(&VoNode::imu,this); + logtime = fopen((std::string(getenv("HOME"))+"/Project/time.txt").c_str(), "w+"); } @@ -81,8 +82,8 @@ VoNode::~VoNode() { quit_=true; fclose(logtime); - vio_th->join(); - delete vio_th; + imu_th->join(); + delete imu_th; delete logtime; delete vo_; delete cam_; @@ -91,7 +92,6 @@ VoNode::~VoNode() void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) { try { - ROS_INFO("image back"); auto start=std::chrono::steady_clock::now(); cv::Mat img=cv_bridge::toCvShare(msg, "mono8")->image; vo_->addImage(img, msg->header.stamp.toSec()); @@ -107,9 +107,17 @@ void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) } } void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { - ROS_INFO("imu back"); + float imu_in[7]; + imu_in[0] = imu->angular_velocity.x; + imu_in[1] = imu->angular_velocity.y; + imu_in[2] = imu->angular_velocity.z; + imu_in[3] = imu->linear_acceleration.x; + imu_in[4] = imu->linear_acceleration.y; + imu_in[5] = imu->linear_acceleration.z; + imu_in[6] = imu->header.stamp.sec; + vo_->imu_integPtr_->update(imu_in); } -void VoNode::vio(){ +void VoNode::imu(){ ros::NodeHandle nh; std::cout << "create vo_node" << std::endl; // subscribe to cam msgs @@ -119,7 +127,6 @@ void VoNode::vio(){ while(ros::ok() && !quit_) { ros::spinOnce(); - // TODO check when last image was processed. when too long ago. publish warning that no msgs are received! } } From f4d1ce4f4ffde20d6baa38394a59f7d545c5866c Mon Sep 17 00:00:00 2001 From: gfuse Date: Tue, 13 Apr 2021 13:28:09 +0200 Subject: [PATCH 177/215] develop imu_integration --- svo/include/svo/imu_integration.h | 82 ++++++++++++++++++++++++++++++- svo/src/imu_integration.cpp | 36 ++++++++++++-- 2 files changed, 111 insertions(+), 7 deletions(-) diff --git a/svo/include/svo/imu_integration.h b/svo/include/svo/imu_integration.h index 7f05e20..3cfb77e 100644 --- a/svo/include/svo/imu_integration.h +++ b/svo/include/svo/imu_integration.h @@ -7,17 +7,93 @@ #include #include #include -#include -#include #include #include #include +#include #include #include using gtsam::symbol_shorthand::B; // Bias (ax,ay,az,gx,gy,gz) using gtsam::symbol_shorthand::V; // Vel (xdot,ydot,zdot) using gtsam::symbol_shorthand::P; // Pose3 (x,y,z,r,p,y) +using gtsam::symbol_shorthand::F; // Feature + +//https://stackoverflow.com/questions/24881799/get-index-in-c11-foreach-loop +// Wrapper class +template +class enumerate_impl +{ +public: + // The return value of the operator* of the iterator, this + // is what you will get inside of the for loop + struct item + { + size_t index; + typename T::value_type & item; + }; + typedef item value_type; + + // Custom iterator with minimal interface + struct iterator + { + iterator(typename T::iterator _it, size_t counter=0) : + it(_it), counter(counter) + {} + + iterator operator++() + { + return iterator(++it, ++counter); + } + + bool operator!=(iterator other) + { + return it != other.it; + } + + typename T::iterator::value_type item() + { + return *it; + } + + value_type operator*() + { + return value_type{counter, *it}; + } + + size_t index() + { + return counter; + } + + private: + typename T::iterator it; + size_t counter; + }; + + enumerate_impl(T & t) : container(t) {} + + iterator begin() + { + return iterator(container.begin()); + } + + iterator end() + { + return iterator(container.end()); + } + +private: + T & container; +}; + +// A templated free function allows you to create the wrapper class +// conveniently +template +enumerate_impl enumerate(T & t) +{ + return enumerate_impl(t); +} class Imu_Integration{ public: @@ -33,6 +109,8 @@ private: std::unique_ptr graphPtr; boost::shared_ptr parameterPtr; std::shared_ptr preintegratedPtr; + boost::shared_ptr ProjectNoisePtr; + boost::shared_ptr cameraPtr; std::uint32_t t_1=1e-18; std::uint32_t imu_factor_id=0; }; diff --git a/svo/src/imu_integration.cpp b/svo/src/imu_integration.cpp index 4e641f0..575d31b 100644 --- a/svo/src/imu_integration.cpp +++ b/svo/src/imu_integration.cpp @@ -5,6 +5,8 @@ #include "svo/imu_integration.h" #include #include +#include "svo/feature.h" +#include "svo/point.h" Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ statePtr=std::make_shared(gtsam::Pose3(gtsam::Rot3(SE_init.rotation_matrix()),SE_init.translation()), @@ -18,15 +20,16 @@ Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 0.01, 0.01, 0.01, 0.5, 0.5, 0.5).finished())); graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 0.1)); graphPtr->addPrior(B(0),*imu_biasPtr.get(),gtsam::noiseModel::Isotropic::Sigma(6, 1e-3)); - parameterPtr = gtsam::PreintegratedCombinedMeasurements::Params::MakeSharedD(); + parameterPtr = gtsam::PreintegratedCombinedMeasurements::Params::MakeSharedD();// TODO check the IMU frame parameterPtr->accelerometerCovariance=gtsam::I_3x3 * pow(0.0003924, 2); // acc white noise in continuous parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * pow(0.00020568902491,2); // gyro white noise in continuous parameterPtr->integrationCovariance=gtsam::I_3x3 * 1e-8; // integration uncertainty continuous - // PreintegrationCombinedMeasurements params: parameterPtr->biasAccCovariance = gtsam::I_3x3 * pow(0.004905, 2);; // acc bias in continuous parameterPtr->biasOmegaCovariance = gtsam::I_3x3 * pow(0.000001454441043, 2); // gyro bias in continuous parameterPtr->biasAccOmegaInt = gtsam::I_6x6 * 1e-5; // error in the bias used for preintegration preintegratedPtr = std::make_shared(parameterPtr,*imu_biasPtr.get()); + ProjectNoisePtr = gtsam::noiseModel::Isotropic::Sigma(2, 0.1); // error in the bias used for projection + cameraPtr=boost::make_shared(15,12,20,3,12); assert(preintegratedPtr); } Imu_Integration::~Imu_Integration(){ @@ -47,12 +50,35 @@ bool Imu_Integration::reset(){ return true; } bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size_t& num_obs){ - // Adding IMU factor and GPS factor and optimizing. + // Adding IMU factor and and pre-integration. auto preint_imu_combined =dynamic_cast(*preintegratedPtr); + gtsam::NavState Estimate_state = preintegratedPtr->predict(*statePtr.get(), *imu_biasPtr.get()); ++imu_factor_id; + valuesPtr->insert(P(imu_factor_id), Estimate_state.pose()); + valuesPtr->insert(V(imu_factor_id), Estimate_state.v()); + valuesPtr->insert(B(imu_factor_id), *imu_biasPtr.get()); gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), preint_imu_combined); - graphPtr->add(imu_factor); - if(!reset())return false; + graphPtr->emplace_shared(imu_factor); + for(auto&& f:enumerate(new_frame->fts_)){ + if(f.item->point==NULL)continue; + valuesPtr->insert(F(f.index), new_frame->T_f_w_ * f.item->point->pos_); + graphPtr->emplace_shared >( + f.item->px, ProjectNoisePtr, P( imu_factor_id), F(f.index), cameraPtr); + } + + // Now optimize. + gtsam::LevenbergMarquardtParams params; + params.setVerbosityLM("SUMMARY"); + gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr.get(), *valuesPtr.get(), params); + gtsam::Values result = optimizer.optimize(); + // Overwrite the beginning of the preintegration for the next step. + statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); + imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); + preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr.get()); + t_1=1e-18; + new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); + // new_frame->Cov_=gtsam:: + //if(!reset())return false; return true; } \ No newline at end of file From 382c41725b761e2ec18a1cbfd3e2b8495f56b07f Mon Sep 17 00:00:00 2001 From: gfuse Date: Thu, 15 Apr 2021 18:20:08 +0200 Subject: [PATCH 178/215] complete pipline and test with unity_dataset --- svo/CMakeLists.txt | 28 +++---- svo/include/svo/imu_integration.h | 15 ++-- svo/include/svo/svoVisionFactor.h | 71 ++++++++++++++++++ svo/src/frame_handler_mono.cpp | 2 +- svo/src/imu_integration.cpp | 118 +++++++++++++++++++----------- vio_svo/CMakeLists.txt | 14 ++-- vio_svo/launch/unity.launch | 22 ++++++ vio_svo/package.xml | 2 + vio_svo/param/unity.yaml | 8 ++ vio_svo/src/vo_node.cpp | 20 +++-- 10 files changed, 223 insertions(+), 77 deletions(-) create mode 100644 svo/include/svo/svoVisionFactor.h create mode 100644 vio_svo/launch/unity.launch create mode 100644 vio_svo/param/unity.yaml diff --git a/svo/CMakeLists.txt b/svo/CMakeLists.txt index 19beebd..ff39094 100644 --- a/svo/CMakeLists.txt +++ b/svo/CMakeLists.txt @@ -134,23 +134,23 @@ set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) ################################################################################ # TESTS -ADD_EXECUTABLE(test_feature_align test/test_feature_alignment.cpp) -TARGET_LINK_LIBRARIES(test_feature_align svo) +#ADD_EXECUTABLE(test_feature_align test/test_feature_alignment.cpp) +#TARGET_LINK_LIBRARIES(test_feature_align svo) -ADD_EXECUTABLE(test_pipeline test/test_pipeline.cpp) -TARGET_LINK_LIBRARIES(test_pipeline svo) +#ADD_EXECUTABLE(test_pipeline test/test_pipeline.cpp) +#TARGET_LINK_LIBRARIES(test_pipeline svo) -ADD_EXECUTABLE(test_matcher test/test_matcher.cpp) -TARGET_LINK_LIBRARIES(test_matcher svo) +#ADD_EXECUTABLE(test_matcher test/test_matcher.cpp) +#TARGET_LINK_LIBRARIES(test_matcher svo) -ADD_EXECUTABLE(test_feature_detection test/test_feature_detection.cpp) -TARGET_LINK_LIBRARIES(test_feature_detection svo) +#ADD_EXECUTABLE(test_feature_detection test/test_feature_detection.cpp) +#TARGET_LINK_LIBRARIES(test_feature_detection svo) -ADD_EXECUTABLE(test_depth_filter test/test_depth_filter.cpp) -TARGET_LINK_LIBRARIES(test_depth_filter svo) +#ADD_EXECUTABLE(test_depth_filter test/test_depth_filter.cpp) +#TARGET_LINK_LIBRARIES(test_depth_filter svo) -ADD_EXECUTABLE(test_sparse_img_align test/test_sparse_img_align.cpp) -TARGET_LINK_LIBRARIES(test_sparse_img_align svo) +#ADD_EXECUTABLE(test_sparse_img_align test/test_sparse_img_align.cpp) +#TARGET_LINK_LIBRARIES(test_sparse_img_align svo) -ADD_EXECUTABLE(test_pose_optimizer test/test_pose_optimizer.cpp) -TARGET_LINK_LIBRARIES(test_pose_optimizer svo) +#ADD_EXECUTABLE(test_pose_optimizer test/test_pose_optimizer.cpp) +#TARGET_LINK_LIBRARIES(test_pose_optimizer svo) diff --git a/svo/include/svo/imu_integration.h b/svo/include/svo/imu_integration.h index 3cfb77e..442565d 100644 --- a/svo/include/svo/imu_integration.h +++ b/svo/include/svo/imu_integration.h @@ -99,19 +99,20 @@ class Imu_Integration{ public: Imu_Integration(Sophus::SE3& SE_init); ~Imu_Integration(); - bool reset(); + bool reset(gtsam::Values& result); bool update(float* imu= nullptr); - bool predict(boost::shared_ptr&,std::size_t&); + bool predict(boost::shared_ptr&,std::size_t&,const double reproj_thresh); private: std::shared_ptr statePtr; std::shared_ptr imu_biasPtr; - std::unique_ptr valuesPtr; - std::unique_ptr graphPtr; + std::shared_ptr valuesPtr; + std::shared_ptr graphPtr; boost::shared_ptr parameterPtr; - std::shared_ptr preintegratedPtr; + std::shared_ptr preintegratedPtr; boost::shared_ptr ProjectNoisePtr; - boost::shared_ptr cameraPtr; - std::uint32_t t_1=1e-18; + std::chrono::steady_clock::time_point t_1; std::uint32_t imu_factor_id=0; + double imu_mean=0.0; + bool syn=false; }; #endif //SVO_IMU_INTEGRATION_H diff --git a/svo/include/svo/svoVisionFactor.h b/svo/include/svo/svoVisionFactor.h new file mode 100644 index 0000000..b3f8ab3 --- /dev/null +++ b/svo/include/svo/svoVisionFactor.h @@ -0,0 +1,71 @@ +// +// Created by root on 4/13/21. +// + +#ifndef SVO_SVOVISIONFACTOR_H +#define SVO_SVOVISIONFACTOR_H +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + + class VisionFactor: public gtsam::NoiseModelFactor1 { + + private: + // measurement information + gtsam::Point3 feature; /// body_P_sensor_; ///< TODO The pose of the sensor in the body frame + int level; ///< Image pyramid level where feature was extracted. + + public: + /// shorthand for a smart pointer to a factor + typedef boost::shared_ptr shared_ptr; + + /** + * Constructor + * @param feature Unit-bearing vector of the feature. + * @param model is the standard deviation + * @param pointKey is the index of the landmark + * @param poseKey is the index of the camera pose + * @param landmark 3D position of the landmark + * @param body_P_sensor is the transform from body to sensor frame (default identity) + * @param level Image pyramid level where feature was extracted. + */ + VisionFactor(const gtsam::Point3& feature, const gtsam::Point3& landmark,const int level, const gtsam::SharedNoiseModel& Hp, + gtsam::Key poseKey,boost::optional body_P_sensor = boost::none) : + gtsam::NoiseModelFactor1(Hp, poseKey), feature(feature), landmark(landmark),body_P_sensor_(body_P_sensor),level(level){} + virtual ~VisionFactor(){} + + /// error function + /// @param p the Estimated pose in Pose3 + /// @param H the optional Jacobian matrix, which use boost optional and has default null pointer + gtsam::Vector evaluateError(const gtsam::Pose3& p, boost::optional Hp = boost::none) const { + // note that use boost optional like a pointer + // only calculate jacobian matrix when non-null pointer exists + gtsam::Matrix26 J; + gtsam::Point3 point(p*landmark); + svo::Frame::jacobian_xyz2uv(point, J); + if(Hp)(*Hp) = (gtsam::Matrix(2,6)<< J / (1<( + gtsam::NonlinearFactor::shared_ptr(new VisionFactor(*this))); } + + }; + +} // namespace gtsamexamples +#endif //SVO_SVOVISIONFACTOR_H diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index e4a3140..e51b3ba 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -160,7 +160,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() // pose optimization subject to change for adding IMU SVO_START_TIMER("pose_optimizer"); size_t sfba_n_edges_final; - if(!imu_integPtr_->predict(new_frame_,sfba_n_edges_final)) + if(!imu_integPtr_->predict(new_frame_,sfba_n_edges_final,Config::poseOptimThresh())) return RESULT_FAILURE; /* double sfba_thresh, sfba_error_init, sfba_error_final; diff --git a/svo/src/imu_integration.cpp b/svo/src/imu_integration.cpp index 575d31b..44e70ab 100644 --- a/svo/src/imu_integration.cpp +++ b/svo/src/imu_integration.cpp @@ -7,19 +7,20 @@ #include #include "svo/feature.h" #include "svo/point.h" +#include "svo/svoVisionFactor.h" Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ statePtr=std::make_shared(gtsam::Pose3(gtsam::Rot3(SE_init.rotation_matrix()),SE_init.translation()), gtsam::Vector3(0.0,0.0,0.0)); imu_biasPtr=std::make_shared(); - valuesPtr=std::make_unique(); + valuesPtr=std::make_shared(); valuesPtr->insert(P(0),statePtr->pose()); valuesPtr->insert(V(0),statePtr->v()); - valuesPtr->insert(B(0),*imu_biasPtr.get()); - graphPtr=std::make_unique(); + valuesPtr->insert(B(0),*imu_biasPtr); + graphPtr=std::make_shared(); graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 0.01, 0.01, 0.01, 0.5, 0.5, 0.5).finished())); graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 0.1)); - graphPtr->addPrior(B(0),*imu_biasPtr.get(),gtsam::noiseModel::Isotropic::Sigma(6, 1e-3)); + graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-3)); parameterPtr = gtsam::PreintegratedCombinedMeasurements::Params::MakeSharedD();// TODO check the IMU frame parameterPtr->accelerometerCovariance=gtsam::I_3x3 * pow(0.0003924, 2); // acc white noise in continuous parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * pow(0.00020568902491,2); // gyro white noise in continuous @@ -27,58 +28,87 @@ Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ parameterPtr->biasAccCovariance = gtsam::I_3x3 * pow(0.004905, 2);; // acc bias in continuous parameterPtr->biasOmegaCovariance = gtsam::I_3x3 * pow(0.000001454441043, 2); // gyro bias in continuous parameterPtr->biasAccOmegaInt = gtsam::I_6x6 * 1e-5; // error in the bias used for preintegration - preintegratedPtr = std::make_shared(parameterPtr,*imu_biasPtr.get()); - ProjectNoisePtr = gtsam::noiseModel::Isotropic::Sigma(2, 0.1); // error in the bias used for projection - cameraPtr=boost::make_shared(15,12,20,3,12); + preintegratedPtr = std::make_shared(parameterPtr,*imu_biasPtr); + ProjectNoisePtr = gtsam::noiseModel::Isotropic::Sigma(2, 0.1); // TODO change the noise used for projection assert(preintegratedPtr); } Imu_Integration::~Imu_Integration(){ } bool Imu_Integration::update(float* imu){ - if(t_1<1e-4){ - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),0.005); - t_1=imu[6]; - }else{ - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),imu[6]-t_1); - t_1=imu[6]; + if(syn)return false; + double m=0.0; + for(int i=0;i<6;++i){ + m+=abs(imu[i]); } - return true; -} -bool Imu_Integration::reset(){ - preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr.get()); - return true; -} -bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size_t& num_obs){ - // Adding IMU factor and and pre-integration. - auto preint_imu_combined =dynamic_cast(*preintegratedPtr); - gtsam::NavState Estimate_state = preintegratedPtr->predict(*statePtr.get(), *imu_biasPtr.get()); - ++imu_factor_id; - valuesPtr->insert(P(imu_factor_id), Estimate_state.pose()); - valuesPtr->insert(V(imu_factor_id), Estimate_state.v()); - valuesPtr->insert(B(imu_factor_id), *imu_biasPtr.get()); - gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), - preint_imu_combined); - graphPtr->emplace_shared(imu_factor); - for(auto&& f:enumerate(new_frame->fts_)){ - if(f.item->point==NULL)continue; - valuesPtr->insert(F(f.index), new_frame->T_f_w_ * f.item->point->pos_); - graphPtr->emplace_shared >( - f.item->px, ProjectNoisePtr, P( imu_factor_id), F(f.index), cameraPtr); + if((0.1666666667*m - imu_mean)>1e-6){ + imu_mean=0.1666666667*m; + auto in=std::chrono::steady_clock::now(); + if(std::chrono::duration(in-t_1).count()>20.0){ + t_1=in; + }else{ + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),std::chrono::duration(in-t_1).count()); + t_1=in; + } + return true; } + return false; - // Now optimize. - gtsam::LevenbergMarquardtParams params; - params.setVerbosityLM("SUMMARY"); - gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr.get(), *valuesPtr.get(), params); - gtsam::Values result = optimizer.optimize(); +} +bool Imu_Integration::reset(gtsam::Values& result){ // Overwrite the beginning of the preintegration for the next step. statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); - preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr.get()); - t_1=1e-18; + preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr); + graphPtr->resize(0); + valuesPtr->erase(P(imu_factor_id-1)); + valuesPtr->erase(V(imu_factor_id-1)); + valuesPtr->erase(B(imu_factor_id-1)); + t_1=std::chrono::steady_clock::now(); + return true; +} +bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size_t& num_obs,const double reproj_thresh){ + // Adding IMU factor and and pre-integration. + syn=true; + auto preint_imu_combined =dynamic_cast(*preintegratedPtr); + gtsam::NavState Estimate_state = preintegratedPtr->predict(*statePtr, *imu_biasPtr); + ++imu_factor_id; + valuesPtr->insert(P(imu_factor_id), Estimate_state.pose()); + valuesPtr->insert(V(imu_factor_id), Estimate_state.v()); + valuesPtr->insert(B(imu_factor_id), *imu_biasPtr); + gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), + preint_imu_combined); + graphPtr->emplace_shared(imu_factor); + num_obs=0; + for(auto&& f:new_frame->fts_){ + if(f->point==NULL)continue; + graphPtr->add(svo::VisionFactor(f->f, f->point->pos_,f->level, ProjectNoisePtr,P(imu_factor_id))); + ++num_obs; + } + // Now optimize. + //graphPtr->print(); + //valuesPtr->print(); + gtsam::LevenbergMarquardtParams params; + params.setVerbosityLM("SUMMARY"); + gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr, params); + gtsam::Values result = optimizer.optimize(); + reset(result); + syn=false; new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); - // new_frame->Cov_=gtsam:: - //if(!reset())return false; + double reproj_thresh_scaled = reproj_thresh / new_frame->cam_->errorMultiplier2(); + for(auto&& f:new_frame->fts_) + { + if(f->point == NULL) + continue; + Eigen::Vector2d e = vk::project2d(f->f) - vk::project2d(result.at(P(imu_factor_id)) * f->point->pos_); + double sqrt_inv_cov = 1.0 / (1<level); + e *= sqrt_inv_cov; + if(e.norm() > reproj_thresh_scaled) + { + // we don't need to delete a reference in the point since it was not created yet + f->point = NULL; + --num_obs; + } + } return true; } \ No newline at end of file diff --git a/vio_svo/CMakeLists.txt b/vio_svo/CMakeLists.txt index 059a8bf..bb8fdc9 100644 --- a/vio_svo/CMakeLists.txt +++ b/vio_svo/CMakeLists.txt @@ -8,7 +8,7 @@ SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/" # Set build flags. Set IS_ARM on odroid board as environment variable SET(CMAKE_CXX_FLAGS "-Wall -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") IF(DEFINED ENV{ARM_ARCHITECTURE}) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -march=armv7-a") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse -msse2 -msse3 -mssse3") ENDIF() @@ -20,8 +20,9 @@ ENDIF() SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -fsee -fomit-frame-pointer -fno-signed-zeros -fno-math-errno -funroll-loops") # Add catkin and required ROS packages -FIND_PACKAGE(catkin REQUIRED COMPONENTS - roscpp +FIND_PACKAGE(catkin REQUIRED COMPONENTS + geometry_msgs + roscpp cmake_modules nav_msgs std_msgs @@ -41,11 +42,12 @@ FIND_PACKAGE(OpenCV REQUIRED) FIND_PACKAGE(Eigen REQUIRED) FIND_PACKAGE(Sophus REQUIRED) FIND_PACKAGE(Boost REQUIRED COMPONENTS thread) +FIND_PACKAGE(GTSAM REQUIRED) # Describe catkin Project catkin_package( DEPENDS Eigen OpenCV Sophus Boost - CATKIN_DEPENDS roscpp nav_msgs std_msgs visualization_msgs sensor_msgs image_transport cv_bridge tf svo svo_msgs vikit_common vikit_ros + CATKIN_DEPENDS roscpp nav_msgs std_msgs visualization_msgs sensor_msgs image_transport cv_bridge tf svo svo_msgs vikit_common vikit_ros geometry_msgs INCLUDE_DIRS include LIBRARIES svo_visualizer ) @@ -70,10 +72,10 @@ LIST(APPEND LINK_LIBS # Create visualizer library ADD_LIBRARY(svo_visualizer src/visualizer.cpp) -TARGET_LINK_LIBRARIES(svo_visualizer ${LINK_LIBS}) +TARGET_LINK_LIBRARIES(svo_visualizer ${LINK_LIBS} gtsam) # Create Executables ADD_EXECUTABLE(vo src/vo_node.cpp) -TARGET_LINK_LIBRARIES(vo svo_visualizer) +TARGET_LINK_LIBRARIES(vo svo_visualizer ${LINK_LIBS}) #ADD_EXECUTABLE(benchmark src/benchmark_node.cpp) #TARGET_LINK_LIBRARIES(benchmark svo_visualizer) diff --git a/vio_svo/launch/unity.launch b/vio_svo/launch/unity.launch new file mode 100644 index 0000000..ea34997 --- /dev/null +++ b/vio_svo/launch/unity.launch @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vio_svo/package.xml b/vio_svo/package.xml index ff9eab3..bb5b0f2 100644 --- a/vio_svo/package.xml +++ b/vio_svo/package.xml @@ -26,6 +26,7 @@ svo_msgs vikit_common vikit_ros + geometry_msgs roscpp @@ -40,4 +41,5 @@ svo_msgs vikit_common vikit_ros + geometry_msgs \ No newline at end of file diff --git a/vio_svo/param/unity.yaml b/vio_svo/param/unity.yaml new file mode 100644 index 0000000..023f378 --- /dev/null +++ b/vio_svo/param/unity.yaml @@ -0,0 +1,8 @@ +cam_model: ATAN +cam_width: 1024 +cam_height: 720 +cam_fx: 1.98248 +cam_fy: 2.68212 +cam_cx: 0.502524 +cam_cy: 0.497744 +cam_d0: -0.000499999 \ No newline at end of file diff --git a/vio_svo/src/vo_node.cpp b/vio_svo/src/vo_node.cpp index 908abb8..0333176 100644 --- a/vio_svo/src/vo_node.cpp +++ b/vio_svo/src/vo_node.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +50,8 @@ public: VoNode(); ~VoNode(); void imgCb(const sensor_msgs::ImageConstPtr& msg); - void imuCb(const sensor_msgs::ImuPtr& imu); + //void imuCb(const sensor_msgs::ImuPtr& imu); + void imuCb(const geometry_msgs::PoseStamped& imu); void imu(); }; @@ -106,15 +108,22 @@ void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) ROS_ERROR("cv_bridge exception: %s", e.what()); } } -void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { - float imu_in[7]; - imu_in[0] = imu->angular_velocity.x; +void VoNode::imuCb(const geometry_msgs::PoseStamped &imu) { + float imu_in[6]; + /*imu_in[0] = imu->angular_velocity.x; imu_in[1] = imu->angular_velocity.y; imu_in[2] = imu->angular_velocity.z; imu_in[3] = imu->linear_acceleration.x; imu_in[4] = imu->linear_acceleration.y; imu_in[5] = imu->linear_acceleration.z; imu_in[6] = imu->header.stamp.sec; + */ + imu_in[0] = imu.pose.position.z; + imu_in[1] = imu.pose.position.x; + imu_in[2] = imu.pose.position.y+9.8; + imu_in[3] = imu.pose.orientation.z; + imu_in[4] = imu.pose.orientation.x; + imu_in[5] = imu.pose.orientation.y; vo_->imu_integPtr_->update(imu_in); } void VoNode::imu(){ @@ -137,11 +146,12 @@ int main(int argc, char **argv) ros::init(argc, argv, "vio"); svo::VoNode vo_node; ros::NodeHandle nh; - ros::Subscriber imu_sub=nh.subscribe(vk::getParam("vio/imu_topic", "imu/raw"),10,&svo::VoNode::imuCb, &vo_node); + ros::Subscriber imu_sub=nh.subscribe(vk::getParam("vio/imu_topic", "imu/raw"),1,&svo::VoNode::imuCb, &vo_node); // start processing callbacks while(ros::ok() && !vo_node.quit_) { ros::spinOnce(); + usleep(1000); // TODO check when last image was processed. when too long ago. publish warning that no msgs are received! } printf("SVO terminated.\n"); From 121cfe1095abce32b8248b85409c7f8917219dd5 Mon Sep 17 00:00:00 2001 From: gfuse Date: Fri, 16 Apr 2021 17:55:40 +0200 Subject: [PATCH 179/215] debuging based on px30 -> still in progress --- svo/include/svo/imu_integration.h | 4 +-- svo/src/imu_integration.cpp | 56 ++++++++++++++++++------------- vio_svo/launch/Px30.launch | 6 ++-- vio_svo/src/vo_node.cpp | 28 ++++++---------- 4 files changed, 47 insertions(+), 47 deletions(-) diff --git a/svo/include/svo/imu_integration.h b/svo/include/svo/imu_integration.h index 442565d..8c6f95c 100644 --- a/svo/include/svo/imu_integration.h +++ b/svo/include/svo/imu_integration.h @@ -100,7 +100,7 @@ public: Imu_Integration(Sophus::SE3& SE_init); ~Imu_Integration(); bool reset(gtsam::Values& result); - bool update(float* imu= nullptr); + bool update(double* imu= nullptr); bool predict(boost::shared_ptr&,std::size_t&,const double reproj_thresh); private: std::shared_ptr statePtr; @@ -112,7 +112,7 @@ private: boost::shared_ptr ProjectNoisePtr; std::chrono::steady_clock::time_point t_1; std::uint32_t imu_factor_id=0; - double imu_mean=0.0; + std::uint64_t imu_stamp=0.0; bool syn=false; }; #endif //SVO_IMU_INTEGRATION_H diff --git a/svo/src/imu_integration.cpp b/svo/src/imu_integration.cpp index 44e70ab..f6b9809 100644 --- a/svo/src/imu_integration.cpp +++ b/svo/src/imu_integration.cpp @@ -8,47 +8,45 @@ #include "svo/feature.h" #include "svo/point.h" #include "svo/svoVisionFactor.h" +#include Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ statePtr=std::make_shared(gtsam::Pose3(gtsam::Rot3(SE_init.rotation_matrix()),SE_init.translation()), gtsam::Vector3(0.0,0.0,0.0)); - imu_biasPtr=std::make_shared(); + imu_biasPtr=std::make_shared(gtsam::Vector3(1e-8,1e-8,1e-8),gtsam::Vector3(1e-8,1e-8,1e-8)); valuesPtr=std::make_shared(); valuesPtr->insert(P(0),statePtr->pose()); valuesPtr->insert(V(0),statePtr->v()); valuesPtr->insert(B(0),*imu_biasPtr); graphPtr=std::make_shared(); - graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 0.01, 0.01, 0.01, 0.5, 0.5, 0.5).finished())); - graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 0.1)); - graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-3)); + graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 0.01, 0.01, 0.01, 0.01, 0.01, 0.01).finished())); + graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 0.01)); + graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-4)); parameterPtr = gtsam::PreintegratedCombinedMeasurements::Params::MakeSharedD();// TODO check the IMU frame - parameterPtr->accelerometerCovariance=gtsam::I_3x3 * pow(0.0003924, 2); // acc white noise in continuous - parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * pow(0.00020568902491,2); // gyro white noise in continuous + parameterPtr->accelerometerCovariance=gtsam::I_3x3 * 1e-3; // acc white noise in continuous + parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * 1e-3; // gyro white noise in continuous parameterPtr->integrationCovariance=gtsam::I_3x3 * 1e-8; // integration uncertainty continuous - parameterPtr->biasAccCovariance = gtsam::I_3x3 * pow(0.004905, 2);; // acc bias in continuous - parameterPtr->biasOmegaCovariance = gtsam::I_3x3 * pow(0.000001454441043, 2); // gyro bias in continuous + parameterPtr->biasAccCovariance = gtsam::I_3x3 * 1e-8; // acc bias in continuous + parameterPtr->biasOmegaCovariance = gtsam::I_3x3 * 1e-8; // gyro bias in continuous parameterPtr->biasAccOmegaInt = gtsam::I_6x6 * 1e-5; // error in the bias used for preintegration preintegratedPtr = std::make_shared(parameterPtr,*imu_biasPtr); - ProjectNoisePtr = gtsam::noiseModel::Isotropic::Sigma(2, 0.1); // TODO change the noise used for projection + ProjectNoisePtr = gtsam::noiseModel::Isotropic::Sigma(2, 1e-8); // TODO change the noise used for projection assert(preintegratedPtr); } Imu_Integration::~Imu_Integration(){ } -bool Imu_Integration::update(float* imu){ +bool Imu_Integration::update(double* imu){ if(syn)return false; - double m=0.0; - for(int i=0;i<6;++i){ - m+=abs(imu[i]); - } - if((0.1666666667*m - imu_mean)>1e-6){ - imu_mean=0.1666666667*m; + if(imu[6]>imu_stamp){ auto in=std::chrono::steady_clock::now(); if(std::chrono::duration(in-t_1).count()>20.0){ t_1=in; + imu_stamp=imu[6]; }else{ preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),std::chrono::duration(in-t_1).count()); t_1=in; + imu_stamp=imu[6]; } return true; } @@ -60,11 +58,11 @@ bool Imu_Integration::reset(gtsam::Values& result){ statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr); - graphPtr->resize(0); - valuesPtr->erase(P(imu_factor_id-1)); - valuesPtr->erase(V(imu_factor_id-1)); - valuesPtr->erase(B(imu_factor_id-1)); - t_1=std::chrono::steady_clock::now(); + //graphPtr->resize(0); + //valuesPtr->erase(P(imu_factor_id-1)); + //valuesPtr->erase(V(imu_factor_id-1)); + //valuesPtr->erase(B(imu_factor_id-1)); + //t_1=std::chrono::steady_clock::now(); return true; } bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size_t& num_obs,const double reproj_thresh){ @@ -72,6 +70,8 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size syn=true; auto preint_imu_combined =dynamic_cast(*preintegratedPtr); gtsam::NavState Estimate_state = preintegratedPtr->predict(*statePtr, *imu_biasPtr); + std::cout<<"--------------------------------------------------------------------------PreIntegration----------------------------------------------"<<'\n'; + //preintegratedPtr->print(); ++imu_factor_id; valuesPtr->insert(P(imu_factor_id), Estimate_state.pose()); valuesPtr->insert(V(imu_factor_id), Estimate_state.v()); @@ -79,28 +79,36 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), preint_imu_combined); graphPtr->emplace_shared(imu_factor); + imu_factor.print(); num_obs=0; for(auto&& f:new_frame->fts_){ if(f->point==NULL)continue; - graphPtr->add(svo::VisionFactor(f->f, f->point->pos_,f->level, ProjectNoisePtr,P(imu_factor_id))); + graphPtr->emplace_shared(f->f, f->point->pos_,f->level, ProjectNoisePtr,P(imu_factor_id)); ++num_obs; } // Now optimize. + std::cout<<"--------------------------------------------------------------------------graph----------------------------------------------"<<'\n'; //graphPtr->print(); - //valuesPtr->print(); + std::cout<<"--------------------------------------------------------------------------values----------------------------------------------"<<'\n'; + valuesPtr->print(); gtsam::LevenbergMarquardtParams params; params.setVerbosityLM("SUMMARY"); gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr, params); gtsam::Values result = optimizer.optimize(); + gtsam::Marginals marginals(*graphPtr, result); + std::cout<<"--------------------------------------------------------------------------marginals----------------------------------------------"<<'\n'; + //marginals.print(); reset(result); syn=false; new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); + new_frame->Cov_=marginals.marginalCovariance(P(imu_factor_id)); + std::cout<Cov_<<'\n'; double reproj_thresh_scaled = reproj_thresh / new_frame->cam_->errorMultiplier2(); for(auto&& f:new_frame->fts_) { if(f->point == NULL) continue; - Eigen::Vector2d e = vk::project2d(f->f) - vk::project2d(result.at(P(imu_factor_id)) * f->point->pos_); + Eigen::Vector2d e = vk::project2d(f->f) - vk::project2d(new_frame->T_f_w_ * f->point->pos_); double sqrt_inv_cov = 1.0 / (1<level); e *= sqrt_inv_cov; if(e.norm() > reproj_thresh_scaled) diff --git a/vio_svo/launch/Px30.launch b/vio_svo/launch/Px30.launch index 6ff3dab..2afa3b2 100644 --- a/vio_svo/launch/Px30.launch +++ b/vio_svo/launch/Px30.launch @@ -7,13 +7,13 @@ - + - + - + diff --git a/vio_svo/src/vo_node.cpp b/vio_svo/src/vo_node.cpp index 0333176..ebe8c7a 100644 --- a/vio_svo/src/vo_node.cpp +++ b/vio_svo/src/vo_node.cpp @@ -50,8 +50,7 @@ public: VoNode(); ~VoNode(); void imgCb(const sensor_msgs::ImageConstPtr& msg); - //void imuCb(const sensor_msgs::ImuPtr& imu); - void imuCb(const geometry_msgs::PoseStamped& imu); + void imuCb(const sensor_msgs::ImuPtr& imu); void imu(); }; @@ -108,22 +107,15 @@ void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) ROS_ERROR("cv_bridge exception: %s", e.what()); } } -void VoNode::imuCb(const geometry_msgs::PoseStamped &imu) { - float imu_in[6]; - /*imu_in[0] = imu->angular_velocity.x; - imu_in[1] = imu->angular_velocity.y; - imu_in[2] = imu->angular_velocity.z; - imu_in[3] = imu->linear_acceleration.x; - imu_in[4] = imu->linear_acceleration.y; - imu_in[5] = imu->linear_acceleration.z; - imu_in[6] = imu->header.stamp.sec; - */ - imu_in[0] = imu.pose.position.z; - imu_in[1] = imu.pose.position.x; - imu_in[2] = imu.pose.position.y+9.8; - imu_in[3] = imu.pose.orientation.z; - imu_in[4] = imu.pose.orientation.x; - imu_in[5] = imu.pose.orientation.y; +void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { + double imu_in[7]; + imu_in[0] = imu->linear_acceleration.x; + imu_in[1] = imu->linear_acceleration.y; + imu_in[2] = imu->linear_acceleration.z; + imu_in[3] = imu->angular_velocity.x; + imu_in[4] = imu->angular_velocity.y; + imu_in[5] = imu->angular_velocity.z; + imu_in[6] = imu->header.stamp.toNSec(); vo_->imu_integPtr_->update(imu_in); } void VoNode::imu(){ From 661acff27f82140a1ccce4168f8f02d4407a7735 Mon Sep 17 00:00:00 2001 From: gfuse Date: Mon, 19 Apr 2021 19:49:17 +0200 Subject: [PATCH 180/215] The best possible situation 19.4.2021 --- svo/include/svo/imu_integration.h | 8 +- svo/include/svo/svoVisionFactor.h | 5 +- svo/src/frame_handler_mono.cpp | 35 ++------ svo/src/imu_integration.cpp | 142 ++++++++++++++++-------------- vio_svo/launch/Px30.launch | 6 +- vio_svo/param/vo_fast.yaml | 9 +- vio_svo/src/vo_node.cpp | 5 +- 7 files changed, 102 insertions(+), 108 deletions(-) diff --git a/svo/include/svo/imu_integration.h b/svo/include/svo/imu_integration.h index 8c6f95c..b6da3a7 100644 --- a/svo/include/svo/imu_integration.h +++ b/svo/include/svo/imu_integration.h @@ -11,13 +11,14 @@ #include #include #include +#include #include #include using gtsam::symbol_shorthand::B; // Bias (ax,ay,az,gx,gy,gz) using gtsam::symbol_shorthand::V; // Vel (xdot,ydot,zdot) using gtsam::symbol_shorthand::P; // Pose3 (x,y,z,r,p,y) -using gtsam::symbol_shorthand::F; // Feature +using gtsam::symbol_shorthand::C; // Camera pose //https://stackoverflow.com/questions/24881799/get-index-in-c11-foreach-loop // Wrapper class @@ -99,7 +100,7 @@ class Imu_Integration{ public: Imu_Integration(Sophus::SE3& SE_init); ~Imu_Integration(); - bool reset(gtsam::Values& result); + bool reset(gtsam::ISAM2& optimizer,boost::shared_ptr& new_frame); bool update(double* imu= nullptr); bool predict(boost::shared_ptr&,std::size_t&,const double reproj_thresh); private: @@ -112,7 +113,8 @@ private: boost::shared_ptr ProjectNoisePtr; std::chrono::steady_clock::time_point t_1; std::uint32_t imu_factor_id=0; - std::uint64_t imu_stamp=0.0; + uint imu_n=0; + std::shared_ptr optimizerParamPtr; bool syn=false; }; #endif //SVO_IMU_INTEGRATION_H diff --git a/svo/include/svo/svoVisionFactor.h b/svo/include/svo/svoVisionFactor.h index b3f8ab3..cd00816 100644 --- a/svo/include/svo/svoVisionFactor.h +++ b/svo/include/svo/svoVisionFactor.h @@ -53,9 +53,8 @@ namespace svo { gtsam::Matrix26 J; gtsam::Point3 point(p*landmark); svo::Frame::jacobian_xyz2uv(point, J); - if(Hp)(*Hp) = (gtsam::Matrix(2,6)<< J / (1<T_f_w_ = last_frame_->T_f_w_; // sparse image align - SVO_START_TIMER("sparse_img_align"); SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), 30, SparseImgAlign::GaussNewton, false, false); size_t img_align_n_tracked = img_align.run(last_frame_, new_frame_); - SVO_STOP_TIMER("sparse_img_align"); - SVO_LOG(img_align_n_tracked); - SVO_DEBUG_STREAM("Img Align:\t Tracked = " << img_align_n_tracked); + std::cout<<"Img Align:\t Tracked = "<T_f_w_ = last_frame_->T_f_w_; // reset to avoid crazy pose jumps @@ -158,22 +150,12 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() } // pose optimization subject to change for adding IMU - SVO_START_TIMER("pose_optimizer"); size_t sfba_n_edges_final; if(!imu_integPtr_->predict(new_frame_,sfba_n_edges_final,Config::poseOptimThresh())) return RESULT_FAILURE; - /* - double sfba_thresh, sfba_error_init, sfba_error_final; - pose_optimizer::optimizeGaussNewton( - Config::poseOptimThresh(), Config::poseOptimNumIter(), false, - new_frame_, sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final); - SVO_STOP_TIMER("pose_optimizer"); - SVO_LOG4(sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final); - SVO_DEBUG_STREAM("PoseOptimizer:\t ErrInit = "<T_f_w_ = last_frame_->T_f_w_; // reset to avoid crazy pose jumps diff --git a/svo/src/imu_integration.cpp b/svo/src/imu_integration.cpp index f6b9809..6d710fb 100644 --- a/svo/src/imu_integration.cpp +++ b/svo/src/imu_integration.cpp @@ -9,28 +9,25 @@ #include "svo/point.h" #include "svo/svoVisionFactor.h" #include +#include Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ - statePtr=std::make_shared(gtsam::Pose3(gtsam::Rot3(SE_init.rotation_matrix()),SE_init.translation()), - gtsam::Vector3(0.0,0.0,0.0)); - imu_biasPtr=std::make_shared(gtsam::Vector3(1e-8,1e-8,1e-8),gtsam::Vector3(1e-8,1e-8,1e-8)); - valuesPtr=std::make_shared(); - valuesPtr->insert(P(0),statePtr->pose()); - valuesPtr->insert(V(0),statePtr->v()); - valuesPtr->insert(B(0),*imu_biasPtr); graphPtr=std::make_shared(); - graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 0.01, 0.01, 0.01, 0.01, 0.01, 0.01).finished())); - graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 0.01)); - graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-4)); + valuesPtr=std::make_shared(); parameterPtr = gtsam::PreintegratedCombinedMeasurements::Params::MakeSharedD();// TODO check the IMU frame - parameterPtr->accelerometerCovariance=gtsam::I_3x3 * 1e-3; // acc white noise in continuous - parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * 1e-3; // gyro white noise in continuous - parameterPtr->integrationCovariance=gtsam::I_3x3 * 1e-8; // integration uncertainty continuous - parameterPtr->biasAccCovariance = gtsam::I_3x3 * 1e-8; // acc bias in continuous - parameterPtr->biasOmegaCovariance = gtsam::I_3x3 * 1e-8; // gyro bias in continuous - parameterPtr->biasAccOmegaInt = gtsam::I_6x6 * 1e-5; // error in the bias used for preintegration + parameterPtr->accelerometerCovariance=gtsam::I_3x3 * 1e-4; // acc white noise in continuous + parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * 1e-4; // gyro white noise in continuous + parameterPtr->integrationCovariance=gtsam::I_3x3 * 1e-1; // integration uncertainty continuous + parameterPtr->biasAccCovariance = gtsam::I_3x3 * 1e-1; // acc bias in continuous + parameterPtr->biasOmegaCovariance = gtsam::I_3x3 * 1e-1; // gyro bias in continuous + parameterPtr->biasAccOmegaInt = gtsam::I_6x6 * 1e-2; // error in the bias used for preintegration + imu_biasPtr=std::make_shared(gtsam::Vector3(1e-8,1e-8,1e-8),gtsam::Vector3(1e-8,1e-8,1e-8)); preintegratedPtr = std::make_shared(parameterPtr,*imu_biasPtr); - ProjectNoisePtr = gtsam::noiseModel::Isotropic::Sigma(2, 1e-8); // TODO change the noise used for projection + ProjectNoisePtr = gtsam::noiseModel::Isotropic::Sigma(2, 1e-8); // the noise used for projection + optimizerParamPtr=std::make_shared(); + optimizerParamPtr->relinearizeThreshold = 0.1; + optimizerParamPtr->relinearizeSkip = 1; + optimizerParamPtr->evaluateNonlinearError=true; assert(preintegratedPtr); } Imu_Integration::~Imu_Integration(){ @@ -38,48 +35,66 @@ Imu_Integration::~Imu_Integration(){ } bool Imu_Integration::update(double* imu){ if(syn)return false; - if(imu[6]>imu_stamp){ - auto in=std::chrono::steady_clock::now(); - if(std::chrono::duration(in-t_1).count()>20.0){ - t_1=in; - imu_stamp=imu[6]; - }else{ - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),std::chrono::duration(in-t_1).count()); - t_1=in; - imu_stamp=imu[6]; - } - return true; + if(imu_factor_id<1)return false; + auto in=std::chrono::steady_clock::now(); + if(std::chrono::duration(in-t_1).count()>20.0){ + t_1=in; + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),0.005); + }else{ + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),std::chrono::duration(in-t_1).count()); + t_1=in; + ++imu_n; } - return false; + return true; } -bool Imu_Integration::reset(gtsam::Values& result){ +bool Imu_Integration::reset(gtsam::ISAM2& optimizer,boost::shared_ptr& new_frame){ + gtsam::Values result = optimizer.calculateEstimate(); // Overwrite the beginning of the preintegration for the next step. statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr); - //graphPtr->resize(0); - //valuesPtr->erase(P(imu_factor_id-1)); - //valuesPtr->erase(V(imu_factor_id-1)); - //valuesPtr->erase(B(imu_factor_id-1)); - //t_1=std::chrono::steady_clock::now(); + ++imu_factor_id; + syn=false; + new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); + new_frame->Cov_=optimizer.marginalCovariance(P(imu_factor_id-1)); + graphPtr->resize(0); + valuesPtr->clear(); + valuesPtr->insert(P(imu_factor_id-1),statePtr->pose()); + valuesPtr->insert(V(imu_factor_id-1),statePtr->v()); + valuesPtr->insert(B(imu_factor_id-1),*imu_biasPtr); + graphPtr->addPrior(P(imu_factor_id-1),statePtr->pose(),optimizer.marginalCovariance(P(imu_factor_id-1))); + graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),optimizer.marginalCovariance(V(imu_factor_id-1))); + graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,optimizer.marginalCovariance(B(imu_factor_id-1))); return true; } bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size_t& num_obs,const double reproj_thresh){ - // Adding IMU factor and and pre-integration. + usleep(5000); syn=true; - auto preint_imu_combined =dynamic_cast(*preintegratedPtr); - gtsam::NavState Estimate_state = preintegratedPtr->predict(*statePtr, *imu_biasPtr); - std::cout<<"--------------------------------------------------------------------------PreIntegration----------------------------------------------"<<'\n'; - //preintegratedPtr->print(); - ++imu_factor_id; - valuesPtr->insert(P(imu_factor_id), Estimate_state.pose()); - valuesPtr->insert(V(imu_factor_id), Estimate_state.v()); - valuesPtr->insert(B(imu_factor_id), *imu_biasPtr); - gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), - preint_imu_combined); - graphPtr->emplace_shared(imu_factor); - imu_factor.print(); + if(imu_factor_id<1){ + statePtr=std::make_shared(gtsam::Pose3(new_frame->T_f_w_.matrix()), + gtsam::Vector3(1e-12,1e-12,1e-12)); + valuesPtr->insert(P(0),statePtr->pose()); + valuesPtr->insert(V(0),statePtr->v()); + valuesPtr->insert(B(0),*imu_biasPtr); + graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 1e-9, 1e-9, 1e-9, 1e-9, 1e-9, 1e-9).finished())); + graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 1e-4)); + graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-2)); + }else{ + if(imu_n<3)return false; + auto preint_imu_combined =dynamic_cast(*preintegratedPtr); + //gtsam::NavState Estimate_state = preintegratedPtr->predict(*statePtr, *imu_biasPtr); + valuesPtr->insert(P(imu_factor_id), gtsam::Pose3(new_frame->T_f_w_.matrix())); + //valuesPtr->insert(P(imu_factor_id), Estimate_state.pose()); + valuesPtr->insert(V(imu_factor_id), statePtr->v()); + //valuesPtr->insert(V(imu_factor_id), Estimate_state.v()); + valuesPtr->insert(B(imu_factor_id), *imu_biasPtr); + gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), + preint_imu_combined); + graphPtr->emplace_shared(imu_factor); + imu_n=0; + } + num_obs=0; for(auto&& f:new_frame->fts_){ if(f->point==NULL)continue; @@ -87,32 +102,25 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size ++num_obs; } // Now optimize. - std::cout<<"--------------------------------------------------------------------------graph----------------------------------------------"<<'\n'; - //graphPtr->print(); - std::cout<<"--------------------------------------------------------------------------values----------------------------------------------"<<'\n'; - valuesPtr->print(); - gtsam::LevenbergMarquardtParams params; - params.setVerbosityLM("SUMMARY"); - gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr, params); - gtsam::Values result = optimizer.optimize(); - gtsam::Marginals marginals(*graphPtr, result); - std::cout<<"--------------------------------------------------------------------------marginals----------------------------------------------"<<'\n'; - //marginals.print(); - reset(result); - syn=false; - new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); - new_frame->Cov_=marginals.marginalCovariance(P(imu_factor_id)); - std::cout<Cov_<<'\n'; + gtsam::ISAM2 optimizer(*optimizerParamPtr); + optimizer.update(*graphPtr, *valuesPtr); + // Each call to iSAM2 update(*) performs one iteration of the iterative + // nonlinear solver. If accuracy is desired at the expense of time, + // update(*) can be called additional times to perform multiple optimizer + // iterations every step. + optimizer.update(); + // optimizer.print(); + reset(optimizer,new_frame); + // Remove Measurements with too large reprojection error double reproj_thresh_scaled = reproj_thresh / new_frame->cam_->errorMultiplier2(); for(auto&& f:new_frame->fts_) { if(f->point == NULL) continue; - Eigen::Vector2d e = vk::project2d(f->f) - vk::project2d(new_frame->T_f_w_ * f->point->pos_); - double sqrt_inv_cov = 1.0 / (1<level); - e *= sqrt_inv_cov; + Eigen::Vector2d e = (vk::project2d(f->f) - vk::project2d(new_frame->T_f_w_ * f->point->pos_))*1.0 / (1<level); if(e.norm() > reproj_thresh_scaled) { + std::cout<<"Error: "<point = NULL; --num_obs; diff --git a/vio_svo/launch/Px30.launch b/vio_svo/launch/Px30.launch index 2afa3b2..06083d0 100644 --- a/vio_svo/launch/Px30.launch +++ b/vio_svo/launch/Px30.launch @@ -9,9 +9,6 @@ - - - @@ -19,4 +16,7 @@ + + + diff --git a/vio_svo/param/vo_fast.yaml b/vio_svo/param/vo_fast.yaml index 3df87dd..3fa20a3 100644 --- a/vio_svo/param/vo_fast.yaml +++ b/vio_svo/param/vo_fast.yaml @@ -1,3 +1,6 @@ -grid_size: 30 -max_n_kfs: 10 -loba_num_iter: 0 \ No newline at end of file +svo: + grid_size: 30 + max_n_kfs: 10 + loba_num_iter: 0 + quality_min_fts: 20 + quality_max_drop_fts: 50 \ No newline at end of file diff --git a/vio_svo/src/vo_node.cpp b/vio_svo/src/vo_node.cpp index ebe8c7a..2f98da0 100644 --- a/vio_svo/src/vo_node.cpp +++ b/vio_svo/src/vo_node.cpp @@ -108,14 +108,13 @@ void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) } } void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { - double imu_in[7]; + double imu_in[6]; imu_in[0] = imu->linear_acceleration.x; imu_in[1] = imu->linear_acceleration.y; imu_in[2] = imu->linear_acceleration.z; imu_in[3] = imu->angular_velocity.x; imu_in[4] = imu->angular_velocity.y; imu_in[5] = imu->angular_velocity.z; - imu_in[6] = imu->header.stamp.toNSec(); vo_->imu_integPtr_->update(imu_in); } void VoNode::imu(){ @@ -123,7 +122,7 @@ void VoNode::imu(){ std::cout << "create vo_node" << std::endl; // subscribe to cam msgs image_transport::ImageTransport it(nh); - image_transport::Subscriber it_sub = it.subscribe(vk::getParam("vio/cam_topic", "camera/image_raw"), 5, &svo::VoNode::imgCb, this); + image_transport::Subscriber it_sub = it.subscribe(vk::getParam("vio/cam_topic", "camera/image_raw"), 1, &svo::VoNode::imgCb, this); // start processing callbacks while(ros::ok() && !quit_) { From 4987e55ec7fb5119c3202e1dc5d53cd92159995b Mon Sep 17 00:00:00 2001 From: gfuse Date: Tue, 20 Apr 2021 16:18:52 +0200 Subject: [PATCH 181/215] The best possible situation 20.4.2021 --- svo/include/svo/config.h | 18 +++++++++++ svo/include/svo/imu_integration.h | 1 + svo/src/config.cpp | 9 +++++- svo/src/frame_handler_mono.cpp | 18 ++++------- svo/src/imu_integration.cpp | 51 ++++++++++++++++++++++--------- vio_svo/param/vo_fast.yaml | 17 ++++++++--- 6 files changed, 81 insertions(+), 33 deletions(-) diff --git a/svo/include/svo/config.h b/svo/include/svo/config.h index d4f50df..e1c97b1 100644 --- a/svo/include/svo/config.h +++ b/svo/include/svo/config.h @@ -119,6 +119,23 @@ public: /// If within one frame, this amount of features are dropped. Tracking quality is bad. static int& qualityMaxFtsDrop() { return getInstance().quality_max_drop_fts; } + /// acc white noise in continuous. + static double& ACC_Noise() { return getInstance().ACC_noise; } + + /// acc white noise in continuous. + static double& GYO_Noise() { return getInstance().GYO_noise; } + /// integration uncertainty continuous + static double& IUC() { return getInstance().iuc; } + // acc bias in continuous + static double& ABC() { return getInstance().abc; } + // gyro bias in continuous + static double& GBC() { return getInstance().gbc; } + // error in the bias used for preintegration + static double& EBP() { return getInstance().ebp; } + // the noise used for projection + static double& NRP() { return getInstance().nrp; } + + private: Config(); Config(Config const&); @@ -152,6 +169,7 @@ private: size_t max_fts; size_t quality_min_fts; int quality_max_drop_fts; + double nrp,ebp,gbc,abc,iuc,ACC_noise,GYO_noise; }; } // namespace svo diff --git a/svo/include/svo/imu_integration.h b/svo/include/svo/imu_integration.h index b6da3a7..11b9055 100644 --- a/svo/include/svo/imu_integration.h +++ b/svo/include/svo/imu_integration.h @@ -101,6 +101,7 @@ public: Imu_Integration(Sophus::SE3& SE_init); ~Imu_Integration(); bool reset(gtsam::ISAM2& optimizer,boost::shared_ptr& new_frame); + bool reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr& new_frame); bool update(double* imu= nullptr); bool predict(boost::shared_ptr&,std::size_t&,const double reproj_thresh); private: diff --git a/svo/src/config.cpp b/svo/src/config.cpp index f6820f4..e8475fe 100644 --- a/svo/src/config.cpp +++ b/svo/src/config.cpp @@ -51,7 +51,14 @@ Config::Config() : img_imu_delay(vk::getParam("svo/img_imu_delay", 0.0)), max_fts(vk::getParam("svo/max_fts", 120)), quality_min_fts(vk::getParam("svo/quality_min_fts", 50)), - quality_max_drop_fts(vk::getParam("svo/quality_max_drop_fts", 40)) + quality_max_drop_fts(vk::getParam("svo/quality_max_drop_fts", 40)), + ACC_noise(vk::getParam("svo/ACC_noise", 1e-4)), + GYO_noise(vk::getParam("svo/GYO_noise", 1e-4)), + iuc(vk::getParam("svo/IUC", 1e-1)), + abc(vk::getParam("svo/ABC", 1e-1)), + gbc(vk::getParam("svo/GBC", 1e-1)), + ebp(vk::getParam("svo/EBP", 1e-2)), + nrp(vk::getParam("svo/NRP", 1e-5)) #else trace_name("svo"), trace_dir("/tmp"), diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index e5111cf..780d9c7 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -66,9 +66,7 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) overlap_kfs_.clear(); // create new frame - //SVO_START_TIMER("pyramid_creation"); new_frame_.reset(new Frame(cam_, img.clone(), timestamp)); - //SVO_STOP_TIMER("pyramid_creation"); // process frame UpdateResult res = RESULT_FAILURE; @@ -135,12 +133,10 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() // sparse image align SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), 30, SparseImgAlign::GaussNewton, false, false); - size_t img_align_n_tracked = img_align.run(last_frame_, new_frame_); - std::cout<<"Img Align:\t Tracked = "<predict(new_frame_,sfba_n_edges_final,Config::poseOptimThresh())) return RESULT_FAILURE; - std::cout<<"reprojected point after opmization: "<T_f_w_ = last_frame_->T_f_w_; // reset to avoid crazy pose jumps @@ -179,7 +174,6 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() return RESULT_NO_KEYFRAME; } new_frame_->setKeyframe(); - SVO_DEBUG_STREAM("New keyframe selected."); // new keyframe selected for(Features::iterator it=new_frame_->fts_.begin(); it!=new_frame_->fts_.end(); ++it) @@ -218,7 +212,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() // add keyframe to map map_.addKeyframe(new_frame_); - + std::cerr<<"Svo pipline was finished\n"; return RESULT_IS_KEYFRAME; } diff --git a/svo/src/imu_integration.cpp b/svo/src/imu_integration.cpp index 6d710fb..2aed670 100644 --- a/svo/src/imu_integration.cpp +++ b/svo/src/imu_integration.cpp @@ -10,24 +10,26 @@ #include "svo/svoVisionFactor.h" #include #include +#include +#include Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ graphPtr=std::make_shared(); valuesPtr=std::make_shared(); parameterPtr = gtsam::PreintegratedCombinedMeasurements::Params::MakeSharedD();// TODO check the IMU frame - parameterPtr->accelerometerCovariance=gtsam::I_3x3 * 1e-4; // acc white noise in continuous - parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * 1e-4; // gyro white noise in continuous - parameterPtr->integrationCovariance=gtsam::I_3x3 * 1e-1; // integration uncertainty continuous - parameterPtr->biasAccCovariance = gtsam::I_3x3 * 1e-1; // acc bias in continuous - parameterPtr->biasOmegaCovariance = gtsam::I_3x3 * 1e-1; // gyro bias in continuous - parameterPtr->biasAccOmegaInt = gtsam::I_6x6 * 1e-2; // error in the bias used for preintegration + parameterPtr->accelerometerCovariance=gtsam::I_3x3 * svo::Config::ACC_Noise(); // acc white noise in continuous + parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * svo::Config::GYO_Noise();// gyro white noise in continuous + parameterPtr->integrationCovariance=gtsam::I_3x3 * svo::Config::IUC(); // integration uncertainty continuous + parameterPtr->biasAccCovariance = gtsam::I_3x3 * svo::Config::ABC(); // acc bias in continuous + parameterPtr->biasOmegaCovariance = gtsam::I_3x3 * svo::Config::GBC(); // gyro bias in continuous + parameterPtr->biasAccOmegaInt = gtsam::I_6x6 * svo::Config::EBP(); // error in the bias used for preintegration imu_biasPtr=std::make_shared(gtsam::Vector3(1e-8,1e-8,1e-8),gtsam::Vector3(1e-8,1e-8,1e-8)); preintegratedPtr = std::make_shared(parameterPtr,*imu_biasPtr); - ProjectNoisePtr = gtsam::noiseModel::Isotropic::Sigma(2, 1e-8); // the noise used for projection + ProjectNoisePtr = gtsam::noiseModel::Isotropic::Sigma(2, svo::Config::NRP()); // the noise used for projection optimizerParamPtr=std::make_shared(); optimizerParamPtr->relinearizeThreshold = 0.1; optimizerParamPtr->relinearizeSkip = 1; - optimizerParamPtr->evaluateNonlinearError=true; + //optimizerParamPtr->evaluateNonlinearError=true; assert(preintegratedPtr); } Imu_Integration::~Imu_Integration(){ @@ -68,6 +70,27 @@ bool Imu_Integration::reset(gtsam::ISAM2& optimizer,boost::shared_ptraddPrior(B(imu_factor_id-1),*imu_biasPtr,optimizer.marginalCovariance(B(imu_factor_id-1))); return true; } +bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr& new_frame){ + gtsam::Values result = optimizer.optimize(); + // Overwrite the beginning of the preintegration for the next step. + statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); + imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); + preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr); + ++imu_factor_id; + syn=false; + gtsam::Marginals marginals(*graphPtr,result); + new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); + new_frame->Cov_=marginals.marginalCovariance(P(imu_factor_id-1)); + graphPtr->resize(0); + valuesPtr->clear(); + valuesPtr->insert(P(imu_factor_id-1),statePtr->pose()); + valuesPtr->insert(V(imu_factor_id-1),statePtr->v()); + valuesPtr->insert(B(imu_factor_id-1),*imu_biasPtr); + graphPtr->addPrior(P(imu_factor_id-1),statePtr->pose(),marginals.marginalCovariance(P(imu_factor_id-1))); + graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),marginals.marginalCovariance(V(imu_factor_id-1))); + graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,marginals.marginalCovariance(B(imu_factor_id-1))); + return true; +} bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size_t& num_obs,const double reproj_thresh){ usleep(5000); syn=true; @@ -83,11 +106,8 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size }else{ if(imu_n<3)return false; auto preint_imu_combined =dynamic_cast(*preintegratedPtr); - //gtsam::NavState Estimate_state = preintegratedPtr->predict(*statePtr, *imu_biasPtr); valuesPtr->insert(P(imu_factor_id), gtsam::Pose3(new_frame->T_f_w_.matrix())); - //valuesPtr->insert(P(imu_factor_id), Estimate_state.pose()); valuesPtr->insert(V(imu_factor_id), statePtr->v()); - //valuesPtr->insert(V(imu_factor_id), Estimate_state.v()); valuesPtr->insert(B(imu_factor_id), *imu_biasPtr); gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), preint_imu_combined); @@ -102,14 +122,16 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size ++num_obs; } // Now optimize. - gtsam::ISAM2 optimizer(*optimizerParamPtr); - optimizer.update(*graphPtr, *valuesPtr); + //gtsam::ISAM2 optimizer(*optimizerParamPtr); + //optimizer.update(*graphPtr, *valuesPtr); // Each call to iSAM2 update(*) performs one iteration of the iterative // nonlinear solver. If accuracy is desired at the expense of time, // update(*) can be called additional times to perform multiple optimizer // iterations every step. - optimizer.update(); + //optimizer.update(); // optimizer.print(); + gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr); + reset(optimizer,new_frame); // Remove Measurements with too large reprojection error double reproj_thresh_scaled = reproj_thresh / new_frame->cam_->errorMultiplier2(); @@ -120,7 +142,6 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size Eigen::Vector2d e = (vk::project2d(f->f) - vk::project2d(new_frame->T_f_w_ * f->point->pos_))*1.0 / (1<level); if(e.norm() > reproj_thresh_scaled) { - std::cout<<"Error: "<point = NULL; --num_obs; diff --git a/vio_svo/param/vo_fast.yaml b/vio_svo/param/vo_fast.yaml index 3fa20a3..84e6549 100644 --- a/vio_svo/param/vo_fast.yaml +++ b/vio_svo/param/vo_fast.yaml @@ -1,6 +1,13 @@ svo: - grid_size: 30 - max_n_kfs: 10 - loba_num_iter: 0 - quality_min_fts: 20 - quality_max_drop_fts: 50 \ No newline at end of file + grid_size: 30 #Feature grid size of a cell in [px]. + max_n_kfs: 10 #Limit the number of keyframes in the map. This makes nslam essentially. a Visual Odometry. Set to 0 if unlimited number of keyframes are allowed. Minimum number of keyframes is 3. + loba_num_iter: 0 #Number of iterations in the local bundle adjustment. + quality_min_fts: 10 #If the number of tracked features drops below this threshold. Tracking quality is bad. + quality_max_drop_fts: 60 #If within one frame, this amount of features are dropped. Tracking quality is bad. + ACC_noise: 0.0001 #acc white noise in continuous + GYO_noise: 0.0001 #gyro white noise in continuous + IUC: 0.1 #integration uncertainty continuous + ABC: 0.1 #acc bias in continuous + GBC: 0.1 #gyro bias in continuous + EBP: 0.01 #error in the bias used for preintegration + NRP: 0.0000001 #noise used for projection in preintegration From 33c4e7e8e2c91b074dba0877300dc41daf9b2f35 Mon Sep 17 00:00:00 2001 From: gfuse Date: Tue, 20 Apr 2021 16:31:10 +0200 Subject: [PATCH 182/215] The best possible situation 20.4.2021 --- vio_svo/param/vo_fast.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vio_svo/param/vo_fast.yaml b/vio_svo/param/vo_fast.yaml index 84e6549..e33b18a 100644 --- a/vio_svo/param/vo_fast.yaml +++ b/vio_svo/param/vo_fast.yaml @@ -4,10 +4,10 @@ svo: loba_num_iter: 0 #Number of iterations in the local bundle adjustment. quality_min_fts: 10 #If the number of tracked features drops below this threshold. Tracking quality is bad. quality_max_drop_fts: 60 #If within one frame, this amount of features are dropped. Tracking quality is bad. - ACC_noise: 0.0001 #acc white noise in continuous - GYO_noise: 0.0001 #gyro white noise in continuous + ACC_noise: 0.00001 #acc white noise in continuous + GYO_noise: 0.00001 #gyro white noise in continuous IUC: 0.1 #integration uncertainty continuous ABC: 0.1 #acc bias in continuous GBC: 0.1 #gyro bias in continuous - EBP: 0.01 #error in the bias used for preintegration + EBP: 0.1 #error in the bias used for preintegration NRP: 0.0000001 #noise used for projection in preintegration From 85470c37b6ba0fa0ce9d211cb17dd4b238e67453 Mon Sep 17 00:00:00 2001 From: gfuse Date: Wed, 21 Apr 2021 11:16:56 +0200 Subject: [PATCH 183/215] The best possible situation 21.4.2021 --- svo/src/frame_handler_mono.cpp | 17 ++++++++--------- svo/src/imu_integration.cpp | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/svo/src/frame_handler_mono.cpp b/svo/src/frame_handler_mono.cpp index 780d9c7..799cb8c 100644 --- a/svo/src/frame_handler_mono.cpp +++ b/svo/src/frame_handler_mono.cpp @@ -136,10 +136,9 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() img_align.run(last_frame_, new_frame_); // map reprojection & feature alignment reprojector_.reprojectMap(new_frame_, overlap_kfs_); - std::cerr<<"Reprojection Map:\t nPoints = "<T_f_w_ = last_frame_->T_f_w_; // reset to avoid crazy pose jumps tracking_quality_ = TRACKING_INSUFFICIENT; return RESULT_FAILURE; @@ -148,15 +147,17 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() // pose optimization subject to change for adding IMU size_t sfba_n_edges_final; if(!imu_integPtr_->predict(new_frame_,sfba_n_edges_final,Config::poseOptimThresh())) - return RESULT_FAILURE; + return RESULT_FAILURE; + + std::cerr<<"Reprojected points after opmization: "< 30) + usleep(2000); + if(img_align_n_tracked > Config::qualityMinFts()) { SE3 T_f_w_last = last_frame_->T_f_w_; last_frame_ = ref_keyframe; @@ -237,7 +237,6 @@ FrameHandlerMono::UpdateResult FrameHandlerMono::relocalizeFrame( if(res != RESULT_FAILURE) { stage_ = STAGE_DEFAULT_FRAME; - SVO_INFO_STREAM("Relocalization successful."); } else new_frame_->T_f_w_ = T_f_w_last; // reset to last well localized pose diff --git a/svo/src/imu_integration.cpp b/svo/src/imu_integration.cpp index 2aed670..c2a720f 100644 --- a/svo/src/imu_integration.cpp +++ b/svo/src/imu_integration.cpp @@ -104,7 +104,7 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 1e-4)); graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-2)); }else{ - if(imu_n<3)return false; + if(imu_n<1)return false; auto preint_imu_combined =dynamic_cast(*preintegratedPtr); valuesPtr->insert(P(imu_factor_id), gtsam::Pose3(new_frame->T_f_w_.matrix())); valuesPtr->insert(V(imu_factor_id), statePtr->v()); From fa3b7f1e1a57c442f175f22863fa64c637e6676e Mon Sep 17 00:00:00 2001 From: gfuse Date: Wed, 5 May 2021 11:19:06 +0200 Subject: [PATCH 184/215] init GPU --- .../Forster2014ICRA.pdf | Bin LICENCE => CPU_version/LICENCE | 0 README.md => CPU_version/README.md | 5 +- .../src/rqt_svo => CPU_version}/__init__.py | 0 {svo => CPU_version/svo}/.idea/.gitignore | 0 {svo => CPU_version/svo}/.idea/misc.xml | 0 {svo => CPU_version/svo}/.idea/modules.xml | 0 {svo => CPU_version/svo}/.idea/svo.iml | 0 {svo => CPU_version/svo}/.idea/vcs.xml | 0 {svo => CPU_version/svo}/CMakeLists.txt | 30 +- .../svo}/CMakeModules/FindEigen.cmake | 0 .../svo}/CMakeModules/FindG2O.cmake | 0 {svo => CPU_version/svo}/Doxyfile | 0 {svo => CPU_version/svo}/doc/.gitignore | 2 +- .../svo}/include/svo/bundle_adjustment.h | 0 {svo => CPU_version/svo}/include/svo/config.h | 0 .../svo}/include/svo/depth_filter.h | 0 .../svo}/include/svo/feature.h | 0 .../svo}/include/svo/feature_alignment.h | 0 .../svo}/include/svo/feature_detection.h | 0 {svo => CPU_version/svo}/include/svo/frame.h | 0 .../svo}/include/svo/frame_handler_base.h | 0 .../svo}/include/svo/frame_handler_mono.h | 0 {svo => CPU_version/svo}/include/svo/global.h | 0 .../svo}/include/svo/imu_integration.h | 0 .../svo}/include/svo/initialization.h | 0 {svo => CPU_version/svo}/include/svo/map.h | 0 .../svo}/include/svo/matcher.h | 0 {svo => CPU_version/svo}/include/svo/point.h | 0 .../svo}/include/svo/pose_optimizer.h | 0 .../svo}/include/svo/reprojector.h | 0 .../svo}/include/svo/sparse_img_align.h | 0 .../svo}/include/svo/svoVisionFactor.h | 0 {svo => CPU_version/svo}/package.xml | 0 .../svo}/src/bundle_adjustment.cpp | 0 {svo => CPU_version/svo}/src/config.cpp | 0 {svo => CPU_version/svo}/src/depth_filter.cpp | 0 .../svo}/src/feature_alignment.cpp | 0 .../svo}/src/feature_detection.cpp | 0 {svo => CPU_version/svo}/src/frame.cpp | 1 - .../svo}/src/frame_handler_base.cpp | 0 .../svo}/src/frame_handler_mono.cpp | 0 .../svo}/src/imu_integration.cpp | 0 .../svo}/src/initialization.cpp | 0 {svo => CPU_version/svo}/src/map.cpp | 0 {svo => CPU_version/svo}/src/matcher.cpp | 0 {svo => CPU_version/svo}/src/point.cpp | 0 .../svo}/src/pose_optimizer.cpp | 0 {svo => CPU_version/svo}/src/reprojector.cpp | 0 .../svo}/src/sparse_img_align.cpp | 0 {svo => CPU_version/svo}/test/README.md | 0 {svo => CPU_version/svo}/test/benchmark.csv | 0 {svo => CPU_version/svo}/test/data/.gitignore | 2 +- .../svo}/test/results/.gitignore | 2 +- .../svo}/test/test_depth_filter.cpp | 0 .../svo}/test/test_feature_alignment.cpp | 0 .../svo}/test/test_feature_detection.cpp | 0 .../svo}/test/test_matcher.cpp | 0 .../svo}/test/test_pipeline.cpp | 0 .../svo}/test/test_pose_optimizer.cpp | 0 .../svo}/test/test_sparse_img_align.cpp | 0 {svo => CPU_version/svo}/test/test_utils.h | 0 .../svo_analysis}/.gitignore | 0 .../svo_analysis}/CMakeLists.txt | 0 .../svo_analysis}/README.md | 0 .../svo_analysis/__init__.py | 0 .../svo_analysis}/comparisons/speed.yaml | 0 .../svo_analysis}/comparisons/textures.yaml | 0 .../svo_analysis}/experiments/.gitignore | 0 .../svo_analysis}/package.xml | 0 .../svo_analysis}/results/.gitignore | 2 +- CPU_version/svo_analysis/scripts/__init__.py | 0 .../svo_analysis}/scripts/benchmark.py | 0 .../svo_analysis}/scripts/compare_results.py | 0 .../svo_analysis}/scripts/comparison.py | 0 .../svo_analysis}/scripts/evaluate.py | 0 .../svo_analysis}/setup.py | 0 CPU_version/svo_analysis/src/__init__.py | 0 .../svo_analysis/src/svo_analysis/__init__.py | 0 .../src/svo_analysis/analyse_dataset.py | 0 .../src/svo_analysis/analyse_depth.py | 0 .../src/svo_analysis/analyse_logs.py | 0 .../src/svo_analysis/analyse_timing.py | 0 .../src/svo_analysis/analyse_trajectory.py | 0 .../svo_analysis/filter_groundtruth_smooth.py | 0 .../src/svo_analysis/hand_eye_calib.py | 0 .../tum_benchmark_tools/__init__.py | 0 .../tum_benchmark_tools/associate.py | 0 .../tum_benchmark_tools/evaluate_ate.py | 5 +- .../tum_benchmark_tools/evaluate_rpe.py | 0 .../svo_msgs}/.idea/.gitignore | 0 .../svo_msgs}/.idea/misc.xml | 0 .../svo_msgs}/.idea/modules.xml | 0 .../svo_msgs}/.idea/svo_msgs.iml | 0 .../svo_msgs}/.idea/vcs.xml | 0 .../svo_msgs}/CMakeLists.txt | 2 +- .../svo_msgs}/msg/DenseInput.msg | 0 .../svo_msgs}/msg/Feature.msg | 0 .../svo_msgs}/msg/Info.msg | 0 .../svo_msgs}/msg/NbvTrajectory.msg | 0 .../svo_msgs}/package.xml | 0 .../svo_ros}/.idea/modules.xml | 0 .../svo_ros}/.idea/svo_ros.iml | 0 .../svo_ros}/.idea/vcs.xml | 0 .../svo_ros}/.idea/workspace.xml | 0 .../vio_svo}/.idea/.gitignore | 0 .../vio_svo}/.idea/misc.xml | 0 .../vio_svo}/.idea/modules.xml | 0 .../vio_svo}/.idea/svo_ros.iml | 0 .../vio_svo}/.idea/vcs.xml | 0 .../vio_svo}/CMakeLists.txt | 4 +- .../vio_svo}/include/vio_svo/visualizer.h | 6 - .../vio_svo}/launch/Px30.launch | 0 .../vio_svo}/launch/live.launch | 0 .../vio_svo}/launch/test.launch | 0 .../vio_svo}/launch/unity.launch | 0 {vio_svo => CPU_version/vio_svo}/package.xml | 0 .../vio_svo}/param/camera_atan.yaml | 0 .../vio_svo}/param/camera_pinhole.yaml | 0 .../vio_svo}/param/px30.yaml | 0 .../vio_svo}/param/unity.yaml | 0 .../vio_svo}/param/vo_accurate.yaml | 0 .../vio_svo}/param/vo_fast.yaml | 0 .../vio_svo}/rqt.perspective | 0 .../vio_svo}/rviz_config.rviz | 0 .../vio_svo}/src/visualizer.cpp | 1 - .../vio_svo}/src/vo_node.cpp | 24 +- rqt_svo/CMakeLists.txt | 22 -- rqt_svo/README.md | 10 - rqt_svo/package.xml | 25 -- rqt_svo/plugin.xml | 12 - rqt_svo/resource/widget.ui | 101 ------ rqt_svo/scripts/rqt_svo | 10 - rqt_svo/setup.py | 12 - rqt_svo/src/rqt_svo/svo.py | 81 ----- rqt_svo/src/rqt_svo/svo_widget.py | 126 ------- svo/doc/notation.ipe | 312 ------------------ svo/doc/notation.pdf | Bin 50379 -> 0 bytes svo/doc/notation.png | Bin 27376 -> 0 bytes svo_analysis/.gitignore | 1 - svo_analysis/experiments/asl2_acc.yaml | 3 - svo_analysis/experiments/asl2_fast.yaml | 3 - .../experiments/flying_room_1_fast.yaml | 3 - svo_analysis/experiments/synthetic.yaml | 10 - vio_svo/include/vio_svo/dataset_img.h | 62 ---- 145 files changed, 37 insertions(+), 842 deletions(-) rename Forster2014ICRA.pdf => CPU_version/Forster2014ICRA.pdf (100%) mode change 100644 => 100755 rename LICENCE => CPU_version/LICENCE (100%) mode change 100644 => 100755 rename README.md => CPU_version/README.md (88%) mode change 100644 => 100755 rename {rqt_svo/src/rqt_svo => CPU_version}/__init__.py (100%) rename {svo => CPU_version/svo}/.idea/.gitignore (100%) rename {svo => CPU_version/svo}/.idea/misc.xml (100%) rename {svo => CPU_version/svo}/.idea/modules.xml (100%) rename {svo => CPU_version/svo}/.idea/svo.iml (100%) rename {svo => CPU_version/svo}/.idea/vcs.xml (100%) rename {svo => CPU_version/svo}/CMakeLists.txt (91%) rename {svo => CPU_version/svo}/CMakeModules/FindEigen.cmake (100%) rename {svo => CPU_version/svo}/CMakeModules/FindG2O.cmake (100%) rename {svo => CPU_version/svo}/Doxyfile (100%) rename {svo => CPU_version/svo}/doc/.gitignore (50%) rename {svo => CPU_version/svo}/include/svo/bundle_adjustment.h (100%) rename {svo => CPU_version/svo}/include/svo/config.h (100%) rename {svo => CPU_version/svo}/include/svo/depth_filter.h (100%) rename {svo => CPU_version/svo}/include/svo/feature.h (100%) rename {svo => CPU_version/svo}/include/svo/feature_alignment.h (100%) rename {svo => CPU_version/svo}/include/svo/feature_detection.h (100%) rename {svo => CPU_version/svo}/include/svo/frame.h (100%) rename {svo => CPU_version/svo}/include/svo/frame_handler_base.h (100%) rename {svo => CPU_version/svo}/include/svo/frame_handler_mono.h (100%) rename {svo => CPU_version/svo}/include/svo/global.h (100%) rename {svo => CPU_version/svo}/include/svo/imu_integration.h (100%) rename {svo => CPU_version/svo}/include/svo/initialization.h (100%) rename {svo => CPU_version/svo}/include/svo/map.h (100%) rename {svo => CPU_version/svo}/include/svo/matcher.h (100%) rename {svo => CPU_version/svo}/include/svo/point.h (100%) rename {svo => CPU_version/svo}/include/svo/pose_optimizer.h (100%) rename {svo => CPU_version/svo}/include/svo/reprojector.h (100%) rename {svo => CPU_version/svo}/include/svo/sparse_img_align.h (100%) rename {svo => CPU_version/svo}/include/svo/svoVisionFactor.h (100%) rename {svo => CPU_version/svo}/package.xml (100%) rename {svo => CPU_version/svo}/src/bundle_adjustment.cpp (100%) rename {svo => CPU_version/svo}/src/config.cpp (100%) rename {svo => CPU_version/svo}/src/depth_filter.cpp (100%) rename {svo => CPU_version/svo}/src/feature_alignment.cpp (100%) rename {svo => CPU_version/svo}/src/feature_detection.cpp (100%) rename {svo => CPU_version/svo}/src/frame.cpp (99%) rename {svo => CPU_version/svo}/src/frame_handler_base.cpp (100%) rename {svo => CPU_version/svo}/src/frame_handler_mono.cpp (100%) rename {svo => CPU_version/svo}/src/imu_integration.cpp (100%) rename {svo => CPU_version/svo}/src/initialization.cpp (100%) rename {svo => CPU_version/svo}/src/map.cpp (100%) rename {svo => CPU_version/svo}/src/matcher.cpp (100%) rename {svo => CPU_version/svo}/src/point.cpp (100%) rename {svo => CPU_version/svo}/src/pose_optimizer.cpp (100%) rename {svo => CPU_version/svo}/src/reprojector.cpp (100%) rename {svo => CPU_version/svo}/src/sparse_img_align.cpp (100%) rename {svo => CPU_version/svo}/test/README.md (100%) rename {svo => CPU_version/svo}/test/benchmark.csv (100%) rename {svo => CPU_version/svo}/test/data/.gitignore (50%) rename {svo => CPU_version/svo}/test/results/.gitignore (50%) rename {svo => CPU_version/svo}/test/test_depth_filter.cpp (100%) rename {svo => CPU_version/svo}/test/test_feature_alignment.cpp (100%) rename {svo => CPU_version/svo}/test/test_feature_detection.cpp (100%) rename {svo => CPU_version/svo}/test/test_matcher.cpp (100%) rename {svo => CPU_version/svo}/test/test_pipeline.cpp (100%) rename {svo => CPU_version/svo}/test/test_pose_optimizer.cpp (100%) rename {svo => CPU_version/svo}/test/test_sparse_img_align.cpp (100%) rename {svo => CPU_version/svo}/test/test_utils.h (100%) rename {rqt_svo/src/rqt_svo => CPU_version/svo_analysis}/.gitignore (100%) rename {svo_analysis => CPU_version/svo_analysis}/CMakeLists.txt (100%) rename {svo_analysis => CPU_version/svo_analysis}/README.md (100%) rename {svo_analysis/src => CPU_version}/svo_analysis/__init__.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/comparisons/speed.yaml (100%) rename {svo_analysis => CPU_version/svo_analysis}/comparisons/textures.yaml (100%) rename {svo_analysis => CPU_version/svo_analysis}/experiments/.gitignore (100%) rename {svo_analysis => CPU_version/svo_analysis}/package.xml (100%) rename {svo_analysis => CPU_version/svo_analysis}/results/.gitignore (52%) create mode 100644 CPU_version/svo_analysis/scripts/__init__.py rename {svo_analysis => CPU_version/svo_analysis}/scripts/benchmark.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/scripts/compare_results.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/scripts/comparison.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/scripts/evaluate.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/setup.py (100%) create mode 100644 CPU_version/svo_analysis/src/__init__.py create mode 100644 CPU_version/svo_analysis/src/svo_analysis/__init__.py rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/analyse_dataset.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/analyse_depth.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/analyse_logs.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/analyse_timing.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/analyse_trajectory.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/filter_groundtruth_smooth.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/hand_eye_calib.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/tum_benchmark_tools/__init__.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/tum_benchmark_tools/associate.py (100%) rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py (97%) rename {svo_analysis => CPU_version/svo_analysis}/src/svo_analysis/tum_benchmark_tools/evaluate_rpe.py (100%) rename {svo_msgs => CPU_version/svo_msgs}/.idea/.gitignore (100%) rename {svo_msgs => CPU_version/svo_msgs}/.idea/misc.xml (100%) rename {svo_msgs => CPU_version/svo_msgs}/.idea/modules.xml (100%) rename {svo_msgs => CPU_version/svo_msgs}/.idea/svo_msgs.iml (100%) rename {svo_msgs => CPU_version/svo_msgs}/.idea/vcs.xml (100%) rename {svo_msgs => CPU_version/svo_msgs}/CMakeLists.txt (91%) rename {svo_msgs => CPU_version/svo_msgs}/msg/DenseInput.msg (100%) rename {svo_msgs => CPU_version/svo_msgs}/msg/Feature.msg (100%) rename {svo_msgs => CPU_version/svo_msgs}/msg/Info.msg (100%) rename {svo_msgs => CPU_version/svo_msgs}/msg/NbvTrajectory.msg (100%) rename {svo_msgs => CPU_version/svo_msgs}/package.xml (100%) rename {svo_ros => CPU_version/svo_ros}/.idea/modules.xml (100%) rename {svo_ros => CPU_version/svo_ros}/.idea/svo_ros.iml (100%) rename {svo_ros => CPU_version/svo_ros}/.idea/vcs.xml (100%) rename {svo_ros => CPU_version/svo_ros}/.idea/workspace.xml (100%) rename {vio_svo => CPU_version/vio_svo}/.idea/.gitignore (100%) rename {vio_svo => CPU_version/vio_svo}/.idea/misc.xml (100%) rename {vio_svo => CPU_version/vio_svo}/.idea/modules.xml (100%) rename {vio_svo => CPU_version/vio_svo}/.idea/svo_ros.iml (100%) rename {vio_svo => CPU_version/vio_svo}/.idea/vcs.xml (100%) rename {vio_svo => CPU_version/vio_svo}/CMakeLists.txt (95%) rename {vio_svo => CPU_version/vio_svo}/include/vio_svo/visualizer.h (91%) rename {vio_svo => CPU_version/vio_svo}/launch/Px30.launch (100%) rename {vio_svo => CPU_version/vio_svo}/launch/live.launch (100%) rename {vio_svo => CPU_version/vio_svo}/launch/test.launch (100%) rename {vio_svo => CPU_version/vio_svo}/launch/unity.launch (100%) rename {vio_svo => CPU_version/vio_svo}/package.xml (100%) rename {vio_svo => CPU_version/vio_svo}/param/camera_atan.yaml (100%) rename {vio_svo => CPU_version/vio_svo}/param/camera_pinhole.yaml (100%) rename {vio_svo => CPU_version/vio_svo}/param/px30.yaml (100%) rename {vio_svo => CPU_version/vio_svo}/param/unity.yaml (100%) rename {vio_svo => CPU_version/vio_svo}/param/vo_accurate.yaml (100%) rename {vio_svo => CPU_version/vio_svo}/param/vo_fast.yaml (100%) rename {vio_svo => CPU_version/vio_svo}/rqt.perspective (100%) rename {vio_svo => CPU_version/vio_svo}/rviz_config.rviz (100%) rename {vio_svo => CPU_version/vio_svo}/src/visualizer.cpp (99%) rename {vio_svo => CPU_version/vio_svo}/src/vo_node.cpp (88%) delete mode 100644 rqt_svo/CMakeLists.txt delete mode 100644 rqt_svo/README.md delete mode 100644 rqt_svo/package.xml delete mode 100644 rqt_svo/plugin.xml delete mode 100644 rqt_svo/resource/widget.ui delete mode 100755 rqt_svo/scripts/rqt_svo delete mode 100644 rqt_svo/setup.py delete mode 100644 rqt_svo/src/rqt_svo/svo.py delete mode 100644 rqt_svo/src/rqt_svo/svo_widget.py delete mode 100644 svo/doc/notation.ipe delete mode 100644 svo/doc/notation.pdf delete mode 100644 svo/doc/notation.png delete mode 100644 svo_analysis/.gitignore delete mode 100644 svo_analysis/experiments/asl2_acc.yaml delete mode 100644 svo_analysis/experiments/asl2_fast.yaml delete mode 100644 svo_analysis/experiments/flying_room_1_fast.yaml delete mode 100644 svo_analysis/experiments/synthetic.yaml delete mode 100644 vio_svo/include/vio_svo/dataset_img.h diff --git a/Forster2014ICRA.pdf b/CPU_version/Forster2014ICRA.pdf old mode 100644 new mode 100755 similarity index 100% rename from Forster2014ICRA.pdf rename to CPU_version/Forster2014ICRA.pdf diff --git a/LICENCE b/CPU_version/LICENCE old mode 100644 new mode 100755 similarity index 100% rename from LICENCE rename to CPU_version/LICENCE diff --git a/README.md b/CPU_version/README.md old mode 100644 new mode 100755 similarity index 88% rename from README.md rename to CPU_version/README.md index 1e098a9..1d27172 --- a/README.md +++ b/CPU_version/README.md @@ -1,7 +1,7 @@ SVO === -This code implements a semi-direct monocular visual odometry pipeline. +This code implements a semi-direct monocular visual odometry pipeline which has been integrated with GTSAM to infused IMU as well. Video: http://youtu.be/2YnIMfw6bJY @@ -32,10 +32,11 @@ If you use SVO in an academic context, please cite the following publication: #### Documentation The API is documented here: http://uzh-rpg.github.io/rpg_svo/doc/ +The GTSAM documentation https://gtsam.org/tutorials/ #### Instructions -See the Wiki for more instructions. https://github.com/uzh-rpg/rpg_svo/wiki +See the Wiki for more instructions. https://github.com/uzh-rpg/rpg_svo/wiki and https://gtsam.org/get_started/ #### Contributing diff --git a/rqt_svo/src/rqt_svo/__init__.py b/CPU_version/__init__.py similarity index 100% rename from rqt_svo/src/rqt_svo/__init__.py rename to CPU_version/__init__.py diff --git a/svo/.idea/.gitignore b/CPU_version/svo/.idea/.gitignore similarity index 100% rename from svo/.idea/.gitignore rename to CPU_version/svo/.idea/.gitignore diff --git a/svo/.idea/misc.xml b/CPU_version/svo/.idea/misc.xml similarity index 100% rename from svo/.idea/misc.xml rename to CPU_version/svo/.idea/misc.xml diff --git a/svo/.idea/modules.xml b/CPU_version/svo/.idea/modules.xml similarity index 100% rename from svo/.idea/modules.xml rename to CPU_version/svo/.idea/modules.xml diff --git a/svo/.idea/svo.iml b/CPU_version/svo/.idea/svo.iml similarity index 100% rename from svo/.idea/svo.iml rename to CPU_version/svo/.idea/svo.iml diff --git a/svo/.idea/vcs.xml b/CPU_version/svo/.idea/vcs.xml similarity index 100% rename from svo/.idea/vcs.xml rename to CPU_version/svo/.idea/vcs.xml diff --git a/svo/CMakeLists.txt b/CPU_version/svo/CMakeLists.txt similarity index 91% rename from svo/CMakeLists.txt rename to CPU_version/svo/CMakeLists.txt index ff39094..5ecd775 100644 --- a/svo/CMakeLists.txt +++ b/CPU_version/svo/CMakeLists.txt @@ -71,7 +71,7 @@ ENDIF() # Include dirs INCLUDE_DIRECTORIES( - include + include ${Eigen_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${Sophus_INCLUDE_DIRS} @@ -96,20 +96,20 @@ ENDIF() # Set sourcefiles LIST(APPEND SOURCEFILES - src/frame_handler_mono.cpp - src/frame_handler_base.cpp - src/frame.cpp - src/point.cpp - src/map.cpp - src/pose_optimizer.cpp - src/initialization.cpp - src/matcher.cpp - src/reprojector.cpp - src/feature_alignment.cpp - src/feature_detection.cpp - src/depth_filter.cpp - src/config.cpp - src/sparse_img_align.cpp src/imu_integration.cpp) + src/frame_handler_mono.cpp + src/frame_handler_base.cpp + src/frame.cpp + src/point.cpp + src/map.cpp + src/pose_optimizer.cpp + src/initialization.cpp + src/matcher.cpp + src/reprojector.cpp + src/feature_alignment.cpp + src/feature_detection.cpp + src/depth_filter.cpp + src/config.cpp + src/sparse_img_align.cpp src/imu_integration.cpp) # Add g2o if available IF(HAVE_G2O) diff --git a/svo/CMakeModules/FindEigen.cmake b/CPU_version/svo/CMakeModules/FindEigen.cmake similarity index 100% rename from svo/CMakeModules/FindEigen.cmake rename to CPU_version/svo/CMakeModules/FindEigen.cmake diff --git a/svo/CMakeModules/FindG2O.cmake b/CPU_version/svo/CMakeModules/FindG2O.cmake similarity index 100% rename from svo/CMakeModules/FindG2O.cmake rename to CPU_version/svo/CMakeModules/FindG2O.cmake diff --git a/svo/Doxyfile b/CPU_version/svo/Doxyfile similarity index 100% rename from svo/Doxyfile rename to CPU_version/svo/Doxyfile diff --git a/svo/doc/.gitignore b/CPU_version/svo/doc/.gitignore similarity index 50% rename from svo/doc/.gitignore rename to CPU_version/svo/doc/.gitignore index c96a04f..cf57c3b 100644 --- a/svo/doc/.gitignore +++ b/CPU_version/svo/doc/.gitignore @@ -1,2 +1,2 @@ -* +.gitignore !.gitignore \ No newline at end of file diff --git a/svo/include/svo/bundle_adjustment.h b/CPU_version/svo/include/svo/bundle_adjustment.h similarity index 100% rename from svo/include/svo/bundle_adjustment.h rename to CPU_version/svo/include/svo/bundle_adjustment.h diff --git a/svo/include/svo/config.h b/CPU_version/svo/include/svo/config.h similarity index 100% rename from svo/include/svo/config.h rename to CPU_version/svo/include/svo/config.h diff --git a/svo/include/svo/depth_filter.h b/CPU_version/svo/include/svo/depth_filter.h similarity index 100% rename from svo/include/svo/depth_filter.h rename to CPU_version/svo/include/svo/depth_filter.h diff --git a/svo/include/svo/feature.h b/CPU_version/svo/include/svo/feature.h similarity index 100% rename from svo/include/svo/feature.h rename to CPU_version/svo/include/svo/feature.h diff --git a/svo/include/svo/feature_alignment.h b/CPU_version/svo/include/svo/feature_alignment.h similarity index 100% rename from svo/include/svo/feature_alignment.h rename to CPU_version/svo/include/svo/feature_alignment.h diff --git a/svo/include/svo/feature_detection.h b/CPU_version/svo/include/svo/feature_detection.h similarity index 100% rename from svo/include/svo/feature_detection.h rename to CPU_version/svo/include/svo/feature_detection.h diff --git a/svo/include/svo/frame.h b/CPU_version/svo/include/svo/frame.h similarity index 100% rename from svo/include/svo/frame.h rename to CPU_version/svo/include/svo/frame.h diff --git a/svo/include/svo/frame_handler_base.h b/CPU_version/svo/include/svo/frame_handler_base.h similarity index 100% rename from svo/include/svo/frame_handler_base.h rename to CPU_version/svo/include/svo/frame_handler_base.h diff --git a/svo/include/svo/frame_handler_mono.h b/CPU_version/svo/include/svo/frame_handler_mono.h similarity index 100% rename from svo/include/svo/frame_handler_mono.h rename to CPU_version/svo/include/svo/frame_handler_mono.h diff --git a/svo/include/svo/global.h b/CPU_version/svo/include/svo/global.h similarity index 100% rename from svo/include/svo/global.h rename to CPU_version/svo/include/svo/global.h diff --git a/svo/include/svo/imu_integration.h b/CPU_version/svo/include/svo/imu_integration.h similarity index 100% rename from svo/include/svo/imu_integration.h rename to CPU_version/svo/include/svo/imu_integration.h diff --git a/svo/include/svo/initialization.h b/CPU_version/svo/include/svo/initialization.h similarity index 100% rename from svo/include/svo/initialization.h rename to CPU_version/svo/include/svo/initialization.h diff --git a/svo/include/svo/map.h b/CPU_version/svo/include/svo/map.h similarity index 100% rename from svo/include/svo/map.h rename to CPU_version/svo/include/svo/map.h diff --git a/svo/include/svo/matcher.h b/CPU_version/svo/include/svo/matcher.h similarity index 100% rename from svo/include/svo/matcher.h rename to CPU_version/svo/include/svo/matcher.h diff --git a/svo/include/svo/point.h b/CPU_version/svo/include/svo/point.h similarity index 100% rename from svo/include/svo/point.h rename to CPU_version/svo/include/svo/point.h diff --git a/svo/include/svo/pose_optimizer.h b/CPU_version/svo/include/svo/pose_optimizer.h similarity index 100% rename from svo/include/svo/pose_optimizer.h rename to CPU_version/svo/include/svo/pose_optimizer.h diff --git a/svo/include/svo/reprojector.h b/CPU_version/svo/include/svo/reprojector.h similarity index 100% rename from svo/include/svo/reprojector.h rename to CPU_version/svo/include/svo/reprojector.h diff --git a/svo/include/svo/sparse_img_align.h b/CPU_version/svo/include/svo/sparse_img_align.h similarity index 100% rename from svo/include/svo/sparse_img_align.h rename to CPU_version/svo/include/svo/sparse_img_align.h diff --git a/svo/include/svo/svoVisionFactor.h b/CPU_version/svo/include/svo/svoVisionFactor.h similarity index 100% rename from svo/include/svo/svoVisionFactor.h rename to CPU_version/svo/include/svo/svoVisionFactor.h diff --git a/svo/package.xml b/CPU_version/svo/package.xml similarity index 100% rename from svo/package.xml rename to CPU_version/svo/package.xml diff --git a/svo/src/bundle_adjustment.cpp b/CPU_version/svo/src/bundle_adjustment.cpp similarity index 100% rename from svo/src/bundle_adjustment.cpp rename to CPU_version/svo/src/bundle_adjustment.cpp diff --git a/svo/src/config.cpp b/CPU_version/svo/src/config.cpp similarity index 100% rename from svo/src/config.cpp rename to CPU_version/svo/src/config.cpp diff --git a/svo/src/depth_filter.cpp b/CPU_version/svo/src/depth_filter.cpp similarity index 100% rename from svo/src/depth_filter.cpp rename to CPU_version/svo/src/depth_filter.cpp diff --git a/svo/src/feature_alignment.cpp b/CPU_version/svo/src/feature_alignment.cpp similarity index 100% rename from svo/src/feature_alignment.cpp rename to CPU_version/svo/src/feature_alignment.cpp diff --git a/svo/src/feature_detection.cpp b/CPU_version/svo/src/feature_detection.cpp similarity index 100% rename from svo/src/feature_detection.cpp rename to CPU_version/svo/src/feature_detection.cpp diff --git a/svo/src/frame.cpp b/CPU_version/svo/src/frame.cpp similarity index 99% rename from svo/src/frame.cpp rename to CPU_version/svo/src/frame.cpp index 0779891..44ddab6 100644 --- a/svo/src/frame.cpp +++ b/CPU_version/svo/src/frame.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/svo/src/frame_handler_base.cpp b/CPU_version/svo/src/frame_handler_base.cpp similarity index 100% rename from svo/src/frame_handler_base.cpp rename to CPU_version/svo/src/frame_handler_base.cpp diff --git a/svo/src/frame_handler_mono.cpp b/CPU_version/svo/src/frame_handler_mono.cpp similarity index 100% rename from svo/src/frame_handler_mono.cpp rename to CPU_version/svo/src/frame_handler_mono.cpp diff --git a/svo/src/imu_integration.cpp b/CPU_version/svo/src/imu_integration.cpp similarity index 100% rename from svo/src/imu_integration.cpp rename to CPU_version/svo/src/imu_integration.cpp diff --git a/svo/src/initialization.cpp b/CPU_version/svo/src/initialization.cpp similarity index 100% rename from svo/src/initialization.cpp rename to CPU_version/svo/src/initialization.cpp diff --git a/svo/src/map.cpp b/CPU_version/svo/src/map.cpp similarity index 100% rename from svo/src/map.cpp rename to CPU_version/svo/src/map.cpp diff --git a/svo/src/matcher.cpp b/CPU_version/svo/src/matcher.cpp similarity index 100% rename from svo/src/matcher.cpp rename to CPU_version/svo/src/matcher.cpp diff --git a/svo/src/point.cpp b/CPU_version/svo/src/point.cpp similarity index 100% rename from svo/src/point.cpp rename to CPU_version/svo/src/point.cpp diff --git a/svo/src/pose_optimizer.cpp b/CPU_version/svo/src/pose_optimizer.cpp similarity index 100% rename from svo/src/pose_optimizer.cpp rename to CPU_version/svo/src/pose_optimizer.cpp diff --git a/svo/src/reprojector.cpp b/CPU_version/svo/src/reprojector.cpp similarity index 100% rename from svo/src/reprojector.cpp rename to CPU_version/svo/src/reprojector.cpp diff --git a/svo/src/sparse_img_align.cpp b/CPU_version/svo/src/sparse_img_align.cpp similarity index 100% rename from svo/src/sparse_img_align.cpp rename to CPU_version/svo/src/sparse_img_align.cpp diff --git a/svo/test/README.md b/CPU_version/svo/test/README.md similarity index 100% rename from svo/test/README.md rename to CPU_version/svo/test/README.md diff --git a/svo/test/benchmark.csv b/CPU_version/svo/test/benchmark.csv similarity index 100% rename from svo/test/benchmark.csv rename to CPU_version/svo/test/benchmark.csv diff --git a/svo/test/data/.gitignore b/CPU_version/svo/test/data/.gitignore similarity index 50% rename from svo/test/data/.gitignore rename to CPU_version/svo/test/data/.gitignore index c96a04f..cf57c3b 100644 --- a/svo/test/data/.gitignore +++ b/CPU_version/svo/test/data/.gitignore @@ -1,2 +1,2 @@ -* +.gitignore !.gitignore \ No newline at end of file diff --git a/svo/test/results/.gitignore b/CPU_version/svo/test/results/.gitignore similarity index 50% rename from svo/test/results/.gitignore rename to CPU_version/svo/test/results/.gitignore index c96a04f..cf57c3b 100644 --- a/svo/test/results/.gitignore +++ b/CPU_version/svo/test/results/.gitignore @@ -1,2 +1,2 @@ -* +.gitignore !.gitignore \ No newline at end of file diff --git a/svo/test/test_depth_filter.cpp b/CPU_version/svo/test/test_depth_filter.cpp similarity index 100% rename from svo/test/test_depth_filter.cpp rename to CPU_version/svo/test/test_depth_filter.cpp diff --git a/svo/test/test_feature_alignment.cpp b/CPU_version/svo/test/test_feature_alignment.cpp similarity index 100% rename from svo/test/test_feature_alignment.cpp rename to CPU_version/svo/test/test_feature_alignment.cpp diff --git a/svo/test/test_feature_detection.cpp b/CPU_version/svo/test/test_feature_detection.cpp similarity index 100% rename from svo/test/test_feature_detection.cpp rename to CPU_version/svo/test/test_feature_detection.cpp diff --git a/svo/test/test_matcher.cpp b/CPU_version/svo/test/test_matcher.cpp similarity index 100% rename from svo/test/test_matcher.cpp rename to CPU_version/svo/test/test_matcher.cpp diff --git a/svo/test/test_pipeline.cpp b/CPU_version/svo/test/test_pipeline.cpp similarity index 100% rename from svo/test/test_pipeline.cpp rename to CPU_version/svo/test/test_pipeline.cpp diff --git a/svo/test/test_pose_optimizer.cpp b/CPU_version/svo/test/test_pose_optimizer.cpp similarity index 100% rename from svo/test/test_pose_optimizer.cpp rename to CPU_version/svo/test/test_pose_optimizer.cpp diff --git a/svo/test/test_sparse_img_align.cpp b/CPU_version/svo/test/test_sparse_img_align.cpp similarity index 100% rename from svo/test/test_sparse_img_align.cpp rename to CPU_version/svo/test/test_sparse_img_align.cpp diff --git a/svo/test/test_utils.h b/CPU_version/svo/test/test_utils.h similarity index 100% rename from svo/test/test_utils.h rename to CPU_version/svo/test/test_utils.h diff --git a/rqt_svo/src/rqt_svo/.gitignore b/CPU_version/svo_analysis/.gitignore similarity index 100% rename from rqt_svo/src/rqt_svo/.gitignore rename to CPU_version/svo_analysis/.gitignore diff --git a/svo_analysis/CMakeLists.txt b/CPU_version/svo_analysis/CMakeLists.txt similarity index 100% rename from svo_analysis/CMakeLists.txt rename to CPU_version/svo_analysis/CMakeLists.txt diff --git a/svo_analysis/README.md b/CPU_version/svo_analysis/README.md similarity index 100% rename from svo_analysis/README.md rename to CPU_version/svo_analysis/README.md diff --git a/svo_analysis/src/svo_analysis/__init__.py b/CPU_version/svo_analysis/__init__.py similarity index 100% rename from svo_analysis/src/svo_analysis/__init__.py rename to CPU_version/svo_analysis/__init__.py diff --git a/svo_analysis/comparisons/speed.yaml b/CPU_version/svo_analysis/comparisons/speed.yaml similarity index 100% rename from svo_analysis/comparisons/speed.yaml rename to CPU_version/svo_analysis/comparisons/speed.yaml diff --git a/svo_analysis/comparisons/textures.yaml b/CPU_version/svo_analysis/comparisons/textures.yaml similarity index 100% rename from svo_analysis/comparisons/textures.yaml rename to CPU_version/svo_analysis/comparisons/textures.yaml diff --git a/svo_analysis/experiments/.gitignore b/CPU_version/svo_analysis/experiments/.gitignore similarity index 100% rename from svo_analysis/experiments/.gitignore rename to CPU_version/svo_analysis/experiments/.gitignore diff --git a/svo_analysis/package.xml b/CPU_version/svo_analysis/package.xml similarity index 100% rename from svo_analysis/package.xml rename to CPU_version/svo_analysis/package.xml diff --git a/svo_analysis/results/.gitignore b/CPU_version/svo_analysis/results/.gitignore similarity index 52% rename from svo_analysis/results/.gitignore rename to CPU_version/svo_analysis/results/.gitignore index d6b7ef3..c1aefd2 100644 --- a/svo_analysis/results/.gitignore +++ b/CPU_version/svo_analysis/results/.gitignore @@ -1,2 +1,2 @@ -* +.gitignore !.gitignore diff --git a/CPU_version/svo_analysis/scripts/__init__.py b/CPU_version/svo_analysis/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/svo_analysis/scripts/benchmark.py b/CPU_version/svo_analysis/scripts/benchmark.py similarity index 100% rename from svo_analysis/scripts/benchmark.py rename to CPU_version/svo_analysis/scripts/benchmark.py diff --git a/svo_analysis/scripts/compare_results.py b/CPU_version/svo_analysis/scripts/compare_results.py similarity index 100% rename from svo_analysis/scripts/compare_results.py rename to CPU_version/svo_analysis/scripts/compare_results.py diff --git a/svo_analysis/scripts/comparison.py b/CPU_version/svo_analysis/scripts/comparison.py similarity index 100% rename from svo_analysis/scripts/comparison.py rename to CPU_version/svo_analysis/scripts/comparison.py diff --git a/svo_analysis/scripts/evaluate.py b/CPU_version/svo_analysis/scripts/evaluate.py similarity index 100% rename from svo_analysis/scripts/evaluate.py rename to CPU_version/svo_analysis/scripts/evaluate.py diff --git a/svo_analysis/setup.py b/CPU_version/svo_analysis/setup.py similarity index 100% rename from svo_analysis/setup.py rename to CPU_version/svo_analysis/setup.py diff --git a/CPU_version/svo_analysis/src/__init__.py b/CPU_version/svo_analysis/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/CPU_version/svo_analysis/src/svo_analysis/__init__.py b/CPU_version/svo_analysis/src/svo_analysis/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/svo_analysis/src/svo_analysis/analyse_dataset.py b/CPU_version/svo_analysis/src/svo_analysis/analyse_dataset.py similarity index 100% rename from svo_analysis/src/svo_analysis/analyse_dataset.py rename to CPU_version/svo_analysis/src/svo_analysis/analyse_dataset.py diff --git a/svo_analysis/src/svo_analysis/analyse_depth.py b/CPU_version/svo_analysis/src/svo_analysis/analyse_depth.py similarity index 100% rename from svo_analysis/src/svo_analysis/analyse_depth.py rename to CPU_version/svo_analysis/src/svo_analysis/analyse_depth.py diff --git a/svo_analysis/src/svo_analysis/analyse_logs.py b/CPU_version/svo_analysis/src/svo_analysis/analyse_logs.py similarity index 100% rename from svo_analysis/src/svo_analysis/analyse_logs.py rename to CPU_version/svo_analysis/src/svo_analysis/analyse_logs.py diff --git a/svo_analysis/src/svo_analysis/analyse_timing.py b/CPU_version/svo_analysis/src/svo_analysis/analyse_timing.py similarity index 100% rename from svo_analysis/src/svo_analysis/analyse_timing.py rename to CPU_version/svo_analysis/src/svo_analysis/analyse_timing.py diff --git a/svo_analysis/src/svo_analysis/analyse_trajectory.py b/CPU_version/svo_analysis/src/svo_analysis/analyse_trajectory.py similarity index 100% rename from svo_analysis/src/svo_analysis/analyse_trajectory.py rename to CPU_version/svo_analysis/src/svo_analysis/analyse_trajectory.py diff --git a/svo_analysis/src/svo_analysis/filter_groundtruth_smooth.py b/CPU_version/svo_analysis/src/svo_analysis/filter_groundtruth_smooth.py similarity index 100% rename from svo_analysis/src/svo_analysis/filter_groundtruth_smooth.py rename to CPU_version/svo_analysis/src/svo_analysis/filter_groundtruth_smooth.py diff --git a/svo_analysis/src/svo_analysis/hand_eye_calib.py b/CPU_version/svo_analysis/src/svo_analysis/hand_eye_calib.py similarity index 100% rename from svo_analysis/src/svo_analysis/hand_eye_calib.py rename to CPU_version/svo_analysis/src/svo_analysis/hand_eye_calib.py diff --git a/svo_analysis/src/svo_analysis/tum_benchmark_tools/__init__.py b/CPU_version/svo_analysis/src/svo_analysis/tum_benchmark_tools/__init__.py similarity index 100% rename from svo_analysis/src/svo_analysis/tum_benchmark_tools/__init__.py rename to CPU_version/svo_analysis/src/svo_analysis/tum_benchmark_tools/__init__.py diff --git a/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py b/CPU_version/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py similarity index 100% rename from svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py rename to CPU_version/svo_analysis/src/svo_analysis/tum_benchmark_tools/associate.py diff --git a/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py b/CPU_version/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py similarity index 97% rename from svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py rename to CPU_version/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py index 683b598..a8b2ca9 100755 --- a/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py +++ b/CPU_version/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_ate.py @@ -129,7 +129,7 @@ if __name__=="__main__": first_list = associate.read_file_list(args.first_file) second_list = associate.read_file_list(args.second_file) - matches = associate.associate(first_list, second_list,float(args.offset),float(args.max_difference)) + matches = associate.associate(first_list, second_list, float(args.offset), float(args.max_difference)) if len(matches)<2: sys.exit("Couldn't find matching timestamp pairs between groundtruth and estimated trajectory! Did you choose the correct sequence?") @@ -175,8 +175,7 @@ if __name__=="__main__": import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt - import matplotlib.pylab as pylab - from matplotlib.patches import Ellipse + fig = plt.figure() ax = fig.add_subplot(111) plot_traj(ax,first_stamps,first_xyz_full.transpose().A,'-',"black","ground truth") diff --git a/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_rpe.py b/CPU_version/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_rpe.py similarity index 100% rename from svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_rpe.py rename to CPU_version/svo_analysis/src/svo_analysis/tum_benchmark_tools/evaluate_rpe.py diff --git a/svo_msgs/.idea/.gitignore b/CPU_version/svo_msgs/.idea/.gitignore similarity index 100% rename from svo_msgs/.idea/.gitignore rename to CPU_version/svo_msgs/.idea/.gitignore diff --git a/svo_msgs/.idea/misc.xml b/CPU_version/svo_msgs/.idea/misc.xml similarity index 100% rename from svo_msgs/.idea/misc.xml rename to CPU_version/svo_msgs/.idea/misc.xml diff --git a/svo_msgs/.idea/modules.xml b/CPU_version/svo_msgs/.idea/modules.xml similarity index 100% rename from svo_msgs/.idea/modules.xml rename to CPU_version/svo_msgs/.idea/modules.xml diff --git a/svo_msgs/.idea/svo_msgs.iml b/CPU_version/svo_msgs/.idea/svo_msgs.iml similarity index 100% rename from svo_msgs/.idea/svo_msgs.iml rename to CPU_version/svo_msgs/.idea/svo_msgs.iml diff --git a/svo_msgs/.idea/vcs.xml b/CPU_version/svo_msgs/.idea/vcs.xml similarity index 100% rename from svo_msgs/.idea/vcs.xml rename to CPU_version/svo_msgs/.idea/vcs.xml diff --git a/svo_msgs/CMakeLists.txt b/CPU_version/svo_msgs/CMakeLists.txt similarity index 91% rename from svo_msgs/CMakeLists.txt rename to CPU_version/svo_msgs/CMakeLists.txt index 23d4e3b..06bb680 100644 --- a/svo_msgs/CMakeLists.txt +++ b/CPU_version/svo_msgs/CMakeLists.txt @@ -9,7 +9,7 @@ find_package(catkin REQUIRED COMPONENTS ) # search for all msg files -FILE(GLOB messages_to_build RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/msg" +FILE(GLOB messages_to_build RELATIVE "msg" "${CMAKE_CURRENT_SOURCE_DIR}/msg/*.msg") # notify catkin to look at the previously found msg files diff --git a/svo_msgs/msg/DenseInput.msg b/CPU_version/svo_msgs/msg/DenseInput.msg similarity index 100% rename from svo_msgs/msg/DenseInput.msg rename to CPU_version/svo_msgs/msg/DenseInput.msg diff --git a/svo_msgs/msg/Feature.msg b/CPU_version/svo_msgs/msg/Feature.msg similarity index 100% rename from svo_msgs/msg/Feature.msg rename to CPU_version/svo_msgs/msg/Feature.msg diff --git a/svo_msgs/msg/Info.msg b/CPU_version/svo_msgs/msg/Info.msg similarity index 100% rename from svo_msgs/msg/Info.msg rename to CPU_version/svo_msgs/msg/Info.msg diff --git a/svo_msgs/msg/NbvTrajectory.msg b/CPU_version/svo_msgs/msg/NbvTrajectory.msg similarity index 100% rename from svo_msgs/msg/NbvTrajectory.msg rename to CPU_version/svo_msgs/msg/NbvTrajectory.msg diff --git a/svo_msgs/package.xml b/CPU_version/svo_msgs/package.xml similarity index 100% rename from svo_msgs/package.xml rename to CPU_version/svo_msgs/package.xml diff --git a/svo_ros/.idea/modules.xml b/CPU_version/svo_ros/.idea/modules.xml similarity index 100% rename from svo_ros/.idea/modules.xml rename to CPU_version/svo_ros/.idea/modules.xml diff --git a/svo_ros/.idea/svo_ros.iml b/CPU_version/svo_ros/.idea/svo_ros.iml similarity index 100% rename from svo_ros/.idea/svo_ros.iml rename to CPU_version/svo_ros/.idea/svo_ros.iml diff --git a/svo_ros/.idea/vcs.xml b/CPU_version/svo_ros/.idea/vcs.xml similarity index 100% rename from svo_ros/.idea/vcs.xml rename to CPU_version/svo_ros/.idea/vcs.xml diff --git a/svo_ros/.idea/workspace.xml b/CPU_version/svo_ros/.idea/workspace.xml similarity index 100% rename from svo_ros/.idea/workspace.xml rename to CPU_version/svo_ros/.idea/workspace.xml diff --git a/vio_svo/.idea/.gitignore b/CPU_version/vio_svo/.idea/.gitignore similarity index 100% rename from vio_svo/.idea/.gitignore rename to CPU_version/vio_svo/.idea/.gitignore diff --git a/vio_svo/.idea/misc.xml b/CPU_version/vio_svo/.idea/misc.xml similarity index 100% rename from vio_svo/.idea/misc.xml rename to CPU_version/vio_svo/.idea/misc.xml diff --git a/vio_svo/.idea/modules.xml b/CPU_version/vio_svo/.idea/modules.xml similarity index 100% rename from vio_svo/.idea/modules.xml rename to CPU_version/vio_svo/.idea/modules.xml diff --git a/vio_svo/.idea/svo_ros.iml b/CPU_version/vio_svo/.idea/svo_ros.iml similarity index 100% rename from vio_svo/.idea/svo_ros.iml rename to CPU_version/vio_svo/.idea/svo_ros.iml diff --git a/vio_svo/.idea/vcs.xml b/CPU_version/vio_svo/.idea/vcs.xml similarity index 100% rename from vio_svo/.idea/vcs.xml rename to CPU_version/vio_svo/.idea/vcs.xml diff --git a/vio_svo/CMakeLists.txt b/CPU_version/vio_svo/CMakeLists.txt similarity index 95% rename from vio_svo/CMakeLists.txt rename to CPU_version/vio_svo/CMakeLists.txt index bb8fdc9..b57bcfc 100644 --- a/vio_svo/CMakeLists.txt +++ b/CPU_version/vio_svo/CMakeLists.txt @@ -54,7 +54,7 @@ catkin_package( # Include dirs INCLUDE_DIRECTORIES( - include + include ${Eigen_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${Sophus_INCLUDE_DIRS} @@ -77,5 +77,3 @@ TARGET_LINK_LIBRARIES(svo_visualizer ${LINK_LIBS} gtsam) # Create Executables ADD_EXECUTABLE(vo src/vo_node.cpp) TARGET_LINK_LIBRARIES(vo svo_visualizer ${LINK_LIBS}) -#ADD_EXECUTABLE(benchmark src/benchmark_node.cpp) -#TARGET_LINK_LIBRARIES(benchmark svo_visualizer) diff --git a/vio_svo/include/vio_svo/visualizer.h b/CPU_version/vio_svo/include/vio_svo/visualizer.h similarity index 91% rename from vio_svo/include/vio_svo/visualizer.h rename to CPU_version/vio_svo/include/vio_svo/visualizer.h index 4a09a8d..1b730ee 100644 --- a/vio_svo/include/vio_svo/visualizer.h +++ b/CPU_version/vio_svo/include/vio_svo/visualizer.h @@ -22,16 +22,10 @@ #include #include #include -#include -#include -#include -#include -#include #include #include #include #include -#include namespace svo { diff --git a/vio_svo/launch/Px30.launch b/CPU_version/vio_svo/launch/Px30.launch similarity index 100% rename from vio_svo/launch/Px30.launch rename to CPU_version/vio_svo/launch/Px30.launch diff --git a/vio_svo/launch/live.launch b/CPU_version/vio_svo/launch/live.launch similarity index 100% rename from vio_svo/launch/live.launch rename to CPU_version/vio_svo/launch/live.launch diff --git a/vio_svo/launch/test.launch b/CPU_version/vio_svo/launch/test.launch similarity index 100% rename from vio_svo/launch/test.launch rename to CPU_version/vio_svo/launch/test.launch diff --git a/vio_svo/launch/unity.launch b/CPU_version/vio_svo/launch/unity.launch similarity index 100% rename from vio_svo/launch/unity.launch rename to CPU_version/vio_svo/launch/unity.launch diff --git a/vio_svo/package.xml b/CPU_version/vio_svo/package.xml similarity index 100% rename from vio_svo/package.xml rename to CPU_version/vio_svo/package.xml diff --git a/vio_svo/param/camera_atan.yaml b/CPU_version/vio_svo/param/camera_atan.yaml similarity index 100% rename from vio_svo/param/camera_atan.yaml rename to CPU_version/vio_svo/param/camera_atan.yaml diff --git a/vio_svo/param/camera_pinhole.yaml b/CPU_version/vio_svo/param/camera_pinhole.yaml similarity index 100% rename from vio_svo/param/camera_pinhole.yaml rename to CPU_version/vio_svo/param/camera_pinhole.yaml diff --git a/vio_svo/param/px30.yaml b/CPU_version/vio_svo/param/px30.yaml similarity index 100% rename from vio_svo/param/px30.yaml rename to CPU_version/vio_svo/param/px30.yaml diff --git a/vio_svo/param/unity.yaml b/CPU_version/vio_svo/param/unity.yaml similarity index 100% rename from vio_svo/param/unity.yaml rename to CPU_version/vio_svo/param/unity.yaml diff --git a/vio_svo/param/vo_accurate.yaml b/CPU_version/vio_svo/param/vo_accurate.yaml similarity index 100% rename from vio_svo/param/vo_accurate.yaml rename to CPU_version/vio_svo/param/vo_accurate.yaml diff --git a/vio_svo/param/vo_fast.yaml b/CPU_version/vio_svo/param/vo_fast.yaml similarity index 100% rename from vio_svo/param/vo_fast.yaml rename to CPU_version/vio_svo/param/vo_fast.yaml diff --git a/vio_svo/rqt.perspective b/CPU_version/vio_svo/rqt.perspective similarity index 100% rename from vio_svo/rqt.perspective rename to CPU_version/vio_svo/rqt.perspective diff --git a/vio_svo/rviz_config.rviz b/CPU_version/vio_svo/rviz_config.rviz similarity index 100% rename from vio_svo/rviz_config.rviz rename to CPU_version/vio_svo/rviz_config.rviz diff --git a/vio_svo/src/visualizer.cpp b/CPU_version/vio_svo/src/visualizer.cpp similarity index 99% rename from vio_svo/src/visualizer.cpp rename to CPU_version/vio_svo/src/visualizer.cpp index 511c167..4d3a631 100644 --- a/vio_svo/src/visualizer.cpp +++ b/CPU_version/vio_svo/src/visualizer.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/vio_svo/src/vo_node.cpp b/CPU_version/vio_svo/src/vo_node.cpp similarity index 88% rename from vio_svo/src/vo_node.cpp rename to CPU_version/vio_svo/src/vo_node.cpp index 2f98da0..9779f3e 100644 --- a/vio_svo/src/vo_node.cpp +++ b/CPU_version/vio_svo/src/vo_node.cpp @@ -16,21 +16,16 @@ #include #include #include -#include #include #include #include #include -#include -#include -#include #include #include #include #include #include #include -#include #include @@ -52,6 +47,8 @@ public: void imgCb(const sensor_msgs::ImageConstPtr& msg); void imuCb(const sensor_msgs::ImuPtr& imu); void imu(); +private: + double* imu_; }; VoNode::VoNode() : @@ -61,6 +58,7 @@ VoNode::VoNode() : quit_(false) { // Create Camera + imu_=(double *)calloc(static_cast(6), sizeof(double)); if(!vk::camera_loader::loadFromRosNs("vio", cam_)) throw std::runtime_error("Camera model not correctly specified."); // Get initial position and orientation @@ -75,7 +73,7 @@ VoNode::VoNode() : vo_ = new svo::FrameHandlerMono(cam_,visualizer_.T_world_from_vision_); vo_->start(); imu_th=new boost::thread(&VoNode::imu,this); - logtime = fopen((std::string(getenv("HOME"))+"/Project/time.txt").c_str(), "w+"); + logtime = fopen((std::string(getenv("HOME"))+"/time.txt").c_str(), "w+"); } @@ -109,17 +107,17 @@ void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) } void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { double imu_in[6]; - imu_in[0] = imu->linear_acceleration.x; - imu_in[1] = imu->linear_acceleration.y; - imu_in[2] = imu->linear_acceleration.z; - imu_in[3] = imu->angular_velocity.x; - imu_in[4] = imu->angular_velocity.y; - imu_in[5] = imu->angular_velocity.z; + imu_in[0] = 0.1*imu_[0]+0.9*imu->linear_acceleration.x; + imu_in[1] = 0.1*imu_[1]+0.9*imu->linear_acceleration.y; + imu_in[2] = 0.1*imu_[2]+0.9*imu->linear_acceleration.z; + imu_in[3] = 0.1*imu_[3]+0.9*imu->angular_velocity.x; + imu_in[4] = 0.1*imu_[4]+0.9*imu->angular_velocity.y; + imu_in[5] = 0.1*imu_[5]+0.9*imu->angular_velocity.z; + memcpy(imu_, imu_in, static_cast(6*sizeof(double))); vo_->imu_integPtr_->update(imu_in); } void VoNode::imu(){ ros::NodeHandle nh; - std::cout << "create vo_node" << std::endl; // subscribe to cam msgs image_transport::ImageTransport it(nh); image_transport::Subscriber it_sub = it.subscribe(vk::getParam("vio/cam_topic", "camera/image_raw"), 1, &svo::VoNode::imgCb, this); diff --git a/rqt_svo/CMakeLists.txt b/rqt_svo/CMakeLists.txt deleted file mode 100644 index b199493..0000000 --- a/rqt_svo/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -cmake_minimum_required(VERSION 2.8.3) -project(rqt_svo) - -find_package(catkin REQUIRED COMPONENTS - rospy - rqt_gui - rqt_gui_py -) -catkin_package() -catkin_python_setup() - -install(FILES plugin.xml - DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -) - -install(DIRECTORY resource - DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} -) - -install(PROGRAMS scripts/rqt_svo - DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} -) \ No newline at end of file diff --git a/rqt_svo/README.md b/rqt_svo/README.md deleted file mode 100644 index 574a497..0000000 --- a/rqt_svo/README.md +++ /dev/null @@ -1,10 +0,0 @@ -run with: - - rosrun rqt_svo rqt_svo - -or start `rqt` and display the widget. - -If it does not work, try this: - - rm ~/.config/ros.org/rqt_gui.ini - rqt \ No newline at end of file diff --git a/rqt_svo/package.xml b/rqt_svo/package.xml deleted file mode 100644 index 862112a..0000000 --- a/rqt_svo/package.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - rqt_svo - 0.0.0 - The rqt_svo package - - cforster - - - TODO - - catkin - rospy - rqt_gui - rqt_gui_py - rospy - rqt_gui - rqt_gui_py - - - - - - - \ No newline at end of file diff --git a/rqt_svo/plugin.xml b/rqt_svo/plugin.xml deleted file mode 100644 index fd6b605..0000000 --- a/rqt_svo/plugin.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - Plugin for SVO - Semi-Direct Visual Odometry - - - - system-help - Great user interface to provide real value. - - - \ No newline at end of file diff --git a/rqt_svo/resource/widget.ui b/rqt_svo/resource/widget.ui deleted file mode 100644 index 7808e37..0000000 --- a/rqt_svo/resource/widget.ui +++ /dev/null @@ -1,101 +0,0 @@ - - - SvoWidget - - - - 0 - 0 - 467 - 140 - - - - SVO - - - - - - - - SVO Namespace: - - - - - - - Topic to send Twist message to - - - - - - - - - - - - - - Current angular velocity - - - Status Message - - - - - - - - - - - 100 - - - 100 - - - %p% - - - - - - - - - - - Start - - - - - - - Reset velocities to zero - - - Reset - - - - - - - Quit - - - - - - - - - - diff --git a/rqt_svo/scripts/rqt_svo b/rqt_svo/scripts/rqt_svo deleted file mode 100755 index 753dcb5..0000000 --- a/rqt_svo/scripts/rqt_svo +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python - -import sys - -from rqt_svo.svo import Svo -from rqt_gui.main import Main - -plugin = 'rqt_svo' -main = Main(filename=plugin) -sys.exit(main.main(sys.argv, standalone=plugin)) # , plugin_argument_provider=Svo.add_arguments \ No newline at end of file diff --git a/rqt_svo/setup.py b/rqt_svo/setup.py deleted file mode 100644 index e07a5df..0000000 --- a/rqt_svo/setup.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -from distutils.core import setup -from catkin_pkg.python_setup import generate_distutils_setup - -d = generate_distutils_setup( - packages=['rqt_svo'], - package_dir={'': 'src'}, - scripts=['scripts/rqt_svo'] -) - -setup(**d) \ No newline at end of file diff --git a/rqt_svo/src/rqt_svo/svo.py b/rqt_svo/src/rqt_svo/svo.py deleted file mode 100644 index bbbb8c6..0000000 --- a/rqt_svo/src/rqt_svo/svo.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python -import os -import rospy -import argparse -from qt_gui.plugin import Plugin -from .svo_widget import SvoWidget - -class Svo(Plugin): - """ - Subclass of Plugin to display SVO status - """ - def __init__(self, context): - - # Init Plugin - super(Svo, self).__init__(context) - self.setObjectName('SvoPlugin') - - # Load arguments - # TODO load topic name from args - args = self._parse_args(context.argv()) - - # Create QWidget - self._widget = SvoWidget() - - # Show _widget.windowTitle on left-top of each plugin (when - # it's set in _widget). This is useful when you open multiple - # plugins at once. Also if you open multiple instances of your - # plugin at once, these lines add number to make it easy to - # tell from pane to pane. - if context.serial_number() > 1: - self._widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number())) - - # Add widget to the user interface - context.add_widget(self._widget) - - def _parse_args(self, argv): - parser = argparse.ArgumentParser(prog='rqt_svo', add_help=False) - group = parser.add_argument_group('Options for rqt_svo plugin') - group.add_argument('topic', type=argparse.FileType('r'), nargs='*', default=[], help='Svo Info Topic to display') - return parser.parse_args(argv) - - def save_settings(self, plugin_settings, instance_settings): - # TODO save intrinsic configuration, usually using: - # instance_settings.set_value(k, v) - print('Saving namespace') - namespace = self._widget._svo_namespace - instance_settings.set_value('namespace', namespace) - pass -# - def restore_settings(self, plugin_settings, instance_settings): - # TODO restore intrinsic configuration, usually using: - # v = instance_settings.value(k) - namespace = instance_settings.value('namespace', 'default') - self._widget.topic_line_edit.setText(namespace) - pass - -# def shutdown_plugin(self): -# # self._unregister_publisher() -# pass -# -# def save_settings(self, plugin_settings, instance_settings): -# # TODO save intrinsic configuration, usually using: -# # instance_settings.set_value(k, v) -# pass -# -# def restore_settings(self, plugin_settings, instance_settings): -# # TODO restore intrinsic configuration, usually using: -# # v = instance_settings.value(k) -# pass - - -# def _unregister_publisher(self): -# if self._publisher is not None: -# self._publisher.unregister() -# self._publisher = None - - - #def trigger_configuration(self): - # Comment in to signal that the plugin has a way to configure - # This will enable a setting button (gear icon) in each dock widget title bar - # Usually used to open a modal configuration dialog diff --git a/rqt_svo/src/rqt_svo/svo_widget.py b/rqt_svo/src/rqt_svo/svo_widget.py deleted file mode 100644 index 57b88f3..0000000 --- a/rqt_svo/src/rqt_svo/svo_widget.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env python -import os -import rospy -import rospkg -import numpy as np -from python_qt_binding import loadUi -from python_qt_binding.QtGui import QWidget -from python_qt_binding.QtCore import QTimer, Slot -from svo_msgs.msg import Info -from std_msgs.msg import String - -class SvoWidget(QWidget): - _last_info_msg = Info() - _publisher = None - _subscriber = None - _num_received_msgs = 0 - _svo_namespace = None - def __init__(self, svo_namespace='svo'): - - # Init QWidget - super(SvoWidget, self).__init__() - self.setObjectName('SvoWidget') - - # load UI - ui_file = os.path.join(rospkg.RosPack().get_path('rqt_svo'), 'resource', 'widget.ui') - loadUi(ui_file, self) - - # init and start update timer for data, the timer calls the function update_info all 40ms - self._update_info_timer = QTimer(self) - self._update_info_timer.timeout.connect(self.update_info) - self._update_info_timer.start(40) - - # set the functions that are called when a button is pressed - self.button_start.pressed.connect(self.on_start_button_pressed) - self.button_reset.pressed.connect(self.on_reset_button_pressed) - self.button_quit.pressed.connect(self.on_quit_button_pressed) - - # set callback for changed topic - self.topic_line_edit.setText(svo_namespace) - self.register(svo_namespace) - self.topic_line_edit.textChanged.connect(self._on_topic_changed) - - # TODO: set a timer when the last message was received and give a warning if it is too long ago! - - @Slot(str) - def _on_topic_changed(self, topic): - self._svo_namespace = str(topic) - self.unregister() - self.register(self._svo_namespace) - - def register(self, svo_namespace): - # Load parameters - max_num_features = rospy.get_param(svo_namespace+'/max_fts', 120) - - # Feature bar - self.num_tracked_bar.setMaximum(max_num_features) - print('set maximum number of features to '+str(max_num_features)) - - # Subscribe to ROS Info topic and register callback - self._subscriber = rospy.Subscriber(svo_namespace+'/info', Info, self.info_cb) - - # Initialize Publisher - self._publisher = rospy.Publisher(svo_namespace+'/remote_key', String) - - def unregister(self): - if self._publisher is not None: - self._publisher.unregister() - self._publisher = None - - if self._subscriber is not None: - self._subscriber.unregister() - self._subscriber = None - - - def info_cb(self, msg): - self._last_info_msg = msg - self._num_received_msgs += 1 - - def update_info(self): - info_text = 'Not Connected' - if self._num_received_msgs > 0: - fps = 0 - if self._last_info_msg.processing_time > 0: - fps = 1.0/self._last_info_msg.processing_time - info_text = 'fps = %.2f' % fps - info_text += '\t #Features = ' + str(self._last_info_msg.num_matches) - info_text += '\t' - if self._last_info_msg.stage == 0: - info_text += '\t PAUSED' - elif self._last_info_msg.stage == 1: - info_text += '\t FIRST_FRAME' - elif self._last_info_msg.stage == 2: - info_text += '\t SECOND_FRAME' - elif self._last_info_msg.stage == 3: - info_text += '\t RUNNING' - if self._last_info_msg.tracking_quality == 0: - info_text += '\t CRITICAL' - elif self._last_info_msg.tracking_quality == 1: - info_text += '\t BAD TRACKING' - elif self._last_info_msg.tracking_quality == 2: - info_text += '\t GOOD TRACKING' - - # set info text - self.svo_info_label.setText(info_text) - - # set progress bar - self.num_tracked_bar.setValue(self._last_info_msg.num_matches) - - def on_start_button_pressed(self): - print('START SLAM') - self.send_command('s') - - def on_reset_button_pressed(self): - print('RESET SLAM') - self.send_command('r') - - def on_quit_button_pressed(self): - print('QUIT SLAM') - self.send_command('q') - - def send_command(self, cmd): - if self._publisher is None: - return - self._publisher.publish(String(cmd)) - - diff --git a/svo/doc/notation.ipe b/svo/doc/notation.ipe deleted file mode 100644 index f8c1efe..0000000 --- a/svo/doc/notation.ipe +++ /dev/null @@ -1,312 +0,0 @@ - - - - - - - -0 0 m --1 0.333 l --1 -0.333 l -h - - - - -0 0 m --1 0.333 l --1 -0.333 l -h - - - - -0.6 0 0 0.6 0 0 e -0.4 0 0 0.4 0 0 e - - - - -0.6 0 0 0.6 0 0 e - - - - - -0.6 0 0 0.6 0 0 e -0.4 0 0 0.4 0 0 e - - -0.4 0 0 0.4 0 0 e - - - - - --0.6 -0.6 m -0.6 -0.6 l -0.6 0.6 l --0.6 0.6 l -h --0.4 -0.4 m -0.4 -0.4 l -0.4 0.4 l --0.4 0.4 l -h - - - - --0.6 -0.6 m -0.6 -0.6 l -0.6 0.6 l --0.6 0.6 l -h - - - - - --0.6 -0.6 m -0.6 -0.6 l -0.6 0.6 l --0.6 0.6 l -h --0.4 -0.4 m -0.4 -0.4 l -0.4 0.4 l --0.4 0.4 l -h - - --0.4 -0.4 m -0.4 -0.4 l -0.4 0.4 l --0.4 0.4 l -h - - - - - - --0.43 -0.57 m -0.57 0.43 l -0.43 0.57 l --0.57 -0.43 l -h - - --0.43 0.57 m -0.57 -0.43 l -0.43 -0.57 l --0.57 0.43 l -h - - - - - -0 0 m --1 0.333 l --1 -0.333 l -h - - - - -0 0 m --1 0.333 l --0.8 0 l --1 -0.333 l -h - - - - -0 0 m --1 0.333 l --0.8 0 l --1 -0.333 l -h - - - - --1 0.333 m -0 0 l --1 -0.333 l - - - - -0 0 m --1 0.333 l --1 -0.333 l -h --1 0 m --2 0.333 l --2 -0.333 l -h - - - - -0 0 m --1 0.333 l --1 -0.333 l -h --1 0 m --2 0.333 l --2 -0.333 l -h - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -$_w\mathtt{p}$ -$\overrightarrow{\mathcal{F}}_w$ - -64 576 m -96 576 l - - -64 576 m -64 608 l - - -64 576 m -80 592 l - - -144 688 m -176 688 l - - -144 688 m -144 720 l - - -144 688 m -160 704 l - - -285.262 759.615 m -162.017 735.456 -129.232 628.801 s - - -$\mathtt{T}_{f,w}$ - -128.441 626.745 m -320.625 647.224 l - - -331.681 587.399 m -331.681 587.399 l - -$x$ -$z$ -$y$ - -256 736 m -224 704 l -320 704 l -352 736 l -h - - -285.262 759.265 m -322.176 651.119 l - -$\mathtt{px}$ - -285.612 758.915 m -315.723 669.632 l - -$\mathtt{f}$ -$\overrightarrow{\mathcal{F}}_f$ - -255.668 719.918 m -274.728 719.957 l - - -256.107 720.028 m -246.655 710.527 l - -$v$ -$u$ - -$\mathbf{p}$ -$_f\mathtt{p}$ - - diff --git a/svo/doc/notation.pdf b/svo/doc/notation.pdf deleted file mode 100644 index 3bc3fcd1e26432ecb0bbd75ccac1399691cf3da1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50379 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 diff --git a/svo/doc/notation.png b/svo/doc/notation.png deleted file mode 100644 index d613b70c287aff422211aaede98b677578c69bda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27376 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 -// (Robotics and Perception Group, University of Zurich, Switzerland). -// -// SVO is free software: you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the Free Software -// Foundation, either version 3 of the License, or any later version. -// -// SVO is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#ifndef DATASET_IMG_H -#define DATASET_IMG_H - -namespace FileType { - -#include -#include -#include - -using ::Eigen::Quaterniond; -using ::Eigen::Vector3d; - -/// Specification of Dataset which contains: Camera Image, Gyroscope Rotation -class DatasetImg -{ -public: - DatasetImg() {} - virtual ~DatasetImg() {} - - double timestamp_; - std::string image_name_; - - friend std::ostream& operator <<(std::ostream& out, const DatasetImg& pair); - friend std::istream& operator >>(std::istream& in, DatasetImg& pair); -}; - -std::ostream& operator <<(std::ostream& out, const DatasetImg& gt) -{ - out - << gt.timestamp_ << " " - << gt.image_name_ << " " - << std::endl; - return out; -} - -std::istream& operator >>(std::istream& in, DatasetImg& gt) -{ - in >> gt.timestamp_; - in >> gt.image_name_; - return in; -} - -} // end namespace FileType - - -#endif /* DATASET_IMG_H */ From 6a08b7de5d8d421dca11049f20db67b68c5ecde4 Mon Sep 17 00:00:00 2001 From: gfuse Date: Wed, 5 May 2021 11:22:00 +0200 Subject: [PATCH 185/215] init GPU --- CPU_version/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CPU_version/README.md b/CPU_version/README.md index 1d27172..00b6d87 100755 --- a/CPU_version/README.md +++ b/CPU_version/README.md @@ -3,9 +3,10 @@ SVO This code implements a semi-direct monocular visual odometry pipeline which has been integrated with GTSAM to infused IMU as well. -Video: http://youtu.be/2YnIMfw6bJY -Paper: http://rpg.ifi.uzh.ch/docs/ICRA14_Forster.pdf +Paper svo: http://rpg.ifi.uzh.ch/docs/ICRA14_Forster.pdf +Paper Svo+GTSAM: https://arxiv.org/abs/1512.02363 + #### Disclaimer From ec7e554add7c9a424c816f104778bef83dfc2154 Mon Sep 17 00:00:00 2001 From: gfuse Date: Wed, 5 May 2021 12:29:29 +0200 Subject: [PATCH 186/215] add GPU svo under development --- CPU_version/svo_msgs/CMakeLists.txt | 6 +- CPU_version/svo_ros/.idea/svo_ros.iml | 8 - CPU_version/svo_ros/.idea/workspace.xml | 627 ------ CPU_version/vio_svo/CMakeLists.txt | 15 +- CPU_version/vio_svo/msg/Info.msg | 6 + CPU_version/vio_svo/package.xml | 4 +- CPU_version/vio_svo/src/visualizer.cpp | 6 +- GPU_version/README.md | 45 + GPU_version/svo/.idea/.gitignore | 8 + GPU_version/svo/.idea/misc.xml | 4 + .../svo}/.idea/modules.xml | 2 +- .../svo_ros => GPU_version/svo}/.idea/vcs.xml | 0 GPU_version/svo/CMakeLists.txt | 132 ++ GPU_version/svo/CMakeModules/FindEigen.cmake | 81 + GPU_version/svo/CMakeModules/FindG2O.cmake | 113 ++ GPU_version/svo/Doxyfile | 1782 +++++++++++++++++ GPU_version/svo/doc/.gitignore | 2 + GPU_version/svo/doc/notation.ipe | 312 +++ GPU_version/svo/doc/notation.pdf | Bin 0 -> 50379 bytes GPU_version/svo/doc/notation.png | Bin 0 -> 27376 bytes .../svo/include/svo/bundle_adjustment.h | 109 + GPU_version/svo/include/svo/config.h | 177 ++ GPU_version/svo/include/svo/depth_filter.h | 171 ++ GPU_version/svo/include/svo/feature.h | 75 + .../svo/include/svo/feature_alignment.h | 63 + .../svo/include/svo/feature_detection.h | 107 + GPU_version/svo/include/svo/frame.h | 154 ++ .../svo/include/svo/frame_handler_base.h | 123 ++ .../svo/include/svo/frame_handler_mono.h | 104 + GPU_version/svo/include/svo/global.h | 101 + GPU_version/svo/include/svo/imu_integration.h | 121 ++ GPU_version/svo/include/svo/initialization.h | 83 + GPU_version/svo/include/svo/map.h | 136 ++ GPU_version/svo/include/svo/matcher.h | 130 ++ GPU_version/svo/include/svo/point.h | 108 + GPU_version/svo/include/svo/pose_optimizer.h | 50 + GPU_version/svo/include/svo/reprojector.h | 101 + .../svo/include/svo/sparse_img_align.h | 83 + GPU_version/svo/include/svo/svoVisionFactor.h | 70 + GPU_version/svo/package.xml | 27 + GPU_version/svo/src/bundle_adjustment.cpp | 435 ++++ GPU_version/svo/src/config.cpp | 102 + GPU_version/svo/src/depth_filter.cpp | 352 ++++ GPU_version/svo/src/feature_alignment.cpp | 601 ++++++ GPU_version/svo/src/feature_detection.cpp | 118 ++ GPU_version/svo/src/frame.cpp | 190 ++ GPU_version/svo/src/frame_handler_base.cpp | 199 ++ GPU_version/svo/src/frame_handler_mono.cpp | 307 +++ GPU_version/svo/src/imu_integration.cpp | 151 ++ GPU_version/svo/src/initialization.cpp | 199 ++ GPU_version/svo/src/map.cpp | 368 ++++ GPU_version/svo/src/matcher.cpp | 323 +++ GPU_version/svo/src/point.cpp | 179 ++ GPU_version/svo/src/pose_optimizer.cpp | 165 ++ GPU_version/svo/src/reprojector.cpp | 219 ++ GPU_version/svo/src/sparse_img_align.cpp | 274 +++ GPU_version/svo/test/README.md | 24 + GPU_version/svo/test/benchmark.csv | 307 +++ GPU_version/svo/test/data/.gitignore | 2 + GPU_version/svo/test/results/.gitignore | 2 + GPU_version/svo/test/test_depth_filter.cpp | 206 ++ .../svo/test/test_feature_alignment.cpp | 124 ++ .../svo/test/test_feature_detection.cpp | 74 + GPU_version/svo/test/test_matcher.cpp | 200 ++ GPU_version/svo/test/test_pipeline.cpp | 98 + GPU_version/svo/test/test_pose_optimizer.cpp | 110 + .../svo/test/test_sparse_img_align.cpp | 163 ++ GPU_version/svo/test/test_utils.h | 57 + 68 files changed, 10147 insertions(+), 648 deletions(-) delete mode 100644 CPU_version/svo_ros/.idea/svo_ros.iml delete mode 100644 CPU_version/svo_ros/.idea/workspace.xml create mode 100644 CPU_version/vio_svo/msg/Info.msg create mode 100755 GPU_version/README.md create mode 100644 GPU_version/svo/.idea/.gitignore create mode 100644 GPU_version/svo/.idea/misc.xml rename {CPU_version/svo_ros => GPU_version/svo}/.idea/modules.xml (59%) rename {CPU_version/svo_ros => GPU_version/svo}/.idea/vcs.xml (100%) create mode 100644 GPU_version/svo/CMakeLists.txt create mode 100644 GPU_version/svo/CMakeModules/FindEigen.cmake create mode 100644 GPU_version/svo/CMakeModules/FindG2O.cmake create mode 100644 GPU_version/svo/Doxyfile create mode 100644 GPU_version/svo/doc/.gitignore create mode 100644 GPU_version/svo/doc/notation.ipe create mode 100644 GPU_version/svo/doc/notation.pdf create mode 100644 GPU_version/svo/doc/notation.png create mode 100644 GPU_version/svo/include/svo/bundle_adjustment.h create mode 100644 GPU_version/svo/include/svo/config.h create mode 100644 GPU_version/svo/include/svo/depth_filter.h create mode 100644 GPU_version/svo/include/svo/feature.h create mode 100644 GPU_version/svo/include/svo/feature_alignment.h create mode 100644 GPU_version/svo/include/svo/feature_detection.h create mode 100644 GPU_version/svo/include/svo/frame.h create mode 100644 GPU_version/svo/include/svo/frame_handler_base.h create mode 100644 GPU_version/svo/include/svo/frame_handler_mono.h create mode 100644 GPU_version/svo/include/svo/global.h create mode 100644 GPU_version/svo/include/svo/imu_integration.h create mode 100644 GPU_version/svo/include/svo/initialization.h create mode 100644 GPU_version/svo/include/svo/map.h create mode 100644 GPU_version/svo/include/svo/matcher.h create mode 100644 GPU_version/svo/include/svo/point.h create mode 100644 GPU_version/svo/include/svo/pose_optimizer.h create mode 100644 GPU_version/svo/include/svo/reprojector.h create mode 100644 GPU_version/svo/include/svo/sparse_img_align.h create mode 100644 GPU_version/svo/include/svo/svoVisionFactor.h create mode 100644 GPU_version/svo/package.xml create mode 100644 GPU_version/svo/src/bundle_adjustment.cpp create mode 100644 GPU_version/svo/src/config.cpp create mode 100644 GPU_version/svo/src/depth_filter.cpp create mode 100644 GPU_version/svo/src/feature_alignment.cpp create mode 100644 GPU_version/svo/src/feature_detection.cpp create mode 100644 GPU_version/svo/src/frame.cpp create mode 100644 GPU_version/svo/src/frame_handler_base.cpp create mode 100644 GPU_version/svo/src/frame_handler_mono.cpp create mode 100644 GPU_version/svo/src/imu_integration.cpp create mode 100644 GPU_version/svo/src/initialization.cpp create mode 100644 GPU_version/svo/src/map.cpp create mode 100644 GPU_version/svo/src/matcher.cpp create mode 100644 GPU_version/svo/src/point.cpp create mode 100644 GPU_version/svo/src/pose_optimizer.cpp create mode 100644 GPU_version/svo/src/reprojector.cpp create mode 100644 GPU_version/svo/src/sparse_img_align.cpp create mode 100644 GPU_version/svo/test/README.md create mode 100644 GPU_version/svo/test/benchmark.csv create mode 100644 GPU_version/svo/test/data/.gitignore create mode 100644 GPU_version/svo/test/results/.gitignore create mode 100644 GPU_version/svo/test/test_depth_filter.cpp create mode 100644 GPU_version/svo/test/test_feature_alignment.cpp create mode 100644 GPU_version/svo/test/test_feature_detection.cpp create mode 100644 GPU_version/svo/test/test_matcher.cpp create mode 100644 GPU_version/svo/test/test_pipeline.cpp create mode 100644 GPU_version/svo/test/test_pose_optimizer.cpp create mode 100644 GPU_version/svo/test/test_sparse_img_align.cpp create mode 100644 GPU_version/svo/test/test_utils.h diff --git a/CPU_version/svo_msgs/CMakeLists.txt b/CPU_version/svo_msgs/CMakeLists.txt index 06bb680..6d1a371 100644 --- a/CPU_version/svo_msgs/CMakeLists.txt +++ b/CPU_version/svo_msgs/CMakeLists.txt @@ -8,14 +8,12 @@ find_package(catkin REQUIRED COMPONENTS sensor_msgs ) -# search for all msg files -FILE(GLOB messages_to_build RELATIVE "msg" - "${CMAKE_CURRENT_SOURCE_DIR}/msg/*.msg") + # notify catkin to look at the previously found msg files add_message_files( FILES - ${messages_to_build} + Info.msg ) # build the header files from the msg files, and notify catkin about the dependencies diff --git a/CPU_version/svo_ros/.idea/svo_ros.iml b/CPU_version/svo_ros/.idea/svo_ros.iml deleted file mode 100644 index bc2cd87..0000000 --- a/CPU_version/svo_ros/.idea/svo_ros.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/CPU_version/svo_ros/.idea/workspace.xml b/CPU_version/svo_ros/.idea/workspace.xml deleted file mode 100644 index 09c1504..0000000 --- a/CPU_version/svo_ros/.idea/workspace.xml +++ /dev/null @@ -1,627 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1615974669888 - - - 1617193017745 - - - 1617640897291 - - - - - - - - - - - - \ No newline at end of file diff --git a/CPU_version/vio_svo/CMakeLists.txt b/CPU_version/vio_svo/CMakeLists.txt index b57bcfc..70101db 100644 --- a/CPU_version/vio_svo/CMakeLists.txt +++ b/CPU_version/vio_svo/CMakeLists.txt @@ -32,7 +32,6 @@ FIND_PACKAGE(catkin REQUIRED COMPONENTS cv_bridge tf svo - svo_msgs vikit_common vikit_ros ) @@ -44,10 +43,22 @@ FIND_PACKAGE(Sophus REQUIRED) FIND_PACKAGE(Boost REQUIRED COMPONENTS thread) FIND_PACKAGE(GTSAM REQUIRED) +# notify catkin to look at the previously found msg files +add_message_files( + FILES + Info.msg +) + +# build the header files from the msg files, and notify catkin about the dependencies +generate_messages( + DEPENDENCIES + geometry_msgs + sensor_msgs +) # Describe catkin Project catkin_package( DEPENDS Eigen OpenCV Sophus Boost - CATKIN_DEPENDS roscpp nav_msgs std_msgs visualization_msgs sensor_msgs image_transport cv_bridge tf svo svo_msgs vikit_common vikit_ros geometry_msgs + CATKIN_DEPENDS roscpp nav_msgs std_msgs visualization_msgs sensor_msgs image_transport cv_bridge tf svo vikit_common vikit_ros geometry_msgs INCLUDE_DIRS include LIBRARIES svo_visualizer ) diff --git a/CPU_version/vio_svo/msg/Info.msg b/CPU_version/vio_svo/msg/Info.msg new file mode 100644 index 0000000..b962e1b --- /dev/null +++ b/CPU_version/vio_svo/msg/Info.msg @@ -0,0 +1,6 @@ +Header header +float32 processing_time +int32[] keyframes +int32 num_matches +int32 tracking_quality +int32 stage \ No newline at end of file diff --git a/CPU_version/vio_svo/package.xml b/CPU_version/vio_svo/package.xml index bb5b0f2..c63372b 100644 --- a/CPU_version/vio_svo/package.xml +++ b/CPU_version/vio_svo/package.xml @@ -6,7 +6,7 @@ Monocular Visual Odometry - ROS Nodes Christian Forster - Christian Forster + Majid Geravand GPLv3 @@ -23,7 +23,6 @@ cv_bridge tf svo - svo_msgs vikit_common vikit_ros geometry_msgs @@ -38,7 +37,6 @@ cv_bridge tf svo - svo_msgs vikit_common vikit_ros geometry_msgs diff --git a/CPU_version/vio_svo/src/visualizer.cpp b/CPU_version/vio_svo/src/visualizer.cpp index 4d3a631..901f9ef 100644 --- a/CPU_version/vio_svo/src/visualizer.cpp +++ b/CPU_version/vio_svo/src/visualizer.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -37,7 +37,7 @@ Visualizer() : pub_frames_ = pnh_.advertise("keyframes", 10); pub_points_ = pnh_.advertise("points", 1000); pub_pose_ = pnh_.advertise("pose",10); - pub_info_ = pnh_.advertise("info", 10); + pub_info_ = pnh_.advertise("info", 10); } void Visualizer::publishMinimal( @@ -55,7 +55,7 @@ void Visualizer::publishMinimal( // publish info msg. if(pub_info_.getNumSubscribers() > 0) { - svo_msgs::Info msg_info; + vio_svo::Info msg_info; msg_info.header = header_msg; msg_info.processing_time = slam.lastProcessingTime(); msg_info.keyframes.reserve(slam.map().keyframes_.size()); diff --git a/GPU_version/README.md b/GPU_version/README.md new file mode 100755 index 0000000..00b6d87 --- /dev/null +++ b/GPU_version/README.md @@ -0,0 +1,45 @@ +SVO +=== + +This code implements a semi-direct monocular visual odometry pipeline which has been integrated with GTSAM to infused IMU as well. + + +Paper svo: http://rpg.ifi.uzh.ch/docs/ICRA14_Forster.pdf +Paper Svo+GTSAM: https://arxiv.org/abs/1512.02363 + + +#### Disclaimer + +SVO has been tested under ROS Groovy, Hydro and Indigo with Ubuntu 12.04, 13.04 and 14.04. This is research code, any fitness for a particular purpose is disclaimed. + + +#### Licence + +The source code is released under a GPLv3 licence. A closed-source professional edition is available for commercial purposes. In this case, please contact the authors for further info. + + +#### Citing + +If you use SVO in an academic context, please cite the following publication: + + @inproceedings{Forster2014ICRA, + author = {Forster, Christian and Pizzoli, Matia and Scaramuzza, Davide}, + title = {{SVO}: Fast Semi-Direct Monocular Visual Odometry}, + booktitle = {IEEE International Conference on Robotics and Automation (ICRA)}, + year = {2014} + } + + +#### Documentation + +The API is documented here: http://uzh-rpg.github.io/rpg_svo/doc/ +The GTSAM documentation https://gtsam.org/tutorials/ + +#### Instructions + +See the Wiki for more instructions. https://github.com/uzh-rpg/rpg_svo/wiki and https://gtsam.org/get_started/ + +#### Contributing + +You are very welcome to contribute to SVO by opening a pull request via Github. +I try to follow the ROS C++ style guide http://wiki.ros.org/CppStyleGuide diff --git a/GPU_version/svo/.idea/.gitignore b/GPU_version/svo/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/GPU_version/svo/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/GPU_version/svo/.idea/misc.xml b/GPU_version/svo/.idea/misc.xml new file mode 100644 index 0000000..79b3c94 --- /dev/null +++ b/GPU_version/svo/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CPU_version/svo_ros/.idea/modules.xml b/GPU_version/svo/.idea/modules.xml similarity index 59% rename from CPU_version/svo_ros/.idea/modules.xml rename to GPU_version/svo/.idea/modules.xml index eb3cacf..4c8cf2b 100644 --- a/CPU_version/svo_ros/.idea/modules.xml +++ b/GPU_version/svo/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/CPU_version/svo_ros/.idea/vcs.xml b/GPU_version/svo/.idea/vcs.xml similarity index 100% rename from CPU_version/svo_ros/.idea/vcs.xml rename to GPU_version/svo/.idea/vcs.xml diff --git a/GPU_version/svo/CMakeLists.txt b/GPU_version/svo/CMakeLists.txt new file mode 100644 index 0000000..ed4b593 --- /dev/null +++ b/GPU_version/svo/CMakeLists.txt @@ -0,0 +1,132 @@ +################################################################################ +# user build settings + +SET(TRACE TRUE) +SET(HAVE_G2O FALSE) +SET(USE_ROS TRUE) # Set FALSE if you want to build this package without Catkin +SET(DEBUG_OUTPUT FALSE) # Only relevant if build without ROS + +################################################################################ + +SET(PROJECT_NAME gpu_svo) +PROJECT(${PROJECT_NAME}) +CMAKE_MINIMUM_REQUIRED (VERSION 2.8.3) +SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo +SET(CMAKE_VERBOSE_MAKEFILE OFF) +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") +set(CMAKE_C_STANDARD 14) +set(CMAKE_CXX_STANDARD 14) + +# Set definitions +IF(TRACE) + ADD_DEFINITIONS(-DSVO_TRACE) +ENDIF() +IF(HAVE_G2O) + ADD_DEFINITIONS(-DUSE_BUNDLE_ADJUSTMENT) +ENDIF() +IF(USE_ROS) + ADD_DEFINITIONS(-DSVO_USE_ROS) +ENDIF() +IF(DEBUG_OUTPUT) + ADD_DEFINITIONS(-DSVO_DEBUG_OUTPUT) +ENDIF() + +# Set build flags, set ARM_ARCHITECTURE environment variable on Odroid +# Set build flags. Set IS_ARM on odroid board as environment variable +SET(CMAKE_CXX_FLAGS "-Wall -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") +IF(DEFINED ENV{ARM_ARCHITECTURE}) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ") +ELSE() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse -msse2 -msse3 -mssse3") +ENDIF() +IF(CMAKE_COMPILER_IS_GNUCC) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +ELSE() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +ENDIF() +SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -fsee -fomit-frame-pointer -fno-signed-zeros -fno-math-errno -funroll-loops") + +# Add plain cmake packages +FIND_PACKAGE(OpenCV REQUIRED) +FIND_PACKAGE(Eigen REQUIRED) +FIND_PACKAGE(Sophus REQUIRED) +FIND_PACKAGE(fast REQUIRED) +FIND_PACKAGE(Boost REQUIRED COMPONENTS thread system) +FIND_PACKAGE(GTSAM REQUIRED) + +set(GTSAM_INCLUDE_DIRS "${GTSAM_INCLUDE_DIR}") +IF(USE_ROS) + FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros) + catkin_package( + DEPENDS Eigen OpenCV Sophus Boost fast GTSAM + CATKIN_DEPENDS roscpp roslib vikit_common vikit_ros + INCLUDE_DIRS include + LIBRARIES ${PROJECT_NAME} + ) +ELSE() + FIND_PACKAGE(vikit_common REQUIRED) + SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) + SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) +ENDIF() + +# Include dirs +INCLUDE_DIRECTORIES( + include + ${Eigen_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${Sophus_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${fast_INCLUDE_DIRS} ${GTSAM_INCLUDE_DIR} +) + +# Set link libraries +LIST(APPEND LINK_LIBS + ${OpenCV_LIBS} + ${Sophus_LIBRARIES} + ${Boost_LIBRARIES} + ${fast_LIBRARIES} +) +IF(USE_ROS) + INCLUDE_DIRECTORIES(${catkin_INCLUDE_DIRS}) + LIST(APPEND LINK_LIBS ${catkin_LIBRARIES}) +ELSE() + INCLUDE_DIRECTORIES(${vikit_common_INCLUDE_DIRS}) + LIST(APPEND LINK_LIBS ${vikit_common_LIBRARIES}) +ENDIF() + +# Set sourcefiles +LIST(APPEND SOURCEFILES + src/frame_handler_mono.cpp + src/frame_handler_base.cpp + src/frame.cpp + src/point.cpp + src/map.cpp + src/pose_optimizer.cpp + src/initialization.cpp + src/matcher.cpp + src/reprojector.cpp + src/feature_alignment.cpp + src/feature_detection.cpp + src/depth_filter.cpp + src/config.cpp + src/sparse_img_align.cpp src/imu_integration.cpp) + +# Add g2o if available +IF(HAVE_G2O) + FIND_PACKAGE(G2O REQUIRED) + INCLUDE_DIRECTORIES( + ${G2O_INCLUDE_DIR} + /usr/include/suitesparse # for cholmod + ) + LIST(APPEND LINK_LIBS + ${G2O_CORE_LIBRARY} ${G2O_STUFF_LIBRARY} ${G2O_SOLVER_CHOLMOD} ${G2O_SOLVER_CSPARSE} ${G2O_SOLVER_DENSE} + ${G2O_SOLVER_PCG} ${G2O_TYPES_SBA} cholmod cxsparse + ) + LIST(APPEND SOURCEFILES src/bundle_adjustment.cpp) +ENDIF(HAVE_G2O) + +# Create svo library +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCEFILES}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LINK_LIBS} gtsam) +set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14) +set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) diff --git a/GPU_version/svo/CMakeModules/FindEigen.cmake b/GPU_version/svo/CMakeModules/FindEigen.cmake new file mode 100644 index 0000000..8587367 --- /dev/null +++ b/GPU_version/svo/CMakeModules/FindEigen.cmake @@ -0,0 +1,81 @@ +############################################################################### +# +# CMake script for finding the Eigen library. +# +# http://eigen.tuxfamily.org/index.php?title=Main_Page +# +# Copyright (c) 2006, 2007 Montel Laurent, +# Copyright (c) 2008, 2009 Gael Guennebaud, +# Copyright (c) 2009 Benoit Jacob +# Redistribution and use is allowed according to the terms of the 2-clause BSD +# license. +# +# +# Input variables: +# +# - Eigen_ROOT_DIR (optional): When specified, header files and libraries +# will be searched for in `${Eigen_ROOT_DIR}/include` and +# `${Eigen_ROOT_DIR}/libs` respectively, and the default CMake search order +# will be ignored. When unspecified, the default CMake search order is used. +# This variable can be specified either as a CMake or environment variable. +# If both are set, preference is given to the CMake variable. +# Use this variable for finding packages installed in a nonstandard location, +# or for enforcing that one of multiple package installations is picked up. +# +# Cache variables (not intended to be used in CMakeLists.txt files) +# +# - Eigen_INCLUDE_DIR: Absolute path to package headers. +# +# +# Output variables: +# +# - Eigen_FOUND: Boolean that indicates if the package was found +# - Eigen_INCLUDE_DIRS: Paths to the necessary header files +# - Eigen_VERSION: Version of Eigen library found +# - Eigen_DEFINITIONS: Definitions to be passed on behalf of eigen +# +# +# Example usage: +# +# # Passing the version means Eigen_FOUND will only be TRUE if a +# # version >= the provided version is found. +# find_package(Eigen 3.1.2) +# if(NOT Eigen_FOUND) +# # Error handling +# endif() +# ... +# add_definitions(${Eigen_DEFINITIONS}) +# ... +# include_directories(${Eigen_INCLUDE_DIRS} ...) +# +############################################################################### + +find_package(PkgConfig) +pkg_check_modules(PC_EIGEN eigen3) +set(EIGEN_DEFINITIONS ${PC_EIGEN_CFLAGS_OTHER}) + + +find_path(EIGEN_INCLUDE_DIR Eigen/Core + HINTS ${PC_EIGEN_INCLUDEDIR} ${PC_EIGEN_INCLUDE_DIRS} + "${Eigen_ROOT_DIR}" "$ENV{EIGEN_ROOT_DIR}" + "${EIGEN_ROOT}" "$ENV{EIGEN_ROOT}" # Backwards Compatibility + PATHS "$ENV{PROGRAMFILES}/Eigen" "$ENV{PROGRAMW6432}/Eigen" + "$ENV{PROGRAMFILES}/Eigen 3.0.0" "$ENV{PROGRAMW6432}/Eigen 3.0.0" + PATH_SUFFIXES eigen3 include/eigen3 include) + +set(EIGEN_INCLUDE_DIRS ${EIGEN_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Eigen DEFAULT_MSG EIGEN_INCLUDE_DIR) + +mark_as_advanced(EIGEN_INCLUDE_DIR) + +if(EIGEN_FOUND) + message(STATUS "Eigen found (include: ${EIGEN_INCLUDE_DIRS})") +endif(EIGEN_FOUND) + + +set(Eigen_INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS}) +set(Eigen_FOUND ${EIGEN_FOUND}) +set(Eigen_VERSION ${EIGEN_VERSION}) +set(Eigen_DEFINITIONS ${EIGEN_DEFINITIONS}) diff --git a/GPU_version/svo/CMakeModules/FindG2O.cmake b/GPU_version/svo/CMakeModules/FindG2O.cmake new file mode 100644 index 0000000..655600f --- /dev/null +++ b/GPU_version/svo/CMakeModules/FindG2O.cmake @@ -0,0 +1,113 @@ +# Find the header files + +FIND_PATH(G2O_INCLUDE_DIR g2o/core/base_vertex.h + ${G2O_ROOT}/include + $ENV{G2O_ROOT}/include + $ENV{G2O_ROOT} + /usr/local/include + /usr/include + /opt/local/include + /sw/local/include + /sw/include + NO_DEFAULT_PATH + ) + +# Macro to unify finding both the debug and release versions of the +# libraries; this is adapted from the OpenSceneGraph FIND_LIBRARY +# macro. + +MACRO(FIND_G2O_LIBRARY MYLIBRARY MYLIBRARYNAME) + + FIND_LIBRARY("${MYLIBRARY}_DEBUG" + NAMES "g2o_${MYLIBRARYNAME}_d" + PATHS + ${G2O_ROOT}/lib/Debug + ${G2O_ROOT}/lib + $ENV{G2O_ROOT}/lib/Debug + $ENV{G2O_ROOT}/lib + NO_DEFAULT_PATH + ) + + FIND_LIBRARY("${MYLIBRARY}_DEBUG" + NAMES "g2o_${MYLIBRARYNAME}_d" + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/lib + /usr/local/lib64 + /usr/lib + /usr/lib64 + /opt/local/lib + /sw/local/lib + /sw/lib + ) + + FIND_LIBRARY(${MYLIBRARY} + NAMES "g2o_${MYLIBRARYNAME}" + PATHS + ${G2O_ROOT}/lib/Release + ${G2O_ROOT}/lib + $ENV{G2O_ROOT}/lib/Release + $ENV{G2O_ROOT}/lib + NO_DEFAULT_PATH + ) + + FIND_LIBRARY(${MYLIBRARY} + NAMES "g2o_${MYLIBRARYNAME}" + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/lib + /usr/local/lib64 + /usr/lib + /usr/lib64 + /opt/local/lib + /sw/local/lib + /sw/lib + ) + + IF(NOT ${MYLIBRARY}_DEBUG) + IF(MYLIBRARY) + SET(${MYLIBRARY}_DEBUG ${MYLIBRARY}) + ENDIF(MYLIBRARY) + ENDIF( NOT ${MYLIBRARY}_DEBUG) + +ENDMACRO(FIND_G2O_LIBRARY LIBRARY LIBRARYNAME) + +# Find the core elements +FIND_G2O_LIBRARY(G2O_STUFF_LIBRARY stuff) +FIND_G2O_LIBRARY(G2O_CORE_LIBRARY core) + +# Find the CLI library +FIND_G2O_LIBRARY(G2O_CLI_LIBRARY cli) + +# Find the pluggable solvers +FIND_G2O_LIBRARY(G2O_SOLVER_CHOLMOD solver_cholmod) +FIND_G2O_LIBRARY(G2O_SOLVER_CSPARSE solver_csparse) +FIND_G2O_LIBRARY(G2O_SOLVER_CSPARSE_EXTENSION csparse_extension) +FIND_G2O_LIBRARY(G2O_SOLVER_DENSE solver_dense) +FIND_G2O_LIBRARY(G2O_SOLVER_PCG solver_pcg) +FIND_G2O_LIBRARY(G2O_SOLVER_SLAM2D_LINEAR solver_slam2d_linear) +FIND_G2O_LIBRARY(G2O_SOLVER_STRUCTURE_ONLY solver_structure_only) +FIND_G2O_LIBRARY(G2O_SOLVER_EIGEN solver_eigen) + +# Find the predefined types +FIND_G2O_LIBRARY(G2O_TYPES_DATA types_data) +FIND_G2O_LIBRARY(G2O_TYPES_ICP types_icp) +FIND_G2O_LIBRARY(G2O_TYPES_SBA types_sba) +FIND_G2O_LIBRARY(G2O_TYPES_SCLAM2D types_sclam2d) +FIND_G2O_LIBRARY(G2O_TYPES_SIM3 types_sim3) +FIND_G2O_LIBRARY(G2O_TYPES_SLAM2D types_slam2d) +FIND_G2O_LIBRARY(G2O_TYPES_SLAM3D types_slam3d) + +# G2O solvers declared found if we found at least one solver +SET(G2O_SOLVERS_FOUND "NO") +IF(G2O_SOLVER_CHOLMOD OR G2O_SOLVER_CSPARSE OR G2O_SOLVER_DENSE OR G2O_SOLVER_PCG OR G2O_SOLVER_SLAM2D_LINEAR OR G2O_SOLVER_STRUCTURE_ONLY OR G2O_SOLVER_EIGEN) + SET(G2O_SOLVERS_FOUND "YES") +ENDIF(G2O_SOLVER_CHOLMOD OR G2O_SOLVER_CSPARSE OR G2O_SOLVER_DENSE OR G2O_SOLVER_PCG OR G2O_SOLVER_SLAM2D_LINEAR OR G2O_SOLVER_STRUCTURE_ONLY OR G2O_SOLVER_EIGEN) + +# G2O itself declared found if we found the core libraries and at least one solver +SET(G2O_FOUND "NO") +IF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_SOLVERS_FOUND) + SET(G2O_FOUND "YES") +ENDIF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_SOLVERS_FOUND) diff --git a/GPU_version/svo/Doxyfile b/GPU_version/svo/Doxyfile new file mode 100644 index 0000000..b1b4256 --- /dev/null +++ b/GPU_version/svo/Doxyfile @@ -0,0 +1,1782 @@ +# Doxyfile 1.7.6.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "svo" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Semi-Direct Visual Odometry" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = "doc" + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = "src", "include/svo" + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = g2o +EXCLUDE_SYMBOLS += vk + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +#
+# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/GPU_version/svo/doc/.gitignore b/GPU_version/svo/doc/.gitignore new file mode 100644 index 0000000..cf57c3b --- /dev/null +++ b/GPU_version/svo/doc/.gitignore @@ -0,0 +1,2 @@ +.gitignore +!.gitignore \ No newline at end of file diff --git a/GPU_version/svo/doc/notation.ipe b/GPU_version/svo/doc/notation.ipe new file mode 100644 index 0000000..f8c1efe --- /dev/null +++ b/GPU_version/svo/doc/notation.ipe @@ -0,0 +1,312 @@ + + + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + +0.6 0 0 0.6 0 0 e + + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + +0.4 0 0 0.4 0 0 e + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + + + +-0.43 -0.57 m +0.57 0.43 l +0.43 0.57 l +-0.57 -0.43 l +h + + +-0.43 0.57 m +0.57 -0.43 l +0.43 -0.57 l +-0.57 0.43 l +h + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +-1 0.333 m +0 0 l +-1 -0.333 l + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$_w\mathtt{p}$ +$\overrightarrow{\mathcal{F}}_w$ + +64 576 m +96 576 l + + +64 576 m +64 608 l + + +64 576 m +80 592 l + + +144 688 m +176 688 l + + +144 688 m +144 720 l + + +144 688 m +160 704 l + + +285.262 759.615 m +162.017 735.456 +129.232 628.801 s + + +$\mathtt{T}_{f,w}$ + +128.441 626.745 m +320.625 647.224 l + + +331.681 587.399 m +331.681 587.399 l + +$x$ +$z$ +$y$ + +256 736 m +224 704 l +320 704 l +352 736 l +h + + +285.262 759.265 m +322.176 651.119 l + +$\mathtt{px}$ + +285.612 758.915 m +315.723 669.632 l + +$\mathtt{f}$ +$\overrightarrow{\mathcal{F}}_f$ + +255.668 719.918 m +274.728 719.957 l + + +256.107 720.028 m +246.655 710.527 l + +$v$ +$u$ + +$\mathbf{p}$ +$_f\mathtt{p}$ + + diff --git a/GPU_version/svo/doc/notation.pdf b/GPU_version/svo/doc/notation.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3bc3fcd1e26432ecb0bbd75ccac1399691cf3da1 GIT binary patch literal 50379 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 literal 0 HcmV?d00001 diff --git a/GPU_version/svo/doc/notation.png b/GPU_version/svo/doc/notation.png new file mode 100644 index 0000000000000000000000000000000000000000..d613b70c287aff422211aaede98b677578c69bda GIT binary patch literal 27376 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 +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_BUNDLE_ADJUSTMENT_H_ +#define SVO_BUNDLE_ADJUSTMENT_H_ + +#include + +namespace g2o { +class EdgeProjectXYZ2UV; +class SparseOptimizer; +class VertexSE3Expmap; +class VertexSBAPointXYZ; +} + +namespace svo { + +typedef g2o::EdgeProjectXYZ2UV g2oEdgeSE3; +typedef g2o::VertexSE3Expmap g2oFrameSE3; +typedef g2o::VertexSBAPointXYZ g2oPoint; + +class Frame; +class Point; +class Feature; +class Map; + +/// Local, global and 2-view bundle adjustment with g2o +namespace ba { + +/// Temporary container to hold the g2o edge with reference to frame and point. +struct EdgeContainerSE3 +{ + g2oEdgeSE3* edge; + Frame* frame; + Feature* feature; + bool is_deleted; + EdgeContainerSE3(g2oEdgeSE3* e, Frame* frame, Feature* feature) : + edge(e), frame(frame), feature(feature), is_deleted(false) + {} +}; + +/// Optimize two camera frames and their observed 3D points. +/// Is used after initialization. +void twoViewBA(Frame* frame1, Frame* frame2, double reproj_thresh, Map* map); + +/// Local bundle adjustment. +/// Optimizes core_kfs and their observed map points while keeping the +/// neighbourhood fixed. +void localBA( + Frame* center_kf, + set* core_kfs, + Map* map, + size_t& n_incorrect_edges_1, + size_t& n_incorrect_edges_2, + double& init_error, + double& final_error); + +/// Global bundle adjustment. +/// Optimizes the whole map. Is currently not used in SVO. +void globalBA(Map* map); + +/// Initialize g2o with solver type, optimization strategy and camera model. +void setupG2o(g2o::SparseOptimizer * optimizer); + +/// Run the optimization on the provided graph. +void runSparseBAOptimizer( + g2o::SparseOptimizer* optimizer, + unsigned int num_iter, + double& init_error, + double& final_error); + +/// Create a g2o vertice from a keyframe object. +g2oFrameSE3* createG2oFrameSE3( + Frame* kf, + size_t id, + bool fixed); + +/// Creates a g2o vertice from a mappoint object. +g2oPoint* createG2oPoint( + Vector3d pos, + size_t id, + bool fixed); + +/// Creates a g2o edge between a g2o keyframe and mappoint vertice with the provided measurement. +g2oEdgeSE3* createG2oEdgeSE3( + g2oFrameSE3* v_kf, + g2oPoint* v_mp, + const Vector2d& f_up, + bool robust_kernel, + double huber_width, + double weight = 1); + +} // namespace ba +} // namespace svo + +#endif // SVO_BUNDLE_ADJUSTMENT_H_ diff --git a/GPU_version/svo/include/svo/config.h b/GPU_version/svo/include/svo/config.h new file mode 100644 index 0000000..e1c97b1 --- /dev/null +++ b/GPU_version/svo/include/svo/config.h @@ -0,0 +1,177 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_CONFIG_H_ +#define SVO_CONFIG_H_ + +#include +#include +#include + +namespace svo { + +using std::string; + +/// Global configuration file of SVO. +/// Implements the Singleton design pattern to allow global access and to ensure +/// that only one instance exists. +class Config +{ +public: + static Config& getInstance(); + + /// Base-name of the tracefiles. + static string& traceName() { return getInstance().trace_name; } + + /// Directory where the tracefiles are saved. + static string& traceDir() { return getInstance().trace_dir; } + + /// Number of pyramid levels used for features. + static size_t& nPyrLevels() { return getInstance().n_pyr_levels; } + + /// Use the IMU to get relative rotations. + static bool& useImu() { return getInstance().use_imu; } + + /// Number of keyframes in the core. The core-kfs are optimized through bundle adjustment. + static size_t& coreNKfs() { return getInstance().core_n_kfs; } + + /// Initial scale of the map. Depends on the distance the camera is moved for the initialization. + static double& mapScale() { return getInstance().map_scale; } + + /// Feature grid size of a cell in [px]. + static size_t& gridSize() { return getInstance().grid_size; } + + /// Initialization: Minimum required disparity between the first two frames. + static double& initMinDisparity() { return getInstance().init_min_disparity; } + + /// Initialization: Minimum number of tracked features. + static size_t& initMinTracked() { return getInstance().init_min_tracked; } + + /// Initialization: Minimum number of inliers after RANSAC. + static size_t& initMinInliers() { return getInstance().init_min_inliers; } + + /// Maximum level of the Lucas Kanade tracker. + static size_t& kltMaxLevel() { return getInstance().klt_max_level; } + + /// Minimum level of the Lucas Kanade tracker. + static size_t& kltMinLevel() { return getInstance().klt_min_level; } + + /// Reprojection threshold [px]. + static double& reprojThresh() { return getInstance().reproj_thresh; } + + /// Reprojection threshold after pose optimization. + static double& poseOptimThresh() { return getInstance().poseoptim_thresh; } + + /// Number of iterations in local bundle adjustment. + static size_t& poseOptimNumIter() { return getInstance().poseoptim_num_iter; } + + /// Maximum number of points to optimize at every iteration. + static size_t& structureOptimMaxPts() { return getInstance().structureoptim_max_pts; } + + /// Number of iterations in structure optimization. + static size_t& structureOptimNumIter() { return getInstance().structureoptim_num_iter; } + + /// Reprojection threshold after bundle adjustment. + static double& lobaThresh() { return getInstance().loba_thresh; } + + /// Threshold for the robust Huber kernel of the local bundle adjustment. + static double& lobaRobustHuberWidth() { return getInstance().loba_robust_huber_width; } + + /// Number of iterations in the local bundle adjustment. + static size_t& lobaNumIter() { return getInstance().loba_num_iter; } + + /// Minimum distance between two keyframes. Relative to the average height in the map. + static double& kfSelectMinDist() { return getInstance().kfselect_mindist; } + + /// Select only features with a minimum Harris corner score for triangulation. + static double& triangMinCornerScore() { return getInstance().triang_min_corner_score; } + + /// Subpixel refinement of reprojection and triangulation. Set to 0 if no subpix refinement required! + static size_t& subpixNIter() { return getInstance().subpix_n_iter; } + + /// Limit the number of keyframes in the map. This makes nslam essentially. + /// a Visual Odometry. Set to 0 if unlimited number of keyframes are allowed. + /// Minimum number of keyframes is 3. + static size_t& maxNKfs() { return getInstance().max_n_kfs; } + + /// How much (in milliseconds) is the camera delayed with respect to the imu. + static double& imgImuDelay() { return getInstance().img_imu_delay; } + + /// Maximum number of features that should be tracked. + static size_t& maxFts() { return getInstance().max_fts; } + + /// If the number of tracked features drops below this threshold. Tracking quality is bad. + static size_t& qualityMinFts() { return getInstance().quality_min_fts; } + + /// If within one frame, this amount of features are dropped. Tracking quality is bad. + static int& qualityMaxFtsDrop() { return getInstance().quality_max_drop_fts; } + + /// acc white noise in continuous. + static double& ACC_Noise() { return getInstance().ACC_noise; } + + /// acc white noise in continuous. + static double& GYO_Noise() { return getInstance().GYO_noise; } + /// integration uncertainty continuous + static double& IUC() { return getInstance().iuc; } + // acc bias in continuous + static double& ABC() { return getInstance().abc; } + // gyro bias in continuous + static double& GBC() { return getInstance().gbc; } + // error in the bias used for preintegration + static double& EBP() { return getInstance().ebp; } + // the noise used for projection + static double& NRP() { return getInstance().nrp; } + + +private: + Config(); + Config(Config const&); + void operator=(Config const&); + string trace_name; + string trace_dir; + size_t n_pyr_levels; + bool use_imu; + size_t core_n_kfs; + double map_scale; + size_t grid_size; + double init_min_disparity; + size_t init_min_tracked; + size_t init_min_inliers; + size_t klt_max_level; + size_t klt_min_level; + double reproj_thresh; + double poseoptim_thresh; + size_t poseoptim_num_iter; + size_t structureoptim_max_pts; + size_t structureoptim_num_iter; + double loba_thresh; + double loba_robust_huber_width; + size_t loba_num_iter; + double kfselect_mindist; + double triang_min_corner_score; + size_t triang_half_patch_size; + size_t subpix_n_iter; + size_t max_n_kfs; + double img_imu_delay; + size_t max_fts; + size_t quality_min_fts; + int quality_max_drop_fts; + double nrp,ebp,gbc,abc,iuc,ACC_noise,GYO_noise; +}; + +} // namespace svo + +#endif // SVO_CONFIG_H_ diff --git a/GPU_version/svo/include/svo/depth_filter.h b/GPU_version/svo/include/svo/depth_filter.h new file mode 100644 index 0000000..1612d0e --- /dev/null +++ b/GPU_version/svo/include/svo/depth_filter.h @@ -0,0 +1,171 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_DEPTH_FILTER_H_ +#define SVO_DEPTH_FILTER_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +class Frame; +class Feature; +class Point; + +/// A seed is a probabilistic depth estimate for a single pixel. +struct Seed +{ + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + static int batch_counter; + static int seed_counter; + int batch_id; //!< Batch id is the id of the keyframe for which the seed was created. + int id; //!< Seed ID, only used for visualization. + Feature* ftr; //!< Feature in the keyframe for which the depth should be computed. + float a; //!< a of Beta distribution: When high, probability of inlier is large. + float b; //!< b of Beta distribution: When high, probability of outlier is large. + float mu; //!< Mean of normal distribution. + float z_range; //!< Max range of the possible depth. + float sigma2; //!< Variance of normal distribution. + Matrix2d patch_cov; //!< Patch covariance in reference image. + Seed(Feature* ftr, float depth_mean, float depth_min); +}; + +/// Depth filter implements the Bayesian Update proposed in: +/// "Video-based, Real-Time Multi View Stereo" by G. Vogiatzis and C. Hernández. +/// In Image and Vision Computing, 29(7):434-441, 2011. +/// +/// The class uses a callback mechanism such that it can be used also by other +/// algorithms than nslam and for simplified testing. +class DepthFilter +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + typedef boost::unique_lock lock_t; + typedef boost::function callback_t; + + /// Depth-filter config parameters + struct Options + { + bool check_ftr_angle; //!< gradient features are only updated if the epipolar line is orthogonal to the gradient. + bool epi_search_1d; //!< restrict Gauss Newton in the epipolar search to the epipolar line. + bool verbose; //!< display output. + bool use_photometric_disparity_error; //!< use photometric disparity error instead of 1px error in tau computation. + int max_n_kfs; //!< maximum number of keyframes for which we maintain seeds. + double sigma_i_sq; //!< image noise. + double seed_convergence_sigma2_thresh; //!< threshold on depth uncertainty for convergence. + Options() + : check_ftr_angle(false), + epi_search_1d(false), + verbose(false), + use_photometric_disparity_error(false), + max_n_kfs(3), + sigma_i_sq(5e-4), + seed_convergence_sigma2_thresh(200.0) + {} + } options_; + + DepthFilter( + feature_detection::DetectorPtr feature_detector, + callback_t seed_converged_cb); + + virtual ~DepthFilter(); + + /// Start this thread when seed updating should be in a parallel thread. + void startThread(); + + /// Stop the parallel thread that is running. + void stopThread(); + + /// Add frame to the queue to be processed. + void addFrame(FramePtr frame); + + /// Add new keyframe to the queue + void addKeyframe(FramePtr frame, double depth_mean, double depth_min); + + /// Remove all seeds which are initialized from the specified keyframe. This + /// function is used to make sure that no seeds points to a non-existent frame + /// when a frame is removed from the map. + void removeKeyframe(FramePtr frame); + + /// If the map is reset, call this function such that we don't have pointers + /// to old frames. + void reset(); + + /// Returns a copy of the seeds belonging to frame. Thread-safe. + /// Can be used to compute the Next-Best-View in parallel. + /// IMPORTANT! Make sure you hold a valid reference counting pointer to frame + /// so it is not being deleted while you use it. + void getSeedsCopy(const FramePtr& frame, std::list& seeds); + + /// Return a reference to the seeds. This is NOT THREAD SAFE! + //std::list& getSeeds() { return seeds_; } Bug 238 + std::list>& getSeeds() { return seeds_; } + + /// Bayes update of the seed, x is the measurement, tau2 the measurement uncertainty + static void updateSeed( + const float x, + const float tau2, + Seed* seed); + + /// Compute the uncertainty of the measurement. + static double computeTau( + const SE3& T_ref_cur, + const Vector3d& f, + const double z, + const double px_error_angle); + +protected: + feature_detection::DetectorPtr feature_detector_; + callback_t seed_converged_cb_; + //std::list seeds_; + std::list> seeds_; + boost::mutex seeds_mut_; + bool seeds_updating_halt_; //!< Set this value to true when seeds updating should be interrupted. + boost::thread* thread_; + std::queue frame_queue_; + boost::mutex frame_queue_mut_; + boost::condition_variable frame_queue_cond_; + FramePtr new_keyframe_; //!< Next keyframe to extract new seeds. + bool new_keyframe_set_; //!< Do we have a new keyframe to process?. + double new_keyframe_min_depth_; //!< Minimum depth in the new keyframe. Used for range in new seeds. + double new_keyframe_mean_depth_; //!< Maximum depth in the new keyframe. Used for range in new seeds. + vk::PerformanceMonitor permon_; //!< Separate performance monitor since the DepthFilter runs in a parallel thread. + Matcher matcher_; + + /// Initialize new seeds from a frame. + void initializeSeeds(FramePtr frame); + + /// Update all seeds with a new measurement frame. + virtual void updateSeeds(FramePtr frame); + + /// When a new keyframe arrives, the frame queue should be cleared. + void clearFrameQueue(); + + /// A thread that is continuously updating the seeds. + void updateSeedsLoop(); +}; + +} // namespace svo + +#endif // SVO_DEPTH_FILTER_H_ diff --git a/GPU_version/svo/include/svo/feature.h b/GPU_version/svo/include/svo/feature.h new file mode 100644 index 0000000..6f90a9a --- /dev/null +++ b/GPU_version/svo/include/svo/feature.h @@ -0,0 +1,75 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FEATURE_H_ +#define SVO_FEATURE_H_ + +#include + +namespace svo { + +/// A salient image region that is tracked across frames. +struct Feature +{ + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + enum FeatureType { + CORNER, + EDGELET + }; + + FeatureType type; //!< Type can be corner or edgelet. + Frame* frame; //!< Pointer to frame in which the feature was detected. + Vector2d px; //!< Coordinates in pixels on pyramid level 0. + Vector3d f; //!< Unit-bearing vector of the feature. + int level; //!< Image pyramid level where feature was extracted. + Point* point; //!< Pointer to 3D point which corresponds to the feature. + Vector2d grad; //!< Dominant gradient direction for edglets, normalized. + + Feature(Frame* _frame, const Vector2d& _px, int _level) : + type(CORNER), + frame(_frame), + px(_px), + f(frame->cam_->cam2world(px)), + level(_level), + point(NULL), + grad(1.0,0.0) + {} + + Feature(Frame* _frame, const Vector2d& _px, const Vector3d& _f, int _level) : + type(CORNER), + frame(_frame), + px(_px), + f(_f), + level(_level), + point(NULL), + grad(1.0,0.0) + {} + + Feature(Frame* _frame, Point* _point, const Vector2d& _px, const Vector3d& _f, int _level) : + type(CORNER), + frame(_frame), + px(_px), + f(_f), + level(_level), + point(_point), + grad(1.0,0.0) + {} +}; + +} // namespace svo + +#endif // SVO_FEATURE_H_ diff --git a/GPU_version/svo/include/svo/feature_alignment.h b/GPU_version/svo/include/svo/feature_alignment.h new file mode 100644 index 0000000..12523e3 --- /dev/null +++ b/GPU_version/svo/include/svo/feature_alignment.h @@ -0,0 +1,63 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FEATURE_ALIGNMENT_H_ +#define SVO_FEATURE_ALIGNMENT_H_ + +#include + +namespace svo { + +/// Subpixel refinement of a reference feature patch with the current image. +/// Implements the inverse-compositional approach (see "Lucas-Kanade 20 Years on" +/// paper by Baker. +namespace feature_alignment { + +bool align1D( + const cv::Mat& cur_img, + const Vector2f& dir, // direction in which the patch is allowed to move + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate, + double& h_inv); + +bool align2D( + const cv::Mat& cur_img, + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate, + bool no_simd = false); + +bool align2D_SSE2( + const cv::Mat& cur_img, + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate); + +bool align2D_NEON( + const cv::Mat& cur_img, + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate); + +} // namespace feature_alignment +} // namespace svo + +#endif // SVO_FEATURE_ALIGNMENT_H_ diff --git a/GPU_version/svo/include/svo/feature_detection.h b/GPU_version/svo/include/svo/feature_detection.h new file mode 100644 index 0000000..d0990a8 --- /dev/null +++ b/GPU_version/svo/include/svo/feature_detection.h @@ -0,0 +1,107 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FEATURE_DETECTION_H_ +#define SVO_FEATURE_DETECTION_H_ + +#include +#include + +namespace svo { + +/// Implementation of various feature detectors. +namespace feature_detection { + +/// Temporary container used for corner detection. Features are initialized from these. +struct Corner +{ + int x; //!< x-coordinate of corner in the image. + int y; //!< y-coordinate of corner in the image. + int level; //!< pyramid level of the corner. + float score; //!< shi-tomasi score of the corner. + float angle; //!< for gradient-features: dominant gradient angle. + Corner(int x, int y, float score, int level, float angle) : + x(x), y(y), level(level), score(score), angle(angle) + {} +}; +typedef vector Corners; + +/// All detectors should derive from this abstract class. +class AbstractDetector +{ +public: + AbstractDetector( + const int img_width, + const int img_height, + const int cell_size, + const int n_pyr_levels); + + virtual ~AbstractDetector() {}; + + virtual void detect( + Frame* frame, + const ImgPyr& img_pyr, + const double detection_threshold, + Features& fts) = 0; + + /// Flag the grid cell as occupied + void setGridOccpuancy(const Vector2d& px); + + /// Set grid cells of existing features as occupied + void setExistingFeatures(const Features& fts); + +protected: + + static const int border_ = 8; //!< no feature should be within 8px of border. + const int cell_size_; + const int n_pyr_levels_; + const int grid_n_cols_; + const int grid_n_rows_; + vector grid_occupancy_; + + void resetGrid(); + + inline int getCellIndex(int x, int y, int level) + { + const int scale = (1< DetectorPtr; + +/// FAST detector by Edward Rosten. +class FastDetector : public AbstractDetector +{ +public: + FastDetector( + const int img_width, + const int img_height, + const int cell_size, + const int n_pyr_levels); + + virtual ~FastDetector() {} + + virtual void detect( + Frame* frame, + const ImgPyr& img_pyr, + const double detection_threshold, + Features& fts); +}; + +} // namespace feature_detection +} // namespace svo + +#endif // SVO_FEATURE_DETECTION_H_ diff --git a/GPU_version/svo/include/svo/frame.h b/GPU_version/svo/include/svo/frame.h new file mode 100644 index 0000000..c926277 --- /dev/null +++ b/GPU_version/svo/include/svo/frame.h @@ -0,0 +1,154 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FRAME_H_ +#define SVO_FRAME_H_ + +#include +#include +#include +#include +#include + +namespace g2o { +class VertexSE3Expmap; +} +typedef g2o::VertexSE3Expmap g2oFrameSE3; + +namespace svo { + +class Point; +struct Feature; + +typedef list Features; +typedef vector ImgPyr; + +/// A frame saves the image, the associated features and the estimated pose. +class Frame : boost::noncopyable +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + static int frame_counter_; //!< Counts the number of created frames. Used to set the unique id. + int id_; //!< Unique id of the frame. + double timestamp_; //!< Timestamp of when the image was recorded. + vk::AbstractCamera* cam_; //!< Camera model. + Sophus::SE3 T_f_w_; //!< Transform (f)rame from (w)orld. + Matrix Cov_; //!< Covariance. + ImgPyr img_pyr_; //!< Image Pyramid. + Features fts_; //!< List of features in the image. + vector key_pts_; //!< Five features and associated 3D points which are used to detect if two frames have overlapping field of view. + bool is_keyframe_; //!< Was this frames selected as keyframe? + g2oFrameSE3* v_kf_; //!< Temporary pointer to the g2o node object of the keyframe. + int last_published_ts_; //!< Timestamp of last publishing. + + Frame(vk::AbstractCamera* cam, const cv::Mat& img, double timestamp); + ~Frame(); + + /// Initialize new frame and create image pyramid. + void initFrame(const cv::Mat& img); + + /// Select this frame as keyframe. + void setKeyframe(); + + /// Add a feature to the image + void addFeature(Feature* ftr); + + /// The KeyPoints are those five features which are closest to the 4 image corners + /// and to the center and which have a 3D point assigned. These points are used + /// to quickly check whether two frames have overlapping field of view. + void setKeyPoints(); + + /// Check if we can select five better key-points. + void checkKeyPoints(Feature* ftr); + + /// If a point is deleted, we must remove the corresponding key-point. + void removeKeyPoint(Feature* ftr); + + /// Return number of point observations. + inline size_t nObs() const { return fts_.size(); } + + /// Check if a point in (w)orld coordinate frame is visible in the image. + bool isVisible(const Vector3d& xyz_w) const; + + /// Full resolution image stored in the frame. + inline const cv::Mat& img() const { return img_pyr_[0]; } + + /// Was this frame selected as keyframe? + inline bool isKeyframe() const { return is_keyframe_; } + + /// Transforms point coordinates in world-frame (w) to camera pixel coordinates (c). + inline Vector2d w2c(const Vector3d& xyz_w) const { return cam_->world2cam( T_f_w_ * xyz_w ); } + + /// Transforms pixel coordinates (c) to frame unit sphere coordinates (f). + inline Vector3d c2f(const Vector2d& px) const { return cam_->cam2world(px[0], px[1]); } + + /// Transforms pixel coordinates (c) to frame unit sphere coordinates (f). + inline Vector3d c2f(const double x, const double y) const { return cam_->cam2world(x, y); } + + /// Transforms point coordinates in world-frame (w) to camera-frams (f). + inline Vector3d w2f(const Vector3d& xyz_w) const { return T_f_w_ * xyz_w; } + + /// Transforms point from frame unit sphere (f) frame to world coordinate frame (w). + inline Vector3d f2w(const Vector3d& f) const { return T_f_w_.inverse() * f; } + + /// Projects Point from unit sphere (f) in camera pixels (c). + inline Vector2d f2c(const Vector3d& f) const { return cam_->world2cam( f ); } + + /// Return the pose of the frame in the (w)orld coordinate frame. + inline Vector3d pos() const { return T_f_w_.inverse().translation(); } + + /// Frame jacobian for projection of 3D point in (f)rame coordinate to + /// unit plane coordinates uv (focal length = 1). + inline static void jacobian_xyz2uv( + const Vector3d& xyz_in_f, + Matrix& J) + { + const double x = xyz_in_f[0]; + const double y = xyz_in_f[1]; + const double z_inv = 1./xyz_in_f[2]; + const double z_inv_2 = z_inv*z_inv; + + J(0,0) = -z_inv; // -1/z + J(0,1) = 0.0; // 0 + J(0,2) = x*z_inv_2; // x/z^2 + J(0,3) = y*J(0,2); // x*y/z^2 + J(0,4) = -(1.0 + x*J(0,2)); // -(1.0 + x^2/z^2) + J(0,5) = y*z_inv; // y/z + + J(1,0) = 0.0; // 0 + J(1,1) = -z_inv; // -1/z + J(1,2) = y*z_inv_2; // y/z^2 + J(1,3) = 1.0 + y*J(1,2); // 1.0 + y^2/z^2 + J(1,4) = -J(0,3); // -x*y/z^2 + J(1,5) = -x*z_inv; // x/z + } +}; + + +/// Some helper functions for the frame object. +namespace frame_utils { + +/// Creates an image pyramid of half-sampled images. +void createImgPyramid(const cv::Mat& img_level_0, int n_levels, ImgPyr& pyr); + +/// Get the average depth of the features in the image. +bool getSceneDepth(const Frame& frame, double& depth_mean, double& depth_min); + +} // namespace frame_utils +} // namespace svo + +#endif // SVO_FRAME_H_ diff --git a/GPU_version/svo/include/svo/frame_handler_base.h b/GPU_version/svo/include/svo/frame_handler_base.h new file mode 100644 index 0000000..9a78639 --- /dev/null +++ b/GPU_version/svo/include/svo/frame_handler_base.h @@ -0,0 +1,123 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FRAME_HANDLER_BASE_H_ +#define SVO_FRAME_HANDLER_BASE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vk +{ +class AbstractCamera; +class PerformanceMonitor; +} + +namespace svo +{ +class Point; +class Matcher; +class DepthFilter; + +/// Base class for various VO pipelines. Manages the map and the state machine. +class FrameHandlerBase : boost::noncopyable +{ +public: + enum Stage { + STAGE_PAUSED, + STAGE_FIRST_FRAME, + STAGE_SECOND_FRAME, + STAGE_DEFAULT_FRAME, + STAGE_RELOCALIZING + }; + enum TrackingQuality { + TRACKING_INSUFFICIENT, + TRACKING_BAD, + TRACKING_GOOD + }; + enum UpdateResult { + RESULT_NO_KEYFRAME, + RESULT_IS_KEYFRAME, + RESULT_FAILURE + }; + + FrameHandlerBase(); + + virtual ~FrameHandlerBase(); + + /// Get the current map. + const Map& map() const { return map_; } + + /// Will reset the map as soon as the current frame is finished processing. + void reset() { set_reset_ = true; } + + /// Start processing. + void start() { set_start_ = true; } + + /// Get the current stage of the algorithm. + Stage stage() const { return stage_; } + + /// Get tracking quality. + TrackingQuality trackingQuality() const { return tracking_quality_; } + + /// Get the processing time of the previous iteration. + double lastProcessingTime() const { return timer_.getTime(); } + + /// Get the number of feature observations of the last frame. + size_t lastNumObservations() const { return num_obs_last_; } + +protected: + Stage stage_; //!< Current stage of the algorithm. + bool set_reset_; //!< Flag that the user can set. Will reset the system before the next iteration. + bool set_start_; //!< Flag the user can set to start the system when the next image is received. + Map map_; //!< Map of keyframes created by the slam system. + vk::Timer timer_; //!< Stopwatch to measure time to process frame. + vk::RingBuffer acc_frame_timings_; //!< Total processing time of the last 10 frames, used to give some user feedback on the performance. + vk::RingBuffer acc_num_obs_; //!< Number of observed features of the last 10 frames, used to give some user feedback on the tracking performance. + size_t num_obs_last_; //!< Number of observations in the previous frame. + TrackingQuality tracking_quality_; //!< An estimate of the tracking quality based on the number of tracked features. + + /// Before a frame is processed, this function is called. + bool startFrameProcessingCommon(const double timestamp); + + /// When a frame is finished processing, this function is called. + int finishFrameProcessingCommon( + const size_t update_id, + const UpdateResult dropout, + const size_t num_observations); + + /// Reset the map and frame handler to start from scratch. + void resetCommon(); + + /// Reset the frame handler. Implement in derived class. + virtual void resetAll() { resetCommon(); } + + /// Set the tracking quality based on the number of tracked features. + virtual void setTrackingQuality(const size_t num_observations); + + /// Optimize some of the observed 3D points. + virtual void optimizeStructure(FramePtr frame, size_t max_n_pts, int max_iter); +}; + +} // namespace nslam + +#endif // SVO_FRAME_HANDLER_BASE_H_ diff --git a/GPU_version/svo/include/svo/frame_handler_mono.h b/GPU_version/svo/include/svo/frame_handler_mono.h new file mode 100644 index 0000000..58789c8 --- /dev/null +++ b/GPU_version/svo/include/svo/frame_handler_mono.h @@ -0,0 +1,104 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_FRAME_HANDLER_H_ +#define SVO_FRAME_HANDLER_H_ + +#include +#include +#include +#include +#include +#include + +namespace svo { + +/// Monocular Visual Odometry Pipeline as described in the SVO paper. +class FrameHandlerMono : public FrameHandlerBase +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + FrameHandlerMono(vk::AbstractCamera* cam,Sophus::SE3& SE_init); + virtual ~FrameHandlerMono(); + + /// Provide an image. + void addImage(const cv::Mat& img, double timestamp); + + /// Set the first frame (used for synthetic datasets in benchmark node) + void setFirstFrame(const FramePtr& first_frame); + + /// Get the last frame that has been processed. + FramePtr lastFrame() { return last_frame_; } + + /// Get the set of spatially closest keyframes of the last frame. + const set& coreKeyframes() { return core_kfs_; } + + /// Return the feature track to visualize the KLT tracking during initialization. + const vector& initFeatureTrackRefPx() const { return klt_homography_init_.px_ref_; } + const vector& initFeatureTrackCurPx() const { return klt_homography_init_.px_cur_; } + + /// Access the depth filter. + DepthFilter* depthFilter() const { return depth_filter_; } + + /// An external place recognition module may know where to relocalize. + bool relocalizeFrameAtPose( + const int keyframe_id, + const SE3& T_kf_f, + const cv::Mat& img, + const double timestamp); + std::unique_ptr imu_integPtr_; //Integration of IMU + +protected: + vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit). + Reprojector reprojector_; //!< Projects points from other keyframes into the current frame + FramePtr new_frame_; //!< Current frame. + FramePtr last_frame_; //!< Last frame, not necessarily a keyframe. + set core_kfs_; //!< Keyframes in the closer neighbourhood. + vector< pair > overlap_kfs_; //!< All keyframes with overlapping field of view. the paired number specifies how many common mappoints are observed TODO: why vector!? + initialization::KltHomographyInit klt_homography_init_; //!< Used to estimate pose of the first two keyframes by estimating a homography. + DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. + + + /// Initialize the visual odometry algorithm. + virtual void initialize(); + + /// Processes the first frame and sets it as a keyframe. + virtual UpdateResult processFirstFrame(); + + /// Processes all frames after the first frame until a keyframe is selected. + virtual UpdateResult processSecondFrame(); + + /// Processes all frames after the first two keyframes. + virtual UpdateResult processFrame(); + + /// Try relocalizing the frame at relative position to provided keyframe. + virtual UpdateResult relocalizeFrame( + const SE3& T_cur_ref, + FramePtr ref_keyframe); + + /// Reset the frame handler. Implement in derived class. + virtual void resetAll(); + + /// Keyframe selection criterion. + virtual bool needNewKf(double scene_depth_mean); + + void setCoreKfs(size_t n_closest); +}; + +} // namespace svo + +#endif // SVO_FRAME_HANDLER_H_ diff --git a/GPU_version/svo/include/svo/global.h b/GPU_version/svo/include/svo/global.h new file mode 100644 index 0000000..03aff4e --- /dev/null +++ b/GPU_version/svo/include/svo/global.h @@ -0,0 +1,101 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_GLOBAL_H_ +#define SVO_GLOBAL_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#ifndef RPG_SVO_VIKIT_IS_VECTOR_SPECIALIZED //Guard for rpg_vikit +#define RPG_SVO_VIKIT_IS_VECTOR_SPECIALIZED +EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector3d) +EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector2d) +#endif + +#ifdef SVO_USE_ROS + #include + #define SVO_DEBUG_STREAM(x) ROS_DEBUG_STREAM(x) + #define SVO_INFO_STREAM(x) ROS_INFO_STREAM(x) + #define SVO_WARN_STREAM(x) ROS_WARN_STREAM(x) + #define SVO_WARN_STREAM_THROTTLE(rate, x) ROS_WARN_STREAM_THROTTLE(rate, x) + #define SVO_ERROR_STREAM(x) ROS_ERROR_STREAM(x) +#else + #define SVO_INFO_STREAM(x) std::cerr<<"\033[0;0m[INFO] "< // Adapted from rosconsole. Copyright (c) 2008, Willow Garage, Inc. + #define SVO_WARN_STREAM_THROTTLE(rate, x) \ + do { \ + static double __log_stream_throttle__last_hit__ = 0.0; \ + std::chrono::time_point __log_stream_throttle__now__ = \ + std::chrono::system_clock::now(); \ + if (__log_stream_throttle__last_hit__ + rate <= \ + std::chrono::duration_cast( \ + __log_stream_throttle__now__.time_since_epoch()).count()) { \ + __log_stream_throttle__last_hit__ = \ + std::chrono::duration_cast( \ + __log_stream_throttle__now__.time_since_epoch()).count(); \ + SVO_WARN_STREAM(x); \ + } \ + } while(0) +#endif + +namespace svo +{ + using namespace Eigen; + using namespace Sophus; + + const double EPS = 0.0000000001; + const double PI = 3.14159265; + +#ifdef SVO_TRACE + extern vk::PerformanceMonitor* g_permon; + #define SVO_LOG(value) g_permon->log(std::string((#value)),(value)) + #define SVO_LOG2(value1, value2) SVO_LOG(value1); SVO_LOG(value2) + #define SVO_LOG3(value1, value2, value3) SVO_LOG2(value1, value2); SVO_LOG(value3) + #define SVO_LOG4(value1, value2, value3, value4) SVO_LOG2(value1, value2); SVO_LOG2(value3, value4) + #define SVO_START_TIMER(name) g_permon->startTimer((name)) + #define SVO_STOP_TIMER(name) g_permon->stopTimer((name)) +#else + #define SVO_LOG(v) + #define SVO_LOG2(v1, v2) + #define SVO_LOG3(v1, v2, v3) + #define SVO_LOG4(v1, v2, v3, v4) + #define SVO_START_TIMER(name) + #define SVO_STOP_TIMER(name) +#endif + + class Frame; + typedef boost::shared_ptr FramePtr; +} // namespace svo + +#endif // SVO_GLOBAL_H_ diff --git a/GPU_version/svo/include/svo/imu_integration.h b/GPU_version/svo/include/svo/imu_integration.h new file mode 100644 index 0000000..11b9055 --- /dev/null +++ b/GPU_version/svo/include/svo/imu_integration.h @@ -0,0 +1,121 @@ +// +// Created by gufe on 4/9/21. +// + +#ifndef SVO_IMU_INTEGRATION_H +#define SVO_IMU_INTEGRATION_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using gtsam::symbol_shorthand::B; // Bias (ax,ay,az,gx,gy,gz) +using gtsam::symbol_shorthand::V; // Vel (xdot,ydot,zdot) +using gtsam::symbol_shorthand::P; // Pose3 (x,y,z,r,p,y) +using gtsam::symbol_shorthand::C; // Camera pose + +//https://stackoverflow.com/questions/24881799/get-index-in-c11-foreach-loop +// Wrapper class +template +class enumerate_impl +{ +public: + // The return value of the operator* of the iterator, this + // is what you will get inside of the for loop + struct item + { + size_t index; + typename T::value_type & item; + }; + typedef item value_type; + + // Custom iterator with minimal interface + struct iterator + { + iterator(typename T::iterator _it, size_t counter=0) : + it(_it), counter(counter) + {} + + iterator operator++() + { + return iterator(++it, ++counter); + } + + bool operator!=(iterator other) + { + return it != other.it; + } + + typename T::iterator::value_type item() + { + return *it; + } + + value_type operator*() + { + return value_type{counter, *it}; + } + + size_t index() + { + return counter; + } + + private: + typename T::iterator it; + size_t counter; + }; + + enumerate_impl(T & t) : container(t) {} + + iterator begin() + { + return iterator(container.begin()); + } + + iterator end() + { + return iterator(container.end()); + } + +private: + T & container; +}; + +// A templated free function allows you to create the wrapper class +// conveniently +template +enumerate_impl enumerate(T & t) +{ + return enumerate_impl(t); +} + +class Imu_Integration{ +public: + Imu_Integration(Sophus::SE3& SE_init); + ~Imu_Integration(); + bool reset(gtsam::ISAM2& optimizer,boost::shared_ptr& new_frame); + bool reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr& new_frame); + bool update(double* imu= nullptr); + bool predict(boost::shared_ptr&,std::size_t&,const double reproj_thresh); +private: + std::shared_ptr statePtr; + std::shared_ptr imu_biasPtr; + std::shared_ptr valuesPtr; + std::shared_ptr graphPtr; + boost::shared_ptr parameterPtr; + std::shared_ptr preintegratedPtr; + boost::shared_ptr ProjectNoisePtr; + std::chrono::steady_clock::time_point t_1; + std::uint32_t imu_factor_id=0; + uint imu_n=0; + std::shared_ptr optimizerParamPtr; + bool syn=false; +}; +#endif //SVO_IMU_INTEGRATION_H diff --git a/GPU_version/svo/include/svo/initialization.h b/GPU_version/svo/include/svo/initialization.h new file mode 100644 index 0000000..cb562e5 --- /dev/null +++ b/GPU_version/svo/include/svo/initialization.h @@ -0,0 +1,83 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_INITIALIZATION_H +#define SVO_INITIALIZATION_H + +#include + +namespace svo { + +class FrameHandlerMono; + +/// Bootstrapping the map from the first two views. +namespace initialization { + +enum InitResult { FAILURE, NO_KEYFRAME, SUCCESS }; + +/// Tracks features using Lucas-Kanade tracker and then estimates a homography. +class KltHomographyInit { + friend class svo::FrameHandlerMono; +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + FramePtr frame_ref_; + KltHomographyInit() {}; + ~KltHomographyInit() {}; + InitResult addFirstFrame(FramePtr frame_ref); + InitResult addSecondFrame(FramePtr frame_ref); + void reset(); + +protected: + vector px_ref_; //!< keypoints to be tracked in reference frame. + vector px_cur_; //!< tracked keypoints in current frame. + vector f_ref_; //!< bearing vectors corresponding to the keypoints in the reference image. + vector f_cur_; //!< bearing vectors corresponding to the keypoints in the current image. + vector disparities_; //!< disparity between first and second frame. + vector inliers_; //!< inliers after the geometric check (e.g., Homography). + vector xyz_in_cur_; //!< 3D points computed during the geometric check. + SE3 T_cur_from_ref_; //!< computed transformation between the first two frames. +}; + +/// Detect Fast corners in the image. +void detectFeatures( + FramePtr frame, + vector& px_vec, + vector& f_vec); + +/// Compute optical flow (Lucas Kanade) for selected keypoints. +void trackKlt( + FramePtr frame_ref, + FramePtr frame_cur, + vector& px_ref, + vector& px_cur, + vector& f_ref, + vector& f_cur, + vector& disparities); + +void computeHomography( + const vector& f_ref, + const vector& f_cur, + double focal_length, + double reprojection_threshold, + vector& inliers, + vector& xyz_in_cur, + SE3& T_cur_from_ref); + +} // namespace initialization +} // namespace svo + +#endif // SVO_INITIALIZATION_H diff --git a/GPU_version/svo/include/svo/map.h b/GPU_version/svo/include/svo/map.h new file mode 100644 index 0000000..458622b --- /dev/null +++ b/GPU_version/svo/include/svo/map.h @@ -0,0 +1,136 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_MAP_H_ +#define SVO_MAP_H_ + +#include +#include +#include +#include + +namespace svo { + +class Point; +class Feature; +class Seed; + +/// Container for converged 3D points that are not already assigned to two keyframes. +class MapPointCandidates +{ +public: + typedef pair PointCandidate; + typedef list PointCandidateList; + + /// The depth-filter is running in a parallel thread and fills the canidate list. + /// This mutex controls concurrent access to point_candidates. + boost::mutex mut_; + + /// Candidate points are created from converged seeds. + /// Until the next keyframe, these points can be used for reprojection and pose optimization. + PointCandidateList candidates_; + list< Point* > trash_points_; + + MapPointCandidates(); + ~MapPointCandidates(); + + /// Add a candidate point. + void newCandidatePoint(Point* point, double depth_sigma2); + + /// Adds the feature to the frame and deletes candidate from list. + void addCandidatePointToFrame(FramePtr frame); + + /// Remove a candidate point from the list of candidates. + bool deleteCandidatePoint(Point* point); + + /// Remove all candidates that belong to a frame. + void removeFrameCandidates(FramePtr frame); + + /// Reset the candidate list, remove and delete all points. + void reset(); + + void deleteCandidate(PointCandidate& c); + + void emptyTrash(); +}; + +/// Map object which saves all keyframes which are in a map. +class Map : boost::noncopyable +{ +public: + list< FramePtr > keyframes_; //!< List of keyframes in the map. + list< Point* > trash_points_; //!< A deleted point is moved to the trash bin. Now and then this is cleaned. One reason is that the visualizer must remove the points also. + MapPointCandidates point_candidates_; + + Map(); + ~Map(); + + /// Reset the map. Delete all keyframes and reset the frame and point counters. + void reset(); + + /// Delete a point in the map and remove all references in keyframes to it. + void safeDeletePoint(Point* pt); + + /// Moves the point to the trash queue which is cleaned now and then. + void deletePoint(Point* pt); + + /// Moves the frame to the trash queue which is cleaned now and then. + bool safeDeleteFrame(FramePtr frame); + + /// Remove the references between a point and a frame. + void removePtFrameRef(Frame* frame, Feature* ftr); + + /// Add a new keyframe to the map. + void addKeyframe(FramePtr new_keyframe); + + /// Given a frame, return all keyframes which have an overlapping field of view. + void getCloseKeyframes(const FramePtr& frame, list< pair >& close_kfs) const; + + /// Return the keyframe which is spatially closest and has overlapping field of view. + FramePtr getClosestKeyframe(const FramePtr& frame) const; + + /// Return the keyframe which is furthest apart from pos. + FramePtr getFurthestKeyframe(const Vector3d& pos) const; + + bool getKeyframeById(const int id, FramePtr& frame) const; + + /// Transform the whole map with rotation R, translation t and scale s. + void transform(const Matrix3d& R, const Vector3d& t, const double& s); + + /// Empty trash bin of deleted keyframes and map points. We don't delete the + /// points immediately to ensure proper cleanup and to provide the visualizer + /// a list of objects which must be removed. + void emptyTrash(); + + /// Return the keyframe which was last inserted in the map. + inline FramePtr lastKeyframe() { return keyframes_.back(); } + + /// Return the number of keyframes in the map + inline size_t size() const { return keyframes_.size(); } +}; + +/// A collection of debug functions to check the data consistency. +namespace map_debug { + +void mapStatistics(Map* map); +void mapValidation(Map* map, int id); +void frameValidation(Frame* frame, int id); +void pointValidation(Point* point, int id); + +} // namespace map_debug +} // namespace svo + +#endif // SVO_MAP_H_ diff --git a/GPU_version/svo/include/svo/matcher.h b/GPU_version/svo/include/svo/matcher.h new file mode 100644 index 0000000..b53340e --- /dev/null +++ b/GPU_version/svo/include/svo/matcher.h @@ -0,0 +1,130 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_MATCHER_H_ +#define SVO_MATCHER_H_ + +#include + +namespace vk { + class AbstractCamera; + namespace patch_score { + template class ZMSSD; + } +} + +namespace svo { + +class Point; +class Frame; +class Feature; + +/// Warp a patch from the reference view to the current view. +namespace warp { + +void getWarpMatrixAffine( + const vk::AbstractCamera& cam_ref, + const vk::AbstractCamera& cam_cur, + const Vector2d& px_ref, + const Vector3d& f_ref, + const double depth_ref, + const SE3& T_cur_ref, + const int level_ref, + Matrix2d& A_cur_ref); + +int getBestSearchLevel( + const Matrix2d& A_cur_ref, + const int max_level); + +void warpAffine( + const Matrix2d& A_cur_ref, + const cv::Mat& img_ref, + const Vector2d& px_ref, + const int level_ref, + const int level_cur, + const int halfpatch_size, + uint8_t* patch); + +} // namespace warp + +/// Patch-matcher for reprojection-matching and epipolar search in triangulation. +class Matcher +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + static const int halfpatch_size_ = 4; + static const int patch_size_ = 8; + + typedef vk::patch_score::ZMSSD PatchScore; + + struct Options + { + bool align_1d; //!< in epipolar search: align patch 1D along epipolar line + int align_max_iter; //!< number of iterations for aligning the feature patches in gauss newton + double max_epi_length_optim;//!< max length of epipolar line to skip epipolar search and directly go to img align + size_t max_epi_search_steps;//!< max number of evaluations along epipolar line + bool subpix_refinement; //!< do gauss newton feature patch alignment after epipolar search + bool epi_search_edgelet_filtering; + double epi_search_edgelet_max_angle; + Options() : + align_1d(false), + align_max_iter(10), + max_epi_length_optim(2.0), + max_epi_search_steps(1000), + subpix_refinement(true), + epi_search_edgelet_filtering(true), + epi_search_edgelet_max_angle(0.7) + {} + } options_; + + uint8_t patch_[patch_size_*patch_size_] __attribute__ ((aligned (16))); + uint8_t patch_with_border_[(patch_size_+2)*(patch_size_+2)] __attribute__ ((aligned (16))); + Matrix2d A_cur_ref_; //!< affine warp matrix + Vector2d epi_dir_; + double epi_length_; //!< length of epipolar line segment in pixels (only used for epipolar search) + double h_inv_; //!< hessian of 1d image alignment along epipolar line + int search_level_; + bool reject_; + Feature* ref_ftr_; + Vector2d px_cur_; + + Matcher() = default; + ~Matcher() = default; + + /// Find a match by directly applying subpix refinement. + /// IMPORTANT! This function assumes that px_cur is already set to an estimate that is within ~2-3 pixel of the final result! + bool findMatchDirect( + const Point& pt, + const Frame& frame, + Vector2d& px_cur); + + /// Find a match by searching along the epipolar line without using any features. + bool findEpipolarMatchDirect( + const Frame& ref_frame, + const Frame& cur_frame, + const Feature& ref_ftr, + const double d_estimate, + const double d_min, + const double d_max, + double& depth); + + void createPatchFromPatchWithBorder(); +}; + +} // namespace svo + +#endif // SVO_MATCHER_H_ diff --git a/GPU_version/svo/include/svo/point.h b/GPU_version/svo/include/svo/point.h new file mode 100644 index 0000000..e1bb81b --- /dev/null +++ b/GPU_version/svo/include/svo/point.h @@ -0,0 +1,108 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_POINT_H_ +#define SVO_POINT_H_ + +#include +#include + +namespace g2o { + class VertexSBAPointXYZ; +} +typedef g2o::VertexSBAPointXYZ g2oPoint; + +namespace svo { + +class Feature; + +typedef Matrix Matrix23d; + +/// A 3D point on the surface of the scene. +class Point : boost::noncopyable +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + enum PointType { + TYPE_DELETED, + TYPE_CANDIDATE, + TYPE_UNKNOWN, + TYPE_GOOD + }; + + static int point_counter_; //!< Counts the number of created points. Used to set the unique id. + int id_; //!< Unique ID of the point. + Vector3d pos_; //!< 3d pos of the point in the world coordinate frame. + Vector3d normal_; //!< Surface normal at point. + Matrix3d normal_information_; //!< Inverse covariance matrix of normal estimation. + bool normal_set_; //!< Flag whether the surface normal was estimated or not. + list obs_; //!< References to keyframes which observe the point. + size_t n_obs_; //!< Number of obervations: Keyframes AND successful reprojections in intermediate frames. + g2oPoint* v_pt_; //!< Temporary pointer to the point-vertex in g2o during bundle adjustment. + int last_published_ts_; //!< Timestamp of last publishing. + int last_projected_kf_id_; //!< Flag for the reprojection: don't reproject a pt twice. + PointType type_; //!< Quality of the point. + int n_failed_reproj_; //!< Number of failed reprojections. Used to assess the quality of the point. + int n_succeeded_reproj_; //!< Number of succeeded reprojections. Used to assess the quality of the point. + int last_structure_optim_; //!< Timestamp of last point optimization + + Point(const Vector3d& pos); + Point(const Vector3d& pos, Feature* ftr); + ~Point(); + + /// Add a reference to a frame. + void addFrameRef(Feature* ftr); + + /// Remove reference to a frame. + bool deleteFrameRef(Frame* frame); + + /// Initialize point normal. The inital estimate will point towards the frame. + void initNormal(); + + /// Check whether mappoint has reference to a frame. + Feature* findFrameRef(Frame* frame); + + /// Get Frame with similar viewpoint. + bool getCloseViewObs(const Vector3d& pos, Feature*& obs) const; + + /// Get number of observations. + inline size_t nRefs() const { return obs_.size(); } + + /// Optimize point position through minimizing the reprojection error. + void optimize(const size_t n_iter); + + /// Jacobian of point projection on unit plane (focal length = 1) in frame (f). + inline static void jacobian_xyz2uv( + const Vector3d& p_in_f, + const Matrix3d& R_f_w, + Matrix23d& point_jac) + { + const double z_inv = 1.0/p_in_f[2]; + const double z_inv_sq = z_inv*z_inv; + point_jac(0, 0) = z_inv; + point_jac(0, 1) = 0.0; + point_jac(0, 2) = -p_in_f[0] * z_inv_sq; + point_jac(1, 0) = 0.0; + point_jac(1, 1) = z_inv; + point_jac(1, 2) = -p_in_f[1] * z_inv_sq; + point_jac = - point_jac * R_f_w; + } +}; + +} // namespace svo + +#endif // SVO_POINT_H_ diff --git a/GPU_version/svo/include/svo/pose_optimizer.h b/GPU_version/svo/include/svo/pose_optimizer.h new file mode 100644 index 0000000..ca048ae --- /dev/null +++ b/GPU_version/svo/include/svo/pose_optimizer.h @@ -0,0 +1,50 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_POSE_OPTIMIZER_H_ +#define SVO_POSE_OPTIMIZER_H_ + +#include + +namespace svo { + +using namespace Eigen; +using namespace Sophus; +using namespace std; + +typedef Matrix Matrix6d; +typedef Matrix Matrix26d; +typedef Matrix Vector6d; + +class Point; + +/// Motion-only bundle adjustment. Minimize the reprojection error of a single frame. +namespace pose_optimizer { + +void optimizeGaussNewton( + const double reproj_thresh, + const size_t n_iter, + const bool verbose, + FramePtr& frame, + double& estimated_scale, + double& error_init, + double& error_final, + size_t& num_obs); + +} // namespace pose_optimizer +} // namespace svo + +#endif // SVO_POSE_OPTIMIZER_H_ diff --git a/GPU_version/svo/include/svo/reprojector.h b/GPU_version/svo/include/svo/reprojector.h new file mode 100644 index 0000000..e345f0d --- /dev/null +++ b/GPU_version/svo/include/svo/reprojector.h @@ -0,0 +1,101 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_REPROJECTION_H_ +#define SVO_REPROJECTION_H_ + +#include +#include + +namespace vk { +class AbstractCamera; +} + +namespace svo { + +class Map; +class Point; + +/// Project points from the map into the image and find the corresponding +/// feature (corner). We don't search a match for every point but only for one +/// point per cell. Thereby, we achieve a homogeneously distributed set of +/// matched features and at the same time we can save processing time by not +/// projecting all points. +class Reprojector +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + /// Reprojector config parameters + struct Options { + size_t max_n_kfs; //!< max number of keyframes to reproject from + bool find_match_direct; + Options() + : max_n_kfs(10), + find_match_direct(true) + {} + } options_; + + size_t n_matches_; + size_t n_trials_; + + Reprojector(vk::AbstractCamera* cam, Map& map); + + ~Reprojector(); + + /// Project points from the map into the image. First finds keyframes with + /// overlapping field of view and projects only those map-points. + void reprojectMap( + FramePtr frame, + std::vector< std::pair >& overlap_kfs); + +private: + + /// A candidate is a point that projects into the image plane and for which we + /// will search a maching feature in the image. + struct Candidate { + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + Point* pt; //!< 3D point. + Vector2d px; //!< projected 2D pixel location. + Candidate(Point* pt, Vector2d& px) : pt(pt), px(px) {} + }; + typedef std::list Cell; + typedef std::vector CandidateGrid; + + /// The grid stores a set of candidate matches. For every grid cell we try to find one match. + struct Grid + { + CandidateGrid cells; + vector cell_order; + int cell_size; + int grid_n_cols; + int grid_n_rows; + }; + + Grid grid_; + Matcher matcher_; + Map& map_; + + static bool pointQualityComparator(Candidate& lhs, Candidate& rhs); + void initializeGrid(vk::AbstractCamera* cam); + void resetGrid(); + bool reprojectCell(Cell& cell, FramePtr frame); + bool reprojectPoint(FramePtr frame, Point* point); +}; + +} // namespace svo + +#endif // SVO_REPROJECTION_H_ diff --git a/GPU_version/svo/include/svo/sparse_img_align.h b/GPU_version/svo/include/svo/sparse_img_align.h new file mode 100644 index 0000000..1bedfed --- /dev/null +++ b/GPU_version/svo/include/svo/sparse_img_align.h @@ -0,0 +1,83 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_SPARSE_IMG_ALIGN_H_ +#define SVO_SPARSE_IMG_ALIGN_H_ + +#include +#include +#include + +namespace vk { +class AbstractCamera; +} + +namespace svo { + +class Feature; + +/// Optimize the pose of the frame by minimizing the photometric error of feature patches. +class SparseImgAlign : public vk::NLLSSolver<6, SE3> +{ + static const int patch_halfsize_ = 2; + static const int patch_size_ = 2*patch_halfsize_; + static const int patch_area_ = patch_size_*patch_size_; +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + cv::Mat resimg_; + + SparseImgAlign( + int n_levels, + int min_level, + int n_iter, + Method method, + bool display, + bool verbose); + + size_t run( + FramePtr ref_frame, + FramePtr cur_frame); + + /// Return fisher information matrix, i.e. the Hessian of the log-likelihood + /// at the converged state. + Matrix getFisherInformation(); + +protected: + FramePtr ref_frame_; //!< reference frame, has depth for gradient pixels. + FramePtr cur_frame_; //!< only the image is known! + int level_; //!< current pyramid level on which the optimization runs. + bool display_; //!< display residual image. + int max_level_; //!< coarsest pyramid level for the alignment. + int min_level_; //!< finest pyramid level for the alignment. + + // cache: + Matrix jacobian_cache_; + bool have_ref_patch_cache_; + cv::Mat ref_patch_cache_; + std::vector visible_fts_; + + void precomputeReferencePatches(); + virtual double computeResiduals(const SE3& model, bool linearize_system, bool compute_weight_scale = false); + virtual int solve(); + virtual void update (const ModelType& old_model, ModelType& new_model); + virtual void startIteration(); + virtual void finishIteration(); +}; + +} // namespace svo + +#endif // SVO_SPARSE_IMG_ALIGN_H_ diff --git a/GPU_version/svo/include/svo/svoVisionFactor.h b/GPU_version/svo/include/svo/svoVisionFactor.h new file mode 100644 index 0000000..cd00816 --- /dev/null +++ b/GPU_version/svo/include/svo/svoVisionFactor.h @@ -0,0 +1,70 @@ +// +// Created by root on 4/13/21. +// + +#ifndef SVO_SVOVISIONFACTOR_H +#define SVO_SVOVISIONFACTOR_H +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + + class VisionFactor: public gtsam::NoiseModelFactor1 { + + private: + // measurement information + gtsam::Point3 feature; /// body_P_sensor_; ///< TODO The pose of the sensor in the body frame + int level; ///< Image pyramid level where feature was extracted. + + public: + /// shorthand for a smart pointer to a factor + typedef boost::shared_ptr shared_ptr; + + /** + * Constructor + * @param feature Unit-bearing vector of the feature. + * @param model is the standard deviation + * @param pointKey is the index of the landmark + * @param poseKey is the index of the camera pose + * @param landmark 3D position of the landmark + * @param body_P_sensor is the transform from body to sensor frame (default identity) + * @param level Image pyramid level where feature was extracted. + */ + VisionFactor(const gtsam::Point3& feature, const gtsam::Point3& landmark,const int level, const gtsam::SharedNoiseModel& Hp, + gtsam::Key poseKey,boost::optional body_P_sensor = boost::none) : + gtsam::NoiseModelFactor1(Hp, poseKey), feature(feature), landmark(landmark),body_P_sensor_(body_P_sensor),level(level){} + virtual ~VisionFactor(){} + + /// error function + /// @param p the Estimated pose in Pose3 + /// @param H the optional Jacobian matrix, which use boost optional and has default null pointer + gtsam::Vector evaluateError(const gtsam::Pose3& p, boost::optional Hp = boost::none) const { + // note that use boost optional like a pointer + // only calculate jacobian matrix when non-null pointer exists + gtsam::Matrix26 J; + gtsam::Point3 point(p*landmark); + svo::Frame::jacobian_xyz2uv(point, J); + Vector2d e = (vk::project2d(feature) - vk::project2d(point))*1.0 / (1<( + gtsam::NonlinearFactor::shared_ptr(new VisionFactor(*this))); } + + }; + +} // namespace gtsamexamples +#endif //SVO_SVOVISIONFACTOR_H diff --git a/GPU_version/svo/package.xml b/GPU_version/svo/package.xml new file mode 100644 index 0000000..8aea0a7 --- /dev/null +++ b/GPU_version/svo/package.xml @@ -0,0 +1,27 @@ + + + gpu_svo + 0.1.0 + + Monocular Visual Odometry + + Christian Forster + Christian Forster + GPLv3 + + + catkin + + + cmake_modules + roscpp + roslib + vikit_common + vikit_ros + + + roscpp + roslib + vikit_common + vikit_ros + \ No newline at end of file diff --git a/GPU_version/svo/src/bundle_adjustment.cpp b/GPU_version/svo/src/bundle_adjustment.cpp new file mode 100644 index 0000000..eaba2b0 --- /dev/null +++ b/GPU_version/svo/src/bundle_adjustment.cpp @@ -0,0 +1,435 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SCHUR_TRICK 1 + +namespace svo { +namespace ba { + +void twoViewBA( + Frame* frame1, + Frame* frame2, + double reproj_thresh, + Map* map) +{ + // scale reprojection threshold in pixels to unit plane + reproj_thresh /= frame1->cam_->errorMultiplier2(); + + // init g2o + g2o::SparseOptimizer optimizer; + setupG2o(&optimizer); + + list edges; + size_t v_id = 0; + + // New Keyframe Vertex 1: This Keyframe is set to fixed! + g2oFrameSE3* v_frame1 = createG2oFrameSE3(frame1, v_id++, true); + optimizer.addVertex(v_frame1); + + // New Keyframe Vertex 2 + g2oFrameSE3* v_frame2 = createG2oFrameSE3(frame2, v_id++, false); + optimizer.addVertex(v_frame2); + + // Create Point Vertices + for(Features::iterator it_ftr=frame1->fts_.begin(); it_ftr!=frame1->fts_.end(); ++it_ftr) + { + Point* pt = (*it_ftr)->point; + if(pt == NULL) + continue; + g2oPoint* v_pt = createG2oPoint(pt->pos_, v_id++, false); + optimizer.addVertex(v_pt); + pt->v_pt_ = v_pt; + g2oEdgeSE3* e = createG2oEdgeSE3(v_frame1, v_pt, vk::project2d((*it_ftr)->f), true, reproj_thresh*Config::lobaRobustHuberWidth()); + optimizer.addEdge(e); + edges.push_back(EdgeContainerSE3(e, frame1, *it_ftr)); // TODO feature now links to frame, so we can simplify edge container! + + // find at which index the second frame observes the point + Feature* ftr_frame2 = pt->findFrameRef(frame2); + e = createG2oEdgeSE3(v_frame2, v_pt, vk::project2d(ftr_frame2->f), true, reproj_thresh*Config::lobaRobustHuberWidth()); + optimizer.addEdge(e); + edges.push_back(EdgeContainerSE3(e, frame2, ftr_frame2)); + } + + // Optimization + double init_error, final_error; + runSparseBAOptimizer(&optimizer, Config::lobaNumIter(), init_error, final_error); + printf("2-View BA: Error before/after = %f / %f\n", init_error, final_error); + + // Update Keyframe Positions + frame1->T_f_w_.rotation_matrix() = v_frame1->estimate().rotation().toRotationMatrix(); + frame1->T_f_w_.translation() = v_frame1->estimate().translation(); + frame2->T_f_w_.rotation_matrix() = v_frame2->estimate().rotation().toRotationMatrix(); + frame2->T_f_w_.translation() = v_frame2->estimate().translation(); + + // Update Mappoint Positions + for(Features::iterator it=frame1->fts_.begin(); it!=frame1->fts_.end(); ++it) + { + if((*it)->point == NULL) + continue; + (*it)->point->pos_ = (*it)->point->v_pt_->estimate(); + (*it)->point->v_pt_ = NULL; + } + + // Find Mappoints with too large reprojection error + const double reproj_thresh_squared = reproj_thresh*reproj_thresh; + size_t n_incorrect_edges = 0; + for(list::iterator it_e = edges.begin(); it_e != edges.end(); ++it_e) + if(it_e->edge->chi2() > reproj_thresh_squared) + { + if(it_e->feature->point != NULL) + { + map->safeDeletePoint(it_e->feature->point); + it_e->feature->point = NULL; + } + ++n_incorrect_edges; + } + + printf("2-View BA: Wrong edges = %zu\n", n_incorrect_edges); +} + +void localBA( + Frame* center_kf, + set* core_kfs, + Map* map, + size_t& n_incorrect_edges_1, + size_t& n_incorrect_edges_2, + double& init_error, + double& final_error) +{ + + // init g2o + g2o::SparseOptimizer optimizer; + setupG2o(&optimizer); + + list edges; + set mps; + list neib_kfs; + size_t v_id = 0; + size_t n_mps = 0; + size_t n_fix_kfs = 0; + size_t n_var_kfs = 1; + size_t n_edges = 0; + n_incorrect_edges_1 = 0; + n_incorrect_edges_2 = 0; + + // Add all core keyframes + for(set::iterator it_kf = core_kfs->begin(); it_kf != core_kfs->end(); ++it_kf) + { + g2oFrameSE3* v_kf = createG2oFrameSE3(it_kf->get(), v_id++, false); + (*it_kf)->v_kf_ = v_kf; + ++n_var_kfs; + assert(optimizer.addVertex(v_kf)); + + // all points that the core keyframes observe are also optimized: + for(Features::iterator it_pt=(*it_kf)->fts_.begin(); it_pt!=(*it_kf)->fts_.end(); ++it_pt) + if((*it_pt)->point != NULL) + mps.insert((*it_pt)->point); + } + + // Now go throug all the points and add a measurement. Add a fixed neighbour + // Keyframe if it is not in the set of core kfs + double reproj_thresh_2 = Config::lobaThresh() / center_kf->cam_->errorMultiplier2(); + double reproj_thresh_1 = Config::poseOptimThresh() / center_kf->cam_->errorMultiplier2(); + double reproj_thresh_1_squared = reproj_thresh_1*reproj_thresh_1; + for(set::iterator it_pt = mps.begin(); it_pt!=mps.end(); ++it_pt) + { + // Create point vertex + g2oPoint* v_pt = createG2oPoint((*it_pt)->pos_, v_id++, false); + (*it_pt)->v_pt_ = v_pt; + assert(optimizer.addVertex(v_pt)); + ++n_mps; + + // Add edges + list::iterator it_obs=(*it_pt)->obs_.begin(); + while(it_obs!=(*it_pt)->obs_.end()) + { + Vector2d error = vk::project2d((*it_obs)->f) - vk::project2d((*it_obs)->frame->w2f((*it_pt)->pos_)); + + if((*it_obs)->frame->v_kf_ == NULL) + { + // frame does not have a vertex yet -> it belongs to the neib kfs and + // is fixed. create one: + g2oFrameSE3* v_kf = createG2oFrameSE3((*it_obs)->frame, v_id++, true); + (*it_obs)->frame->v_kf_ = v_kf; + ++n_fix_kfs; + assert(optimizer.addVertex(v_kf)); + neib_kfs.push_back((*it_obs)->frame); + } + + // create edge + g2oEdgeSE3* e = createG2oEdgeSE3((*it_obs)->frame->v_kf_, v_pt, + vk::project2d((*it_obs)->f), + true, + reproj_thresh_2*Config::lobaRobustHuberWidth(), + 1.0 / (1<<(*it_obs)->level)); + assert(optimizer.addEdge(e)); + edges.push_back(EdgeContainerSE3(e, (*it_obs)->frame, *it_obs)); + ++n_edges; + ++it_obs; + } + } + + // structure only + g2o::StructureOnlySolver<3> structure_only_ba; + g2o::OptimizableGraph::VertexContainer points; + for (g2o::OptimizableGraph::VertexIDMap::const_iterator it = optimizer.vertices().begin(); it != optimizer.vertices().end(); ++it) + { + g2o::OptimizableGraph::Vertex* v = static_cast(it->second); + if (v->dimension() == 3 && v->edges().size() >= 2) + points.push_back(v); + } + structure_only_ba.calc(points, 10); + + // Optimization + if(Config::lobaNumIter() > 0) + runSparseBAOptimizer(&optimizer, Config::lobaNumIter(), init_error, final_error); + + // Update Keyframes + for(set::iterator it = core_kfs->begin(); it != core_kfs->end(); ++it) + { + (*it)->T_f_w_ = SE3( (*it)->v_kf_->estimate().rotation(), + (*it)->v_kf_->estimate().translation()); + (*it)->v_kf_ = NULL; + } + + for(list::iterator it = neib_kfs.begin(); it != neib_kfs.end(); ++it) + (*it)->v_kf_ = NULL; + + // Update Mappoints + for(set::iterator it = mps.begin(); it != mps.end(); ++it) + { + (*it)->pos_ = (*it)->v_pt_->estimate(); + (*it)->v_pt_ = NULL; + } + + // Remove Measurements with too large reprojection error + double reproj_thresh_2_squared = reproj_thresh_2*reproj_thresh_2; + for(list::iterator it = edges.begin(); it != edges.end(); ++it) + { + if(it->edge->chi2() > reproj_thresh_2_squared) //*(1<feature_->level)) + { + map->removePtFrameRef(it->frame, it->feature); + ++n_incorrect_edges_2; + } + } + + // TODO: delete points and edges! + init_error = sqrt(init_error)*center_kf->cam_->errorMultiplier2(); + final_error = sqrt(final_error)*center_kf->cam_->errorMultiplier2(); +} + +void globalBA(Map* map) +{ + // init g2o + g2o::SparseOptimizer optimizer; + setupG2o(&optimizer); + + list edges; + list< pair > incorrect_edges; + + // Go through all Keyframes + size_t v_id = 0; + double reproj_thresh_2 = Config::lobaThresh() / map->lastKeyframe()->cam_->errorMultiplier2(); + double reproj_thresh_1_squared = Config::poseOptimThresh() / map->lastKeyframe()->cam_->errorMultiplier2(); + reproj_thresh_1_squared *= reproj_thresh_1_squared; + for(list::iterator it_kf = map->keyframes_.begin(); + it_kf != map->keyframes_.end(); ++it_kf) + { + // New Keyframe Vertex + g2oFrameSE3* v_kf = createG2oFrameSE3(it_kf->get(), v_id++, false); + (*it_kf)->v_kf_ = v_kf; + optimizer.addVertex(v_kf); + for(Features::iterator it_ftr=(*it_kf)->fts_.begin(); it_ftr!=(*it_kf)->fts_.end(); ++it_ftr) + { + // for each keyframe add edges to all observed mapoints + Point* mp = (*it_ftr)->point; + if(mp == NULL) + continue; + g2oPoint* v_mp = mp->v_pt_; + if(v_mp == NULL) + { + // mappoint-vertex doesn't exist yet. create a new one: + v_mp = createG2oPoint(mp->pos_, v_id++, false); + mp->v_pt_ = v_mp; + optimizer.addVertex(v_mp); + } + + // Due to merging of mappoints it is possible that references in kfs suddenly + // have a very large reprojection error which may result in distorted results. + Vector2d error = vk::project2d((*it_ftr)->f) - vk::project2d((*it_kf)->w2f(mp->pos_)); + if(error.squaredNorm() > reproj_thresh_1_squared) + incorrect_edges.push_back(pair(*it_kf, *it_ftr)); + else + { + g2oEdgeSE3* e = createG2oEdgeSE3(v_kf, v_mp, vk::project2d((*it_ftr)->f), + true, + reproj_thresh_2*Config::lobaRobustHuberWidth()); + + edges.push_back(EdgeContainerSE3(e, it_kf->get(), *it_ftr)); + optimizer.addEdge(e); + } + } + } + + // Optimization + double init_error=0.0, final_error=0.0; + if(Config::lobaNumIter() > 0) + runSparseBAOptimizer(&optimizer, Config::lobaNumIter(), init_error, final_error); + + // Update Keyframe and MapPoint Positions + for(list::iterator it_kf = map->keyframes_.begin(); + it_kf != map->keyframes_.end(); ++it_kf) + { + (*it_kf)->T_f_w_ = SE3( (*it_kf)->v_kf_->estimate().rotation(), + (*it_kf)->v_kf_->estimate().translation()); + (*it_kf)->v_kf_ = NULL; + for(Features::iterator it_ftr=(*it_kf)->fts_.begin(); it_ftr!=(*it_kf)->fts_.end(); ++it_ftr) + { + Point* mp = (*it_ftr)->point; + if(mp == NULL) + continue; + if(mp->v_pt_ == NULL) + continue; // mp was updated before + mp->pos_ = mp->v_pt_->estimate(); + mp->v_pt_ = NULL; + } + } + + // Remove Measurements with too large reprojection error + for(list< pair >::iterator it=incorrect_edges.begin(); + it!=incorrect_edges.end(); ++it) + map->removePtFrameRef(it->first.get(), it->second); + + double reproj_thresh_2_squared = reproj_thresh_2*reproj_thresh_2; + for(list::iterator it = edges.begin(); it != edges.end(); ++it) + { + if(it->edge->chi2() > reproj_thresh_2_squared) + { + map->removePtFrameRef(it->frame, it->feature); + } + } +} + +void setupG2o(g2o::SparseOptimizer * optimizer) +{ + // TODO: What's happening with all this HEAP stuff? Memory Leak? + optimizer->setVerbose(false); + +#if SCHUR_TRICK + // solver + g2o::BlockSolver_6_3::LinearSolverType* linearSolver; + linearSolver = new g2o::LinearSolverCholmod(); + //linearSolver = new g2o::LinearSolverCSparse(); + + g2o::BlockSolver_6_3 * solver_ptr = new g2o::BlockSolver_6_3(linearSolver); + g2o::OptimizationAlgorithmLevenberg * solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr); +#else + g2o::BlockSolverX::LinearSolverType * linearSolver; + linearSolver = new g2o::LinearSolverCholmod(); + //linearSolver = new g2o::LinearSolverCSparse(); + g2o::BlockSolverX * solver_ptr = new g2o::BlockSolverX(linearSolver); + g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr); +#endif + + solver->setMaxTrialsAfterFailure(5); + optimizer->setAlgorithm(solver); + + // setup camera + g2o::CameraParameters * cam_params = new g2o::CameraParameters(1.0, Vector2d(0.,0.), 0.); + cam_params->setId(0); + if (!optimizer->addParameter(cam_params)) { + assert(false); + } +} + +void +runSparseBAOptimizer(g2o::SparseOptimizer* optimizer, + unsigned int num_iter, + double& init_error, double& final_error) +{ + optimizer->initializeOptimization(); + optimizer->computeActiveErrors(); + init_error = optimizer->activeChi2(); + optimizer->optimize(num_iter); + final_error = optimizer->activeChi2(); +} + +g2oFrameSE3* +createG2oFrameSE3(Frame* frame, size_t id, bool fixed) +{ + g2oFrameSE3* v = new g2oFrameSE3(); + v->setId(id); + v->setFixed(fixed); + v->setEstimate(g2o::SE3Quat(frame->T_f_w_.unit_quaternion(), frame->T_f_w_.translation())); + return v; +} + +g2oPoint* +createG2oPoint(Vector3d pos, + size_t id, + bool fixed) +{ + g2oPoint* v = new g2oPoint(); + v->setId(id); +#if SCHUR_TRICK + v->setMarginalized(true); +#endif + v->setFixed(fixed); + v->setEstimate(pos); + return v; +} + +g2oEdgeSE3* +createG2oEdgeSE3( g2oFrameSE3* v_frame, + g2oPoint* v_point, + const Vector2d& f_up, + bool robust_kernel, + double huber_width, + double weight) +{ + g2oEdgeSE3* e = new g2oEdgeSE3(); + e->setVertex(0, dynamic_cast(v_point)); + e->setVertex(1, dynamic_cast(v_frame)); + e->setMeasurement(f_up); + e->information() = weight * Eigen::Matrix2d::Identity(2,2); + g2o::RobustKernelHuber* rk = new g2o::RobustKernelHuber(); // TODO: memory leak + rk->setDelta(huber_width); + e->setRobustKernel(rk); + e->setParameterId(0, 0); //old: e->setId(v_point->id()); + return e; +} + +} // namespace ba +} // namespace svo diff --git a/GPU_version/svo/src/config.cpp b/GPU_version/svo/src/config.cpp new file mode 100644 index 0000000..e8475fe --- /dev/null +++ b/GPU_version/svo/src/config.cpp @@ -0,0 +1,102 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifdef SVO_USE_ROS +#include +#endif +#include + +namespace svo { + +Config::Config() : +#ifdef SVO_USE_ROS + trace_name(vk::getParam("svo/trace_name", "svo")), + trace_dir(vk::getParam("svo/trace_dir", "/tmp")), + n_pyr_levels(vk::getParam("svo/n_pyr_levels", 3)), + use_imu(vk::getParam("svo/use_imu", false)), + core_n_kfs(vk::getParam("svo/core_n_kfs", 3)), + map_scale(vk::getParam("svo/map_scale", 1.0)), + grid_size(vk::getParam("svo/grid_size", 30)), + init_min_disparity(vk::getParam("svo/init_min_disparity", 50.0)), + init_min_tracked(vk::getParam("svo/init_min_tracked", 50)), + init_min_inliers(vk::getParam("svo/init_min_inliers", 40)), + klt_max_level(vk::getParam("svo/klt_max_level", 4)), + klt_min_level(vk::getParam("svo/klt_min_level", 2)), + reproj_thresh(vk::getParam("svo/reproj_thresh", 2.0)), + poseoptim_thresh(vk::getParam("svo/poseoptim_thresh", 2.0)), + poseoptim_num_iter(vk::getParam("svo/poseoptim_num_iter", 10)), + structureoptim_max_pts(vk::getParam("svo/structureoptim_max_pts", 20)), + structureoptim_num_iter(vk::getParam("svo/structureoptim_num_iter", 5)), + loba_thresh(vk::getParam("svo/loba_thresh", 2.0)), + loba_robust_huber_width(vk::getParam("svo/loba_robust_huber_width", 1.0)), + loba_num_iter(vk::getParam("svo/loba_num_iter", 0)), + kfselect_mindist(vk::getParam("svo/kfselect_mindist", 0.12)), + triang_min_corner_score(vk::getParam("svo/triang_min_corner_score", 20.0)), + triang_half_patch_size(vk::getParam("svo/triang_half_patch_size", 4)), + subpix_n_iter(vk::getParam("svo/subpix_n_iter", 10)), + max_n_kfs(vk::getParam("svo/max_n_kfs", 10)), + img_imu_delay(vk::getParam("svo/img_imu_delay", 0.0)), + max_fts(vk::getParam("svo/max_fts", 120)), + quality_min_fts(vk::getParam("svo/quality_min_fts", 50)), + quality_max_drop_fts(vk::getParam("svo/quality_max_drop_fts", 40)), + ACC_noise(vk::getParam("svo/ACC_noise", 1e-4)), + GYO_noise(vk::getParam("svo/GYO_noise", 1e-4)), + iuc(vk::getParam("svo/IUC", 1e-1)), + abc(vk::getParam("svo/ABC", 1e-1)), + gbc(vk::getParam("svo/GBC", 1e-1)), + ebp(vk::getParam("svo/EBP", 1e-2)), + nrp(vk::getParam("svo/NRP", 1e-5)) +#else + trace_name("svo"), + trace_dir("/tmp"), + n_pyr_levels(3), + use_imu(false), + core_n_kfs(3), + map_scale(1.0), + grid_size(25), + init_min_disparity(50.0), + init_min_tracked(50), + init_min_inliers(40), + klt_max_level(4), + klt_min_level(2), + reproj_thresh(2.0), + poseoptim_thresh(2.0), + poseoptim_num_iter(10), + structureoptim_max_pts(20), + structureoptim_num_iter(5), + loba_thresh(2.0), + loba_robust_huber_width(1.0), + loba_num_iter(0), + kfselect_mindist(0.12), + triang_min_corner_score(20.0), + triang_half_patch_size(4), + subpix_n_iter(10), + max_n_kfs(0), + img_imu_delay(0.0), + max_fts(120), + quality_min_fts(50), + quality_max_drop_fts(40) +#endif +{} + +Config& Config::getInstance() +{ + static Config instance; // Instantiated on first use and guaranteed to be destroyed + return instance; +} + +} // namespace svo + diff --git a/GPU_version/svo/src/depth_filter.cpp b/GPU_version/svo/src/depth_filter.cpp new file mode 100644 index 0000000..db24408 --- /dev/null +++ b/GPU_version/svo/src/depth_filter.cpp @@ -0,0 +1,352 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +int Seed::batch_counter = 0; +int Seed::seed_counter = 0; + +Seed::Seed(Feature* ftr, float depth_mean, float depth_min) : + batch_id(batch_counter), + id(seed_counter++), + ftr(ftr), + a(10), + b(10), + mu(1.0/depth_mean), + z_range(1.0/depth_min), + sigma2(z_range*z_range/36) +{} + +DepthFilter::DepthFilter(feature_detection::DetectorPtr feature_detector, callback_t seed_converged_cb) : + feature_detector_(feature_detector), + seed_converged_cb_(seed_converged_cb), + seeds_updating_halt_(false), + thread_(NULL), + new_keyframe_set_(false), + new_keyframe_min_depth_(0.0), + new_keyframe_mean_depth_(0.0) +{} + +DepthFilter::~DepthFilter() +{ + stopThread(); + SVO_INFO_STREAM("DepthFilter destructed."); +} + +void DepthFilter::startThread() +{ + thread_ = new boost::thread(&DepthFilter::updateSeedsLoop, this); +} + +void DepthFilter::stopThread() +{ + SVO_INFO_STREAM("DepthFilter stop thread invoked."); + if(thread_ != NULL) + { + SVO_INFO_STREAM("DepthFilter interrupt and join thread... "); + seeds_updating_halt_ = true; + thread_->interrupt(); + thread_->join(); + thread_ = NULL; + } +} + +void DepthFilter::addFrame(FramePtr frame) +{ + if(thread_ != NULL) + { + { + lock_t lock(frame_queue_mut_); + if(frame_queue_.size() > 2) + frame_queue_.pop(); + frame_queue_.push(frame); + } + seeds_updating_halt_ = false; + frame_queue_cond_.notify_one(); + } + else + updateSeeds(frame); +} + +void DepthFilter::addKeyframe(FramePtr frame, double depth_mean, double depth_min) +{ + new_keyframe_min_depth_ = depth_min; + new_keyframe_mean_depth_ = depth_mean; + if(thread_ != NULL) + { + new_keyframe_ = frame; + new_keyframe_set_ = true; + seeds_updating_halt_ = true; + frame_queue_cond_.notify_one(); + } + else + initializeSeeds(frame); +} + +void DepthFilter::initializeSeeds(FramePtr frame) +{ + Features new_features; + feature_detector_->setExistingFeatures(frame->fts_); + feature_detector_->detect(frame.get(), frame->img_pyr_, + Config::triangMinCornerScore(), new_features); + + // initialize a seed for every new feature + seeds_updating_halt_ = true; + lock_t lock(seeds_mut_); // by locking the updateSeeds function stops + ++Seed::batch_counter; + std::for_each(new_features.begin(), new_features.end(), [&](Feature* ftr){ + seeds_.push_back(Seed(ftr, new_keyframe_mean_depth_, new_keyframe_min_depth_)); + }); + + if(options_.verbose) + SVO_INFO_STREAM("DepthFilter: Initialized "<::iterator it=seeds_.begin(); + size_t n_removed = 0; + while(it!=seeds_.end()) + { + if(it->ftr->frame == frame.get()) + { + it = seeds_.erase(it); + ++n_removed; + } + else + ++it; + } + seeds_updating_halt_ = false; +} + +void DepthFilter::reset() +{ + seeds_updating_halt_ = true; + { + lock_t lock(seeds_mut_); + seeds_.clear(); + } + lock_t lock(); + while(!frame_queue_.empty()) + frame_queue_.pop(); + seeds_updating_halt_ = false; + + if(options_.verbose) + SVO_INFO_STREAM("DepthFilter: RESET."); +} + +void DepthFilter::updateSeedsLoop() +{ + while(!boost::this_thread::interruption_requested()) + { + FramePtr frame; + { + lock_t lock(frame_queue_mut_); + while(frame_queue_.empty() && new_keyframe_set_ == false) + frame_queue_cond_.wait(lock); + if(new_keyframe_set_) + { + new_keyframe_set_ = false; + seeds_updating_halt_ = false; + clearFrameQueue(); + frame = new_keyframe_; + } + else + { + frame = frame_queue_.front(); + frame_queue_.pop(); + } + } + updateSeeds(frame); + if(frame->isKeyframe()) + initializeSeeds(frame); + } +} + +void DepthFilter::updateSeeds(FramePtr frame) +{ + // update only a limited number of seeds, because we don't have time to do it + // for all the seeds in every frame! + size_t n_updates=0, n_failed_matches=0, n_seeds = seeds_.size(); + lock_t lock(seeds_mut_); + std::list::iterator it=seeds_.begin(); + + const double focal_length = frame->cam_->errorMultiplier2(); + double px_noise = 1.0; + double px_error_angle = atan(px_noise/(2.0*focal_length))*2.0; // law of chord (sehnensatz) + + while( it!=seeds_.end()) + { + // set this value true when seeds updating should be interrupted + if(seeds_updating_halt_) + return; + + // check if seed is not already too old + if((Seed::batch_counter - it->batch_id) > options_.max_n_kfs) { + it = seeds_.erase(it); + continue; + } + + // check if point is visible in the current image + SE3 T_ref_cur = it->ftr->frame->T_f_w_ * frame->T_f_w_.inverse(); + const Vector3d xyz_f(T_ref_cur.inverse()*(1.0/it->mu * it->ftr->f) ); + if(xyz_f.z() < 0.0) { + ++it; // behind the camera + continue; + } + if(!frame->cam_->isInFrame(frame->f2c(xyz_f).cast())) { + ++it; // point does not project in image + continue; + } + + // we are using inverse depth coordinates + float z_inv_min = it->mu + sqrt(it->sigma2); + float z_inv_max = max(it->mu - sqrt(it->sigma2), 0.00000001f); + double z; + if(!matcher_.findEpipolarMatchDirect( + *it->ftr->frame, *frame, *it->ftr, 1.0/it->mu, 1.0/z_inv_min, 1.0/z_inv_max, z)) + { + it->b++; // increase outlier probability when no match was found + ++it; + ++n_failed_matches; + continue; + } + + // compute tau + double tau = computeTau(T_ref_cur, it->ftr->f, z, px_error_angle); + double tau_inverse = 0.5 * (1.0/max(0.0000001, z-tau) - 1.0/(z+tau)); + + // update the estimate + updateSeed(1./z, tau_inverse*tau_inverse, &*it); + ++n_updates; + + if(frame->isKeyframe()) + { + // The feature detector should not initialize new seeds close to this location + feature_detector_->setGridOccpuancy(matcher_.px_cur_); + } + + // if the seed has converged, we initialize a new candidate point and remove the seed + if(sqrt(it->sigma2) < it->z_range/options_.seed_convergence_sigma2_thresh) + { + assert(it->ftr->point == NULL); // TODO this should not happen anymore + Vector3d xyz_world(it->ftr->frame->T_f_w_.inverse() * (it->ftr->f * (1.0/it->mu))); + Point* point = new Point(xyz_world, it->ftr); + it->ftr->point = point; + /* FIXME it is not threadsafe to add a feature to the frame here. + if(frame->isKeyframe()) + { + Feature* ftr = new Feature(frame.get(), matcher_.px_cur_, matcher_.search_level_); + ftr->point = point; + point->addFrameRef(ftr); + frame->addFeature(ftr); + it->ftr->frame->addFeature(it->ftr); + } + else + */ + { + seed_converged_cb_(point, it->sigma2); // put in candidate list + } + it = seeds_.erase(it); + } + else if(isnan(z_inv_min)) + { + SVO_WARN_STREAM("z_min is NaN"); + it = seeds_.erase(it); + } + else + ++it; + } +} + +void DepthFilter::clearFrameQueue() +{ + while(!frame_queue_.empty()) + frame_queue_.pop(); +} + +void DepthFilter::getSeedsCopy(const FramePtr& frame, std::list& seeds) +{ + lock_t lock(seeds_mut_); + for(std::list::iterator it=seeds_.begin(); it!=seeds_.end(); ++it) + { + if (it->ftr->frame == frame.get()) + seeds.push_back(*it); + } +} + +void DepthFilter::updateSeed(const float x, const float tau2, Seed* seed) +{ + float norm_scale = sqrt(seed->sigma2 + tau2); + if(std::isnan(norm_scale)) + return; + boost::math::normal_distribution nd(seed->mu, norm_scale); + float s2 = 1./(1./seed->sigma2 + 1./tau2); + float m = s2*(seed->mu/seed->sigma2 + x/tau2); + float C1 = seed->a/(seed->a+seed->b) * boost::math::pdf(nd, x); + float C2 = seed->b/(seed->a+seed->b) * 1./seed->z_range; + float normalization_constant = C1 + C2; + C1 /= normalization_constant; + C2 /= normalization_constant; + float f = C1*(seed->a+1.)/(seed->a+seed->b+1.) + C2*seed->a/(seed->a+seed->b+1.); + float e = C1*(seed->a+1.)*(seed->a+2.)/((seed->a+seed->b+1.)*(seed->a+seed->b+2.)) + + C2*seed->a*(seed->a+1.0f)/((seed->a+seed->b+1.0f)*(seed->a+seed->b+2.0f)); + + // update parameters + float mu_new = C1*m+C2*seed->mu; + seed->sigma2 = C1*(s2 + m*m) + C2*(seed->sigma2 + seed->mu*seed->mu) - mu_new*mu_new; + seed->mu = mu_new; + seed->a = (e-f)/(f-e/f); + seed->b = seed->a*(1.0f-f)/f; +} + +double DepthFilter::computeTau( + const SE3& T_ref_cur, + const Vector3d& f, + const double z, + const double px_error_angle) +{ + Vector3d t(T_ref_cur.translation()); + Vector3d a = f*z-t; + double t_norm = t.norm(); + double a_norm = a.norm(); + double alpha = acos(f.dot(t)/t_norm); // dot product + double beta = acos(a.dot(-t)/(t_norm*a_norm)); // dot product + double beta_plus = beta + px_error_angle; + double gamma_plus = PI-alpha-beta_plus; // triangle angles sum to PI + double z_plus = t_norm*sin(beta_plus)/sin(gamma_plus); // law of sines + return (z_plus - z); // tau +} + +} // namespace svo diff --git a/GPU_version/svo/src/feature_alignment.cpp b/GPU_version/svo/src/feature_alignment.cpp new file mode 100644 index 0000000..faa4027 --- /dev/null +++ b/GPU_version/svo/src/feature_alignment.cpp @@ -0,0 +1,601 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifdef __SSE2__ +#include +#endif +#ifdef __ARM_NEON__ +#include +#endif +#include + +namespace svo { +namespace feature_alignment { + +#define SUBPIX_VERBOSE 0 + +bool align1D( + const cv::Mat& cur_img, + const Vector2f& dir, // direction in which the patch is allowed to move + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate, + double& h_inv) +{ + const int halfpatch_size_ = 4; + const int patch_size = 8; + const int patch_area = 64; + bool converged=false; + + // compute derivative of template and prepare inverse compositional + float __attribute__((__aligned__(16))) ref_patch_dv[patch_area]; + Matrix2f H; H.setZero(); + + // compute gradient and hessian + const int ref_step = patch_size+2; + float* it_dv = ref_patch_dv; + for(int y=0; y= cur_img.cols-halfpatch_size_ || v_r >= cur_img.rows-halfpatch_size_) + break; + + if(isnan(u) || isnan(v)) // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check + return false; + + // compute interpolation weights + float subpix_x = u-u_r; + float subpix_y = v-v_r; + float wTL = (1.0-subpix_x)*(1.0-subpix_y); + float wTR = subpix_x * (1.0-subpix_y); + float wBL = (1.0-subpix_x)*subpix_y; + float wBR = subpix_x * subpix_y; + + // loop through search_patch, interpolate + uint8_t* it_ref = ref_patch; + float* it_ref_dv = ref_patch_dv; + float new_chi2 = 0.0; + Vector2f Jres; Jres.setZero(); + for(int y=0; y 0 && new_chi2 > chi2) + { +#if SUBPIX_VERBOSE + cout << "error increased." << endl; +#endif + u -= update[0]; + v -= update[1]; + break; + } + + chi2 = new_chi2; + update = Hinv * Jres; + u += update[0]*dir[0]; + v += update[0]*dir[1]; + mean_diff += update[1]; + +#if SUBPIX_VERBOSE + cout << "Iter " << iter << ":" + << "\t u=" << u << ", v=" << v + << "\t update = " << update[0] << ", " << update[1] + << "\t new chi2 = " << new_chi2 << endl; +#endif + + if(update[0]*update[0]+update[1]*update[1] < min_update_squared) + { +#if SUBPIX_VERBOSE + cout << "converged." << endl; +#endif + converged=true; + break; + } + } + + cur_px_estimate << u, v; + return converged; +} + +bool align2D( + const cv::Mat& cur_img, + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate, + bool no_simd) +{ +#ifdef __ARM_NEON__ + if(!no_simd) + return align2D_NEON(cur_img, ref_patch_with_border, ref_patch, n_iter, cur_px_estimate); +#endif + + const int halfpatch_size_ = 4; + const int patch_size_ = 8; + const int patch_area_ = 64; + bool converged=false; + + // compute derivative of template and prepare inverse compositional + float __attribute__((__aligned__(16))) ref_patch_dx[patch_area_]; + float __attribute__((__aligned__(16))) ref_patch_dy[patch_area_]; + Matrix3f H; H.setZero(); + + // compute gradient and hessian + const int ref_step = patch_size_+2; + float* it_dx = ref_patch_dx; + float* it_dy = ref_patch_dy; + for(int y=0; y= cur_img.cols-halfpatch_size_ || v_r >= cur_img.rows-halfpatch_size_) + break; + + if(isnan(u) || isnan(v)) // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check + return false; + + // compute interpolation weights + float subpix_x = u-u_r; + float subpix_y = v-v_r; + float wTL = (1.0-subpix_x)*(1.0-subpix_y); + float wTR = subpix_x * (1.0-subpix_y); + float wBL = (1.0-subpix_x)*subpix_y; + float wBR = subpix_x * subpix_y; + + // loop through search_patch, interpolate + uint8_t* it_ref = ref_patch; + float* it_ref_dx = ref_patch_dx; + float* it_ref_dy = ref_patch_dy; +// float new_chi2 = 0.0; + Vector3f Jres; Jres.setZero(); + for(int y=0; y 0 && new_chi2 > chi2) + { +#if SUBPIX_VERBOSE + cout << "error increased." << endl; +#endif + u -= update[0]; + v -= update[1]; + break; + } + chi2 = new_chi2; +*/ + update = Hinv * Jres; + u += update[0]; + v += update[1]; + mean_diff += update[2]; + +#if SUBPIX_VERBOSE + cout << "Iter " << iter << ":" + << "\t u=" << u << ", v=" << v + << "\t update = " << update[0] << ", " << update[1] +// << "\t new chi2 = " << new_chi2 << endl; +#endif + + if(update[0]*update[0]+update[1]*update[1] < min_update_squared) + { +#if SUBPIX_VERBOSE + cout << "converged." << endl; +#endif + converged=true; + break; + } + } + + cur_px_estimate << u, v; + return converged; +} + +#define DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n)) // rounds to closest integer and descales + +bool align2D_SSE2( + const cv::Mat& cur_img, + uint8_t* ref_patch_with_border, + uint8_t* ref_patch, + const int n_iter, + Vector2d& cur_px_estimate) +{ + // TODO: This function should not be used as the alignment is not robust to illumination changes! + const int halfpatch_size = 4; + const int patch_size = 8; + const int patch_area = 64; + bool converged=false; + const int W_BITS = 14; + + // compute derivative of template and prepare inverse compositional + int16_t __attribute__((__aligned__(16))) ref_patch_dx[patch_area]; + int16_t __attribute__((__aligned__(16))) ref_patch_dy[patch_area]; + + // compute gradient and hessian + const int ref_step = patch_size+2; + int16_t* it_dx = ref_patch_dx; + int16_t* it_dy = ref_patch_dy; + float A11=0, A12=0, A22=0; + for(int y=0; y(it[1]) - it[-1]; + int16_t dy = static_cast(it[ref_step]) - it[-ref_step]; + *it_dx = dx; + *it_dy = dy; // we are missing a factor 1/2 + A11 += static_cast(dx*dx); // we are missing a factor 1/4 + A12 += static_cast(dx*dy); + A22 += static_cast(dy*dy); + } + } + + // Compute pixel location in new image: + float u = cur_px_estimate.x(); + float v = cur_px_estimate.y(); + + // termination condition + const float min_update_squared = 0.03*0.03; + const int cur_step = cur_img.step.p[0]; + const float Dinv = 1.0f/(A11*A22 - A12*A12); // we are missing an extra factor 16 + float chi2 = 0; + float update_u = 0, update_v = 0; + + for(int iter = 0; iter= cur_img.cols-halfpatch_size || v_r >= cur_img.rows-halfpatch_size) + break; + + if(isnan(u) || isnan(v)) // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check + return false; + + float subpix_x = u-u_r; + float subpix_y = v-v_r; + float b1=0, b2=0; + float new_chi2 = 0.0; + +#ifdef __SSE2__ + // compute bilinear interpolation weights + int wTL = static_cast((1.0f-subpix_x)*(1.0f-subpix_y)*(1 << W_BITS)); + int wTR = static_cast(subpix_x * (1.0f-subpix_y)*(1 << W_BITS)); + int wBL = static_cast((1.0f-subpix_x)*subpix_y*(1 << W_BITS)); + int wBR = (1 << W_BITS) - wTL - wTR - wBL; + + __m128i qw0 = _mm_set1_epi32(wTL + (wTR << 16)); // Sets the 4 signed 32-bit integer values to [wTL, wTR]. + __m128i qw1 = _mm_set1_epi32(wBL + (wBR << 16)); + __m128i z = _mm_setzero_si128(); + __m128 qb0 = _mm_setzero_ps(); // 4 floats + __m128 qb1 = _mm_setzero_ps(); // 4 floats + __m128i qdelta = _mm_set1_epi32(1 << (W_BITS-1)); + for(int y=0; y(it[1] - it[-1]); + *it_dy = static_cast(it[ref_step] - it[-ref_step]); // divide by 2 missing + Vector3f J(*it_dx, *it_dy, 1.0f); + H += J*J.transpose(); + } + } + Matrix3f Hinv = H.inverse(); + float mean_diff = 0.0; + + // Compute pixel location in new image: + float u = cur_px_estimate.x(); + float v = cur_px_estimate.y(); + + // termination condition + const float min_update_squared = 0.03*0.03; + const int cur_step = cur_img.step.p[0]; + Vector3f update; + Vector3f Jres; + for(int iter = 0; iter= cur_img.cols-halfpatch_size || v_r >= cur_img.rows-halfpatch_size) + break; + + if(isnan(u) || isnan(v)) // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check + return false; + + float subpix_x = u-u_r; + float subpix_y = v-v_r; + float b1=0, b2=0; + +#ifdef __ARM_NEON__ + const int SHIFT_BITS = 7; + const uint16_t wTL = static_cast((1.0f-subpix_x)*(1.0f-subpix_y)*(1<(subpix_x*(1.0f-subpix_y)*(1<((1.0f-subpix_x)*subpix_y*(1<((1 << SHIFT_BITS) - wTL - wTR - wBL); + + // initialize result to zero + int32x4_t vb1 = vdupq_n_s32(0); + int32x4_t vb2 = vdupq_n_s32(0); + int16x8_t vmean_diff = vdupq_n_s16( (int16_t) (mean_diff+0.5) ); + int16x8_t vres_sum = vdupq_n_s16(0); + for(int y=0; y Vr[i] := Va[i] + Vb[i] * Vc[i] + // int32x4_t vmlal_s16(int32x4_t a, int16x4_t b, int16x4_t c); // VMLAL.S16 q0,d0,d0 + int16x8_t grad = vld1q_s16(ref_patch_dx + y*patch_size); + vb1 = vmlal_s16(vb1, vget_low_s16(grad), vget_low_s16(res)); + vb1 = vmlal_s16(vb1, vget_high_s16(grad), vget_high_s16(res)); + + grad = vld1q_s16(ref_patch_dy + y*patch_size); + vb2 = vmlal_s16(vb2, vget_low_s16(grad), vget_low_s16(res)); + vb2 = vmlal_s16(vb2, vget_high_s16(grad), vget_high_s16(res)); + } + + // finally, sum results of vb1, vb2 and vres_sum + int32x2_t tmp; + tmp = vpadd_s32(vget_low_s32(vb1), vget_high_s32(vb1)); + Jres[0] = -vget_lane_s32(tmp, 0) - vget_lane_s32(tmp, 1); + + tmp = vpadd_s32(vget_low_s32(vb2), vget_high_s32(vb2)); + Jres[1] = -vget_lane_s32(tmp, 0) - vget_lane_s32(tmp, 1); + + int32x4_t vres_sum1 = vpaddlq_s16(vres_sum); + tmp = vpadd_s32(vget_low_s32(vres_sum1), vget_high_s32(vres_sum1)); + Jres[2] = -vget_lane_s32(tmp, 0) - vget_lane_s32(tmp, 1); +#endif + + update = Hinv * Jres * 2; // * 2 to compensate because above, we did not compute the derivative correctly + u += update[0]; + v += update[1]; + mean_diff += update[2]; + +#if SUBPIX_VERBOSE + cout << "Iter " << iter << ":" + << "\t u=" << u << ", v=" << v + << "\t update = " << update[0] << ", " << update[1] << endl; +#endif + + if(update[0]*update[0]+update[1]*update[1] < min_update_squared) + { +#if SUBPIX_VERBOSE + cout << "converged." << endl; +#endif + converged=true; + break; + } + } + + cur_px_estimate << u, v; + return converged; +} + +} // namespace feature_alignment +} // namespace svo diff --git a/GPU_version/svo/src/feature_detection.cpp b/GPU_version/svo/src/feature_detection.cpp new file mode 100644 index 0000000..98183f8 --- /dev/null +++ b/GPU_version/svo/src/feature_detection.cpp @@ -0,0 +1,118 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include + +namespace svo { +namespace feature_detection { + +AbstractDetector::AbstractDetector( + const int img_width, + const int img_height, + const int cell_size, + const int n_pyr_levels) : + cell_size_(cell_size), + n_pyr_levels_(n_pyr_levels), + grid_n_cols_(ceil(static_cast(img_width)/cell_size_)), + grid_n_rows_(ceil(static_cast(img_height)/cell_size_)), + grid_occupancy_(grid_n_cols_*grid_n_rows_, false) +{} + +void AbstractDetector::resetGrid() +{ + std::fill(grid_occupancy_.begin(), grid_occupancy_.end(), false); +} + +void AbstractDetector::setExistingFeatures(const Features& fts) +{ + std::for_each(fts.begin(), fts.end(), [&](Feature* i){ + grid_occupancy_.at( + static_cast(i->px[1]/cell_size_)*grid_n_cols_ + + static_cast(i->px[0]/cell_size_)) = true; + }); +} + +void AbstractDetector::setGridOccpuancy(const Vector2d& px) +{ + grid_occupancy_.at( + static_cast(px[1]/cell_size_)*grid_n_cols_ + + static_cast(px[0]/cell_size_)) = true; +} + +FastDetector::FastDetector( + const int img_width, + const int img_height, + const int cell_size, + const int n_pyr_levels) : + AbstractDetector(img_width, img_height, cell_size, n_pyr_levels) +{} + +void FastDetector::detect( + Frame* frame, + const ImgPyr& img_pyr, + const double detection_threshold, + Features& fts) +{ + Corners corners(grid_n_cols_*grid_n_rows_, Corner(0,0,detection_threshold,0,0.0f)); + for(int L=0; L fast_corners; +#if __SSE2__ + fast::fast_corner_detect_10_sse2( + (fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, + img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); +#elif HAVE_FAST_NEON + fast::fast_corner_detect_9_neon( + (fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, + img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); +#else + fast::fast_corner_detect_10( + (fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, + img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); +#endif + vector scores, nm_corners; + fast::fast_corner_score_10((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, fast_corners, 20, scores); + fast::fast_nonmax_3x3(fast_corners, scores, nm_corners); + + for(auto it=nm_corners.begin(), ite=nm_corners.end(); it!=ite; ++it) + { + fast::fast_xy& xy = fast_corners.at(*it); + const int k = static_cast((xy.y*scale)/cell_size_)*grid_n_cols_ + + static_cast((xy.x*scale)/cell_size_); + if(grid_occupancy_[k]) + continue; + const float score = vk::shiTomasiScore(img_pyr[L], xy.x, xy.y); + if(score > corners.at(k).score) + corners.at(k) = Corner(xy.x*scale, xy.y*scale, score, L, 0.0f); + } + } + + // Create feature for every corner that has high enough corner score + std::for_each(corners.begin(), corners.end(), [&](Corner& c) { + if(c.score > detection_threshold) + fts.push_back(new Feature(frame, Vector2d(c.x, c.y), c.level)); + }); + + resetGrid(); +} + +} // namespace feature_detection +} // namespace svo + diff --git a/GPU_version/svo/src/frame.cpp b/GPU_version/svo/src/frame.cpp new file mode 100644 index 0000000..44ddab6 --- /dev/null +++ b/GPU_version/svo/src/frame.cpp @@ -0,0 +1,190 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +int Frame::frame_counter_ = 0; + +Frame::Frame(vk::AbstractCamera* cam, const cv::Mat& img, double timestamp) : + id_(frame_counter_++), + timestamp_(timestamp), + cam_(cam), + key_pts_(5), + is_keyframe_(false), + v_kf_(NULL) +{ + initFrame(img); +} + +Frame::~Frame() +{ + std::for_each(fts_.begin(), fts_.end(), [&](Feature* i){delete i;}); +} + +void Frame::initFrame(const cv::Mat& img) +{ + // check image + if(img.empty() || img.type() != CV_8UC1 || img.cols != cam_->width() || img.rows != cam_->height()) + throw std::runtime_error("Frame: provided image has not the same size as the camera model or image is not grayscale"); + + // Set keypoints to NULL + std::for_each(key_pts_.begin(), key_pts_.end(), [&](Feature* ftr){ ftr=NULL; }); + + // Build Image Pyramid + frame_utils::createImgPyramid(img, max(Config::nPyrLevels(), Config::kltMaxLevel()+1), img_pyr_); +} + +void Frame::setKeyframe() +{ + is_keyframe_ = true; + setKeyPoints(); +} + +void Frame::addFeature(Feature* ftr) +{ + fts_.push_back(ftr); +} + +void Frame::setKeyPoints() +{ + for(size_t i = 0; i < 5; ++i) + if(key_pts_[i] != NULL) + if(key_pts_[i]->point == NULL) + key_pts_[i] = NULL; + + std::for_each(fts_.begin(), fts_.end(), [&](Feature* ftr){ if(ftr->point != NULL) checkKeyPoints(ftr); }); +} + +void Frame::checkKeyPoints(Feature* ftr) +{ + const int cu = cam_->width()/2; + const int cv = cam_->height()/2; + + // center pixel + if(key_pts_[0] == NULL) + key_pts_[0] = ftr; + else if(std::max(std::fabs(ftr->px[0]-cu), std::fabs(ftr->px[1]-cv)) + < std::max(std::fabs(key_pts_[0]->px[0]-cu), std::fabs(key_pts_[0]->px[1]-cv))) + key_pts_[0] = ftr; + + if(ftr->px[0] >= cu && ftr->px[1] >= cv) + { + if(key_pts_[1] == NULL) + key_pts_[1] = ftr; + else if((ftr->px[0]-cu) * (ftr->px[1]-cv) + > (key_pts_[1]->px[0]-cu) * (key_pts_[1]->px[1]-cv)) + key_pts_[1] = ftr; + } + if(ftr->px[0] >= cu && ftr->px[1] < cv) + { + if(key_pts_[2] == NULL) + key_pts_[2] = ftr; + else if((ftr->px[0]-cu) * (ftr->px[1]-cv) + > (key_pts_[2]->px[0]-cu) * (key_pts_[2]->px[1]-cv)) + key_pts_[2] = ftr; + } + if(ftr->px[0] < cv && ftr->px[1] < cv) + { + if(key_pts_[3] == NULL) + key_pts_[3] = ftr; + else if((ftr->px[0]-cu) * (ftr->px[1]-cv) + > (key_pts_[3]->px[0]-cu) * (key_pts_[3]->px[1]-cv)) + key_pts_[3] = ftr; + } + if(ftr->px[0] < cv && ftr->px[1] >= cv) + { + if(key_pts_[4] == NULL) + key_pts_[4] = ftr; + else if((ftr->px[0]-cu) * (ftr->px[1]-cv) + > (key_pts_[4]->px[0]-cu) * (key_pts_[4]->px[1]-cv)) + key_pts_[4] = ftr; + } +} + +void Frame::removeKeyPoint(Feature* ftr) +{ + bool found = false; + std::for_each(key_pts_.begin(), key_pts_.end(), [&](Feature*& i){ + if(i == ftr) { + i = NULL; + found = true; + } + }); + if(found) + setKeyPoints(); +} + +bool Frame::isVisible(const Vector3d& xyz_w) const +{ + Vector3d xyz_f = T_f_w_*xyz_w; + if(xyz_f.z() < 0.0) + return false; // point is behind the camera + Vector2d px = f2c(xyz_f); + if(px[0] >= 0.0 && px[1] >= 0.0 && px[0] < cam_->width() && px[1] < cam_->height()) + return true; + return false; +} + + +/// Utility functions for the Frame class +namespace frame_utils { + +void createImgPyramid(const cv::Mat& img_level_0, int n_levels, ImgPyr& pyr) +{ + pyr.resize(n_levels); + pyr[0] = img_level_0; + for(int i=1; i depth_vec; + depth_vec.reserve(frame.fts_.size()); + depth_min = std::numeric_limits::max(); + for(auto it=frame.fts_.begin(), ite=frame.fts_.end(); it!=ite; ++it) + { + if((*it)->point != NULL) + { + const double z = frame.w2f((*it)->point->pos_).z(); + depth_vec.push_back(z); + depth_min = fmin(z, depth_min); + } + } + if(depth_vec.empty()) + { + SVO_WARN_STREAM("Cannot set scene depth. Frame has no point-observations!"); + return false; + } + depth_mean = vk::getMedian(depth_vec); + return true; +} + +} // namespace frame_utils +} // namespace svo diff --git a/GPU_version/svo/src/frame_handler_base.cpp b/GPU_version/svo/src/frame_handler_base.cpp new file mode 100644 index 0000000..175ee01 --- /dev/null +++ b/GPU_version/svo/src/frame_handler_base.cpp @@ -0,0 +1,199 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo +{ + +// definition of global and static variables which were declared in the header +#ifdef SVO_TRACE +vk::PerformanceMonitor* g_permon = NULL; +#endif + +FrameHandlerBase::FrameHandlerBase() : + stage_(STAGE_PAUSED), + set_reset_(false), + set_start_(false), + acc_frame_timings_(10), + acc_num_obs_(10), + num_obs_last_(0), + tracking_quality_(TRACKING_INSUFFICIENT) +{ +#ifdef SVO_TRACE + // Initialize Performance Monitor + g_permon = new vk::PerformanceMonitor(); + g_permon->addTimer("pyramid_creation"); + g_permon->addTimer("sparse_img_align"); + g_permon->addTimer("reproject"); + g_permon->addTimer("reproject_kfs"); + g_permon->addTimer("reproject_candidates"); + g_permon->addTimer("feature_align"); + g_permon->addTimer("pose_optimizer"); + g_permon->addTimer("point_optimizer"); + g_permon->addTimer("local_ba"); + g_permon->addTimer("tot_time"); + g_permon->addLog("timestamp"); + g_permon->addLog("img_align_n_tracked"); + g_permon->addLog("repr_n_mps"); + g_permon->addLog("repr_n_new_references"); + g_permon->addLog("sfba_thresh"); + g_permon->addLog("sfba_error_init"); + g_permon->addLog("sfba_error_final"); + g_permon->addLog("sfba_n_edges_final"); + g_permon->addLog("loba_n_erredges_init"); + g_permon->addLog("loba_n_erredges_fin"); + g_permon->addLog("loba_err_init"); + g_permon->addLog("loba_err_fin"); + g_permon->addLog("n_candidates"); + g_permon->addLog("dropout"); + g_permon->init(Config::traceName(), Config::traceDir()); +#endif + + SVO_INFO_STREAM("SVO initialized"); +} + +FrameHandlerBase::~FrameHandlerBase() +{ + SVO_INFO_STREAM("SVO destructor invoked"); +#ifdef SVO_TRACE + delete g_permon; +#endif +} + +bool FrameHandlerBase::startFrameProcessingCommon(const double timestamp) +{ + if(set_start_) + { + resetAll(); + stage_ = STAGE_FIRST_FRAME; + } + + if(stage_ == STAGE_PAUSED) + return false; + + SVO_LOG(timestamp); + SVO_DEBUG_STREAM("New Frame"); + SVO_START_TIMER("tot_time"); + timer_.start(); + + // some cleanup from last iteration, can't do before because of visualization + map_.emptyTrash(); + return true; +} + +int FrameHandlerBase::finishFrameProcessingCommon( + const size_t update_id, + const UpdateResult dropout, + const size_t num_observations) +{ + SVO_DEBUG_STREAM("Frame: "<writeToFile(); + { + boost::unique_lock lock(map_.point_candidates_.mut_); + size_t n_candidates = map_.point_candidates_.candidates_.size(); + SVO_LOG(n_candidates); + } +#endif + + if(dropout == RESULT_FAILURE && + (stage_ == STAGE_DEFAULT_FRAME || stage_ == STAGE_RELOCALIZING )) + { + stage_ = STAGE_RELOCALIZING; + tracking_quality_ = TRACKING_INSUFFICIENT; + } + else if (dropout == RESULT_FAILURE) + resetAll(); + if(set_reset_) + resetAll(); + + return 0; +} + +void FrameHandlerBase::resetCommon() +{ + map_.reset(); + stage_ = STAGE_PAUSED; + set_reset_ = false; + set_start_ = false; + tracking_quality_ = TRACKING_INSUFFICIENT; + num_obs_last_ = 0; + SVO_INFO_STREAM("RESET"); +} + +void FrameHandlerBase::setTrackingQuality(const size_t num_observations) +{ + tracking_quality_ = TRACKING_GOOD; + if(num_observations < Config::qualityMinFts()) + { + SVO_WARN_STREAM_THROTTLE(0.5, "Tracking less than "<< Config::qualityMinFts() <<" features!"); + tracking_quality_ = TRACKING_INSUFFICIENT; + } + const int feature_drop = static_cast(std::min(num_obs_last_, Config::maxFts())) - num_observations; + if(feature_drop > Config::qualityMaxFtsDrop()) + { + SVO_WARN_STREAM("Lost "<< feature_drop <<" features!"); + tracking_quality_ = TRACKING_INSUFFICIENT; + } +} + +bool ptLastOptimComparator(Point* lhs, Point* rhs) +{ + return (lhs->last_structure_optim_ < rhs->last_structure_optim_); +} + +void FrameHandlerBase::optimizeStructure( + FramePtr frame, + size_t max_n_pts, + int max_iter) +{ + deque pts; + for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point != NULL) + pts.push_back((*it)->point); + } + max_n_pts = min(max_n_pts, pts.size()); + nth_element(pts.begin(), pts.begin() + max_n_pts, pts.end(), ptLastOptimComparator); + for(deque::iterator it=pts.begin(); it!=pts.begin()+max_n_pts; ++it) + { + (*it)->optimize(max_iter); + (*it)->last_structure_optim_ = frame->id_; + } +} + + +} // namespace svo diff --git a/GPU_version/svo/src/frame_handler_mono.cpp b/GPU_version/svo/src/frame_handler_mono.cpp new file mode 100644 index 0000000..799cb8c --- /dev/null +++ b/GPU_version/svo/src/frame_handler_mono.cpp @@ -0,0 +1,307 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef USE_BUNDLE_ADJUSTMENT +#include +#endif + +namespace svo { + +FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam,Sophus::SE3& SE_init) : + FrameHandlerBase(), + cam_(cam), + reprojector_(cam_, map_), + depth_filter_(NULL) +{ + initialize(); + imu_integPtr_=std::make_unique(SE_init); +} + +void FrameHandlerMono::initialize() +{ + feature_detection::DetectorPtr feature_detector( + new feature_detection::FastDetector( + cam_->width(), cam_->height(), Config::gridSize(), Config::nPyrLevels())); + DepthFilter::callback_t depth_filter_cb = boost::bind( + &MapPointCandidates::newCandidatePoint, &map_.point_candidates_, _1, _2); + depth_filter_ = new DepthFilter(feature_detector, depth_filter_cb); + depth_filter_->startThread(); +} + +FrameHandlerMono::~FrameHandlerMono() +{ + delete depth_filter_; +} + +void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) +{ + if(!startFrameProcessingCommon(timestamp)) + return; + + // some cleanup from last iteration, can't do before because of visualization + core_kfs_.clear(); + overlap_kfs_.clear(); + + // create new frame + new_frame_.reset(new Frame(cam_, img.clone(), timestamp)); + + // process frame + UpdateResult res = RESULT_FAILURE; + if(stage_ == STAGE_DEFAULT_FRAME) + res = processFrame(); + else if(stage_ == STAGE_SECOND_FRAME) + res = processSecondFrame(); + else if(stage_ == STAGE_FIRST_FRAME) + res = processFirstFrame(); + else if(stage_ == STAGE_RELOCALIZING) + res = relocalizeFrame(SE3(Matrix3d::Identity(), Vector3d::Zero()), + map_.getClosestKeyframe(last_frame_)); + + // set last frame + last_frame_ = new_frame_; + new_frame_.reset(); + // finish processing + finishFrameProcessingCommon(last_frame_->id_, res, last_frame_->nObs()); +} + +FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() +{ + new_frame_->T_f_w_ = SE3(Matrix3d::Identity(), Vector3d::Zero()); + if(klt_homography_init_.addFirstFrame(new_frame_) == initialization::FAILURE) + return RESULT_NO_KEYFRAME; + new_frame_->setKeyframe(); + map_.addKeyframe(new_frame_); + stage_ = STAGE_SECOND_FRAME; + SVO_INFO_STREAM("Init: Selected first frame."); + return RESULT_IS_KEYFRAME; +} + +FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() +{ + initialization::InitResult res = klt_homography_init_.addSecondFrame(new_frame_); + if(res == initialization::FAILURE) + return RESULT_FAILURE; + else if(res == initialization::NO_KEYFRAME) + return RESULT_NO_KEYFRAME; + + // two-frame bundle adjustment +#ifdef USE_BUNDLE_ADJUSTMENT + ba::twoViewBA(new_frame_.get(), map_.lastKeyframe().get(), Config::lobaThresh(), &map_); +#endif + + new_frame_->setKeyframe(); + double depth_mean, depth_min; + frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); + depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min); + + // add frame to map + map_.addKeyframe(new_frame_); + stage_ = STAGE_DEFAULT_FRAME; + klt_homography_init_.reset(); + SVO_INFO_STREAM("Init: Selected second frame, triangulated initial map."); + return RESULT_IS_KEYFRAME; +} + +FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() +{ + // Set initial pose TODO use prior + new_frame_->T_f_w_ = last_frame_->T_f_w_; + + // sparse image align + SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), + 30, SparseImgAlign::GaussNewton, false, false); + img_align.run(last_frame_, new_frame_); + // map reprojection & feature alignment + reprojector_.reprojectMap(new_frame_, overlap_kfs_); + std::cerr<<"Reprojection Map:\t nPoints = "<T_f_w_ = last_frame_->T_f_w_; // reset to avoid crazy pose jumps + tracking_quality_ = TRACKING_INSUFFICIENT; + return RESULT_FAILURE; + } + + // pose optimization subject to change for adding IMU + size_t sfba_n_edges_final; + if(!imu_integPtr_->predict(new_frame_,sfba_n_edges_final,Config::poseOptimThresh())) + return RESULT_FAILURE; + + + std::cerr<<"Reprojected points after opmization: "<T_f_w_ = last_frame_->T_f_w_; // reset to avoid crazy pose jumps + return RESULT_FAILURE; + } + double depth_mean, depth_min; + frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); + if(!needNewKf(depth_mean) || tracking_quality_ == TRACKING_BAD) + { + depth_filter_->addFrame(new_frame_); + return RESULT_NO_KEYFRAME; + } + new_frame_->setKeyframe(); + + // new keyframe selected + for(Features::iterator it=new_frame_->fts_.begin(); it!=new_frame_->fts_.end(); ++it) + if((*it)->point != NULL) + (*it)->point->addFrameRef(*it); + map_.point_candidates_.addCandidatePointToFrame(new_frame_); + + // optional bundle adjustment +#ifdef USE_BUNDLE_ADJUSTMENT + if(Config::lobaNumIter() > 0) + { + SVO_START_TIMER("local_ba"); + setCoreKfs(Config::coreNKfs()); + size_t loba_n_erredges_init, loba_n_erredges_fin; + double loba_err_init, loba_err_fin; + ba::localBA(new_frame_.get(), &core_kfs_, &map_, + loba_n_erredges_init, loba_n_erredges_fin, + loba_err_init, loba_err_fin); + SVO_STOP_TIMER("local_ba"); + SVO_LOG4(loba_n_erredges_init, loba_n_erredges_fin, loba_err_init, loba_err_fin); + SVO_DEBUG_STREAM("Local BA:\t RemovedEdges {"<addKeyframe(new_frame_, depth_mean, 0.5*depth_min); + + // if limited number of keyframes, remove the one furthest apart + if(Config::maxNKfs() > 2 && map_.size() >= Config::maxNKfs()) + { + FramePtr furthest_frame = map_.getFurthestKeyframe(new_frame_->pos()); + depth_filter_->removeKeyframe(furthest_frame); // TODO this interrupts the mapper thread, maybe we can solve this better + map_.safeDeleteFrame(furthest_frame); + } + + // add keyframe to map + map_.addKeyframe(new_frame_); + std::cerr<<"Svo pipline was finished\n"; + return RESULT_IS_KEYFRAME; +} + +FrameHandlerMono::UpdateResult FrameHandlerMono::relocalizeFrame( + const SE3& T_cur_ref, + FramePtr ref_keyframe) +{ + if(ref_keyframe == nullptr) + { + return RESULT_FAILURE; + } + SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), + 30, SparseImgAlign::GaussNewton, false, false); + size_t img_align_n_tracked = img_align.run(ref_keyframe, new_frame_); + usleep(2000); + if(img_align_n_tracked > Config::qualityMinFts()) + { + SE3 T_f_w_last = last_frame_->T_f_w_; + last_frame_ = ref_keyframe; + FrameHandlerMono::UpdateResult res = processFrame(); + if(res != RESULT_FAILURE) + { + stage_ = STAGE_DEFAULT_FRAME; + } + else + new_frame_->T_f_w_ = T_f_w_last; // reset to last well localized pose + return res; + } + return RESULT_FAILURE; +} + +bool FrameHandlerMono::relocalizeFrameAtPose( + const int keyframe_id, + const SE3& T_f_kf, + const cv::Mat& img, + const double timestamp) +{ + FramePtr ref_keyframe; + if(!map_.getKeyframeById(keyframe_id, ref_keyframe)) + return false; + new_frame_.reset(new Frame(cam_, img.clone(), timestamp)); + UpdateResult res = relocalizeFrame(T_f_kf, ref_keyframe); + if(res != RESULT_FAILURE) { + last_frame_ = new_frame_; + return true; + } + return false; +} + +void FrameHandlerMono::resetAll() +{ + resetCommon(); + last_frame_.reset(); + new_frame_.reset(); + core_kfs_.clear(); + overlap_kfs_.clear(); + depth_filter_->reset(); +} + +void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame) +{ + resetAll(); + last_frame_ = first_frame; + last_frame_->setKeyframe(); + map_.addKeyframe(last_frame_); + stage_ = STAGE_DEFAULT_FRAME; +} + +bool FrameHandlerMono::needNewKf(double scene_depth_mean) +{ + for(auto it=overlap_kfs_.begin(), ite=overlap_kfs_.end(); it!=ite; ++it) + { + Vector3d relpos = new_frame_->w2f(it->first->pos()); + if(fabs(relpos.x())/scene_depth_mean < Config::kfSelectMinDist() && + fabs(relpos.y())/scene_depth_mean < Config::kfSelectMinDist()*0.8 && + fabs(relpos.z())/scene_depth_mean < Config::kfSelectMinDist()*1.3) + return false; + } + return true; +} + +void FrameHandlerMono::setCoreKfs(size_t n_closest) +{ + size_t n = min(n_closest, overlap_kfs_.size()-1); + std::partial_sort(overlap_kfs_.begin(), overlap_kfs_.begin()+n, overlap_kfs_.end(), + boost::bind(&pair::second, _1) > + boost::bind(&pair::second, _2)); + std::for_each(overlap_kfs_.begin(), overlap_kfs_.end(), [&](pair& i){ core_kfs_.insert(i.first); }); +} + +} // namespace svo diff --git a/GPU_version/svo/src/imu_integration.cpp b/GPU_version/svo/src/imu_integration.cpp new file mode 100644 index 0000000..c2a720f --- /dev/null +++ b/GPU_version/svo/src/imu_integration.cpp @@ -0,0 +1,151 @@ +// +// Created by gfuse on 4/9/21. +// +//#define NDEBUG +#include "svo/imu_integration.h" +#include +#include +#include "svo/feature.h" +#include "svo/point.h" +#include "svo/svoVisionFactor.h" +#include +#include +#include +#include + +Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ + graphPtr=std::make_shared(); + valuesPtr=std::make_shared(); + parameterPtr = gtsam::PreintegratedCombinedMeasurements::Params::MakeSharedD();// TODO check the IMU frame + parameterPtr->accelerometerCovariance=gtsam::I_3x3 * svo::Config::ACC_Noise(); // acc white noise in continuous + parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * svo::Config::GYO_Noise();// gyro white noise in continuous + parameterPtr->integrationCovariance=gtsam::I_3x3 * svo::Config::IUC(); // integration uncertainty continuous + parameterPtr->biasAccCovariance = gtsam::I_3x3 * svo::Config::ABC(); // acc bias in continuous + parameterPtr->biasOmegaCovariance = gtsam::I_3x3 * svo::Config::GBC(); // gyro bias in continuous + parameterPtr->biasAccOmegaInt = gtsam::I_6x6 * svo::Config::EBP(); // error in the bias used for preintegration + imu_biasPtr=std::make_shared(gtsam::Vector3(1e-8,1e-8,1e-8),gtsam::Vector3(1e-8,1e-8,1e-8)); + preintegratedPtr = std::make_shared(parameterPtr,*imu_biasPtr); + ProjectNoisePtr = gtsam::noiseModel::Isotropic::Sigma(2, svo::Config::NRP()); // the noise used for projection + optimizerParamPtr=std::make_shared(); + optimizerParamPtr->relinearizeThreshold = 0.1; + optimizerParamPtr->relinearizeSkip = 1; + //optimizerParamPtr->evaluateNonlinearError=true; + assert(preintegratedPtr); +} +Imu_Integration::~Imu_Integration(){ + +} +bool Imu_Integration::update(double* imu){ + if(syn)return false; + if(imu_factor_id<1)return false; + auto in=std::chrono::steady_clock::now(); + if(std::chrono::duration(in-t_1).count()>20.0){ + t_1=in; + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),0.005); + }else{ + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),std::chrono::duration(in-t_1).count()); + t_1=in; + ++imu_n; + } + return true; + +} +bool Imu_Integration::reset(gtsam::ISAM2& optimizer,boost::shared_ptr& new_frame){ + gtsam::Values result = optimizer.calculateEstimate(); + // Overwrite the beginning of the preintegration for the next step. + statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); + imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); + preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr); + ++imu_factor_id; + syn=false; + new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); + new_frame->Cov_=optimizer.marginalCovariance(P(imu_factor_id-1)); + graphPtr->resize(0); + valuesPtr->clear(); + valuesPtr->insert(P(imu_factor_id-1),statePtr->pose()); + valuesPtr->insert(V(imu_factor_id-1),statePtr->v()); + valuesPtr->insert(B(imu_factor_id-1),*imu_biasPtr); + graphPtr->addPrior(P(imu_factor_id-1),statePtr->pose(),optimizer.marginalCovariance(P(imu_factor_id-1))); + graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),optimizer.marginalCovariance(V(imu_factor_id-1))); + graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,optimizer.marginalCovariance(B(imu_factor_id-1))); + return true; +} +bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr& new_frame){ + gtsam::Values result = optimizer.optimize(); + // Overwrite the beginning of the preintegration for the next step. + statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); + imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); + preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr); + ++imu_factor_id; + syn=false; + gtsam::Marginals marginals(*graphPtr,result); + new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); + new_frame->Cov_=marginals.marginalCovariance(P(imu_factor_id-1)); + graphPtr->resize(0); + valuesPtr->clear(); + valuesPtr->insert(P(imu_factor_id-1),statePtr->pose()); + valuesPtr->insert(V(imu_factor_id-1),statePtr->v()); + valuesPtr->insert(B(imu_factor_id-1),*imu_biasPtr); + graphPtr->addPrior(P(imu_factor_id-1),statePtr->pose(),marginals.marginalCovariance(P(imu_factor_id-1))); + graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),marginals.marginalCovariance(V(imu_factor_id-1))); + graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,marginals.marginalCovariance(B(imu_factor_id-1))); + return true; +} +bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size_t& num_obs,const double reproj_thresh){ + usleep(5000); + syn=true; + if(imu_factor_id<1){ + statePtr=std::make_shared(gtsam::Pose3(new_frame->T_f_w_.matrix()), + gtsam::Vector3(1e-12,1e-12,1e-12)); + valuesPtr->insert(P(0),statePtr->pose()); + valuesPtr->insert(V(0),statePtr->v()); + valuesPtr->insert(B(0),*imu_biasPtr); + graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 1e-9, 1e-9, 1e-9, 1e-9, 1e-9, 1e-9).finished())); + graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 1e-4)); + graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-2)); + }else{ + if(imu_n<1)return false; + auto preint_imu_combined =dynamic_cast(*preintegratedPtr); + valuesPtr->insert(P(imu_factor_id), gtsam::Pose3(new_frame->T_f_w_.matrix())); + valuesPtr->insert(V(imu_factor_id), statePtr->v()); + valuesPtr->insert(B(imu_factor_id), *imu_biasPtr); + gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), + preint_imu_combined); + graphPtr->emplace_shared(imu_factor); + imu_n=0; + } + + num_obs=0; + for(auto&& f:new_frame->fts_){ + if(f->point==NULL)continue; + graphPtr->emplace_shared(f->f, f->point->pos_,f->level, ProjectNoisePtr,P(imu_factor_id)); + ++num_obs; + } + // Now optimize. + //gtsam::ISAM2 optimizer(*optimizerParamPtr); + //optimizer.update(*graphPtr, *valuesPtr); + // Each call to iSAM2 update(*) performs one iteration of the iterative + // nonlinear solver. If accuracy is desired at the expense of time, + // update(*) can be called additional times to perform multiple optimizer + // iterations every step. + //optimizer.update(); + // optimizer.print(); + gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr); + + reset(optimizer,new_frame); + // Remove Measurements with too large reprojection error + double reproj_thresh_scaled = reproj_thresh / new_frame->cam_->errorMultiplier2(); + for(auto&& f:new_frame->fts_) + { + if(f->point == NULL) + continue; + Eigen::Vector2d e = (vk::project2d(f->f) - vk::project2d(new_frame->T_f_w_ * f->point->pos_))*1.0 / (1<level); + if(e.norm() > reproj_thresh_scaled) + { + // we don't need to delete a reference in the point since it was not created yet + f->point = NULL; + --num_obs; + } + } + return true; +} \ No newline at end of file diff --git a/GPU_version/svo/src/initialization.cpp b/GPU_version/svo/src/initialization.cpp new file mode 100644 index 0000000..571a0bc --- /dev/null +++ b/GPU_version/svo/src/initialization.cpp @@ -0,0 +1,199 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { +namespace initialization { + +InitResult KltHomographyInit::addFirstFrame(FramePtr frame_ref) +{ + reset(); + detectFeatures(frame_ref, px_ref_, f_ref_); + if(px_ref_.size() < 100) + { + SVO_WARN_STREAM_THROTTLE(2.0, "First image has less than 100 features. Retry in more textured environment."); + return FAILURE; + } + frame_ref_ = frame_ref; + px_cur_.insert(px_cur_.begin(), px_ref_.begin(), px_ref_.end()); + return SUCCESS; +} + +InitResult KltHomographyInit::addSecondFrame(FramePtr frame_cur) +{ + trackKlt(frame_ref_, frame_cur, px_ref_, px_cur_, f_ref_, f_cur_, disparities_); + SVO_INFO_STREAM("Init: KLT tracked "<< disparities_.size() <<" features"); + + if(disparities_.size() < Config::initMinTracked()) + return FAILURE; + + double disparity = vk::getMedian(disparities_); + SVO_INFO_STREAM("Init: KLT "<cam_->errorMultiplier2(), Config::poseOptimThresh(), + inliers_, xyz_in_cur_, T_cur_from_ref_); + SVO_INFO_STREAM("Init: Homography RANSAC "< depth_vec; + for(size_t i=0; iT_f_w_ = T_cur_from_ref_ * frame_ref_->T_f_w_; + frame_cur->T_f_w_.translation() = + -frame_cur->T_f_w_.rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); + + // For each inlier create 3D point and add feature in both frames + SE3 T_world_cur = frame_cur->T_f_w_.inverse(); + for(vector::iterator it=inliers_.begin(); it!=inliers_.end(); ++it) + { + Vector2d px_cur(px_cur_[*it].x, px_cur_[*it].y); + Vector2d px_ref(px_ref_[*it].x, px_ref_[*it].y); + if(frame_ref_->cam_->isInFrame(px_cur.cast(), 10) && frame_ref_->cam_->isInFrame(px_ref.cast(), 10) && xyz_in_cur_[*it].z() > 0) + { + Vector3d pos = T_world_cur * (xyz_in_cur_[*it]*scale); + Point* new_point = new Point(pos); + + Feature* ftr_cur(new Feature(frame_cur.get(), new_point, px_cur, f_cur_[*it], 0)); + frame_cur->addFeature(ftr_cur); + new_point->addFrameRef(ftr_cur); + + Feature* ftr_ref(new Feature(frame_ref_.get(), new_point, px_ref, f_ref_[*it], 0)); + frame_ref_->addFeature(ftr_ref); + new_point->addFrameRef(ftr_ref); + } + } + return SUCCESS; +} + +void KltHomographyInit::reset() +{ + px_cur_.clear(); + frame_ref_.reset(); +} + +void detectFeatures( + FramePtr frame, + vector& px_vec, + vector& f_vec) +{ + Features new_features; + feature_detection::FastDetector detector( + frame->img().cols, frame->img().rows, Config::gridSize(), Config::nPyrLevels()); + detector.detect(frame.get(), frame->img_pyr_, Config::triangMinCornerScore(), new_features); + + // now for all maximum corners, initialize a new seed + px_vec.clear(); px_vec.reserve(new_features.size()); + f_vec.clear(); f_vec.reserve(new_features.size()); + std::for_each(new_features.begin(), new_features.end(), [&](Feature* ftr){ + px_vec.push_back(cv::Point2f(ftr->px[0], ftr->px[1])); + f_vec.push_back(ftr->f); + delete ftr; + }); +} + +void trackKlt( + FramePtr frame_ref, + FramePtr frame_cur, + vector& px_ref, + vector& px_cur, + vector& f_ref, + vector& f_cur, + vector& disparities) +{ + const double klt_win_size = 30.0; + const int klt_max_iter = 30; + const double klt_eps = 0.001; + vector status; + vector error; + vector min_eig_vec; + cv::TermCriteria termcrit(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, klt_max_iter, klt_eps); + cv::calcOpticalFlowPyrLK(frame_ref->img_pyr_[0], frame_cur->img_pyr_[0], + px_ref, px_cur, + status, error, + cv::Size2i(klt_win_size, klt_win_size), + 4, termcrit, cv::OPTFLOW_USE_INITIAL_FLOW); + + vector::iterator px_ref_it = px_ref.begin(); + vector::iterator px_cur_it = px_cur.begin(); + vector::iterator f_ref_it = f_ref.begin(); + f_cur.clear(); f_cur.reserve(px_cur.size()); + disparities.clear(); disparities.reserve(px_cur.size()); + for(size_t i=0; px_ref_it != px_ref.end(); ++i) + { + if(!status[i]) + { + px_ref_it = px_ref.erase(px_ref_it); + px_cur_it = px_cur.erase(px_cur_it); + f_ref_it = f_ref.erase(f_ref_it); + continue; + } + f_cur.push_back(frame_cur->c2f(px_cur_it->x, px_cur_it->y)); + disparities.push_back(Vector2d(px_ref_it->x - px_cur_it->x, px_ref_it->y - px_cur_it->y).norm()); + ++px_ref_it; + ++px_cur_it; + ++f_ref_it; + } +} + +void computeHomography( + const vector& f_ref, + const vector& f_cur, + double focal_length, + double reprojection_threshold, + vector& inliers, + vector& xyz_in_cur, + SE3& T_cur_from_ref) +{ + vector uv_ref(f_ref.size()); + vector uv_cur(f_cur.size()); + for(size_t i=0, i_max=f_ref.size(); i outliers; + vk::computeInliers(f_cur, f_ref, + Homography.T_c2_from_c1.rotation_matrix(), Homography.T_c2_from_c1.translation(), + reprojection_threshold, focal_length, + xyz_in_cur, inliers, outliers); + T_cur_from_ref = Homography.T_c2_from_c1; +} + + +} // namespace initialization +} // namespace svo diff --git a/GPU_version/svo/src/map.cpp b/GPU_version/svo/src/map.cpp new file mode 100644 index 0000000..2ecad1c --- /dev/null +++ b/GPU_version/svo/src/map.cpp @@ -0,0 +1,368 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include + +namespace svo { + +Map::Map() {} + +Map::~Map() +{ + reset(); + SVO_INFO_STREAM("Map destructed"); +} + +void Map::reset() +{ + keyframes_.clear(); + point_candidates_.reset(); + emptyTrash(); +} + +bool Map::safeDeleteFrame(FramePtr frame) +{ + bool found = false; + for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) + { + if(*it == frame) + { + std::for_each((*it)->fts_.begin(), (*it)->fts_.end(), [&](Feature* ftr){ + removePtFrameRef(it->get(), ftr); + }); + keyframes_.erase(it); + found = true; + break; + } + } + + point_candidates_.removeFrameCandidates(frame); + + if(found) + return true; + + SVO_ERROR_STREAM("Tried to delete Keyframe in map which was not there."); + return false; +} + +void Map::removePtFrameRef(Frame* frame, Feature* ftr) +{ + if(ftr->point == NULL) + return; // mappoint may have been deleted in a previous ref. removal + Point* pt = ftr->point; + ftr->point = NULL; + if(pt->obs_.size() <= 2) + { + // If the references list of mappoint has only size=2, delete mappoint + safeDeletePoint(pt); + return; + } + pt->deleteFrameRef(frame); // Remove reference from map_point + frame->removeKeyPoint(ftr); // Check if mp was keyMp in keyframe +} + +void Map::safeDeletePoint(Point* pt) +{ + // Delete references to mappoints in all keyframes + std::for_each(pt->obs_.begin(), pt->obs_.end(), [&](Feature* ftr){ + ftr->point=NULL; + ftr->frame->removeKeyPoint(ftr); + }); + pt->obs_.clear(); + + // Delete mappoint + deletePoint(pt); +} + +void Map::deletePoint(Point* pt) +{ + pt->type_ = Point::TYPE_DELETED; + trash_points_.push_back(pt); +} + +void Map::addKeyframe(FramePtr new_keyframe) +{ + keyframes_.push_back(new_keyframe); +} + +void Map::getCloseKeyframes( + const FramePtr& frame, + std::list< std::pair >& close_kfs) const +{ + for(auto kf : keyframes_) + { + // check if kf has overlaping field of view with frame, use therefore KeyPoints + for(auto keypoint : kf->key_pts_) + { + if(keypoint == nullptr) + continue; + + if(frame->isVisible(keypoint->point->pos_)) + { + close_kfs.push_back( + std::make_pair( + kf, (frame->T_f_w_.translation()-kf->T_f_w_.translation()).norm())); + break; // this keyframe has an overlapping field of view -> add to close_kfs + } + } + } +} + +FramePtr Map::getClosestKeyframe(const FramePtr& frame) const +{ + list< pair > close_kfs; + getCloseKeyframes(frame, close_kfs); + if(close_kfs.empty()) + { + return nullptr; + } + + + // Sort KFs with overlap according to their closeness + close_kfs.sort(boost::bind(&std::pair::second, _1) < + boost::bind(&std::pair::second, _2)); + + if(close_kfs.front().first != frame) + return close_kfs.front().first; + close_kfs.pop_front(); + return close_kfs.front().first; +} + +FramePtr Map::getFurthestKeyframe(const Vector3d& pos) const +{ + FramePtr furthest_kf; + double maxdist = 0.0; + for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) + { + double dist = ((*it)->pos()-pos).norm(); + if(dist > maxdist) { + maxdist = dist; + furthest_kf = *it; + } + } + return furthest_kf; +} + +bool Map::getKeyframeById(const int id, FramePtr& frame) const +{ + bool found = false; + for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) + if((*it)->id_ == id) { + found = true; + frame = *it; + break; + } + return found; +} + +void Map::transform(const Matrix3d& R, const Vector3d& t, const double& s) +{ + for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) + { + Vector3d pos = s*R*(*it)->pos() + t; + Matrix3d rot = R*(*it)->T_f_w_.rotation_matrix().inverse(); + (*it)->T_f_w_ = SE3(rot, pos).inverse(); + for(auto ftr=(*it)->fts_.begin(); ftr!=(*it)->fts_.end(); ++ftr) + { + if((*ftr)->point == NULL) + continue; + if((*ftr)->point->last_published_ts_ == -1000) + continue; + (*ftr)->point->last_published_ts_ = -1000; + (*ftr)->point->pos_ = s*R*(*ftr)->point->pos_ + t; + } + } +} + +void Map::emptyTrash() +{ + std::for_each(trash_points_.begin(), trash_points_.end(), [&](Point*& pt){ + delete pt; + pt=NULL; + }); + trash_points_.clear(); + point_candidates_.emptyTrash(); +} + +MapPointCandidates::MapPointCandidates() +{} + +MapPointCandidates::~MapPointCandidates() +{ + reset(); +} + +void MapPointCandidates::newCandidatePoint(Point* point, double depth_sigma2) +{ + point->type_ = Point::TYPE_CANDIDATE; + boost::unique_lock lock(mut_); + candidates_.push_back(PointCandidate(point, point->obs_.front())); +} + +void MapPointCandidates::addCandidatePointToFrame(FramePtr frame) +{ + boost::unique_lock lock(mut_); + PointCandidateList::iterator it=candidates_.begin(); + while(it != candidates_.end()) + { + if(it->first->obs_.front()->frame == frame.get()) + { + // insert feature in the frame + it->first->type_ = Point::TYPE_UNKNOWN; + it->first->n_failed_reproj_ = 0; + it->second->frame->addFeature(it->second); + it = candidates_.erase(it); + } + else + ++it; + } +} + +bool MapPointCandidates::deleteCandidatePoint(Point* point) +{ + boost::unique_lock lock(mut_); + for(auto it=candidates_.begin(), ite=candidates_.end(); it!=ite; ++it) + { + if(it->first == point) + { + deleteCandidate(*it); + candidates_.erase(it); + return true; + } + } + return false; +} + +void MapPointCandidates::removeFrameCandidates(FramePtr frame) +{ + boost::unique_lock lock(mut_); + auto it=candidates_.begin(); + while(it!=candidates_.end()) + { + if(it->second->frame == frame.get()) + { + deleteCandidate(*it); + it = candidates_.erase(it); + } + else + ++it; + } +} + +void MapPointCandidates::reset() +{ + boost::unique_lock lock(mut_); + std::for_each(candidates_.begin(), candidates_.end(), [&](PointCandidate& c){ + delete c.first; + delete c.second; + }); + candidates_.clear(); +} + +void MapPointCandidates::deleteCandidate(PointCandidate& c) +{ + // camera-rig: another frame might still be pointing to the candidate point + // therefore, we can't delete it right now. + delete c.second; c.second=NULL; + c.first->type_ = Point::TYPE_DELETED; + trash_points_.push_back(c.first); +} + +void MapPointCandidates::emptyTrash() +{ + std::for_each(trash_points_.begin(), trash_points_.end(), [&](Point*& p){ + delete p; p=NULL; + }); + trash_points_.clear(); +} + +namespace map_debug { + +void mapValidation(Map* map, int id) +{ + for(auto it=map->keyframes_.begin(); it!=map->keyframes_.end(); ++it) + frameValidation(it->get(), id); +} + +void frameValidation(Frame* frame, int id) +{ + for(auto it = frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point==NULL) + continue; + + if((*it)->point->type_ == Point::TYPE_DELETED) + printf("ERROR DataValidation %i: Referenced point was deleted.\n", id); + + if(!(*it)->point->findFrameRef(frame)) + printf("ERROR DataValidation %i: Frame has reference but point does not have a reference back.\n", id); + + pointValidation((*it)->point, id); + } + for(auto it=frame->key_pts_.begin(); it!=frame->key_pts_.end(); ++it) + if(*it != NULL) + if((*it)->point == NULL) + printf("ERROR DataValidation %i: KeyPoints not correct!\n", id); +} + +void pointValidation(Point* point, int id) +{ + for(auto it=point->obs_.begin(); it!=point->obs_.end(); ++it) + { + bool found=false; + for(auto it_ftr=(*it)->frame->fts_.begin(); it_ftr!=(*it)->frame->fts_.end(); ++it_ftr) + if((*it_ftr)->point == point) { + found=true; break; + } + if(!found) + printf("ERROR DataValidation %i: Point %i has inconsistent reference in frame %i, is candidate = %i\n", id, point->id_, (*it)->frame->id_, (int) point->type_); + } +} + +void mapStatistics(Map* map) +{ + // compute average number of features which each frame observes + size_t n_pt_obs(0); + for(auto it=map->keyframes_.begin(); it!=map->keyframes_.end(); ++it) + n_pt_obs += (*it)->nObs(); + printf("\n\nMap Statistics: Frame avg. point obs = %f\n", (float) n_pt_obs/map->size()); + + // compute average number of observations that each point has + size_t n_frame_obs(0); + size_t n_pts(0); + std::set points; + for(auto it=map->keyframes_.begin(); it!=map->keyframes_.end(); ++it) + { + for(auto ftr=(*it)->fts_.begin(); ftr!=(*it)->fts_.end(); ++ftr) + { + if((*ftr)->point == NULL) + continue; + if(points.insert((*ftr)->point).second) { + ++n_pts; + n_frame_obs += (*ftr)->point->nRefs(); + } + } + } + printf("Map Statistics: Point avg. frame obs = %f\n\n", (float) n_frame_obs/n_pts); +} + +} // namespace map_debug +} // namespace svo diff --git a/GPU_version/svo/src/matcher.cpp b/GPU_version/svo/src/matcher.cpp new file mode 100644 index 0000000..38a89fb --- /dev/null +++ b/GPU_version/svo/src/matcher.cpp @@ -0,0 +1,323 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +namespace warp { + +void getWarpMatrixAffine( + const vk::AbstractCamera& cam_ref, + const vk::AbstractCamera& cam_cur, + const Vector2d& px_ref, + const Vector3d& f_ref, + const double depth_ref, + const SE3& T_cur_ref, + const int level_ref, + Matrix2d& A_cur_ref) +{ + // Compute affine warp matrix A_ref_cur + const int halfpatch_size = 5; + const Vector3d xyz_ref(f_ref*depth_ref); + Vector3d xyz_du_ref(cam_ref.cam2world(px_ref + Vector2d(halfpatch_size,0)*(1< 3.0 && search_level < max_level) + { + search_level += 1; + D *= 0.25; + } + return search_level; +} + +void warpAffine( + const Matrix2d& A_cur_ref, + const cv::Mat& img_ref, + const Vector2d& px_ref, + const int level_ref, + const int search_level, + const int halfpatch_size, + uint8_t* patch) +{ + const int patch_size = halfpatch_size*2 ; + const Matrix2f A_ref_cur = A_cur_ref.inverse().cast(); + if(isnan(A_ref_cur(0,0))) + { + printf("Affine warp is NaN, probably camera has no translation\n"); // TODO + return; + } + + // Perform the warp on a larger patch. + uint8_t* patch_ptr = patch; + const Vector2f px_ref_pyr = px_ref.cast() / (1<=img_ref.cols-1 || px[1]>=img_ref.rows-1) + *patch_ptr = 0; + else + *patch_ptr = (uint8_t) vk::interpolateMat_8u(img_ref, px[0], px[1]); + } + } +} + +} // namespace warp + +bool depthFromTriangulation( + const SE3& T_search_ref, + const Vector3d& f_ref, + const Vector3d& f_cur, + double& depth) +{ + Matrix A; A << T_search_ref.rotation_matrix() * f_ref, f_cur; + const Matrix2d AtA = A.transpose()*A; + if(AtA.determinant() < 0.000001) + return false; + const Vector2d depth2 = - AtA.inverse()*A.transpose()*T_search_ref.translation(); + depth = fabs(depth2[0]); + return true; +} + +void Matcher::createPatchFromPatchWithBorder() +{ + uint8_t* ref_patch_ptr = patch_; + for(int y=1; yframe->cam_->isInFrame( + ref_ftr_->px.cast()/(1<level), halfpatch_size_+2, ref_ftr_->level)) + return false; + + // warp affine + warp::getWarpMatrixAffine( + *ref_ftr_->frame->cam_, *cur_frame.cam_, ref_ftr_->px, ref_ftr_->f, + (ref_ftr_->frame->pos() - pt.pos_).norm(), + cur_frame.T_f_w_ * ref_ftr_->frame->T_f_w_.inverse(), ref_ftr_->level, A_cur_ref_); + search_level_ = warp::getBestSearchLevel(A_cur_ref_, Config::nPyrLevels()-1); + warp::warpAffine(A_cur_ref_, ref_ftr_->frame->img_pyr_[ref_ftr_->level], ref_ftr_->px, + ref_ftr_->level, search_level_, halfpatch_size_+1, patch_with_border_); + createPatchFromPatchWithBorder(); + + // px_cur should be set + Vector2d px_scaled(px_cur/(1<type == Feature::EDGELET) + { + Vector2d dir_cur(A_cur_ref_*ref_ftr_->grad); + dir_cur.normalize(); + success = feature_alignment::align1D( + cur_frame.img_pyr_[search_level_], dir_cur.cast(), + patch_with_border_, patch_, options_.align_max_iter, px_scaled, h_inv_); + } + else + { + success = feature_alignment::align2D( + cur_frame.img_pyr_[search_level_], patch_with_border_, patch_, + options_.align_max_iter, px_scaled); + } + px_cur = px_scaled * (1<world2cam(A)); + Vector2d px_B(cur_frame.cam_->world2cam(B)); + epi_length_ = (px_A-px_B).norm() / (1<().normalized(), + patch_with_border_, patch_, options_.align_max_iter, px_scaled, h_inv_); + else + res = feature_alignment::align2D( + cur_frame.img_pyr_[search_level_], patch_with_border_, patch_, + options_.align_max_iter, px_scaled); + if(res) + { + px_cur_ = px_scaled*(1<cam2world(px_cur_), depth)) + return true; + } + return false; + } + + size_t n_steps = epi_length_/0.7; // one step per pixel + Vector2d step = epi_dir_/n_steps; + + if(n_steps > options_.max_epi_search_steps) + { + printf("WARNING: skip epipolar search: %zu evaluations, px_lenght=%f, d_min=%f, d_max=%f.\n", + n_steps, epi_length_, d_min, d_max); + return false; + } + + // for matching, precompute sum and sum2 of warped reference patch + int pixel_sum = 0; + int pixel_sum_square = 0; + PatchScore patch_score(patch_); + + // now we sample along the epipolar line + Vector2d uv = B-step; + Vector2i last_checked_pxi(0,0); + ++n_steps; + for(size_t i=0; iworld2cam(uv)); + Vector2i pxi(px[0]/(1<isInFrame(pxi, patch_size_, search_level_)) + continue; + + // TODO interpolation would probably be a good idea + uint8_t* cur_patch_ptr = cur_frame.img_pyr_[search_level_].data + + (pxi[1]-halfpatch_size_)*cur_frame.img_pyr_[search_level_].cols + + (pxi[0]-halfpatch_size_); + int zmssd = patch_score.computeScore(cur_patch_ptr, cur_frame.img_pyr_[search_level_].cols); + + if(zmssd < zmssd_best) { + zmssd_best = zmssd; + uv_best = uv; + } + } + + if(zmssd_best < PatchScore::threshold()) + { + if(options_.subpix_refinement) + { + px_cur_ = cur_frame.cam_->world2cam(uv_best); + Vector2d px_scaled(px_cur_/(1<().normalized(), + patch_with_border_, patch_, options_.align_max_iter, px_scaled, h_inv_); + else + res = feature_alignment::align2D( + cur_frame.img_pyr_[search_level_], patch_with_border_, patch_, + options_.align_max_iter, px_scaled); + if(res) + { + px_cur_ = px_scaled*(1<cam2world(px_cur_), depth)) + return true; + } + return false; + } + px_cur_ = cur_frame.cam_->world2cam(uv_best); + if(depthFromTriangulation(T_cur_ref, ref_ftr.f, vk::unproject2d(uv_best).normalized(), depth)) + return true; + } + return false; +} + +} // namespace svo diff --git a/GPU_version/svo/src/point.cpp b/GPU_version/svo/src/point.cpp new file mode 100644 index 0000000..2e45e06 --- /dev/null +++ b/GPU_version/svo/src/point.cpp @@ -0,0 +1,179 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include + +namespace svo { + +int Point::point_counter_ = 0; + +Point::Point(const Vector3d& pos) : + id_(point_counter_++), + pos_(pos), + normal_set_(false), + n_obs_(0), + v_pt_(NULL), + last_published_ts_(0), + last_projected_kf_id_(-1), + type_(TYPE_UNKNOWN), + n_failed_reproj_(0), + n_succeeded_reproj_(0), + last_structure_optim_(0) +{} + +Point::Point(const Vector3d& pos, Feature* ftr) : + id_(point_counter_++), + pos_(pos), + normal_set_(false), + n_obs_(1), + v_pt_(NULL), + last_published_ts_(0), + last_projected_kf_id_(-1), + type_(TYPE_UNKNOWN), + n_failed_reproj_(0), + n_succeeded_reproj_(0), + last_structure_optim_(0) +{ + obs_.push_front(ftr); +} + +Point::~Point() +{} + +void Point::addFrameRef(Feature* ftr) +{ + obs_.push_front(ftr); + ++n_obs_; +} + +Feature* Point::findFrameRef(Frame* frame) +{ + for(auto it=obs_.begin(), ite=obs_.end(); it!=ite; ++it) + if((*it)->frame == frame) + return *it; + return NULL; // no keyframe found +} + +bool Point::deleteFrameRef(Frame* frame) +{ + for(auto it=obs_.begin(), ite=obs_.end(); it!=ite; ++it) + { + if((*it)->frame == frame) + { + obs_.erase(it); + return true; + } + } + return false; +} + +void Point::initNormal() +{ + assert(!obs_.empty()); + const Feature* ftr = obs_.back(); + assert(ftr->frame != NULL); + normal_ = ftr->frame->T_f_w_.rotation_matrix().transpose()*(-ftr->f); + normal_information_ = DiagonalMatrix(pow(20/(pos_-ftr->frame->pos()).norm(),2), 1.0, 1.0); + normal_set_ = true; +} + +bool Point::getCloseViewObs(const Vector3d& framepos, Feature*& ftr) const +{ + // TODO: get frame with same point of view AND same pyramid level! + Vector3d obs_dir(framepos - pos_); obs_dir.normalize(); + auto min_it=obs_.begin(); + double min_cos_angle = 0; + for(auto it=obs_.begin(), ite=obs_.end(); it!=ite; ++it) + { + Vector3d dir((*it)->frame->pos() - pos_); dir.normalize(); + double cos_angle = obs_dir.dot(dir); + if(cos_angle > min_cos_angle) + { + min_cos_angle = cos_angle; + min_it = it; + } + } + ftr = *min_it; + if(min_cos_angle < 0.5) // assume that observations larger than 60° are useless + return false; + return true; +} + +void Point::optimize(const size_t n_iter) +{ + Vector3d old_point = pos_; + double chi2 = 0.0; + Matrix3d A; + Vector3d b; + + for(size_t i=0; iframe->T_f_w_ * pos_); + Point::jacobian_xyz2uv(p_in_f, (*it)->frame->T_f_w_.rotation_matrix(), J); + const Vector2d e(vk::project2d((*it)->f) - vk::project2d(p_in_f)); + new_chi2 += e.squaredNorm(); + A.noalias() += J.transpose() * J; + b.noalias() -= J.transpose() * e; + } + + // solve linear system + const Vector3d dp(A.ldlt().solve(b)); + + // check if error increased + if((i > 0 && new_chi2 > chi2) || (bool) std::isnan((double)dp[0])) + { +#ifdef POINT_OPTIMIZER_DEBUG + cout << "it " << i + << "\t FAILURE \t new_chi2 = " << new_chi2 << endl; +#endif + pos_ = old_point; // roll-back + break; + } + + // update the model + Vector3d new_point = pos_ + dp; + old_point = pos_; + pos_ = new_point; + chi2 = new_chi2; +#ifdef POINT_OPTIMIZER_DEBUG + cout << "it " << i + << "\t Success \t new_chi2 = " << new_chi2 + << "\t norm(b) = " << vk::norm_max(b) + << endl; +#endif + + // stop when converged + if(vk::norm_max(dp) <= EPS) + break; + } +#ifdef POINT_OPTIMIZER_DEBUG + cout << endl; +#endif +} + +} // namespace svo diff --git a/GPU_version/svo/src/pose_optimizer.cpp b/GPU_version/svo/src/pose_optimizer.cpp new file mode 100644 index 0000000..1c491b0 --- /dev/null +++ b/GPU_version/svo/src/pose_optimizer.cpp @@ -0,0 +1,165 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include + +namespace svo { +namespace pose_optimizer { + +void optimizeGaussNewton( + const double reproj_thresh, + const size_t n_iter, + const bool verbose, + FramePtr& frame, + double& estimated_scale, + double& error_init, + double& error_final, + size_t& num_obs) +{ + // init + double chi2(0.0); + vector chi2_vec_init, chi2_vec_final; + vk::robust_cost::TukeyWeightFunction weight_function; + SE3 T_old(frame->T_f_w_); + Matrix6d A; + Vector6d b; + + // compute the scale of the error for robust estimation + std::vector errors; errors.reserve(frame->fts_.size()); + for(auto it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point == NULL) + continue; + //Reprojection error + Vector2d e = vk::project2d((*it)->f) + - vk::project2d(frame->T_f_w_ * (*it)->point->pos_); + e *= 1.0 / (1<<(*it)->level); + errors.push_back(e.norm()); + } + if(errors.empty()) + return; + vk::robust_cost::MADScaleEstimator scale_estimator; + estimated_scale = scale_estimator.compute(errors); + + num_obs = errors.size(); + chi2_vec_init.reserve(num_obs); + chi2_vec_final.reserve(num_obs); + double scale = estimated_scale; + for(size_t iter=0; itercam_->errorMultiplier2(); + + b.setZero(); + A.setZero(); + double new_chi2(0.0); + + // compute residual + for(auto it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point == NULL) + continue; + Matrix26d J; + Vector3d xyz_f(frame->T_f_w_ * (*it)->point->pos_); + Frame::jacobian_xyz2uv(xyz_f, J); + Vector2d e = vk::project2d((*it)->f) - vk::project2d(xyz_f); + double sqrt_inv_cov = 1.0 / (1<<(*it)->level); + e *= sqrt_inv_cov; + if(iter == 0) + chi2_vec_init.push_back(e.squaredNorm()); // just for debug + J *= sqrt_inv_cov; + double weight = weight_function.value(e.norm()/scale); + A.noalias() += J.transpose()*J*weight; + b.noalias() -= J.transpose()*e*weight; + new_chi2 += e.squaredNorm()*weight; + } + + // solve linear system + const Vector6d dT(A.ldlt().solve(b)); + + // check if error increased + if((iter > 0 && new_chi2 > chi2) || (bool) std::isnan((double)dT[0])) + { + if(verbose) + std::cout << "it " << iter + << "\t FAILURE \t new_chi2 = " << new_chi2 << std::endl; + frame->T_f_w_ = T_old; // roll-back + break; + } + + // update the model + SE3 T_new = SE3::exp(dT)*frame->T_f_w_; + T_old = frame->T_f_w_; + frame->T_f_w_ = T_new; + chi2 = new_chi2; + if(verbose) + std::cout << "it " << iter + << "\t Success \t new_chi2 = " << new_chi2 + << "\t norm(dT) = " << vk::norm_max(dT) << std::endl; + + // stop when converged + if(vk::norm_max(dT) <= EPS) + break; + } + + // Set covariance as inverse information matrix. Optimistic estimator! + const double pixel_variance=1.0; + frame->Cov_ = pixel_variance*(A*std::pow(frame->cam_->errorMultiplier2(),2)).inverse(); + + // Remove Measurements with too large reprojection error + double reproj_thresh_scaled = reproj_thresh / frame->cam_->errorMultiplier2(); + size_t n_deleted_refs = 0; + for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) + { + if((*it)->point == NULL) + continue; + Vector2d e = vk::project2d((*it)->f) - vk::project2d(frame->T_f_w_ * (*it)->point->pos_); + double sqrt_inv_cov = 1.0 / (1<<(*it)->level); + e *= sqrt_inv_cov; + chi2_vec_final.push_back(e.squaredNorm()); + if(e.norm() > reproj_thresh_scaled) + { + // we don't need to delete a reference in the point since it was not created yet + (*it)->point = NULL; + ++n_deleted_refs; + } + } + + error_init=0.0; + error_final=0.0; + if(!chi2_vec_init.empty()) + error_init = sqrt(vk::getMedian(chi2_vec_init))*frame->cam_->errorMultiplier2(); + if(!chi2_vec_final.empty()) + error_final = sqrt(vk::getMedian(chi2_vec_final))*frame->cam_->errorMultiplier2(); + + estimated_scale *= frame->cam_->errorMultiplier2(); + if(verbose) + std::cout << "n deleted obs = " << n_deleted_refs + << "\t scale = " << estimated_scale + << "\t error init = " << error_init + << "\t error end = " << error_final << std::endl; + num_obs -= n_deleted_refs; +} + +} // namespace pose_optimizer +} // namespace svo diff --git a/GPU_version/svo/src/reprojector.cpp b/GPU_version/svo/src/reprojector.cpp new file mode 100644 index 0000000..81a7835 --- /dev/null +++ b/GPU_version/svo/src/reprojector.cpp @@ -0,0 +1,219 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +Reprojector::Reprojector(vk::AbstractCamera* cam, Map& map) : + map_(map) +{ + initializeGrid(cam); +} + +Reprojector::~Reprojector() +{ + std::for_each(grid_.cells.begin(), grid_.cells.end(), [&](Cell* c){ delete c; }); +} + +void Reprojector::initializeGrid(vk::AbstractCamera* cam) +{ + grid_.cell_size = Config::gridSize(); + grid_.grid_n_cols = ceil(static_cast(cam->width())/grid_.cell_size); + grid_.grid_n_rows = ceil(static_cast(cam->height())/grid_.cell_size); + grid_.cells.resize(grid_.grid_n_cols*grid_.grid_n_rows); + std::for_each(grid_.cells.begin(), grid_.cells.end(), [&](Cell*& c){ c = new Cell; }); + grid_.cell_order.resize(grid_.cells.size()); + for(size_t i=0; iclear(); }); +} + +void Reprojector::reprojectMap( + FramePtr frame, + std::vector< std::pair >& overlap_kfs) +{ + resetGrid(); + + // Identify those Keyframes which share a common field of view. + SVO_START_TIMER("reproject_kfs"); + list< pair > close_kfs; + map_.getCloseKeyframes(frame, close_kfs); + + // Sort KFs with overlap according to their closeness + close_kfs.sort(boost::bind(&std::pair::second, _1) < + boost::bind(&std::pair::second, _2)); + + // Reproject all mappoints of the closest N kfs with overlap. We only store + // in which grid cell the points fall. + size_t n = 0; + overlap_kfs.reserve(options_.max_n_kfs); + for(auto it_frame=close_kfs.begin(), ite_frame=close_kfs.end(); + it_frame!=ite_frame && nfirst; + overlap_kfs.push_back(pair(ref_frame,0)); + + // Try to reproject each mappoint that the other KF observes + for(auto it_ftr=ref_frame->fts_.begin(), ite_ftr=ref_frame->fts_.end(); + it_ftr!=ite_ftr; ++it_ftr) + { + // check if the feature has a mappoint assigned + if((*it_ftr)->point == NULL) + continue; + + // make sure we project a point only once + if((*it_ftr)->point->last_projected_kf_id_ == frame->id_) + continue; + (*it_ftr)->point->last_projected_kf_id_ = frame->id_; + if(reprojectPoint(frame, (*it_ftr)->point)) + overlap_kfs.back().second++; + } + } + SVO_STOP_TIMER("reproject_kfs"); + + // Now project all point candidates + SVO_START_TIMER("reproject_candidates"); + { + boost::unique_lock lock(map_.point_candidates_.mut_); + auto it=map_.point_candidates_.candidates_.begin(); + while(it!=map_.point_candidates_.candidates_.end()) + { + if(!reprojectPoint(frame, it->first)) + { + it->first->n_failed_reproj_ += 3; + if(it->first->n_failed_reproj_ > 30) + { + map_.point_candidates_.deleteCandidate(*it); + it = map_.point_candidates_.candidates_.erase(it); + continue; + } + } + ++it; + } + } // unlock the mutex when out of scope + SVO_STOP_TIMER("reproject_candidates"); + + // Now we go through each grid cell and select one point to match. + // At the end, we should have at maximum one reprojected point per cell. + SVO_START_TIMER("feature_align"); + for(size_t i=0; i (size_t) Config::maxFts()) + break; + } + SVO_STOP_TIMER("feature_align"); +} + +bool Reprojector::pointQualityComparator(Candidate& lhs, Candidate& rhs) +{ + if(lhs.pt->type_ > rhs.pt->type_) + return true; + return false; +} + +bool Reprojector::reprojectCell(Cell& cell, FramePtr frame) +{ + cell.sort(boost::bind(&Reprojector::pointQualityComparator, _1, _2)); + Cell::iterator it=cell.begin(); + while(it!=cell.end()) + { + ++n_trials_; + + if(it->pt->type_ == Point::TYPE_DELETED) + { + it = cell.erase(it); + continue; + } + + bool found_match = true; + if(options_.find_match_direct) + found_match = matcher_.findMatchDirect(*it->pt, *frame, it->px); + if(!found_match) + { + it->pt->n_failed_reproj_++; + if(it->pt->type_ == Point::TYPE_UNKNOWN && it->pt->n_failed_reproj_ > 15) + map_.safeDeletePoint(it->pt); + if(it->pt->type_ == Point::TYPE_CANDIDATE && it->pt->n_failed_reproj_ > 30) + map_.point_candidates_.deleteCandidatePoint(it->pt); + it = cell.erase(it); + continue; + } + it->pt->n_succeeded_reproj_++; + if(it->pt->type_ == Point::TYPE_UNKNOWN && it->pt->n_succeeded_reproj_ > 10) + it->pt->type_ = Point::TYPE_GOOD; + + Feature* new_feature = new Feature(frame.get(), it->px, matcher_.search_level_); + frame->addFeature(new_feature); + + // Here we add a reference in the feature to the 3D point, the other way + // round is only done if this frame is selected as keyframe. + new_feature->point = it->pt; + + if(matcher_.ref_ftr_->type == Feature::EDGELET) + { + new_feature->type = Feature::EDGELET; + new_feature->grad = matcher_.A_cur_ref_*matcher_.ref_ftr_->grad; + new_feature->grad.normalize(); + } + + // If the keyframe is selected and we reproject the rest, we don't have to + // check this point anymore. + it = cell.erase(it); + + // Maximum one point per cell. + return true; + } + return false; +} + +bool Reprojector::reprojectPoint(FramePtr frame, Point* point) +{ + Vector2d px(frame->w2c(point->pos_)); + if(frame->cam_->isInFrame(px.cast(), 8)) // 8px is the patch size in the matcher + { + const int k = static_cast(px[1]/grid_.cell_size)*grid_.grid_n_cols + + static_cast(px[0]/grid_.cell_size); + grid_.cells.at(k)->push_back(Candidate(point, px)); + return true; + } + return false; +} + +} // namespace svo diff --git a/GPU_version/svo/src/sparse_img_align.cpp b/GPU_version/svo/src/sparse_img_align.cpp new file mode 100644 index 0000000..ce1570b --- /dev/null +++ b/GPU_version/svo/src/sparse_img_align.cpp @@ -0,0 +1,274 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +SparseImgAlign::SparseImgAlign( + int max_level, int min_level, int n_iter, + Method method, bool display, bool verbose) : + display_(display), + max_level_(max_level), + min_level_(min_level) +{ + n_iter_ = n_iter; + n_iter_init_ = n_iter_; + method_ = method; + verbose_ = verbose; + eps_ = 0.000001; +} + +size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) +{ + reset(); + + if(ref_frame->fts_.empty()) + { + SVO_WARN_STREAM("SparseImgAlign: no features to track!"); + return 0; + } + + ref_frame_ = ref_frame; + cur_frame_ = cur_frame; + ref_patch_cache_ = cv::Mat(ref_frame_->fts_.size(), patch_area_, CV_32F); + jacobian_cache_.resize(Eigen::NoChange, ref_patch_cache_.rows*patch_area_); + visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? + + SE3 T_cur_from_ref(cur_frame_->T_f_w_ * ref_frame_->T_f_w_.inverse()); + + for(level_=max_level_; level_>=min_level_; --level_) + { + mu_ = 0.1; + jacobian_cache_.setZero(); + have_ref_patch_cache_ = false; + if(verbose_) + printf("\nPYRAMID LEVEL %i\n---------------\n", level_); + optimize(T_cur_from_ref); + } + cur_frame_->T_f_w_ = T_cur_from_ref * ref_frame_->T_f_w_; + + + + return n_meas_/patch_area_; +} + +Matrix SparseImgAlign::getFisherInformation() +{ + double sigma_i_sq = 5e-4*255*255; // image noise + Matrix I = H_/sigma_i_sq; + return I; +} + +void SparseImgAlign::precomputeReferencePatches() +{ + const int border = patch_halfsize_+1; + const cv::Mat& ref_img = ref_frame_->img_pyr_.at(level_); + const int stride = ref_img.cols; + const float scale = 1.0f/(1<pos(); + const double focal_length = ref_frame_->cam_->errorMultiplier2(); + size_t feature_counter = 0; + std::vector::iterator visiblity_it = visible_fts_.begin(); + for(auto it=ref_frame_->fts_.begin(), ite=ref_frame_->fts_.end(); + it!=ite; ++it, ++feature_counter, ++visiblity_it) + { + // check if reference with patch size is within image + const float u_ref = (*it)->px[0]*scale; + const float v_ref = (*it)->px[1]*scale; + const int u_ref_i = floorf(u_ref); + const int v_ref_i = floorf(v_ref); + if((*it)->point == NULL || u_ref_i-border < 0 || v_ref_i-border < 0 || u_ref_i+border >= ref_img.cols || v_ref_i+border >= ref_img.rows) + continue; + *visiblity_it = true; + + // cannot just take the 3d points coordinate because of the reprojection errors in the reference image!!! + const double depth(((*it)->point->pos_ - ref_pos).norm()); + const Vector3d xyz_ref((*it)->f*depth); + + // evaluate projection jacobian + Matrix frame_jac; + Frame::jacobian_xyz2uv(xyz_ref, frame_jac); + + // compute bilateral interpolation weights for reference image + const float subpix_u_ref = u_ref-u_ref_i; + const float subpix_v_ref = v_ref-v_ref_i; + const float w_ref_tl = (1.0-subpix_u_ref) * (1.0-subpix_v_ref); + const float w_ref_tr = subpix_u_ref * (1.0-subpix_v_ref); + const float w_ref_bl = (1.0-subpix_u_ref) * subpix_v_ref; + const float w_ref_br = subpix_u_ref * subpix_v_ref; + size_t pixel_counter = 0; + float* cache_ptr = reinterpret_cast(ref_patch_cache_.data) + patch_area_*feature_counter; + for(int y=0; yimg_pyr_.at(level_); + + if(linearize_system && display_) + resimg_ = cv::Mat(cur_img.size(), CV_32F, cv::Scalar(0)); + + if(have_ref_patch_cache_ == false) + precomputeReferencePatches(); + + // compute the weights on the first iteration + std::vector errors; + if(compute_weight_scale) + errors.reserve(visible_fts_.size()); + const int stride = cur_img.cols; + const int border = patch_halfsize_+1; + const float scale = 1.0f/(1<pos()); + float chi2 = 0.0; + size_t feature_counter = 0; // is used to compute the index of the cached jacobian + std::vector::iterator visiblity_it = visible_fts_.begin(); + for(auto it=ref_frame_->fts_.begin(); it!=ref_frame_->fts_.end(); + ++it, ++feature_counter, ++visiblity_it) + { + // check if feature is within image + if(!*visiblity_it) + continue; + + // compute pixel location in cur img + const double depth = ((*it)->point->pos_ - ref_pos).norm(); + const Vector3d xyz_ref((*it)->f*depth); + const Vector3d xyz_cur(T_cur_from_ref * xyz_ref); + const Vector2f uv_cur_pyr(cur_frame_->cam_->world2cam(xyz_cur).cast() * scale); + const float u_cur = uv_cur_pyr[0]; + const float v_cur = uv_cur_pyr[1]; + const int u_cur_i = floorf(u_cur); + const int v_cur_i = floorf(v_cur); + + // check if projection is within the image + if(u_cur_i < 0 || v_cur_i < 0 || u_cur_i-border < 0 || v_cur_i-border < 0 || u_cur_i+border >= cur_img.cols || v_cur_i+border >= cur_img.rows) + continue; + + // compute bilateral interpolation weights for the current image + const float subpix_u_cur = u_cur-u_cur_i; + const float subpix_v_cur = v_cur-v_cur_i; + const float w_cur_tl = (1.0-subpix_u_cur) * (1.0-subpix_v_cur); + const float w_cur_tr = subpix_u_cur * (1.0-subpix_v_cur); + const float w_cur_bl = (1.0-subpix_u_cur) * subpix_v_cur; + const float w_cur_br = subpix_u_cur * subpix_v_cur; + float* ref_patch_cache_ptr = reinterpret_cast(ref_patch_cache_.data) + patch_area_*feature_counter; + size_t pixel_counter = 0; // is used to compute the index of the cached jacobian + for(int y=0; yvalue(res/scale_); + } + + chi2 += res*res*weight; + n_meas_++; + + if(linearize_system) + { + // compute Jacobian, weighted Hessian and weighted "steepest descend images" (times error) + const Vector6d J(jacobian_cache_.col(feature_counter*patch_area_ + pixel_counter)); + H_.noalias() += J*J.transpose()*weight; + Jres_.noalias() -= J*res*weight; + if(display_) + resimg_.at((int) v_cur+y-patch_halfsize_, (int) u_cur+x-patch_halfsize_) = res/255.0; + } + } + } + } + + // compute the weights on the first iteration + if(compute_weight_scale && iter_ == 0) + scale_ = scale_estimator_->compute(errors); + + return chi2/n_meas_; +} + +int SparseImgAlign::solve() +{ + x_ = H_.ldlt().solve(Jres_); + if((bool) std::isnan((double) x_[0])) + return 0; + return 1; +} + +void SparseImgAlign::update( + const ModelType& T_curold_from_ref, + ModelType& T_curnew_from_ref) +{ + T_curnew_from_ref = T_curold_from_ref * SE3::exp(-x_); +} + +void SparseImgAlign::startIteration() +{} + +void SparseImgAlign::finishIteration() +{ + if(display_) + { + cv::namedWindow("residuals", CV_WINDOW_AUTOSIZE); + cv::imshow("residuals", resimg_*10); + cv::waitKey(0); + } +} + +} // namespace svo + diff --git a/GPU_version/svo/test/README.md b/GPU_version/svo/test/README.md new file mode 100644 index 0000000..c70f832 --- /dev/null +++ b/GPU_version/svo/test/README.md @@ -0,0 +1,24 @@ +#### Download Test Data + +Create a folder where you will store all datasets, e.g.: + + mkdir Datasets + +In your `.bashrc` script, create a new environment variable pointing to the dataset folder: + + export SVO_DATASET_DIR=${HOME}/Datasets + +Source your new `.bashrc` script, go to the new dataset folder and download the test data: + + source ~/.bashrc + cd ${SVO_DATASET_DIR} + wget http://rpg.ifi.uzh.ch/datasets/sin2_tex2_h1_v8_d.tar.gz -O - | tar -xz + +You can then run the tests, e.g.: + + rosrun svo test_pipeline + +or if you are not using ROS: + + cd svo/bin + ./test_pipeline diff --git a/GPU_version/svo/test/benchmark.csv b/GPU_version/svo/test/benchmark.csv new file mode 100644 index 0000000..a3831e4 --- /dev/null +++ b/GPU_version/svo/test/benchmark.csv @@ -0,0 +1,307 @@ +local_ba,point_optimizer,pose_optimizer,pyramid_creation,reproject,sparse_img_align,tot_time,dropout,img_align_n_tracked,loba_err_fin,loba_err_init,loba_n_erredges_fin,loba_n_erredges_init,n_candidates,repr_n_mps,repr_n_new_references,sfba_error_final,sfba_error_init,sfba_n_edges_final,sfba_thresh +0.000000000000000,0.000000000000000,0.000000000000000,0.000231000000000,0.000000000000000,0.000000000000000,0.005536000000000,1.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000,0.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000326000000000,0.000000000000000,0.000000000000000,0.016564000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000189000000000,0.000000000000000,0.000000000000000,0.016754000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000133000000000,0.000000000000000,0.000000000000000,0.017082000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000136000000000,0.000000000000000,0.000000000000000,0.023259000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000120000000000,0.000000000000000,0.000000000000000,0.029114000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000231000000000,0.000000000000000,0.000000000000000,0.032538000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000123000000000,0.000000000000000,0.000000000000000,0.031375000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000137000000000,0.000000000000000,0.000000000000000,0.029995000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000119000000000,0.000000000000000,0.000000000000000,0.030888000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000461000000000,0.000000000000000,0.000000000000000,0.036835000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000000000000000,0.000000000000000,0.000159000000000,0.000000000000000,0.000000000000000,0.090994000000000,1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000 +0.000000000000000,0.000036000000000,0.000143000000000,0.000117000000000,0.000836000000000,0.001616000000000,0.002862000000000,0.000000000000000,279.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,148.000000000000000,121.000000000000000,0.170175036288445,0.209622100274678,121.000000000000000,0.310240723182540 +0.000000000000000,0.000025000000000,0.000180000000000,0.000123000000000,0.000817000000000,0.000802000000000,0.001981000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,151.000000000000000,121.000000000000000,0.200086249066279,0.226929968835210,119.000000000000000,0.335856340084193 +0.000000000000000,0.000043000000000,0.000247000000000,0.000202000000000,0.000836000000000,0.000882000000000,0.002289000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,150.000000000000000,121.000000000000000,0.220021653137765,0.250579787207819,120.000000000000000,0.370858080741496 +0.000000000000000,0.000027000000000,0.000173000000000,0.000125000000000,0.000796000000000,0.000863000000000,0.002018000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,153.000000000000000,121.000000000000000,0.241933923583207,0.315090761433966,119.000000000000000,0.466334367626374 +0.000000000000000,0.000025000000000,0.000171000000000,0.000123000000000,0.000752000000000,0.000893000000000,0.002012000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,145.000000000000000,121.000000000000000,0.272951476803891,0.278442112643762,118.000000000000000,0.412094340922640 +0.000000000000000,0.000058000000000,0.000180000000000,0.000213000000000,0.001057000000000,0.000834000000000,0.002415000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,176.000000000000000,121.000000000000000,0.295685268713144,0.345204254249458,120.000000000000000,0.510902319377397 +0.000000000000000,0.000029000000000,0.000104000000000,0.000125000000000,0.000868000000000,0.000845000000000,0.002006000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,154.000000000000000,121.000000000000000,0.280726297104857,0.351937246921774,119.000000000000000,0.520867118388044 +0.000000000000000,0.000030000000000,0.000173000000000,0.000117000000000,0.000872000000000,0.000829000000000,0.002054000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,160.000000000000000,121.000000000000000,0.299712702632539,0.325868379793256,119.000000000000000,0.482285213145440 +0.000000000000000,0.000030000000000,0.000135000000000,0.000312000000000,0.001611000000000,0.000955000000000,0.003094000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,0.000000000000000,157.000000000000000,121.000000000000000,0.266414418920375,0.325723952270968,121.000000000000000,0.482071463677943 +0.000000000000000,0.000019000000000,0.000134000000000,0.000120000000000,0.000807000000000,0.000746000000000,0.001858000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,52.000000000000000,146.000000000000000,121.000000000000000,0.268513470166789,0.275002624777888,120.000000000000000,0.407003878905728 +0.000000000000000,0.000023000000000,0.000116000000000,0.000137000000000,0.000918000000000,0.000845000000000,0.002086000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,76.000000000000000,141.000000000000000,121.000000000000000,0.291779184224341,0.283057831418736,119.000000000000000,0.418925579815900 +0.000000000000000,0.000020000000000,0.000174000000000,0.000139000000000,0.000841000000000,0.000842000000000,0.002050000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,97.000000000000000,146.000000000000000,121.000000000000000,0.284752630550729,0.313033048850307,118.000000000000000,0.463288905244113 +0.000000000000000,0.000018000000000,0.000125000000000,0.000116000000000,0.000918000000000,0.000737000000000,0.001957000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,108.000000000000000,164.000000000000000,121.000000000000000,0.266984542461140,0.310809088449218,117.000000000000000,0.459997446489587 +0.000000000000000,0.000025000000000,0.000187000000000,0.000215000000000,0.001123000000000,0.000838000000000,0.002412000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,82.000000000000000,172.000000000000000,121.000000000000000,0.281472742741066,0.318106456171594,118.000000000000000,0.470797581856187 +0.000000000000000,0.000032000000000,0.000104000000000,0.000133000000000,0.000982000000000,0.001074000000000,0.002360000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,82.000000000000000,169.000000000000000,121.000000000000000,0.259578544711984,0.296051216412790,118.000000000000000,0.438155829408007 +0.000000000000000,0.000026000000000,0.000173000000000,0.000114000000000,0.000975000000000,0.000678000000000,0.001991000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,87.000000000000000,169.000000000000000,121.000000000000000,0.260854021690335,0.463271429083291,119.000000000000000,0.685641725628487 +0.000000000000000,0.000020000000000,0.000231000000000,0.000213000000000,0.001255000000000,0.000764000000000,0.002547000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,100.000000000000000,162.000000000000000,121.000000000000000,0.224857460689169,0.241819176684415,120.000000000000000,0.357892398925400 +0.000000000000000,0.000016000000000,0.000174000000000,0.000123000000000,0.000964000000000,0.000761000000000,0.002072000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,177.000000000000000,163.000000000000000,121.000000000000000,0.232802572049831,0.307670939545318,121.000000000000000,0.455352982415734 +0.000000000000000,0.000019000000000,0.000171000000000,0.000117000000000,0.000954000000000,0.000685000000000,0.001989000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,215.000000000000000,163.000000000000000,121.000000000000000,0.223503314093231,0.245376537152124,121.000000000000000,0.363157262109869 +0.000000000000000,0.000022000000000,0.000153000000000,0.000321000000000,0.001789000000000,0.000999000000000,0.003323000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,236.000000000000000,160.000000000000000,121.000000000000000,0.238679756461930,0.260245176933572,121.000000000000000,0.385162868349003 +0.000000000000000,0.000017000000000,0.000103000000000,0.000121000000000,0.000950000000000,0.000690000000000,0.001925000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,253.000000000000000,156.000000000000000,121.000000000000000,0.240028083468930,0.347317483304434,119.000000000000000,0.514029864789977 +0.000000000000000,0.000026000000000,0.000155000000000,0.000141000000000,0.001421000000000,0.000834000000000,0.002605000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,225.000000000000000,203.000000000000000,121.000000000000000,0.237050818956117,0.342187690832661,118.000000000000000,0.506437791010399 +0.000000000000000,0.000031000000000,0.000105000000000,0.000133000000000,0.001151000000000,0.000787000000000,0.002244000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,224.000000000000000,192.000000000000000,121.000000000000000,0.228256287503905,0.255917399607126,118.000000000000000,0.378757763709815 +0.000000000000000,0.000029000000000,0.000173000000000,0.000116000000000,0.001046000000000,0.000670000000000,0.002067000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,237.000000000000000,174.000000000000000,121.000000000000000,0.253024524323249,0.270830988595337,117.000000000000000,0.400829860236131 +0.000000000000000,0.000032000000000,0.000206000000000,0.000201000000000,0.001159000000000,0.000767000000000,0.002415000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,243.000000000000000,168.000000000000000,121.000000000000000,0.255837803512081,0.309767343777557,117.000000000000000,0.458455710853014 +0.000000000000000,0.000029000000000,0.000102000000000,0.000134000000000,0.001078000000000,0.000785000000000,0.002160000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,247.000000000000000,176.000000000000000,121.000000000000000,0.242039161090674,0.295753112981567,120.000000000000000,0.437714633120047 +0.000000000000000,0.000018000000000,0.000174000000000,0.000117000000000,0.001043000000000,0.000946000000000,0.002334000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,284.000000000000000,173.000000000000000,121.000000000000000,0.234035474669157,0.262962395172133,120.000000000000000,0.389184330309739 +0.000000000000000,0.000042000000000,0.000251000000000,0.000203000000000,0.001816000000000,0.000807000000000,0.003189000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,323.000000000000000,168.000000000000000,121.000000000000000,0.243963461663248,0.254676688230514,118.000000000000000,0.376921484440742 +0.000000000000000,0.000022000000000,0.000128000000000,0.000121000000000,0.001084000000000,0.000899000000000,0.002287000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,346.000000000000000,164.000000000000000,121.000000000000000,0.237498671286056,0.242318617577444,120.000000000000000,0.358631550548166 +0.000000000000000,0.000042000000000,0.000198000000000,0.000115000000000,0.001158000000000,0.000720000000000,0.002269000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,360.000000000000000,174.000000000000000,121.000000000000000,0.231204372046851,0.310626801011824,119.000000000000000,0.459727694560518 +0.000000000000000,0.000020000000000,0.000128000000000,0.000280000000000,0.000998000000000,0.000883000000000,0.002349000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,371.000000000000000,154.000000000000000,121.000000000000000,0.226372262196515,0.240389813013775,118.000000000000000,0.355776916048274 +0.000000000000000,0.000020000000000,0.000125000000000,0.000116000000000,0.001040000000000,0.000676000000000,0.002025000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,383.000000000000000,163.000000000000000,121.000000000000000,0.243430360339485,0.289701992216838,116.000000000000000,0.428758939836188 +0.000000000000000,0.000028000000000,0.000186000000000,0.000201000000000,0.001357000000000,0.000862000000000,0.002663000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,351.000000000000000,189.000000000000000,121.000000000000000,0.238491256129826,0.289513389727138,119.000000000000000,0.428479837315611 +0.000000000000000,0.000024000000000,0.000104000000000,0.000131000000000,0.001197000000000,0.000689000000000,0.002178000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,351.000000000000000,187.000000000000000,121.000000000000000,0.253535521704090,0.299150905814168,119.000000000000000,0.442743330689269 +0.000000000000000,0.000013000000000,0.000128000000000,0.000142000000000,0.001157000000000,0.000751000000000,0.002226000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,360.000000000000000,182.000000000000000,121.000000000000000,0.242747326189240,0.331002657945821,119.000000000000000,0.489883908154680 +0.000000000000000,0.000041000000000,0.000225000000000,0.000214000000000,0.001614000000000,0.000892000000000,0.003073000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,420.000000000000000,166.000000000000000,121.000000000000000,0.214060199250618,0.291833988602564,120.000000000000000,0.431914284304601 +0.000000000000000,0.000016000000000,0.000113000000000,0.000126000000000,0.001256000000000,0.000871000000000,0.002419000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,467.000000000000000,189.000000000000000,121.000000000000000,0.191542639509251,0.219467558857437,120.000000000000000,0.324811977376153 +0.000000000000000,0.000022000000000,0.000110000000000,0.000116000000000,0.001163000000000,0.000737000000000,0.002178000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,491.000000000000000,176.000000000000000,121.000000000000000,0.237287779136815,0.290385733638894,119.000000000000000,0.429770876012296 +0.000000000000000,0.000016000000000,0.000108000000000,0.000532000000000,0.001507000000000,0.001176000000000,0.003390000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,503.000000000000000,195.000000000000000,121.000000000000000,0.255418654779892,0.271366103996528,119.000000000000000,0.401621830064983 +0.000000000000000,0.000023000000000,0.000128000000000,0.000118000000000,0.001247000000000,0.000704000000000,0.002255000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,519.000000000000000,192.000000000000000,121.000000000000000,0.243354932726649,0.322133765000893,118.000000000000000,0.476758002689501 +0.000000000000000,0.000028000000000,0.000117000000000,0.000194000000000,0.001487000000000,0.000763000000000,0.002640000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,537.000000000000000,182.000000000000000,121.000000000000000,0.256839812012575,0.290001379744665,120.000000000000000,0.429202006242450 +0.000000000000000,0.000021000000000,0.000192000000000,0.000135000000000,0.001268000000000,0.000737000000000,0.002390000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,551.000000000000000,186.000000000000000,121.000000000000000,0.234921062453291,0.278307687859489,121.000000000000000,0.411895400770342 +0.000000000000000,0.000023000000000,0.000110000000000,0.000128000000000,0.001205000000000,0.000853000000000,0.002375000000000,1.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,566.000000000000000,182.000000000000000,121.000000000000000,0.236213436253286,0.243545081705577,120.000000000000000,0.360446727806674 +0.000000000000000,0.000033000000000,0.000148000000000,0.000221000000000,0.001810000000000,0.000752000000000,0.003004000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,523.000000000000000,194.000000000000000,121.000000000000000,0.256770574347429,0.281629144927868,120.000000000000000,0.416811158357270 +0.000000000000000,0.000018000000000,0.000107000000000,0.000166000000000,0.001283000000000,0.000754000000000,0.002364000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,523.000000000000000,193.000000000000000,121.000000000000000,0.238569415669078,0.245006057597332,120.000000000000000,0.362608988913209 +0.000000000000000,0.000026000000000,0.000199000000000,0.000126000000000,0.001415000000000,0.000739000000000,0.002538000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,525.000000000000000,207.000000000000000,121.000000000000000,0.272522903927536,0.292694935292295,120.000000000000000,0.433188542480310 +0.000000000000000,0.000024000000000,0.000152000000000,0.000385000000000,0.001329000000000,0.000772000000000,0.002715000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,532.000000000000000,193.000000000000000,121.000000000000000,0.300157389608362,0.352279544787609,121.000000000000000,0.521373718272822 +0.000000000000000,0.000025000000000,0.000103000000000,0.000124000000000,0.001300000000000,0.000765000000000,0.002352000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,542.000000000000000,192.000000000000000,121.000000000000000,0.262925192895899,0.296136504354747,121.000000000000000,0.438282037121495 +0.000000000000000,0.000027000000000,0.000159000000000,0.000227000000000,0.001454000000000,0.000792000000000,0.002702000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,565.000000000000000,171.000000000000000,121.000000000000000,0.281949830225302,0.308467076957178,121.000000000000000,0.456531258033208 +0.000000000000000,0.000027000000000,0.000177000000000,0.000130000000000,0.001440000000000,0.000817000000000,0.002620000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,608.000000000000000,201.000000000000000,121.000000000000000,0.262127192155801,0.344178587739890,120.000000000000000,0.509384339297628 +0.000000000000000,0.000031000000000,0.000173000000000,0.000122000000000,0.001320000000000,0.000744000000000,0.002429000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,636.000000000000000,196.000000000000000,121.000000000000000,0.243118415564597,0.307364154563702,120.000000000000000,0.454898948018352 +0.000000000000000,0.000031000000000,0.000237000000000,0.000391000000000,0.002601000000000,0.000982000000000,0.004294000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,663.000000000000000,198.000000000000000,121.000000000000000,0.308234194177187,0.324201216218454,120.000000000000000,0.479817768949582 +0.000000000000000,0.000016000000000,0.000102000000000,0.000118000000000,0.001370000000000,0.000653000000000,0.002310000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,687.000000000000000,198.000000000000000,121.000000000000000,0.262171425081880,0.309537417467615,120.000000000000000,0.458115349322126 +0.000000000000000,0.000024000000000,0.000120000000000,0.000223000000000,0.001806000000000,0.000776000000000,0.002976000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,661.000000000000000,229.000000000000000,121.000000000000000,0.297772053023002,0.357203726783215,120.000000000000000,0.528661518750357 +0.000000000000000,0.000022000000000,0.000131000000000,0.000225000000000,0.001322000000000,0.000818000000000,0.002549000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,661.000000000000000,195.000000000000000,121.000000000000000,0.273836774721146,0.292258185663714,119.000000000000000,0.432542138616555 +0.000000000000000,0.000028000000000,0.000189000000000,0.000113000000000,0.001354000000000,0.000656000000000,0.002369000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,668.000000000000000,208.000000000000000,121.000000000000000,0.290291300745150,0.351263582277828,120.000000000000000,0.519870092614610 +0.000000000000000,0.000020000000000,0.000106000000000,0.000362000000000,0.002527000000000,0.000881000000000,0.003941000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,682.000000000000000,211.000000000000000,121.000000000000000,0.258959916330166,0.286061529228379,120.000000000000000,0.423371078465586 +0.000000000000000,0.000023000000000,0.000183000000000,0.000117000000000,0.001452000000000,0.000716000000000,0.002520000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,696.000000000000000,219.000000000000000,121.000000000000000,0.299843168031565,0.306288599781015,118.000000000000000,0.453307123537539 +0.000000000000000,0.000024000000000,0.000190000000000,0.000229000000000,0.001590000000000,0.000704000000000,0.002778000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,704.000000000000000,201.000000000000000,121.000000000000000,0.274895969986079,0.339774469390948,119.000000000000000,0.502866218860539 +0.000000000000000,0.000032000000000,0.000184000000000,0.000127000000000,0.001388000000000,0.000658000000000,0.002422000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,712.000000000000000,205.000000000000000,121.000000000000000,0.276261011279968,0.281429264300083,120.000000000000000,0.416515325859454 +0.000000000000000,0.000019000000000,0.000103000000000,0.000122000000000,0.001302000000000,0.000759000000000,0.002334000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,743.000000000000000,194.000000000000000,121.000000000000000,0.308426080941849,0.293337004748022,118.000000000000000,0.434138764752467 +0.000000000000000,0.000020000000000,0.000188000000000,0.000336000000000,0.002590000000000,0.000953000000000,0.004130000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,769.000000000000000,216.000000000000000,121.000000000000000,0.273447755201539,0.322902569141660,119.000000000000000,0.477895792772933 +0.000000000000000,0.000019000000000,0.000104000000000,0.000118000000000,0.001466000000000,0.000743000000000,0.002480000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,791.000000000000000,204.000000000000000,121.000000000000000,0.288081750238067,0.251959938318303,120.000000000000000,0.372900704820467 +0.000000000000000,0.000024000000000,0.000118000000000,0.000231000000000,0.001575000000000,0.000986000000000,0.003013000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,803.000000000000000,190.000000000000000,121.000000000000000,0.282457846343284,0.276454604943847,117.000000000000000,0.409152821737331 +0.000000000000000,0.000016000000000,0.000210000000000,0.000129000000000,0.001436000000000,0.000881000000000,0.002693000000000,0.000000000000000,111.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,781.000000000000000,208.000000000000000,121.000000000000000,0.294182859046983,0.317841061067694,121.000000000000000,0.470404755925379 +0.000000000000000,0.000015000000000,0.000142000000000,0.000184000000000,0.001424000000000,0.000955000000000,0.002755000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,781.000000000000000,194.000000000000000,121.000000000000000,0.243748783908456,0.304183797141307,119.000000000000000,0.450192011884479 +0.000000000000000,0.000014000000000,0.000107000000000,0.000318000000000,0.001624000000000,0.000893000000000,0.002992000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,803.000000000000000,220.000000000000000,121.000000000000000,0.265012454662619,0.270354981784829,119.000000000000000,0.400125381617550 +0.000000000000000,0.000023000000000,0.000213000000000,0.000128000000000,0.001340000000000,0.000949000000000,0.002681000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,811.000000000000000,196.000000000000000,121.000000000000000,0.253755971722852,0.269982133879470,119.000000000000000,0.399573570359238 +0.000000000000000,0.000038000000000,0.000249000000000,0.000219000000000,0.001747000000000,0.000847000000000,0.003214000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,821.000000000000000,217.000000000000000,121.000000000000000,0.242158110541114,0.277566291448718,118.000000000000000,0.410798121492822 +0.000000000000000,0.000022000000000,0.000200000000000,0.000131000000000,0.001465000000000,0.000761000000000,0.002608000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,826.000000000000000,208.000000000000000,121.000000000000000,0.247025005586580,0.299927107710462,119.000000000000000,0.443892088763821 +0.000000000000000,0.000028000000000,0.000129000000000,0.000115000000000,0.001507000000000,0.000767000000000,0.002582000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,835.000000000000000,206.000000000000000,121.000000000000000,0.251694282278063,0.262688495423133,119.000000000000000,0.388778969531936 +0.000000000000000,0.000018000000000,0.000176000000000,0.000303000000000,0.001569000000000,0.000763000000000,0.002865000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,858.000000000000000,208.000000000000000,121.000000000000000,0.204259521447942,0.239471125876921,121.000000000000000,0.354417264227415 +0.000000000000000,0.000027000000000,0.000197000000000,0.000119000000000,0.001520000000000,0.000717000000000,0.002613000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,887.000000000000000,182.000000000000000,121.000000000000000,0.288688133937508,0.321107040561571,121.000000000000000,0.475238455753857 +0.000000000000000,0.000074000000000,0.000308000000000,0.000231000000000,0.002302000000000,0.000817000000000,0.004009000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,895.000000000000000,169.000000000000000,121.000000000000000,0.226466756684178,0.283662806855079,120.000000000000000,0.419820962132456 +0.000000000000000,0.000032000000000,0.000120000000000,0.000146000000000,0.001779000000000,0.000719000000000,0.002820000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,887.000000000000000,201.000000000000000,121.000000000000000,0.248964133477333,0.301424345755280,121.000000000000000,0.446108027319984 +0.000000000000000,0.000031000000000,0.000209000000000,0.000347000000000,0.002379000000000,0.001268000000000,0.004286000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,881.000000000000000,197.000000000000000,121.000000000000000,0.197089987231914,0.215315450958625,121.000000000000000,0.318666844452755 +0.000000000000000,0.000022000000000,0.000183000000000,0.000138000000000,0.001523000000000,0.000904000000000,0.002805000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,889.000000000000000,208.000000000000000,121.000000000000000,0.211913610123421,0.217730864556872,121.000000000000000,0.322241701945577 +0.000000000000000,0.000023000000000,0.000188000000000,0.000135000000000,0.001539000000000,0.001010000000000,0.002927000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,912.000000000000000,191.000000000000000,121.000000000000000,0.223781553150169,0.264534665335954,119.000000000000000,0.391511288186158 +0.000000000000000,0.000024000000000,0.000111000000000,0.000561000000000,0.002319000000000,0.001083000000000,0.004153000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,959.000000000000000,191.000000000000000,121.000000000000000,0.192480342616366,0.242812113218322,120.000000000000000,0.359361932832411 +0.000000000000000,0.000023000000000,0.000113000000000,0.000129000000000,0.001473000000000,0.000780000000000,0.002555000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1010.000000000000000,186.000000000000000,121.000000000000000,0.226239188570666,0.246580462159093,121.000000000000000,0.364939080501376 +0.000000000000000,0.000025000000000,0.000147000000000,0.000235000000000,0.001877000000000,0.001081000000000,0.003415000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1042.000000000000000,191.000000000000000,121.000000000000000,0.213010810373553,0.226959616128893,121.000000000000000,0.335900212048673 +0.000000000000000,0.000019000000000,0.000180000000000,0.000123000000000,0.001581000000000,0.000797000000000,0.002856000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1066.000000000000000,197.000000000000000,121.000000000000000,0.236500218717681,0.308339991149568,118.000000000000000,0.456343184784554 +0.000000000000000,0.000020000000000,0.000176000000000,0.000124000000000,0.001670000000000,0.001020000000000,0.003039000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1045.000000000000000,222.000000000000000,121.000000000000000,0.203403550946325,0.322649020817046,119.000000000000000,0.477520556062907 +0.000000000000000,0.000021000000000,0.000102000000000,0.000120000000000,0.001506000000000,0.000747000000000,0.002537000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1040.000000000000000,208.000000000000000,121.000000000000000,0.217457541731394,0.242874100604298,119.000000000000000,0.359453694988533 +0.000000000000000,0.000014000000000,0.000102000000000,0.000114000000000,0.001438000000000,0.000775000000000,0.002481000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,202.000000000000000,121.000000000000000,0.237066555963892,0.363698547046353,120.000000000000000,0.538273825733024 +0.000000000000000,0.000028000000000,0.000138000000000,0.000130000000000,0.001867000000000,0.000905000000000,0.003190000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1051.000000000000000,204.000000000000000,121.000000000000000,0.204004037194742,0.217771792656962,121.000000000000000,0.322302253343558 +0.000000000000000,0.000016000000000,0.000108000000000,0.000146000000000,0.001730000000000,0.000807000000000,0.002848000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1092.000000000000000,216.000000000000000,121.000000000000000,0.189498788663577,0.218460412109291,119.000000000000000,0.323321417274184 +0.000000000000000,0.000021000000000,0.000142000000000,0.000136000000000,0.001571000000000,0.000950000000000,0.002860000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1150.000000000000000,195.000000000000000,121.000000000000000,0.234911243099688,0.229840840010708,121.000000000000000,0.340164460854319 +0.000000000000000,0.000023000000000,0.000178000000000,0.000327000000000,0.001509000000000,0.001060000000000,0.003143000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1188.000000000000000,188.000000000000000,121.000000000000000,0.238938910296195,0.242239031677996,119.000000000000000,0.358513758367035 +0.000000000000000,0.000026000000000,0.000127000000000,0.000121000000000,0.001413000000000,0.000746000000000,0.002666000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1209.000000000000000,181.000000000000000,121.000000000000000,0.231069770120829,0.351821144360750,121.000000000000000,0.520695269679250 +0.000000000000000,0.000013000000000,0.000123000000000,0.000156000000000,0.002291000000000,0.000810000000000,0.003493000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1131.000000000000000,223.000000000000000,121.000000000000000,0.232050436410629,0.243086413240903,121.000000000000000,0.359767900135068 +0.000000000000000,0.000017000000000,0.000183000000000,0.000122000000000,0.001660000000000,0.000828000000000,0.002856000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1126.000000000000000,205.000000000000000,121.000000000000000,0.217672407670591,0.232176089084970,120.000000000000000,0.343620616378729 +0.000000000000000,0.000025000000000,0.000104000000000,0.000126000000000,0.001640000000000,0.000956000000000,0.002894000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1122.000000000000000,225.000000000000000,121.000000000000000,0.210874531577464,0.231177462797771,120.000000000000000,0.342142641667492 +0.000000000000000,0.000011000000000,0.000104000000000,0.000149000000000,0.001579000000000,0.000928000000000,0.002811000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1124.000000000000000,218.000000000000000,121.000000000000000,0.199068638688048,0.231930228681434,121.000000000000000,0.343256752009726 +0.000000000000000,0.000016000000000,0.000105000000000,0.000114000000000,0.001529000000000,0.000835000000000,0.002636000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1131.000000000000000,217.000000000000000,121.000000000000000,0.199461859922069,0.201973412653913,121.000000000000000,0.298920644384362 +0.000000000000000,0.000020000000000,0.000107000000000,0.000175000000000,0.002271000000000,0.000832000000000,0.003453000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1170.000000000000000,216.000000000000000,121.000000000000000,0.220686177070489,0.284068818474203,121.000000000000000,0.420421851360250 +0.000000000000000,0.000021000000000,0.000110000000000,0.000115000000000,0.001720000000000,0.000987000000000,0.002996000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1207.000000000000000,220.000000000000000,121.000000000000000,0.211157109658996,0.207022193542394,121.000000000000000,0.306392853689555 +0.000000000000000,0.000019000000000,0.000128000000000,0.000124000000000,0.001660000000000,0.000836000000000,0.002805000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1249.000000000000000,230.000000000000000,121.000000000000000,0.227298389602018,0.273505984323976,121.000000000000000,0.404788875408716 +0.000000000000000,0.000019000000000,0.000103000000000,0.000135000000000,0.001696000000000,0.000751000000000,0.002919000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,235.000000000000000,121.000000000000000,0.230641563123264,0.341660758731761,121.000000000000000,0.505657951678639 +0.000000000000000,0.000015000000000,0.000177000000000,0.000130000000000,0.001556000000000,0.000919000000000,0.002864000000000,0.000000000000000,106.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1118.000000000000000,225.000000000000000,121.000000000000000,0.192303276106424,0.284766422639249,121.000000000000000,0.421454308293938 +0.000000000000000,0.000013000000000,0.000138000000000,0.000178000000000,0.002041000000000,0.000992000000000,0.003412000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1112.000000000000000,223.000000000000000,121.000000000000000,0.206634709237684,0.414844586254086,120.000000000000000,0.613969997701391 +0.000000000000000,0.000015000000000,0.000134000000000,0.000127000000000,0.001905000000000,0.000764000000000,0.002995000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1116.000000000000000,248.000000000000000,121.000000000000000,0.217282816286385,0.386388750278064,121.000000000000000,0.571855388443357 +0.000000000000000,0.000016000000000,0.000128000000000,0.000127000000000,0.001825000000000,0.000925000000000,0.003066000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1115.000000000000000,245.000000000000000,121.000000000000000,0.205232081617916,0.260414398266005,121.000000000000000,0.385413312570202 +0.000000000000000,0.000020000000000,0.000107000000000,0.000141000000000,0.001807000000000,0.000923000000000,0.003060000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1141.000000000000000,234.000000000000000,121.000000000000000,0.215575249362573,0.253408200953891,120.000000000000000,0.375044163656510 +0.000000000000000,0.000019000000000,0.000128000000000,0.000120000000000,0.001568000000000,0.000884000000000,0.002762000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1162.000000000000000,189.000000000000000,121.000000000000000,0.263382144346756,0.344167879309156,121.000000000000000,0.509368468563933 +0.000000000000000,0.000023000000000,0.000131000000000,0.000373000000000,0.001757000000000,0.001182000000000,0.003515000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1191.000000000000000,211.000000000000000,121.000000000000000,0.211945557067404,0.302128504397490,121.000000000000000,0.447150188651345 +0.000000000000000,0.000025000000000,0.000154000000000,0.000124000000000,0.001844000000000,0.000803000000000,0.003004000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1216.000000000000000,227.000000000000000,121.000000000000000,0.202381916559221,0.390013881008811,120.000000000000000,0.577220555675650 +0.000000000000000,0.000015000000000,0.000109000000000,0.000129000000000,0.001708000000000,0.000890000000000,0.002894000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1231.000000000000000,213.000000000000000,121.000000000000000,0.214162701863959,0.216971594768139,120.000000000000000,0.321117988293146 +0.000000000000000,0.000019000000000,0.000106000000000,0.000141000000000,0.001738000000000,0.000788000000000,0.002834000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,223.000000000000000,121.000000000000000,0.199426583525084,0.257295226754736,121.000000000000000,0.380796925542741 +0.000000000000000,0.000015000000000,0.000104000000000,0.000127000000000,0.001749000000000,0.000817000000000,0.002854000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,237.000000000000000,121.000000000000000,0.197980287517504,0.261753748672962,121.000000000000000,0.387395536882405 +0.000000000000000,0.000022000000000,0.000120000000000,0.000159000000000,0.002300000000000,0.000963000000000,0.003628000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1233.000000000000000,228.000000000000000,121.000000000000000,0.236498759179881,0.240201532654298,121.000000000000000,0.355498268421338 +0.000000000000000,0.000017000000000,0.000181000000000,0.000128000000000,0.001959000000000,0.000872000000000,0.003382000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,248.000000000000000,121.000000000000000,0.184287569106640,0.201686577196243,121.000000000000000,0.298496127529902 +0.000000000000000,0.000013000000000,0.000178000000000,0.000136000000000,0.001684000000000,0.000852000000000,0.002943000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1105.000000000000000,230.000000000000000,121.000000000000000,0.190585604418642,0.200521952748998,120.000000000000000,0.296772510252565 +0.000000000000000,0.000019000000000,0.000106000000000,0.000143000000000,0.001668000000000,0.000981000000000,0.002955000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1104.000000000000000,218.000000000000000,121.000000000000000,0.200527511479873,0.209064190915326,120.000000000000000,0.309415015408653 +0.000000000000000,0.000014000000000,0.000104000000000,0.000123000000000,0.001517000000000,0.000849000000000,0.002647000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1144.000000000000000,201.000000000000000,121.000000000000000,0.227018266784565,0.269186250934732,121.000000000000000,0.398395648547930 +0.000000000000000,0.000017000000000,0.000178000000000,0.000348000000000,0.001620000000000,0.001141000000000,0.003354000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1182.000000000000000,206.000000000000000,121.000000000000000,0.206456021778136,0.213075158345683,121.000000000000000,0.315351251063391 +0.000000000000000,0.000026000000000,0.000108000000000,0.000150000000000,0.001619000000000,0.000821000000000,0.002770000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1214.000000000000000,197.000000000000000,121.000000000000000,0.195769620795380,0.235699009656539,120.000000000000000,0.348834556747284 +0.000000000000000,0.000018000000000,0.000178000000000,0.000127000000000,0.001593000000000,0.000826000000000,0.002776000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,206.000000000000000,121.000000000000000,0.202443810598108,0.259322628022743,121.000000000000000,0.383797505085764 +0.000000000000000,0.000018000000000,0.000105000000000,0.000140000000000,0.001539000000000,0.001030000000000,0.002870000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1255.000000000000000,195.000000000000000,121.000000000000000,0.234795060265796,0.251596569636394,120.000000000000000,0.372362919449417 +0.000000000000000,0.000017000000000,0.000175000000000,0.000125000000000,0.001584000000000,0.000833000000000,0.002923000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1267.000000000000000,221.000000000000000,121.000000000000000,0.207163879614002,0.272216719799699,121.000000000000000,0.402880748216245 +0.000000000000000,0.000017000000000,0.000133000000000,0.000153000000000,0.002442000000000,0.000831000000000,0.003670000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1147.000000000000000,216.000000000000000,121.000000000000000,0.170524915168911,0.199849692332816,121.000000000000000,0.295777531500515 +0.000000000000000,0.000013000000000,0.000157000000000,0.000149000000000,0.001748000000000,0.000942000000000,0.003057000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1147.000000000000000,234.000000000000000,121.000000000000000,0.189221335752284,0.197743002271810,121.000000000000000,0.292659639941872 +0.000000000000000,0.000020000000000,0.000178000000000,0.000125000000000,0.001721000000000,0.000742000000000,0.002827000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1176.000000000000000,225.000000000000000,121.000000000000000,0.198900978356214,0.245389821232497,119.000000000000000,0.363176948895773 +0.000000000000000,0.000013000000000,0.000176000000000,0.000145000000000,0.001697000000000,0.000855000000000,0.002929000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1221.000000000000000,222.000000000000000,121.000000000000000,0.196051895442564,0.262432687056220,121.000000000000000,0.388400396935210 +0.000000000000000,0.000015000000000,0.000176000000000,0.000128000000000,0.001658000000000,0.000736000000000,0.002754000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1264.000000000000000,222.000000000000000,121.000000000000000,0.188130722176495,0.226906201366918,120.000000000000000,0.335821186914497 +0.000000000000000,0.000015000000000,0.000114000000000,0.000128000000000,0.001732000000000,0.000994000000000,0.003025000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1280.000000000000000,221.000000000000000,121.000000000000000,0.195205519657246,0.208004184809569,119.000000000000000,0.307846188328575 +0.000000000000000,0.000020000000000,0.000195000000000,0.000126000000000,0.002006000000000,0.000791000000000,0.003194000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1295.000000000000000,262.000000000000000,121.000000000000000,0.204929539974912,0.216820480192029,119.000000000000000,0.320894306981155 +0.000000000000000,0.000017000000000,0.000176000000000,0.000139000000000,0.001546000000000,0.000896000000000,0.002812000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1303.000000000000000,192.000000000000000,121.000000000000000,0.226704780607630,0.257512342665443,120.000000000000000,0.381118257356317 +0.000000000000000,0.000011000000000,0.000105000000000,0.000299000000000,0.001761000000000,0.001102000000000,0.003328000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1303.000000000000000,234.000000000000000,121.000000000000000,0.206579202251784,0.240623999885611,121.000000000000000,0.356123519730790 +0.000000000000000,0.000020000000000,0.000103000000000,0.000130000000000,0.001498000000000,0.000871000000000,0.002766000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1312.000000000000000,207.000000000000000,121.000000000000000,0.208586912880041,0.214158703806542,121.000000000000000,0.316954877506999 +0.000000000000000,0.000017000000000,0.000176000000000,0.000374000000000,0.001665000000000,0.000976000000000,0.003373000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1139.000000000000000,223.000000000000000,121.000000000000000,0.209543770412094,0.213150938854858,121.000000000000000,0.315463382345879 +0.000000000000000,0.000021000000000,0.000157000000000,0.000124000000000,0.001652000000000,0.000947000000000,0.002947000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1137.000000000000000,212.000000000000000,121.000000000000000,0.214888927283406,0.261239649375707,120.000000000000000,0.386634701996087 +0.000000000000000,0.000018000000000,0.000104000000000,0.000124000000000,0.001479000000000,0.000897000000000,0.002661000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1182.000000000000000,188.000000000000000,121.000000000000000,0.205526459876717,0.194046988139053,121.000000000000000,0.287189543909738 +0.000000000000000,0.000016000000000,0.000175000000000,0.000142000000000,0.001509000000000,0.000744000000000,0.002626000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,190.000000000000000,121.000000000000000,0.193638964960760,0.209501566643394,121.000000000000000,0.310062329059690 +0.000000000000000,0.000022000000000,0.000103000000000,0.000125000000000,0.001561000000000,0.000725000000000,0.002572000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1250.000000000000000,218.000000000000000,121.000000000000000,0.192895828207804,0.213686959411965,121.000000000000000,0.316256716855654 +0.000000000000000,0.000023000000000,0.000184000000000,0.000162000000000,0.001899000000000,0.000812000000000,0.003140000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1258.000000000000000,187.000000000000000,121.000000000000000,0.178433372351327,0.196124969530122,120.000000000000000,0.290264953456693 +0.000000000000000,0.000016000000000,0.000134000000000,0.000140000000000,0.001663000000000,0.000876000000000,0.002874000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1274.000000000000000,203.000000000000000,121.000000000000000,0.204379056805537,0.211513754780143,119.000000000000000,0.313040366095618 +0.000000000000000,0.000020000000000,0.000176000000000,0.000130000000000,0.001587000000000,0.000869000000000,0.002823000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1284.000000000000000,206.000000000000000,121.000000000000000,0.194394953473234,0.214318086264921,121.000000000000000,0.317190765131688 +0.000000000000000,0.000017000000000,0.000107000000000,0.000148000000000,0.001575000000000,0.000805000000000,0.002693000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1286.000000000000000,205.000000000000000,121.000000000000000,0.192692252511560,0.217301832678175,121.000000000000000,0.321606720966583 +0.000000000000000,0.000020000000000,0.000173000000000,0.000124000000000,0.001507000000000,0.000785000000000,0.002649000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,210.000000000000000,121.000000000000000,0.204881580167579,0.231890569564824,121.000000000000000,0.343198045458178 +0.000000000000000,0.000041000000000,0.000220000000000,0.000144000000000,0.001900000000000,0.000655000000000,0.003038000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,206.000000000000000,121.000000000000000,0.174115401194611,0.223973720218107,121.000000000000000,0.331481122502030 +0.000000000000000,0.000043000000000,0.000182000000000,0.000145000000000,0.001457000000000,0.000728000000000,0.002734000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1272.000000000000000,191.000000000000000,121.000000000000000,0.194538477548438,0.187220557909554,121.000000000000000,0.277086431960381 +0.000000000000000,0.000020000000000,0.000182000000000,0.000129000000000,0.001451000000000,0.000813000000000,0.002657000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1148.000000000000000,207.000000000000000,121.000000000000000,0.209547468410092,0.205381330935579,119.000000000000000,0.303964378715603 +0.000000000000000,0.000037000000000,0.000255000000000,0.000211000000000,0.002943000000000,0.001198000000000,0.004740000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1146.000000000000000,192.000000000000000,121.000000000000000,0.194112090334278,0.213834860708738,121.000000000000000,0.316475596512546 +0.000000000000000,0.000021000000000,0.000119000000000,0.000128000000000,0.001482000000000,0.000836000000000,0.002622000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1196.000000000000000,188.000000000000000,121.000000000000000,0.194707145965396,0.200711676435348,120.000000000000000,0.297053280716492 +0.000000000000000,0.000018000000000,0.000128000000000,0.000353000000000,0.001530000000000,0.001123000000000,0.003198000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1222.000000000000000,182.000000000000000,121.000000000000000,0.165297929068422,0.223118899091734,120.000000000000000,0.330215962199139 +0.000000000000000,0.000019000000000,0.000133000000000,0.000124000000000,0.001554000000000,0.001016000000000,0.002890000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1250.000000000000000,187.000000000000000,121.000000000000000,0.189732092265728,0.231665076279646,121.000000000000000,0.342864305156952 +0.000000000000000,0.000018000000000,0.000195000000000,0.000130000000000,0.001387000000000,0.000871000000000,0.002639000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,167.000000000000000,121.000000000000000,0.173396135722069,0.185374303680201,121.000000000000000,0.274353961674946 +0.000000000000000,0.000015000000000,0.000105000000000,0.000165000000000,0.001566000000000,0.001052000000000,0.002950000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1292.000000000000000,196.000000000000000,121.000000000000000,0.192868888286218,0.205034141945327,120.000000000000000,0.303450551076308 +0.000000000000000,0.000014000000000,0.000102000000000,0.000127000000000,0.001521000000000,0.000791000000000,0.002592000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1302.000000000000000,199.000000000000000,121.000000000000000,0.190528673137881,0.222906754530888,121.000000000000000,0.329902009771293 +0.000000000000000,0.000021000000000,0.000215000000000,0.000167000000000,0.001934000000000,0.000805000000000,0.003204000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1308.000000000000000,190.000000000000000,121.000000000000000,0.202526348712512,0.259278841345545,120.000000000000000,0.383732682741932 +0.000000000000000,0.000022000000000,0.000156000000000,0.000126000000000,0.001696000000000,0.000788000000000,0.002834000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1308.000000000000000,190.000000000000000,121.000000000000000,0.196451913404442,0.201069768524068,120.000000000000000,0.297583282351909 +0.000000000000000,0.000025000000000,0.000103000000000,0.000132000000000,0.001543000000000,0.000902000000000,0.002745000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1305.000000000000000,194.000000000000000,121.000000000000000,0.200871633124814,0.183908150343481,120.000000000000000,0.272184068463992 +0.000000000000000,0.000025000000000,0.000102000000000,0.000150000000000,0.001478000000000,0.000854000000000,0.002788000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1335.000000000000000,179.000000000000000,121.000000000000000,0.193823047570574,0.212329442302877,119.000000000000000,0.314247578003029 +0.000000000000000,0.000016000000000,0.000196000000000,0.000126000000000,0.001299000000000,0.000752000000000,0.002455000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1194.000000000000000,176.000000000000000,121.000000000000000,0.207923081779578,0.229508478265270,121.000000000000000,0.339672543925396 +0.000000000000000,0.000018000000000,0.000110000000000,0.000166000000000,0.001844000000000,0.000982000000000,0.003170000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1189.000000000000000,180.000000000000000,121.000000000000000,0.163342705330096,0.249575746286056,120.000000000000000,0.369372120119674 +0.000000000000000,0.000015000000000,0.000183000000000,0.000124000000000,0.001749000000000,0.000847000000000,0.002963000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1218.000000000000000,212.000000000000000,121.000000000000000,0.173881865983057,0.194395754595030,121.000000000000000,0.287705721832844 +0.000000000000000,0.000026000000000,0.000176000000000,0.000127000000000,0.001498000000000,0.000877000000000,0.002752000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1259.000000000000000,185.000000000000000,121.000000000000000,0.155523040470466,0.162766723518840,120.000000000000000,0.240894740082153 +0.000000000000000,0.000015000000000,0.000177000000000,0.000144000000000,0.001550000000000,0.000743000000000,0.002669000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,192.000000000000000,121.000000000000000,0.152934150143871,0.272911472202902,121.000000000000000,0.403908984747820 +0.000000000000000,0.000014000000000,0.000174000000000,0.000116000000000,0.001439000000000,0.000731000000000,0.002513000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1291.000000000000000,196.000000000000000,121.000000000000000,0.188113809380047,0.184618919088813,121.000000000000000,0.273236010008633 +0.000000000000000,0.000016000000000,0.000106000000000,0.000145000000000,0.002198000000000,0.000804000000000,0.003318000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1299.000000000000000,184.000000000000000,121.000000000000000,0.189391540723312,0.210953756830538,121.000000000000000,0.312211549881851 +0.000000000000000,0.000019000000000,0.000181000000000,0.000116000000000,0.001662000000000,0.000840000000000,0.002865000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1306.000000000000000,204.000000000000000,121.000000000000000,0.184488742976474,0.215925329354907,121.000000000000000,0.319569479795696 +0.000000000000000,0.000016000000000,0.000183000000000,0.000132000000000,0.001540000000000,0.000737000000000,0.002647000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1313.000000000000000,197.000000000000000,121.000000000000000,0.164667840588859,0.233194073999862,121.000000000000000,0.345127224117476 +0.000000000000000,0.000017000000000,0.000177000000000,0.000144000000000,0.001453000000000,0.000747000000000,0.002725000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1307.000000000000000,179.000000000000000,121.000000000000000,0.190996220324968,0.267097150771334,121.000000000000000,0.395303787014294 +0.000000000000000,0.000017000000000,0.000177000000000,0.000120000000000,0.001414000000000,0.000681000000000,0.002474000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1109.000000000000000,205.000000000000000,121.000000000000000,0.175048358387321,0.227273301247532,121.000000000000000,0.336364481552976 +0.000000000000000,0.000023000000000,0.000186000000000,0.000160000000000,0.001932000000000,0.000738000000000,0.003097000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1100.000000000000000,194.000000000000000,121.000000000000000,0.173557283673669,0.191658131610694,121.000000000000000,0.283654034716855 +0.000000000000000,0.000019000000000,0.000107000000000,0.000116000000000,0.001671000000000,0.000745000000000,0.002708000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1144.000000000000000,204.000000000000000,121.000000000000000,0.158568907261423,0.243359531069700,121.000000000000000,0.360172098406900 +0.000000000000000,0.000018000000000,0.000103000000000,0.000132000000000,0.001512000000000,0.000732000000000,0.002547000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1187.000000000000000,194.000000000000000,121.000000000000000,0.146749823653506,0.164413086505490,121.000000000000000,0.243331352597904 +0.000000000000000,0.000014000000000,0.000181000000000,0.000144000000000,0.001537000000000,0.000892000000000,0.002808000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1214.000000000000000,196.000000000000000,121.000000000000000,0.131283592229348,0.155956326816494,121.000000000000000,0.230815358417731 +0.000000000000000,0.000012000000000,0.000176000000000,0.000121000000000,0.001482000000000,0.000877000000000,0.002705000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1244.000000000000000,196.000000000000000,121.000000000000000,0.159033296053125,0.194395333842714,121.000000000000000,0.287705090036121 +0.000000000000000,0.000020000000000,0.000211000000000,0.000162000000000,0.001881000000000,0.000840000000000,0.003174000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1262.000000000000000,184.000000000000000,121.000000000000000,0.163845159646448,0.177604150932044,121.000000000000000,0.262854149344864 +0.000000000000000,0.000015000000000,0.000115000000000,0.000124000000000,0.001771000000000,0.000924000000000,0.002997000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1269.000000000000000,218.000000000000000,121.000000000000000,0.167741708685618,0.187775885781358,121.000000000000000,0.277908323682058 +0.000000000000000,0.000012000000000,0.000104000000000,0.000127000000000,0.001764000000000,0.000780000000000,0.002830000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1278.000000000000000,229.000000000000000,121.000000000000000,0.186347950475868,0.251813866360726,121.000000000000000,0.372684503981683 +0.000000000000000,0.000020000000000,0.000102000000000,0.000142000000000,0.001444000000000,0.000872000000000,0.002621000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1275.000000000000000,174.000000000000000,121.000000000000000,0.166303486197133,0.189747084068580,120.000000000000000,0.280825682960661 +0.000000000000000,0.000016000000000,0.000125000000000,0.000117000000000,0.001504000000000,0.000769000000000,0.002568000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1276.000000000000000,202.000000000000000,121.000000000000000,0.167769122437661,0.195787376215580,121.000000000000000,0.289765303335874 +0.000000000000000,0.000029000000000,0.000158000000000,0.000154000000000,0.001818000000000,0.000771000000000,0.003044000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1304.000000000000000,177.000000000000000,121.000000000000000,0.158463858246833,0.191255881763862,119.000000000000000,0.283058705300228 +0.000000000000000,0.000020000000000,0.000185000000000,0.000118000000000,0.001683000000000,0.000786000000000,0.002860000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1339.000000000000000,206.000000000000000,121.000000000000000,0.161183566619254,0.178028171732775,121.000000000000000,0.263481700394391 +0.000000000000000,0.000017000000000,0.000177000000000,0.000136000000000,0.001597000000000,0.000782000000000,0.002874000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1383.000000000000000,198.000000000000000,121.000000000000000,0.142916686874711,0.162123928033689,121.000000000000000,0.239943431119633 +0.000000000000000,0.000016000000000,0.000127000000000,0.000234000000000,0.001629000000000,0.000716000000000,0.002906000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,214.000000000000000,121.000000000000000,0.154355717762879,0.218609409653489,121.000000000000000,0.323541914330688 +0.000000000000000,0.000018000000000,0.000175000000000,0.000117000000000,0.001623000000000,0.000874000000000,0.002848000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1218.000000000000000,227.000000000000000,121.000000000000000,0.174558038196839,0.199124535422790,121.000000000000000,0.294704311042227 +0.000000000000000,0.000023000000000,0.000101000000000,0.000109000000000,0.001533000000000,0.000703000000000,0.002504000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1228.000000000000000,215.000000000000000,121.000000000000000,0.137995003938898,0.152632389051692,121.000000000000000,0.225895936409808 +0.000000000000000,0.000027000000000,0.000177000000000,0.000139000000000,0.001775000000000,0.000662000000000,0.002820000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1232.000000000000000,237.000000000000000,121.000000000000000,0.135541904251767,0.167668386817417,121.000000000000000,0.248149206964557 +0.000000000000000,0.000022000000000,0.000181000000000,0.000307000000000,0.001635000000000,0.001033000000000,0.003237000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1233.000000000000000,200.000000000000000,121.000000000000000,0.163536557849499,0.206044880204936,121.000000000000000,0.304946443542624 +0.000000000000000,0.000013000000000,0.000197000000000,0.000138000000000,0.001693000000000,0.000665000000000,0.002750000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1227.000000000000000,224.000000000000000,121.000000000000000,0.153373223673703,0.199555553830275,120.000000000000000,0.295342223558018 +0.000000000000000,0.000022000000000,0.000130000000000,0.000127000000000,0.001747000000000,0.000744000000000,0.002816000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,234.000000000000000,121.000000000000000,0.139032943637894,0.186670354479152,121.000000000000000,0.276272121799386 +0.000000000000000,0.000023000000000,0.000189000000000,0.000117000000000,0.001436000000000,0.000905000000000,0.002707000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,191.000000000000000,121.000000000000000,0.139072087006321,0.170137357542569,121.000000000000000,0.251803291766507 +0.000000000000000,0.000019000000000,0.000189000000000,0.000134000000000,0.001636000000000,0.001043000000000,0.003059000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1226.000000000000000,205.000000000000000,121.000000000000000,0.147221191440148,0.219839242753776,121.000000000000000,0.325362095419246 +0.000000000000000,0.000026000000000,0.000136000000000,0.000141000000000,0.001640000000000,0.000834000000000,0.002814000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1226.000000000000000,198.000000000000000,121.000000000000000,0.134535729635055,0.177361976863745,120.000000000000000,0.262495743699553 +0.000000000000000,0.000024000000000,0.000188000000000,0.000137000000000,0.001576000000000,0.000999000000000,0.002968000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1224.000000000000000,202.000000000000000,121.000000000000000,0.150440594097383,0.170822892372034,120.000000000000000,0.252817881488855 +0.000000000000000,0.000018000000000,0.000128000000000,0.000123000000000,0.001595000000000,0.000906000000000,0.002923000000000,1.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,211.000000000000000,121.000000000000000,0.161157776486683,0.176850558454008,121.000000000000000,0.261738825952921 +0.000000000000000,0.000023000000000,0.000171000000000,0.000136000000000,0.001546000000000,0.000836000000000,0.002772000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1094.000000000000000,211.000000000000000,121.000000000000000,0.135044752661059,0.176661372259443,121.000000000000000,0.261458838916931 +0.000000000000000,0.000016000000000,0.000180000000000,0.000129000000000,0.001692000000000,0.000849000000000,0.002919000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1089.000000000000000,203.000000000000000,121.000000000000000,0.143949354754192,0.167668782751111,120.000000000000000,0.248149788217542 +0.000000000000000,0.000017000000000,0.000108000000000,0.000139000000000,0.001568000000000,0.000704000000000,0.002578000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1166.000000000000000,200.000000000000000,121.000000000000000,0.155160670749007,0.231930876186467,120.000000000000000,0.343257712340746 +0.000000000000000,0.000035000000000,0.000227000000000,0.000132000000000,0.001664000000000,0.000790000000000,0.002968000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1216.000000000000000,195.000000000000000,121.000000000000000,0.133676069237326,0.147626375091364,120.000000000000000,0.218487058408179 +0.000000000000000,0.000015000000000,0.000128000000000,0.000120000000000,0.001551000000000,0.000732000000000,0.002590000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1232.000000000000000,204.000000000000000,121.000000000000000,0.122400626475427,0.146223124911287,121.000000000000000,0.216410216218663 +0.000000000000000,0.000020000000000,0.000245000000000,0.000118000000000,0.001618000000000,0.000770000000000,0.002815000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1238.000000000000000,219.000000000000000,121.000000000000000,0.137303784430655,0.150577933818061,121.000000000000000,0.222855351498252 +0.000000000000000,0.000016000000000,0.000214000000000,0.000131000000000,0.001570000000000,0.000888000000000,0.002875000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1239.000000000000000,183.000000000000000,121.000000000000000,0.131464957645487,0.148026075188344,121.000000000000000,0.219078597044465 +0.000000000000000,0.000018000000000,0.000103000000000,0.000139000000000,0.001556000000000,0.000929000000000,0.002796000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,197.000000000000000,121.000000000000000,0.128347170794260,0.131002024287506,121.000000000000000,0.193882998604601 +0.000000000000000,0.000034000000000,0.000281000000000,0.000139000000000,0.001662000000000,0.000725000000000,0.002956000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1226.000000000000000,194.000000000000000,121.000000000000000,0.162024538919116,0.207094523301695,121.000000000000000,0.306499905326386 +0.000000000000000,0.000019000000000,0.000198000000000,0.000119000000000,0.001621000000000,0.000844000000000,0.002973000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1223.000000000000000,215.000000000000000,121.000000000000000,0.153235488057770,0.262436341625619,121.000000000000000,0.388405779843294 +0.000000000000000,0.000021000000000,0.000198000000000,0.000131000000000,0.001561000000000,0.000847000000000,0.002828000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1054.000000000000000,201.000000000000000,121.000000000000000,0.157919685289792,0.167838875425546,121.000000000000000,0.248401521304057 +0.000000000000000,0.000015000000000,0.000170000000000,0.000130000000000,0.001648000000000,0.000666000000000,0.002683000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,211.000000000000000,121.000000000000000,0.142424009465490,0.209332762567431,120.000000000000000,0.309812491363346 +0.000000000000000,0.000020000000000,0.000127000000000,0.000139000000000,0.001528000000000,0.000726000000000,0.002588000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1039.000000000000000,207.000000000000000,121.000000000000000,0.140603779602412,0.159626649619649,121.000000000000000,0.236247445558979 +0.000000000000000,0.000019000000000,0.000194000000000,0.000143000000000,0.001999000000000,0.000624000000000,0.003025000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1040.000000000000000,205.000000000000000,121.000000000000000,0.147458908627836,0.237281094131071,121.000000000000000,0.351176020676474 +0.000000000000000,0.000022000000000,0.000175000000000,0.000126000000000,0.001454000000000,0.000837000000000,0.002656000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1106.000000000000000,198.000000000000000,121.000000000000000,0.125862132363062,0.146166756283214,120.000000000000000,0.216326793779291 +0.000000000000000,0.000018000000000,0.000233000000000,0.000119000000000,0.001470000000000,0.000923000000000,0.002807000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1145.000000000000000,188.000000000000000,121.000000000000000,0.148866800739627,0.175671536734951,121.000000000000000,0.259993879218198 +0.000000000000000,0.000021000000000,0.000205000000000,0.000128000000000,0.001543000000000,0.000761000000000,0.002708000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1156.000000000000000,186.000000000000000,121.000000000000000,0.127848678819928,0.170790549426913,121.000000000000000,0.252770016569082 +0.000000000000000,0.000016000000000,0.000176000000000,0.000145000000000,0.001515000000000,0.000719000000000,0.002758000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1165.000000000000000,189.000000000000000,121.000000000000000,0.145912191034524,0.246210134411681,121.000000000000000,0.364391034751536 +0.000000000000000,0.000017000000000,0.000137000000000,0.000142000000000,0.001535000000000,0.000625000000000,0.002544000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1007.000000000000000,197.000000000000000,121.000000000000000,0.155415123408675,0.250107101898265,121.000000000000000,0.370158504865490 +0.000000000000000,0.000018000000000,0.000187000000000,0.000129000000000,0.001485000000000,0.000745000000000,0.002609000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,997.000000000000000,196.000000000000000,121.000000000000000,0.156330994449520,0.195977327324711,121.000000000000000,0.290046452877835 +0.000000000000000,0.000027000000000,0.000216000000000,0.000122000000000,0.001463000000000,0.000715000000000,0.002603000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,994.000000000000000,202.000000000000000,121.000000000000000,0.148181823678736,0.163960783045368,121.000000000000000,0.242661951333412 +0.000000000000000,0.000021000000000,0.000148000000000,0.000131000000000,0.001726000000000,0.000788000000000,0.002871000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,990.000000000000000,214.000000000000000,121.000000000000000,0.159041550968813,0.290710356872846,121.000000000000000,0.430251294240852 +0.000000000000000,0.000014000000000,0.000109000000000,0.000146000000000,0.001782000000000,0.000832000000000,0.002935000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,989.000000000000000,237.000000000000000,121.000000000000000,0.144598980992546,0.166027958406800,121.000000000000000,0.245721363787328 +0.000000000000000,0.000033000000000,0.000225000000000,0.000141000000000,0.001562000000000,0.000724000000000,0.002797000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,989.000000000000000,200.000000000000000,121.000000000000000,0.138993500529387,0.196990361228138,121.000000000000000,0.291545731774589 +0.000000000000000,0.000018000000000,0.000102000000000,0.000130000000000,0.001577000000000,0.000768000000000,0.002776000000000,1.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1025.000000000000000,218.000000000000000,121.000000000000000,0.159928213604770,0.189984919538914,121.000000000000000,0.281177669551262 +0.000000000000000,0.000012000000000,0.000247000000000,0.000124000000000,0.001584000000000,0.000607000000000,0.002648000000000,0.000000000000000,108.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,912.000000000000000,232.000000000000000,121.000000000000000,0.169367654114597,0.221725877325533,121.000000000000000,0.328154308402856 +0.000000000000000,0.000029000000000,0.000128000000000,0.000128000000000,0.001642000000000,0.000782000000000,0.002760000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,911.000000000000000,211.000000000000000,121.000000000000000,0.147968518377667,0.154122927463339,121.000000000000000,0.228101943121478 +0.000000000000000,0.000016000000000,0.000176000000000,0.000142000000000,0.001527000000000,0.000917000000000,0.002821000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,946.000000000000000,207.000000000000000,121.000000000000000,0.137541055415491,0.157761641471241,121.000000000000000,0.233487226761447 +0.000000000000000,0.000032000000000,0.000147000000000,0.000136000000000,0.001548000000000,0.000751000000000,0.002712000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,954.000000000000000,199.000000000000000,121.000000000000000,0.162415187446687,0.197580421079148,121.000000000000000,0.292419026477691 +0.000000000000000,0.000019000000000,0.000178000000000,0.000129000000000,0.001473000000000,0.000728000000000,0.002570000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,952.000000000000000,191.000000000000000,121.000000000000000,0.171041015417160,0.194915117263576,121.000000000000000,0.288474365726664 +0.000000000000000,0.000029000000000,0.000197000000000,0.000115000000000,0.001354000000000,0.000809000000000,0.002551000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,965.000000000000000,175.000000000000000,121.000000000000000,0.154222763807780,0.285544163762687,120.000000000000000,0.422605366108563 +0.000000000000000,0.000019000000000,0.000139000000000,0.000125000000000,0.001460000000000,0.000814000000000,0.002600000000000,0.000000000000000,114.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,968.000000000000000,171.000000000000000,121.000000000000000,0.150595603214115,0.221852768512487,121.000000000000000,0.328342103660952 +0.000000000000000,0.000013000000000,0.000104000000000,0.000134000000000,0.001356000000000,0.000752000000000,0.002398000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,996.000000000000000,168.000000000000000,121.000000000000000,0.147430237486138,0.148159285827304,121.000000000000000,0.219275742894069 +0.000000000000000,0.000020000000000,0.000193000000000,0.000142000000000,0.001953000000000,0.000947000000000,0.003301000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1030.000000000000000,177.000000000000000,121.000000000000000,0.145798815037739,0.159663663944367,121.000000000000000,0.236302234970841 +0.000000000000000,0.000015000000000,0.000103000000000,0.000115000000000,0.001290000000000,0.000699000000000,0.002255000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,172.000000000000000,121.000000000000000,0.142196014156506,0.187147109561421,121.000000000000000,0.276977737652069 +0.000000000000000,0.000024000000000,0.000160000000000,0.000150000000000,0.001811000000000,0.000777000000000,0.003271000000000,1.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1069.000000000000000,202.000000000000000,121.000000000000000,0.139609449101900,0.165271225439012,121.000000000000000,0.244601415643369 +0.000000000000000,0.000018000000000,0.000179000000000,0.000151000000000,0.001532000000000,0.000737000000000,0.002693000000000,0.000000000000000,97.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,912.000000000000000,203.000000000000000,121.000000000000000,0.147947477270869,0.179555832175793,121.000000000000000,0.265742648149137 +0.000000000000000,0.000019000000000,0.000177000000000,0.000125000000000,0.001512000000000,0.000717000000000,0.002588000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,911.000000000000000,212.000000000000000,121.000000000000000,0.147575394987053,0.165266294276773,121.000000000000000,0.244594112073245 +0.000000000000000,0.000016000000000,0.000106000000000,0.000137000000000,0.001490000000000,0.000826000000000,0.002618000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,915.000000000000000,203.000000000000000,121.000000000000000,0.154152939014589,0.159181033056470,121.000000000000000,0.235587925595243 +0.000000000000000,0.000013000000000,0.000177000000000,0.000117000000000,0.001355000000000,0.000751000000000,0.002448000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,921.000000000000000,192.000000000000000,121.000000000000000,0.150692609588339,0.183809895950044,121.000000000000000,0.272038654130109 +0.000000000000000,0.000023000000000,0.000221000000000,0.000167000000000,0.001790000000000,0.000948000000000,0.003199000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,932.000000000000000,170.000000000000000,121.000000000000000,0.149963553230709,0.203273297272569,121.000000000000000,0.300844465407444 +0.000000000000000,0.000026000000000,0.000151000000000,0.000122000000000,0.001357000000000,0.000723000000000,0.002422000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,961.000000000000000,168.000000000000000,121.000000000000000,0.142178288778563,0.151033799800819,121.000000000000000,0.223530034583352 +0.000000000000000,0.000018000000000,0.000155000000000,0.000123000000000,0.001394000000000,0.000766000000000,0.002492000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,986.000000000000000,182.000000000000000,121.000000000000000,0.141207634148801,0.172667793318101,121.000000000000000,0.255548330024774 +0.000000000000000,0.000018000000000,0.000174000000000,0.000143000000000,0.001389000000000,0.000790000000000,0.002550000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1023.000000000000000,171.000000000000000,121.000000000000000,0.140177814193211,0.162740001476768,121.000000000000000,0.240855214879131 +0.000000000000000,0.000021000000000,0.000173000000000,0.000122000000000,0.001280000000000,0.000796000000000,0.002581000000000,1.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1049.000000000000000,171.000000000000000,121.000000000000000,0.138041804635574,0.175894893269503,121.000000000000000,0.260324460535807 +0.000000000000000,0.000040000000000,0.000240000000000,0.000156000000000,0.001610000000000,0.000905000000000,0.003078000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,887.000000000000000,181.000000000000000,121.000000000000000,0.128640393991057,0.132619727567557,121.000000000000000,0.196277204924269 +0.000000000000000,0.000016000000000,0.000181000000000,0.000117000000000,0.001424000000000,0.000760000000000,0.002543000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,886.000000000000000,172.000000000000000,121.000000000000000,0.138352531751683,0.243902625004102,121.000000000000000,0.360975895470416 +0.000000000000000,0.000020000000000,0.000178000000000,0.000131000000000,0.001344000000000,0.000965000000000,0.002674000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,904.000000000000000,177.000000000000000,121.000000000000000,0.132849298892330,0.165943140041726,121.000000000000000,0.245595863686171 +0.000000000000000,0.000018000000000,0.000129000000000,0.000145000000000,0.001297000000000,0.000878000000000,0.002506000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,916.000000000000000,164.000000000000000,121.000000000000000,0.139100399764650,0.179464095411716,121.000000000000000,0.265606862397320 +0.000000000000000,0.000015000000000,0.000175000000000,0.000119000000000,0.001188000000000,0.000717000000000,0.002249000000000,0.000000000000000,116.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,926.000000000000000,158.000000000000000,121.000000000000000,0.124508577433483,0.232688205210390,121.000000000000000,0.344378545000118 +0.000000000000000,0.000041000000000,0.000173000000000,0.000189000000000,0.001590000000000,0.000722000000000,0.002820000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,950.000000000000000,167.000000000000000,121.000000000000000,0.124364211160562,0.198989442345874,121.000000000000000,0.294504385287040 +0.000000000000000,0.000022000000000,0.000180000000000,0.000121000000000,0.001454000000000,0.000762000000000,0.002586000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,981.000000000000000,174.000000000000000,121.000000000000000,0.121986273502660,0.181985786779231,121.000000000000000,0.269338961458690 +0.000000000000000,0.000022000000000,0.000175000000000,0.000128000000000,0.001283000000000,0.000822000000000,0.002468000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1006.000000000000000,154.000000000000000,121.000000000000000,0.120933033868538,0.208757551950541,121.000000000000000,0.308961183186222 +0.000000000000000,0.000026000000000,0.000175000000000,0.000143000000000,0.001286000000000,0.000813000000000,0.002485000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1029.000000000000000,160.000000000000000,121.000000000000000,0.109269904153490,0.130322654376541,121.000000000000000,0.192877532026941 +0.000000000000000,0.000023000000000,0.000175000000000,0.000120000000000,0.001254000000000,0.000637000000000,0.002411000000000,1.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1040.000000000000000,160.000000000000000,121.000000000000000,0.126897062957379,0.186841162125259,121.000000000000000,0.276524916304396 +0.000000000000000,0.000021000000000,0.000140000000000,0.000122000000000,0.001471000000000,0.000691000000000,0.002520000000000,0.000000000000000,113.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,891.000000000000000,190.000000000000000,121.000000000000000,0.112694197899670,0.185521960041402,121.000000000000000,0.274572512797542 +0.000000000000000,0.000020000000000,0.000176000000000,0.000199000000000,0.001263000000000,0.000879000000000,0.002581000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,888.000000000000000,161.000000000000000,121.000000000000000,0.099793871260750,0.108940668612828,121.000000000000000,0.161232198827340 +0.000000000000000,0.000018000000000,0.000103000000000,0.000137000000000,0.001309000000000,0.000726000000000,0.002333000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,901.000000000000000,171.000000000000000,121.000000000000000,0.091727983876207,0.161347683449736,121.000000000000000,0.238794571957605 +0.000000000000000,0.000018000000000,0.000175000000000,0.000143000000000,0.001336000000000,0.000860000000000,0.002571000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,909.000000000000000,175.000000000000000,121.000000000000000,0.124196463571817,0.147059251648374,121.000000000000000,0.217647703825064 +0.000000000000000,0.000019000000000,0.000174000000000,0.000125000000000,0.001265000000000,0.000845000000000,0.002464000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,911.000000000000000,175.000000000000000,121.000000000000000,0.114265472855587,0.148521989180687,121.000000000000000,0.219812542662230 +0.000000000000000,0.000030000000000,0.000158000000000,0.000151000000000,0.001613000000000,0.000756000000000,0.002826000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,943.000000000000000,170.000000000000000,121.000000000000000,0.092242007337942,0.147927216635033,121.000000000000000,0.218932272923301 +0.000000000000000,0.000017000000000,0.000106000000000,0.000120000000000,0.001308000000000,0.001030000000000,0.002622000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,970.000000000000000,159.000000000000000,121.000000000000000,0.106941604326635,0.142972503313410,121.000000000000000,0.211599311615969 +0.000000000000000,0.000021000000000,0.000127000000000,0.000130000000000,0.001305000000000,0.000748000000000,0.002368000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,989.000000000000000,164.000000000000000,121.000000000000000,0.114683633251297,0.167145956283516,121.000000000000000,0.247376014134327 +0.000000000000000,0.000023000000000,0.000135000000000,0.000297000000000,0.001353000000000,0.000968000000000,0.002824000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1014.000000000000000,170.000000000000000,121.000000000000000,0.103049615014965,0.141054167934770,121.000000000000000,0.208760168771737 +0.000000000000000,0.000020000000000,0.000101000000000,0.000125000000000,0.001114000000000,0.000766000000000,0.002163000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1033.000000000000000,149.000000000000000,121.000000000000000,0.088395574941732,0.099895628586074,121.000000000000000,0.147845538218435 +0.000000000000000,0.000023000000000,0.000190000000000,0.000110000000000,0.001226000000000,0.000774000000000,0.002371000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1048.000000000000000,162.000000000000000,121.000000000000000,0.098469632616480,0.121321004607324,121.000000000000000,0.179555087237014 +0.000000000000000,0.000022000000000,0.000180000000000,0.000138000000000,0.001374000000000,0.001109000000000,0.002867000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1058.000000000000000,162.000000000000000,121.000000000000000,0.106165831669812,0.125397650867987,120.000000000000000,0.185588518499696 +0.000000000000000,0.000022000000000,0.000177000000000,0.000138000000000,0.001328000000000,0.000617000000000,0.002320000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1063.000000000000000,154.000000000000000,121.000000000000000,0.100439787680905,0.214221605374360,121.000000000000000,0.317047979072175 +0.000000000000000,0.000019000000000,0.000114000000000,0.000131000000000,0.001262000000000,0.000730000000000,0.002294000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1073.000000000000000,151.000000000000000,121.000000000000000,0.101286833254115,0.171921771357668,121.000000000000000,0.254444227342640 +0.000000000000000,0.000018000000000,0.000111000000000,0.000120000000000,0.001321000000000,0.000814000000000,0.002422000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1075.000000000000000,159.000000000000000,121.000000000000000,0.100562747826060,0.189141833234101,121.000000000000000,0.279929921566071 +0.000000000000000,0.000020000000000,0.000137000000000,0.000115000000000,0.001291000000000,0.000697000000000,0.002305000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1102.000000000000000,170.000000000000000,121.000000000000000,0.108513981039663,0.171230581801412,121.000000000000000,0.253421272631674 +0.000000000000000,0.000023000000000,0.000142000000000,0.000126000000000,0.001300000000000,0.000836000000000,0.002476000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1133.000000000000000,146.000000000000000,121.000000000000000,0.093525447667265,0.136448459114485,121.000000000000000,0.201943713921807 +0.000000000000000,0.000018000000000,0.000175000000000,0.000137000000000,0.001338000000000,0.000746000000000,0.002454000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1153.000000000000000,167.000000000000000,121.000000000000000,0.098830315127647,0.135984610426414,121.000000000000000,0.201257228873912 +0.000000000000000,0.000016000000000,0.000153000000000,0.000133000000000,0.001342000000000,0.000846000000000,0.002529000000000,0.000000000000000,115.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1169.000000000000000,168.000000000000000,121.000000000000000,0.104911664860530,0.116528427363267,121.000000000000000,0.172462069689336 +0.000000000000000,0.000016000000000,0.000177000000000,0.000153000000000,0.001420000000000,0.001057000000000,0.002862000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1189.000000000000000,171.000000000000000,121.000000000000000,0.112357270101045,0.155883824635645,121.000000000000000,0.230708054062211 +0.000000000000000,0.000019000000000,0.000183000000000,0.000118000000000,0.001173000000000,0.000692000000000,0.002218000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1205.000000000000000,160.000000000000000,121.000000000000000,0.114134537418471,0.211839504506888,121.000000000000000,0.313522477539393 +0.000000000000000,0.000022000000000,0.000144000000000,0.000340000000000,0.002673000000000,0.001050000000000,0.004300000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1210.000000000000000,169.000000000000000,121.000000000000000,0.118247530316238,0.220707314595291,121.000000000000000,0.326646841420566 +0.000000000000000,0.000021000000000,0.000121000000000,0.000119000000000,0.001312000000000,0.000708000000000,0.002323000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1221.000000000000000,159.000000000000000,121.000000000000000,0.108077994964789,0.189119078021565,121.000000000000000,0.279896234164773 +0.000000000000000,0.000022000000000,0.000131000000000,0.000170000000000,0.001575000000000,0.000930000000000,0.002873000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1227.000000000000000,161.000000000000000,121.000000000000000,0.111392372838571,0.157100432720142,121.000000000000000,0.232508649452340 +0.000000000000000,0.000021000000000,0.000129000000000,0.000146000000000,0.001357000000000,0.001069000000000,0.002758000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1238.000000000000000,169.000000000000000,121.000000000000000,0.115843692072703,0.148606734789863,121.000000000000000,0.219937966947781 +0.000000000000000,0.000018000000000,0.000196000000000,0.000246000000000,0.003021000000000,0.001245000000000,0.004778000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1237.000000000000000,170.000000000000000,121.000000000000000,0.110486981424295,0.140524548316829,121.000000000000000,0.207976323848749 +0.000000000000000,0.000019000000000,0.000176000000000,0.000120000000000,0.001319000000000,0.000781000000000,0.002451000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1234.000000000000000,166.000000000000000,121.000000000000000,0.116858932300554,0.142202739311708,121.000000000000000,0.210460043128204 +0.000000000000000,0.000023000000000,0.000194000000000,0.000117000000000,0.001352000000000,0.000677000000000,0.002411000000000,0.000000000000000,121.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1229.000000000000000,165.000000000000000,121.000000000000000,0.110055898076008,0.160160155663640,121.000000000000000,0.237037039832150 +0.000000000000000,0.000019000000000,0.000128000000000,0.000129000000000,0.001375000000000,0.000783000000000,0.002473000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1230.000000000000000,170.000000000000000,121.000000000000000,0.126041915882071,0.160651736154074,121.000000000000000,0.237764591667073 +0.000000000000000,0.000024000000000,0.000199000000000,0.000203000000000,0.001799000000000,0.000878000000000,0.003158000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1227.000000000000000,182.000000000000000,121.000000000000000,0.131395777815393,0.222014190834195,121.000000000000000,0.328581023909914 +0.000000000000000,0.000019000000000,0.000103000000000,0.000125000000000,0.001415000000000,0.000879000000000,0.002580000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1227.000000000000000,183.000000000000000,121.000000000000000,0.135634727713905,0.187089754575309,121.000000000000000,0.276892849444298 +0.000000000000000,0.000017000000000,0.000101000000000,0.000119000000000,0.001263000000000,0.000774000000000,0.002307000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1226.000000000000000,171.000000000000000,121.000000000000000,0.140713971719655,0.131521683676958,121.000000000000000,0.194652084756127 +0.000000000000000,0.000016000000000,0.000127000000000,0.000147000000000,0.001449000000000,0.000744000000000,0.002523000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1225.000000000000000,178.000000000000000,121.000000000000000,0.139061294677762,0.203192935815326,121.000000000000000,0.300725561264080 +0.000000000000000,0.000018000000000,0.000191000000000,0.000120000000000,0.001241000000000,0.000897000000000,0.002515000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1221.000000000000000,165.000000000000000,121.000000000000000,0.137698280788293,0.173674353597993,121.000000000000000,0.257038030883200 +0.000000000000000,0.000018000000000,0.000177000000000,0.000127000000000,0.001350000000000,0.000790000000000,0.002651000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1209.000000000000000,165.000000000000000,121.000000000000000,0.156706447381789,0.199509549579289,121.000000000000000,0.295274141143093 +0.000000000000000,0.000016000000000,0.000153000000000,0.000147000000000,0.001501000000000,0.000734000000000,0.002643000000000,0.000000000000000,112.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1046.000000000000000,206.000000000000000,121.000000000000000,0.145254964747455,0.192623491876607,121.000000000000000,0.285082754555528 +0.000000000000000,0.000017000000000,0.000175000000000,0.000117000000000,0.001356000000000,0.000838000000000,0.002539000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1044.000000000000000,191.000000000000000,121.000000000000000,0.154344725976771,0.284210388757305,121.000000000000000,0.420631380425634 +0.000000000000000,0.000021000000000,0.000118000000000,0.000127000000000,0.001456000000000,0.000725000000000,0.002492000000000,0.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1039.000000000000000,193.000000000000000,121.000000000000000,0.154361389589804,0.236960337646421,121.000000000000000,0.350701313890299 +0.000000000000000,0.000018000000000,0.000108000000000,0.000128000000000,0.001548000000000,0.000868000000000,0.002721000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1036.000000000000000,190.000000000000000,121.000000000000000,0.144847037730729,0.155773166896081,121.000000000000000,0.230544292351477 +0.000000000000000,0.000018000000000,0.000129000000000,0.000124000000000,0.001383000000000,0.000975000000000,0.002669000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1027.000000000000000,183.000000000000000,121.000000000000000,0.145841805810321,0.158516249676071,121.000000000000000,0.234604041193658 +0.000000000000000,0.000028000000000,0.000216000000000,0.000131000000000,0.001615000000000,0.000765000000000,0.002878000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1020.000000000000000,192.000000000000000,121.000000000000000,0.144426676201549,0.156437471874113,121.000000000000000,0.231527443868863 +0.000000000000000,0.000021000000000,0.000153000000000,0.000120000000000,0.001406000000000,0.000771000000000,0.002509000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1015.000000000000000,188.000000000000000,121.000000000000000,0.147869059454709,0.168692675134760,120.000000000000000,0.249665165294811 +0.000000000000000,0.000021000000000,0.000170000000000,0.000115000000000,0.001425000000000,0.000608000000000,0.002395000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1012.000000000000000,187.000000000000000,121.000000000000000,0.168987279193652,0.289264692226178,121.000000000000000,0.428111727272626 +0.000000000000000,0.000017000000000,0.000135000000000,0.000127000000000,0.001615000000000,0.000791000000000,0.002734000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1011.000000000000000,192.000000000000000,121.000000000000000,0.170578883496370,0.166353065557405,121.000000000000000,0.246202540171952 +0.000000000000000,0.000019000000000,0.000178000000000,0.000136000000000,0.001520000000000,0.000741000000000,0.002636000000000,0.000000000000000,118.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,1005.000000000000000,203.000000000000000,121.000000000000000,0.156640038600278,0.207055055847171,121.000000000000000,0.306441476765396 +0.000000000000000,0.000033000000000,0.000177000000000,0.000135000000000,0.001641000000000,0.000861000000000,0.003288000000000,1.000000000000000,120.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,999.000000000000000,186.000000000000000,121.000000000000000,0.143274685502394,0.179257874186524,121.000000000000000,0.265301654036128 +0.000000000000000,0.000015000000000,0.000129000000000,0.000142000000000,0.001443000000000,0.000740000000000,0.002555000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,821.000000000000000,202.000000000000000,121.000000000000000,0.156881076812533,0.218447877056405,121.000000000000000,0.323302867722382 +0.000000000000000,0.000036000000000,0.000177000000000,0.000151000000000,0.001530000000000,0.000725000000000,0.002741000000000,0.000000000000000,117.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,820.000000000000000,168.000000000000000,121.000000000000000,0.155951030020751,0.213023655758012,121.000000000000000,0.315275031106667 +0.000000000000000,0.000030000000000,0.000196000000000,0.000128000000000,0.001426000000000,0.000831000000000,0.002660000000000,0.000000000000000,119.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,-1.000000000000000,816.000000000000000 \ No newline at end of file diff --git a/GPU_version/svo/test/data/.gitignore b/GPU_version/svo/test/data/.gitignore new file mode 100644 index 0000000..cf57c3b --- /dev/null +++ b/GPU_version/svo/test/data/.gitignore @@ -0,0 +1,2 @@ +.gitignore +!.gitignore \ No newline at end of file diff --git a/GPU_version/svo/test/results/.gitignore b/GPU_version/svo/test/results/.gitignore new file mode 100644 index 0000000..cf57c3b --- /dev/null +++ b/GPU_version/svo/test/results/.gitignore @@ -0,0 +1,2 @@ +.gitignore +!.gitignore \ No newline at end of file diff --git a/GPU_version/svo/test/test_depth_filter.cpp b/GPU_version/svo/test/test_depth_filter.cpp new file mode 100644 index 0000000..4d22493 --- /dev/null +++ b/GPU_version/svo/test/test_depth_filter.cpp @@ -0,0 +1,206 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_utils.h" + +namespace { + +struct ConvergedSeed { + int x_, y_; + double depth_, error_; + ConvergedSeed(int x, int y, double depth, double error) : + x_(x), y_(y), depth_(depth), error_(error) + {} +}; + +/// DepthFilter Test-Fixture +class DepthFilterTest { + public: + DepthFilterTest(); + virtual ~DepthFilterTest(); + void depthFilterCb(svo::Point* point, double depth_sigma2); + void testReconstruction(std::string dataset_dir, std::string experiment_name); + + std::list results_; + std::vector errors_; + size_t n_converged_seeds_; + vk::PinholeCamera* cam_; + svo::DepthFilter* depth_filter_; + svo::FramePtr frame_ref_; + svo::FramePtr frame_cur_; + cv::Mat depth_ref_; +}; + +DepthFilterTest::DepthFilterTest() : + n_converged_seeds_(0), + cam_(new vk::PinholeCamera(752, 480, 315.5, 315.5, 376.0, 240.0)), + depth_filter_(NULL) +{ + errors_.reserve(1000); +} + +DepthFilterTest::~DepthFilterTest() +{ + delete cam_; +} + +void DepthFilterTest::depthFilterCb(svo::Point* point, double depth_sigma2) +{ + double depth = (frame_ref_->pos() - point->pos_).norm(); + double error = fabs(depth - depth_ref_.at(point->obs_.front()->px[1], + point->obs_.front()->px[0])); + results_.push_back(ConvergedSeed( + point->obs_.front()->px[0], point->obs_.front()->px[1], depth, error)); + errors_.push_back(error); + delete point->obs_.front(); + delete point; + ++n_converged_seeds_; +} + +void DepthFilterTest::testReconstruction( + std::string dataset_dir, + std::string experiment_name) +{ + vk::FileReader sequence_file_reader(dataset_dir+"/trajectory.txt"); + std::vector sequence; + sequence_file_reader.skipComments(); + if(!sequence_file_reader.next()) + std::runtime_error("Failed to open sequence file"); + sequence_file_reader.readAllEntries(sequence); + std::cout << "RUN EXPERIMENT: read " << sequence.size() << " dataset entries." << std::endl; + std::vector::iterator it = sequence.begin(); + vk::Timer t; + std::list n_converged_per_iteration; + + svo::feature_detection::DetectorPtr feature_detector( + new svo::feature_detection::FastDetector( + cam_->width(), cam_->height(), svo::Config::gridSize(), svo::Config::nPyrLevels())); + svo::DepthFilter::callback_t depth_filter_cb = boost::bind(&DepthFilterTest::depthFilterCb, this, _1, _2); + depth_filter_ = new svo::DepthFilter(feature_detector, depth_filter_cb); + depth_filter_->options_.verbose = true; + + for(int i=0; it != sequence.end() && i<20; ++it, ++i) + { + std::string img_name(dataset_dir+"/img/" + (*it).image_name_ + "_0.png"); + printf("reading image: '%s'\n", img_name.c_str()); + cv::Mat img(cv::imread(img_name, 0)); + assert(!img.empty()); + + Sophus::SE3 T_w_f(it->q_, it->t_); + if(i == 0) + { + // create reference frame and load ground truth depthmap + frame_ref_ = boost::make_shared(cam_, img, 0.0); + frame_ref_->T_f_w_ = T_w_f.inverse(); + depth_filter_->addKeyframe(frame_ref_, 2, 0.5); + vk::blender_utils::loadBlenderDepthmap(dataset_dir+"/depth/" + (*it).image_name_ + "_0.depth", *cam_, depth_ref_); + continue; + } + + n_converged_seeds_ = 0; + frame_cur_ = boost::make_shared(cam_, img, 0.0); + frame_cur_->T_f_w_ = T_w_f.inverse(); + depth_filter_->addFrame(frame_cur_); + n_converged_per_iteration.push_back(n_converged_seeds_); + } + printf("Experiment '%s' took %f ms\n", experiment_name.c_str(), t.stop()*1000); + + // compute mean, median and variance of error in converged area + { + printf("# converged: \t %zu (ref: 287)\n", errors_.size()); + double sum_error = 0; + std::for_each(errors_.begin(), errors_.end(), [&](double& e){sum_error+=e;}); + printf("mean error: \t %f cm (ref: 0.080357)\n", sum_error*100/errors_.size()); + std::vector::iterator it = errors_.begin()+0.5*errors_.size(); + std::nth_element(errors_.begin(), it, errors_.end()); + printf("50-percentile: \t %f cm (ref: 0.062042)\n", *it*100); + it = errors_.begin()+0.8*errors_.size(); + std::nth_element(errors_.begin(), it, errors_.end()); + printf("80-percentile: \t %f cm (ref: 0.124526)\n", *it*100); + it = errors_.begin()+0.95*errors_.size(); + std::nth_element(errors_.begin(), it, errors_.end()); + printf("95-percentile: \t %f cm (ref: 0.200417)\n", *it*100); + } + + // trace error + std::string trace_dir(svo::test_utils::getTraceDir()); + std::string trace_name(trace_dir + "/depth_filter_" + experiment_name + ".txt"); + std::ofstream ofs(trace_name.c_str()); + for(std::list::iterator i=results_.begin(); i!=results_.end(); ++i) + ofs << i->x_ << ", " << i->y_ << ", " << fabs(i->error_) << std::endl; + ofs.close(); + + // trace convergence rate + trace_name = trace_dir + "/depth_filter_" + experiment_name + "_convergence.txt"; + ofs.open(trace_name.c_str()); + for(std::list::iterator it=n_converged_per_iteration.begin(); + it!=n_converged_per_iteration.end(); ++it) + ofs << *it << std::endl; + ofs.close(); + + // write ply file for pointcloud visualization in Meshlab + trace_name = trace_dir + "/depth_filter_" + experiment_name + ".ply"; + ofs.open(trace_name.c_str()); + ofs << "ply" << std::endl + << "format ascii 1.0" << std::endl + << "element vertex " << results_.size() << std::endl + << "property float x" << std::endl + << "property float y" << std::endl + << "property float z" << std::endl + << "property uchar blue" << std::endl + << "property uchar green" << std::endl + << "property uchar red" << std::endl + << "end_header" << std::endl; + + for(std::list::iterator i=results_.begin(); i!=results_.end(); ++i) + { + cv::Vec3b c = frame_ref_->img_pyr_[0].at(i->y_, i->x_); + Eigen::Vector3d p = cam_->cam2world(i->x_, i->y_)*i->depth_; + ofs << p[0] << " " << p[1] << " " << p[2] << " " + << (int) c[0] << " " << (int) c[1] << " " << (int) c[2] << std::endl; + } +} + +} // namespace + +int main(int argc, char** argv) +{ + DepthFilterTest test; + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d"); + std::string experiment_name("sin2_tex2_h1_v8_d"); + test.testReconstruction(dataset_dir, experiment_name); + return 0; +} diff --git a/GPU_version/svo/test/test_feature_alignment.cpp b/GPU_version/svo/test/test_feature_alignment.cpp new file mode 100644 index 0000000..dac8911 --- /dev/null +++ b/GPU_version/svo/test/test_feature_alignment.cpp @@ -0,0 +1,124 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include "test_utils.h" +#if __ARM_NEON__ +#include +#endif + +using namespace Eigen; + +void generateRefPatchNoWarpInterpolate(const cv::Mat& img, const Vector2d& px, + cv::Mat& ref_patch_with_border) +{ + // compute interpolation weights + const int u_r = floor(px[0]); + const int v_r = floor(px[1]); + const float subpix_u = px[0]-u_r; + const float subpix_v = px[1]-v_r; + const float wTL = (1.0-subpix_u)*(1.0-subpix_v); + const float wTR = subpix_u * (1.0-subpix_v); + const float wBL = (1.0-subpix_u)*subpix_v; + const float wBR = subpix_u * subpix_v; + + // loop through search_patch, interpolate + ref_patch_with_border = cv::Mat(10, 10, CV_8UC1); + uint8_t* patch_ptr = ref_patch_with_border.data; + const int stride = img.step.p[0]; + for(int y=0; y<10; ++y) + { + uint8_t* img_ptr = (uint8_t*) img.data + (v_r+y-4-1)*stride + u_r-4-1; + for(int x=0; x<10; ++x, ++patch_ptr, ++img_ptr) + *patch_ptr = wTL*img_ptr[0] + wTR*img_ptr[1] + wBL*img_ptr[stride] + wBR*img_ptr[stride+1]; + } +} + +int main(int argc, char **argv) +{ + + std::string img_name(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d/img/frame_000002_0.png"); + printf("Loading image '%s'\n", img_name.c_str()); + cv::Mat img(cv::imread(img_name, 0)); + assert(img.type() == CV_8UC1); + + // TODO: test on corner/gradient features! + Vector2d px_true(130.2,120.3); + + // create reference patch with border + cv::Mat ref_patch_with_border; + generateRefPatchNoWarpInterpolate(img, px_true, ref_patch_with_border); + + // create reference patch, aligned + uint8_t* ref_patch = vk::aligned_mem::aligned_alloc(64, 16); + uint8_t* ref_patch_ptr = ref_patch; + for(int y=1; y<9; ++y) + { + uint8_t* ref_patch_border_ptr = ref_patch_with_border.data + y*10 + 1; + for(int x=0; x<8; ++x, ++ref_patch_border_ptr, ++ref_patch_ptr) + *ref_patch_ptr = *ref_patch_border_ptr; + } + + Vector2d px_est, px_error(-1.1, -0.8); + double h_inv; + vk::Timer t; + for(int i=0; i<1000; ++i) + { + px_est = px_true-px_error; + Vector2f dir = px_error.normalized().cast(); + svo::feature_alignment::align1D(img, dir, ref_patch_with_border.data, ref_patch, 3, px_est, h_inv); + } + Vector2d e = px_est-px_true; + printf("1000Xalign 1D took %fms, error = %fpx \t (ref i7-W520: 1.982000ms, 0.000033px) \n", t.stop()*1000, e.norm()); + + t.start(); + for(int i=0; i<1000; ++i) + { + px_est = px_true-px_error; + svo::feature_alignment::align2D(img, ref_patch_with_border.data, ref_patch, 3, px_est, true); + } + e = px_est-px_true; + printf("1000Xalign 2D took %fms, error = %fpx \t (ref i7-W520: 2.306000ms, 0.015102px)\n", t.stop()*1000, e.norm()); + +#ifdef __SSE2__ + // Note, this KLT implementation is not invariant to illuminatino changes! + t.start(); + for(int i=0; i<1000; ++i) + { + px_est = px_true-px_error; + svo::feature_alignment::align2D_SSE2(img, ref_patch_with_border.data, ref_patch, 3, px_est); + } + e = px_est-px_true; + printf("1000Xalign 2D SSE2 %fms, error = %fpx \t (ref i7-W520: 0.460000ms, 0.021881px)\n", t.stop()*1000, e.norm()); +#endif + +#ifdef __ARM_NEON__ + t.start(); + for(int i=0; i<1000; ++i) + { + px_est = px_true-px_error; + svo::feature_alignment::align2D_NEON(img, ref_patch_with_border.data, ref_patch, 3, px_est); + } + e = px_est-px_true; + printf("1000Xalign 2D NEON %fms, error = %fpx \t (ref Odroid-U2: ?, ?)\n", t.stop()*1000, e.norm()); +#endif + + return 0; +} diff --git a/GPU_version/svo/test/test_feature_detection.cpp b/GPU_version/svo/test/test_feature_detection.cpp new file mode 100644 index 0000000..3ba2b2f --- /dev/null +++ b/GPU_version/svo/test/test_feature_detection.cpp @@ -0,0 +1,74 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_utils.h" + +namespace { + +using namespace Eigen; +using namespace std; + +void testCornerDetector() +{ + std::string img_name(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d/img/frame_000002_0.png"); + printf("Loading image '%s'\n", img_name.c_str()); + cv::Mat img(cv::imread(img_name, 0)); + assert(img.type() == CV_8UC1 && !img.empty()); + + vk::AbstractCamera* cam = new vk::ATANCamera(752, 480, 0.511496, 0.802603, 0.530199, 0.496011, 0.934092); + svo::FramePtr frame(new svo::Frame(cam, img, 0.0)); + + // Corner detection + vk::Timer t; + svo::Features fts; + svo::feature_detection::FastDetector fast_detector( + img.cols, img.rows, svo::Config::gridSize(), svo::Config::nPyrLevels()); + for(int i=0; i<100; ++i) + { + fast_detector.detect(frame.get(), frame->img_pyr_, svo::Config::triangMinCornerScore(), fts); + } + printf("Fast corner detection took %f ms, %zu corners detected (ref i7-W520: 7.166360ms, 40000)\n", t.stop()*10, fts.size()); + printf("Note, in this case, feature detection also contains the cam2world projection of the feature.\n"); + cv::Mat img_rgb = cv::Mat(img.size(), CV_8UC3); + cv::cvtColor(img, img_rgb, CV_GRAY2RGB); + std::for_each(fts.begin(), fts.end(), [&](svo::Feature* i){ + cv::circle(img_rgb, cv::Point2f(i->px[0], i->px[1]), 4*(i->level+1), cv::Scalar(0,255,0), 1); + }); + cv::imshow("ref_img", img_rgb); + cv::waitKey(0); + + std::for_each(fts.begin(), fts.end(), [&](svo::Feature* i){ delete i; }); +} + +} // namespace + + +int main(int argc, char **argv) +{ + testCornerDetector(); + return 0; +} diff --git a/GPU_version/svo/test/test_matcher.cpp b/GPU_version/svo/test/test_matcher.cpp new file mode 100644 index 0000000..0b65cb9 --- /dev/null +++ b/GPU_version/svo/test/test_matcher.cpp @@ -0,0 +1,200 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_utils.h" + +namespace { + +/// Matcher Test-Fixture +class MatcherTest { + public: + MatcherTest() + { + cam_ = new vk::PinholeCamera(752, 480, 315.5, 315.5, 376.0, 240.0); + + // load images + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d"); + std::string img_name(dataset_dir+"/img/frame_000002_0.png"); + printf("Loading image '%s'\n", img_name.c_str()); + cv::Mat img_ref(cv::imread(img_name, 0)); + img_name = std::string(dataset_dir+"/img/frame_000006_0.png"); + printf("Loading image '%s'\n", img_name.c_str()); + cv::Mat img_cur(cv::imread(img_name, 0)); + assert(!img_ref.empty() && !img_cur.empty()); + + // create frame + frame_ref_ = new svo::Frame(cam_, img_ref, 1.0); + frame_cur_ = new svo::Frame(cam_, img_cur, 2.0); + ref_ftr_ = new svo::Feature(frame_ref_, Eigen::Vector2d(300, 260), 0); + + // set poses + Eigen::Vector3d t_w_ref(0.1131, 0.1131, 2.0000); + Eigen::Vector3d t_w_cur(0.5673, 0.5641, 2.0000); + Eigen::Quaterniond q_w_ref(0.0, 0.8227, 0.2149, 0.0); + Eigen::Quaterniond q_w_cur(0.0, 0.8235, 0.2130, 0.0); + frame_ref_->T_f_w_ = Sophus::SE3(q_w_ref, t_w_ref).inverse(); + frame_cur_->T_f_w_ = Sophus::SE3(q_w_cur, t_w_cur).inverse(); + + // load ground-truth depth + vk::blender_utils::loadBlenderDepthmap(dataset_dir+"/depth/frame_000002_0.depth", *cam_, depth_ref_); + } + + virtual ~MatcherTest() + { + delete cam_; + delete frame_ref_; + delete frame_cur_; + delete ref_ftr_; + } + + // Individual tests + void testEpipolarSearchFullImg(); + void testWarpAffine(); + + // Objects declared here can be used by all tests + vk::PinholeCamera* cam_; + svo::Frame* frame_ref_; + svo::Frame* frame_cur_; + svo::Feature* ref_ftr_; + cv::Mat depth_ref_; +}; + +void MatcherTest::testEpipolarSearchFullImg() +{ + svo::Matcher matcher; + cv::Mat depthmap(frame_ref_->cam_->height(), frame_ref_->cam_->width(), CV_32FC1, cv::Scalar(0)); + cv::Mat error_map(depthmap.rows, depthmap.cols, CV_32FC1, cv::Scalar(0)); + cv::Mat mask(depthmap.rows, depthmap.cols, CV_8UC1, cv::Scalar(1)); + double depth_range = 0.8; + size_t n_converged = 0; + double sum_error = 0; + std::vector errors; errors.reserve(depthmap.cols*depthmap.rows); + for(int y=4; y(y, x); + double depth_estimate; + int res = matcher.findEpipolarMatchDirect( + *frame_ref_, *frame_cur_, ftr, depth_gt, fmax(depth_gt-depth_range,0.0), + depth_gt+depth_range, depth_estimate); + if(res) + { + depthmap.at(y,x) = depth_estimate; + error_map.at(y,x) = fabsf(depth_estimate-depth_gt); + ++n_converged; + sum_error += error_map.at(y,x); + errors.push_back(error_map.at(y,x)); + } + else + mask.at(y,x) = 0; + } + } + + // compute mean, median and variance of error in converged area + printf("n converged: \t %zu mm (ref: 216114)\n", n_converged); + printf("mean error: \t %f mm (ref: 0.410084)\n", sum_error*100/n_converged); + std::vector::iterator it = errors.begin()+0.5*errors.size(); + std::nth_element(errors.begin(), it, errors.end()); + printf("50-percentile: \t %f mm (ref: 0.083203)\n", *it*100); + it = errors.begin()+0.8*errors.size(); + std::nth_element(errors.begin(), it, errors.end()); + printf("80-percentile: \t %f mm (ref: 0.161824)\n", *it*100); + it = errors.begin()+0.95*errors.size(); + std::nth_element(errors.begin(), it, errors.end()); + printf("95-percentile: \t %f mm (ref: 0.263539)\n", *it*100); + + // save results to file + std::ofstream output_stream; + std::string trace_dir(svo::test_utils::getTraceDir()); + std::string output_filename(trace_dir + "/depthmap.bin"); + output_stream.open(output_filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + output_stream.write((const char *)depthmap.data, depthmap.rows*depthmap.cols*sizeof(float)); + output_stream.close(); + + output_filename.assign(trace_dir + "/depthmap_error.bin"); + output_stream.open(output_filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + output_stream.write((const char *)error_map.data, error_map.rows*error_map.cols*sizeof(float)); + output_stream.close(); + + output_filename.assign(trace_dir + "/depthmap_mask.bin"); + output_stream.open(output_filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + output_stream.write((const char *)mask.data, mask.rows*mask.cols*sizeof(uint8_t)); + output_stream.close(); +} + +void MatcherTest::testWarpAffine() +{ + const int halfpatch_size = 15; + const int patch_size=halfpatch_size*2; + svo::Matcher matcher; + double depth = 1.0; + + Sophus::SE3 T_cur_ref(frame_cur_->T_f_w_*frame_ref_->T_f_w_.inverse()); + Eigen::Vector2d px_cur(frame_cur_->cam_->world2cam(T_cur_ref*(ref_ftr_->f*depth))); + + // compute reference patch + cv::Mat ref_patch(matcher.halfpatch_size_+1, matcher.halfpatch_size_+1, + CV_8U, matcher.patch_with_border_); + + Eigen::Matrix2d A_cur_ref; + svo::warp::getWarpMatrixAffine( + *cam_, *cam_, ref_ftr_->px, ref_ftr_->f, 1.0, T_cur_ref, ref_ftr_->level, A_cur_ref); + int level_cur = svo::warp::getBestSearchLevel(A_cur_ref, svo::Config::nPyrLevels()-1); + svo::warp::warpAffine( + A_cur_ref, ref_ftr_->frame->img_pyr_[ref_ftr_->level], ref_ftr_->px, + ref_ftr_->level, level_cur, matcher.halfpatch_size_+1, matcher.patch_with_border_); + + // copy current patch + Eigen::Vector2i pxi(px_cur[0]/(1<img_pyr_.at(level_cur)(cv::Range(pxi[1]-halfpatch_size, + pxi[1]+halfpatch_size), + cv::Range(pxi[0]-halfpatch_size, + pxi[0]+halfpatch_size)).copyTo(cur_patch); + + // display results + cv::circle(frame_cur_->img_pyr_[level_cur], + cv::Point2f(pxi[0], pxi[1]), + patch_size, cv::Scalar(255), 2); + cv::circle(frame_ref_->img_pyr_[ref_ftr_->level], + cv::Point2f(ref_ftr_->px[0]/(1<level), ref_ftr_->px[1]/(1<level)), + patch_size, cv::Scalar(255), 2); + cv::imshow("cur_patch", cur_patch); + cv::imshow("ref_patch", ref_patch); + cv::imshow("ref_img", frame_ref_->img_pyr_[ref_ftr_->level]); + cv::imshow("cur_img", frame_cur_->img_pyr_[level_cur]); + cv::waitKey(0); +} + +} // namespace + +int main(int argc, char** argv) +{ + MatcherTest test; + test.testEpipolarSearchFullImg(); +// test.testWarpAffine(); + return 0; +} diff --git a/GPU_version/svo/test/test_pipeline.cpp b/GPU_version/svo/test/test_pipeline.cpp new file mode 100644 index 0000000..ede3b25 --- /dev/null +++ b/GPU_version/svo/test/test_pipeline.cpp @@ -0,0 +1,98 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_utils.h" + +namespace svo { + +class BenchmarkNode +{ + vk::AbstractCamera* cam_; + svo::FrameHandlerMono* vo_; + +public: + BenchmarkNode(); + ~BenchmarkNode(); + void runFromFolder(); +}; + +BenchmarkNode::BenchmarkNode() +{ + cam_ = new vk::PinholeCamera(752, 480, 315.5, 315.5, 376.0, 240.0); + vo_ = new svo::FrameHandlerMono(cam_); + vo_->start(); +} + +BenchmarkNode::~BenchmarkNode() +{ + delete vo_; + delete cam_; +} + +void BenchmarkNode::runFromFolder() +{ + for(int img_id = 2; img_id < 188; ++img_id) + { + // load image + std::stringstream ss; + ss << svo::test_utils::getDatasetDir() << "/sin2_tex2_h1_v8_d/img/frame_" + << std::setw( 6 ) << std::setfill( '0' ) << img_id << "_0.png"; + if(img_id == 2) + std::cout << "reading image " << ss.str() << std::endl; + cv::Mat img(cv::imread(ss.str().c_str(), 0)); + assert(!img.empty()); + + // process frame + vo_->addImage(img, 0.01*img_id); + + // display tracking quality + if(vo_->lastFrame() != NULL) + { + std::cout << "Frame-Id: " << vo_->lastFrame()->id_ << " \t" + << "#Features: " << vo_->lastNumObservations() << " \t" + << "Proc. Time: " << vo_->lastProcessingTime()*1000 << "ms \n"; + + // access the pose of the camera via vo_->lastFrame()->T_f_w_. + } + } +} + +} // namespace svo + +int main(int argc, char** argv) +{ + { + svo::BenchmarkNode benchmark; + benchmark.runFromFolder(); + } + printf("BenchmarkNode finished.\n"); + return 0; +} + diff --git a/GPU_version/svo/test/test_pose_optimizer.cpp b/GPU_version/svo/test/test_pose_optimizer.cpp new file mode 100644 index 0000000..59e0b46 --- /dev/null +++ b/GPU_version/svo/test/test_pose_optimizer.cpp @@ -0,0 +1,110 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_utils.h" + +namespace { + +using namespace svo; +using namespace Eigen; + +/// Pose Optimizer Test-Fixture +class PoseOptimizerTest { + public: + PoseOptimizerTest() + { + cam_ = new vk::PinholeCamera(752, 480, 315.5, 315.5, 376.0, 240.0); + + // load image + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d"); + std::string img_name(dataset_dir+"/img/frame_000002_0.png"); + printf("Loading image '%s'\n", img_name.c_str()); + cv::Mat img(cv::imread(img_name, 0)); + assert(!img.empty()); + + // create frame + frame_.reset(new svo::Frame(cam_, img, 1.0)); + + // set pose + Eigen::Vector3d t_w_ref(0.1131, 0.1131, 2.0000); + Eigen::Quaterniond q_w_ref(0.0, 0.8227, 0.2149, 0.0); + frame_->T_f_w_ = Sophus::SE3(q_w_ref, t_w_ref).inverse(); + + // load ground-truth depth + vk::blender_utils::loadBlenderDepthmap(dataset_dir + "/depth/frame_000002_0.depth", *cam_, depthmap_); + + // detect features + feature_detection::FastDetector detector( + cam_->width(), cam_->height(), Config::gridSize(), Config::nPyrLevels()); + detector.detect(frame_.get(), frame_->img_pyr_, Config::triangMinCornerScore(), frame_->fts_); + size_t n_fts = 0; + std::for_each(frame_->fts_.begin(), frame_->fts_.end(), [&](Feature* i){ + Point* point(new Point(frame_->f2w(i->f*depthmap_.at(i->px[1], i->px[0])), i)); + i->point = point; + ++n_fts; + }); + printf("Added %zu features to frame.\n", n_fts); + } + + virtual ~PoseOptimizerTest() + { + delete cam_; + } + + // Individual tests + void test(const Vector3d& pose_disturbance, double pixel_sigma2); + + // Objects declared here can be used by all tests + vk::PinholeCamera* cam_; + FramePtr frame_; + cv::Mat depthmap_; +}; + +void PoseOptimizerTest::test(const Vector3d& pose_disturbance, double pixel_sigma2) +{ + printf("Add %f px noise to each observation\n", pixel_sigma2); + for(Features::iterator it=frame_->fts_.begin(); it!=frame_->fts_.end(); ++it) + { + (*it)->px += Vector2d(vk::Sample::gaussian(pixel_sigma2), vk::Sample::gaussian(pixel_sigma2)); + (*it)->f = frame_->c2f((*it)->px); + } + frame_->T_f_w_ = frame_->T_f_w_*SE3(Matrix3d::Identity(), pose_disturbance); + double estimated_scale, error_init, error_final; + size_t num_obs; + pose_optimizer::optimizeGaussNewton( + Config::reprojThresh(), 10, true, frame_, + estimated_scale, error_init, error_final, num_obs); +} + +} // namespace + +int main(int argc, char** argv) +{ + PoseOptimizerTest test; + test.test(Eigen::Vector3d(0.2, 0.2, 0.2), 1.0); + return 0; +} diff --git a/GPU_version/svo/test/test_sparse_img_align.cpp b/GPU_version/svo/test/test_sparse_img_align.cpp new file mode 100644 index 0000000..1312da0 --- /dev/null +++ b/GPU_version/svo/test/test_sparse_img_align.cpp @@ -0,0 +1,163 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_utils.h" + +namespace { + +/// SparseImgAlign Test-Fixture +class SparseImgAlignTest { + public: + + SparseImgAlignTest(); + virtual ~SparseImgAlignTest(); + void testSequence( + const std::string& dataset_dir, + const std::string& experiment_name, + svo::feature_detection::AbstractDetector* feature_detector); + + vk::PinholeCamera* cam_; + svo::FramePtr frame_ref_; + svo::FramePtr frame_cur_; +}; + +SparseImgAlignTest::SparseImgAlignTest() : + cam_(new vk::PinholeCamera(752, 480, 315.5, 315.5, 376.0, 240.0)) +{} + +SparseImgAlignTest::~SparseImgAlignTest() +{} + +void SparseImgAlignTest::testSequence( + const std::string& dataset_dir, + const std::string& experiment_name, + svo::feature_detection::AbstractDetector* feature_detector) +{ + vk::FileReader sequence_file_reader(dataset_dir+"/trajectory.txt"); + std::vector sequence; + sequence_file_reader.skipComments(); + if(!sequence_file_reader.next()) + std::runtime_error("Failed to open sequence file"); + sequence_file_reader.readAllEntries(sequence); + printf("RUN EXPERIMENT: read %zu dataset entries.\n", sequence.size()); + std::vector::iterator iter = sequence.begin(); + std::list translation_error; + + Sophus::SE3 T_prev_w, T_prevgt_w; + std::string trace_dir(svo::test_utils::getTraceDir()); + std::string trace_name(trace_dir + "/sparse_img_align_" + experiment_name + "_trans_estimate.txt"); + std::ofstream ofs(trace_name.c_str()); + for(int i=0; iter != sequence.end() && i<30; ++iter, ++i) + { + // load img + // IMPORTANT: We need to flip the image because the Povray dataset has a + // negative focal length in y direction which we didn't set. + std::string img_name(dataset_dir+"/img/" + iter->image_name_ + "_0.png"); + cv::Mat img(cv::imread(img_name, 0)); + assert(!img.empty()); + + // load pose + Sophus::SE3 T_w_gt(iter->q_, iter->t_); + Sophus::SE3 T_gt_w = T_w_gt.inverse(); // ground-truth + + if(i==0) + { + // set reference frame + frame_ref_.reset(new svo::Frame(cam_, img, 0.0)); + frame_ref_->T_f_w_ = T_gt_w; + + // load ground-truth depth + cv::Mat depthmap; + vk::blender_utils::loadBlenderDepthmap( + dataset_dir+"/depth/"+iter->image_name_+"_0.depth", *cam_, depthmap); + + // extract features, generate features with 3D points + feature_detector->detect( + frame_ref_.get(), frame_ref_->img_pyr_, svo::Config::triangMinCornerScore(), frame_ref_->fts_); + std::for_each(frame_ref_->fts_.begin(), frame_ref_->fts_.end(), [&](svo::Feature* i) { + Eigen::Vector3d pt_pos_cur = i->f*depthmap.at(i->px[1], i->px[0]); + Eigen::Vector3d pt_pos_w = frame_ref_->T_f_w_.inverse()*pt_pos_cur; + svo::Point* pt = new svo::Point(pt_pos_w, i); + i->point = pt; + }); + + printf("Added %zu 3d pts to the reference frame.\n", frame_ref_->nObs()); + T_prev_w = frame_ref_->T_f_w_; + T_prevgt_w = T_gt_w; + continue; + } + + frame_cur_.reset(new svo::Frame(cam_, img, 0.0)); + //frame_cur_->T_f_w_ = frame_ref_->T_f_w_; // start at reference frame + frame_cur_->T_f_w_ = T_prev_w; // start at last frame + + // run image align + vk::Timer t; + svo::SparseImgAlign img_align(svo::Config::kltMaxLevel(), svo::Config::kltMinLevel(), + 30, svo::SparseImgAlign::GaussNewton, false, false); + img_align.run(frame_ref_, frame_cur_); + + // compute error + Sophus::SE3 T_f_gt = frame_cur_->T_f_w_ * T_gt_w.inverse(); + translation_error.push_back(T_f_gt.translation().norm()); + printf("[%3.i] time = %f ms \t |t| = %f \t translation error = %f\n", + i, t.stop()*1000, (frame_ref_->T_f_w_*T_gt_w.inverse()).translation().norm(), + translation_error.back()); + + // save old pose for next iteration + T_prev_w = frame_cur_->T_f_w_; + T_prevgt_w = T_gt_w; + + ofs << frame_cur_->T_f_w_.inverse().translation().transpose() << " " + << T_gt_w.inverse().translation().transpose() << std::endl; + } + ofs.close(); + + // trace error + trace_name = trace_dir + "/sparse_img_align_" + experiment_name + "_trans_error.txt"; + ofs.open(trace_name.c_str()); + for(std::list::iterator it=translation_error.begin(); it!=translation_error.end(); ++it) + ofs << *it << std::endl; + ofs.close(); +} + +} // namespace + + +int main(int argc, char** argv) +{ + std::string experiment_name("flying_room_1_rig_1_fast_minlev0"); + std::string dataset_dir(svo::test_utils::getDatasetDir() + "/sin2_tex2_h1_v8_d"); + svo::Config::triangMinCornerScore() = 20; + svo::Config::kltMinLevel() = 0; + SparseImgAlignTest test; + svo::feature_detection::FastDetector detector( + test.cam_->width(), test.cam_->height(), svo::Config::gridSize(), svo::Config::nPyrLevels()); + test.testSequence(dataset_dir, experiment_name, &detector); + return 0; +} diff --git a/GPU_version/svo/test/test_utils.h b/GPU_version/svo/test/test_utils.h new file mode 100644 index 0000000..2759fe0 --- /dev/null +++ b/GPU_version/svo/test/test_utils.h @@ -0,0 +1,57 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef TEST_UTILS_H_ +#define TEST_UTILS_H_ + +#include +#include // for getenv +#ifdef SVO_USE_ROS +# include +# include +#endif + +namespace svo { +namespace test_utils { + +std::string getDatasetDir() +{ + const char* env_dir = std::getenv("SVO_DATASET_DIR"); +#ifdef SVO_USE_ROS + std::string dataset_dir(ros::package::getPath("svo")+"/test/data"); + if(env_dir != NULL) + dataset_dir = std::string(env_dir); + return dataset_dir; +#else + return std::string(env_dir); +#endif +} + +std::string getTraceDir() +{ +#ifdef SVO_USE_ROS + std::string default_dir(ros::package::getPath("svo")+"/test/results"); + return vk::getParam("svo/trace_dir", default_dir); +#else + return "/tmp"; +#endif +} + +} // namespace test_utils +} // namespace svo + + +#endif // TEST_UTILS_H_ From 5687fe5057657f3dbc82904bcf6896f5579f9415 Mon Sep 17 00:00:00 2001 From: gfuse Date: Wed, 5 May 2021 14:35:12 +0200 Subject: [PATCH 187/215] add fast kernel --- GPU_version/svo/CMakeLists.txt | 90 ++++------- GPU_version/svo/include/svo/cl_class.h | 197 +++++++++++++++++++++++++ GPU_version/svo/kernel/fast-gray.cl | 103 +++++++++++++ GPU_version/svo/src/cl_class.cpp | 56 +++++++ 4 files changed, 384 insertions(+), 62 deletions(-) create mode 100644 GPU_version/svo/include/svo/cl_class.h create mode 100644 GPU_version/svo/kernel/fast-gray.cl create mode 100644 GPU_version/svo/src/cl_class.cpp diff --git a/GPU_version/svo/CMakeLists.txt b/GPU_version/svo/CMakeLists.txt index ed4b593..4f0c7c5 100644 --- a/GPU_version/svo/CMakeLists.txt +++ b/GPU_version/svo/CMakeLists.txt @@ -1,16 +1,7 @@ -################################################################################ -# user build settings - -SET(TRACE TRUE) -SET(HAVE_G2O FALSE) -SET(USE_ROS TRUE) # Set FALSE if you want to build this package without Catkin -SET(DEBUG_OUTPUT FALSE) # Only relevant if build without ROS - -################################################################################ - SET(PROJECT_NAME gpu_svo) PROJECT(${PROJECT_NAME}) CMAKE_MINIMUM_REQUIRED (VERSION 2.8.3) + SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo SET(CMAKE_VERBOSE_MAKEFILE OFF) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") @@ -18,18 +9,9 @@ set(CMAKE_C_STANDARD 14) set(CMAKE_CXX_STANDARD 14) # Set definitions -IF(TRACE) - ADD_DEFINITIONS(-DSVO_TRACE) -ENDIF() -IF(HAVE_G2O) - ADD_DEFINITIONS(-DUSE_BUNDLE_ADJUSTMENT) -ENDIF() -IF(USE_ROS) - ADD_DEFINITIONS(-DSVO_USE_ROS) -ENDIF() -IF(DEBUG_OUTPUT) - ADD_DEFINITIONS(-DSVO_DEBUG_OUTPUT) -ENDIF() +ADD_DEFINITIONS(-DSVO_TRACE) +ADD_DEFINITIONS(-DSVO_USE_ROS) + # Set build flags, set ARM_ARCHITECTURE environment variable on Odroid # Set build flags. Set IS_ARM on odroid board as environment variable @@ -50,49 +32,44 @@ SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -fsee -fomit-frame-pointer - FIND_PACKAGE(OpenCV REQUIRED) FIND_PACKAGE(Eigen REQUIRED) FIND_PACKAGE(Sophus REQUIRED) -FIND_PACKAGE(fast REQUIRED) FIND_PACKAGE(Boost REQUIRED COMPONENTS thread system) FIND_PACKAGE(GTSAM REQUIRED) +FIND_PACKAGE(OpenCL REQUIRED) +FIND_PACKAGE(vikit_common REQUIRED) set(GTSAM_INCLUDE_DIRS "${GTSAM_INCLUDE_DIR}") -IF(USE_ROS) - FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros) - catkin_package( +FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros) +catkin_package( DEPENDS Eigen OpenCV Sophus Boost fast GTSAM CATKIN_DEPENDS roscpp roslib vikit_common vikit_ros INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} - ) -ELSE() - FIND_PACKAGE(vikit_common REQUIRED) - SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) - SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) -ENDIF() +) + # Include dirs INCLUDE_DIRECTORIES( include - ${Eigen_INCLUDE_DIRS} - ${OpenCV_INCLUDE_DIRS} - ${Sophus_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${fast_INCLUDE_DIRS} ${GTSAM_INCLUDE_DIR} + kernel + ${Eigen_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${Sophus_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${OpenCL_INCLUDE_DIRS} + ${GTSAM_INCLUDE_DIR} + ${catkin_INCLUDE_DIRS} ) # Set link libraries -LIST(APPEND LINK_LIBS +LIST(APPEND LINK_LIBS + gtsam ${OpenCV_LIBS} ${Sophus_LIBRARIES} ${Boost_LIBRARIES} - ${fast_LIBRARIES} + ${OpenCL_LIBRARIES} + ${catkin_LIBRARIES} ) -IF(USE_ROS) - INCLUDE_DIRECTORIES(${catkin_INCLUDE_DIRS}) - LIST(APPEND LINK_LIBS ${catkin_LIBRARIES}) -ELSE() - INCLUDE_DIRECTORIES(${vikit_common_INCLUDE_DIRS}) - LIST(APPEND LINK_LIBS ${vikit_common_LIBRARIES}) -ENDIF() + # Set sourcefiles LIST(APPEND SOURCEFILES @@ -109,24 +86,13 @@ LIST(APPEND SOURCEFILES src/feature_detection.cpp src/depth_filter.cpp src/config.cpp - src/sparse_img_align.cpp src/imu_integration.cpp) - -# Add g2o if available -IF(HAVE_G2O) - FIND_PACKAGE(G2O REQUIRED) - INCLUDE_DIRECTORIES( - ${G2O_INCLUDE_DIR} - /usr/include/suitesparse # for cholmod - ) - LIST(APPEND LINK_LIBS - ${G2O_CORE_LIBRARY} ${G2O_STUFF_LIBRARY} ${G2O_SOLVER_CHOLMOD} ${G2O_SOLVER_CSPARSE} ${G2O_SOLVER_DENSE} - ${G2O_SOLVER_PCG} ${G2O_TYPES_SBA} cholmod cxsparse - ) - LIST(APPEND SOURCEFILES src/bundle_adjustment.cpp) -ENDIF(HAVE_G2O) + src/sparse_img_align.cpp + src/imu_integration.cpp + src/cl_class.cpp) # Create svo library ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCEFILES}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LINK_LIBS} gtsam) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LINK_LIBS} ) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) +target_compile_features(${PROJECT_NAME} PRIVATE cxx_range_for) diff --git a/GPU_version/svo/include/svo/cl_class.h b/GPU_version/svo/include/svo/cl_class.h new file mode 100644 index 0000000..c0b378a --- /dev/null +++ b/GPU_version/svo/include/svo/cl_class.h @@ -0,0 +1,197 @@ +// +// Created by root on 4/27/21. +// + +#ifndef VIO_OPENCL_CL_CLASS_H +#define VIO_OPENCL_CL_CLASS_H +#include +#include +#include +#include +#include +#include +#define __CL_ENABLE_EXCEPTIONS +#include +#include + +class kernel{ +public: + kernel(cl::Program* program,std::string name){_kernel = new cl::Kernel(*program,name.c_str());}; + ~kernel(){ + //for(auto i:_buffers)i.first.first.; + _buffers.clear(); + _images.clear(); + }; + template + int32_t write(size_t id/*buffer ID*/,T* buf,cl::CommandQueue* queue,cl::Context* context,size_t buf_size){ + try{ + _buffers.push_back(std::pair,size_t>(std::pair(cl::Buffer(*context, CL_MEM_READ_WRITE, sizeof(T) * buf_size), + buf_size),id)); + queue->enqueueWriteBuffer(_buffers.back().first.first,CL_TRUE, 0, sizeof(T) * buf_size, buf); + _kernel->setArg(id,_buffers.back().first.first); + return CL_SUCCESS; + }catch (std::exception& err){ + std::cerr<<"Error C:Kernel, F:write\n"<(cl::Image2D(*context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, + cl::ImageFormat(CL_R, CL_UNSIGNED_INT8), + buf.size().width, + buf.size().height, + 0, + reinterpret_cast(buf.data)),id)); + /* }else{ + _images.push_back(std::pair(cl::Image2D(*context, CL_MEM_READ_WRITE, + cl::ImageFormat(CL_RGBA, CL_UNORM_INT8), + buf.size().width, + buf.size().height),id)); + }*/ + + _kernel->setArg(id,_images.back().first); + return CL_SUCCESS; + }catch (std::exception& err){ + std::cerr<<"Error C:Kernel, F:write image\n"< + int32_t reload(size_t id,T* buf,cl::CommandQueue* queue){ + try{ + if(id>_buffers.size())return CL_MAP_FAILURE; + for(auto i:_buffers)if(i.second==id) + queue->enqueueWriteBuffer(i.first.first,CL_TRUE, 0, sizeof(T) * i.first.second, buf); + return CL_SUCCESS; + }catch (std::exception& err){ + std::cerr<<"Reload buffer on GPU failed\n"<(buf.data)); + return CL_SUCCESS; + }catch (std::exception& err){ + std::cerr<<"Reload buffer on GPU failed\n"<,size_t>> _buffers; + std::vector> _images; + +}; +class read_cl{ +public: + read_cl(std::string path){ + src_str=(char *)malloc(0x100000); + FILE *fp; + fp = fopen(path.c_str(), "r"); + size = fread(src_str, 1, 0x100000, fp); + fclose(fp); + } + void print(){ + std::cerr< + int32_t write_buf(size_t id1/*kernal ID*/,size_t id2/*buffer ID*/, int size,T* buf) { + try{ + _kernels.at(id1).write(id2,buf,queue,context,size); + return CL_SUCCESS; + }catch (std::exception& err){ + std::cerr<<"Write buffer on GPU failed\n"< + int32_t write_buf(size_t id1/*kernal ID*/,size_t id2/*buffer ID*/,T& value){ + _kernels.at(id1)._kernel->setArg(id2,value); + }; + template + int32_t reload_buf(size_t id1/*kernal ID*/,size_t id2/*buffer ID*/,T* buf) { + try{ + _kernels.at(id1).reload(id2,buf,queue); + return CL_SUCCESS; + }catch (std::exception& err){ + std::cerr<<"Reload buffer on GPU failed\n"< + int32_t run(size_t id1/*kernal ID*/,std::size_t x=1,std::size_t y=1,std::size_t z=1,size_t id2=0/*last id of the kernel related to the output*/, + size_t size_out=0/*out put buffer size*/, + T* out= nullptr) { + try{ + //std::cerr<<"kernel: "<<_kernels.at(id1)._kernel->getInfo(); + //std::cerr<<" ,Args: "<<_kernels.at(id1)._kernel->getInfo()<<" ,Run out: "; + cl::Buffer out_buf(*context, CL_MEM_READ_WRITE, sizeof(T) * size_out); + _kernels.at(id1)._kernel->setArg(id2,out_buf); + if(z>1 && y>1){ + std::cerr<enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x,y,z)/*Global*/, cl::NullRange/*local*/)<<'\n'; + }else if(z<2 && y>1){ + queue->enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x,y)/*Global*/, cl::NullRange/*local*/); + //std::cerr<enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x,y)/*Global*/, cl::NullRange/*local*/)<<'\n'; + /*std::cerr<<_kernels.at(id1)._kernel->getArgInfo(0)<<'\n'; + std::cerr<<_kernels.at(id1)._kernel->getArgInfo(1)<<'\n'; + std::cerr<<_kernels.at(id1)._kernel->getArgInfo(2)<<'\n'; + std::cerr<<_kernels.at(id1)._kernel->getArgInfo(3)<<'\n';*/ + }else{ + std::cerr<enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x)/*Global*/, cl::NullRange/*local*/)<<'\n'; + }; + queue->enqueueReadBuffer(out_buf, CL_TRUE, 0, sizeof(T) * size_out, out); + //wait for kernel to finish + queue->finish(); + return CL_SUCCESS; + } catch (std::exception& err) { + std::cerr<<"RUN kernel Error\n"< _kernels; + cl::Context* context = NULL; + cl::Device device; + cl::Program* program = NULL; + cl::CommandQueue* queue=NULL; +}; + +#endif //VIO_OPENCL_CL_CLASS_H diff --git a/GPU_version/svo/kernel/fast-gray.cl b/GPU_version/svo/kernel/fast-gray.cl new file mode 100644 index 0000000..e9ba8f4 --- /dev/null +++ b/GPU_version/svo/kernel/fast-gray.cl @@ -0,0 +1,103 @@ +// Copyright (C) 2011 Dmitri Nikulin +// Copyright (C) 2011 Monash University +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +// Enable OpenCL 32-bit integer atomic functions. + +__kernel void fast_gray( + __read_only image2d_t image, + __global int2 * corners, + __global int * icorner, + int fast_count +) { + + // Prepare a suitable OpenCL image sampler. + sampler_t const sampler = CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; + + // Use global work item as 2D image coordinates. + int const x = get_global_id(0); + int const y = get_global_id(1); + if(x>16 && x16){ + int2 const xy = (int2)(x, y); + // Read the candidate pixel. + int const p00 = read_imageui(image, sampler, xy).x; + + // Read other pixels in a circle around the candidate pixel. + int const p01 = read_imageui(image, sampler, xy + (int2)( 0, 3)).x; + int const p05 = read_imageui(image, sampler, xy + (int2)( 3, 0)).x; + int const p09 = read_imageui(image, sampler, xy + (int2)( 0, -3)).x; + int const p13 = read_imageui(image, sampler, xy + (int2)(-3, 0)).x; + + // Check the absolute difference of each circle pixel. + int const d01 = (abs(p01 - p00) > FAST_THRESH); + int const d05 = (abs(p05 - p00) > FAST_THRESH); + int const d09 = (abs(p09 - p00) > FAST_THRESH); + int const d13 = (abs(p13 - p00) > FAST_THRESH); + + // Check if any two adjacent circle pixels have a high absolute difference. + + if ((d01 && d05) ||(d05 && d09) ||(d09 && d13) ||(d13 && d01)) { + // Read other pixels in a circle around the candidate pixel. + int const p02 = read_imageui(image, sampler, xy + (int2)( 1, 3)).x; + int const p03 = read_imageui(image, sampler, xy + (int2)( 2, 2)).x; + int const p04 = read_imageui(image, sampler, xy + (int2)( 3, 1)).x; + int const p06 = read_imageui(image, sampler, xy + (int2)( 3, -1)).x; + int const p07 = read_imageui(image, sampler, xy + (int2)( 2, -2)).x; + int const p08 = read_imageui(image, sampler, xy + (int2)( 1, -3)).x; + int const p10 = read_imageui(image, sampler, xy + (int2)(-1, -3)).x; + int const p11 = read_imageui(image, sampler, xy + (int2)(-2, -2)).x; + int const p12 = read_imageui(image, sampler, xy + (int2)(-3, -1)).x; + int const p14 = read_imageui(image, sampler, xy + (int2)(-3, 1)).x; + int const p15 = read_imageui(image, sampler, xy + (int2)(-2, 2)).x; + int const p16 = read_imageui(image, sampler, xy + (int2)(-1, 3)).x; + // Select the maximum score. + int sco = p00; + sco = max(sco, p01); + sco = max(sco, p02); + sco = max(sco, p03); + sco = max(sco, p04); + sco = max(sco, p05); + sco = max(sco, p06); + sco = max(sco, p07); + sco = max(sco, p08); + sco = max(sco, p09); + sco = max(sco, p10); + sco = max(sco, p11); + sco = max(sco, p12); + sco = max(sco, p13); + sco = max(sco, p14); + sco = max(sco, p15); + + // Keep this score if it is as good as the maximum. + if (p00 >= sco) { + // Atomically append to corner buffer. + int const icorn = atom_inc(icorner); + if (icorn < fast_count) + corners[icorn] = xy; + } + } + + } + +} + diff --git a/GPU_version/svo/src/cl_class.cpp b/GPU_version/svo/src/cl_class.cpp new file mode 100644 index 0000000..59ba287 --- /dev/null +++ b/GPU_version/svo/src/cl_class.cpp @@ -0,0 +1,56 @@ +// +// Created by root on 4/27/21. +// +#include "svo/cl_class.h" +opencl::opencl() { + std::vector all_platforms; + cl::Platform::get(&all_platforms); + if (all_platforms.size() == 0){ + std::cerr << " No platforms found. Check OpenCL installation!\n"; + exit(1); + } + //get default device of the default platform + std::vector all_devices; + for(auto i:all_platforms){ + std::cout << "Find platform: " << i.getInfo() << "\n"; + i.getDevices(CL_DEVICE_TYPE_GPU, &all_devices); + } + + if (all_devices.size() == 0){ + std::cout << " No devices found. Check OpenCL installation!\n"; + exit(1); + } + device = all_devices[0]; + std::cout << "CL_DEVICE_NAME: " << device.getInfo() <<'\n' + << "CL_DEVICE_OPENCL_C_VERSION: " <()<<'\n' + << "CL_DEVICE_BUILT_IN_KERNELS: " <()<<'\n' + << "CL_DEVICE_COMPILER_AVAILABLE: " <()<<'\n' + << "CL_DEVICE_LOCAL_MEM_SIZE: " <()<<'\n' + << "CL_DEVICE_GLOBAL_MEM_SIZE: " <()<<'\n'; + + context=new cl::Context({ device }); + cl::Program::Sources sources; + read_cl int_add("../kernel/int_add.cl"); + sources.push_back({ int_add.src_str, int_add.size }); + read_cl double_add("../kernel/double_add.cl"); + sources.push_back({ double_add.src_str, double_add.size }); + read_cl corner_10_less("../kernel/is_corner_10_less.cl"); + sources.push_back({ corner_10_less.src_str, corner_10_less.size }); + read_cl prefast("../kernel/prefast-gray.cl"); + sources.push_back({ prefast.src_str, prefast.size }); + //read_cl fast("../kernel/fast-gray.cl"); + // sources.push_back({ fast.src_str, fast.size}); + program=new cl::Program(*context, sources); + if(program->build({ device },"-DFAST_THRESH=40 -DFAST_RING=15") !=0) + std::cout << " Error building: " << program->getBuildInfo(device)<<'\n' + <getBuildInfo(device) << '\n'; + queue=new cl::CommandQueue(*context,device,0,NULL); +} +opencl::~opencl() { + queue->finish(); +} +void opencl::clear_buf() { + _kernels.clear(); + queue->flush(); +} + From 5a693259d6aa9d238310cfcba23eb240df4e5af5 Mon Sep 17 00:00:00 2001 From: gfuse Date: Wed, 5 May 2021 19:12:01 +0200 Subject: [PATCH 188/215] add fast kernel --- GPU_version/svo/include/svo/cl_class.h | 92 +++++++++---------- .../svo/include/svo/feature_detection.h | 7 +- GPU_version/svo/kernel/fast-gray.cl | 27 +----- GPU_version/svo/src/cl_class.cpp | 22 ++--- GPU_version/svo/src/feature_detection.cpp | 53 ++++++----- GPU_version/svo/src/frame.cpp | 1 - 6 files changed, 85 insertions(+), 117 deletions(-) diff --git a/GPU_version/svo/include/svo/cl_class.h b/GPU_version/svo/include/svo/cl_class.h index c0b378a..ff4cd39 100644 --- a/GPU_version/svo/include/svo/cl_class.h +++ b/GPU_version/svo/include/svo/cl_class.h @@ -10,7 +10,6 @@ #include #include #include -#define __CL_ENABLE_EXCEPTIONS #include #include @@ -18,45 +17,40 @@ class kernel{ public: kernel(cl::Program* program,std::string name){_kernel = new cl::Kernel(*program,name.c_str());}; ~kernel(){ - //for(auto i:_buffers)i.first.first.; _buffers.clear(); _images.clear(); }; template int32_t write(size_t id/*buffer ID*/,T* buf,cl::CommandQueue* queue,cl::Context* context,size_t buf_size){ - try{ - _buffers.push_back(std::pair,size_t>(std::pair(cl::Buffer(*context, CL_MEM_READ_WRITE, sizeof(T) * buf_size), + _buffers.push_back(std::pair,size_t>(std::pair(cl::Buffer(*context, CL_MEM_READ_WRITE, sizeof(T) * buf_size), buf_size),id)); - queue->enqueueWriteBuffer(_buffers.back().first.first,CL_TRUE, 0, sizeof(T) * buf_size, buf); - _kernel->setArg(id,_buffers.back().first.first); - return CL_SUCCESS; - }catch (std::exception& err){ - std::cerr<<"Error C:Kernel, F:write\n"<enqueueWriteBuffer(_buffers.back().first.first,CL_TRUE, 0, sizeof(T) * buf_size, buf); + if(err!=0){ + std::cerr<<"Error C:Kernel, F:write, L:enqueueWriteBuffer\n"<setArg(id,_buffers.back().first.first); + if(err!=0){ + std::cerr<<"Error C:Kernel, F:write, L3:setArg\n"<(cl::Image2D(*context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, + _images.push_back(std::pair(cl::Image2D(*context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, cl::ImageFormat(CL_R, CL_UNSIGNED_INT8), buf.size().width, buf.size().height, 0, reinterpret_cast(buf.data)),id)); - /* }else{ - _images.push_back(std::pair(cl::Image2D(*context, CL_MEM_READ_WRITE, - cl::ImageFormat(CL_RGBA, CL_UNORM_INT8), - buf.size().width, - buf.size().height),id)); - }*/ - _kernel->setArg(id,_images.back().first); - return CL_SUCCESS; - }catch (std::exception& err){ - std::cerr<<"Error C:Kernel, F:write image\n"<setArg(id,_images.back().first); + if(err!=0){ + std::cerr<<"Error C:Kernel, F:write image, L:setArg\n"< @@ -87,6 +81,12 @@ public: } }; cl::Kernel* _kernel = NULL; + std::pair read(size_t id){ + for(auto i:_buffers)if(i.second==id)return i.first; + } + cl::Image2D read_img(size_t id){ + for(auto i:_images)if(i.second==id)return i.first; + } private: std::vector,size_t>> _buffers; std::vector> _images; @@ -132,7 +132,7 @@ public: } } template - int32_t write_buf(size_t id1/*kernal ID*/,size_t id2/*buffer ID*/,T& value){ + int32_t write_buf(size_t id1/*kernal ID*/,size_t id2/*buffer ID*/,T&& value){ _kernels.at(id1)._kernel->setArg(id2,value); }; template @@ -154,37 +154,29 @@ public: return CL_MAP_FAILURE; } } - template - int32_t run(size_t id1/*kernal ID*/,std::size_t x=1,std::size_t y=1,std::size_t z=1,size_t id2=0/*last id of the kernel related to the output*/, - size_t size_out=0/*out put buffer size*/, - T* out= nullptr) { - try{ - //std::cerr<<"kernel: "<<_kernels.at(id1)._kernel->getInfo(); - //std::cerr<<" ,Args: "<<_kernels.at(id1)._kernel->getInfo()<<" ,Run out: "; - cl::Buffer out_buf(*context, CL_MEM_READ_WRITE, sizeof(T) * size_out); - _kernels.at(id1)._kernel->setArg(id2,out_buf); + int32_t run(size_t id1/*kernal ID*/,std::size_t x=1,std::size_t y=1,std::size_t z=1) { + cl_int err=0; if(z>1 && y>1){ - std::cerr<enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x,y,z)/*Global*/, cl::NullRange/*local*/)<<'\n'; + err=queue->enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x,y,z)/*Global*/, cl::NullRange/*local*/); }else if(z<2 && y>1){ - queue->enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x,y)/*Global*/, cl::NullRange/*local*/); - //std::cerr<enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x,y)/*Global*/, cl::NullRange/*local*/)<<'\n'; - /*std::cerr<<_kernels.at(id1)._kernel->getArgInfo(0)<<'\n'; - std::cerr<<_kernels.at(id1)._kernel->getArgInfo(1)<<'\n'; - std::cerr<<_kernels.at(id1)._kernel->getArgInfo(2)<<'\n'; - std::cerr<<_kernels.at(id1)._kernel->getArgInfo(3)<<'\n';*/ + err=queue->enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x,y)/*Global*/, cl::NullRange/*local*/); }else{ - std::cerr<enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x)/*Global*/, cl::NullRange/*local*/)<<'\n'; + err=queue->enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x)/*Global*/, cl::NullRange/*local*/); }; - queue->enqueueReadBuffer(out_buf, CL_TRUE, 0, sizeof(T) * size_out, out); - //wait for kernel to finish queue->finish(); - return CL_SUCCESS; - } catch (std::exception& err) { - std::cerr<<"RUN kernel Error\n"<getInfo(); + std::cerr<<" ,Args: "<<_kernels.at(id1)._kernel->getInfo()<<" ,Run out: "<getInfo();++i) + std::cerr<<"argument type "<getArgInfo(i)<<'\n'; + } + return err; } + template + void read(size_t id1/*kernal ID*/,size_t id2/*buffer ID*/, T* out){ + queue->enqueueReadBuffer(_kernels.at(id1).read(id2).first, CL_TRUE, 0, sizeof(T) * _kernels.at(id1).read(id2).second, out); + } void clear_buf(); private: std::vector _kernels; diff --git a/GPU_version/svo/include/svo/feature_detection.h b/GPU_version/svo/include/svo/feature_detection.h index d0990a8..6267d20 100644 --- a/GPU_version/svo/include/svo/feature_detection.h +++ b/GPU_version/svo/include/svo/feature_detection.h @@ -19,6 +19,7 @@ #include #include +#include namespace svo { @@ -49,7 +50,10 @@ public: const int cell_size, const int n_pyr_levels); - virtual ~AbstractDetector() {}; + virtual ~AbstractDetector() { + gpu_fast_->clear_buf(); + gpu_fast_->make_kernel("fast_gray"); + }; virtual void detect( Frame* frame, @@ -62,6 +66,7 @@ public: /// Set grid cells of existing features as occupied void setExistingFeatures(const Features& fts); + opencl* gpu_fast_= nullptr; protected: diff --git a/GPU_version/svo/kernel/fast-gray.cl b/GPU_version/svo/kernel/fast-gray.cl index e9ba8f4..ec36066 100644 --- a/GPU_version/svo/kernel/fast-gray.cl +++ b/GPU_version/svo/kernel/fast-gray.cl @@ -1,28 +1,5 @@ -// Copyright (C) 2011 Dmitri Nikulin -// Copyright (C) 2011 Monash University -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. - -// Enable OpenCL 32-bit integer atomic functions. +// Copyright (C) 2021 Majid Geravand +// Copyright (C) 2021 Gfuse __kernel void fast_gray( __read_only image2d_t image, diff --git a/GPU_version/svo/src/cl_class.cpp b/GPU_version/svo/src/cl_class.cpp index 59ba287..d32f140 100644 --- a/GPU_version/svo/src/cl_class.cpp +++ b/GPU_version/svo/src/cl_class.cpp @@ -25,32 +25,24 @@ opencl::opencl() { << "CL_DEVICE_OPENCL_C_VERSION: " <()<<'\n' << "CL_DEVICE_BUILT_IN_KERNELS: " <()<<'\n' << "CL_DEVICE_COMPILER_AVAILABLE: " <()<<'\n' - << "CL_DEVICE_LOCAL_MEM_SIZE: " <()<<'\n' - << "CL_DEVICE_GLOBAL_MEM_SIZE: " <()<<'\n'; + << "CL_DEVICE_LOCAL_MEM_SIZE: " <()<<'\n' + << "CL_DEVICE_GLOBAL_MEM_SIZE: " <()<<'\n'; context=new cl::Context({ device }); cl::Program::Sources sources; - read_cl int_add("../kernel/int_add.cl"); - sources.push_back({ int_add.src_str, int_add.size }); - read_cl double_add("../kernel/double_add.cl"); - sources.push_back({ double_add.src_str, double_add.size }); - read_cl corner_10_less("../kernel/is_corner_10_less.cl"); - sources.push_back({ corner_10_less.src_str, corner_10_less.size }); - read_cl prefast("../kernel/prefast-gray.cl"); - sources.push_back({ prefast.src_str, prefast.size }); - //read_cl fast("../kernel/fast-gray.cl"); - // sources.push_back({ fast.src_str, fast.size}); + read_cl fast("../kernel/fast-gray.cl"); + sources.push_back({ fast.src_str, fast.size }); program=new cl::Program(*context, sources); - if(program->build({ device },"-DFAST_THRESH=40 -DFAST_RING=15") !=0) + if(program->build({ device },"-DFAST_THRESH=40") !=0) std::cout << " Error building: " << program->getBuildInfo(device)<<'\n' <getBuildInfo(device) << '\n'; queue=new cl::CommandQueue(*context,device,0,NULL); } opencl::~opencl() { - queue->finish(); } void opencl::clear_buf() { - _kernels.clear(); + queue->finish(); queue->flush(); + _kernels.clear(); } diff --git a/GPU_version/svo/src/feature_detection.cpp b/GPU_version/svo/src/feature_detection.cpp index 98183f8..8aaac0c 100644 --- a/GPU_version/svo/src/feature_detection.cpp +++ b/GPU_version/svo/src/feature_detection.cpp @@ -16,7 +16,6 @@ #include #include -#include #include namespace svo { @@ -32,7 +31,16 @@ AbstractDetector::AbstractDetector( grid_n_cols_(ceil(static_cast(img_width)/cell_size_)), grid_n_rows_(ceil(static_cast(img_height)/cell_size_)), grid_occupancy_(grid_n_cols_*grid_n_rows_, false) -{} +{ + gpu_fast_= new opencl(); + cv::Mat init=cv::Mat::zeros(cv::Size(img_width, img_height),CV_8UC1); + gpu_fast_->write_buf(0,0,init); + cl_int2 corners[img_width*img_height]; + gpu_fast_->write_buf(0,1,img_width*img_height,corners); + int icorner[1]={0}; + gpu_fast_->write_buf(0,2,1,icorner); + gpu_fast_->write_buf(0,3,(1 << 18)); +} void AbstractDetector::resetGrid() { @@ -73,35 +81,30 @@ void FastDetector::detect( for(int L=0; L fast_corners; -#if __SSE2__ - fast::fast_corner_detect_10_sse2( - (fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, - img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); -#elif HAVE_FAST_NEON - fast::fast_corner_detect_9_neon( - (fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, - img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); -#else - fast::fast_corner_detect_10( - (fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, - img_pyr[L].rows, img_pyr[L].cols, 20, fast_corners); -#endif - vector scores, nm_corners; - fast::fast_corner_score_10((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, fast_corners, 20, scores); - fast::fast_nonmax_3x3(fast_corners, scores, nm_corners); + gpu_fast_->reload_buf(0,0,img_pyr[L].data); + int icorner[1]={0}; + gpu_fast_->reload_buf(0,2,icorner); + gpu_fast_->run(0,img_pyr[L].cols,img_pyr[L].rows); + cl_int2* fast_corners; + gpu_fast_->read(0,1,fast_corners); + int count[1]={0}; + gpu_fast_->read(0,2,count); + //vector scores, nm_corners; + //fast::fast_corner_score_10((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, fast_corners, 20, scores); + //fast::fast_nonmax_3x3(fast_corners, scores, nm_corners); - for(auto it=nm_corners.begin(), ite=nm_corners.end(); it!=ite; ++it) + for(uint i=0;i((xy.y*scale)/cell_size_)*grid_n_cols_ - + static_cast((xy.x*scale)/cell_size_); + if(fast_corners[i].x<0 || fast_corners[i].x>img_pyr[L].cols || fast_corners[i].y>img_pyr[L].rows || fast_corners[i].y<0)continue; + const int k = static_cast((fast_corners[i].y*scale)/cell_size_)*grid_n_cols_ + + static_cast((fast_corners[i].x*scale)/cell_size_); if(grid_occupancy_[k]) continue; - const float score = vk::shiTomasiScore(img_pyr[L], xy.x, xy.y); + const float score = vk::shiTomasiScore(img_pyr[L], fast_corners[i].x, fast_corners[i].y); if(score > corners.at(k).score) - corners.at(k) = Corner(xy.x*scale, xy.y*scale, score, L, 0.0f); + corners.at(k) = Corner(fast_corners[i].x*scale, fast_corners[i].y*scale, score, L, 0.0f); } + } // Create feature for every corner that has high enough corner score diff --git a/GPU_version/svo/src/frame.cpp b/GPU_version/svo/src/frame.cpp index 44ddab6..440c32d 100644 --- a/GPU_version/svo/src/frame.cpp +++ b/GPU_version/svo/src/frame.cpp @@ -22,7 +22,6 @@ #include #include #include -#include namespace svo { From 9dbc540a5d6f00428d5eb12523cad86b4ce99b96 Mon Sep 17 00:00:00 2001 From: gfuse Date: Sat, 8 May 2021 11:53:15 +0200 Subject: [PATCH 189/215] debug gpu version done --- GPU_version/svo/CMakeLists.txt | 1 + .../{svo => gpu_svo}/bundle_adjustment.h | 2 +- .../svo/include/{svo => gpu_svo}/cl_class.h | 6 +- .../svo/include/{svo => gpu_svo}/config.h | 0 .../include/{svo => gpu_svo}/depth_filter.h | 6 +- .../svo/include/{svo => gpu_svo}/feature.h | 2 +- .../{svo => gpu_svo}/feature_alignment.h | 2 +- .../{svo => gpu_svo}/feature_detection.h | 11 +- .../svo/include/{svo => gpu_svo}/frame.h | 2 +- .../{svo => gpu_svo}/frame_handler_base.h | 4 +- .../{svo => gpu_svo}/frame_handler_mono.h | 17 +- .../svo/include/{svo => gpu_svo}/global.h | 0 .../{svo => gpu_svo}/imu_integration.h | 2 +- .../include/{svo => gpu_svo}/initialization.h | 9 +- .../svo/include/{svo => gpu_svo}/map.h | 2 +- .../svo/include/{svo => gpu_svo}/matcher.h | 2 +- .../svo/include/{svo => gpu_svo}/point.h | 2 +- .../include/{svo => gpu_svo}/pose_optimizer.h | 2 +- .../include/{svo => gpu_svo}/reprojector.h | 4 +- .../{svo => gpu_svo}/sparse_img_align.h | 2 +- .../{svo => gpu_svo}/svoVisionFactor.h | 2 +- GPU_version/svo/src/bundle_adjustment.cpp | 12 +- GPU_version/svo/src/cl_class.cpp | 6 +- GPU_version/svo/src/config.cpp | 2 +- GPU_version/svo/src/depth_filter.cpp | 16 +- GPU_version/svo/src/feature_alignment.cpp | 2 +- GPU_version/svo/src/feature_detection.cpp | 34 +- GPU_version/svo/src/frame.cpp | 8 +- GPU_version/svo/src/frame_handler_base.cpp | 12 +- GPU_version/svo/src/frame_handler_mono.cpp | 38 ++- GPU_version/svo/src/imu_integration.cpp | 10 +- GPU_version/svo/src/initialization.cpp | 19 +- GPU_version/svo/src/map.cpp | 8 +- GPU_version/svo/src/matcher.cpp | 12 +- GPU_version/svo/src/point.cpp | 6 +- GPU_version/svo/src/pose_optimizer.cpp | 8 +- GPU_version/svo/src/reprojector.cpp | 12 +- GPU_version/svo/src/sparse_img_align.cpp | 10 +- GPU_version/vio/.idea/.gitignore | 8 + GPU_version/vio/.idea/misc.xml | 4 + GPU_version/vio/.idea/modules.xml | 8 + GPU_version/vio/.idea/vcs.xml | 6 + GPU_version/vio/CMakeLists.txt | 92 ++++++ GPU_version/vio/include/vio_gpu/visualizer.h | 73 +++++ GPU_version/vio/launch/Px30.launch | 22 ++ GPU_version/vio/launch/live.launch | 16 + GPU_version/vio/launch/test.launch | 22 ++ GPU_version/vio/launch/unity.launch | 22 ++ GPU_version/vio/msg/Info.msg | 6 + GPU_version/vio/package.xml | 43 +++ GPU_version/vio/param/camera_atan.yaml | 8 + GPU_version/vio/param/camera_pinhole.yaml | 11 + GPU_version/vio/param/px30.yaml | 8 + GPU_version/vio/param/unity.yaml | 8 + GPU_version/vio/param/vo_accurate.yaml | 4 + GPU_version/vio/param/vo_fast.yaml | 13 + GPU_version/vio/rqt.perspective | 293 ++++++++++++++++++ GPU_version/vio/rviz_config.rviz | 153 +++++++++ GPU_version/vio/src/visualizer.cpp | 127 ++++++++ GPU_version/vio/src/vo_node.cpp | 148 +++++++++ 60 files changed, 1249 insertions(+), 141 deletions(-) rename GPU_version/svo/include/{svo => gpu_svo}/bundle_adjustment.h (99%) rename GPU_version/svo/include/{svo => gpu_svo}/cl_class.h (98%) rename GPU_version/svo/include/{svo => gpu_svo}/config.h (100%) rename GPU_version/svo/include/{svo => gpu_svo}/depth_filter.h (98%) rename GPU_version/svo/include/{svo => gpu_svo}/feature.h (98%) rename GPU_version/svo/include/{svo => gpu_svo}/feature_alignment.h (98%) rename GPU_version/svo/include/{svo => gpu_svo}/feature_detection.h (94%) rename GPU_version/svo/include/{svo => gpu_svo}/frame.h (99%) rename GPU_version/svo/include/{svo => gpu_svo}/frame_handler_base.h (98%) rename GPU_version/svo/include/{svo => gpu_svo}/frame_handler_mono.h (90%) rename GPU_version/svo/include/{svo => gpu_svo}/global.h (100%) rename GPU_version/svo/include/{svo => gpu_svo}/imu_integration.h (99%) rename GPU_version/svo/include/{svo => gpu_svo}/initialization.h (93%) rename GPU_version/svo/include/{svo => gpu_svo}/map.h (99%) rename GPU_version/svo/include/{svo => gpu_svo}/matcher.h (99%) rename GPU_version/svo/include/{svo => gpu_svo}/point.h (99%) rename GPU_version/svo/include/{svo => gpu_svo}/pose_optimizer.h (98%) rename GPU_version/svo/include/{svo => gpu_svo}/reprojector.h (98%) rename GPU_version/svo/include/{svo => gpu_svo}/sparse_img_align.h (98%) rename GPU_version/svo/include/{svo => gpu_svo}/svoVisionFactor.h (99%) create mode 100644 GPU_version/vio/.idea/.gitignore create mode 100644 GPU_version/vio/.idea/misc.xml create mode 100644 GPU_version/vio/.idea/modules.xml create mode 100644 GPU_version/vio/.idea/vcs.xml create mode 100644 GPU_version/vio/CMakeLists.txt create mode 100644 GPU_version/vio/include/vio_gpu/visualizer.h create mode 100644 GPU_version/vio/launch/Px30.launch create mode 100644 GPU_version/vio/launch/live.launch create mode 100644 GPU_version/vio/launch/test.launch create mode 100644 GPU_version/vio/launch/unity.launch create mode 100644 GPU_version/vio/msg/Info.msg create mode 100644 GPU_version/vio/package.xml create mode 100644 GPU_version/vio/param/camera_atan.yaml create mode 100644 GPU_version/vio/param/camera_pinhole.yaml create mode 100644 GPU_version/vio/param/px30.yaml create mode 100644 GPU_version/vio/param/unity.yaml create mode 100644 GPU_version/vio/param/vo_accurate.yaml create mode 100644 GPU_version/vio/param/vo_fast.yaml create mode 100644 GPU_version/vio/rqt.perspective create mode 100644 GPU_version/vio/rviz_config.rviz create mode 100644 GPU_version/vio/src/visualizer.cpp create mode 100644 GPU_version/vio/src/vo_node.cpp diff --git a/GPU_version/svo/CMakeLists.txt b/GPU_version/svo/CMakeLists.txt index 4f0c7c5..ed41132 100644 --- a/GPU_version/svo/CMakeLists.txt +++ b/GPU_version/svo/CMakeLists.txt @@ -96,3 +96,4 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LINK_LIBS} ) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) target_compile_features(${PROJECT_NAME} PRIVATE cxx_range_for) +ADD_DEFINITIONS(-DKERNEL_DIR=\"${PROJECT_SOURCE_DIR}/kernel\") diff --git a/GPU_version/svo/include/svo/bundle_adjustment.h b/GPU_version/svo/include/gpu_svo/bundle_adjustment.h similarity index 99% rename from GPU_version/svo/include/svo/bundle_adjustment.h rename to GPU_version/svo/include/gpu_svo/bundle_adjustment.h index f3c3501..9eb8a94 100644 --- a/GPU_version/svo/include/svo/bundle_adjustment.h +++ b/GPU_version/svo/include/gpu_svo/bundle_adjustment.h @@ -17,7 +17,7 @@ #ifndef SVO_BUNDLE_ADJUSTMENT_H_ #define SVO_BUNDLE_ADJUSTMENT_H_ -#include +#include namespace g2o { class EdgeProjectXYZ2UV; diff --git a/GPU_version/svo/include/svo/cl_class.h b/GPU_version/svo/include/gpu_svo/cl_class.h similarity index 98% rename from GPU_version/svo/include/svo/cl_class.h rename to GPU_version/svo/include/gpu_svo/cl_class.h index ff4cd39..bffee33 100644 --- a/GPU_version/svo/include/svo/cl_class.h +++ b/GPU_version/svo/include/gpu_svo/cl_class.h @@ -67,13 +67,15 @@ public: }; int32_t reload(size_t id,cv::Mat& buf,cl::Context* context){ try{ - for(auto i:_images)if(i.second==id) + for(auto i:_images)if(i.second==id){ i.first=cl::Image2D(*context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, cl::ImageFormat(CL_R, CL_UNSIGNED_INT8), buf.size().width, buf.size().height, 0, reinterpret_cast(buf.data)); + } + return CL_SUCCESS; }catch (std::exception& err){ std::cerr<<"Reload buffer on GPU failed\n"< #include #include -#include -#include -#include +#include +#include +#include namespace svo { diff --git a/GPU_version/svo/include/svo/feature.h b/GPU_version/svo/include/gpu_svo/feature.h similarity index 98% rename from GPU_version/svo/include/svo/feature.h rename to GPU_version/svo/include/gpu_svo/feature.h index 6f90a9a..2184c4b 100644 --- a/GPU_version/svo/include/svo/feature.h +++ b/GPU_version/svo/include/gpu_svo/feature.h @@ -17,7 +17,7 @@ #ifndef SVO_FEATURE_H_ #define SVO_FEATURE_H_ -#include +#include namespace svo { diff --git a/GPU_version/svo/include/svo/feature_alignment.h b/GPU_version/svo/include/gpu_svo/feature_alignment.h similarity index 98% rename from GPU_version/svo/include/svo/feature_alignment.h rename to GPU_version/svo/include/gpu_svo/feature_alignment.h index 12523e3..e3b40a8 100644 --- a/GPU_version/svo/include/svo/feature_alignment.h +++ b/GPU_version/svo/include/gpu_svo/feature_alignment.h @@ -17,7 +17,7 @@ #ifndef SVO_FEATURE_ALIGNMENT_H_ #define SVO_FEATURE_ALIGNMENT_H_ -#include +#include namespace svo { diff --git a/GPU_version/svo/include/svo/feature_detection.h b/GPU_version/svo/include/gpu_svo/feature_detection.h similarity index 94% rename from GPU_version/svo/include/svo/feature_detection.h rename to GPU_version/svo/include/gpu_svo/feature_detection.h index 6267d20..4dc5ec8 100644 --- a/GPU_version/svo/include/svo/feature_detection.h +++ b/GPU_version/svo/include/gpu_svo/feature_detection.h @@ -17,9 +17,9 @@ #ifndef SVO_FEATURE_DETECTION_H_ #define SVO_FEATURE_DETECTION_H_ -#include -#include -#include +#include +#include +#include namespace svo { @@ -51,8 +51,6 @@ public: const int n_pyr_levels); virtual ~AbstractDetector() { - gpu_fast_->clear_buf(); - gpu_fast_->make_kernel("fast_gray"); }; virtual void detect( @@ -66,7 +64,6 @@ public: /// Set grid cells of existing features as occupied void setExistingFeatures(const Features& fts); - opencl* gpu_fast_= nullptr; protected: @@ -95,6 +92,7 @@ public: const int img_width, const int img_height, const int cell_size, + opencl* gpu_fast_, const int n_pyr_levels); virtual ~FastDetector() {} @@ -104,6 +102,7 @@ public: const ImgPyr& img_pyr, const double detection_threshold, Features& fts); + opencl* gpu_fast_; }; } // namespace feature_detection diff --git a/GPU_version/svo/include/svo/frame.h b/GPU_version/svo/include/gpu_svo/frame.h similarity index 99% rename from GPU_version/svo/include/svo/frame.h rename to GPU_version/svo/include/gpu_svo/frame.h index c926277..43b344e 100644 --- a/GPU_version/svo/include/svo/frame.h +++ b/GPU_version/svo/include/gpu_svo/frame.h @@ -21,7 +21,7 @@ #include #include #include -#include +#include namespace g2o { class VertexSE3Expmap; diff --git a/GPU_version/svo/include/svo/frame_handler_base.h b/GPU_version/svo/include/gpu_svo/frame_handler_base.h similarity index 98% rename from GPU_version/svo/include/svo/frame_handler_base.h rename to GPU_version/svo/include/gpu_svo/frame_handler_base.h index 9a78639..9b207b3 100644 --- a/GPU_version/svo/include/svo/frame_handler_base.h +++ b/GPU_version/svo/include/gpu_svo/frame_handler_base.h @@ -23,8 +23,8 @@ #include #include #include -#include -#include +#include +#include namespace vk { diff --git a/GPU_version/svo/include/svo/frame_handler_mono.h b/GPU_version/svo/include/gpu_svo/frame_handler_mono.h similarity index 90% rename from GPU_version/svo/include/svo/frame_handler_mono.h rename to GPU_version/svo/include/gpu_svo/frame_handler_mono.h index 58789c8..58b8b22 100644 --- a/GPU_version/svo/include/svo/frame_handler_mono.h +++ b/GPU_version/svo/include/gpu_svo/frame_handler_mono.h @@ -19,10 +19,11 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace svo { @@ -48,8 +49,8 @@ public: const set& coreKeyframes() { return core_kfs_; } /// Return the feature track to visualize the KLT tracking during initialization. - const vector& initFeatureTrackRefPx() const { return klt_homography_init_.px_ref_; } - const vector& initFeatureTrackCurPx() const { return klt_homography_init_.px_cur_; } + const vector& initFeatureTrackRefPx() const { return klt_homography_init_->px_ref_; } + const vector& initFeatureTrackCurPx() const { return klt_homography_init_->px_cur_; } /// Access the depth filter. DepthFilter* depthFilter() const { return depth_filter_; } @@ -69,9 +70,9 @@ protected: FramePtr last_frame_; //!< Last frame, not necessarily a keyframe. set core_kfs_; //!< Keyframes in the closer neighbourhood. vector< pair > overlap_kfs_; //!< All keyframes with overlapping field of view. the paired number specifies how many common mappoints are observed TODO: why vector!? - initialization::KltHomographyInit klt_homography_init_; //!< Used to estimate pose of the first two keyframes by estimating a homography. + initialization::KltHomographyInit* klt_homography_init_; //!< Used to estimate pose of the first two keyframes by estimating a homography. DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. - + opencl* gpu_fast_; /// Initialize the visual odometry algorithm. virtual void initialize(); diff --git a/GPU_version/svo/include/svo/global.h b/GPU_version/svo/include/gpu_svo/global.h similarity index 100% rename from GPU_version/svo/include/svo/global.h rename to GPU_version/svo/include/gpu_svo/global.h diff --git a/GPU_version/svo/include/svo/imu_integration.h b/GPU_version/svo/include/gpu_svo/imu_integration.h similarity index 99% rename from GPU_version/svo/include/svo/imu_integration.h rename to GPU_version/svo/include/gpu_svo/imu_integration.h index 11b9055..2692f71 100644 --- a/GPU_version/svo/include/svo/imu_integration.h +++ b/GPU_version/svo/include/gpu_svo/imu_integration.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include using gtsam::symbol_shorthand::B; // Bias (ax,ay,az,gx,gy,gz) using gtsam::symbol_shorthand::V; // Vel (xdot,ydot,zdot) diff --git a/GPU_version/svo/include/svo/initialization.h b/GPU_version/svo/include/gpu_svo/initialization.h similarity index 93% rename from GPU_version/svo/include/svo/initialization.h rename to GPU_version/svo/include/gpu_svo/initialization.h index cb562e5..21f9350 100644 --- a/GPU_version/svo/include/svo/initialization.h +++ b/GPU_version/svo/include/gpu_svo/initialization.h @@ -17,7 +17,8 @@ #ifndef SVO_INITIALIZATION_H #define SVO_INITIALIZATION_H -#include +#include +#include namespace svo { @@ -35,7 +36,7 @@ public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW FramePtr frame_ref_; - KltHomographyInit() {}; + KltHomographyInit(opencl* gpu_fast_):gpu_fast_(gpu_fast_) {}; ~KltHomographyInit() {}; InitResult addFirstFrame(FramePtr frame_ref); InitResult addSecondFrame(FramePtr frame_ref); @@ -50,13 +51,15 @@ protected: vector inliers_; //!< inliers after the geometric check (e.g., Homography). vector xyz_in_cur_; //!< 3D points computed during the geometric check. SE3 T_cur_from_ref_; //!< computed transformation between the first two frames. + opencl* gpu_fast_; }; /// Detect Fast corners in the image. void detectFeatures( FramePtr frame, vector& px_vec, - vector& f_vec); + vector& f_vec, + opencl* gpu_fast); /// Compute optical flow (Lucas Kanade) for selected keypoints. void trackKlt( diff --git a/GPU_version/svo/include/svo/map.h b/GPU_version/svo/include/gpu_svo/map.h similarity index 99% rename from GPU_version/svo/include/svo/map.h rename to GPU_version/svo/include/gpu_svo/map.h index 458622b..3bee80b 100644 --- a/GPU_version/svo/include/svo/map.h +++ b/GPU_version/svo/include/gpu_svo/map.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include namespace svo { diff --git a/GPU_version/svo/include/svo/matcher.h b/GPU_version/svo/include/gpu_svo/matcher.h similarity index 99% rename from GPU_version/svo/include/svo/matcher.h rename to GPU_version/svo/include/gpu_svo/matcher.h index b53340e..1eeb9fd 100644 --- a/GPU_version/svo/include/svo/matcher.h +++ b/GPU_version/svo/include/gpu_svo/matcher.h @@ -17,7 +17,7 @@ #ifndef SVO_MATCHER_H_ #define SVO_MATCHER_H_ -#include +#include namespace vk { class AbstractCamera; diff --git a/GPU_version/svo/include/svo/point.h b/GPU_version/svo/include/gpu_svo/point.h similarity index 99% rename from GPU_version/svo/include/svo/point.h rename to GPU_version/svo/include/gpu_svo/point.h index e1bb81b..81d2769 100644 --- a/GPU_version/svo/include/svo/point.h +++ b/GPU_version/svo/include/gpu_svo/point.h @@ -18,7 +18,7 @@ #define SVO_POINT_H_ #include -#include +#include namespace g2o { class VertexSBAPointXYZ; diff --git a/GPU_version/svo/include/svo/pose_optimizer.h b/GPU_version/svo/include/gpu_svo/pose_optimizer.h similarity index 98% rename from GPU_version/svo/include/svo/pose_optimizer.h rename to GPU_version/svo/include/gpu_svo/pose_optimizer.h index ca048ae..d0ad926 100644 --- a/GPU_version/svo/include/svo/pose_optimizer.h +++ b/GPU_version/svo/include/gpu_svo/pose_optimizer.h @@ -17,7 +17,7 @@ #ifndef SVO_POSE_OPTIMIZER_H_ #define SVO_POSE_OPTIMIZER_H_ -#include +#include namespace svo { diff --git a/GPU_version/svo/include/svo/reprojector.h b/GPU_version/svo/include/gpu_svo/reprojector.h similarity index 98% rename from GPU_version/svo/include/svo/reprojector.h rename to GPU_version/svo/include/gpu_svo/reprojector.h index e345f0d..8d50c35 100644 --- a/GPU_version/svo/include/svo/reprojector.h +++ b/GPU_version/svo/include/gpu_svo/reprojector.h @@ -17,8 +17,8 @@ #ifndef SVO_REPROJECTION_H_ #define SVO_REPROJECTION_H_ -#include -#include +#include +#include namespace vk { class AbstractCamera; diff --git a/GPU_version/svo/include/svo/sparse_img_align.h b/GPU_version/svo/include/gpu_svo/sparse_img_align.h similarity index 98% rename from GPU_version/svo/include/svo/sparse_img_align.h rename to GPU_version/svo/include/gpu_svo/sparse_img_align.h index 1bedfed..58374be 100644 --- a/GPU_version/svo/include/svo/sparse_img_align.h +++ b/GPU_version/svo/include/gpu_svo/sparse_img_align.h @@ -19,7 +19,7 @@ #include #include -#include +#include namespace vk { class AbstractCamera; diff --git a/GPU_version/svo/include/svo/svoVisionFactor.h b/GPU_version/svo/include/gpu_svo/svoVisionFactor.h similarity index 99% rename from GPU_version/svo/include/svo/svoVisionFactor.h rename to GPU_version/svo/include/gpu_svo/svoVisionFactor.h index cd00816..738bd95 100644 --- a/GPU_version/svo/include/svo/svoVisionFactor.h +++ b/GPU_version/svo/include/gpu_svo/svoVisionFactor.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include namespace svo { diff --git a/GPU_version/svo/src/bundle_adjustment.cpp b/GPU_version/svo/src/bundle_adjustment.cpp index eaba2b0..883116f 100644 --- a/GPU_version/svo/src/bundle_adjustment.cpp +++ b/GPU_version/svo/src/bundle_adjustment.cpp @@ -26,12 +26,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #define SCHUR_TRICK 1 diff --git a/GPU_version/svo/src/cl_class.cpp b/GPU_version/svo/src/cl_class.cpp index d32f140..a26d455 100644 --- a/GPU_version/svo/src/cl_class.cpp +++ b/GPU_version/svo/src/cl_class.cpp @@ -1,7 +1,7 @@ // // Created by root on 4/27/21. // -#include "svo/cl_class.h" +#include "gpu_svo/cl_class.h" opencl::opencl() { std::vector all_platforms; cl::Platform::get(&all_platforms); @@ -12,7 +12,7 @@ opencl::opencl() { //get default device of the default platform std::vector all_devices; for(auto i:all_platforms){ - std::cout << "Find platform: " << i.getInfo() << "\n"; + std::cout << "Find platform number:"<< i.getInfo() << "\n"; i.getDevices(CL_DEVICE_TYPE_GPU, &all_devices); } @@ -30,7 +30,7 @@ opencl::opencl() { context=new cl::Context({ device }); cl::Program::Sources sources; - read_cl fast("../kernel/fast-gray.cl"); + read_cl fast(std::string(KERNEL_DIR)+"/fast-gray.cl"); sources.push_back({ fast.src_str, fast.size }); program=new cl::Program(*context, sources); if(program->build({ device },"-DFAST_THRESH=40") !=0) diff --git a/GPU_version/svo/src/config.cpp b/GPU_version/svo/src/config.cpp index e8475fe..2f09b60 100644 --- a/GPU_version/svo/src/config.cpp +++ b/GPU_version/svo/src/config.cpp @@ -17,7 +17,7 @@ #ifdef SVO_USE_ROS #include #endif -#include +#include namespace svo { diff --git a/GPU_version/svo/src/depth_filter.cpp b/GPU_version/svo/src/depth_filter.cpp index db24408..f6fa977 100644 --- a/GPU_version/svo/src/depth_filter.cpp +++ b/GPU_version/svo/src/depth_filter.cpp @@ -20,14 +20,14 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include namespace svo { diff --git a/GPU_version/svo/src/feature_alignment.cpp b/GPU_version/svo/src/feature_alignment.cpp index faa4027..3605333 100644 --- a/GPU_version/svo/src/feature_alignment.cpp +++ b/GPU_version/svo/src/feature_alignment.cpp @@ -20,7 +20,7 @@ #ifdef __ARM_NEON__ #include #endif -#include +#include namespace svo { namespace feature_alignment { diff --git a/GPU_version/svo/src/feature_detection.cpp b/GPU_version/svo/src/feature_detection.cpp index 8aaac0c..3a98d20 100644 --- a/GPU_version/svo/src/feature_detection.cpp +++ b/GPU_version/svo/src/feature_detection.cpp @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include -#include +#include +#include #include namespace svo { @@ -32,14 +32,6 @@ AbstractDetector::AbstractDetector( grid_n_rows_(ceil(static_cast(img_height)/cell_size_)), grid_occupancy_(grid_n_cols_*grid_n_rows_, false) { - gpu_fast_= new opencl(); - cv::Mat init=cv::Mat::zeros(cv::Size(img_width, img_height),CV_8UC1); - gpu_fast_->write_buf(0,0,init); - cl_int2 corners[img_width*img_height]; - gpu_fast_->write_buf(0,1,img_width*img_height,corners); - int icorner[1]={0}; - gpu_fast_->write_buf(0,2,1,icorner); - gpu_fast_->write_buf(0,3,(1 << 18)); } void AbstractDetector::resetGrid() @@ -67,9 +59,11 @@ FastDetector::FastDetector( const int img_width, const int img_height, const int cell_size, + opencl* gpu_fast_, const int n_pyr_levels) : - AbstractDetector(img_width, img_height, cell_size, n_pyr_levels) -{} + AbstractDetector(img_width, img_height, cell_size, n_pyr_levels),gpu_fast_(gpu_fast_) +{ +} void FastDetector::detect( Frame* frame, @@ -81,26 +75,28 @@ void FastDetector::detect( for(int L=0; Lreload_buf(0,0,img_pyr[L].data); + cv::Mat img=img_pyr.at(L); + gpu_fast_->reload_buf(0,0,img); int icorner[1]={0}; gpu_fast_->reload_buf(0,2,icorner); gpu_fast_->run(0,img_pyr[L].cols,img_pyr[L].rows); - cl_int2* fast_corners; + cl_int2 fast_corners[1000000]; gpu_fast_->read(0,1,fast_corners); int count[1]={0}; gpu_fast_->read(0,2,count); - //vector scores, nm_corners; - //fast::fast_corner_score_10((fast::fast_byte*) img_pyr[L].data, img_pyr[L].cols, fast_corners, 20, scores); - //fast::fast_nonmax_3x3(fast_corners, scores, nm_corners); - for(uint i=0;iimg_pyr[L].cols || fast_corners[i].y>img_pyr[L].rows || fast_corners[i].y<0)continue; + if(fast_corners[i].x<0 || fast_corners[i].x>img_pyr[L].cols || fast_corners[i].y>img_pyr[L].rows || fast_corners[i].y<0) + continue; + const int k = static_cast((fast_corners[i].y*scale)/cell_size_)*grid_n_cols_ + static_cast((fast_corners[i].x*scale)/cell_size_); + if(grid_occupancy_[k]) continue; + const float score = vk::shiTomasiScore(img_pyr[L], fast_corners[i].x, fast_corners[i].y); + if(score > corners.at(k).score) corners.at(k) = Corner(fast_corners[i].x*scale, fast_corners[i].y*scale, score, L, 0.0f); } diff --git a/GPU_version/svo/src/frame.cpp b/GPU_version/svo/src/frame.cpp index 440c32d..632e376 100644 --- a/GPU_version/svo/src/frame.cpp +++ b/GPU_version/svo/src/frame.cpp @@ -15,10 +15,10 @@ // along with this program. If not, see . #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include diff --git a/GPU_version/svo/src/frame_handler_base.cpp b/GPU_version/svo/src/frame_handler_base.cpp index 175ee01..6dcef82 100644 --- a/GPU_version/svo/src/frame_handler_base.cpp +++ b/GPU_version/svo/src/frame_handler_base.cpp @@ -19,12 +19,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include namespace svo { diff --git a/GPU_version/svo/src/frame_handler_mono.cpp b/GPU_version/svo/src/frame_handler_mono.cpp index 799cb8c..1e6a98e 100644 --- a/GPU_version/svo/src/frame_handler_mono.cpp +++ b/GPU_version/svo/src/frame_handler_mono.cpp @@ -14,18 +14,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include #ifdef USE_BUNDLE_ADJUSTMENT -#include +#include #endif namespace svo { @@ -36,6 +36,16 @@ FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam,Sophus::SE3& SE_init) reprojector_(cam_, map_), depth_filter_(NULL) { + gpu_fast_= new opencl(); + gpu_fast_->make_kernel("fast_gray"); + cv::Mat img=cv::Mat(cv::Size(1000, 1000),CV_8UC1); + gpu_fast_->write_buf(0,0,img); + cl_int2 corners_[1000000]; + gpu_fast_->write_buf(0,1,1000000,corners_); + int icorner[1]={0}; + gpu_fast_->write_buf(0,2,1,icorner); + gpu_fast_->write_buf(0,3,(1 << 18)); + klt_homography_init_=new initialization::KltHomographyInit(gpu_fast_); initialize(); imu_integPtr_=std::make_unique(SE_init); } @@ -44,7 +54,7 @@ void FrameHandlerMono::initialize() { feature_detection::DetectorPtr feature_detector( new feature_detection::FastDetector( - cam_->width(), cam_->height(), Config::gridSize(), Config::nPyrLevels())); + cam_->width(), cam_->height(), Config::gridSize(),gpu_fast_, Config::nPyrLevels())); DepthFilter::callback_t depth_filter_cb = boost::bind( &MapPointCandidates::newCandidatePoint, &map_.point_candidates_, _1, _2); depth_filter_ = new DepthFilter(feature_detector, depth_filter_cb); @@ -90,7 +100,7 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() { new_frame_->T_f_w_ = SE3(Matrix3d::Identity(), Vector3d::Zero()); - if(klt_homography_init_.addFirstFrame(new_frame_) == initialization::FAILURE) + if(klt_homography_init_->addFirstFrame(new_frame_) == initialization::FAILURE) return RESULT_NO_KEYFRAME; new_frame_->setKeyframe(); map_.addKeyframe(new_frame_); @@ -101,7 +111,7 @@ FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() { - initialization::InitResult res = klt_homography_init_.addSecondFrame(new_frame_); + initialization::InitResult res = klt_homography_init_->addSecondFrame(new_frame_); if(res == initialization::FAILURE) return RESULT_FAILURE; else if(res == initialization::NO_KEYFRAME) @@ -120,7 +130,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() // add frame to map map_.addKeyframe(new_frame_); stage_ = STAGE_DEFAULT_FRAME; - klt_homography_init_.reset(); + klt_homography_init_->reset(); SVO_INFO_STREAM("Init: Selected second frame, triangulated initial map."); return RESULT_IS_KEYFRAME; } diff --git a/GPU_version/svo/src/imu_integration.cpp b/GPU_version/svo/src/imu_integration.cpp index c2a720f..2238f7c 100644 --- a/GPU_version/svo/src/imu_integration.cpp +++ b/GPU_version/svo/src/imu_integration.cpp @@ -2,16 +2,16 @@ // Created by gfuse on 4/9/21. // //#define NDEBUG -#include "svo/imu_integration.h" +#include "gpu_svo/imu_integration.h" #include #include -#include "svo/feature.h" -#include "svo/point.h" -#include "svo/svoVisionFactor.h" +#include "gpu_svo/feature.h" +#include "gpu_svo/point.h" +#include "gpu_svo/svoVisionFactor.h" #include #include #include -#include +#include Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ graphPtr=std::make_shared(); diff --git a/GPU_version/svo/src/initialization.cpp b/GPU_version/svo/src/initialization.cpp index 571a0bc..ce04d24 100644 --- a/GPU_version/svo/src/initialization.cpp +++ b/GPU_version/svo/src/initialization.cpp @@ -14,12 +14,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include @@ -29,7 +29,7 @@ namespace initialization { InitResult KltHomographyInit::addFirstFrame(FramePtr frame_ref) { reset(); - detectFeatures(frame_ref, px_ref_, f_ref_); + detectFeatures(frame_ref, px_ref_, f_ref_,gpu_fast_); if(px_ref_.size() < 100) { SVO_WARN_STREAM_THROTTLE(2.0, "First image has less than 100 features. Retry in more textured environment."); @@ -107,11 +107,12 @@ void KltHomographyInit::reset() void detectFeatures( FramePtr frame, vector& px_vec, - vector& f_vec) + vector& f_vec, + opencl* gpu_fast) { Features new_features; feature_detection::FastDetector detector( - frame->img().cols, frame->img().rows, Config::gridSize(), Config::nPyrLevels()); + frame->img().cols, frame->img().rows, Config::gridSize(), gpu_fast,Config::nPyrLevels()); detector.detect(frame.get(), frame->img_pyr_, Config::triangMinCornerScore(), new_features); // now for all maximum corners, initialize a new seed diff --git a/GPU_version/svo/src/map.cpp b/GPU_version/svo/src/map.cpp index 2ecad1c..90c7416 100644 --- a/GPU_version/svo/src/map.cpp +++ b/GPU_version/svo/src/map.cpp @@ -15,10 +15,10 @@ // along with this program. If not, see . #include -#include -#include -#include -#include +#include +#include +#include +#include #include namespace svo { diff --git a/GPU_version/svo/src/matcher.cpp b/GPU_version/svo/src/matcher.cpp index 38a89fb..9f44701 100644 --- a/GPU_version/svo/src/matcher.cpp +++ b/GPU_version/svo/src/matcher.cpp @@ -19,12 +19,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include namespace svo { diff --git a/GPU_version/svo/src/point.cpp b/GPU_version/svo/src/point.cpp index 2e45e06..533bed4 100644 --- a/GPU_version/svo/src/point.cpp +++ b/GPU_version/svo/src/point.cpp @@ -16,9 +16,9 @@ #include #include -#include -#include -#include +#include +#include +#include namespace svo { diff --git a/GPU_version/svo/src/pose_optimizer.cpp b/GPU_version/svo/src/pose_optimizer.cpp index 1c491b0..8af359f 100644 --- a/GPU_version/svo/src/pose_optimizer.cpp +++ b/GPU_version/svo/src/pose_optimizer.cpp @@ -15,10 +15,10 @@ // along with this program. If not, see . #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include diff --git a/GPU_version/svo/src/reprojector.cpp b/GPU_version/svo/src/reprojector.cpp index 81a7835..888d3d2 100644 --- a/GPU_version/svo/src/reprojector.cpp +++ b/GPU_version/svo/src/reprojector.cpp @@ -16,12 +16,12 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include diff --git a/GPU_version/svo/src/sparse_img_align.cpp b/GPU_version/svo/src/sparse_img_align.cpp index ce1570b..21432c6 100644 --- a/GPU_version/svo/src/sparse_img_align.cpp +++ b/GPU_version/svo/src/sparse_img_align.cpp @@ -15,11 +15,11 @@ // along with this program. If not, see . #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include diff --git a/GPU_version/vio/.idea/.gitignore b/GPU_version/vio/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/GPU_version/vio/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/GPU_version/vio/.idea/misc.xml b/GPU_version/vio/.idea/misc.xml new file mode 100644 index 0000000..79b3c94 --- /dev/null +++ b/GPU_version/vio/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/GPU_version/vio/.idea/modules.xml b/GPU_version/vio/.idea/modules.xml new file mode 100644 index 0000000..eb3cacf --- /dev/null +++ b/GPU_version/vio/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/GPU_version/vio/.idea/vcs.xml b/GPU_version/vio/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/GPU_version/vio/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/GPU_version/vio/CMakeLists.txt b/GPU_version/vio/CMakeLists.txt new file mode 100644 index 0000000..a9872a4 --- /dev/null +++ b/GPU_version/vio/CMakeLists.txt @@ -0,0 +1,92 @@ +SET(PROJECT_NAME vio_gpu) +PROJECT(${PROJECT_NAME}) +CMAKE_MINIMUM_REQUIRED (VERSION 2.8.3) +SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo +SET(CMAKE_VERBOSE_MAKEFILE OFF) +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") + +# Set build flags. Set IS_ARM on odroid board as environment variable +SET(CMAKE_CXX_FLAGS "-Wall -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") +IF(DEFINED ENV{ARM_ARCHITECTURE}) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") +ELSE() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse -msse2 -msse3 -mssse3") +ENDIF() +IF(CMAKE_COMPILER_IS_GNUCC) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +ELSE() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +ENDIF() +SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -fsee -fomit-frame-pointer -fno-signed-zeros -fno-math-errno -funroll-loops") + +# Add catkin and required ROS packages +FIND_PACKAGE(catkin REQUIRED COMPONENTS + geometry_msgs + roscpp + cmake_modules + nav_msgs + std_msgs + visualization_msgs + sensor_msgs + image_transport + cv_bridge + tf + gpu_svo + vikit_common + vikit_ros +) + +# Add plain cmake packages +FIND_PACKAGE(OpenCV REQUIRED) +FIND_PACKAGE(Eigen REQUIRED) +FIND_PACKAGE(Sophus REQUIRED) +FIND_PACKAGE(Boost REQUIRED COMPONENTS thread) +FIND_PACKAGE(GTSAM REQUIRED) +FIND_PACKAGE(OpenCL REQUIRED) + +# notify catkin to look at the previously found msg files +add_message_files( + FILES + Info.msg +) + +# build the header files from the msg files, and notify catkin about the dependencies +generate_messages( + DEPENDENCIES + geometry_msgs + sensor_msgs +) +# Describe catkin Project +catkin_package( + DEPENDS Eigen OpenCV Sophus Boost + CATKIN_DEPENDS roscpp nav_msgs std_msgs visualization_msgs sensor_msgs image_transport cv_bridge tf gpu_svo vikit_common vikit_ros geometry_msgs + INCLUDE_DIRS include + LIBRARIES ${PROJECT_NAME}_visualizer +) + +# Include dirs +INCLUDE_DIRECTORIES( + include + ${Eigen_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${Sophus_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${catkin_INCLUDE_DIRS} +) + +# Set link libraries +LIST(APPEND LINK_LIBS + ${OpenCV_LIBS} + ${Sophus_LIBRARIES} + ${Boost_LIBRARIES} + ${catkin_LIBRARIES} + ${OpenCL_LIBRARIES} +) + +# Create visualizer library +ADD_LIBRARY(${PROJECT_NAME}_visualizer src/visualizer.cpp) +TARGET_LINK_LIBRARIES(${PROJECT_NAME}_visualizer ${LINK_LIBS} gtsam) + +# Create Executables +ADD_EXECUTABLE(${PROJECT_NAME} src/vo_node.cpp) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${PROJECT_NAME}_visualizer ${LINK_LIBS}) diff --git a/GPU_version/vio/include/vio_gpu/visualizer.h b/GPU_version/vio/include/vio_gpu/visualizer.h new file mode 100644 index 0000000..0ff8834 --- /dev/null +++ b/GPU_version/vio/include/vio_gpu/visualizer.h @@ -0,0 +1,73 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef SVO_VISUALIZER_H_ +#define SVO_VISUALIZER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +class Frame; +class Point; +class Map; +class FrameHandlerMono; + +typedef boost::shared_ptr FramePtr; + +/// This class bundles all functions to publish visualisation messages. +class Visualizer +{ +public: + ros::NodeHandle pnh_; + size_t trace_id_; + ros::Publisher pub_frames_; + ros::Publisher pub_points_; + ros::Publisher pub_pose_; + ros::Publisher pub_info_; + tf::TransformBroadcaster br_; + SE3 T_world_from_vision_; + + Visualizer(); + + ~Visualizer() {}; + + void publishMinimal( + const cv::Mat& img, + const FramePtr& frame, + const FrameHandlerMono& slam, + const double timestamp); + + void visualizeMarkers( + const FramePtr& frame, + const set& core_kfs, + const Map& map); + + void removeDeletedPts(const Map& map); + +}; + +} // end namespace svo + +#endif /* SVO_VISUALIZER_H_ */ diff --git a/GPU_version/vio/launch/Px30.launch b/GPU_version/vio/launch/Px30.launch new file mode 100644 index 0000000..f57f8c0 --- /dev/null +++ b/GPU_version/vio/launch/Px30.launch @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/GPU_version/vio/launch/live.launch b/GPU_version/vio/launch/live.launch new file mode 100644 index 0000000..7cd0ad8 --- /dev/null +++ b/GPU_version/vio/launch/live.launch @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/GPU_version/vio/launch/test.launch b/GPU_version/vio/launch/test.launch new file mode 100644 index 0000000..4bcd965 --- /dev/null +++ b/GPU_version/vio/launch/test.launch @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/GPU_version/vio/launch/unity.launch b/GPU_version/vio/launch/unity.launch new file mode 100644 index 0000000..ea34997 --- /dev/null +++ b/GPU_version/vio/launch/unity.launch @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GPU_version/vio/msg/Info.msg b/GPU_version/vio/msg/Info.msg new file mode 100644 index 0000000..b962e1b --- /dev/null +++ b/GPU_version/vio/msg/Info.msg @@ -0,0 +1,6 @@ +Header header +float32 processing_time +int32[] keyframes +int32 num_matches +int32 tracking_quality +int32 stage \ No newline at end of file diff --git a/GPU_version/vio/package.xml b/GPU_version/vio/package.xml new file mode 100644 index 0000000..7f8fbc5 --- /dev/null +++ b/GPU_version/vio/package.xml @@ -0,0 +1,43 @@ + + + vio_gpu + 0.1.0 + + Monocular Visual Odometry - ROS Nodes + + Majid Geravand + Majid Geravand + GPLv3 + + + catkin + + + roscpp + cmake_modules + nav_msgs + std_msgs + visualization_msgs + sensor_msgs + image_transport + cv_bridge + tf + gpu_svo + vikit_common + vikit_ros + geometry_msgs + + + roscpp + nav_msgs + std_msgs + visualization_msgs + sensor_msgs + image_transport + cv_bridge + tf + vikit_common + vikit_ros + geometry_msgs + gpu_svo + \ No newline at end of file diff --git a/GPU_version/vio/param/camera_atan.yaml b/GPU_version/vio/param/camera_atan.yaml new file mode 100644 index 0000000..e3c625c --- /dev/null +++ b/GPU_version/vio/param/camera_atan.yaml @@ -0,0 +1,8 @@ +cam_model: ATAN +cam_width: 752 +cam_height: 480 +cam_fx: 0.509326 +cam_fy: 0.796651 +cam_cx: 0.45905 +cam_cy: 0.510056 +cam_d0: 0.9320 \ No newline at end of file diff --git a/GPU_version/vio/param/camera_pinhole.yaml b/GPU_version/vio/param/camera_pinhole.yaml new file mode 100644 index 0000000..506a856 --- /dev/null +++ b/GPU_version/vio/param/camera_pinhole.yaml @@ -0,0 +1,11 @@ +cam_model: Pinhole +cam_width: 640 +cam_height: 480 +cam_fx: 789.860721 +cam_fy: 790.097440 +cam_cx: 305.323524 +cam_cy: 260.464072 +cam_d0: 0.027470 +cam_d1: -0.051518 +cam_d2: 0.004375 +cam_d3: -0.004028 \ No newline at end of file diff --git a/GPU_version/vio/param/px30.yaml b/GPU_version/vio/param/px30.yaml new file mode 100644 index 0000000..10fa932 --- /dev/null +++ b/GPU_version/vio/param/px30.yaml @@ -0,0 +1,8 @@ +cam_model: ATAN +cam_width: 640 +cam_height: 480 +cam_fx: 0.463632 +cam_fy: 0.823661 +cam_cx: 0.497465 +cam_cy: 0.498443 +cam_d0: 1.01687 \ No newline at end of file diff --git a/GPU_version/vio/param/unity.yaml b/GPU_version/vio/param/unity.yaml new file mode 100644 index 0000000..023f378 --- /dev/null +++ b/GPU_version/vio/param/unity.yaml @@ -0,0 +1,8 @@ +cam_model: ATAN +cam_width: 1024 +cam_height: 720 +cam_fx: 1.98248 +cam_fy: 2.68212 +cam_cx: 0.502524 +cam_cy: 0.497744 +cam_d0: -0.000499999 \ No newline at end of file diff --git a/GPU_version/vio/param/vo_accurate.yaml b/GPU_version/vio/param/vo_accurate.yaml new file mode 100644 index 0000000..8446875 --- /dev/null +++ b/GPU_version/vio/param/vo_accurate.yaml @@ -0,0 +1,4 @@ +grid_size: 20 +max_n_kfs: 50 +loba_num_iter: 10 +max_fts: 200 \ No newline at end of file diff --git a/GPU_version/vio/param/vo_fast.yaml b/GPU_version/vio/param/vo_fast.yaml new file mode 100644 index 0000000..e33b18a --- /dev/null +++ b/GPU_version/vio/param/vo_fast.yaml @@ -0,0 +1,13 @@ +svo: + grid_size: 30 #Feature grid size of a cell in [px]. + max_n_kfs: 10 #Limit the number of keyframes in the map. This makes nslam essentially. a Visual Odometry. Set to 0 if unlimited number of keyframes are allowed. Minimum number of keyframes is 3. + loba_num_iter: 0 #Number of iterations in the local bundle adjustment. + quality_min_fts: 10 #If the number of tracked features drops below this threshold. Tracking quality is bad. + quality_max_drop_fts: 60 #If within one frame, this amount of features are dropped. Tracking quality is bad. + ACC_noise: 0.00001 #acc white noise in continuous + GYO_noise: 0.00001 #gyro white noise in continuous + IUC: 0.1 #integration uncertainty continuous + ABC: 0.1 #acc bias in continuous + GBC: 0.1 #gyro bias in continuous + EBP: 0.1 #error in the bias used for preintegration + NRP: 0.0000001 #noise used for projection in preintegration diff --git a/GPU_version/vio/rqt.perspective b/GPU_version/vio/rqt.perspective new file mode 100644 index 0000000..66dd7ef --- /dev/null +++ b/GPU_version/vio/rqt.perspective @@ -0,0 +1,293 @@ +{ + "keys": {}, + "groups": { + "pluginmanager": { + "keys": { + "running-plugins": { + "type": "repr", + "repr": "{u'rqt_rviz/RViz': [1], u'rqt_reconfigure/Param': [1], u'rqt_image_view/ImageView': [1], u'svo_rqt/Svo': [1]}" + } + }, + "groups": { + "plugin__rqt_rviz__RViz__1": { + "keys": {}, + "groups": { + "dock_widget__": { + "keys": { + "dockable": { + "type": "repr", + "repr": "True" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + } + } + }, + "plugin__rqt_robot_steering__RobotSteering__1": { + "keys": {}, + "groups": { + "dock_widget__RobotSteeringUi": { + "keys": { + "dockable": { + "type": "repr", + "repr": "u'true'" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + }, + "plugin": { + "keys": { + "topic": { + "type": "repr", + "repr": "u'/cmd_vel'" + }, + "vx_min": { + "type": "repr", + "repr": "u'-1'" + }, + "vw_min": { + "type": "repr", + "repr": "u'-3'" + }, + "vw_max": { + "type": "repr", + "repr": "u'3'" + }, + "vx_max": { + "type": "repr", + "repr": "u'1'" + } + }, + "groups": {} + } + } + }, + "plugin__rqt_reconfigure__Param__1": { + "keys": {}, + "groups": { + "dock_widget___plugincontainer_top_widget": { + "keys": { + "dockable": { + "type": "repr", + "repr": "True" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + }, + "plugin": { + "keys": { + "splitter": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff0000000000000002000000c00000006401000000060100000001')", + "pretty-print": " d " + }, + "_splitter": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff00000000000000020000013e0000006401000000090100000002')", + "pretty-print": " > d " + } + }, + "groups": {} + } + } + }, + "plugin__rqt_image_view__ImageView__1": { + "keys": {}, + "groups": { + "dock_widget__ImageViewWidget": { + "keys": { + "dockable": { + "type": "repr", + "repr": "True" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + }, + "plugin": { + "keys": { + "dynamic_range": { + "type": "repr", + "repr": "False" + }, + "max_range": { + "type": "repr", + "repr": "10.0" + }, + "topic": { + "type": "repr", + "repr": "u'/svo/image'" + }, + "zoom1": { + "type": "repr", + "repr": "False" + } + }, + "groups": {} + } + } + }, + "plugin__svo_rqt__Svo__1": { + "keys": {}, + "groups": { + "dock_widget__SvoWidget": { + "keys": { + "dockable": { + "type": "repr", + "repr": "True" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + }, + "dock_widget__SvoUi": { + "keys": { + "dockable": { + "type": "repr", + "repr": "u'true'" + }, + "parent": { + "type": "repr", + "repr": "None" + } + }, + "groups": {} + } + } + }, + "plugin__rqt_shell__Shell__1": { + "keys": {}, + "groups": { + "plugin": { + "keys": { + "shell_type": { + "type": "repr", + "repr": "u'0'" + } + }, + "groups": {} + } + } + }, + "plugin__rqt_console__Console__1": { + "keys": {}, + "groups": { + "plugin": { + "keys": { + "show_highlighted_only": { + "type": "repr", + "repr": "u'false'" + }, + "message_limit": { + "type": "repr", + "repr": "u'20000'" + }, + "exclude_filters": { + "type": "repr", + "repr": "u'severity'" + }, + "table_splitter": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff00000000000000020000004e000000ed01000000090100000002')", + "pretty-print": " N " + }, + "highlight_filters": { + "type": "repr", + "repr": "u'message'" + }, + "paused": { + "type": "repr", + "repr": "u'false'" + }, + "settings_exist": { + "type": "repr", + "repr": "u'true'" + }, + "filter_splitter": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff0000000000000002000000720000007201000000090100000002')", + "pretty-print": " r r " + } + }, + "groups": { + "exclude_filter_0": { + "keys": { + "enabled": { + "type": "repr", + "repr": "u'true'" + }, + "itemlist": { + "type": "repr", + "repr": "u''" + } + }, + "groups": {} + }, + "highlight_filter_0": { + "keys": { + "regex": { + "type": "repr", + "repr": "u'false'" + }, + "text": { + "type": "repr", + "repr": "u''" + }, + "enabled": { + "type": "repr", + "repr": "u'true'" + } + }, + "groups": {} + } + } + } + } + } + } + }, + "mainwindow": { + "keys": { + "geometry": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('01d9d0cb00010000000007a9fffffffc00001187000005a7000007b1000000180000117f0000059f000000000000')", + "pretty-print": " " + }, + "state": { + "type": "repr(QByteArray.hex)", + "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff00000000fd0000000100000003000009cf00000559fc0100000005fb0000002c00730076006f005f007200710074005f005f00530076006f005f005f0031005f005f00530076006f005500690100000000000003890000000000000000fb0000006a007200710074005f0072006f0062006f0074005f007300740065006500720069006e0067005f005f0052006f0062006f0074005300740065006500720069006e0067005f005f0031005f005f0052006f0062006f0074005300740065006500720069006e00670055006901000000000000020b0000000000000000fc00000000000003530000022e00fffffffc0200000004fb0000003400730076006f005f007200710074005f005f00530076006f005f005f0031005f005f00530076006f0057006900640067006500740100000019000000a30000009900fffffffb0000004c007200710074005f0063006f006e0073006f006c0065005f005f0043006f006e0073006f006c0065005f005f0031005f005f0043006f006e0073006f006c006500570069006400670065007401000000c3000003b50000000000000000fb0000005a007200710074005f0069006d006100670065005f0076006900650077005f005f0049006d0061006700650056006900650077005f005f0031005f005f0049006d006100670065005600690065007700570069006400670065007401000000c2000002700000005100fffffffb0000006c007200710074005f007200650063006f006e006600690067007500720065005f005f0050006100720061006d005f005f0031005f005f005f0070006c007500670069006e0063006f006e007400610069006e00650072005f0074006f0070005f00770069006400670065007401000003380000023a0000010f00fffffffb00000026007200710074005f007200760069007a005f005f005200560069007a005f005f0031005f005f010000035900000676000000a700fffffffb00000040007200710074005f007300680065006c006c005f005f005300680065006c006c005f005f0031005f005f0058005400650072006d005700690064006700650074010000091c000000b30000000000000000000009cf0000000000000004000000040000000800000008fc00000001000000030000000100000036004d0069006e0069006d0069007a006500640044006f0063006b00570069006400670065007400730054006f006f006c0062006100720000000000ffffffff0000000000000000')", + "pretty-print": " ,svo_rqt__Svo__1__SvoUi jrqt_robot_steering__RobotSteering__1__RobotSteeringUi S . p Q 8 : Y v " + } + }, + "groups": { + "toolbar_areas": { + "keys": { + "MinimizedDockWidgetsToolbar": { + "type": "repr", + "repr": "8" + } + }, + "groups": {} + } + } + } + } +} \ No newline at end of file diff --git a/GPU_version/vio/rviz_config.rviz b/GPU_version/vio/rviz_config.rviz new file mode 100644 index 0000000..95d7c0e --- /dev/null +++ b/GPU_version/vio/rviz_config.rviz @@ -0,0 +1,153 @@ +Panels: + - Class: rviz/Displays + Help Height: 108 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + - /Status1 + - /TF1 + - /Marker1 + - /Marker2 + - /Marker2/Namespaces1 + - /Image1 + Splitter Ratio: 0.5 + Tree Height: 680 + - Class: rviz/Selection + Name: Selection + - Class: rviz/Tool Properties + Expanded: + - /2D Pose Estimate1 + - /2D Nav Goal1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.588679 + - Class: rviz/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: Image +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.03 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Class: rviz/TF + Enabled: false + Frame Timeout: 15 + Frames: + All Enabled: true + Marker Scale: 1 + Name: TF + Show Arrows: true + Show Axes: true + Show Names: true + Tree: + {} + Update Interval: 0 + Value: false + - Class: rviz/Marker + Enabled: true + Marker Topic: /svo/keyframes + Name: Marker + Namespaces: + cams: true + kfs: true + Queue Size: 100 + Value: true + - Class: rviz/Marker + Enabled: true + Marker Topic: /svo/points + Name: Marker + Namespaces: + pts: true + trajectory: true + Queue Size: 100 + Value: true + - Class: rviz/Image + Enabled: true + Image Topic: /svo/image + Max Value: 1 + Median window: 5 + Min Value: 0 + Name: Image + Normalize Range: true + Queue Size: 2 + Transport Hint: raw + Value: true + Enabled: true + Global Options: + Background Color: 255; 255; 255 + Fixed Frame: /world + Name: root + Tools: + - Class: rviz/Interact + Hide Inactive Objects: true + - Class: rviz/MoveCamera + - Class: rviz/Select + - Class: rviz/FocusCamera + - Class: rviz/Measure + - Class: rviz/SetInitialPose + Topic: /initialpose + - Class: rviz/SetGoal + Topic: /move_base_simple/goal + - Class: rviz/PublishPoint + Single click: true + Topic: /clicked_point + Value: true + Views: + Current: + Class: rviz/Orbit + Distance: 5.48911 + Focal Point: + X: 0.777511 + Y: 0.689927 + Z: -0.445833 + Name: Current View + Near Clip Distance: 0.01 + Pitch: 0.125204 + Target Frame: + Value: Orbit (rviz) + Yaw: 4.45215 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 1416 + Hide Left Dock: false + Hide Right Dock: true + Image: + collapsed: false + QMainWindow State: 000000ff00000000fd0000000400000000000002cc00000542fc0200000009fb0000001200530065006c0065006300740069006f006e00000000280000009b0000006400fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000002800000355000000dd00fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d0061006700650100000383000001e70000001600ffffff000000010000010f000003dafc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a005600690065007700730000000028000003da000000b000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000003ce0000003efc0100000002fb0000000800540069006d00650000000000000003ce000002f600fffffffb0000000800540069006d00650100000000000004500000000000000000000006fd0000054200000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: true + Width: 2511 + X: 1962 + Y: 24 diff --git a/GPU_version/vio/src/visualizer.cpp b/GPU_version/vio/src/visualizer.cpp new file mode 100644 index 0000000..d2327f4 --- /dev/null +++ b/GPU_version/vio/src/visualizer.cpp @@ -0,0 +1,127 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + +Visualizer:: +Visualizer() : + pnh_("~"), + trace_id_(0), + T_world_from_vision_(Matrix3d::Identity(), Vector3d::Zero()) +{ + // Init ROS Marker Publishers + pub_frames_ = pnh_.advertise("keyframes", 10); + pub_points_ = pnh_.advertise("points", 1000); + pub_pose_ = pnh_.advertise("pose",10); + pub_info_ = pnh_.advertise("info", 10); +} + +void Visualizer::publishMinimal( + const cv::Mat& img, + const FramePtr& frame, + const FrameHandlerMono& slam, + const double timestamp) +{ + ++trace_id_; + std_msgs::Header header_msg; + header_msg.frame_id = "/cam"; + header_msg.seq = trace_id_; + header_msg.stamp = ros::Time(timestamp); + + // publish info msg. + if(pub_info_.getNumSubscribers() > 0) + { + vio_gpu::Info msg_info; + msg_info.header = header_msg; + msg_info.processing_time = slam.lastProcessingTime(); + msg_info.keyframes.reserve(slam.map().keyframes_.size()); + for(list::const_iterator it=slam.map().keyframes_.begin(); it!=slam.map().keyframes_.end(); ++it) + msg_info.keyframes.push_back((*it)->id_); + msg_info.stage = static_cast(slam.stage()); + msg_info.tracking_quality = static_cast(slam.trackingQuality()); + if(frame != NULL) + msg_info.num_matches = slam.lastNumObservations(); + else + msg_info.num_matches = 0; + pub_info_.publish(msg_info); + } + if(pub_pose_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) + { + Quaterniond q; + Vector3d p; + Matrix Cov; + // publish cam in world frame (Estimated odometry in the worls frame) + SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse());// do not confused with inverse. the T_f_w_ is the from camera to initial position with reference of camera + q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); + p = T_world_from_cam.translation(); + Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj(); + geometry_msgs::PoseWithCovarianceStampedPtr msg_pose(new geometry_msgs::PoseWithCovarianceStamped); + msg_pose->header = header_msg; + msg_pose->pose.pose.position.x = p[0]; + msg_pose->pose.pose.position.y = p[1]; + msg_pose->pose.pose.position.z = p[2]; + msg_pose->pose.pose.orientation.x = q.x(); + msg_pose->pose.pose.orientation.y = q.y(); + msg_pose->pose.pose.orientation.z = q.z(); + msg_pose->pose.pose.orientation.w = q.w(); + for(size_t i=0; i<36; ++i) + msg_pose->pose.covariance[i] = Cov(i%6, i/6); + pub_pose_.publish(msg_pose); + } +} + +void Visualizer::visualizeMarkers( + const FramePtr& frame, + const set& core_kfs, + const Map& map) +{ + if(frame == NULL) + return; + + vk::output_helper::publishTfTransform( + frame->T_f_w_*T_world_from_vision_.inverse(), + ros::Time(frame->timestamp_), "cam_pos", "world", br_); + + if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) + { + vk::output_helper::publishPointMarker( + pub_points_, T_world_from_vision_*frame->pos(), "trajectory", + ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5)); + removeDeletedPts(map); + } +} + +void Visualizer::removeDeletedPts(const Map& map) +{ + if(pub_points_.getNumSubscribers() > 0) + { + for(list::const_iterator it=map.trash_points_.begin(); it!=map.trash_points_.end(); ++it) + vk::output_helper::publishPointMarker(pub_points_, Vector3d(), "pts", ros::Time::now(), (*it)->id_, 2, 0.006, Vector3d()); + } +} + +} // end namespace gpu_svo diff --git a/GPU_version/vio/src/vo_node.cpp b/GPU_version/vio/src/vo_node.cpp new file mode 100644 index 0000000..c11c6a0 --- /dev/null +++ b/GPU_version/vio/src/vo_node.cpp @@ -0,0 +1,148 @@ +// This file is part of SVO - Semi-direct Visual Odometry. +// +// Copyright (C) 2014 Christian Forster +// (Robotics and Perception Group, University of Zurich, Switzerland). +// +// SVO is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or any later version. +// +// SVO is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace svo { + +/// SVO Interface +class VoNode +{ +public: + svo::FrameHandlerMono* vo_; + svo::Visualizer visualizer_; + bool publish_markers_; //!< publish only the minimal amount of info (choice for embedded devices) + vk::AbstractCamera* cam_; + FILE* logtime; + bool quit_; + boost::thread* imu_th; + VoNode(); + ~VoNode(); + void imgCb(const sensor_msgs::ImageConstPtr& msg); + void imuCb(const sensor_msgs::ImuPtr& imu); + void imu(); +private: + double* imu_; +}; + +VoNode::VoNode() : + vo_(NULL), + publish_markers_(vk::getParam("vio/publish_markers", true)), + cam_(NULL), + quit_(false) +{ + // Create Camera + imu_=(double *)calloc(static_cast(6), sizeof(double)); + if(!vk::camera_loader::loadFromRosNs("vio", cam_)) + throw std::runtime_error("Camera model not correctly specified."); + // Get initial position and orientation + visualizer_.T_world_from_vision_ = Sophus::SE3( + vk::rpy2dcm(Vector3d(vk::getParam("vio/init_rx", 0.0), + vk::getParam("vio/init_ry", 0.0), + vk::getParam("vio/init_rz", 0.0))), + Eigen::Vector3d(vk::getParam("vio/init_tx", 0.0), + vk::getParam("vio/init_ty", 0.0), + vk::getParam("vio/init_tz", 0.0))); + // Init VO and start + vo_ = new svo::FrameHandlerMono(cam_,visualizer_.T_world_from_vision_); + vo_->start(); + imu_th=new boost::thread(&VoNode::imu,this); + logtime = fopen((std::string(getenv("HOME"))+"/time.txt").c_str(), "w+"); + +} + +VoNode::~VoNode() +{ + quit_=true; + fclose(logtime); + imu_th->join(); + delete imu_th; + delete logtime; + delete vo_; + delete cam_; +} + +void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) +{ + try { + auto start=std::chrono::steady_clock::now(); + cv::Mat img=cv_bridge::toCvShare(msg, "mono8")->image; + vo_->addImage(img, msg->header.stamp.toSec()); + visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, msg->header.stamp.toSec()); + if(publish_markers_ && vo_->stage() != FrameHandlerBase::STAGE_PAUSED) + visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); + if(vo_->stage() == FrameHandlerMono::STAGE_PAUSED) + usleep(100000); + fprintf(logtime, "%s\n",std::to_string(std::chrono::duration(std::chrono::steady_clock::now()-start).count()).c_str()); + + } catch (cv_bridge::Exception& e) { + ROS_ERROR("cv_bridge exception: %s", e.what()); + } +} +void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { + double imu_in[6]; + imu_in[0] = 0.1*imu_[0]+0.9*imu->linear_acceleration.x; + imu_in[1] = 0.1*imu_[1]+0.9*imu->linear_acceleration.y; + imu_in[2] = 0.1*imu_[2]+0.9*imu->linear_acceleration.z; + imu_in[3] = 0.1*imu_[3]+0.9*imu->angular_velocity.x; + imu_in[4] = 0.1*imu_[4]+0.9*imu->angular_velocity.y; + imu_in[5] = 0.1*imu_[5]+0.9*imu->angular_velocity.z; + memcpy(imu_, imu_in, static_cast(6*sizeof(double))); + vo_->imu_integPtr_->update(imu_in); +} +void VoNode::imu(){ + ros::NodeHandle nh; + // subscribe to cam msgs + image_transport::ImageTransport it(nh); + image_transport::Subscriber it_sub = it.subscribe(vk::getParam("vio/cam_topic", "camera/image_raw"), 1, &svo::VoNode::imgCb, this); + // start processing callbacks + while(ros::ok() && !quit_) + { + ros::spinOnce(); + } + +} +} // namespace svo + +int main(int argc, char **argv) +{ + ros::init(argc, argv, "vio"); + svo::VoNode vo_node; + ros::NodeHandle nh; + ros::Subscriber imu_sub=nh.subscribe(vk::getParam("vio/imu_topic", "imu/raw"),1,&svo::VoNode::imuCb, &vo_node); + // start processing callbacks + while(ros::ok() && !vo_node.quit_) + { + ros::spinOnce(); + usleep(1000); + // TODO check when last image was processed. when too long ago. publish warning that no msgs are received! + } + printf("SVO terminated.\n"); + return 0; +} From 2d0f81ebe05b44da30c7ed3be617ef7641513ff3 Mon Sep 17 00:00:00 2001 From: gfuse Date: Sat, 8 May 2021 17:26:27 +0200 Subject: [PATCH 190/215] correct frame --- .idea/.gitignore | 8 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/rpg_svo.iml | 2 + .idea/vcs.xml | 6 + CPU_version/svo/doc/notation.ipe | 312 ++++++++++++++++++++++++ CPU_version/svo/doc/notation.pdf | Bin 0 -> 50379 bytes CPU_version/svo/doc/notation.png | Bin 0 -> 27376 bytes CPU_version/svo/src/imu_integration.cpp | 6 +- GPU_version/svo/.idea/.name | 1 + GPU_version/svo/.idea/svo.iml | 2 + GPU_version/svo/.idea/vcs.xml | 1 + GPU_version/svo/src/imu_integration.cpp | 15 +- GPU_version/vio/.idea/.name | 1 + GPU_version/vio/.idea/svo_ros.iml | 2 + GPU_version/vio/.idea/vcs.xml | 1 + 16 files changed, 360 insertions(+), 11 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/rpg_svo.iml create mode 100644 .idea/vcs.xml create mode 100644 CPU_version/svo/doc/notation.ipe create mode 100644 CPU_version/svo/doc/notation.pdf create mode 100644 CPU_version/svo/doc/notation.png create mode 100644 GPU_version/svo/.idea/.name create mode 100644 GPU_version/svo/.idea/svo.iml create mode 100644 GPU_version/vio/.idea/.name create mode 100644 GPU_version/vio/.idea/svo_ros.iml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..339cee9 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..1ef27e7 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/rpg_svo.iml b/.idea/rpg_svo.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/rpg_svo.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CPU_version/svo/doc/notation.ipe b/CPU_version/svo/doc/notation.ipe new file mode 100644 index 0000000..f8c1efe --- /dev/null +++ b/CPU_version/svo/doc/notation.ipe @@ -0,0 +1,312 @@ + + + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + +0.6 0 0 0.6 0 0 e + + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + +0.4 0 0 0.4 0 0 e + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + + + +-0.43 -0.57 m +0.57 0.43 l +0.43 0.57 l +-0.57 -0.43 l +h + + +-0.43 0.57 m +0.57 -0.43 l +0.43 -0.57 l +-0.57 0.43 l +h + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +-1 0.333 m +0 0 l +-1 -0.333 l + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$_w\mathtt{p}$ +$\overrightarrow{\mathcal{F}}_w$ + +64 576 m +96 576 l + + +64 576 m +64 608 l + + +64 576 m +80 592 l + + +144 688 m +176 688 l + + +144 688 m +144 720 l + + +144 688 m +160 704 l + + +285.262 759.615 m +162.017 735.456 +129.232 628.801 s + + +$\mathtt{T}_{f,w}$ + +128.441 626.745 m +320.625 647.224 l + + +331.681 587.399 m +331.681 587.399 l + +$x$ +$z$ +$y$ + +256 736 m +224 704 l +320 704 l +352 736 l +h + + +285.262 759.265 m +322.176 651.119 l + +$\mathtt{px}$ + +285.612 758.915 m +315.723 669.632 l + +$\mathtt{f}$ +$\overrightarrow{\mathcal{F}}_f$ + +255.668 719.918 m +274.728 719.957 l + + +256.107 720.028 m +246.655 710.527 l + +$v$ +$u$ + +$\mathbf{p}$ +$_f\mathtt{p}$ + + diff --git a/CPU_version/svo/doc/notation.pdf b/CPU_version/svo/doc/notation.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3bc3fcd1e26432ecb0bbd75ccac1399691cf3da1 GIT binary patch literal 50379 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 literal 0 HcmV?d00001 diff --git a/CPU_version/svo/doc/notation.png b/CPU_version/svo/doc/notation.png new file mode 100644 index 0000000000000000000000000000000000000000..d613b70c287aff422211aaede98b677578c69bda GIT binary patch literal 27376 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 valuesPtr=std::make_shared(); - parameterPtr = gtsam::PreintegratedCombinedMeasurements::Params::MakeSharedD();// TODO check the IMU frame + gtsam::Vector4 g=SE_init.matrix()*gtsam::Vector4(0, 0, 9.8,1.0); + parameterPtr = boost::shared_ptr(new gtsam::PreintegrationCombinedParams(gtsam::Vector3(g.x(),g.y(),g.z()))); + parameterPtr->setBodyPSensor(gtsam::Pose3(SE_init.matrix()));// The pose of the sensor in the body frame parameterPtr->accelerometerCovariance=gtsam::I_3x3 * svo::Config::ACC_Noise(); // acc white noise in continuous parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * svo::Config::GYO_Noise();// gyro white noise in continuous parameterPtr->integrationCovariance=gtsam::I_3x3 * svo::Config::IUC(); // integration uncertainty continuous @@ -148,4 +150,4 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size } } return true; -} \ No newline at end of file +} diff --git a/GPU_version/svo/.idea/.name b/GPU_version/svo/.idea/.name new file mode 100644 index 0000000..4b0f94b --- /dev/null +++ b/GPU_version/svo/.idea/.name @@ -0,0 +1 @@ +gpu_svo \ No newline at end of file diff --git a/GPU_version/svo/.idea/svo.iml b/GPU_version/svo/.idea/svo.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/GPU_version/svo/.idea/svo.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/GPU_version/svo/.idea/vcs.xml b/GPU_version/svo/.idea/vcs.xml index 6c0b863..64713b8 100644 --- a/GPU_version/svo/.idea/vcs.xml +++ b/GPU_version/svo/.idea/vcs.xml @@ -1,6 +1,7 @@ + \ No newline at end of file diff --git a/GPU_version/svo/src/imu_integration.cpp b/GPU_version/svo/src/imu_integration.cpp index 2238f7c..b3f80ab 100644 --- a/GPU_version/svo/src/imu_integration.cpp +++ b/GPU_version/svo/src/imu_integration.cpp @@ -16,7 +16,12 @@ Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ graphPtr=std::make_shared(); valuesPtr=std::make_shared(); - parameterPtr = gtsam::PreintegratedCombinedMeasurements::Params::MakeSharedD();// TODO check the IMU frame + // Example: pitch and roll of aircraft in an ENU Cartesian frame. + // If pitch and roll are zero for an aerospace frame, + // that means Z is pointing down, i.e., direction of Z = (0,0,-1) + gtsam::Vector4 g=SE_init.matrix()*gtsam::Vector4(0, 0, 9.8,1.0); + parameterPtr = boost::shared_ptr(new gtsam::PreintegrationCombinedParams(gtsam::Vector3(g.x(),g.y(),g.z()))); + parameterPtr->setBodyPSensor(gtsam::Pose3(SE_init.matrix()));// The pose of the sensor in the body frame parameterPtr->accelerometerCovariance=gtsam::I_3x3 * svo::Config::ACC_Noise(); // acc white noise in continuous parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * svo::Config::GYO_Noise();// gyro white noise in continuous parameterPtr->integrationCovariance=gtsam::I_3x3 * svo::Config::IUC(); // integration uncertainty continuous @@ -122,14 +127,6 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size ++num_obs; } // Now optimize. - //gtsam::ISAM2 optimizer(*optimizerParamPtr); - //optimizer.update(*graphPtr, *valuesPtr); - // Each call to iSAM2 update(*) performs one iteration of the iterative - // nonlinear solver. If accuracy is desired at the expense of time, - // update(*) can be called additional times to perform multiple optimizer - // iterations every step. - //optimizer.update(); - // optimizer.print(); gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr); reset(optimizer,new_frame); diff --git a/GPU_version/vio/.idea/.name b/GPU_version/vio/.idea/.name new file mode 100644 index 0000000..06a578d --- /dev/null +++ b/GPU_version/vio/.idea/.name @@ -0,0 +1 @@ +vio_gpu \ No newline at end of file diff --git a/GPU_version/vio/.idea/svo_ros.iml b/GPU_version/vio/.idea/svo_ros.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/GPU_version/vio/.idea/svo_ros.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/GPU_version/vio/.idea/vcs.xml b/GPU_version/vio/.idea/vcs.xml index 6c0b863..64713b8 100644 --- a/GPU_version/vio/.idea/vcs.xml +++ b/GPU_version/vio/.idea/vcs.xml @@ -1,6 +1,7 @@ + \ No newline at end of file From d3dbd88133c77f99247cb98e2968c5803e911d41 Mon Sep 17 00:00:00 2001 From: gfuse Date: Tue, 11 May 2021 10:38:13 +0200 Subject: [PATCH 191/215] optimized gpu --- CPU_version/vio_svo/launch/Px30.launch | 2 +- GPU_version/svo/include/gpu_svo/cl.hpp | 12947 +++++++++++++++++++ GPU_version/svo/include/gpu_svo/cl_class.h | 2 +- GPU_version/svo/include/gpu_svo/config.h | 10 +- GPU_version/svo/kernel/fast-gray.cl | 3 + GPU_version/svo/src/feature_detection.cpp | 17 +- GPU_version/svo/src/frame_handler_mono.cpp | 6 +- GPU_version/svo/src/imu_integration.cpp | 2 + GPU_version/vio/launch/Px30.launch | 6 +- 9 files changed, 12972 insertions(+), 23 deletions(-) create mode 100644 GPU_version/svo/include/gpu_svo/cl.hpp diff --git a/CPU_version/vio_svo/launch/Px30.launch b/CPU_version/vio_svo/launch/Px30.launch index 06083d0..f6cad34 100644 --- a/CPU_version/vio_svo/launch/Px30.launch +++ b/CPU_version/vio_svo/launch/Px30.launch @@ -10,7 +10,7 @@ - + diff --git a/GPU_version/svo/include/gpu_svo/cl.hpp b/GPU_version/svo/include/gpu_svo/cl.hpp new file mode 100644 index 0000000..6634f8c --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/cl.hpp @@ -0,0 +1,12947 @@ +/******************************************************************************* + * Copyright (c) 2008-2015 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS + * KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS + * SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT + * https://www.khronos.org/registry/ + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + ******************************************************************************/ + +/*! \file + * + * \brief C++ bindings for OpenCL 1.0 (rev 48), OpenCL 1.1 (rev 33) and + * OpenCL 1.2 (rev 15) + * \author Benedict R. Gaster, Laurent Morichetti and Lee Howes + * + * Additions and fixes from: + * Brian Cole, March 3rd 2010 and April 2012 + * Matt Gruenke, April 2012. + * Bruce Merry, February 2013. + * Tom Deakin and Simon McIntosh-Smith, July 2013 + * + * \version 1.2.9 + * \date December 2015 + * + * Optional extension support + * + * cl + * cl_ext_device_fission + * #define USE_CL_DEVICE_FISSION + */ + +/*! \mainpage + * \section intro Introduction + * For many large applications C++ is the language of choice and so it seems + * reasonable to define C++ bindings for OpenCL. + * + * + * The interface is contained with a single C++ header file \em cl.hpp and all + * definitions are contained within the namespace \em cl. There is no additional + * requirement to include \em cl.h and to use either the C++ or original C + * bindings it is enough to simply include \em cl.hpp. + * + * The bindings themselves are lightweight and correspond closely to the + * underlying C API. Using the C++ bindings introduces no additional execution + * overhead. + * + * For detail documentation on the bindings see: + * + * The OpenCL C++ Wrapper API 1.2 (revision 09) + * http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.2.pdf + * + * \section example Example + * + * The following example shows a general use case for the C++ + * bindings, including support for the optional exception feature and + * also the supplied vector and string classes, see following sections for + * decriptions of these features. + * + * \code + * #define __CL_ENABLE_EXCEPTIONS + * + * #if defined(__APPLE__) || defined(__MACOSX) + * #include + * #else + * #include + * #endif + * #include + * #include + * #include + * + * const char * helloStr = "__kernel void " + * "hello(void) " + * "{ " + * " " + * "} "; + * + * int + * main(void) + * { + * cl_int err = CL_SUCCESS; + * try { + * + * std::vector platforms; + * cl::Platform::get(&platforms); + * if (platforms.size() == 0) { + * std::cout << "Platform size 0\n"; + * return -1; + * } + * + * cl_context_properties properties[] = + * { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0}; + * cl::Context context(CL_DEVICE_TYPE_CPU, properties); + * + * std::vector devices = context.getInfo(); + * + * cl::Program::Sources source(1, + * std::make_pair(helloStr,strlen(helloStr))); + * cl::Program program_ = cl::Program(context, source); + * program_.build(devices); + * + * cl::Kernel kernel(program_, "hello", &err); + * + * cl::Event event; + * cl::CommandQueue queue(context, devices[0], 0, &err); + * queue.enqueueNDRangeKernel( + * kernel, + * cl::NullRange, + * cl::NDRange(4,4), + * cl::NullRange, + * NULL, + * &event); + * + * event.wait(); + * } + * catch (cl::Error err) { + * std::cerr + * << "ERROR: " + * << err.what() + * << "(" + * << err.err() + * << ")" + * << std::endl; + * } + * + * return EXIT_SUCCESS; + * } + * + * \endcode + * + */ +#ifndef CL_HPP_ +#define CL_HPP_ + +#ifdef _WIN32 + +#include + +#if defined(USE_DX_INTEROP) +#include +#include +#endif +#endif // _WIN32 + +#if defined(_MSC_VER) +#include +#endif // _MSC_VER + +// +#if defined(USE_CL_DEVICE_FISSION) +#include +#endif + +#if defined(__APPLE__) || defined(__MACOSX) +#include +#else +#include +#endif // !__APPLE__ + +#if (_MSC_VER >= 1700) || (__cplusplus >= 201103L) +#define CL_HPP_RVALUE_REFERENCES_SUPPORTED +#define CL_HPP_CPP11_ATOMICS_SUPPORTED +#include +#endif + +#if (__cplusplus >= 201103L) +#define CL_HPP_NOEXCEPT noexcept +#else +#define CL_HPP_NOEXCEPT +#endif + + +// To avoid accidentally taking ownership of core OpenCL types +// such as cl_kernel constructors are made explicit +// under OpenCL 1.2 +#if defined(CL_VERSION_1_2) && !defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) +#define __CL_EXPLICIT_CONSTRUCTORS explicit +#else // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) +#define __CL_EXPLICIT_CONSTRUCTORS +#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) + +// Define deprecated prefixes and suffixes to ensure compilation +// in case they are not pre-defined +#if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED) +#define CL_EXT_PREFIX__VERSION_1_1_DEPRECATED +#endif // #if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED) +#if !defined(CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED) +#define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED +#endif // #if !defined(CL_EXT_PREFIX__VERSION_1_1_DEPRECATED) + +#if !defined(CL_CALLBACK) +#define CL_CALLBACK +#endif //CL_CALLBACK + +#include +#include +#include + +#if defined(__CL_ENABLE_EXCEPTIONS) +#include +#endif // #if defined(__CL_ENABLE_EXCEPTIONS) + +#if !defined(__NO_STD_VECTOR) +#include +#endif + +#if !defined(__NO_STD_STRING) +#include +#endif + +#if defined(__ANDROID__) || defined(linux) || defined(__APPLE__) || defined(__MACOSX) +#include +#endif // linux + +#include + + +/*! \namespace cl + * + * \brief The OpenCL C++ bindings are defined within this namespace. + * + */ +namespace cl { + +class Memory; + +/** + * Deprecated APIs for 1.2 + */ +#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) +#define __INIT_CL_EXT_FCN_PTR(name) \ + if(!pfn_##name) { \ + pfn_##name = (PFN_##name) \ + clGetExtensionFunctionAddress(#name); \ + if(!pfn_##name) { \ + } \ + } +#endif // #if defined(CL_VERSION_1_1) + +#if defined(CL_VERSION_1_2) +#define __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, name) \ + if(!pfn_##name) { \ + pfn_##name = (PFN_##name) \ + clGetExtensionFunctionAddressForPlatform(platform, #name); \ + if(!pfn_##name) { \ + } \ + } +#endif // #if defined(CL_VERSION_1_1) + +class Program; +class Device; +class Context; +class CommandQueue; +class Memory; +class Buffer; + +#if defined(__CL_ENABLE_EXCEPTIONS) +/*! \brief Exception class + * + * This may be thrown by API functions when __CL_ENABLE_EXCEPTIONS is defined. + */ +class Error : public std::exception +{ +private: + cl_int err_; + const char * errStr_; +public: + /*! \brief Create a new CL error exception for a given error code + * and corresponding message. + * + * \param err error code value. + * + * \param errStr a descriptive string that must remain in scope until + * handling of the exception has concluded. If set, it + * will be returned by what(). + */ + Error(cl_int err, const char * errStr = NULL) : err_(err), errStr_(errStr) + {} + + ~Error() throw() {} + + /*! \brief Get error string associated with exception + * + * \return A memory pointer to the error message string. + */ + virtual const char * what() const throw () + { + if (errStr_ == NULL) { + return "empty"; + } + else { + return errStr_; + } + } + + /*! \brief Get error code associated with exception + * + * \return The error code. + */ + cl_int err(void) const { return err_; } +}; + +#define __ERR_STR(x) #x +#else +#define __ERR_STR(x) NULL +#endif // __CL_ENABLE_EXCEPTIONS + + +namespace detail +{ +#if defined(__CL_ENABLE_EXCEPTIONS) +static inline cl_int errHandler ( + cl_int err, + const char * errStr = NULL) +{ + if (err != CL_SUCCESS) { + throw Error(err, errStr); + } + return err; +} +#else +static inline cl_int errHandler (cl_int err, const char * errStr = NULL) +{ + (void) errStr; // suppress unused variable warning + return err; +} +#endif // __CL_ENABLE_EXCEPTIONS +} + + + +//! \cond DOXYGEN_DETAIL +#if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS) +#define __GET_DEVICE_INFO_ERR __ERR_STR(clGetDeviceInfo) +#define __GET_PLATFORM_INFO_ERR __ERR_STR(clGetPlatformInfo) +#define __GET_DEVICE_IDS_ERR __ERR_STR(clGetDeviceIDs) +#define __GET_PLATFORM_IDS_ERR __ERR_STR(clGetPlatformIDs) +#define __GET_CONTEXT_INFO_ERR __ERR_STR(clGetContextInfo) +#define __GET_EVENT_INFO_ERR __ERR_STR(clGetEventInfo) +#define __GET_EVENT_PROFILE_INFO_ERR __ERR_STR(clGetEventProfileInfo) +#define __GET_MEM_OBJECT_INFO_ERR __ERR_STR(clGetMemObjectInfo) +#define __GET_IMAGE_INFO_ERR __ERR_STR(clGetImageInfo) +#define __GET_SAMPLER_INFO_ERR __ERR_STR(clGetSamplerInfo) +#define __GET_KERNEL_INFO_ERR __ERR_STR(clGetKernelInfo) +#if defined(CL_VERSION_1_2) +#define __GET_KERNEL_ARG_INFO_ERR __ERR_STR(clGetKernelArgInfo) +#endif // #if defined(CL_VERSION_1_2) +#define __GET_KERNEL_WORK_GROUP_INFO_ERR __ERR_STR(clGetKernelWorkGroupInfo) +#define __GET_PROGRAM_INFO_ERR __ERR_STR(clGetProgramInfo) +#define __GET_PROGRAM_BUILD_INFO_ERR __ERR_STR(clGetProgramBuildInfo) +#define __GET_COMMAND_QUEUE_INFO_ERR __ERR_STR(clGetCommandQueueInfo) + +#define __CREATE_CONTEXT_ERR __ERR_STR(clCreateContext) +#define __CREATE_CONTEXT_FROM_TYPE_ERR __ERR_STR(clCreateContextFromType) +#define __GET_SUPPORTED_IMAGE_FORMATS_ERR __ERR_STR(clGetSupportedImageFormats) + +#define __CREATE_BUFFER_ERR __ERR_STR(clCreateBuffer) +#define __COPY_ERR __ERR_STR(cl::copy) +#define __CREATE_SUBBUFFER_ERR __ERR_STR(clCreateSubBuffer) +#define __CREATE_GL_BUFFER_ERR __ERR_STR(clCreateFromGLBuffer) +#define __CREATE_GL_RENDER_BUFFER_ERR __ERR_STR(clCreateFromGLBuffer) +#define __GET_GL_OBJECT_INFO_ERR __ERR_STR(clGetGLObjectInfo) +#if defined(CL_VERSION_1_2) +#define __CREATE_IMAGE_ERR __ERR_STR(clCreateImage) +#define __CREATE_GL_TEXTURE_ERR __ERR_STR(clCreateFromGLTexture) +#define __IMAGE_DIMENSION_ERR __ERR_STR(Incorrect image dimensions) +#endif // #if defined(CL_VERSION_1_2) +#define __CREATE_SAMPLER_ERR __ERR_STR(clCreateSampler) +#define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR __ERR_STR(clSetMemObjectDestructorCallback) + +#define __CREATE_USER_EVENT_ERR __ERR_STR(clCreateUserEvent) +#define __SET_USER_EVENT_STATUS_ERR __ERR_STR(clSetUserEventStatus) +#define __SET_EVENT_CALLBACK_ERR __ERR_STR(clSetEventCallback) +#define __WAIT_FOR_EVENTS_ERR __ERR_STR(clWaitForEvents) + +#define __CREATE_KERNEL_ERR __ERR_STR(clCreateKernel) +#define __SET_KERNEL_ARGS_ERR __ERR_STR(clSetKernelArg) +#define __CREATE_PROGRAM_WITH_SOURCE_ERR __ERR_STR(clCreateProgramWithSource) +#define __CREATE_PROGRAM_WITH_BINARY_ERR __ERR_STR(clCreateProgramWithBinary) +#if defined(CL_VERSION_1_2) +#define __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR __ERR_STR(clCreateProgramWithBuiltInKernels) +#endif // #if defined(CL_VERSION_1_2) +#define __BUILD_PROGRAM_ERR __ERR_STR(clBuildProgram) +#if defined(CL_VERSION_1_2) +#define __COMPILE_PROGRAM_ERR __ERR_STR(clCompileProgram) +#define __LINK_PROGRAM_ERR __ERR_STR(clLinkProgram) +#endif // #if defined(CL_VERSION_1_2) +#define __CREATE_KERNELS_IN_PROGRAM_ERR __ERR_STR(clCreateKernelsInProgram) + +#define __CREATE_COMMAND_QUEUE_ERR __ERR_STR(clCreateCommandQueue) +#define __SET_COMMAND_QUEUE_PROPERTY_ERR __ERR_STR(clSetCommandQueueProperty) +#define __ENQUEUE_READ_BUFFER_ERR __ERR_STR(clEnqueueReadBuffer) +#define __ENQUEUE_READ_BUFFER_RECT_ERR __ERR_STR(clEnqueueReadBufferRect) +#define __ENQUEUE_WRITE_BUFFER_ERR __ERR_STR(clEnqueueWriteBuffer) +#define __ENQUEUE_WRITE_BUFFER_RECT_ERR __ERR_STR(clEnqueueWriteBufferRect) +#define __ENQEUE_COPY_BUFFER_ERR __ERR_STR(clEnqueueCopyBuffer) +#define __ENQEUE_COPY_BUFFER_RECT_ERR __ERR_STR(clEnqueueCopyBufferRect) +#define __ENQUEUE_FILL_BUFFER_ERR __ERR_STR(clEnqueueFillBuffer) +#define __ENQUEUE_READ_IMAGE_ERR __ERR_STR(clEnqueueReadImage) +#define __ENQUEUE_WRITE_IMAGE_ERR __ERR_STR(clEnqueueWriteImage) +#define __ENQUEUE_COPY_IMAGE_ERR __ERR_STR(clEnqueueCopyImage) +#define __ENQUEUE_FILL_IMAGE_ERR __ERR_STR(clEnqueueFillImage) +#define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR __ERR_STR(clEnqueueCopyImageToBuffer) +#define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR __ERR_STR(clEnqueueCopyBufferToImage) +#define __ENQUEUE_MAP_BUFFER_ERR __ERR_STR(clEnqueueMapBuffer) +#define __ENQUEUE_MAP_IMAGE_ERR __ERR_STR(clEnqueueMapImage) +#define __ENQUEUE_UNMAP_MEM_OBJECT_ERR __ERR_STR(clEnqueueUnMapMemObject) +#define __ENQUEUE_NDRANGE_KERNEL_ERR __ERR_STR(clEnqueueNDRangeKernel) +#define __ENQUEUE_TASK_ERR __ERR_STR(clEnqueueTask) +#define __ENQUEUE_NATIVE_KERNEL __ERR_STR(clEnqueueNativeKernel) +#if defined(CL_VERSION_1_2) +#define __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR __ERR_STR(clEnqueueMigrateMemObjects) +#endif // #if defined(CL_VERSION_1_2) + +#define __ENQUEUE_ACQUIRE_GL_ERR __ERR_STR(clEnqueueAcquireGLObjects) +#define __ENQUEUE_RELEASE_GL_ERR __ERR_STR(clEnqueueReleaseGLObjects) + + +#define __RETAIN_ERR __ERR_STR(Retain Object) +#define __RELEASE_ERR __ERR_STR(Release Object) +#define __FLUSH_ERR __ERR_STR(clFlush) +#define __FINISH_ERR __ERR_STR(clFinish) +#define __VECTOR_CAPACITY_ERR __ERR_STR(Vector capacity error) + +/** + * CL 1.2 version that uses device fission. + */ +#if defined(CL_VERSION_1_2) +#define __CREATE_SUB_DEVICES __ERR_STR(clCreateSubDevices) +#else +#define __CREATE_SUB_DEVICES __ERR_STR(clCreateSubDevicesEXT) +#endif // #if defined(CL_VERSION_1_2) + +/** + * Deprecated APIs for 1.2 + */ +#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) +#define __ENQUEUE_MARKER_ERR __ERR_STR(clEnqueueMarker) +#define __ENQUEUE_WAIT_FOR_EVENTS_ERR __ERR_STR(clEnqueueWaitForEvents) +#define __ENQUEUE_BARRIER_ERR __ERR_STR(clEnqueueBarrier) +#define __UNLOAD_COMPILER_ERR __ERR_STR(clUnloadCompiler) +#define __CREATE_GL_TEXTURE_2D_ERR __ERR_STR(clCreateFromGLTexture2D) +#define __CREATE_GL_TEXTURE_3D_ERR __ERR_STR(clCreateFromGLTexture3D) +#define __CREATE_IMAGE2D_ERR __ERR_STR(clCreateImage2D) +#define __CREATE_IMAGE3D_ERR __ERR_STR(clCreateImage3D) +#endif // #if defined(CL_VERSION_1_1) + +#endif // __CL_USER_OVERRIDE_ERROR_STRINGS +//! \endcond + +/** + * CL 1.2 marker and barrier commands + */ +#if defined(CL_VERSION_1_2) +#define __ENQUEUE_MARKER_WAIT_LIST_ERR __ERR_STR(clEnqueueMarkerWithWaitList) +#define __ENQUEUE_BARRIER_WAIT_LIST_ERR __ERR_STR(clEnqueueBarrierWithWaitList) +#endif // #if defined(CL_VERSION_1_2) + +#if !defined(__USE_DEV_STRING) && !defined(__NO_STD_STRING) +typedef std::string STRING_CLASS; +#elif !defined(__USE_DEV_STRING) + +/*! \class string + * \brief Simple string class, that provides a limited subset of std::string + * functionality but avoids many of the issues that come with that class. + + * \note Deprecated. Please use std::string as default or + * re-define the string class to match the std::string + * interface by defining STRING_CLASS + */ +class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED string +{ +private: + ::size_t size_; + char * str_; +public: + //! \brief Constructs an empty string, allocating no memory. + string(void) : size_(0), str_(NULL) + { + } + + /*! \brief Constructs a string populated from an arbitrary value of + * specified size. + * + * An extra '\0' is added, in case none was contained in str. + * + * \param str the initial value of the string instance. Note that '\0' + * characters receive no special treatment. If NULL, + * the string is left empty, with a size of 0. + * + * \param size the number of characters to copy from str. + */ + string(const char * str, ::size_t size) : + size_(size), + str_(NULL) + { + if( size > 0 ) { + str_ = new char[size_+1]; + if (str_ != NULL) { + memcpy(str_, str, size_ * sizeof(char)); + str_[size_] = '\0'; + } + else { + size_ = 0; + } + } + } + + /*! \brief Constructs a string populated from a null-terminated value. + * + * \param str the null-terminated initial value of the string instance. + * If NULL, the string is left empty, with a size of 0. + */ + string(const char * str) : + size_(0), + str_(NULL) + { + if( str ) { + size_= ::strlen(str); + } + if( size_ > 0 ) { + str_ = new char[size_ + 1]; + if (str_ != NULL) { + memcpy(str_, str, (size_ + 1) * sizeof(char)); + } + } + } + + void resize( ::size_t n ) + { + if( size_ == n ) { + return; + } + if (n == 0) { + if( str_ ) { + delete [] str_; + } + str_ = NULL; + size_ = 0; + } + else { + char *newString = new char[n + 1]; + ::size_t copySize = n; + if( size_ < n ) { + copySize = size_; + } + size_ = n; + + if(str_) { + memcpy(newString, str_, (copySize + 1) * sizeof(char)); + } + if( copySize < size_ ) { + memset(newString + copySize, 0, size_ - copySize); + } + newString[size_] = '\0'; + + delete [] str_; + str_ = newString; + } + } + + const char& operator[] ( ::size_t pos ) const + { + return str_[pos]; + } + + char& operator[] ( ::size_t pos ) + { + return str_[pos]; + } + + /*! \brief Copies the value of another string to this one. + * + * \param rhs the string to copy. + * + * \returns a reference to the modified instance. + */ + string& operator=(const string& rhs) + { + if (this == &rhs) { + return *this; + } + + if( str_ != NULL ) { + delete [] str_; + str_ = NULL; + size_ = 0; + } + + if (rhs.size_ == 0 || rhs.str_ == NULL) { + str_ = NULL; + size_ = 0; + } + else { + str_ = new char[rhs.size_ + 1]; + size_ = rhs.size_; + + if (str_ != NULL) { + memcpy(str_, rhs.str_, (size_ + 1) * sizeof(char)); + } + else { + size_ = 0; + } + } + + return *this; + } + + /*! \brief Constructs a string by copying the value of another instance. + * + * \param rhs the string to copy. + */ + string(const string& rhs) : + size_(0), + str_(NULL) + { + *this = rhs; + } + + //! \brief Destructor - frees memory used to hold the current value. + ~string() + { + delete[] str_; + str_ = NULL; + } + + //! \brief Queries the length of the string, excluding any added '\0's. + ::size_t size(void) const { return size_; } + + //! \brief Queries the length of the string, excluding any added '\0's. + ::size_t length(void) const { return size(); } + + /*! \brief Returns a pointer to the private copy held by this instance, + * or "" if empty/unset. + */ + const char * c_str(void) const { return (str_) ? str_ : "";} +} CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; +typedef cl::string STRING_CLASS; +#endif // #elif !defined(__USE_DEV_STRING) + +#if !defined(__USE_DEV_VECTOR) && !defined(__NO_STD_VECTOR) +#define VECTOR_CLASS std::vector +#elif !defined(__USE_DEV_VECTOR) +#define VECTOR_CLASS cl::vector + +#if !defined(__MAX_DEFAULT_VECTOR_SIZE) +#define __MAX_DEFAULT_VECTOR_SIZE 10 +#endif + +/*! \class vector + * \brief Fixed sized vector implementation that mirroring + * + * \note Deprecated. Please use std::vector as default or + * re-define the vector class to match the std::vector + * interface by defining VECTOR_CLASS + + * \note Not recommended for use with custom objects as + * current implementation will construct N elements + * + * std::vector functionality. + * \brief Fixed sized vector compatible with std::vector. + * + * \note + * This differs from std::vector<> not just in memory allocation, + * but also in terms of when members are constructed, destroyed, + * and assigned instead of being copy constructed. + * + * \param T type of element contained in the vector. + * + * \param N maximum size of the vector. + */ +template +class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED vector +{ +private: + T data_[N]; + unsigned int size_; + +public: + //! \brief Constructs an empty vector with no memory allocated. + vector() : + size_(static_cast(0)) + {} + + //! \brief Deallocates the vector's memory and destroys all of its elements. + ~vector() + { + clear(); + } + + //! \brief Returns the number of elements currently contained. + unsigned int size(void) const + { + return size_; + } + + /*! \brief Empties the vector of all elements. + * \note + * This does not deallocate memory but will invoke destructors + * on contained elements. + */ + void clear() + { + while(!empty()) { + pop_back(); + } + } + + /*! \brief Appends an element after the last valid element. + * Calling this on a vector that has reached capacity will throw an + * exception if exceptions are enabled. + */ + void push_back (const T& x) + { + if (size() < N) { + new (&data_[size_]) T(x); + size_++; + } else { + detail::errHandler(CL_MEM_OBJECT_ALLOCATION_FAILURE, __VECTOR_CAPACITY_ERR); + } + } + + /*! \brief Removes the last valid element from the vector. + * Calling this on an empty vector will throw an exception + * if exceptions are enabled. + */ + void pop_back(void) + { + if (size_ != 0) { + --size_; + data_[size_].~T(); + } else { + detail::errHandler(CL_MEM_OBJECT_ALLOCATION_FAILURE, __VECTOR_CAPACITY_ERR); + } + } + + /*! \brief Constructs with a value copied from another. + * + * \param vec the vector to copy. + */ + vector(const vector& vec) : + size_(vec.size_) + { + if (size_ != 0) { + assign(vec.begin(), vec.end()); + } + } + + /*! \brief Constructs with a specified number of initial elements. + * + * \param size number of initial elements. + * + * \param val value of initial elements. + */ + vector(unsigned int size, const T& val = T()) : + size_(0) + { + for (unsigned int i = 0; i < size; i++) { + push_back(val); + } + } + + /*! \brief Overwrites the current content with that copied from another + * instance. + * + * \param rhs vector to copy. + * + * \returns a reference to this. + */ + vector& operator=(const vector& rhs) + { + if (this == &rhs) { + return *this; + } + + if (rhs.size_ != 0) { + assign(rhs.begin(), rhs.end()); + } else { + clear(); + } + + return *this; + } + + /*! \brief Tests equality against another instance. + * + * \param vec the vector against which to compare. + */ + bool operator==(vector &vec) + { + if (size() != vec.size()) { + return false; + } + + for( unsigned int i = 0; i < size(); ++i ) { + if( operator[](i) != vec[i] ) { + return false; + } + } + return true; + } + + //! \brief Conversion operator to T*. + operator T* () { return data_; } + + //! \brief Conversion operator to const T*. + operator const T* () const { return data_; } + + //! \brief Tests whether this instance has any elements. + bool empty (void) const + { + return size_==0; + } + + //! \brief Returns the maximum number of elements this instance can hold. + unsigned int max_size (void) const + { + return N; + } + + //! \brief Returns the maximum number of elements this instance can hold. + unsigned int capacity () const + { + return N; + } + + //! \brief Resizes the vector to the given size + void resize(unsigned int newSize, T fill = T()) + { + if (newSize > N) + { + detail::errHandler(CL_MEM_OBJECT_ALLOCATION_FAILURE, __VECTOR_CAPACITY_ERR); + } + else + { + while (size_ < newSize) + { + new (&data_[size_]) T(fill); + size_++; + } + while (size_ > newSize) + { + --size_; + data_[size_].~T(); + } + } + } + + /*! \brief Returns a reference to a given element. + * + * \param index which element to access. * + * \note + * The caller is responsible for ensuring index is >= 0 and < size(). + */ + T& operator[](int index) + { + return data_[index]; + } + + /*! \brief Returns a const reference to a given element. + * + * \param index which element to access. + * + * \note + * The caller is responsible for ensuring index is >= 0 and < size(). + */ + const T& operator[](int index) const + { + return data_[index]; + } + + /*! \brief Assigns elements of the vector based on a source iterator range. + * + * \param start Beginning iterator of source range + * \param end Enditerator of source range + * + * \note + * Will throw an exception if exceptions are enabled and size exceeded. + */ + template + void assign(I start, I end) + { + clear(); + while(start != end) { + push_back(*start); + start++; + } + } + + /*! \class iterator + * \brief Const iterator class for vectors + */ + class iterator + { + private: + const vector *vec_; + int index_; + + /** + * Internal iterator constructor to capture reference + * to the vector it iterates over rather than taking + * the vector by copy. + */ + iterator (const vector &vec, int index) : + vec_(&vec) + { + if( !vec.empty() ) { + index_ = index; + } else { + index_ = -1; + } + } + + public: + iterator(void) : + index_(-1), + vec_(NULL) + { + } + + iterator(const iterator& rhs) : + vec_(rhs.vec_), + index_(rhs.index_) + { + } + + ~iterator(void) {} + + static iterator begin(const cl::vector &vec) + { + iterator i(vec, 0); + + return i; + } + + static iterator end(const cl::vector &vec) + { + iterator i(vec, vec.size()); + + return i; + } + + bool operator==(iterator i) + { + return ((vec_ == i.vec_) && + (index_ == i.index_)); + } + + bool operator!=(iterator i) + { + return (!(*this==i)); + } + + iterator& operator++() + { + ++index_; + return *this; + } + + iterator operator++(int) + { + iterator retVal(*this); + ++index_; + return retVal; + } + + iterator& operator--() + { + --index_; + return *this; + } + + iterator operator--(int) + { + iterator retVal(*this); + --index_; + return retVal; + } + + const T& operator *() const + { + return (*vec_)[index_]; + } + }; + + iterator begin(void) + { + return iterator::begin(*this); + } + + iterator begin(void) const + { + return iterator::begin(*this); + } + + iterator end(void) + { + return iterator::end(*this); + } + + iterator end(void) const + { + return iterator::end(*this); + } + + T& front(void) + { + return data_[0]; + } + + T& back(void) + { + return data_[size_]; + } + + const T& front(void) const + { + return data_[0]; + } + + const T& back(void) const + { + return data_[size_-1]; + } +} CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; +#endif // #if !defined(__USE_DEV_VECTOR) && !defined(__NO_STD_VECTOR) + + + + + +namespace detail { +#define __DEFAULT_NOT_INITIALIZED 1 +#define __DEFAULT_BEING_INITIALIZED 2 +#define __DEFAULT_INITIALIZED 4 + + /* + * Compare and exchange primitives are needed for handling of defaults + */ + +#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED + inline int compare_exchange(std::atomic * dest, int exchange, int comparand) +#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED + inline int compare_exchange(volatile int * dest, int exchange, int comparand) +#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED + { +#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED + std::atomic_compare_exchange_strong(dest, &comparand, exchange); + return comparand; +#elif _MSC_VER + return (int)(_InterlockedCompareExchange( + (volatile long*)dest, + (long)exchange, + (long)comparand)); +#else // !_MSC_VER && !CL_HPP_CPP11_ATOMICS_SUPPORTED + return (__sync_val_compare_and_swap( + dest, + comparand, + exchange)); +#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED + } + + inline void fence() { +#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED + std::atomic_thread_fence(std::memory_order_seq_cst); +#elif _MSC_VER // !CL_HPP_CPP11_ATOMICS_SUPPORTED + _ReadWriteBarrier(); +#else // !_MSC_VER && !CL_HPP_CPP11_ATOMICS_SUPPORTED + __sync_synchronize(); +#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED + } +} // namespace detail + + +/*! \brief class used to interface between C++ and + * OpenCL C calls that require arrays of size_t values, whose + * size is known statically. + */ +template +class size_t +{ +private: + ::size_t data_[N]; + +public: + //! \brief Initialize size_t to all 0s + size_t() + { + for( int i = 0; i < N; ++i ) { + data_[i] = 0; + } + } + + ::size_t& operator[](int index) + { + return data_[index]; + } + + const ::size_t& operator[](int index) const + { + return data_[index]; + } + + //! \brief Conversion operator to T*. + operator ::size_t* () { return data_; } + + //! \brief Conversion operator to const T*. + operator const ::size_t* () const { return data_; } +}; + +namespace detail { + +// Generic getInfoHelper. The final parameter is used to guide overload +// resolution: the actual parameter passed is an int, which makes this +// a worse conversion sequence than a specialization that declares the +// parameter as an int. +template +inline cl_int getInfoHelper(Functor f, cl_uint name, T* param, long) +{ + return f(name, sizeof(T), param, NULL); +} + +// Specialized getInfoHelper for VECTOR_CLASS params +template +inline cl_int getInfoHelper(Func f, cl_uint name, VECTOR_CLASS* param, long) +{ + ::size_t required; + cl_int err = f(name, 0, NULL, &required); + if (err != CL_SUCCESS) { + return err; + } + + T* value = (T*) alloca(required); + err = f(name, required, value, NULL); + if (err != CL_SUCCESS) { + return err; + } + + param->assign(&value[0], &value[required/sizeof(T)]); + return CL_SUCCESS; +} + +/* Specialization for reference-counted types. This depends on the + * existence of Wrapper::cl_type, and none of the other types having the + * cl_type member. Note that simplify specifying the parameter as Wrapper + * does not work, because when using a derived type (e.g. Context) the generic + * template will provide a better match. + */ +template +inline cl_int getInfoHelper(Func f, cl_uint name, VECTOR_CLASS* param, int, typename T::cl_type = 0) +{ + ::size_t required; + cl_int err = f(name, 0, NULL, &required); + if (err != CL_SUCCESS) { + return err; + } + + typename T::cl_type * value = (typename T::cl_type *) alloca(required); + err = f(name, required, value, NULL); + if (err != CL_SUCCESS) { + return err; + } + + ::size_t elements = required / sizeof(typename T::cl_type); + param->assign(&value[0], &value[elements]); + for (::size_t i = 0; i < elements; i++) + { + if (value[i] != NULL) + { + err = (*param)[i].retain(); + if (err != CL_SUCCESS) { + return err; + } + } + } + return CL_SUCCESS; +} + +// Specialized for getInfo +template +inline cl_int getInfoHelper(Func f, cl_uint name, VECTOR_CLASS* param, int) +{ + cl_int err = f(name, param->size() * sizeof(char *), &(*param)[0], NULL); + + if (err != CL_SUCCESS) { + return err; + } + + return CL_SUCCESS; +} + +// Specialized GetInfoHelper for STRING_CLASS params +template +inline cl_int getInfoHelper(Func f, cl_uint name, STRING_CLASS* param, long) +{ +#if defined(__NO_STD_VECTOR) || defined(__NO_STD_STRING) + ::size_t required; + cl_int err = f(name, 0, NULL, &required); + if (err != CL_SUCCESS) { + return err; + } + + char* value = (char*)alloca(required); + err = f(name, required, value, NULL); + if (err != CL_SUCCESS) { + return err; + } + + *param = value; + return CL_SUCCESS; +#else + ::size_t required; + cl_int err = f(name, 0, NULL, &required); + if (err != CL_SUCCESS) { + return err; + } + + // std::string has a constant data member + // a char vector does not + VECTOR_CLASS value(required); + err = f(name, required, value.data(), NULL); + if (err != CL_SUCCESS) { + return err; + } + if (param) { + param->assign(value.begin(), value.end()); + } +#endif + return CL_SUCCESS; +} + +// Specialized GetInfoHelper for cl::size_t params +template +inline cl_int getInfoHelper(Func f, cl_uint name, size_t* param, long) +{ + ::size_t required; + cl_int err = f(name, 0, NULL, &required); + if (err != CL_SUCCESS) { + return err; + } + + ::size_t* value = (::size_t*) alloca(required); + err = f(name, required, value, NULL); + if (err != CL_SUCCESS) { + return err; + } + + for(int i = 0; i < N; ++i) { + (*param)[i] = value[i]; + } + + return CL_SUCCESS; +} + +template struct ReferenceHandler; + +/* Specialization for reference-counted types. This depends on the + * existence of Wrapper::cl_type, and none of the other types having the + * cl_type member. Note that simplify specifying the parameter as Wrapper + * does not work, because when using a derived type (e.g. Context) the generic + * template will provide a better match. + */ +template +inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_type = 0) +{ + typename T::cl_type value; + cl_int err = f(name, sizeof(value), &value, NULL); + if (err != CL_SUCCESS) { + return err; + } + *param = value; + if (value != NULL) + { + err = param->retain(); + if (err != CL_SUCCESS) { + return err; + } + } + return CL_SUCCESS; +} + +#define __PARAM_NAME_INFO_1_0(F) \ + F(cl_platform_info, CL_PLATFORM_PROFILE, STRING_CLASS) \ + F(cl_platform_info, CL_PLATFORM_VERSION, STRING_CLASS) \ + F(cl_platform_info, CL_PLATFORM_NAME, STRING_CLASS) \ + F(cl_platform_info, CL_PLATFORM_VENDOR, STRING_CLASS) \ + F(cl_platform_info, CL_PLATFORM_EXTENSIONS, STRING_CLASS) \ + \ + F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \ + F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \ + F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \ + F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \ + F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, ::size_t) \ + F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, VECTOR_CLASS< ::size_t>) \ + F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \ + F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \ + F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \ + F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \ + F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \ + F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \ + F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \ + F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_uint) \ + F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \ + F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \ + F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \ + F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, ::size_t) \ + F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, ::size_t) \ + F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, ::size_t) \ + F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, ::size_t) \ + F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, ::size_t) \ + F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_bool) \ + F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, ::size_t) \ + F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \ + F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \ + F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \ + F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \ + F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \ + F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\ + F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \ + F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \ + F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \ + F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \ + F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \ + F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \ + F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \ + F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, ::size_t) \ + F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \ + F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \ + F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \ + F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \ + F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties) \ + F(cl_device_info, CL_DEVICE_PLATFORM, cl_platform_id) \ + F(cl_device_info, CL_DEVICE_NAME, STRING_CLASS) \ + F(cl_device_info, CL_DEVICE_VENDOR, STRING_CLASS) \ + F(cl_device_info, CL_DRIVER_VERSION, STRING_CLASS) \ + F(cl_device_info, CL_DEVICE_PROFILE, STRING_CLASS) \ + F(cl_device_info, CL_DEVICE_VERSION, STRING_CLASS) \ + F(cl_device_info, CL_DEVICE_EXTENSIONS, STRING_CLASS) \ + \ + F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \ + F(cl_context_info, CL_CONTEXT_DEVICES, VECTOR_CLASS) \ + F(cl_context_info, CL_CONTEXT_PROPERTIES, VECTOR_CLASS) \ + \ + F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \ + F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \ + F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \ + F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_int) \ + \ + F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \ + F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \ + F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \ + F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \ + \ + F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \ + F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \ + F(cl_mem_info, CL_MEM_SIZE, ::size_t) \ + F(cl_mem_info, CL_MEM_HOST_PTR, void*) \ + F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \ + F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \ + F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \ + \ + F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \ + F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, ::size_t) \ + F(cl_image_info, CL_IMAGE_ROW_PITCH, ::size_t) \ + F(cl_image_info, CL_IMAGE_SLICE_PITCH, ::size_t) \ + F(cl_image_info, CL_IMAGE_WIDTH, ::size_t) \ + F(cl_image_info, CL_IMAGE_HEIGHT, ::size_t) \ + F(cl_image_info, CL_IMAGE_DEPTH, ::size_t) \ + \ + F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \ + F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \ + F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_bool) \ + F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_addressing_mode) \ + F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_filter_mode) \ + \ + F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \ + F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \ + F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \ + F(cl_program_info, CL_PROGRAM_DEVICES, VECTOR_CLASS) \ + F(cl_program_info, CL_PROGRAM_SOURCE, STRING_CLASS) \ + F(cl_program_info, CL_PROGRAM_BINARY_SIZES, VECTOR_CLASS< ::size_t>) \ + F(cl_program_info, CL_PROGRAM_BINARIES, VECTOR_CLASS) \ + \ + F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \ + F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, STRING_CLASS) \ + F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, STRING_CLASS) \ + \ + F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, STRING_CLASS) \ + F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \ + F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \ + F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \ + F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \ + \ + F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, ::size_t) \ + F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::size_t<3>) \ + F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \ + \ + F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \ + F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \ + F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \ + F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties) + +#if defined(CL_VERSION_1_1) +#define __PARAM_NAME_INFO_1_1(F) \ + F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\ + F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \ + F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \ + F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \ + F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \ + F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \ + F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \ + F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \ + F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \ + F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \ + F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \ + F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool) \ + F(cl_device_info, CL_DEVICE_OPENCL_C_VERSION, STRING_CLASS) \ + \ + F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \ + F(cl_mem_info, CL_MEM_OFFSET, ::size_t) \ + \ + F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, ::size_t) \ + F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \ + \ + F(cl_event_info, CL_EVENT_CONTEXT, cl::Context) +#endif // CL_VERSION_1_1 + + +#if defined(CL_VERSION_1_2) +#define __PARAM_NAME_INFO_1_2(F) \ + F(cl_image_info, CL_IMAGE_BUFFER, cl::Buffer) \ + \ + F(cl_program_info, CL_PROGRAM_NUM_KERNELS, ::size_t) \ + F(cl_program_info, CL_PROGRAM_KERNEL_NAMES, STRING_CLASS) \ + \ + F(cl_program_build_info, CL_PROGRAM_BINARY_TYPE, cl_program_binary_type) \ + \ + F(cl_kernel_info, CL_KERNEL_ATTRIBUTES, STRING_CLASS) \ + \ + F(cl_kernel_arg_info, CL_KERNEL_ARG_ADDRESS_QUALIFIER, cl_kernel_arg_address_qualifier) \ + F(cl_kernel_arg_info, CL_KERNEL_ARG_ACCESS_QUALIFIER, cl_kernel_arg_access_qualifier) \ + F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_NAME, STRING_CLASS) \ + F(cl_kernel_arg_info, CL_KERNEL_ARG_NAME, STRING_CLASS) \ + F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_QUALIFIER, cl_kernel_arg_type_qualifier) \ + \ + F(cl_device_info, CL_DEVICE_PARENT_DEVICE, cl_device_id) \ + F(cl_device_info, CL_DEVICE_PARTITION_PROPERTIES, VECTOR_CLASS) \ + F(cl_device_info, CL_DEVICE_PARTITION_TYPE, VECTOR_CLASS) \ + F(cl_device_info, CL_DEVICE_REFERENCE_COUNT, cl_uint) \ + F(cl_device_info, CL_DEVICE_PREFERRED_INTEROP_USER_SYNC, ::size_t) \ + F(cl_device_info, CL_DEVICE_PARTITION_AFFINITY_DOMAIN, cl_device_affinity_domain) \ + F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS, STRING_CLASS) +#endif // #if defined(CL_VERSION_1_2) + +#if defined(USE_CL_DEVICE_FISSION) +#define __PARAM_NAME_DEVICE_FISSION(F) \ + F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl_device_id) \ + F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, VECTOR_CLASS) \ + F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, VECTOR_CLASS) \ + F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \ + F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, VECTOR_CLASS) +#endif // USE_CL_DEVICE_FISSION + +template +struct param_traits {}; + +#define __CL_DECLARE_PARAM_TRAITS(token, param_name, T) \ +struct token; \ +template<> \ +struct param_traits \ +{ \ + enum { value = param_name }; \ + typedef T param_type; \ +}; + +__PARAM_NAME_INFO_1_0(__CL_DECLARE_PARAM_TRAITS) +#if defined(CL_VERSION_1_1) +__PARAM_NAME_INFO_1_1(__CL_DECLARE_PARAM_TRAITS) +#endif // CL_VERSION_1_1 +#if defined(CL_VERSION_1_2) +__PARAM_NAME_INFO_1_2(__CL_DECLARE_PARAM_TRAITS) +#endif // CL_VERSION_1_1 + +#if defined(USE_CL_DEVICE_FISSION) +__PARAM_NAME_DEVICE_FISSION(__CL_DECLARE_PARAM_TRAITS); +#endif // USE_CL_DEVICE_FISSION + +#ifdef CL_PLATFORM_ICD_SUFFIX_KHR +__CL_DECLARE_PARAM_TRAITS(cl_platform_info, CL_PLATFORM_ICD_SUFFIX_KHR, STRING_CLASS) +#endif + +#ifdef CL_DEVICE_PROFILING_TIMER_OFFSET_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_PROFILING_TIMER_OFFSET_AMD, cl_ulong) +#endif + +#ifdef CL_DEVICE_GLOBAL_FREE_MEMORY_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_FREE_MEMORY_AMD, VECTOR_CLASS< ::size_t>) +#endif +#ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD, cl_uint) +#endif +#ifdef CL_DEVICE_SIMD_WIDTH_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_SIMD_WIDTH_AMD, cl_uint) +#endif +#ifdef CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD, cl_uint) +#endif +#ifdef CL_DEVICE_WAVEFRONT_WIDTH_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_WAVEFRONT_WIDTH_AMD, cl_uint) +#endif +#ifdef CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD, cl_uint) +#endif +#ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD, cl_uint) +#endif +#ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD, cl_uint) +#endif +#ifdef CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD, cl_uint) +#endif +#ifdef CL_DEVICE_LOCAL_MEM_BANKS_AMD +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_LOCAL_MEM_BANKS_AMD, cl_uint) +#endif + +#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, cl_uint) +#endif +#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV, cl_uint) +#endif +#ifdef CL_DEVICE_REGISTERS_PER_BLOCK_NV +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_REGISTERS_PER_BLOCK_NV, cl_uint) +#endif +#ifdef CL_DEVICE_WARP_SIZE_NV +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_WARP_SIZE_NV, cl_uint) +#endif +#ifdef CL_DEVICE_GPU_OVERLAP_NV +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_GPU_OVERLAP_NV, cl_bool) +#endif +#ifdef CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV, cl_bool) +#endif +#ifdef CL_DEVICE_INTEGRATED_MEMORY_NV +__CL_DECLARE_PARAM_TRAITS(cl_device_info, CL_DEVICE_INTEGRATED_MEMORY_NV, cl_bool) +#endif + +// Convenience functions + +template +inline cl_int +getInfo(Func f, cl_uint name, T* param) +{ + return getInfoHelper(f, name, param, 0); +} + +template +struct GetInfoFunctor0 +{ + Func f_; const Arg0& arg0_; + cl_int operator ()( + cl_uint param, ::size_t size, void* value, ::size_t* size_ret) + { return f_(arg0_, param, size, value, size_ret); } +}; + +template +struct GetInfoFunctor1 +{ + Func f_; const Arg0& arg0_; const Arg1& arg1_; + cl_int operator ()( + cl_uint param, ::size_t size, void* value, ::size_t* size_ret) + { return f_(arg0_, arg1_, param, size, value, size_ret); } +}; + +template +inline cl_int +getInfo(Func f, const Arg0& arg0, cl_uint name, T* param) +{ + GetInfoFunctor0 f0 = { f, arg0 }; + return getInfoHelper(f0, name, param, 0); +} + +template +inline cl_int +getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param) +{ + GetInfoFunctor1 f0 = { f, arg0, arg1 }; + return getInfoHelper(f0, name, param, 0); +} + +template +struct ReferenceHandler +{ }; + +#if defined(CL_VERSION_1_2) +/** + * OpenCL 1.2 devices do have retain/release. + */ +template <> +struct ReferenceHandler +{ + /** + * Retain the device. + * \param device A valid device created using createSubDevices + * \return + * CL_SUCCESS if the function executed successfully. + * CL_INVALID_DEVICE if device was not a valid subdevice + * CL_OUT_OF_RESOURCES + * CL_OUT_OF_HOST_MEMORY + */ + static cl_int retain(cl_device_id device) + { return ::clRetainDevice(device); } + /** + * Retain the device. + * \param device A valid device created using createSubDevices + * \return + * CL_SUCCESS if the function executed successfully. + * CL_INVALID_DEVICE if device was not a valid subdevice + * CL_OUT_OF_RESOURCES + * CL_OUT_OF_HOST_MEMORY + */ + static cl_int release(cl_device_id device) + { return ::clReleaseDevice(device); } +}; +#else // #if defined(CL_VERSION_1_2) +/** + * OpenCL 1.1 devices do not have retain/release. + */ +template <> +struct ReferenceHandler +{ + // cl_device_id does not have retain(). + static cl_int retain(cl_device_id) + { return CL_SUCCESS; } + // cl_device_id does not have release(). + static cl_int release(cl_device_id) + { return CL_SUCCESS; } +}; +#endif // #if defined(CL_VERSION_1_2) + +template <> +struct ReferenceHandler +{ + // cl_platform_id does not have retain(). + static cl_int retain(cl_platform_id) + { return CL_SUCCESS; } + // cl_platform_id does not have release(). + static cl_int release(cl_platform_id) + { return CL_SUCCESS; } +}; + +template <> +struct ReferenceHandler +{ + static cl_int retain(cl_context context) + { return ::clRetainContext(context); } + static cl_int release(cl_context context) + { return ::clReleaseContext(context); } +}; + +template <> +struct ReferenceHandler +{ + static cl_int retain(cl_command_queue queue) + { return ::clRetainCommandQueue(queue); } + static cl_int release(cl_command_queue queue) + { return ::clReleaseCommandQueue(queue); } +}; + +template <> +struct ReferenceHandler +{ + static cl_int retain(cl_mem memory) + { return ::clRetainMemObject(memory); } + static cl_int release(cl_mem memory) + { return ::clReleaseMemObject(memory); } +}; + +template <> +struct ReferenceHandler +{ + static cl_int retain(cl_sampler sampler) + { return ::clRetainSampler(sampler); } + static cl_int release(cl_sampler sampler) + { return ::clReleaseSampler(sampler); } +}; + +template <> +struct ReferenceHandler +{ + static cl_int retain(cl_program program) + { return ::clRetainProgram(program); } + static cl_int release(cl_program program) + { return ::clReleaseProgram(program); } +}; + +template <> +struct ReferenceHandler +{ + static cl_int retain(cl_kernel kernel) + { return ::clRetainKernel(kernel); } + static cl_int release(cl_kernel kernel) + { return ::clReleaseKernel(kernel); } +}; + +template <> +struct ReferenceHandler +{ + static cl_int retain(cl_event event) + { return ::clRetainEvent(event); } + static cl_int release(cl_event event) + { return ::clReleaseEvent(event); } +}; + + +// Extracts version number with major in the upper 16 bits, minor in the lower 16 +static cl_uint getVersion(const char *versionInfo) +{ + int highVersion = 0; + int lowVersion = 0; + int index = 7; + while(versionInfo[index] != '.' ) { + highVersion *= 10; + highVersion += versionInfo[index]-'0'; + ++index; + } + ++index; + while(versionInfo[index] != ' ' && versionInfo[index] != '\0') { + lowVersion *= 10; + lowVersion += versionInfo[index]-'0'; + ++index; + } + return (highVersion << 16) | lowVersion; +} + +static cl_uint getPlatformVersion(cl_platform_id platform) +{ + ::size_t size = 0; + clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, NULL, &size); + char *versionInfo = (char *) alloca(size); + clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, &versionInfo[0], &size); + return getVersion(versionInfo); +} + +static cl_uint getDevicePlatformVersion(cl_device_id device) +{ + cl_platform_id platform; + clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(platform), &platform, NULL); + return getPlatformVersion(platform); +} + +#if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) +static cl_uint getContextPlatformVersion(cl_context context) +{ + // The platform cannot be queried directly, so we first have to grab a + // device and obtain its context + ::size_t size = 0; + clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &size); + if (size == 0) + return 0; + cl_device_id *devices = (cl_device_id *) alloca(size); + clGetContextInfo(context, CL_CONTEXT_DEVICES, size, devices, NULL); + return getDevicePlatformVersion(devices[0]); +} +#endif // #if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) + +template +class Wrapper +{ +public: + typedef T cl_type; + +protected: + cl_type object_; + +public: + Wrapper() : object_(NULL) { } + + Wrapper(const cl_type &obj) : object_(obj) { } + + ~Wrapper() + { + if (object_ != NULL) { release(); } + } + + Wrapper(const Wrapper& rhs) + { + object_ = rhs.object_; + if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); } + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + Wrapper(Wrapper&& rhs) CL_HPP_NOEXCEPT + { + object_ = rhs.object_; + rhs.object_ = NULL; + } +#endif + + Wrapper& operator = (const Wrapper& rhs) + { + if (this != &rhs) { + if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } + object_ = rhs.object_; + if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); } + } + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + Wrapper& operator = (Wrapper&& rhs) + { + if (this != &rhs) { + if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } + object_ = rhs.object_; + rhs.object_ = NULL; + } + return *this; + } +#endif + + Wrapper& operator = (const cl_type &rhs) + { + if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } + object_ = rhs; + return *this; + } + + cl_type operator ()() const { return object_; } + + cl_type& operator ()() { return object_; } + +protected: + template + friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type); + + cl_int retain() const + { + return ReferenceHandler::retain(object_); + } + + cl_int release() const + { + return ReferenceHandler::release(object_); + } +}; + +template <> +class Wrapper +{ +public: + typedef cl_device_id cl_type; + +protected: + cl_type object_; + bool referenceCountable_; + + static bool isReferenceCountable(cl_device_id device) + { + bool retVal = false; + if (device != NULL) { + int version = getDevicePlatformVersion(device); + if(version > ((1 << 16) + 1)) { + retVal = true; + } + } + return retVal; + } + +public: + Wrapper() : object_(NULL), referenceCountable_(false) + { + } + + Wrapper(const cl_type &obj) : object_(obj), referenceCountable_(false) + { + referenceCountable_ = isReferenceCountable(obj); + } + + ~Wrapper() + { + if (object_ != NULL) { release(); } + } + + Wrapper(const Wrapper& rhs) + { + object_ = rhs.object_; + referenceCountable_ = isReferenceCountable(object_); + if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); } + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + Wrapper(Wrapper&& rhs) CL_HPP_NOEXCEPT + { + object_ = rhs.object_; + referenceCountable_ = rhs.referenceCountable_; + rhs.object_ = NULL; + rhs.referenceCountable_ = false; + } +#endif + + Wrapper& operator = (const Wrapper& rhs) + { + if (this != &rhs) { + if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } + object_ = rhs.object_; + referenceCountable_ = rhs.referenceCountable_; + if (object_ != NULL) { detail::errHandler(retain(), __RETAIN_ERR); } + } + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + Wrapper& operator = (Wrapper&& rhs) + { + if (this != &rhs) { + if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } + object_ = rhs.object_; + referenceCountable_ = rhs.referenceCountable_; + rhs.object_ = NULL; + rhs.referenceCountable_ = false; + } + return *this; + } +#endif + + Wrapper& operator = (const cl_type &rhs) + { + if (object_ != NULL) { detail::errHandler(release(), __RELEASE_ERR); } + object_ = rhs; + referenceCountable_ = isReferenceCountable(object_); + return *this; + } + + cl_type operator ()() const { return object_; } + + cl_type& operator ()() { return object_; } + +protected: + template + friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type); + + template + friend inline cl_int getInfoHelper(Func, cl_uint, VECTOR_CLASS*, int, typename U::cl_type); + + cl_int retain() const + { + if( referenceCountable_ ) { + return ReferenceHandler::retain(object_); + } + else { + return CL_SUCCESS; + } + } + + cl_int release() const + { + if( referenceCountable_ ) { + return ReferenceHandler::release(object_); + } + else { + return CL_SUCCESS; + } + } +}; + +} // namespace detail +//! \endcond + +/*! \stuct ImageFormat + * \brief Adds constructors and member functions for cl_image_format. + * + * \see cl_image_format + */ +struct ImageFormat : public cl_image_format +{ + //! \brief Default constructor - performs no initialization. + ImageFormat(){} + + //! \brief Initializing constructor. + ImageFormat(cl_channel_order order, cl_channel_type type) + { + image_channel_order = order; + image_channel_data_type = type; + } + + //! \brief Assignment operator. + ImageFormat& operator = (const ImageFormat& rhs) + { + if (this != &rhs) { + this->image_channel_data_type = rhs.image_channel_data_type; + this->image_channel_order = rhs.image_channel_order; + } + return *this; + } +}; + +/*! \brief Class interface for cl_device_id. + * + * \note Copies of these objects are inexpensive, since they don't 'own' + * any underlying resources or data structures. + * + * \see cl_device_id + */ +class Device : public detail::Wrapper +{ +public: + //! \brief Default constructor - initializes to NULL. + Device() : detail::Wrapper() { } + + /*! \brief Constructor from cl_device_id. + * + * This simply copies the device ID value, which is an inexpensive operation. + */ + __CL_EXPLICIT_CONSTRUCTORS Device(const cl_device_id &device) : detail::Wrapper(device) { } + + /*! \brief Returns the first device on the default context. + * + * \see Context::getDefault() + */ + static Device getDefault(cl_int * err = NULL); + + /*! \brief Assignment operator from cl_device_id. + * + * This simply copies the device ID value, which is an inexpensive operation. + */ + Device& operator = (const cl_device_id& rhs) + { + detail::Wrapper::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Device(const Device& dev) : detail::Wrapper(dev) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Device& operator = (const Device &dev) + { + detail::Wrapper::operator=(dev); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Device(Device&& dev) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(dev)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Device& operator = (Device &&dev) + { + detail::Wrapper::operator=(std::move(dev)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + + //! \brief Wrapper for clGetDeviceInfo(). + template + cl_int getInfo(cl_device_info name, T* param) const + { + return detail::errHandler( + detail::getInfo(&::clGetDeviceInfo, object_, name, param), + __GET_DEVICE_INFO_ERR); + } + + //! \brief Wrapper for clGetDeviceInfo() that returns by value. + template typename + detail::param_traits::param_type + getInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_device_info, name>::param_type param; + cl_int result = getInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + + /** + * CL 1.2 version + */ +#if defined(CL_VERSION_1_2) + //! \brief Wrapper for clCreateSubDevicesEXT(). + cl_int createSubDevices( + const cl_device_partition_property * properties, + VECTOR_CLASS* devices) + { + cl_uint n = 0; + cl_int err = clCreateSubDevices(object_, properties, 0, NULL, &n); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __CREATE_SUB_DEVICES); + } + + cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); + err = clCreateSubDevices(object_, properties, n, ids, NULL); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __CREATE_SUB_DEVICES); + } + + devices->assign(&ids[0], &ids[n]); + return CL_SUCCESS; + } +#endif // #if defined(CL_VERSION_1_2) + +/** + * CL 1.1 version that uses device fission. + */ +#if defined(CL_VERSION_1_1) +#if defined(USE_CL_DEVICE_FISSION) + cl_int createSubDevices( + const cl_device_partition_property_ext * properties, + VECTOR_CLASS* devices) + { + typedef CL_API_ENTRY cl_int + ( CL_API_CALL * PFN_clCreateSubDevicesEXT)( + cl_device_id /*in_device*/, + const cl_device_partition_property_ext * /* properties */, + cl_uint /*num_entries*/, + cl_device_id * /*out_devices*/, + cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1; + + static PFN_clCreateSubDevicesEXT pfn_clCreateSubDevicesEXT = NULL; + __INIT_CL_EXT_FCN_PTR(clCreateSubDevicesEXT); + + cl_uint n = 0; + cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, NULL, &n); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __CREATE_SUB_DEVICES); + } + + cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); + err = pfn_clCreateSubDevicesEXT(object_, properties, n, ids, NULL); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __CREATE_SUB_DEVICES); + } + + devices->assign(&ids[0], &ids[n]); + return CL_SUCCESS; + } +#endif // #if defined(USE_CL_DEVICE_FISSION) +#endif // #if defined(CL_VERSION_1_1) +}; + +/*! \brief Class interface for cl_platform_id. + * + * \note Copies of these objects are inexpensive, since they don't 'own' + * any underlying resources or data structures. + * + * \see cl_platform_id + */ +class Platform : public detail::Wrapper +{ +public: + //! \brief Default constructor - initializes to NULL. + Platform() : detail::Wrapper() { } + + /*! \brief Constructor from cl_platform_id. + * + * This simply copies the platform ID value, which is an inexpensive operation. + */ + __CL_EXPLICIT_CONSTRUCTORS Platform(const cl_platform_id &platform) : detail::Wrapper(platform) { } + + /*! \brief Assignment operator from cl_platform_id. + * + * This simply copies the platform ID value, which is an inexpensive operation. + */ + Platform& operator = (const cl_platform_id& rhs) + { + detail::Wrapper::operator=(rhs); + return *this; + } + + //! \brief Wrapper for clGetPlatformInfo(). + cl_int getInfo(cl_platform_info name, STRING_CLASS* param) const + { + return detail::errHandler( + detail::getInfo(&::clGetPlatformInfo, object_, name, param), + __GET_PLATFORM_INFO_ERR); + } + + //! \brief Wrapper for clGetPlatformInfo() that returns by value. + template typename + detail::param_traits::param_type + getInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_platform_info, name>::param_type param; + cl_int result = getInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + + /*! \brief Gets a list of devices for this platform. + * + * Wraps clGetDeviceIDs(). + */ + cl_int getDevices( + cl_device_type type, + VECTOR_CLASS* devices) const + { + cl_uint n = 0; + if( devices == NULL ) { + return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR); + } + cl_int err = ::clGetDeviceIDs(object_, type, 0, NULL, &n); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_DEVICE_IDS_ERR); + } + + cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); + err = ::clGetDeviceIDs(object_, type, n, ids, NULL); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_DEVICE_IDS_ERR); + } + + devices->assign(&ids[0], &ids[n]); + return CL_SUCCESS; + } + +#if defined(USE_DX_INTEROP) + /*! \brief Get the list of available D3D10 devices. + * + * \param d3d_device_source. + * + * \param d3d_object. + * + * \param d3d_device_set. + * + * \param devices returns a vector of OpenCL D3D10 devices found. The cl::Device + * values returned in devices can be used to identify a specific OpenCL + * device. If \a devices argument is NULL, this argument is ignored. + * + * \return One of the following values: + * - CL_SUCCESS if the function is executed successfully. + * + * The application can query specific capabilities of the OpenCL device(s) + * returned by cl::getDevices. This can be used by the application to + * determine which device(s) to use. + * + * \note In the case that exceptions are enabled and a return value + * other than CL_SUCCESS is generated, then cl::Error exception is + * generated. + */ + cl_int getDevices( + cl_d3d10_device_source_khr d3d_device_source, + void * d3d_object, + cl_d3d10_device_set_khr d3d_device_set, + VECTOR_CLASS* devices) const + { + typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)( + cl_platform_id platform, + cl_d3d10_device_source_khr d3d_device_source, + void * d3d_object, + cl_d3d10_device_set_khr d3d_device_set, + cl_uint num_entries, + cl_device_id * devices, + cl_uint* num_devices); + + if( devices == NULL ) { + return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR); + } + + static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = NULL; + __INIT_CL_EXT_FCN_PTR_PLATFORM(object_, clGetDeviceIDsFromD3D10KHR); + + cl_uint n = 0; + cl_int err = pfn_clGetDeviceIDsFromD3D10KHR( + object_, + d3d_device_source, + d3d_object, + d3d_device_set, + 0, + NULL, + &n); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_DEVICE_IDS_ERR); + } + + cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); + err = pfn_clGetDeviceIDsFromD3D10KHR( + object_, + d3d_device_source, + d3d_object, + d3d_device_set, + n, + ids, + NULL); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_DEVICE_IDS_ERR); + } + + devices->assign(&ids[0], &ids[n]); + return CL_SUCCESS; + } +#endif + + /*! \brief Gets a list of available platforms. + * + * Wraps clGetPlatformIDs(). + */ + static cl_int get( + VECTOR_CLASS* platforms) + { + cl_uint n = 0; + + if( platforms == NULL ) { + return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR); + } + + cl_int err = ::clGetPlatformIDs(0, NULL, &n); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); + } + + cl_platform_id* ids = (cl_platform_id*) alloca( + n * sizeof(cl_platform_id)); + err = ::clGetPlatformIDs(n, ids, NULL); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); + } + + platforms->assign(&ids[0], &ids[n]); + return CL_SUCCESS; + } + + /*! \brief Gets the first available platform. + * + * Wraps clGetPlatformIDs(), returning the first result. + */ + static cl_int get( + Platform * platform) + { + cl_uint n = 0; + + if( platform == NULL ) { + return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR); + } + + cl_int err = ::clGetPlatformIDs(0, NULL, &n); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); + } + + cl_platform_id* ids = (cl_platform_id*) alloca( + n * sizeof(cl_platform_id)); + err = ::clGetPlatformIDs(n, ids, NULL); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); + } + + *platform = ids[0]; + return CL_SUCCESS; + } + + /*! \brief Gets the first available platform, returning it by value. + * + * Wraps clGetPlatformIDs(), returning the first result. + */ + static Platform get( + cl_int * errResult = NULL) + { + Platform platform; + cl_uint n = 0; + cl_int err = ::clGetPlatformIDs(0, NULL, &n); + if (err != CL_SUCCESS) { + detail::errHandler(err, __GET_PLATFORM_IDS_ERR); + if (errResult != NULL) { + *errResult = err; + } + return Platform(); + } + + cl_platform_id* ids = (cl_platform_id*) alloca( + n * sizeof(cl_platform_id)); + err = ::clGetPlatformIDs(n, ids, NULL); + + if (err != CL_SUCCESS) { + detail::errHandler(err, __GET_PLATFORM_IDS_ERR); + if (errResult != NULL) { + *errResult = err; + } + return Platform(); + } + + + return Platform(ids[0]); + } + + static Platform getDefault( + cl_int *errResult = NULL ) + { + return get(errResult); + } + + +#if defined(CL_VERSION_1_2) + //! \brief Wrapper for clUnloadCompiler(). + cl_int + unloadCompiler() + { + return ::clUnloadPlatformCompiler(object_); + } +#endif // #if defined(CL_VERSION_1_2) +}; // class Platform + +/** + * Deprecated APIs for 1.2 + */ +#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) +/** + * Unload the OpenCL compiler. + * \note Deprecated for OpenCL 1.2. Use Platform::unloadCompiler instead. + */ +inline CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int +UnloadCompiler() CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; +inline cl_int +UnloadCompiler() +{ + return ::clUnloadCompiler(); +} +#endif // #if defined(CL_VERSION_1_1) + +/*! \brief Class interface for cl_context. + * + * \note Copies of these objects are shallow, meaning that the copy will refer + * to the same underlying cl_context as the original. For details, see + * clRetainContext() and clReleaseContext(). + * + * \see cl_context + */ +class Context + : public detail::Wrapper +{ +private: + +#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED + static std::atomic default_initialized_; +#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED + static volatile int default_initialized_; +#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED + static Context default_; + static volatile cl_int default_error_; +public: + /*! \brief Constructs a context including a list of specified devices. + * + * Wraps clCreateContext(). + */ + Context( + const VECTOR_CLASS& devices, + cl_context_properties* properties = NULL, + void (CL_CALLBACK * notifyFptr)( + const char *, + const void *, + ::size_t, + void *) = NULL, + void* data = NULL, + cl_int* err = NULL) + { + cl_int error; + + ::size_t numDevices = devices.size(); + cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id)); + for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) { + deviceIDs[deviceIndex] = (devices[deviceIndex])(); + } + + object_ = ::clCreateContext( + properties, (cl_uint) numDevices, + deviceIDs, + notifyFptr, data, &error); + + detail::errHandler(error, __CREATE_CONTEXT_ERR); + if (err != NULL) { + *err = error; + } + } + + Context( + const Device& device, + cl_context_properties* properties = NULL, + void (CL_CALLBACK * notifyFptr)( + const char *, + const void *, + ::size_t, + void *) = NULL, + void* data = NULL, + cl_int* err = NULL) + { + cl_int error; + + cl_device_id deviceID = device(); + + object_ = ::clCreateContext( + properties, 1, + &deviceID, + notifyFptr, data, &error); + + detail::errHandler(error, __CREATE_CONTEXT_ERR); + if (err != NULL) { + *err = error; + } + } + + /*! \brief Constructs a context including all or a subset of devices of a specified type. + * + * Wraps clCreateContextFromType(). + */ + Context( + cl_device_type type, + cl_context_properties* properties = NULL, + void (CL_CALLBACK * notifyFptr)( + const char *, + const void *, + ::size_t, + void *) = NULL, + void* data = NULL, + cl_int* err = NULL) + { + cl_int error; + +#if !defined(__APPLE__) && !defined(__MACOS) + cl_context_properties prop[4] = {CL_CONTEXT_PLATFORM, 0, 0, 0 }; + + if (properties == NULL) { + // Get a valid platform ID as we cannot send in a blank one + VECTOR_CLASS platforms; + error = Platform::get(&platforms); + if (error != CL_SUCCESS) { + detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR); + if (err != NULL) { + *err = error; + } + return; + } + + // Check the platforms we found for a device of our specified type + cl_context_properties platform_id = 0; + for (unsigned int i = 0; i < platforms.size(); i++) { + + VECTOR_CLASS devices; + +#if defined(__CL_ENABLE_EXCEPTIONS) + try { +#endif + + error = platforms[i].getDevices(type, &devices); + +#if defined(__CL_ENABLE_EXCEPTIONS) + } catch (Error) {} + // Catch if exceptions are enabled as we don't want to exit if first platform has no devices of type + // We do error checking next anyway, and can throw there if needed +#endif + + // Only squash CL_SUCCESS and CL_DEVICE_NOT_FOUND + if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND) { + detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR); + if (err != NULL) { + *err = error; + } + } + + if (devices.size() > 0) { + platform_id = (cl_context_properties)platforms[i](); + break; + } + } + + if (platform_id == 0) { + detail::errHandler(CL_DEVICE_NOT_FOUND, __CREATE_CONTEXT_FROM_TYPE_ERR); + if (err != NULL) { + *err = CL_DEVICE_NOT_FOUND; + } + return; + } + + prop[1] = platform_id; + properties = &prop[0]; + } +#endif + object_ = ::clCreateContextFromType( + properties, type, notifyFptr, data, &error); + + detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR); + if (err != NULL) { + *err = error; + } + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Context(const Context& ctx) : detail::Wrapper(ctx) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Context& operator = (const Context &ctx) + { + detail::Wrapper::operator=(ctx); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Context(Context&& ctx) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(ctx)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Context& operator = (Context &&ctx) + { + detail::Wrapper::operator=(std::move(ctx)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + + /*! \brief Returns a singleton context including all devices of CL_DEVICE_TYPE_DEFAULT. + * + * \note All calls to this function return the same cl_context as the first. + */ + static Context getDefault(cl_int * err = NULL) + { + int state = detail::compare_exchange( + &default_initialized_, + __DEFAULT_BEING_INITIALIZED, __DEFAULT_NOT_INITIALIZED); + + if (state & __DEFAULT_INITIALIZED) { + if (err != NULL) { + *err = default_error_; + } + return default_; + } + + if (state & __DEFAULT_BEING_INITIALIZED) { + // Assume writes will propagate eventually... + while(default_initialized_ != __DEFAULT_INITIALIZED) { + detail::fence(); + } + + if (err != NULL) { + *err = default_error_; + } + return default_; + } + + cl_int error; + default_ = Context( + CL_DEVICE_TYPE_DEFAULT, + NULL, + NULL, + NULL, + &error); + + detail::fence(); + + default_error_ = error; + // Assume writes will propagate eventually... + default_initialized_ = __DEFAULT_INITIALIZED; + + detail::fence(); + + if (err != NULL) { + *err = default_error_; + } + return default_; + + } + + //! \brief Default constructor - initializes to NULL. + Context() : detail::Wrapper() { } + + /*! \brief Constructor from cl_context - takes ownership. + * + * This effectively transfers ownership of a refcount on the cl_context + * into the new Context object. + */ + __CL_EXPLICIT_CONSTRUCTORS Context(const cl_context& context) : detail::Wrapper(context) { } + + /*! \brief Assignment operator from cl_context - takes ownership. + * + * This effectively transfers ownership of a refcount on the rhs and calls + * clReleaseContext() on the value previously held by this instance. + */ + Context& operator = (const cl_context& rhs) + { + detail::Wrapper::operator=(rhs); + return *this; + } + + //! \brief Wrapper for clGetContextInfo(). + template + cl_int getInfo(cl_context_info name, T* param) const + { + return detail::errHandler( + detail::getInfo(&::clGetContextInfo, object_, name, param), + __GET_CONTEXT_INFO_ERR); + } + + //! \brief Wrapper for clGetContextInfo() that returns by value. + template typename + detail::param_traits::param_type + getInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_context_info, name>::param_type param; + cl_int result = getInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + + /*! \brief Gets a list of supported image formats. + * + * Wraps clGetSupportedImageFormats(). + */ + cl_int getSupportedImageFormats( + cl_mem_flags flags, + cl_mem_object_type type, + VECTOR_CLASS* formats) const + { + cl_uint numEntries; + + if (!formats) { + return CL_SUCCESS; + } + + cl_int err = ::clGetSupportedImageFormats( + object_, + flags, + type, + 0, + NULL, + &numEntries); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR); + } + + if (numEntries > 0) { + ImageFormat* value = (ImageFormat*) + alloca(numEntries * sizeof(ImageFormat)); + err = ::clGetSupportedImageFormats( + object_, + flags, + type, + numEntries, + (cl_image_format*)value, + NULL); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR); + } + + formats->assign(&value[0], &value[numEntries]); + } + else { + formats->clear(); + } + return CL_SUCCESS; + } +}; + +inline Device Device::getDefault(cl_int * err) +{ + cl_int error; + Device device; + + Context context = Context::getDefault(&error); + detail::errHandler(error, __CREATE_CONTEXT_ERR); + + if (error != CL_SUCCESS) { + if (err != NULL) { + *err = error; + } + } + else { + device = context.getInfo()[0]; + if (err != NULL) { + *err = CL_SUCCESS; + } + } + + return device; +} + + +#ifdef _WIN32 +#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED +__declspec(selectany) std::atomic Context::default_initialized_; +#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED +__declspec(selectany) volatile int Context::default_initialized_ = __DEFAULT_NOT_INITIALIZED; +#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED +__declspec(selectany) Context Context::default_; +__declspec(selectany) volatile cl_int Context::default_error_ = CL_SUCCESS; +#else // !_WIN32 +#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED +__attribute__((weak)) std::atomic Context::default_initialized_; +#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED +__attribute__((weak)) volatile int Context::default_initialized_ = __DEFAULT_NOT_INITIALIZED; +#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED +__attribute__((weak)) Context Context::default_; +__attribute__((weak)) volatile cl_int Context::default_error_ = CL_SUCCESS; +#endif // !_WIN32 + +/*! \brief Class interface for cl_event. + * + * \note Copies of these objects are shallow, meaning that the copy will refer + * to the same underlying cl_event as the original. For details, see + * clRetainEvent() and clReleaseEvent(). + * + * \see cl_event + */ +class Event : public detail::Wrapper +{ +public: + //! \brief Default constructor - initializes to NULL. + Event() : detail::Wrapper() { } + + /*! \brief Constructor from cl_event - takes ownership. + * + * This effectively transfers ownership of a refcount on the cl_event + * into the new Event object. + */ + __CL_EXPLICIT_CONSTRUCTORS Event(const cl_event& event) : detail::Wrapper(event) { } + + /*! \brief Assignment operator from cl_event - takes ownership. + * + * This effectively transfers ownership of a refcount on the rhs and calls + * clReleaseEvent() on the value previously held by this instance. + */ + Event& operator = (const cl_event& rhs) + { + detail::Wrapper::operator=(rhs); + return *this; + } + + //! \brief Wrapper for clGetEventInfo(). + template + cl_int getInfo(cl_event_info name, T* param) const + { + return detail::errHandler( + detail::getInfo(&::clGetEventInfo, object_, name, param), + __GET_EVENT_INFO_ERR); + } + + //! \brief Wrapper for clGetEventInfo() that returns by value. + template typename + detail::param_traits::param_type + getInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_event_info, name>::param_type param; + cl_int result = getInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + + //! \brief Wrapper for clGetEventProfilingInfo(). + template + cl_int getProfilingInfo(cl_profiling_info name, T* param) const + { + return detail::errHandler(detail::getInfo( + &::clGetEventProfilingInfo, object_, name, param), + __GET_EVENT_PROFILE_INFO_ERR); + } + + //! \brief Wrapper for clGetEventProfilingInfo() that returns by value. + template typename + detail::param_traits::param_type + getProfilingInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_profiling_info, name>::param_type param; + cl_int result = getProfilingInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + + /*! \brief Blocks the calling thread until this event completes. + * + * Wraps clWaitForEvents(). + */ + cl_int wait() const + { + return detail::errHandler( + ::clWaitForEvents(1, &object_), + __WAIT_FOR_EVENTS_ERR); + } + +#if defined(CL_VERSION_1_1) + /*! \brief Registers a user callback function for a specific command execution status. + * + * Wraps clSetEventCallback(). + */ + cl_int setCallback( + cl_int type, + void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *), + void * user_data = NULL) + { + return detail::errHandler( + ::clSetEventCallback( + object_, + type, + pfn_notify, + user_data), + __SET_EVENT_CALLBACK_ERR); + } +#endif + + /*! \brief Blocks the calling thread until every event specified is complete. + * + * Wraps clWaitForEvents(). + */ + static cl_int + waitForEvents(const VECTOR_CLASS& events) + { + return detail::errHandler( + ::clWaitForEvents( + (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : NULL), + __WAIT_FOR_EVENTS_ERR); + } +}; + +#if defined(CL_VERSION_1_1) +/*! \brief Class interface for user events (a subset of cl_event's). + * + * See Event for details about copy semantics, etc. + */ +class UserEvent : public Event +{ +public: + /*! \brief Constructs a user event on a given context. + * + * Wraps clCreateUserEvent(). + */ + UserEvent( + const Context& context, + cl_int * err = NULL) + { + cl_int error; + object_ = ::clCreateUserEvent( + context(), + &error); + + detail::errHandler(error, __CREATE_USER_EVENT_ERR); + if (err != NULL) { + *err = error; + } + } + + //! \brief Default constructor - initializes to NULL. + UserEvent() : Event() { } + + /*! \brief Sets the execution status of a user event object. + * + * Wraps clSetUserEventStatus(). + */ + cl_int setStatus(cl_int status) + { + return detail::errHandler( + ::clSetUserEventStatus(object_,status), + __SET_USER_EVENT_STATUS_ERR); + } +}; +#endif + +/*! \brief Blocks the calling thread until every event specified is complete. + * + * Wraps clWaitForEvents(). + */ +inline static cl_int +WaitForEvents(const VECTOR_CLASS& events) +{ + return detail::errHandler( + ::clWaitForEvents( + (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : NULL), + __WAIT_FOR_EVENTS_ERR); +} + +/*! \brief Class interface for cl_mem. + * + * \note Copies of these objects are shallow, meaning that the copy will refer + * to the same underlying cl_mem as the original. For details, see + * clRetainMemObject() and clReleaseMemObject(). + * + * \see cl_mem + */ +class Memory : public detail::Wrapper +{ +public: + //! \brief Default constructor - initializes to NULL. + Memory() : detail::Wrapper() { } + + /*! \brief Constructor from cl_mem - takes ownership. + * + * This effectively transfers ownership of a refcount on the cl_mem + * into the new Memory object. + */ + __CL_EXPLICIT_CONSTRUCTORS Memory(const cl_mem& memory) : detail::Wrapper(memory) { } + + /*! \brief Assignment operator from cl_mem - takes ownership. + * + * This effectively transfers ownership of a refcount on the rhs and calls + * clReleaseMemObject() on the value previously held by this instance. + */ + Memory& operator = (const cl_mem& rhs) + { + detail::Wrapper::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Memory(const Memory& mem) : detail::Wrapper(mem) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Memory& operator = (const Memory &mem) + { + detail::Wrapper::operator=(mem); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Memory(Memory&& mem) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(mem)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Memory& operator = (Memory &&mem) + { + detail::Wrapper::operator=(std::move(mem)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + + //! \brief Wrapper for clGetMemObjectInfo(). + template + cl_int getInfo(cl_mem_info name, T* param) const + { + return detail::errHandler( + detail::getInfo(&::clGetMemObjectInfo, object_, name, param), + __GET_MEM_OBJECT_INFO_ERR); + } + + //! \brief Wrapper for clGetMemObjectInfo() that returns by value. + template typename + detail::param_traits::param_type + getInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_mem_info, name>::param_type param; + cl_int result = getInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + +#if defined(CL_VERSION_1_1) + /*! \brief Registers a callback function to be called when the memory object + * is no longer needed. + * + * Wraps clSetMemObjectDestructorCallback(). + * + * Repeated calls to this function, for a given cl_mem value, will append + * to the list of functions called (in reverse order) when memory object's + * resources are freed and the memory object is deleted. + * + * \note + * The registered callbacks are associated with the underlying cl_mem + * value - not the Memory class instance. + */ + cl_int setDestructorCallback( + void (CL_CALLBACK * pfn_notify)(cl_mem, void *), + void * user_data = NULL) + { + return detail::errHandler( + ::clSetMemObjectDestructorCallback( + object_, + pfn_notify, + user_data), + __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR); + } +#endif + +}; + +// Pre-declare copy functions +class Buffer; +template< typename IteratorType > +cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer ); +template< typename IteratorType > +cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator ); +template< typename IteratorType > +cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer ); +template< typename IteratorType > +cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator ); + + +/*! \brief Class interface for Buffer Memory Objects. + * + * See Memory for details about copy semantics, etc. + * + * \see Memory + */ +class Buffer : public Memory +{ +public: + + /*! \brief Constructs a Buffer in a specified context. + * + * Wraps clCreateBuffer(). + * + * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was + * specified. Note alignment & exclusivity requirements. + */ + Buffer( + const Context& context, + cl_mem_flags flags, + ::size_t size, + void* host_ptr = NULL, + cl_int* err = NULL) + { + cl_int error; + object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error); + + detail::errHandler(error, __CREATE_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + } + + /*! \brief Constructs a Buffer in the default context. + * + * Wraps clCreateBuffer(). + * + * \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was + * specified. Note alignment & exclusivity requirements. + * + * \see Context::getDefault() + */ + Buffer( + cl_mem_flags flags, + ::size_t size, + void* host_ptr = NULL, + cl_int* err = NULL) + { + cl_int error; + + Context context = Context::getDefault(err); + + object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error); + + detail::errHandler(error, __CREATE_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + } + + /*! + * \brief Construct a Buffer from a host container via iterators. + * IteratorType must be random access. + * If useHostPtr is specified iterators must represent contiguous data. + */ + template< typename IteratorType > + Buffer( + IteratorType startIterator, + IteratorType endIterator, + bool readOnly, + bool useHostPtr = false, + cl_int* err = NULL) + { + typedef typename std::iterator_traits::value_type DataType; + cl_int error; + + cl_mem_flags flags = 0; + if( readOnly ) { + flags |= CL_MEM_READ_ONLY; + } + else { + flags |= CL_MEM_READ_WRITE; + } + if( useHostPtr ) { + flags |= CL_MEM_USE_HOST_PTR; + } + + ::size_t size = sizeof(DataType)*(endIterator - startIterator); + + Context context = Context::getDefault(err); + + if( useHostPtr ) { + object_ = ::clCreateBuffer(context(), flags, size, static_cast(&*startIterator), &error); + } else { + object_ = ::clCreateBuffer(context(), flags, size, 0, &error); + } + + detail::errHandler(error, __CREATE_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + + if( !useHostPtr ) { + error = cl::copy(startIterator, endIterator, *this); + detail::errHandler(error, __CREATE_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + } + } + + /*! + * \brief Construct a Buffer from a host container via iterators using a specified context. + * IteratorType must be random access. + * If useHostPtr is specified iterators must represent contiguous data. + */ + template< typename IteratorType > + Buffer(const Context &context, IteratorType startIterator, IteratorType endIterator, + bool readOnly, bool useHostPtr = false, cl_int* err = NULL); + + /*! + * \brief Construct a Buffer from a host container via iterators using a specified queue. + * If useHostPtr is specified iterators must represent contiguous data. + */ + template< typename IteratorType > + Buffer(const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, + bool readOnly, bool useHostPtr = false, cl_int* err = NULL); + + //! \brief Default constructor - initializes to NULL. + Buffer() : Memory() { } + + /*! \brief Constructor from cl_mem - takes ownership. + * + * See Memory for further details. + */ + __CL_EXPLICIT_CONSTRUCTORS Buffer(const cl_mem& buffer) : Memory(buffer) { } + + /*! \brief Assignment from cl_mem - performs shallow copy. + * + * See Memory for further details. + */ + Buffer& operator = (const cl_mem& rhs) + { + Memory::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Buffer(const Buffer& buf) : Memory(buf) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Buffer& operator = (const Buffer &buf) + { + Memory::operator=(buf); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Buffer(Buffer&& buf) CL_HPP_NOEXCEPT : Memory(std::move(buf)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Buffer& operator = (Buffer &&buf) + { + Memory::operator=(std::move(buf)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + +#if defined(CL_VERSION_1_1) + /*! \brief Creates a new buffer object from this. + * + * Wraps clCreateSubBuffer(). + */ + Buffer createSubBuffer( + cl_mem_flags flags, + cl_buffer_create_type buffer_create_type, + const void * buffer_create_info, + cl_int * err = NULL) + { + Buffer result; + cl_int error; + result.object_ = ::clCreateSubBuffer( + object_, + flags, + buffer_create_type, + buffer_create_info, + &error); + + detail::errHandler(error, __CREATE_SUBBUFFER_ERR); + if (err != NULL) { + *err = error; + } + + return result; + } +#endif +}; + +#if defined (USE_DX_INTEROP) +/*! \brief Class interface for creating OpenCL buffers from ID3D10Buffer's. + * + * This is provided to facilitate interoperability with Direct3D. + * + * See Memory for details about copy semantics, etc. + * + * \see Memory + */ +class BufferD3D10 : public Buffer +{ +public: + typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)( + cl_context context, cl_mem_flags flags, ID3D10Buffer* buffer, + cl_int* errcode_ret); + + /*! \brief Constructs a BufferD3D10, in a specified context, from a + * given ID3D10Buffer. + * + * Wraps clCreateFromD3D10BufferKHR(). + */ + BufferD3D10( + const Context& context, + cl_mem_flags flags, + ID3D10Buffer* bufobj, + cl_int * err = NULL) + { + static PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR = NULL; + +#if defined(CL_VERSION_1_2) + vector props = context.getInfo(); + cl_platform platform = -1; + for( int i = 0; i < props.size(); ++i ) { + if( props[i] == CL_CONTEXT_PLATFORM ) { + platform = props[i+1]; + } + } + __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, clCreateFromD3D10BufferKHR); +#endif +#if defined(CL_VERSION_1_1) + __INIT_CL_EXT_FCN_PTR(clCreateFromD3D10BufferKHR); +#endif + + cl_int error; + object_ = pfn_clCreateFromD3D10BufferKHR( + context(), + flags, + bufobj, + &error); + + detail::errHandler(error, __CREATE_GL_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + } + + //! \brief Default constructor - initializes to NULL. + BufferD3D10() : Buffer() { } + + /*! \brief Constructor from cl_mem - takes ownership. + * + * See Memory for further details. + */ + __CL_EXPLICIT_CONSTRUCTORS BufferD3D10(const cl_mem& buffer) : Buffer(buffer) { } + + /*! \brief Assignment from cl_mem - performs shallow copy. + * + * See Memory for further details. + */ + BufferD3D10& operator = (const cl_mem& rhs) + { + Buffer::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + BufferD3D10(const BufferD3D10& buf) : Buffer(buf) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + BufferD3D10& operator = (const BufferD3D10 &buf) + { + Buffer::operator=(buf); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + BufferD3D10(BufferD3D10&& buf) CL_HPP_NOEXCEPT : Buffer(std::move(buf)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + BufferD3D10& operator = (BufferD3D10 &&buf) + { + Buffer::operator=(std::move(buf)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) +}; +#endif + +/*! \brief Class interface for GL Buffer Memory Objects. + * + * This is provided to facilitate interoperability with OpenGL. + * + * See Memory for details about copy semantics, etc. + * + * \see Memory + */ +class BufferGL : public Buffer +{ +public: + /*! \brief Constructs a BufferGL in a specified context, from a given + * GL buffer. + * + * Wraps clCreateFromGLBuffer(). + */ + BufferGL( + const Context& context, + cl_mem_flags flags, + cl_GLuint bufobj, + cl_int * err = NULL) + { + cl_int error; + object_ = ::clCreateFromGLBuffer( + context(), + flags, + bufobj, + &error); + + detail::errHandler(error, __CREATE_GL_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + } + + //! \brief Default constructor - initializes to NULL. + BufferGL() : Buffer() { } + + /*! \brief Constructor from cl_mem - takes ownership. + * + * See Memory for further details. + */ + __CL_EXPLICIT_CONSTRUCTORS BufferGL(const cl_mem& buffer) : Buffer(buffer) { } + + /*! \brief Assignment from cl_mem - performs shallow copy. + * + * See Memory for further details. + */ + BufferGL& operator = (const cl_mem& rhs) + { + Buffer::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + BufferGL(const BufferGL& buf) : Buffer(buf) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + BufferGL& operator = (const BufferGL &buf) + { + Buffer::operator=(buf); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + BufferGL(BufferGL&& buf) CL_HPP_NOEXCEPT : Buffer(std::move(buf)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + BufferGL& operator = (BufferGL &&buf) + { + Buffer::operator=(std::move(buf)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + + //! \brief Wrapper for clGetGLObjectInfo(). + cl_int getObjectInfo( + cl_gl_object_type *type, + cl_GLuint * gl_object_name) + { + return detail::errHandler( + ::clGetGLObjectInfo(object_,type,gl_object_name), + __GET_GL_OBJECT_INFO_ERR); + } +}; + +/*! \brief C++ base class for Image Memory objects. + * + * See Memory for details about copy semantics, etc. + * + * \see Memory + */ +class Image : public Memory +{ +protected: + //! \brief Default constructor - initializes to NULL. + Image() : Memory() { } + + /*! \brief Constructor from cl_mem - takes ownership. + * + * See Memory for further details. + */ + __CL_EXPLICIT_CONSTRUCTORS Image(const cl_mem& image) : Memory(image) { } + + /*! \brief Assignment from cl_mem - performs shallow copy. + * + * See Memory for further details. + */ + Image& operator = (const cl_mem& rhs) + { + Memory::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image(const Image& img) : Memory(img) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image& operator = (const Image &img) + { + Memory::operator=(img); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Image(Image&& img) CL_HPP_NOEXCEPT : Memory(std::move(img)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Image& operator = (Image &&img) + { + Memory::operator=(std::move(img)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + +public: + //! \brief Wrapper for clGetImageInfo(). + template + cl_int getImageInfo(cl_image_info name, T* param) const + { + return detail::errHandler( + detail::getInfo(&::clGetImageInfo, object_, name, param), + __GET_IMAGE_INFO_ERR); + } + + //! \brief Wrapper for clGetImageInfo() that returns by value. + template typename + detail::param_traits::param_type + getImageInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_image_info, name>::param_type param; + cl_int result = getImageInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } +}; + +#if defined(CL_VERSION_1_2) +/*! \brief Class interface for 1D Image Memory objects. + * + * See Memory for details about copy semantics, etc. + * + * \see Memory + */ +class Image1D : public Image +{ +public: + /*! \brief Constructs a 1D Image in a specified context. + * + * Wraps clCreateImage(). + */ + Image1D( + const Context& context, + cl_mem_flags flags, + ImageFormat format, + ::size_t width, + void* host_ptr = NULL, + cl_int* err = NULL) + { + cl_int error; + cl_image_desc desc = + { + CL_MEM_OBJECT_IMAGE1D, + width, + 0, 0, 0, 0, 0, 0, 0, 0 + }; + object_ = ::clCreateImage( + context(), + flags, + &format, + &desc, + host_ptr, + &error); + + detail::errHandler(error, __CREATE_IMAGE_ERR); + if (err != NULL) { + *err = error; + } + } + + //! \brief Default constructor - initializes to NULL. + Image1D() { } + + /*! \brief Constructor from cl_mem - takes ownership. + * + * See Memory for further details. + */ + __CL_EXPLICIT_CONSTRUCTORS Image1D(const cl_mem& image1D) : Image(image1D) { } + + /*! \brief Assignment from cl_mem - performs shallow copy. + * + * See Memory for further details. + */ + Image1D& operator = (const cl_mem& rhs) + { + Image::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image1D(const Image1D& img) : Image(img) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image1D& operator = (const Image1D &img) + { + Image::operator=(img); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Image1D(Image1D&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Image1D& operator = (Image1D &&img) + { + Image::operator=(std::move(img)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) +}; + +/*! \class Image1DBuffer + * \brief Image interface for 1D buffer images. + */ +class Image1DBuffer : public Image +{ +public: + Image1DBuffer( + const Context& context, + cl_mem_flags flags, + ImageFormat format, + ::size_t width, + const Buffer &buffer, + cl_int* err = NULL) + { + cl_int error; + cl_image_desc desc = + { + CL_MEM_OBJECT_IMAGE1D_BUFFER, + width, + 0, 0, 0, 0, 0, 0, 0, + buffer() + }; + object_ = ::clCreateImage( + context(), + flags, + &format, + &desc, + NULL, + &error); + + detail::errHandler(error, __CREATE_IMAGE_ERR); + if (err != NULL) { + *err = error; + } + } + + Image1DBuffer() { } + + __CL_EXPLICIT_CONSTRUCTORS Image1DBuffer(const cl_mem& image1D) : Image(image1D) { } + + Image1DBuffer& operator = (const cl_mem& rhs) + { + Image::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image1DBuffer(const Image1DBuffer& img) : Image(img) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image1DBuffer& operator = (const Image1DBuffer &img) + { + Image::operator=(img); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Image1DBuffer(Image1DBuffer&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Image1DBuffer& operator = (Image1DBuffer &&img) + { + Image::operator=(std::move(img)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) +}; + +/*! \class Image1DArray + * \brief Image interface for arrays of 1D images. + */ +class Image1DArray : public Image +{ +public: + Image1DArray( + const Context& context, + cl_mem_flags flags, + ImageFormat format, + ::size_t arraySize, + ::size_t width, + ::size_t rowPitch, + void* host_ptr = NULL, + cl_int* err = NULL) + { + cl_int error; + cl_image_desc desc = + { + CL_MEM_OBJECT_IMAGE1D_ARRAY, + width, + 0, 0, // height, depth (unused) + arraySize, + rowPitch, + 0, 0, 0, 0 + }; + object_ = ::clCreateImage( + context(), + flags, + &format, + &desc, + host_ptr, + &error); + + detail::errHandler(error, __CREATE_IMAGE_ERR); + if (err != NULL) { + *err = error; + } + } + + Image1DArray() { } + + __CL_EXPLICIT_CONSTRUCTORS Image1DArray(const cl_mem& imageArray) : Image(imageArray) { } + + Image1DArray& operator = (const cl_mem& rhs) + { + Image::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image1DArray(const Image1DArray& img) : Image(img) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image1DArray& operator = (const Image1DArray &img) + { + Image::operator=(img); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Image1DArray(Image1DArray&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Image1DArray& operator = (Image1DArray &&img) + { + Image::operator=(std::move(img)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) +}; +#endif // #if defined(CL_VERSION_1_2) + + +/*! \brief Class interface for 2D Image Memory objects. + * + * See Memory for details about copy semantics, etc. + * + * \see Memory + */ +class Image2D : public Image +{ +public: + /*! \brief Constructs a 1D Image in a specified context. + * + * Wraps clCreateImage(). + */ + Image2D( + const Context& context, + cl_mem_flags flags, + ImageFormat format, + ::size_t width, + ::size_t height, + ::size_t row_pitch = 0, + void* host_ptr = NULL, + cl_int* err = NULL) + { + cl_int error; + bool useCreateImage; + +#if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) + // Run-time decision based on the actual platform + { + cl_uint version = detail::getContextPlatformVersion(context()); + useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above + } +#elif defined(CL_VERSION_1_2) + useCreateImage = true; +#else + useCreateImage = false; +#endif + +#if defined(CL_VERSION_1_2) + if (useCreateImage) + { + cl_image_desc desc = + { + CL_MEM_OBJECT_IMAGE2D, + width, + height, + 0, 0, // depth, array size (unused) + row_pitch, + 0, 0, 0, 0 + }; + object_ = ::clCreateImage( + context(), + flags, + &format, + &desc, + host_ptr, + &error); + + detail::errHandler(error, __CREATE_IMAGE_ERR); + if (err != NULL) { + *err = error; + } + } +#endif // #if defined(CL_VERSION_1_2) +#if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) + if (!useCreateImage) + { + object_ = ::clCreateImage2D( + context(), flags,&format, width, height, row_pitch, host_ptr, &error); + + detail::errHandler(error, __CREATE_IMAGE2D_ERR); + if (err != NULL) { + *err = error; + } + } +#endif // #if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) + } + + //! \brief Default constructor - initializes to NULL. + Image2D() { } + + /*! \brief Constructor from cl_mem - takes ownership. + * + * See Memory for further details. + */ + __CL_EXPLICIT_CONSTRUCTORS Image2D(const cl_mem& image2D) : Image(image2D) { } + + /*! \brief Assignment from cl_mem - performs shallow copy. + * + * See Memory for further details. + */ + Image2D& operator = (const cl_mem& rhs) + { + Image::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image2D(const Image2D& img) : Image(img) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image2D& operator = (const Image2D &img) + { + Image::operator=(img); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Image2D(Image2D&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Image2D& operator = (Image2D &&img) + { + Image::operator=(std::move(img)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) +}; + + +#if !defined(CL_VERSION_1_2) +/*! \brief Class interface for GL 2D Image Memory objects. + * + * This is provided to facilitate interoperability with OpenGL. + * + * See Memory for details about copy semantics, etc. + * + * \see Memory + * \note Deprecated for OpenCL 1.2. Please use ImageGL instead. + */ +class CL_EXT_PREFIX__VERSION_1_1_DEPRECATED Image2DGL CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED : public Image2D +{ +public: + /*! \brief Constructs an Image2DGL in a specified context, from a given + * GL Texture. + * + * Wraps clCreateFromGLTexture2D(). + */ + Image2DGL( + const Context& context, + cl_mem_flags flags, + cl_GLenum target, + cl_GLint miplevel, + cl_GLuint texobj, + cl_int * err = NULL) + { + cl_int error; + object_ = ::clCreateFromGLTexture2D( + context(), + flags, + target, + miplevel, + texobj, + &error); + + detail::errHandler(error, __CREATE_GL_TEXTURE_2D_ERR); + if (err != NULL) { + *err = error; + } + + } + + //! \brief Default constructor - initializes to NULL. + Image2DGL() : Image2D() { } + + /*! \brief Constructor from cl_mem - takes ownership. + * + * See Memory for further details. + */ + __CL_EXPLICIT_CONSTRUCTORS Image2DGL(const cl_mem& image) : Image2D(image) { } + + /*! \brief Assignment from cl_mem - performs shallow copy. + * + * See Memory for further details. + */ + Image2DGL& operator = (const cl_mem& rhs) + { + Image2D::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image2DGL(const Image2DGL& img) : Image2D(img) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image2DGL& operator = (const Image2DGL &img) + { + Image2D::operator=(img); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Image2DGL(Image2DGL&& img) CL_HPP_NOEXCEPT : Image2D(std::move(img)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Image2DGL& operator = (Image2DGL &&img) + { + Image2D::operator=(std::move(img)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) +}; +#endif // #if !defined(CL_VERSION_1_2) + +#if defined(CL_VERSION_1_2) +/*! \class Image2DArray + * \brief Image interface for arrays of 2D images. + */ +class Image2DArray : public Image +{ +public: + Image2DArray( + const Context& context, + cl_mem_flags flags, + ImageFormat format, + ::size_t arraySize, + ::size_t width, + ::size_t height, + ::size_t rowPitch, + ::size_t slicePitch, + void* host_ptr = NULL, + cl_int* err = NULL) + { + cl_int error; + cl_image_desc desc = + { + CL_MEM_OBJECT_IMAGE2D_ARRAY, + width, + height, + 0, // depth (unused) + arraySize, + rowPitch, + slicePitch, + 0, 0, 0 + }; + object_ = ::clCreateImage( + context(), + flags, + &format, + &desc, + host_ptr, + &error); + + detail::errHandler(error, __CREATE_IMAGE_ERR); + if (err != NULL) { + *err = error; + } + } + + Image2DArray() { } + + __CL_EXPLICIT_CONSTRUCTORS Image2DArray(const cl_mem& imageArray) : Image(imageArray) { } + + Image2DArray& operator = (const cl_mem& rhs) + { + Image::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image2DArray(const Image2DArray& img) : Image(img) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image2DArray& operator = (const Image2DArray &img) + { + Image::operator=(img); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Image2DArray(Image2DArray&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Image2DArray& operator = (Image2DArray &&img) + { + Image::operator=(std::move(img)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) +}; +#endif // #if defined(CL_VERSION_1_2) + +/*! \brief Class interface for 3D Image Memory objects. + * + * See Memory for details about copy semantics, etc. + * + * \see Memory + */ +class Image3D : public Image +{ +public: + /*! \brief Constructs a 3D Image in a specified context. + * + * Wraps clCreateImage(). + */ + Image3D( + const Context& context, + cl_mem_flags flags, + ImageFormat format, + ::size_t width, + ::size_t height, + ::size_t depth, + ::size_t row_pitch = 0, + ::size_t slice_pitch = 0, + void* host_ptr = NULL, + cl_int* err = NULL) + { + cl_int error; + bool useCreateImage; + +#if defined(CL_VERSION_1_2) && defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) + // Run-time decision based on the actual platform + { + cl_uint version = detail::getContextPlatformVersion(context()); + useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above + } +#elif defined(CL_VERSION_1_2) + useCreateImage = true; +#else + useCreateImage = false; +#endif + +#if defined(CL_VERSION_1_2) + if (useCreateImage) + { + cl_image_desc desc = + { + CL_MEM_OBJECT_IMAGE3D, + width, + height, + depth, + 0, // array size (unused) + row_pitch, + slice_pitch, + 0, 0, 0 + }; + object_ = ::clCreateImage( + context(), + flags, + &format, + &desc, + host_ptr, + &error); + + detail::errHandler(error, __CREATE_IMAGE_ERR); + if (err != NULL) { + *err = error; + } + } +#endif // #if defined(CL_VERSION_1_2) +#if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) + if (!useCreateImage) + { + object_ = ::clCreateImage3D( + context(), flags, &format, width, height, depth, row_pitch, + slice_pitch, host_ptr, &error); + + detail::errHandler(error, __CREATE_IMAGE3D_ERR); + if (err != NULL) { + *err = error; + } + } +#endif // #if !defined(CL_VERSION_1_2) || defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) + } + + //! \brief Default constructor - initializes to NULL. + Image3D() : Image() { } + + /*! \brief Constructor from cl_mem - takes ownership. + * + * See Memory for further details. + */ + __CL_EXPLICIT_CONSTRUCTORS Image3D(const cl_mem& image3D) : Image(image3D) { } + + /*! \brief Assignment from cl_mem - performs shallow copy. + * + * See Memory for further details. + */ + Image3D& operator = (const cl_mem& rhs) + { + Image::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image3D(const Image3D& img) : Image(img) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image3D& operator = (const Image3D &img) + { + Image::operator=(img); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Image3D(Image3D&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Image3D& operator = (Image3D &&img) + { + Image::operator=(std::move(img)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) +}; + +#if !defined(CL_VERSION_1_2) +/*! \brief Class interface for GL 3D Image Memory objects. + * + * This is provided to facilitate interoperability with OpenGL. + * + * See Memory for details about copy semantics, etc. + * + * \see Memory + */ +class Image3DGL : public Image3D +{ +public: + /*! \brief Constructs an Image3DGL in a specified context, from a given + * GL Texture. + * + * Wraps clCreateFromGLTexture3D(). + */ + Image3DGL( + const Context& context, + cl_mem_flags flags, + cl_GLenum target, + cl_GLint miplevel, + cl_GLuint texobj, + cl_int * err = NULL) + { + cl_int error; + object_ = ::clCreateFromGLTexture3D( + context(), + flags, + target, + miplevel, + texobj, + &error); + + detail::errHandler(error, __CREATE_GL_TEXTURE_3D_ERR); + if (err != NULL) { + *err = error; + } + } + + //! \brief Default constructor - initializes to NULL. + Image3DGL() : Image3D() { } + + /*! \brief Constructor from cl_mem - takes ownership. + * + * See Memory for further details. + */ + __CL_EXPLICIT_CONSTRUCTORS Image3DGL(const cl_mem& image) : Image3D(image) { } + + /*! \brief Assignment from cl_mem - performs shallow copy. + * + * See Memory for further details. + */ + Image3DGL& operator = (const cl_mem& rhs) + { + Image3D::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image3DGL(const Image3DGL& img) : Image3D(img) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Image3DGL& operator = (const Image3DGL &img) + { + Image3D::operator=(img); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Image3DGL(Image3DGL&& img) CL_HPP_NOEXCEPT : Image3D(std::move(img)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Image3DGL& operator = (Image3DGL &&img) + { + Image3D::operator=(std::move(img)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) +}; +#endif // #if !defined(CL_VERSION_1_2) + +#if defined(CL_VERSION_1_2) +/*! \class ImageGL + * \brief general image interface for GL interop. + * We abstract the 2D and 3D GL images into a single instance here + * that wraps all GL sourced images on the grounds that setup information + * was performed by OpenCL anyway. + */ +class ImageGL : public Image +{ +public: + ImageGL( + const Context& context, + cl_mem_flags flags, + cl_GLenum target, + cl_GLint miplevel, + cl_GLuint texobj, + cl_int * err = NULL) + { + cl_int error; + object_ = ::clCreateFromGLTexture( + context(), + flags, + target, + miplevel, + texobj, + &error); + + detail::errHandler(error, __CREATE_GL_TEXTURE_ERR); + if (err != NULL) { + *err = error; + } + } + + ImageGL() : Image() { } + + __CL_EXPLICIT_CONSTRUCTORS ImageGL(const cl_mem& image) : Image(image) { } + + ImageGL& operator = (const cl_mem& rhs) + { + Image::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + ImageGL(const ImageGL& img) : Image(img) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + ImageGL& operator = (const ImageGL &img) + { + Image::operator=(img); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + ImageGL(ImageGL&& img) CL_HPP_NOEXCEPT : Image(std::move(img)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + ImageGL& operator = (ImageGL &&img) + { + Image::operator=(std::move(img)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) +}; +#endif // #if defined(CL_VERSION_1_2) + +/*! \brief Class interface for GL Render Buffer Memory Objects. +* +* This is provided to facilitate interoperability with OpenGL. +* +* See Memory for details about copy semantics, etc. +* +* \see Memory +*/ +class BufferRenderGL : +#if defined(CL_VERSION_1_2) + public ImageGL +#else // #if defined(CL_VERSION_1_2) + public Image2DGL +#endif //#if defined(CL_VERSION_1_2) +{ +public: + /*! \brief Constructs a BufferRenderGL in a specified context, from a given + * GL Renderbuffer. + * + * Wraps clCreateFromGLRenderbuffer(). + */ + BufferRenderGL( + const Context& context, + cl_mem_flags flags, + cl_GLuint bufobj, + cl_int * err = NULL) + { + cl_int error; + object_ = ::clCreateFromGLRenderbuffer( + context(), + flags, + bufobj, + &error); + + detail::errHandler(error, __CREATE_GL_RENDER_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + } + + //! \brief Default constructor - initializes to NULL. +#if defined(CL_VERSION_1_2) + BufferRenderGL() : ImageGL() {}; +#else // #if defined(CL_VERSION_1_2) + BufferRenderGL() : Image2DGL() {}; +#endif //#if defined(CL_VERSION_1_2) + + /*! \brief Constructor from cl_mem - takes ownership. + * + * See Memory for further details. + */ +#if defined(CL_VERSION_1_2) + __CL_EXPLICIT_CONSTRUCTORS BufferRenderGL(const cl_mem& buffer) : ImageGL(buffer) { } +#else // #if defined(CL_VERSION_1_2) + __CL_EXPLICIT_CONSTRUCTORS BufferRenderGL(const cl_mem& buffer) : Image2DGL(buffer) { } +#endif //#if defined(CL_VERSION_1_2) + + + /*! \brief Assignment from cl_mem - performs shallow copy. + * + * See Memory for further details. + */ + BufferRenderGL& operator = (const cl_mem& rhs) + { +#if defined(CL_VERSION_1_2) + ImageGL::operator=(rhs); +#else // #if defined(CL_VERSION_1_2) + Image2DGL::operator=(rhs); +#endif //#if defined(CL_VERSION_1_2) + + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ +#if defined(CL_VERSION_1_2) + BufferRenderGL(const BufferRenderGL& buf) : ImageGL(buf) {} +#else // #if defined(CL_VERSION_1_2) + BufferRenderGL(const BufferRenderGL& buf) : Image2DGL(buf) {} +#endif //#if defined(CL_VERSION_1_2) + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + BufferRenderGL& operator = (const BufferRenderGL &rhs) + { +#if defined(CL_VERSION_1_2) + ImageGL::operator=(rhs); +#else // #if defined(CL_VERSION_1_2) + Image2DGL::operator=(rhs); +#endif //#if defined(CL_VERSION_1_2) + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ +#if defined(CL_VERSION_1_2) + BufferRenderGL(BufferRenderGL&& buf) CL_HPP_NOEXCEPT : ImageGL(std::move(buf)) {} +#else // #if defined(CL_VERSION_1_2) + BufferRenderGL(BufferRenderGL&& buf) CL_HPP_NOEXCEPT : Image2DGL(std::move(buf)) {} +#endif //#if defined(CL_VERSION_1_2) + + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + BufferRenderGL& operator = (BufferRenderGL &&buf) + { +#if defined(CL_VERSION_1_2) + ImageGL::operator=(std::move(buf)); +#else // #if defined(CL_VERSION_1_2) + Image2DGL::operator=(std::move(buf)); +#endif //#if defined(CL_VERSION_1_2) + + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + + //! \brief Wrapper for clGetGLObjectInfo(). + cl_int getObjectInfo( + cl_gl_object_type *type, + cl_GLuint * gl_object_name) + { + return detail::errHandler( + ::clGetGLObjectInfo(object_, type, gl_object_name), + __GET_GL_OBJECT_INFO_ERR); + } +}; + +/*! \brief Class interface for cl_sampler. + * + * \note Copies of these objects are shallow, meaning that the copy will refer + * to the same underlying cl_sampler as the original. For details, see + * clRetainSampler() and clReleaseSampler(). + * + * \see cl_sampler + */ +class Sampler : public detail::Wrapper +{ +public: + //! \brief Default constructor - initializes to NULL. + Sampler() { } + + /*! \brief Constructs a Sampler in a specified context. + * + * Wraps clCreateSampler(). + */ + Sampler( + const Context& context, + cl_bool normalized_coords, + cl_addressing_mode addressing_mode, + cl_filter_mode filter_mode, + cl_int* err = NULL) + { + cl_int error; + object_ = ::clCreateSampler( + context(), + normalized_coords, + addressing_mode, + filter_mode, + &error); + + detail::errHandler(error, __CREATE_SAMPLER_ERR); + if (err != NULL) { + *err = error; + } + } + + /*! \brief Constructor from cl_sampler - takes ownership. + * + * This effectively transfers ownership of a refcount on the cl_sampler + * into the new Sampler object. + */ + __CL_EXPLICIT_CONSTRUCTORS Sampler(const cl_sampler& sampler) : detail::Wrapper(sampler) { } + + /*! \brief Assignment operator from cl_sampler - takes ownership. + * + * This effectively transfers ownership of a refcount on the rhs and calls + * clReleaseSampler() on the value previously held by this instance. + */ + Sampler& operator = (const cl_sampler& rhs) + { + detail::Wrapper::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Sampler(const Sampler& sam) : detail::Wrapper(sam) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Sampler& operator = (const Sampler &sam) + { + detail::Wrapper::operator=(sam); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Sampler(Sampler&& sam) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(sam)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Sampler& operator = (Sampler &&sam) + { + detail::Wrapper::operator=(std::move(sam)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + + //! \brief Wrapper for clGetSamplerInfo(). + template + cl_int getInfo(cl_sampler_info name, T* param) const + { + return detail::errHandler( + detail::getInfo(&::clGetSamplerInfo, object_, name, param), + __GET_SAMPLER_INFO_ERR); + } + + //! \brief Wrapper for clGetSamplerInfo() that returns by value. + template typename + detail::param_traits::param_type + getInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_sampler_info, name>::param_type param; + cl_int result = getInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } +}; + +class Program; +class CommandQueue; +class Kernel; + +//! \brief Class interface for specifying NDRange values. +class NDRange +{ +private: + size_t<3> sizes_; + cl_uint dimensions_; + +public: + //! \brief Default constructor - resulting range has zero dimensions. + NDRange() + : dimensions_(0) + { } + + //! \brief Constructs one-dimensional range. + NDRange(::size_t size0) + : dimensions_(1) + { + sizes_[0] = size0; + } + + //! \brief Constructs two-dimensional range. + NDRange(::size_t size0, ::size_t size1) + : dimensions_(2) + { + sizes_[0] = size0; + sizes_[1] = size1; + } + + //! \brief Constructs three-dimensional range. + NDRange(::size_t size0, ::size_t size1, ::size_t size2) + : dimensions_(3) + { + sizes_[0] = size0; + sizes_[1] = size1; + sizes_[2] = size2; + } + + /*! \brief Conversion operator to const ::size_t *. + * + * \returns a pointer to the size of the first dimension. + */ + operator const ::size_t*() const { + return (const ::size_t*) sizes_; + } + + //! \brief Queries the number of dimensions in the range. + ::size_t dimensions() const { return dimensions_; } +}; + +//! \brief A zero-dimensional range. +static const NDRange NullRange; + +//! \brief Local address wrapper for use with Kernel::setArg +struct LocalSpaceArg +{ + ::size_t size_; +}; + +namespace detail { + +template +struct KernelArgumentHandler +{ + static ::size_t size(const T&) { return sizeof(T); } + static const T* ptr(const T& value) { return &value; } +}; + +template <> +struct KernelArgumentHandler +{ + static ::size_t size(const LocalSpaceArg& value) { return value.size_; } + static const void* ptr(const LocalSpaceArg&) { return NULL; } +}; + +} +//! \endcond + +/*! __local + * \brief Helper function for generating LocalSpaceArg objects. + * Deprecated. Replaced with Local. + */ +inline CL_EXT_PREFIX__VERSION_1_1_DEPRECATED LocalSpaceArg +__local(::size_t size) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; +inline LocalSpaceArg +__local(::size_t size) +{ + LocalSpaceArg ret = { size }; + return ret; +} + +/*! Local + * \brief Helper function for generating LocalSpaceArg objects. + */ +inline LocalSpaceArg +Local(::size_t size) +{ + LocalSpaceArg ret = { size }; + return ret; +} + +//class KernelFunctor; + +/*! \brief Class interface for cl_kernel. + * + * \note Copies of these objects are shallow, meaning that the copy will refer + * to the same underlying cl_kernel as the original. For details, see + * clRetainKernel() and clReleaseKernel(). + * + * \see cl_kernel + */ +class Kernel : public detail::Wrapper +{ +public: + inline Kernel(const Program& program, const char* name, cl_int* err = NULL); + + //! \brief Default constructor - initializes to NULL. + Kernel() { } + + /*! \brief Constructor from cl_kernel - takes ownership. + * + * This effectively transfers ownership of a refcount on the cl_kernel + * into the new Kernel object. + */ + __CL_EXPLICIT_CONSTRUCTORS Kernel(const cl_kernel& kernel) : detail::Wrapper(kernel) { } + + /*! \brief Assignment operator from cl_kernel - takes ownership. + * + * This effectively transfers ownership of a refcount on the rhs and calls + * clReleaseKernel() on the value previously held by this instance. + */ + Kernel& operator = (const cl_kernel& rhs) + { + detail::Wrapper::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Kernel(const Kernel& kernel) : detail::Wrapper(kernel) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Kernel& operator = (const Kernel &kernel) + { + detail::Wrapper::operator=(kernel); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Kernel(Kernel&& kernel) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(kernel)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Kernel& operator = (Kernel &&kernel) + { + detail::Wrapper::operator=(std::move(kernel)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + + template + cl_int getInfo(cl_kernel_info name, T* param) const + { + return detail::errHandler( + detail::getInfo(&::clGetKernelInfo, object_, name, param), + __GET_KERNEL_INFO_ERR); + } + + template typename + detail::param_traits::param_type + getInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_kernel_info, name>::param_type param; + cl_int result = getInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + +#if defined(CL_VERSION_1_2) + template + cl_int getArgInfo(cl_uint argIndex, cl_kernel_arg_info name, T* param) const + { + return detail::errHandler( + detail::getInfo(&::clGetKernelArgInfo, object_, argIndex, name, param), + __GET_KERNEL_ARG_INFO_ERR); + } + + template typename + detail::param_traits::param_type + getArgInfo(cl_uint argIndex, cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_kernel_arg_info, name>::param_type param; + cl_int result = getArgInfo(argIndex, name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } +#endif // #if defined(CL_VERSION_1_2) + + template + cl_int getWorkGroupInfo( + const Device& device, cl_kernel_work_group_info name, T* param) const + { + return detail::errHandler( + detail::getInfo( + &::clGetKernelWorkGroupInfo, object_, device(), name, param), + __GET_KERNEL_WORK_GROUP_INFO_ERR); + } + + template typename + detail::param_traits::param_type + getWorkGroupInfo(const Device& device, cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_kernel_work_group_info, name>::param_type param; + cl_int result = getWorkGroupInfo(device, name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + + template + cl_int setArg(cl_uint index, const T &value) + { + return detail::errHandler( + ::clSetKernelArg( + object_, + index, + detail::KernelArgumentHandler::size(value), + detail::KernelArgumentHandler::ptr(value)), + __SET_KERNEL_ARGS_ERR); + } + + cl_int setArg(cl_uint index, ::size_t size, const void* argPtr) + { + return detail::errHandler( + ::clSetKernelArg(object_, index, size, argPtr), + __SET_KERNEL_ARGS_ERR); + } +}; + +/*! \class Program + * \brief Program interface that implements cl_program. + */ +class Program : public detail::Wrapper +{ +public: + typedef VECTOR_CLASS > Binaries; + typedef VECTOR_CLASS > Sources; + + Program( + const STRING_CLASS& source, + bool build = false, + cl_int* err = NULL) + { + cl_int error; + + const char * strings = source.c_str(); + const ::size_t length = source.size(); + + Context context = Context::getDefault(err); + + object_ = ::clCreateProgramWithSource( + context(), (cl_uint)1, &strings, &length, &error); + + detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR); + + if (error == CL_SUCCESS && build) { + + error = ::clBuildProgram( + object_, + 0, + NULL, + "", + NULL, + NULL); + + detail::errHandler(error, __BUILD_PROGRAM_ERR); + } + + if (err != NULL) { + *err = error; + } + } + + Program( + const Context& context, + const STRING_CLASS& source, + bool build = false, + cl_int* err = NULL) + { + cl_int error; + + const char * strings = source.c_str(); + const ::size_t length = source.size(); + + object_ = ::clCreateProgramWithSource( + context(), (cl_uint)1, &strings, &length, &error); + + detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR); + + if (error == CL_SUCCESS && build) { + + error = ::clBuildProgram( + object_, + 0, + NULL, + "", + NULL, + NULL); + + detail::errHandler(error, __BUILD_PROGRAM_ERR); + } + + if (err != NULL) { + *err = error; + } + } + + Program( + const Context& context, + const Sources& sources, + cl_int* err = NULL) + { + cl_int error; + + const ::size_t n = (::size_t)sources.size(); + ::size_t* lengths = (::size_t*) alloca(n * sizeof(::size_t)); + const char** strings = (const char**) alloca(n * sizeof(const char*)); + + for (::size_t i = 0; i < n; ++i) { + strings[i] = sources[(int)i].first; + lengths[i] = sources[(int)i].second; + } + + object_ = ::clCreateProgramWithSource( + context(), (cl_uint)n, strings, lengths, &error); + + detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR); + if (err != NULL) { + *err = error; + } + } + + /** + * Construct a program object from a list of devices and a per-device list of binaries. + * \param context A valid OpenCL context in which to construct the program. + * \param devices A vector of OpenCL device objects for which the program will be created. + * \param binaries A vector of pairs of a pointer to a binary object and its length. + * \param binaryStatus An optional vector that on completion will be resized to + * match the size of binaries and filled with values to specify if each binary + * was successfully loaded. + * Set to CL_SUCCESS if the binary was successfully loaded. + * Set to CL_INVALID_VALUE if the length is 0 or the binary pointer is NULL. + * Set to CL_INVALID_BINARY if the binary provided is not valid for the matching device. + * \param err if non-NULL will be set to CL_SUCCESS on successful operation or one of the following errors: + * CL_INVALID_CONTEXT if context is not a valid context. + * CL_INVALID_VALUE if the length of devices is zero; or if the length of binaries does not match the length of devices; + * or if any entry in binaries is NULL or has length 0. + * CL_INVALID_DEVICE if OpenCL devices listed in devices are not in the list of devices associated with context. + * CL_INVALID_BINARY if an invalid program binary was encountered for any device. binaryStatus will return specific status for each device. + * CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required by the OpenCL implementation on the host. + */ + Program( + const Context& context, + const VECTOR_CLASS& devices, + const Binaries& binaries, + VECTOR_CLASS* binaryStatus = NULL, + cl_int* err = NULL) + { + cl_int error; + + const ::size_t numDevices = devices.size(); + + // Catch size mismatch early and return + if(binaries.size() != numDevices) { + error = CL_INVALID_VALUE; + detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR); + if (err != NULL) { + *err = error; + } + return; + } + + ::size_t* lengths = (::size_t*) alloca(numDevices * sizeof(::size_t)); + const unsigned char** images = (const unsigned char**) alloca(numDevices * sizeof(const unsigned char**)); + + for (::size_t i = 0; i < numDevices; ++i) { + images[i] = (const unsigned char*)binaries[i].first; + lengths[i] = binaries[(int)i].second; + } + + cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id)); + for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) { + deviceIDs[deviceIndex] = (devices[deviceIndex])(); + } + + if(binaryStatus) { + binaryStatus->resize(numDevices); + } + + object_ = ::clCreateProgramWithBinary( + context(), (cl_uint) devices.size(), + deviceIDs, + lengths, images, (binaryStatus != NULL && numDevices > 0) + ? &binaryStatus->front() + : NULL, &error); + + detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR); + if (err != NULL) { + *err = error; + } + } + + +#if defined(CL_VERSION_1_2) + /** + * Create program using builtin kernels. + * \param kernelNames Semi-colon separated list of builtin kernel names + */ + Program( + const Context& context, + const VECTOR_CLASS& devices, + const STRING_CLASS& kernelNames, + cl_int* err = NULL) + { + cl_int error; + + + ::size_t numDevices = devices.size(); + cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id)); + for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) { + deviceIDs[deviceIndex] = (devices[deviceIndex])(); + } + + object_ = ::clCreateProgramWithBuiltInKernels( + context(), + (cl_uint) devices.size(), + deviceIDs, + kernelNames.c_str(), + &error); + + detail::errHandler(error, __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR); + if (err != NULL) { + *err = error; + } + } +#endif // #if defined(CL_VERSION_1_2) + + Program() { } + + __CL_EXPLICIT_CONSTRUCTORS Program(const cl_program& program) : detail::Wrapper(program) { } + + Program& operator = (const cl_program& rhs) + { + detail::Wrapper::operator=(rhs); + return *this; + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + Program(const Program& program) : detail::Wrapper(program) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + Program& operator = (const Program &program) + { + detail::Wrapper::operator=(program); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + Program(Program&& program) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(program)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + Program& operator = (Program &&program) + { + detail::Wrapper::operator=(std::move(program)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + + cl_int build( + const VECTOR_CLASS& devices, + const char* options = NULL, + void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, + void* data = NULL) const + { + ::size_t numDevices = devices.size(); + cl_device_id* deviceIDs = (cl_device_id*) alloca(numDevices * sizeof(cl_device_id)); + for( ::size_t deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) { + deviceIDs[deviceIndex] = (devices[deviceIndex])(); + } + + return detail::errHandler( + ::clBuildProgram( + object_, + (cl_uint) + devices.size(), + deviceIDs, + options, + notifyFptr, + data), + __BUILD_PROGRAM_ERR); + } + + cl_int build( + const char* options = NULL, + void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, + void* data = NULL) const + { + return detail::errHandler( + ::clBuildProgram( + object_, + 0, + NULL, + options, + notifyFptr, + data), + __BUILD_PROGRAM_ERR); + } + +#if defined(CL_VERSION_1_2) + cl_int compile( + const char* options = NULL, + void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, + void* data = NULL) const + { + return detail::errHandler( + ::clCompileProgram( + object_, + 0, + NULL, + options, + 0, + NULL, + NULL, + notifyFptr, + data), + __COMPILE_PROGRAM_ERR); + } +#endif + + template + cl_int getInfo(cl_program_info name, T* param) const + { + return detail::errHandler( + detail::getInfo(&::clGetProgramInfo, object_, name, param), + __GET_PROGRAM_INFO_ERR); + } + + template typename + detail::param_traits::param_type + getInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_program_info, name>::param_type param; + cl_int result = getInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + + template + cl_int getBuildInfo( + const Device& device, cl_program_build_info name, T* param) const + { + return detail::errHandler( + detail::getInfo( + &::clGetProgramBuildInfo, object_, device(), name, param), + __GET_PROGRAM_BUILD_INFO_ERR); + } + + template typename + detail::param_traits::param_type + getBuildInfo(const Device& device, cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_program_build_info, name>::param_type param; + cl_int result = getBuildInfo(device, name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + + cl_int createKernels(VECTOR_CLASS* kernels) + { + cl_uint numKernels; + cl_int err = ::clCreateKernelsInProgram(object_, 0, NULL, &numKernels); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR); + } + + Kernel* value = (Kernel*) alloca(numKernels * sizeof(Kernel)); + err = ::clCreateKernelsInProgram( + object_, numKernels, (cl_kernel*) value, NULL); + if (err != CL_SUCCESS) { + return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR); + } + + kernels->assign(&value[0], &value[numKernels]); + return CL_SUCCESS; + } +}; + +#if defined(CL_VERSION_1_2) +inline Program linkProgram( + Program input1, + Program input2, + const char* options = NULL, + void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, + void* data = NULL, + cl_int* err = NULL) +{ + cl_int error_local = CL_SUCCESS; + + cl_program programs[2] = { input1(), input2() }; + + Context ctx = input1.getInfo(&error_local); + if(error_local!=CL_SUCCESS) { + detail::errHandler(error_local, __LINK_PROGRAM_ERR); + } + + cl_program prog = ::clLinkProgram( + ctx(), + 0, + NULL, + options, + 2, + programs, + notifyFptr, + data, + &error_local); + + detail::errHandler(error_local,__COMPILE_PROGRAM_ERR); + if (err != NULL) { + *err = error_local; + } + + return Program(prog); +} + +inline Program linkProgram( + VECTOR_CLASS inputPrograms, + const char* options = NULL, + void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, + void* data = NULL, + cl_int* err = NULL) +{ + cl_int error_local = CL_SUCCESS; + + cl_program * programs = (cl_program*) alloca(inputPrograms.size() * sizeof(cl_program)); + + if (programs != NULL) { + for (unsigned int i = 0; i < inputPrograms.size(); i++) { + programs[i] = inputPrograms[i](); + } + } + + Context ctx; + if(inputPrograms.size() > 0) { + ctx = inputPrograms[0].getInfo(&error_local); + if(error_local!=CL_SUCCESS) { + detail::errHandler(error_local, __LINK_PROGRAM_ERR); + } + } + cl_program prog = ::clLinkProgram( + ctx(), + 0, + NULL, + options, + (cl_uint)inputPrograms.size(), + programs, + notifyFptr, + data, + &error_local); + + detail::errHandler(error_local,__COMPILE_PROGRAM_ERR); + if (err != NULL) { + *err = error_local; + } + + return Program(prog); +} +#endif + +template<> +inline VECTOR_CLASS cl::Program::getInfo(cl_int* err) const +{ + VECTOR_CLASS< ::size_t> sizes = getInfo(); + VECTOR_CLASS binaries; + for (VECTOR_CLASS< ::size_t>::iterator s = sizes.begin(); s != sizes.end(); ++s) + { + char *ptr = NULL; + if (*s != 0) + ptr = new char[*s]; + binaries.push_back(ptr); + } + + cl_int result = getInfo(CL_PROGRAM_BINARIES, &binaries); + if (err != NULL) { + *err = result; + } + return binaries; +} + +inline Kernel::Kernel(const Program& program, const char* name, cl_int* err) +{ + cl_int error; + + object_ = ::clCreateKernel(program(), name, &error); + detail::errHandler(error, __CREATE_KERNEL_ERR); + + if (err != NULL) { + *err = error; + } + +} + +/*! \class CommandQueue + * \brief CommandQueue interface for cl_command_queue. + */ +class CommandQueue : public detail::Wrapper +{ +private: +#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED + static std::atomic default_initialized_; +#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED + static volatile int default_initialized_; +#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED + static CommandQueue default_; + static volatile cl_int default_error_; +public: + CommandQueue( + cl_command_queue_properties properties, + cl_int* err = NULL) + { + cl_int error; + + Context context = Context::getDefault(&error); + detail::errHandler(error, __CREATE_CONTEXT_ERR); + + if (error != CL_SUCCESS) { + if (err != NULL) { + *err = error; + } + } + else { + Device device = context.getInfo()[0]; + + object_ = ::clCreateCommandQueue( + context(), device(), properties, &error); + + detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); + if (err != NULL) { + *err = error; + } + } + } + /*! + * \brief Constructs a CommandQueue for an implementation defined device in the given context + */ + explicit CommandQueue( + const Context& context, + cl_command_queue_properties properties = 0, + cl_int* err = NULL) + { + cl_int error; + VECTOR_CLASS devices; + error = context.getInfo(CL_CONTEXT_DEVICES, &devices); + + detail::errHandler(error, __CREATE_CONTEXT_ERR); + + if (error != CL_SUCCESS) + { + if (err != NULL) { + *err = error; + } + return; + } + + object_ = ::clCreateCommandQueue(context(), devices[0](), properties, &error); + + detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); + + if (err != NULL) { + *err = error; + } + + } + + CommandQueue( + const Context& context, + const Device& device, + cl_command_queue_properties properties = 0, + cl_int* err = NULL) + { + cl_int error; + object_ = ::clCreateCommandQueue( + context(), device(), properties, &error); + + detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); + if (err != NULL) { + *err = error; + } + } + + /*! \brief Copy constructor to forward copy to the superclass correctly. + * Required for MSVC. + */ + CommandQueue(const CommandQueue& queue) : detail::Wrapper(queue) {} + + /*! \brief Copy assignment to forward copy to the superclass correctly. + * Required for MSVC. + */ + CommandQueue& operator = (const CommandQueue &queue) + { + detail::Wrapper::operator=(queue); + return *this; + } + +#if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + /*! \brief Move constructor to forward move to the superclass correctly. + * Required for MSVC. + */ + CommandQueue(CommandQueue&& queue) CL_HPP_NOEXCEPT : detail::Wrapper(std::move(queue)) {} + + /*! \brief Move assignment to forward move to the superclass correctly. + * Required for MSVC. + */ + CommandQueue& operator = (CommandQueue &&queue) + { + detail::Wrapper::operator=(std::move(queue)); + return *this; + } +#endif // #if defined(CL_HPP_RVALUE_REFERENCES_SUPPORTED) + + static CommandQueue getDefault(cl_int * err = NULL) + { + int state = detail::compare_exchange( + &default_initialized_, + __DEFAULT_BEING_INITIALIZED, __DEFAULT_NOT_INITIALIZED); + + if (state & __DEFAULT_INITIALIZED) { + if (err != NULL) { + *err = default_error_; + } + return default_; + } + + if (state & __DEFAULT_BEING_INITIALIZED) { + // Assume writes will propagate eventually... + while(default_initialized_ != __DEFAULT_INITIALIZED) { + detail::fence(); + } + + if (err != NULL) { + *err = default_error_; + } + return default_; + } + + cl_int error; + + Context context = Context::getDefault(&error); + detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); + + if (error != CL_SUCCESS) { + if (err != NULL) { + *err = error; + } + } + else { + Device device = context.getInfo()[0]; + + default_ = CommandQueue(context, device, 0, &error); + + detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); + if (err != NULL) { + *err = error; + } + } + + detail::fence(); + + default_error_ = error; + // Assume writes will propagate eventually... + default_initialized_ = __DEFAULT_INITIALIZED; + + detail::fence(); + + if (err != NULL) { + *err = default_error_; + } + return default_; + + } + + CommandQueue() { } + + __CL_EXPLICIT_CONSTRUCTORS CommandQueue(const cl_command_queue& commandQueue) : detail::Wrapper(commandQueue) { } + + CommandQueue& operator = (const cl_command_queue& rhs) + { + detail::Wrapper::operator=(rhs); + return *this; + } + + template + cl_int getInfo(cl_command_queue_info name, T* param) const + { + return detail::errHandler( + detail::getInfo( + &::clGetCommandQueueInfo, object_, name, param), + __GET_COMMAND_QUEUE_INFO_ERR); + } + + template typename + detail::param_traits::param_type + getInfo(cl_int* err = NULL) const + { + typename detail::param_traits< + detail::cl_command_queue_info, name>::param_type param; + cl_int result = getInfo(name, ¶m); + if (err != NULL) { + *err = result; + } + return param; + } + + cl_int enqueueReadBuffer( + const Buffer& buffer, + cl_bool blocking, + ::size_t offset, + ::size_t size, + void* ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueReadBuffer( + object_, buffer(), blocking, offset, size, + ptr, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_READ_BUFFER_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueWriteBuffer( + const Buffer& buffer, + cl_bool blocking, + ::size_t offset, + ::size_t size, + const void* ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueWriteBuffer( + object_, buffer(), blocking, offset, size, + ptr, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_WRITE_BUFFER_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueCopyBuffer( + const Buffer& src, + const Buffer& dst, + ::size_t src_offset, + ::size_t dst_offset, + ::size_t size, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueCopyBuffer( + object_, src(), dst(), src_offset, dst_offset, size, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQEUE_COPY_BUFFER_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueReadBufferRect( + const Buffer& buffer, + cl_bool blocking, + const size_t<3>& buffer_offset, + const size_t<3>& host_offset, + const size_t<3>& region, + ::size_t buffer_row_pitch, + ::size_t buffer_slice_pitch, + ::size_t host_row_pitch, + ::size_t host_slice_pitch, + void *ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueReadBufferRect( + object_, + buffer(), + blocking, + (const ::size_t *)buffer_offset, + (const ::size_t *)host_offset, + (const ::size_t *)region, + buffer_row_pitch, + buffer_slice_pitch, + host_row_pitch, + host_slice_pitch, + ptr, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_READ_BUFFER_RECT_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueWriteBufferRect( + const Buffer& buffer, + cl_bool blocking, + const size_t<3>& buffer_offset, + const size_t<3>& host_offset, + const size_t<3>& region, + ::size_t buffer_row_pitch, + ::size_t buffer_slice_pitch, + ::size_t host_row_pitch, + ::size_t host_slice_pitch, + const void *ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueWriteBufferRect( + object_, + buffer(), + blocking, + (const ::size_t *)buffer_offset, + (const ::size_t *)host_offset, + (const ::size_t *)region, + buffer_row_pitch, + buffer_slice_pitch, + host_row_pitch, + host_slice_pitch, + ptr, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_WRITE_BUFFER_RECT_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueCopyBufferRect( + const Buffer& src, + const Buffer& dst, + const size_t<3>& src_origin, + const size_t<3>& dst_origin, + const size_t<3>& region, + ::size_t src_row_pitch, + ::size_t src_slice_pitch, + ::size_t dst_row_pitch, + ::size_t dst_slice_pitch, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueCopyBufferRect( + object_, + src(), + dst(), + (const ::size_t *)src_origin, + (const ::size_t *)dst_origin, + (const ::size_t *)region, + src_row_pitch, + src_slice_pitch, + dst_row_pitch, + dst_slice_pitch, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQEUE_COPY_BUFFER_RECT_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + +#if defined(CL_VERSION_1_2) + /** + * Enqueue a command to fill a buffer object with a pattern + * of a given size. The pattern is specified a as vector. + * \tparam PatternType The datatype of the pattern field. + * The pattern type must be an accepted OpenCL data type. + */ + template + cl_int enqueueFillBuffer( + const Buffer& buffer, + PatternType pattern, + ::size_t offset, + ::size_t size, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueFillBuffer( + object_, + buffer(), + static_cast(&pattern), + sizeof(PatternType), + offset, + size, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_FILL_BUFFER_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } +#endif // #if defined(CL_VERSION_1_2) + + cl_int enqueueReadImage( + const Image& image, + cl_bool blocking, + const size_t<3>& origin, + const size_t<3>& region, + ::size_t row_pitch, + ::size_t slice_pitch, + void* ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueReadImage( + object_, image(), blocking, (const ::size_t *) origin, + (const ::size_t *) region, row_pitch, slice_pitch, ptr, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_READ_IMAGE_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueWriteImage( + const Image& image, + cl_bool blocking, + const size_t<3>& origin, + const size_t<3>& region, + ::size_t row_pitch, + ::size_t slice_pitch, + const void* ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueWriteImage( + object_, image(), blocking, (const ::size_t *) origin, + (const ::size_t *) region, row_pitch, slice_pitch, ptr, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_WRITE_IMAGE_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueCopyImage( + const Image& src, + const Image& dst, + const size_t<3>& src_origin, + const size_t<3>& dst_origin, + const size_t<3>& region, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueCopyImage( + object_, src(), dst(), (const ::size_t *) src_origin, + (const ::size_t *)dst_origin, (const ::size_t *) region, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_COPY_IMAGE_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + +#if defined(CL_VERSION_1_2) + /** + * Enqueue a command to fill an image object with a specified color. + * \param fillColor is the color to use to fill the image. + * This is a four component RGBA floating-point color value if + * the image channel data type is not an unnormalized signed or + * unsigned data type. + */ + cl_int enqueueFillImage( + const Image& image, + cl_float4 fillColor, + const size_t<3>& origin, + const size_t<3>& region, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueFillImage( + object_, + image(), + static_cast(&fillColor), + (const ::size_t *) origin, + (const ::size_t *) region, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_FILL_IMAGE_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + /** + * Enqueue a command to fill an image object with a specified color. + * \param fillColor is the color to use to fill the image. + * This is a four component RGBA signed integer color value if + * the image channel data type is an unnormalized signed integer + * type. + */ + cl_int enqueueFillImage( + const Image& image, + cl_int4 fillColor, + const size_t<3>& origin, + const size_t<3>& region, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueFillImage( + object_, + image(), + static_cast(&fillColor), + (const ::size_t *) origin, + (const ::size_t *) region, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_FILL_IMAGE_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + /** + * Enqueue a command to fill an image object with a specified color. + * \param fillColor is the color to use to fill the image. + * This is a four component RGBA unsigned integer color value if + * the image channel data type is an unnormalized unsigned integer + * type. + */ + cl_int enqueueFillImage( + const Image& image, + cl_uint4 fillColor, + const size_t<3>& origin, + const size_t<3>& region, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueFillImage( + object_, + image(), + static_cast(&fillColor), + (const ::size_t *) origin, + (const ::size_t *) region, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_FILL_IMAGE_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } +#endif // #if defined(CL_VERSION_1_2) + + cl_int enqueueCopyImageToBuffer( + const Image& src, + const Buffer& dst, + const size_t<3>& src_origin, + const size_t<3>& region, + ::size_t dst_offset, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueCopyImageToBuffer( + object_, src(), dst(), (const ::size_t *) src_origin, + (const ::size_t *) region, dst_offset, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueCopyBufferToImage( + const Buffer& src, + const Image& dst, + ::size_t src_offset, + const size_t<3>& dst_origin, + const size_t<3>& region, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueCopyBufferToImage( + object_, src(), dst(), src_offset, + (const ::size_t *) dst_origin, (const ::size_t *) region, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + void* enqueueMapBuffer( + const Buffer& buffer, + cl_bool blocking, + cl_map_flags flags, + ::size_t offset, + ::size_t size, + const VECTOR_CLASS* events = NULL, + Event* event = NULL, + cl_int* err = NULL) const + { + cl_event tmp; + cl_int error; + void * result = ::clEnqueueMapBuffer( + object_, buffer(), blocking, flags, offset, size, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL, + &error); + + detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + if (event != NULL && error == CL_SUCCESS) + *event = tmp; + + return result; + } + + void* enqueueMapImage( + const Image& buffer, + cl_bool blocking, + cl_map_flags flags, + const size_t<3>& origin, + const size_t<3>& region, + ::size_t * row_pitch, + ::size_t * slice_pitch, + const VECTOR_CLASS* events = NULL, + Event* event = NULL, + cl_int* err = NULL) const + { + cl_event tmp; + cl_int error; + void * result = ::clEnqueueMapImage( + object_, buffer(), blocking, flags, + (const ::size_t *) origin, (const ::size_t *) region, + row_pitch, slice_pitch, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL, + &error); + + detail::errHandler(error, __ENQUEUE_MAP_IMAGE_ERR); + if (err != NULL) { + *err = error; + } + if (event != NULL && error == CL_SUCCESS) + *event = tmp; + return result; + } + + cl_int enqueueUnmapMemObject( + const Memory& memory, + void* mapped_ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueUnmapMemObject( + object_, memory(), mapped_ptr, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_UNMAP_MEM_OBJECT_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + +#if defined(CL_VERSION_1_2) + /** + * Enqueues a marker command which waits for either a list of events to complete, + * or all previously enqueued commands to complete. + * + * Enqueues a marker command which waits for either a list of events to complete, + * or if the list is empty it waits for all commands previously enqueued in command_queue + * to complete before it completes. This command returns an event which can be waited on, + * i.e. this event can be waited on to insure that all events either in the event_wait_list + * or all previously enqueued commands, queued before this command to command_queue, + * have completed. + */ + cl_int enqueueMarkerWithWaitList( + const VECTOR_CLASS *events = 0, + Event *event = 0) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueMarkerWithWaitList( + object_, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_MARKER_WAIT_LIST_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + /** + * A synchronization point that enqueues a barrier operation. + * + * Enqueues a barrier command which waits for either a list of events to complete, + * or if the list is empty it waits for all commands previously enqueued in command_queue + * to complete before it completes. This command blocks command execution, that is, any + * following commands enqueued after it do not execute until it completes. This command + * returns an event which can be waited on, i.e. this event can be waited on to insure that + * all events either in the event_wait_list or all previously enqueued commands, queued + * before this command to command_queue, have completed. + */ + cl_int enqueueBarrierWithWaitList( + const VECTOR_CLASS *events = 0, + Event *event = 0) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueBarrierWithWaitList( + object_, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_BARRIER_WAIT_LIST_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + /** + * Enqueues a command to indicate with which device a set of memory objects + * should be associated. + */ + cl_int enqueueMigrateMemObjects( + const VECTOR_CLASS &memObjects, + cl_mem_migration_flags flags, + const VECTOR_CLASS* events = NULL, + Event* event = NULL + ) const + { + cl_event tmp; + + cl_mem* localMemObjects = static_cast(alloca(memObjects.size() * sizeof(cl_mem))); + for( int i = 0; i < (int)memObjects.size(); ++i ) { + localMemObjects[i] = memObjects[i](); + } + + + cl_int err = detail::errHandler( + ::clEnqueueMigrateMemObjects( + object_, + (cl_uint)memObjects.size(), + static_cast(localMemObjects), + flags, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_UNMAP_MEM_OBJECT_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } +#endif // #if defined(CL_VERSION_1_2) + + cl_int enqueueNDRangeKernel( + const Kernel& kernel, + const NDRange& offset, + const NDRange& global, + const NDRange& local = NullRange, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueNDRangeKernel( + object_, kernel(), (cl_uint) global.dimensions(), + offset.dimensions() != 0 ? (const ::size_t*) offset : NULL, + (const ::size_t*) global, + local.dimensions() != 0 ? (const ::size_t*) local : NULL, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_NDRANGE_KERNEL_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueTask( + const Kernel& kernel, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueTask( + object_, kernel(), + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_TASK_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueNativeKernel( + void (CL_CALLBACK *userFptr)(void *), + std::pair args, + const VECTOR_CLASS* mem_objects = NULL, + const VECTOR_CLASS* mem_locs = NULL, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_mem * mems = (mem_objects != NULL && mem_objects->size() > 0) + ? (cl_mem*) alloca(mem_objects->size() * sizeof(cl_mem)) + : NULL; + + if (mems != NULL) { + for (unsigned int i = 0; i < mem_objects->size(); i++) { + mems[i] = ((*mem_objects)[i])(); + } + } + + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueNativeKernel( + object_, userFptr, args.first, args.second, + (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, + mems, + (mem_locs != NULL && mem_locs->size() > 0) ? (const void **) &mem_locs->front() : NULL, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_NATIVE_KERNEL); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + +/** + * Deprecated APIs for 1.2 + */ +#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) + CL_EXT_PREFIX__VERSION_1_1_DEPRECATED + cl_int enqueueMarker(Event* event = NULL) const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueMarker( + object_, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_MARKER_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + CL_EXT_PREFIX__VERSION_1_1_DEPRECATED + cl_int enqueueWaitForEvents(const VECTOR_CLASS& events) const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED + { + return detail::errHandler( + ::clEnqueueWaitForEvents( + object_, + (cl_uint) events.size(), + events.size() > 0 ? (const cl_event*) &events.front() : NULL), + __ENQUEUE_WAIT_FOR_EVENTS_ERR); + } +#endif // #if defined(CL_VERSION_1_1) + + cl_int enqueueAcquireGLObjects( + const VECTOR_CLASS* mem_objects = NULL, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueAcquireGLObjects( + object_, + (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, + (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_ACQUIRE_GL_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueReleaseGLObjects( + const VECTOR_CLASS* mem_objects = NULL, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueReleaseGLObjects( + object_, + (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, + (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_RELEASE_GL_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + +#if defined (USE_DX_INTEROP) +typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueAcquireD3D10ObjectsKHR)( + cl_command_queue command_queue, cl_uint num_objects, + const cl_mem* mem_objects, cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, cl_event* event); +typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)( + cl_command_queue command_queue, cl_uint num_objects, + const cl_mem* mem_objects, cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, cl_event* event); + + cl_int enqueueAcquireD3D10Objects( + const VECTOR_CLASS* mem_objects = NULL, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + static PFN_clEnqueueAcquireD3D10ObjectsKHR pfn_clEnqueueAcquireD3D10ObjectsKHR = NULL; +#if defined(CL_VERSION_1_2) + cl_context context = getInfo(); + cl::Device device(getInfo()); + cl_platform_id platform = device.getInfo(); + __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, clEnqueueAcquireD3D10ObjectsKHR); +#endif +#if defined(CL_VERSION_1_1) + __INIT_CL_EXT_FCN_PTR(clEnqueueAcquireD3D10ObjectsKHR); +#endif + + cl_event tmp; + cl_int err = detail::errHandler( + pfn_clEnqueueAcquireD3D10ObjectsKHR( + object_, + (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, + (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_ACQUIRE_GL_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } + + cl_int enqueueReleaseD3D10Objects( + const VECTOR_CLASS* mem_objects = NULL, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) const + { + static PFN_clEnqueueReleaseD3D10ObjectsKHR pfn_clEnqueueReleaseD3D10ObjectsKHR = NULL; +#if defined(CL_VERSION_1_2) + cl_context context = getInfo(); + cl::Device device(getInfo()); + cl_platform_id platform = device.getInfo(); + __INIT_CL_EXT_FCN_PTR_PLATFORM(platform, clEnqueueReleaseD3D10ObjectsKHR); +#endif // #if defined(CL_VERSION_1_2) +#if defined(CL_VERSION_1_1) + __INIT_CL_EXT_FCN_PTR(clEnqueueReleaseD3D10ObjectsKHR); +#endif // #if defined(CL_VERSION_1_1) + + cl_event tmp; + cl_int err = detail::errHandler( + pfn_clEnqueueReleaseD3D10ObjectsKHR( + object_, + (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, + (mem_objects != NULL && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): NULL, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_RELEASE_GL_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; + } +#endif + +/** + * Deprecated APIs for 1.2 + */ +#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) || (defined(CL_VERSION_1_1) && !defined(CL_VERSION_1_2)) + CL_EXT_PREFIX__VERSION_1_1_DEPRECATED + cl_int enqueueBarrier() const CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED + { + return detail::errHandler( + ::clEnqueueBarrier(object_), + __ENQUEUE_BARRIER_ERR); + } +#endif // #if defined(CL_VERSION_1_1) + + cl_int flush() const + { + return detail::errHandler(::clFlush(object_), __FLUSH_ERR); + } + + cl_int finish() const + { + return detail::errHandler(::clFinish(object_), __FINISH_ERR); + } +}; + +#ifdef _WIN32 +#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED +__declspec(selectany) std::atomic CommandQueue::default_initialized_; +#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED +__declspec(selectany) volatile int CommandQueue::default_initialized_ = __DEFAULT_NOT_INITIALIZED; +#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED +__declspec(selectany) CommandQueue CommandQueue::default_; +__declspec(selectany) volatile cl_int CommandQueue::default_error_ = CL_SUCCESS; +#else // !_WIN32 +#ifdef CL_HPP_CPP11_ATOMICS_SUPPORTED +__attribute__((weak)) std::atomic CommandQueue::default_initialized_; +#else // !CL_HPP_CPP11_ATOMICS_SUPPORTED +__attribute__((weak)) volatile int CommandQueue::default_initialized_ = __DEFAULT_NOT_INITIALIZED; +#endif // !CL_HPP_CPP11_ATOMICS_SUPPORTED +__attribute__((weak)) CommandQueue CommandQueue::default_; +__attribute__((weak)) volatile cl_int CommandQueue::default_error_ = CL_SUCCESS; +#endif // !_WIN32 + +template< typename IteratorType > +Buffer::Buffer( + const Context &context, + IteratorType startIterator, + IteratorType endIterator, + bool readOnly, + bool useHostPtr, + cl_int* err) +{ + typedef typename std::iterator_traits::value_type DataType; + cl_int error; + + cl_mem_flags flags = 0; + if( readOnly ) { + flags |= CL_MEM_READ_ONLY; + } + else { + flags |= CL_MEM_READ_WRITE; + } + if( useHostPtr ) { + flags |= CL_MEM_USE_HOST_PTR; + } + + ::size_t size = sizeof(DataType)*(endIterator - startIterator); + + if( useHostPtr ) { + object_ = ::clCreateBuffer(context(), flags, size, static_cast(&*startIterator), &error); + } else { + object_ = ::clCreateBuffer(context(), flags, size, 0, &error); + } + + detail::errHandler(error, __CREATE_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + + if( !useHostPtr ) { + CommandQueue queue(context, 0, &error); + detail::errHandler(error, __CREATE_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + + error = cl::copy(queue, startIterator, endIterator, *this); + detail::errHandler(error, __CREATE_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + } +} + +template< typename IteratorType > +Buffer::Buffer( + const CommandQueue &queue, + IteratorType startIterator, + IteratorType endIterator, + bool readOnly, + bool useHostPtr, + cl_int* err) +{ + typedef typename std::iterator_traits::value_type DataType; + cl_int error; + + cl_mem_flags flags = 0; + if (readOnly) { + flags |= CL_MEM_READ_ONLY; + } + else { + flags |= CL_MEM_READ_WRITE; + } + if (useHostPtr) { + flags |= CL_MEM_USE_HOST_PTR; + } + + ::size_t size = sizeof(DataType)*(endIterator - startIterator); + + Context context = queue.getInfo(); + + if (useHostPtr) { + object_ = ::clCreateBuffer(context(), flags, size, static_cast(&*startIterator), &error); + } + else { + object_ = ::clCreateBuffer(context(), flags, size, 0, &error); + } + + detail::errHandler(error, __CREATE_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + + if (!useHostPtr) { + error = cl::copy(queue, startIterator, endIterator, *this); + detail::errHandler(error, __CREATE_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + } +} + +inline cl_int enqueueReadBuffer( + const Buffer& buffer, + cl_bool blocking, + ::size_t offset, + ::size_t size, + void* ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueReadBuffer(buffer, blocking, offset, size, ptr, events, event); +} + +inline cl_int enqueueWriteBuffer( + const Buffer& buffer, + cl_bool blocking, + ::size_t offset, + ::size_t size, + const void* ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueWriteBuffer(buffer, blocking, offset, size, ptr, events, event); +} + +inline void* enqueueMapBuffer( + const Buffer& buffer, + cl_bool blocking, + cl_map_flags flags, + ::size_t offset, + ::size_t size, + const VECTOR_CLASS* events = NULL, + Event* event = NULL, + cl_int* err = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + + void * result = ::clEnqueueMapBuffer( + queue(), buffer(), blocking, flags, offset, size, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (cl_event*) event, + &error); + + detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR); + if (err != NULL) { + *err = error; + } + return result; +} + +inline cl_int enqueueUnmapMemObject( + const Memory& memory, + void* mapped_ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR); + if (error != CL_SUCCESS) { + return error; + } + + cl_event tmp; + cl_int err = detail::errHandler( + ::clEnqueueUnmapMemObject( + queue(), memory(), mapped_ptr, + (events != NULL) ? (cl_uint) events->size() : 0, + (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, + (event != NULL) ? &tmp : NULL), + __ENQUEUE_UNMAP_MEM_OBJECT_ERR); + + if (event != NULL && err == CL_SUCCESS) + *event = tmp; + + return err; +} + +inline cl_int enqueueCopyBuffer( + const Buffer& src, + const Buffer& dst, + ::size_t src_offset, + ::size_t dst_offset, + ::size_t size, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueCopyBuffer(src, dst, src_offset, dst_offset, size, events, event); +} + +/** + * Blocking copy operation between iterators and a buffer. + * Host to Device. + * Uses default command queue. + */ +template< typename IteratorType > +inline cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer ) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + if (error != CL_SUCCESS) + return error; + + return cl::copy(queue, startIterator, endIterator, buffer); +} + +/** + * Blocking copy operation between iterators and a buffer. + * Device to Host. + * Uses default command queue. + */ +template< typename IteratorType > +inline cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator ) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + if (error != CL_SUCCESS) + return error; + + return cl::copy(queue, buffer, startIterator, endIterator); +} + +/** + * Blocking copy operation between iterators and a buffer. + * Host to Device. + * Uses specified queue. + */ +template< typename IteratorType > +inline cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer ) +{ + typedef typename std::iterator_traits::value_type DataType; + cl_int error; + + ::size_t length = endIterator-startIterator; + ::size_t byteLength = length*sizeof(DataType); + + DataType *pointer = + static_cast(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_WRITE, 0, byteLength, 0, 0, &error)); + // if exceptions enabled, enqueueMapBuffer will throw + if( error != CL_SUCCESS ) { + return error; + } +#if defined(_MSC_VER) + std::copy( + startIterator, + endIterator, + stdext::checked_array_iterator( + pointer, length)); +#else + std::copy(startIterator, endIterator, pointer); +#endif + Event endEvent; + error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent); + // if exceptions enabled, enqueueUnmapMemObject will throw + if( error != CL_SUCCESS ) { + return error; + } + endEvent.wait(); + return CL_SUCCESS; +} + +/** + * Blocking copy operation between iterators and a buffer. + * Device to Host. + * Uses specified queue. + */ +template< typename IteratorType > +inline cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator ) +{ + typedef typename std::iterator_traits::value_type DataType; + cl_int error; + + ::size_t length = endIterator-startIterator; + ::size_t byteLength = length*sizeof(DataType); + + DataType *pointer = + static_cast(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_READ, 0, byteLength, 0, 0, &error)); + // if exceptions enabled, enqueueMapBuffer will throw + if( error != CL_SUCCESS ) { + return error; + } + std::copy(pointer, pointer + length, startIterator); + Event endEvent; + error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent); + // if exceptions enabled, enqueueUnmapMemObject will throw + if( error != CL_SUCCESS ) { + return error; + } + endEvent.wait(); + return CL_SUCCESS; +} + +#if defined(CL_VERSION_1_1) +inline cl_int enqueueReadBufferRect( + const Buffer& buffer, + cl_bool blocking, + const size_t<3>& buffer_offset, + const size_t<3>& host_offset, + const size_t<3>& region, + ::size_t buffer_row_pitch, + ::size_t buffer_slice_pitch, + ::size_t host_row_pitch, + ::size_t host_slice_pitch, + void *ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueReadBufferRect( + buffer, + blocking, + buffer_offset, + host_offset, + region, + buffer_row_pitch, + buffer_slice_pitch, + host_row_pitch, + host_slice_pitch, + ptr, + events, + event); +} + +inline cl_int enqueueWriteBufferRect( + const Buffer& buffer, + cl_bool blocking, + const size_t<3>& buffer_offset, + const size_t<3>& host_offset, + const size_t<3>& region, + ::size_t buffer_row_pitch, + ::size_t buffer_slice_pitch, + ::size_t host_row_pitch, + ::size_t host_slice_pitch, + const void *ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueWriteBufferRect( + buffer, + blocking, + buffer_offset, + host_offset, + region, + buffer_row_pitch, + buffer_slice_pitch, + host_row_pitch, + host_slice_pitch, + ptr, + events, + event); +} + +inline cl_int enqueueCopyBufferRect( + const Buffer& src, + const Buffer& dst, + const size_t<3>& src_origin, + const size_t<3>& dst_origin, + const size_t<3>& region, + ::size_t src_row_pitch, + ::size_t src_slice_pitch, + ::size_t dst_row_pitch, + ::size_t dst_slice_pitch, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueCopyBufferRect( + src, + dst, + src_origin, + dst_origin, + region, + src_row_pitch, + src_slice_pitch, + dst_row_pitch, + dst_slice_pitch, + events, + event); +} +#endif + +inline cl_int enqueueReadImage( + const Image& image, + cl_bool blocking, + const size_t<3>& origin, + const size_t<3>& region, + ::size_t row_pitch, + ::size_t slice_pitch, + void* ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueReadImage( + image, + blocking, + origin, + region, + row_pitch, + slice_pitch, + ptr, + events, + event); +} + +inline cl_int enqueueWriteImage( + const Image& image, + cl_bool blocking, + const size_t<3>& origin, + const size_t<3>& region, + ::size_t row_pitch, + ::size_t slice_pitch, + const void* ptr, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueWriteImage( + image, + blocking, + origin, + region, + row_pitch, + slice_pitch, + ptr, + events, + event); +} + +inline cl_int enqueueCopyImage( + const Image& src, + const Image& dst, + const size_t<3>& src_origin, + const size_t<3>& dst_origin, + const size_t<3>& region, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueCopyImage( + src, + dst, + src_origin, + dst_origin, + region, + events, + event); +} + +inline cl_int enqueueCopyImageToBuffer( + const Image& src, + const Buffer& dst, + const size_t<3>& src_origin, + const size_t<3>& region, + ::size_t dst_offset, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueCopyImageToBuffer( + src, + dst, + src_origin, + region, + dst_offset, + events, + event); +} + +inline cl_int enqueueCopyBufferToImage( + const Buffer& src, + const Image& dst, + ::size_t src_offset, + const size_t<3>& dst_origin, + const size_t<3>& region, + const VECTOR_CLASS* events = NULL, + Event* event = NULL) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.enqueueCopyBufferToImage( + src, + dst, + src_offset, + dst_origin, + region, + events, + event); +} + + +inline cl_int flush(void) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + return queue.flush(); +} + +inline cl_int finish(void) +{ + cl_int error; + CommandQueue queue = CommandQueue::getDefault(&error); + + if (error != CL_SUCCESS) { + return error; + } + + + return queue.finish(); +} + +// Kernel Functor support +// New interface as of September 2011 +// Requires the C++11 std::tr1::function (note do not support TR1) +// Visual Studio 2010 and GCC 4.2 + +struct EnqueueArgs +{ + CommandQueue queue_; + const NDRange offset_; + const NDRange global_; + const NDRange local_; + VECTOR_CLASS events_; + + EnqueueArgs(NDRange global) : + queue_(CommandQueue::getDefault()), + offset_(NullRange), + global_(global), + local_(NullRange) + { + + } + + EnqueueArgs(NDRange global, NDRange local) : + queue_(CommandQueue::getDefault()), + offset_(NullRange), + global_(global), + local_(local) + { + + } + + EnqueueArgs(NDRange offset, NDRange global, NDRange local) : + queue_(CommandQueue::getDefault()), + offset_(offset), + global_(global), + local_(local) + { + + } + + EnqueueArgs(Event e, NDRange global) : + queue_(CommandQueue::getDefault()), + offset_(NullRange), + global_(global), + local_(NullRange) + { + events_.push_back(e); + } + + EnqueueArgs(Event e, NDRange global, NDRange local) : + queue_(CommandQueue::getDefault()), + offset_(NullRange), + global_(global), + local_(local) + { + events_.push_back(e); + } + + EnqueueArgs(Event e, NDRange offset, NDRange global, NDRange local) : + queue_(CommandQueue::getDefault()), + offset_(offset), + global_(global), + local_(local) + { + events_.push_back(e); + } + + EnqueueArgs(const VECTOR_CLASS &events, NDRange global) : + queue_(CommandQueue::getDefault()), + offset_(NullRange), + global_(global), + local_(NullRange), + events_(events) + { + + } + + EnqueueArgs(const VECTOR_CLASS &events, NDRange global, NDRange local) : + queue_(CommandQueue::getDefault()), + offset_(NullRange), + global_(global), + local_(local), + events_(events) + { + + } + + EnqueueArgs(const VECTOR_CLASS &events, NDRange offset, NDRange global, NDRange local) : + queue_(CommandQueue::getDefault()), + offset_(offset), + global_(global), + local_(local), + events_(events) + { + + } + + EnqueueArgs(CommandQueue &queue, NDRange global) : + queue_(queue), + offset_(NullRange), + global_(global), + local_(NullRange) + { + + } + + EnqueueArgs(CommandQueue &queue, NDRange global, NDRange local) : + queue_(queue), + offset_(NullRange), + global_(global), + local_(local) + { + + } + + EnqueueArgs(CommandQueue &queue, NDRange offset, NDRange global, NDRange local) : + queue_(queue), + offset_(offset), + global_(global), + local_(local) + { + + } + + EnqueueArgs(CommandQueue &queue, Event e, NDRange global) : + queue_(queue), + offset_(NullRange), + global_(global), + local_(NullRange) + { + events_.push_back(e); + } + + EnqueueArgs(CommandQueue &queue, Event e, NDRange global, NDRange local) : + queue_(queue), + offset_(NullRange), + global_(global), + local_(local) + { + events_.push_back(e); + } + + EnqueueArgs(CommandQueue &queue, Event e, NDRange offset, NDRange global, NDRange local) : + queue_(queue), + offset_(offset), + global_(global), + local_(local) + { + events_.push_back(e); + } + + EnqueueArgs(CommandQueue &queue, const VECTOR_CLASS &events, NDRange global) : + queue_(queue), + offset_(NullRange), + global_(global), + local_(NullRange), + events_(events) + { + + } + + EnqueueArgs(CommandQueue &queue, const VECTOR_CLASS &events, NDRange global, NDRange local) : + queue_(queue), + offset_(NullRange), + global_(global), + local_(local), + events_(events) + { + + } + + EnqueueArgs(CommandQueue &queue, const VECTOR_CLASS &events, NDRange offset, NDRange global, NDRange local) : + queue_(queue), + offset_(offset), + global_(global), + local_(local), + events_(events) + { + + } +}; + +namespace detail { + +class NullType {}; + +template +struct SetArg +{ + static void set (Kernel kernel, T0 arg) + { + kernel.setArg(index, arg); + } +}; + +template +struct SetArg +{ + static void set (Kernel, NullType) + { + } +}; + +template < + typename T0, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6, typename T7, + typename T8, typename T9, typename T10, typename T11, + typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, + typename T20, typename T21, typename T22, typename T23, + typename T24, typename T25, typename T26, typename T27, + typename T28, typename T29, typename T30, typename T31 + +> +class KernelFunctorGlobal +{ +private: + Kernel kernel_; + +public: + KernelFunctorGlobal( + Kernel kernel) : + kernel_(kernel) + {} + + KernelFunctorGlobal( + const Program& program, + const STRING_CLASS name, + cl_int * err = NULL) : + kernel_(program, name.c_str(), err) + {} + + Event operator() ( + const EnqueueArgs& args, + T0 t0, + T1 t1 = NullType(), + T2 t2 = NullType(), + T3 t3 = NullType(), + T4 t4 = NullType(), + T5 t5 = NullType(), + T6 t6 = NullType(), + T7 t7 = NullType(), + T8 t8 = NullType(), + T9 t9 = NullType(), + T10 t10 = NullType(), + T11 t11 = NullType(), + T12 t12 = NullType(), + T13 t13 = NullType(), + T14 t14 = NullType(), + T15 t15 = NullType(), + T16 t16 = NullType(), + T17 t17 = NullType(), + T18 t18 = NullType(), + T19 t19 = NullType(), + T20 t20 = NullType(), + T21 t21 = NullType(), + T22 t22 = NullType(), + T23 t23 = NullType(), + T24 t24 = NullType(), + T25 t25 = NullType(), + T26 t26 = NullType(), + T27 t27 = NullType(), + T28 t28 = NullType(), + T29 t29 = NullType(), + T30 t30 = NullType(), + T31 t31 = NullType() + + ) + { + Event event; + SetArg<0, T0>::set(kernel_, t0); + SetArg<1, T1>::set(kernel_, t1); + SetArg<2, T2>::set(kernel_, t2); + SetArg<3, T3>::set(kernel_, t3); + SetArg<4, T4>::set(kernel_, t4); + SetArg<5, T5>::set(kernel_, t5); + SetArg<6, T6>::set(kernel_, t6); + SetArg<7, T7>::set(kernel_, t7); + SetArg<8, T8>::set(kernel_, t8); + SetArg<9, T9>::set(kernel_, t9); + SetArg<10, T10>::set(kernel_, t10); + SetArg<11, T11>::set(kernel_, t11); + SetArg<12, T12>::set(kernel_, t12); + SetArg<13, T13>::set(kernel_, t13); + SetArg<14, T14>::set(kernel_, t14); + SetArg<15, T15>::set(kernel_, t15); + SetArg<16, T16>::set(kernel_, t16); + SetArg<17, T17>::set(kernel_, t17); + SetArg<18, T18>::set(kernel_, t18); + SetArg<19, T19>::set(kernel_, t19); + SetArg<20, T20>::set(kernel_, t20); + SetArg<21, T21>::set(kernel_, t21); + SetArg<22, T22>::set(kernel_, t22); + SetArg<23, T23>::set(kernel_, t23); + SetArg<24, T24>::set(kernel_, t24); + SetArg<25, T25>::set(kernel_, t25); + SetArg<26, T26>::set(kernel_, t26); + SetArg<27, T27>::set(kernel_, t27); + SetArg<28, T28>::set(kernel_, t28); + SetArg<29, T29>::set(kernel_, t29); + SetArg<30, T30>::set(kernel_, t30); + SetArg<31, T31>::set(kernel_, t31); + + + args.queue_.enqueueNDRangeKernel( + kernel_, + args.offset_, + args.global_, + args.local_, + &args.events_, + &event); + + return event; + } + +}; + +//------------------------------------------------------------------------------------------------------ + + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21, + typename T22, + typename T23, + typename T24, + typename T25, + typename T26, + typename T27, + typename T28, + typename T29, + typename T30, + typename T31> +struct functionImplementation_ +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + T30, + T31> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 32)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + T30, + T31); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21, + T22 arg22, + T23 arg23, + T24 arg24, + T25 arg25, + T26 arg26, + T27 arg27, + T28 arg28, + T29 arg29, + T30 arg30, + T31 arg31) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23, + arg24, + arg25, + arg26, + arg27, + arg28, + arg29, + arg30, + arg31); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21, + typename T22, + typename T23, + typename T24, + typename T25, + typename T26, + typename T27, + typename T28, + typename T29, + typename T30> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + T30, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + T30, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 31)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + T30); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21, + T22 arg22, + T23 arg23, + T24 arg24, + T25 arg25, + T26 arg26, + T27 arg27, + T28 arg28, + T29 arg29, + T30 arg30) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23, + arg24, + arg25, + arg26, + arg27, + arg28, + arg29, + arg30); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21, + typename T22, + typename T23, + typename T24, + typename T25, + typename T26, + typename T27, + typename T28, + typename T29> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 30)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + T29); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21, + T22 arg22, + T23 arg23, + T24 arg24, + T25 arg25, + T26 arg26, + T27 arg27, + T28 arg28, + T29 arg29) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23, + arg24, + arg25, + arg26, + arg27, + arg28, + arg29); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21, + typename T22, + typename T23, + typename T24, + typename T25, + typename T26, + typename T27, + typename T28> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 29)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + T28); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21, + T22 arg22, + T23 arg23, + T24 arg24, + T25 arg25, + T26 arg26, + T27 arg27, + T28 arg28) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23, + arg24, + arg25, + arg26, + arg27, + arg28); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21, + typename T22, + typename T23, + typename T24, + typename T25, + typename T26, + typename T27> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 28)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + T27); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21, + T22 arg22, + T23 arg23, + T24 arg24, + T25 arg25, + T26 arg26, + T27 arg27) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23, + arg24, + arg25, + arg26, + arg27); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21, + typename T22, + typename T23, + typename T24, + typename T25, + typename T26> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 27)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + T26); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21, + T22 arg22, + T23 arg23, + T24 arg24, + T25 arg25, + T26 arg26) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23, + arg24, + arg25, + arg26); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21, + typename T22, + typename T23, + typename T24, + typename T25> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 26)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + T25); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21, + T22 arg22, + T23 arg23, + T24 arg24, + T25 arg25) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23, + arg24, + arg25); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21, + typename T22, + typename T23, + typename T24> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 25)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + T24); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21, + T22 arg22, + T23 arg23, + T24 arg24) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23, + arg24); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21, + typename T22, + typename T23> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 24)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + T23); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21, + T22 arg22, + T23 arg23) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22, + arg23); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21, + typename T22> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 23)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + T22); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21, + T22 arg22) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21, + arg22); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20, + typename T21> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 22)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + T21); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20, + T21 arg21) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20, + arg21); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19, + typename T20> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 21)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + T20); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19, + T20 arg20) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19, + arg20); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18, + typename T19> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 20)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + T19); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18, + T19 arg19) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18, + arg19); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17, + typename T18> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 19)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + T18); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17, + T18 arg18) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17, + arg18); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16, + typename T17> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 18)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + T17); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16, + T17 arg17) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16, + arg17); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15, + typename T16> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 17)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + T16); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15, + T16 arg16) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15, + arg16); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14, + typename T15> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 16)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + T15); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14, + T15 arg15) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14, + arg15); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13, + typename T14> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 15)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + T14); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13, + T14 arg14) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13, + arg14); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12, + typename T13> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 14)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + T13); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12, + T13 arg13) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12, + arg13); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11, + typename T12> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 13)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + T12); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11, + T12 arg12) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11, + arg12); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10, + typename T11> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 12)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + T11); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10, + T11 arg11) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10, + arg11); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9, + typename T10> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 11)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + T10); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9, + T10 arg10) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9, + arg10); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8, + typename T9> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 10)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + T9); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8, + T9 arg9) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8, + arg9); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7, + typename T8> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 9)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7, + T8 arg8) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7, + arg8); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6, + typename T7> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 8)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6, + T7); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6, + T7 arg7) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6, + arg7); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5, + typename T6> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + T6, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + T6, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 7)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5, + T6); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5, + T6 arg6) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5, + arg6); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + T5, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + T5, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 6)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4, + T5); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4, + T5 arg5) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4, + arg5); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3, + typename T4> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + T4, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + T4, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 5)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3, + T4); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3, + T4 arg4) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3, + arg4); + } + + +}; + +template< + typename T0, + typename T1, + typename T2, + typename T3> +struct functionImplementation_ +< T0, + T1, + T2, + T3, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + T3, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 4)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2, + T3); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2, + T3 arg3) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2, + arg3); + } + + +}; + +template< + typename T0, + typename T1, + typename T2> +struct functionImplementation_ +< T0, + T1, + T2, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + T2, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 3)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1, + T2); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1, + T2 arg2) + { + return functor_( + enqueueArgs, + arg0, + arg1, + arg2); + } + + +}; + +template< + typename T0, + typename T1> +struct functionImplementation_ +< T0, + T1, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + T1, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 2)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0, + T1); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0, + T1 arg1) + { + return functor_( + enqueueArgs, + arg0, + arg1); + } + + +}; + +template< + typename T0> +struct functionImplementation_ +< T0, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> +{ + typedef detail::KernelFunctorGlobal< + T0, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType, + NullType> FunctorType; + + FunctorType functor_; + + functionImplementation_(const FunctorType &functor) : + functor_(functor) + { + + #if (defined(_WIN32) && defined(_VARIADIC_MAX) && (_VARIADIC_MAX < 1)) + // Fail variadic expansion for dev11 + static_assert(0, "Visual Studio has a hard limit of argument count for a std::function expansion. Please define _VARIADIC_MAX to be 10. If you need more arguments than that VC12 and below cannot support it."); + #endif + + } + + //! \brief Return type of the functor + typedef Event result_type; + + //! \brief Function signature of kernel functor with no event dependency. + typedef Event type_( + const EnqueueArgs&, + T0); + + Event operator()( + const EnqueueArgs& enqueueArgs, + T0 arg0) + { + return functor_( + enqueueArgs, + arg0); + } + + +}; + + + + + +} // namespace detail + +//---------------------------------------------------------------------------------------------- + +template < + typename T0, typename T1 = detail::NullType, typename T2 = detail::NullType, + typename T3 = detail::NullType, typename T4 = detail::NullType, + typename T5 = detail::NullType, typename T6 = detail::NullType, + typename T7 = detail::NullType, typename T8 = detail::NullType, + typename T9 = detail::NullType, typename T10 = detail::NullType, + typename T11 = detail::NullType, typename T12 = detail::NullType, + typename T13 = detail::NullType, typename T14 = detail::NullType, + typename T15 = detail::NullType, typename T16 = detail::NullType, + typename T17 = detail::NullType, typename T18 = detail::NullType, + typename T19 = detail::NullType, typename T20 = detail::NullType, + typename T21 = detail::NullType, typename T22 = detail::NullType, + typename T23 = detail::NullType, typename T24 = detail::NullType, + typename T25 = detail::NullType, typename T26 = detail::NullType, + typename T27 = detail::NullType, typename T28 = detail::NullType, + typename T29 = detail::NullType, typename T30 = detail::NullType, + typename T31 = detail::NullType + +> +struct make_kernel : + public detail::functionImplementation_< + T0, T1, T2, T3, + T4, T5, T6, T7, + T8, T9, T10, T11, + T12, T13, T14, T15, + T16, T17, T18, T19, + T20, T21, T22, T23, + T24, T25, T26, T27, + T28, T29, T30, T31 + + > +{ +public: + typedef detail::KernelFunctorGlobal< + T0, T1, T2, T3, + T4, T5, T6, T7, + T8, T9, T10, T11, + T12, T13, T14, T15, + T16, T17, T18, T19, + T20, T21, T22, T23, + T24, T25, T26, T27, + T28, T29, T30, T31 + + > FunctorType; + + make_kernel( + const Program& program, + const STRING_CLASS name, + cl_int * err = NULL) : + detail::functionImplementation_< + T0, T1, T2, T3, + T4, T5, T6, T7, + T8, T9, T10, T11, + T12, T13, T14, T15, + T16, T17, T18, T19, + T20, T21, T22, T23, + T24, T25, T26, T27, + T28, T29, T30, T31 + + >( + FunctorType(program, name, err)) + {} + + make_kernel( + const Kernel kernel) : + detail::functionImplementation_< + T0, T1, T2, T3, + T4, T5, T6, T7, + T8, T9, T10, T11, + T12, T13, T14, T15, + T16, T17, T18, T19, + T20, T21, T22, T23, + T24, T25, T26, T27, + T28, T29, T30, T31 + + >( + FunctorType(kernel)) + {} +}; + + +//---------------------------------------------------------------------------------------------------------------------- + +#undef __ERR_STR +#if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS) +#undef __GET_DEVICE_INFO_ERR +#undef __GET_PLATFORM_INFO_ERR +#undef __GET_DEVICE_IDS_ERR +#undef __GET_CONTEXT_INFO_ERR +#undef __GET_EVENT_INFO_ERR +#undef __GET_EVENT_PROFILE_INFO_ERR +#undef __GET_MEM_OBJECT_INFO_ERR +#undef __GET_IMAGE_INFO_ERR +#undef __GET_SAMPLER_INFO_ERR +#undef __GET_KERNEL_INFO_ERR +#undef __GET_KERNEL_ARG_INFO_ERR +#undef __GET_KERNEL_WORK_GROUP_INFO_ERR +#undef __GET_PROGRAM_INFO_ERR +#undef __GET_PROGRAM_BUILD_INFO_ERR +#undef __GET_COMMAND_QUEUE_INFO_ERR + +#undef __CREATE_CONTEXT_ERR +#undef __CREATE_CONTEXT_FROM_TYPE_ERR +#undef __GET_SUPPORTED_IMAGE_FORMATS_ERR + +#undef __CREATE_BUFFER_ERR +#undef __CREATE_SUBBUFFER_ERR +#undef __CREATE_IMAGE2D_ERR +#undef __CREATE_IMAGE3D_ERR +#undef __CREATE_SAMPLER_ERR +#undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR + +#undef __CREATE_USER_EVENT_ERR +#undef __SET_USER_EVENT_STATUS_ERR +#undef __SET_EVENT_CALLBACK_ERR +#undef __SET_PRINTF_CALLBACK_ERR + +#undef __WAIT_FOR_EVENTS_ERR + +#undef __CREATE_KERNEL_ERR +#undef __SET_KERNEL_ARGS_ERR +#undef __CREATE_PROGRAM_WITH_SOURCE_ERR +#undef __CREATE_PROGRAM_WITH_BINARY_ERR +#undef __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR +#undef __BUILD_PROGRAM_ERR +#undef __CREATE_KERNELS_IN_PROGRAM_ERR + +#undef __CREATE_COMMAND_QUEUE_ERR +#undef __SET_COMMAND_QUEUE_PROPERTY_ERR +#undef __ENQUEUE_READ_BUFFER_ERR +#undef __ENQUEUE_WRITE_BUFFER_ERR +#undef __ENQUEUE_READ_BUFFER_RECT_ERR +#undef __ENQUEUE_WRITE_BUFFER_RECT_ERR +#undef __ENQEUE_COPY_BUFFER_ERR +#undef __ENQEUE_COPY_BUFFER_RECT_ERR +#undef __ENQUEUE_READ_IMAGE_ERR +#undef __ENQUEUE_WRITE_IMAGE_ERR +#undef __ENQUEUE_COPY_IMAGE_ERR +#undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR +#undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR +#undef __ENQUEUE_MAP_BUFFER_ERR +#undef __ENQUEUE_MAP_IMAGE_ERR +#undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR +#undef __ENQUEUE_NDRANGE_KERNEL_ERR +#undef __ENQUEUE_TASK_ERR +#undef __ENQUEUE_NATIVE_KERNEL + +#undef __CL_EXPLICIT_CONSTRUCTORS + +#undef __UNLOAD_COMPILER_ERR +#endif //__CL_USER_OVERRIDE_ERROR_STRINGS + +#undef __CL_FUNCTION_TYPE + +// Extensions +/** + * Deprecated APIs for 1.2 + */ +#if defined(CL_VERSION_1_1) +#undef __INIT_CL_EXT_FCN_PTR +#endif // #if defined(CL_VERSION_1_1) +#undef __CREATE_SUB_DEVICES + +#if defined(USE_CL_DEVICE_FISSION) +#undef __PARAM_NAME_DEVICE_FISSION +#endif // USE_CL_DEVICE_FISSION + +#undef __DEFAULT_NOT_INITIALIZED +#undef __DEFAULT_BEING_INITIALIZED +#undef __DEFAULT_INITIALIZED + +#undef CL_HPP_RVALUE_REFERENCES_SUPPORTED +#undef CL_HPP_NOEXCEPT + +} // namespace cl + +#endif // CL_HPP_ diff --git a/GPU_version/svo/include/gpu_svo/cl_class.h b/GPU_version/svo/include/gpu_svo/cl_class.h index bffee33..915305e 100644 --- a/GPU_version/svo/include/gpu_svo/cl_class.h +++ b/GPU_version/svo/include/gpu_svo/cl_class.h @@ -4,7 +4,7 @@ #ifndef VIO_OPENCL_CL_CLASS_H #define VIO_OPENCL_CL_CLASS_H -#include +#include #include #include #include diff --git a/GPU_version/svo/include/gpu_svo/config.h b/GPU_version/svo/include/gpu_svo/config.h index e1c97b1..1001fb6 100644 --- a/GPU_version/svo/include/gpu_svo/config.h +++ b/GPU_version/svo/include/gpu_svo/config.h @@ -122,17 +122,17 @@ public: /// acc white noise in continuous. static double& ACC_Noise() { return getInstance().ACC_noise; } - /// acc white noise in continuous. + /// Gro white noise in continuous. static double& GYO_Noise() { return getInstance().GYO_noise; } /// integration uncertainty continuous static double& IUC() { return getInstance().iuc; } - // acc bias in continuous + /// acc bias in continuous static double& ABC() { return getInstance().abc; } - // gyro bias in continuous + /// gyro bias in continuous static double& GBC() { return getInstance().gbc; } - // error in the bias used for preintegration + /// error in the bias used for preintegration static double& EBP() { return getInstance().ebp; } - // the noise used for projection + /// the noise used for projection static double& NRP() { return getInstance().nrp; } diff --git a/GPU_version/svo/kernel/fast-gray.cl b/GPU_version/svo/kernel/fast-gray.cl index ec36066..ce6a927 100644 --- a/GPU_version/svo/kernel/fast-gray.cl +++ b/GPU_version/svo/kernel/fast-gray.cl @@ -1,6 +1,9 @@ // Copyright (C) 2021 Majid Geravand // Copyright (C) 2021 Gfuse +// Enable OpenCL 32-bit integer atomic functions. +#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable + __kernel void fast_gray( __read_only image2d_t image, __global int2 * corners, diff --git a/GPU_version/svo/src/feature_detection.cpp b/GPU_version/svo/src/feature_detection.cpp index 3a98d20..b5823dd 100644 --- a/GPU_version/svo/src/feature_detection.cpp +++ b/GPU_version/svo/src/feature_detection.cpp @@ -80,7 +80,7 @@ void FastDetector::detect( int icorner[1]={0}; gpu_fast_->reload_buf(0,2,icorner); gpu_fast_->run(0,img_pyr[L].cols,img_pyr[L].rows); - cl_int2 fast_corners[1000000]; + cl_int2 fast_corners[350000]; gpu_fast_->read(0,1,fast_corners); int count[1]={0}; gpu_fast_->read(0,2,count); @@ -97,18 +97,15 @@ void FastDetector::detect( const float score = vk::shiTomasiScore(img_pyr[L], fast_corners[i].x, fast_corners[i].y); - if(score > corners.at(k).score) - corners.at(k) = Corner(fast_corners[i].x*scale, fast_corners[i].y*scale, score, L, 0.0f); + if(score > corners.at(k).score){ + corners.at(k) = Corner(fast_corners[i].x*scale, fast_corners[i].y*scale, score, L, 0.0f); + // Create feature for every corner that has high enough corner score + if(corners.at(k).score > detection_threshold) + fts.push_back(new Feature(frame, Vector2d(corners.at(k).x, corners.at(k).y), corners.at(k).level)); + } } } - - // Create feature for every corner that has high enough corner score - std::for_each(corners.begin(), corners.end(), [&](Corner& c) { - if(c.score > detection_threshold) - fts.push_back(new Feature(frame, Vector2d(c.x, c.y), c.level)); - }); - resetGrid(); } diff --git a/GPU_version/svo/src/frame_handler_mono.cpp b/GPU_version/svo/src/frame_handler_mono.cpp index 1e6a98e..cb4acf6 100644 --- a/GPU_version/svo/src/frame_handler_mono.cpp +++ b/GPU_version/svo/src/frame_handler_mono.cpp @@ -38,10 +38,10 @@ FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam,Sophus::SE3& SE_init) { gpu_fast_= new opencl(); gpu_fast_->make_kernel("fast_gray"); - cv::Mat img=cv::Mat(cv::Size(1000, 1000),CV_8UC1); + cv::Mat img=cv::Mat(cv::Size(700, 500),CV_8UC1); gpu_fast_->write_buf(0,0,img); - cl_int2 corners_[1000000]; - gpu_fast_->write_buf(0,1,1000000,corners_); + cl_int2 corners_[350000]; + gpu_fast_->write_buf(0,1,350000,corners_); int icorner[1]={0}; gpu_fast_->write_buf(0,2,1,icorner); gpu_fast_->write_buf(0,3,(1 << 18)); diff --git a/GPU_version/svo/src/imu_integration.cpp b/GPU_version/svo/src/imu_integration.cpp index b3f80ab..922ef66 100644 --- a/GPU_version/svo/src/imu_integration.cpp +++ b/GPU_version/svo/src/imu_integration.cpp @@ -111,6 +111,8 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size }else{ if(imu_n<1)return false; auto preint_imu_combined =dynamic_cast(*preintegratedPtr); + //preint_imu_combined.predict(*statePtr,*imu_biasPtr).print(); + //std::cerr<T_f_w_.matrix(); valuesPtr->insert(P(imu_factor_id), gtsam::Pose3(new_frame->T_f_w_.matrix())); valuesPtr->insert(V(imu_factor_id), statePtr->v()); valuesPtr->insert(B(imu_factor_id), *imu_biasPtr); diff --git a/GPU_version/vio/launch/Px30.launch b/GPU_version/vio/launch/Px30.launch index f57f8c0..914364e 100644 --- a/GPU_version/vio/launch/Px30.launch +++ b/GPU_version/vio/launch/Px30.launch @@ -10,9 +10,9 @@ - - - + + + From 58849a0b7f5839f2f6d05db469ef1af650ab16e7 Mon Sep 17 00:00:00 2001 From: gfuse Date: Sat, 15 May 2021 17:39:56 +0200 Subject: [PATCH 192/215] edit frames --- GPU_version/vio/launch/Px30.launch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GPU_version/vio/launch/Px30.launch b/GPU_version/vio/launch/Px30.launch index 914364e..c02d6a2 100644 --- a/GPU_version/vio/launch/Px30.launch +++ b/GPU_version/vio/launch/Px30.launch @@ -10,9 +10,9 @@ - - - + + + From e3cb176ae085c010dce6cbbe71cd5a498f9813ab Mon Sep 17 00:00:00 2001 From: Majid Geravand <44868211+Gfuse@users.noreply.github.com> Date: Tue, 25 May 2021 11:15:32 +0200 Subject: [PATCH 193/215] Update README.md --- CPU_version/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CPU_version/README.md b/CPU_version/README.md index 00b6d87..e7c51db 100755 --- a/CPU_version/README.md +++ b/CPU_version/README.md @@ -37,6 +37,10 @@ The GTSAM documentation https://gtsam.org/tutorials/ #### Instructions +First install gtsam library => https://github.com/borglab/gtsam + +Then follow thw SVO instalation + See the Wiki for more instructions. https://github.com/uzh-rpg/rpg_svo/wiki and https://gtsam.org/get_started/ #### Contributing From 086037f5ed19acec8dbc941e90cb1ead781af32b Mon Sep 17 00:00:00 2001 From: Majid Geravand <44868211+Gfuse@users.noreply.github.com> Date: Tue, 25 May 2021 11:22:43 +0200 Subject: [PATCH 194/215] Update README.md --- CPU_version/README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/CPU_version/README.md b/CPU_version/README.md index e7c51db..f4296e1 100755 --- a/CPU_version/README.md +++ b/CPU_version/README.md @@ -39,7 +39,7 @@ The GTSAM documentation https://gtsam.org/tutorials/ First install gtsam library => https://github.com/borglab/gtsam -Then follow thw SVO instalation +Then follow the SVO instalation See the Wiki for more instructions. https://github.com/uzh-rpg/rpg_svo/wiki and https://gtsam.org/get_started/ @@ -47,3 +47,16 @@ See the Wiki for more instructions. https://github.com/uzh-rpg/rpg_svo/wiki and You are very welcome to contribute to SVO by opening a pull request via Github. I try to follow the ROS C++ style guide http://wiki.ros.org/CppStyleGuide + +## Setting + +You can edit the camera position in the launch file as (The IMU frame will rotate to align with camera frame based on the follwoing Eular angles): + + + + + +You can also edit the algorithm parameters in the follwoing file, please look at the config file to underestand the meaning of the parameters (CPU_version/svo/include/svo/config.h) + +CPU_version/vio_svo/param/vo_fast.yaml + From 3ce1beae0a78d0f7f2a174bf2288d9653ba13de2 Mon Sep 17 00:00:00 2001 From: Majid Geravand <44868211+Gfuse@users.noreply.github.com> Date: Tue, 25 May 2021 11:36:55 +0200 Subject: [PATCH 195/215] Update README.md --- CPU_version/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CPU_version/README.md b/CPU_version/README.md index f4296e1..18904c2 100755 --- a/CPU_version/README.md +++ b/CPU_version/README.md @@ -51,6 +51,8 @@ I try to follow the ROS C++ style guide http://wiki.ros.org/CppStyleGuide ## Setting You can edit the camera position in the launch file as (The IMU frame will rotate to align with camera frame based on the follwoing Eular angles): +CPU_version/vio_svo/launch/Px30.launch + From 18b999dc6d348ede7e094cd18028c61165f4f107 Mon Sep 17 00:00:00 2001 From: Majid Geravand <44868211+Gfuse@users.noreply.github.com> Date: Tue, 25 May 2021 11:37:45 +0200 Subject: [PATCH 196/215] Update README.md --- CPU_version/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CPU_version/README.md b/CPU_version/README.md index 18904c2..a4bf9c7 100755 --- a/CPU_version/README.md +++ b/CPU_version/README.md @@ -53,10 +53,10 @@ I try to follow the ROS C++ style guide http://wiki.ros.org/CppStyleGuide You can edit the camera position in the launch file as (The IMU frame will rotate to align with camera frame based on the follwoing Eular angles): CPU_version/vio_svo/launch/Px30.launch - - - - + + + + You can also edit the algorithm parameters in the follwoing file, please look at the config file to underestand the meaning of the parameters (CPU_version/svo/include/svo/config.h) From 568840e115b9591abfbbb1f7cf66047bf6ad8c0f Mon Sep 17 00:00:00 2001 From: Majid Geravand <44868211+Gfuse@users.noreply.github.com> Date: Tue, 25 May 2021 11:37:58 +0200 Subject: [PATCH 197/215] Update Px30.launch --- CPU_version/vio_svo/launch/Px30.launch | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CPU_version/vio_svo/launch/Px30.launch b/CPU_version/vio_svo/launch/Px30.launch index f6cad34..7e3e73c 100644 --- a/CPU_version/vio_svo/launch/Px30.launch +++ b/CPU_version/vio_svo/launch/Px30.launch @@ -9,10 +9,10 @@ - - - - + + + + From 1fba26dfef35460aebe194219a7f429044625a08 Mon Sep 17 00:00:00 2001 From: Majid Geravand <44868211+Gfuse@users.noreply.github.com> Date: Tue, 25 May 2021 11:38:22 +0200 Subject: [PATCH 198/215] Update README.md --- CPU_version/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPU_version/README.md b/CPU_version/README.md index a4bf9c7..8387b0e 100755 --- a/CPU_version/README.md +++ b/CPU_version/README.md @@ -55,7 +55,7 @@ CPU_version/vio_svo/launch/Px30.launch - + You can also edit the algorithm parameters in the follwoing file, please look at the config file to underestand the meaning of the parameters (CPU_version/svo/include/svo/config.h) From cd6f0c5b97f2322571806c689602a6de62eafc6e Mon Sep 17 00:00:00 2001 From: gfuse Date: Wed, 26 May 2021 10:50:20 +0200 Subject: [PATCH 199/215] debug GPU version --- GPU_version/svo/CMakeLists.txt | 18 +- .../svo/include/gpu_svo/abstract_camera.h | 77 ++++ GPU_version/svo/include/gpu_svo/aligned_mem.h | 127 ++++++ GPU_version/svo/include/gpu_svo/atan_camera.h | 91 ++++ GPU_version/svo/include/gpu_svo/config.h | 6 +- .../svo/include/gpu_svo/depth_filter.h | 6 +- GPU_version/svo/include/gpu_svo/for_it.hpp | 87 ++++ GPU_version/svo/include/gpu_svo/frame.h | 22 +- .../svo/include/gpu_svo/frame_handler_base.h | 16 +- .../svo/include/gpu_svo/frame_handler_mono.h | 5 +- GPU_version/svo/include/gpu_svo/global.h | 4 +- GPU_version/svo/include/gpu_svo/homography.h | 85 ++++ .../svo/include/gpu_svo/imu_integration.h | 84 +--- .../svo/include/gpu_svo/initialization.h | 1 + GPU_version/svo/include/gpu_svo/math_utils.h | 171 ++++++++ GPU_version/svo/include/gpu_svo/nlls_solver.h | 169 ++++++++ .../svo/include/gpu_svo/nlls_solver_impl.hpp | 323 ++++++++++++++ .../svo/include/gpu_svo/params_helper.h | 57 +++ GPU_version/svo/include/gpu_svo/patch_score.h | 225 ++++++++++ GPU_version/svo/include/gpu_svo/robust_cost.h | 156 +++++++ .../svo/include/gpu_svo/sparse_img_align.h | 7 +- .../svo/include/gpu_svo/svoVisionFactor.h | 27 +- .../include/gpu_svo/svoVisionFactorLandMark.h | 87 ++++ .../include/gpu_svo/svoVisionFactorSmall.h | 70 +++ GPU_version/svo/include/gpu_svo/timer.h | 81 ++++ GPU_version/svo/include/gpu_svo/vision.h | 77 ++++ GPU_version/svo/src/atan_camera.cpp | 82 ++++ GPU_version/svo/src/bundle_adjustment.cpp | 2 +- GPU_version/svo/src/config.cpp | 42 +- GPU_version/svo/src/depth_filter.cpp | 15 +- GPU_version/svo/src/feature_alignment.cpp | 4 +- GPU_version/svo/src/feature_detection.cpp | 2 +- GPU_version/svo/src/frame.cpp | 5 +- GPU_version/svo/src/frame_handler_base.cpp | 67 +-- GPU_version/svo/src/frame_handler_mono.cpp | 95 ++-- GPU_version/svo/src/homography.cpp | 285 ++++++++++++ GPU_version/svo/src/imu_integration.cpp | 118 +++-- GPU_version/svo/src/initialization.cpp | 72 +-- GPU_version/svo/src/matcher.cpp | 9 +- GPU_version/svo/src/math_utils.cpp | 202 +++++++++ GPU_version/svo/src/point.cpp | 2 +- GPU_version/svo/src/pose_optimizer.cpp | 4 +- GPU_version/svo/src/reprojector.cpp | 26 +- GPU_version/svo/src/robust_cost.cpp | 162 +++++++ GPU_version/svo/src/sparse_img_align.cpp | 12 +- GPU_version/svo/src/vision.cpp | 295 +++++++++++++ .../vio/include/vio_gpu/camera_loader.h | 46 ++ .../vio/include/vio_gpu/output_helper.h | 97 +++++ .../vio/include/vio_gpu/params_helper.h | 54 +++ GPU_version/vio/launch/Px30.launch | 8 +- GPU_version/vio/param/camera_atan.yaml | 8 - GPU_version/vio/param/camera_pinhole.yaml | 11 - GPU_version/vio/param/unity.yaml | 8 - GPU_version/vio/param/vo_accurate.yaml | 4 - GPU_version/vio/param/vo_fast.yaml | 13 +- GPU_version/vio/src/output_helper.cpp | 410 ++++++++++++++++++ GPU_version/vio/src/visualizer.cpp | 8 +- GPU_version/vio/src/vo_node.cpp | 6 +- 58 files changed, 3828 insertions(+), 425 deletions(-) create mode 100644 GPU_version/svo/include/gpu_svo/abstract_camera.h create mode 100644 GPU_version/svo/include/gpu_svo/aligned_mem.h create mode 100644 GPU_version/svo/include/gpu_svo/atan_camera.h create mode 100755 GPU_version/svo/include/gpu_svo/for_it.hpp create mode 100644 GPU_version/svo/include/gpu_svo/homography.h create mode 100644 GPU_version/svo/include/gpu_svo/math_utils.h create mode 100644 GPU_version/svo/include/gpu_svo/nlls_solver.h create mode 100644 GPU_version/svo/include/gpu_svo/nlls_solver_impl.hpp create mode 100644 GPU_version/svo/include/gpu_svo/params_helper.h create mode 100644 GPU_version/svo/include/gpu_svo/patch_score.h create mode 100644 GPU_version/svo/include/gpu_svo/robust_cost.h create mode 100644 GPU_version/svo/include/gpu_svo/svoVisionFactorLandMark.h create mode 100644 GPU_version/svo/include/gpu_svo/svoVisionFactorSmall.h create mode 100644 GPU_version/svo/include/gpu_svo/timer.h create mode 100644 GPU_version/svo/include/gpu_svo/vision.h create mode 100644 GPU_version/svo/src/atan_camera.cpp create mode 100644 GPU_version/svo/src/homography.cpp create mode 100644 GPU_version/svo/src/math_utils.cpp create mode 100644 GPU_version/svo/src/robust_cost.cpp create mode 100644 GPU_version/svo/src/vision.cpp create mode 100644 GPU_version/vio/include/vio_gpu/camera_loader.h create mode 100644 GPU_version/vio/include/vio_gpu/output_helper.h create mode 100644 GPU_version/vio/include/vio_gpu/params_helper.h delete mode 100644 GPU_version/vio/param/camera_atan.yaml delete mode 100644 GPU_version/vio/param/camera_pinhole.yaml delete mode 100644 GPU_version/vio/param/unity.yaml delete mode 100644 GPU_version/vio/param/vo_accurate.yaml create mode 100644 GPU_version/vio/src/output_helper.cpp diff --git a/GPU_version/svo/CMakeLists.txt b/GPU_version/svo/CMakeLists.txt index ed41132..ac021d6 100644 --- a/GPU_version/svo/CMakeLists.txt +++ b/GPU_version/svo/CMakeLists.txt @@ -5,8 +5,8 @@ CMAKE_MINIMUM_REQUIRED (VERSION 2.8.3) SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo SET(CMAKE_VERBOSE_MAKEFILE OFF) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") -set(CMAKE_C_STANDARD 14) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 11) # Set definitions ADD_DEFINITIONS(-DSVO_TRACE) @@ -21,11 +21,6 @@ IF(DEFINED ENV{ARM_ARCHITECTURE}) ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse -msse2 -msse3 -mssse3") ENDIF() -IF(CMAKE_COMPILER_IS_GNUCC) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") -ELSE() - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -ENDIF() SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -fsee -fomit-frame-pointer -fno-signed-zeros -fno-math-errno -funroll-loops") # Add plain cmake packages @@ -88,12 +83,17 @@ LIST(APPEND SOURCEFILES src/config.cpp src/sparse_img_align.cpp src/imu_integration.cpp - src/cl_class.cpp) + src/cl_class.cpp + src/atan_camera.cpp + src/math_utils.cpp + src/robust_cost.cpp + src/vision.cpp + src/homography.cpp) # Create svo library ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCEFILES}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LINK_LIBS} ) -set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14) +set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) target_compile_features(${PROJECT_NAME} PRIVATE cxx_range_for) ADD_DEFINITIONS(-DKERNEL_DIR=\"${PROJECT_SOURCE_DIR}/kernel\") diff --git a/GPU_version/svo/include/gpu_svo/abstract_camera.h b/GPU_version/svo/include/gpu_svo/abstract_camera.h new file mode 100644 index 0000000..5d643dc --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/abstract_camera.h @@ -0,0 +1,77 @@ +/* + * abstract_camera.h + * + * Created on: Jul 23, 2012 + * Author: cforster + */ + +#ifndef ABSTRACT_CAMERA_H_ +#define ABSTRACT_CAMERA_H_ + +#include + +namespace vk +{ + +using namespace std; +using namespace Eigen; + +class AbstractCamera +{ +protected: + + int width_; // TODO cannot be const because of omni-camera model + int height_; + +public: + + AbstractCamera() {}; // need this constructor for omni camera + AbstractCamera(int width, int height) : width_(width), height_(height) {}; + + virtual ~AbstractCamera() {}; + + /// Project from pixels to world coordiantes. Returns a bearing vector of unit length. + virtual Vector3d + cam2world(const double& x, const double& y) const = 0; + + /// Project from pixels to world coordiantes. Returns a bearing vector of unit length. + virtual Vector3d + cam2world(const Vector2d& px) const = 0; + + virtual Vector2d + world2cam(const Vector3d& xyz_c) const = 0; + + /// projects unit plane coordinates to camera coordinates + virtual Vector2d + world2cam(const Vector2d& uv) const = 0; + + virtual double + errorMultiplier2() const = 0; + + virtual double + errorMultiplier() const = 0; + + inline int width() const { return width_; } + + inline int height() const { return height_; } + + inline bool isInFrame(const Vector2i & obs, int boundary=0) const + { + if(obs[0]>=boundary && obs[0]=boundary && obs[1]= boundary && obs[0] < width()/(1<= boundary && obs[1] // memset +#include // memset +#include +#include + +namespace vk { +namespace aligned_mem { + + /// Check if the pointer is aligned to the specified byte granularity + inline bool + is_aligned8(const void* ptr) + { + return ((reinterpret_cast(ptr)) & 0x7) == 0; + } + + inline bool + is_aligned16(const void* ptr) + { + return ((reinterpret_cast(ptr)) & 0xF) == 0; + } + + template struct placement_delete + { + enum { Size = (1<= Size) { + placement_delete::free(buf+Size,M-Size); + placement_delete::destruct(buf); + } else { + placement_delete::free(buf, M); + } + } + }; + + template struct placement_delete + { + static inline void free(T*, size_t ) {} + }; + + inline void * aligned_alloc(size_t count, size_t alignment){ + void * mem = NULL; + assert(posix_memalign(&mem, alignment, count) == 0); + return mem; + } + + inline void aligned_free(void * memory) { + free(memory); + } + + template + inline T * aligned_alloc(size_t count, size_t alignment){ + void * data = aligned_alloc(sizeof(T)* count, alignment); + return new (data) T[count]; + } + + template + inline void aligned_free(T * memory, size_t count){ + placement_delete::free(memory, count); + aligned_free(memory); + } + + template inline void memfill(T* data, int n, const T val) + { + T* de = data + n; + for(;data < de; data++) + *data=val; + } + + template<> inline void memfill(unsigned char* data, int n, const unsigned char val) + { + memset(data, val, n); + } + + template<> inline void memfill(signed char* data, int n, const signed char val) + { + memset(data, val, n); + } + + template<> inline void memfill(char* data, int n, const char val) + { + memset(data, val, n); + } + + template + struct AlignedMem { + T* mem; + size_t count; + AlignedMem(size_t c) : count(c) { + mem = aligned_alloc(count, N); + } + ~AlignedMem() { + aligned_free(mem, count); + } + T* data() { return mem; } + const T* data() const { return mem; } + }; + +} // namespace aligned_mem +} // namespace vikit + + +#endif // VIKIT_ALIGNED_MEM_H_ diff --git a/GPU_version/svo/include/gpu_svo/atan_camera.h b/GPU_version/svo/include/gpu_svo/atan_camera.h new file mode 100644 index 0000000..49550b2 --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/atan_camera.h @@ -0,0 +1,91 @@ +/* + * atan_camera.h + * + * Created on: Aug 21, 2012 + * Author: cforster + * + * This class implements the FOV distortion model of Deverneay and Faugeras, + * Straight lines have to be straight, 2001. + * + * The code is an implementation of the ATAN class in PTAM by Georg Klein using Eigen. + */ + +#ifndef ATAN_CAMERA_H_ +#define ATAN_CAMERA_H_ + +#include +#include +#include +#include +#include + +namespace vk { + +using namespace std; +using namespace Eigen; + +class ATANCamera : public AbstractCamera { + +private: + double fx_, fy_; //!< focal length + double fx_inv_, fy_inv_; //!< inverse focal length + double cx_, cy_; //!< projection center + double s_, s_inv_; //!< distortion model coeff + double tans_; //!< distortion model coeff + double tans_inv_; //!< distortion model coeff + bool distortion_; //!< use distortion model? + + //! Radial distortion transformation factor: returns ration of distorted / undistorted radius. + inline double rtrans_factor(double r) const + { + if(r < 0.001 || s_ == 0.0) + return 1.0; + else + return (s_inv_* atan(r * tans_) / r); + }; + + //! Inverse radial distortion: returns un-distorted radius from distorted. + inline double invrtrans(double r) const + { + if(s_ == 0.0) + return r; + return (tan(r * s_) * tans_inv_); + }; + +public: + + ATANCamera(double width, double height, double fx, double fy, double dx, double dy, double s); + + ~ATANCamera(); + + virtual Vector3d + cam2world(const double& x, const double& y) const; + + virtual Vector3d + cam2world(const Vector2d& px) const; + + virtual Vector2d + world2cam(const Vector3d& xyz_c) const; + + virtual Vector2d + world2cam(const Vector2d& uv) const; + + const Vector2d focal_length() const + { + return Vector2d(fx_, fy_); + } + + virtual double errorMultiplier2() const + { + return fx_; + } + + virtual double errorMultiplier() const + { + return 4*fx_*fy_; + } +}; + +} // end namespace vk + +#endif /* ATAN_CAMERA_H_ */ diff --git a/GPU_version/svo/include/gpu_svo/config.h b/GPU_version/svo/include/gpu_svo/config.h index 1001fb6..9b3c26f 100644 --- a/GPU_version/svo/include/gpu_svo/config.h +++ b/GPU_version/svo/include/gpu_svo/config.h @@ -134,6 +134,10 @@ public: static double& EBP() { return getInstance().ebp; } /// the noise used for projection static double& NRP() { return getInstance().nrp; } + static double& Gravity() { return getInstance().gravity; } + static double& X_off() { return getInstance().acc_x_off; } + static double& Y_off() { return getInstance().acc_y_off; } + static double& Teta_off() { return getInstance().gyr_z_off; } private: @@ -169,7 +173,7 @@ private: size_t max_fts; size_t quality_min_fts; int quality_max_drop_fts; - double nrp,ebp,gbc,abc,iuc,ACC_noise,GYO_noise; + double nrp,ebp,gbc,abc,iuc,ACC_noise,GYO_noise,gravity,acc_x_off,acc_y_off,gyr_z_off; }; } // namespace svo diff --git a/GPU_version/svo/include/gpu_svo/depth_filter.h b/GPU_version/svo/include/gpu_svo/depth_filter.h index d56d256..07d71e5 100644 --- a/GPU_version/svo/include/gpu_svo/depth_filter.h +++ b/GPU_version/svo/include/gpu_svo/depth_filter.h @@ -20,7 +20,7 @@ #include #include #include -#include +//#include #include #include #include @@ -79,7 +79,7 @@ public: epi_search_1d(false), verbose(false), use_photometric_disparity_error(false), - max_n_kfs(3), + max_n_kfs(10), sigma_i_sq(5e-4), seed_convergence_sigma2_thresh(200.0) {} @@ -150,7 +150,7 @@ protected: bool new_keyframe_set_; //!< Do we have a new keyframe to process?. double new_keyframe_min_depth_; //!< Minimum depth in the new keyframe. Used for range in new seeds. double new_keyframe_mean_depth_; //!< Maximum depth in the new keyframe. Used for range in new seeds. - vk::PerformanceMonitor permon_; //!< Separate performance monitor since the DepthFilter runs in a parallel thread. + //vk::PerformanceMonitor permon_; //!< Separate performance monitor since the DepthFilter runs in a parallel thread. Matcher matcher_; /// Initialize new seeds from a frame. diff --git a/GPU_version/svo/include/gpu_svo/for_it.hpp b/GPU_version/svo/include/gpu_svo/for_it.hpp new file mode 100755 index 0000000..808f3cf --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/for_it.hpp @@ -0,0 +1,87 @@ +// +// Created by root on 5/12/21. +// + +#ifndef GPU_SVO_FOR_IT_H +#define GPU_SVO_FOR_IT_H +#include +#include +#include + +//https://stackoverflow.com/questions/24881799/get-index-in-c11-foreach-loop +// Wrapper class +template +class for_impl +{ +public: + // The return value of the operator* of the iterator, this + // is what you will get inside of the for loop + struct item + { + size_t index; + typename T::value_type & item; + }; + typedef item value_type; + + // Custom iterator with minimal interface + struct iterator + { + iterator(typename T::iterator _it, size_t counter=0) : + it(_it), counter(counter) + {} + + iterator operator++() + { + return iterator(++it, ++counter); + } + + bool operator!=(iterator other) + { + return it != other.it; + } + + typename T::iterator::value_type item() + { + return *it; + } + + value_type operator*() + { + return value_type{counter, *it}; + } + + size_t index() + { + return counter; + } + + private: + typename T::iterator it; + size_t counter; + }; + + for_impl(T & t) : container(t) {} + + iterator begin() + { + return iterator(container.begin()); + } + + iterator end() + { + return iterator(container.end()); + } + +private: + T & container; +}; + + +// A templated free function allows you to create the wrapper class +// conveniently +template +for_impl _for(T & t) +{ + return for_impl(t); +} +#endif //GPU_SVO_FOR_IT_H diff --git a/GPU_version/svo/include/gpu_svo/frame.h b/GPU_version/svo/include/gpu_svo/frame.h index 43b344e..3a0fef6 100644 --- a/GPU_version/svo/include/gpu_svo/frame.h +++ b/GPU_version/svo/include/gpu_svo/frame.h @@ -18,8 +18,8 @@ #define SVO_FRAME_H_ #include -#include -#include +#include +#include #include #include @@ -92,6 +92,8 @@ public: /// Transforms point coordinates in world-frame (w) to camera pixel coordinates (c). inline Vector2d w2c(const Vector3d& xyz_w) const { return cam_->world2cam( T_f_w_ * xyz_w ); } + /// Transforms point coordinates in world-frame (w) to camera pixel coordinates (c). + inline Vector2d w2px(const Vector3d& xyz_w) const { return cam_->world2cam( xyz_w ); } /// Transforms pixel coordinates (c) to frame unit sphere coordinates (f). inline Vector3d c2f(const Vector2d& px) const { return cam_->cam2world(px[0], px[1]); } @@ -111,6 +113,7 @@ public: /// Return the pose of the frame in the (w)orld coordinate frame. inline Vector3d pos() const { return T_f_w_.inverse().translation(); } + /// Frame jacobian for projection of 3D point in (f)rame coordinate to /// unit plane coordinates uv (focal length = 1). inline static void jacobian_xyz2uv( @@ -129,13 +132,26 @@ public: J(0,4) = -(1.0 + x*J(0,2)); // -(1.0 + x^2/z^2) J(0,5) = y*z_inv; // y/z - J(1,0) = 0.0; // 0 + J(1,0) = 0.0; // 0 J(1,1) = -z_inv; // -1/z J(1,2) = y*z_inv_2; // y/z^2 J(1,3) = 1.0 + y*J(1,2); // 1.0 + y^2/z^2 J(1,4) = -J(0,3); // -x*y/z^2 J(1,5) = -x*z_inv; // x/z } + inline static void jacobian_l2uv( + const Matrix& p, + Matrix& J){ + double A = -1.0*sqrt(p.z()); + double z_inv = -1/p.z(); + J(0,0) = z_inv; + J(0,1) = 0.0; + J(0,2) = p.x()*A; + + J(1,0) = 0.0; + J(1,1) = z_inv; + J(1,2) =A*p.y(); + } }; diff --git a/GPU_version/svo/include/gpu_svo/frame_handler_base.h b/GPU_version/svo/include/gpu_svo/frame_handler_base.h index 9b207b3..c8d84e5 100644 --- a/GPU_version/svo/include/gpu_svo/frame_handler_base.h +++ b/GPU_version/svo/include/gpu_svo/frame_handler_base.h @@ -18,8 +18,8 @@ #define SVO_FRAME_HANDLER_BASE_H_ #include -#include -#include +//#include +//#include #include #include #include @@ -29,7 +29,7 @@ namespace vk { class AbstractCamera; -class PerformanceMonitor; +//class PerformanceMonitor; } namespace svo @@ -80,19 +80,19 @@ public: TrackingQuality trackingQuality() const { return tracking_quality_; } /// Get the processing time of the previous iteration. - double lastProcessingTime() const { return timer_.getTime(); } + //double lastProcessingTime() const { return timer_.getTime(); } /// Get the number of feature observations of the last frame. - size_t lastNumObservations() const { return num_obs_last_; } + // size_t lastNumObservations() const { return num_obs_last_; } protected: Stage stage_; //!< Current stage of the algorithm. bool set_reset_; //!< Flag that the user can set. Will reset the system before the next iteration. bool set_start_; //!< Flag the user can set to start the system when the next image is received. Map map_; //!< Map of keyframes created by the slam system. - vk::Timer timer_; //!< Stopwatch to measure time to process frame. - vk::RingBuffer acc_frame_timings_; //!< Total processing time of the last 10 frames, used to give some user feedback on the performance. - vk::RingBuffer acc_num_obs_; //!< Number of observed features of the last 10 frames, used to give some user feedback on the tracking performance. + //vk::Timer timer_; //!< Stopwatch to measure time to process frame. + //vk::RingBuffer acc_frame_timings_; //!< Total processing time of the last 10 frames, used to give some user feedback on the performance. + //vk::RingBuffer acc_num_obs_; //!< Number of observed features of the last 10 frames, used to give some user feedback on the tracking performance. size_t num_obs_last_; //!< Number of observations in the previous frame. TrackingQuality tracking_quality_; //!< An estimate of the tracking quality based on the number of tracked features. diff --git a/GPU_version/svo/include/gpu_svo/frame_handler_mono.h b/GPU_version/svo/include/gpu_svo/frame_handler_mono.h index 58b8b22..22180d8 100644 --- a/GPU_version/svo/include/gpu_svo/frame_handler_mono.h +++ b/GPU_version/svo/include/gpu_svo/frame_handler_mono.h @@ -18,7 +18,7 @@ #define SVO_FRAME_HANDLER_H_ #include -#include +#include #include #include #include @@ -61,7 +61,7 @@ public: const SE3& T_kf_f, const cv::Mat& img, const double timestamp); - std::unique_ptr imu_integPtr_; //Integration of IMU + std::shared_ptr imu_integPtr_; //Integration of IMU protected: vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit). @@ -73,6 +73,7 @@ protected: initialization::KltHomographyInit* klt_homography_init_; //!< Used to estimate pose of the first two keyframes by estimating a homography. DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. opencl* gpu_fast_; + uint image_count_=0; /// Initialize the visual odometry algorithm. virtual void initialize(); diff --git a/GPU_version/svo/include/gpu_svo/global.h b/GPU_version/svo/include/gpu_svo/global.h index 03aff4e..f10358d 100644 --- a/GPU_version/svo/include/gpu_svo/global.h +++ b/GPU_version/svo/include/gpu_svo/global.h @@ -27,7 +27,7 @@ #include #include #include -#include +//#include #include #include #ifndef RPG_SVO_VIKIT_IS_VECTOR_SPECIALIZED //Guard for rpg_vikit @@ -78,6 +78,7 @@ namespace svo const double PI = 3.14159265; #ifdef SVO_TRACE + /* extern vk::PerformanceMonitor* g_permon; #define SVO_LOG(value) g_permon->log(std::string((#value)),(value)) #define SVO_LOG2(value1, value2) SVO_LOG(value1); SVO_LOG(value2) @@ -85,6 +86,7 @@ namespace svo #define SVO_LOG4(value1, value2, value3, value4) SVO_LOG2(value1, value2); SVO_LOG2(value3, value4) #define SVO_START_TIMER(name) g_permon->startTimer((name)) #define SVO_STOP_TIMER(name) g_permon->stopTimer((name)) + */ #else #define SVO_LOG(v) #define SVO_LOG2(v1, v2) diff --git a/GPU_version/svo/include/gpu_svo/homography.h b/GPU_version/svo/include/gpu_svo/homography.h new file mode 100644 index 0000000..7f5a7b2 --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/homography.h @@ -0,0 +1,85 @@ +/* + * homography.cpp + * Adaptation of PTAM-GPL HomographyInit class. + * https://github.com/Oxford-PTAM/PTAM-GPL + * Licence: GPLv3 + * Copyright 2008 Isis Innovation Limited + * + * Created on: Sep 2, 2012 + * by: cforster + * + * This class implements the homography decomposition of Faugeras and Lustman's + * 1988 tech report. Code converted to Eigen from PTAM. + * + */ + +#ifndef HOMOGRAPHY_H_ +#define HOMOGRAPHY_H_ + +#include +#include +#include +#include + +namespace vk { + +using namespace Eigen; +using namespace std; + +struct HomographyDecomposition +{ + Vector3d t; + Matrix3d R; + double d; + Vector3d n; + + // Resolved Composition + Sophus::SE3 T; //!< second from first + int score; +}; + +class Homography +{ +public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + Homography (const vector >& _fts1, + const vector >& _fts2, + double _error_multiplier2, + double _thresh_in_px); + + void + calcFromPlaneParams (const Vector3d & normal, + const Vector3d & point_on_plane); + + void + calcFromMatches (); + + size_t + computeMatchesInliers (); + + bool + computeSE3fromMatches (); + + bool + decompose (); + + void + findBestDecomposition (); + + double thresh; + double error_multiplier2; + const vector >& fts_c1; //!< Features on first image on unit plane + const vector >& fts_c2; //!< Features on second image on unit plane + vector inliers; + SE3 T_c2_from_c1; //!< Relative translation and rotation of two images + Matrix3d H_c2_from_c1; //!< Homography + vector decompositions; +}; + + + + +} /* end namespace vk */ + +#endif /* HOMOGRAPHY_H_ */ diff --git a/GPU_version/svo/include/gpu_svo/imu_integration.h b/GPU_version/svo/include/gpu_svo/imu_integration.h index 2692f71..738608f 100644 --- a/GPU_version/svo/include/gpu_svo/imu_integration.h +++ b/GPU_version/svo/include/gpu_svo/imu_integration.h @@ -18,83 +18,7 @@ using gtsam::symbol_shorthand::B; // Bias (ax,ay,az,gx,gy,gz) using gtsam::symbol_shorthand::V; // Vel (xdot,ydot,zdot) using gtsam::symbol_shorthand::P; // Pose3 (x,y,z,r,p,y) -using gtsam::symbol_shorthand::C; // Camera pose - -//https://stackoverflow.com/questions/24881799/get-index-in-c11-foreach-loop -// Wrapper class -template -class enumerate_impl -{ -public: - // The return value of the operator* of the iterator, this - // is what you will get inside of the for loop - struct item - { - size_t index; - typename T::value_type & item; - }; - typedef item value_type; - - // Custom iterator with minimal interface - struct iterator - { - iterator(typename T::iterator _it, size_t counter=0) : - it(_it), counter(counter) - {} - - iterator operator++() - { - return iterator(++it, ++counter); - } - - bool operator!=(iterator other) - { - return it != other.it; - } - - typename T::iterator::value_type item() - { - return *it; - } - - value_type operator*() - { - return value_type{counter, *it}; - } - - size_t index() - { - return counter; - } - - private: - typename T::iterator it; - size_t counter; - }; - - enumerate_impl(T & t) : container(t) {} - - iterator begin() - { - return iterator(container.begin()); - } - - iterator end() - { - return iterator(container.end()); - } - -private: - T & container; -}; - -// A templated free function allows you to create the wrapper class -// conveniently -template -enumerate_impl enumerate(T & t) -{ - return enumerate_impl(t); -} +using gtsam::symbol_shorthand::L; // Landmark class Imu_Integration{ public: @@ -103,7 +27,10 @@ public: bool reset(gtsam::ISAM2& optimizer,boost::shared_ptr& new_frame); bool reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr& new_frame); bool update(double* imu= nullptr); - bool predict(boost::shared_ptr&,std::size_t&,const double reproj_thresh); + bool predict(boost::shared_ptr&, + boost::shared_ptr& last_frame ,std::size_t&,const double reproj_thresh); + bool init(boost::shared_ptr&); + Sophus::SE3 preintegrate_predict(); private: std::shared_ptr statePtr; std::shared_ptr imu_biasPtr; @@ -116,6 +43,7 @@ private: std::uint32_t imu_factor_id=0; uint imu_n=0; std::shared_ptr optimizerParamPtr; + gtsam::NavState Integ_predict; bool syn=false; }; #endif //SVO_IMU_INTEGRATION_H diff --git a/GPU_version/svo/include/gpu_svo/initialization.h b/GPU_version/svo/include/gpu_svo/initialization.h index 21f9350..6c3b3b5 100644 --- a/GPU_version/svo/include/gpu_svo/initialization.h +++ b/GPU_version/svo/include/gpu_svo/initialization.h @@ -19,6 +19,7 @@ #include #include +#include namespace svo { diff --git a/GPU_version/svo/include/gpu_svo/math_utils.h b/GPU_version/svo/include/gpu_svo/math_utils.h new file mode 100644 index 0000000..6fffc38 --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/math_utils.h @@ -0,0 +1,171 @@ +/* + * math_utils.h + * + * Created on: Jul 20, 2012 + * Author: cforster + */ + +#ifndef MATH_UTILS_H_ +#define MATH_UTILS_H_ + + +#include +#include +#include + +namespace vk +{ + +using namespace Eigen; +using namespace std; +using namespace Sophus; + +Vector3d triangulateFeatureNonLin( + const Matrix3d& R, + const Vector3d& t, + const Vector3d& feature1, + const Vector3d& feature2); + +/// Assumes the bearing vectors f_c and f_r are on the epipolar plane, i.e. +/// perfect triangulation without noise! +bool depthFromTriangulationExact( + const Matrix3d& R_r_c, + const Vector3d& t_r_c, + const Vector3d& f_r, + const Vector3d& f_c, + double& depth_in_r, + double& depth_in_c); + +double reprojError( + const Vector3d& f1, + const Vector3d& f2, + double error_multiplier2); + +double computeInliers( + const vector& features1, + const vector& features2, + const Matrix3d& R, + const Vector3d& t, + const double reproj_thresh, + double error_multiplier2, + vector& xyz_vec, + vector& inliers, + vector& outliers); + +void computeInliersOneView( + const vector & feature_sphere_vec, + const vector & xyz_vec, + const Matrix3d &R, + const Vector3d &t, + const double reproj_thresh, + const double error_multiplier2, + vector& inliers, + vector& outliers); + +//! Direct Cosine Matrix to Roll Pitch Yaw +Vector3d dcm2rpy(const Matrix3d &R); + +//! Roll Pitch Yaw to Direct Cosine Matrix +Matrix3d rpy2dcm(const Vector3d &rpy); + +//! Angle Axis parametrization to Quaternion +Quaterniond angax2quat(const Vector3d& n, const double& angle); + +//! Angle Axis parametrization to Matrix representation +Matrix3d angax2dcm(const Vector3d& n, const double& angle); + +double sampsonusError( + const Vector2d &v2Dash, + const Matrix3d& m3Essential, + const Vector2d& v2); + +inline Matrix3d sqew(const Vector3d& v) +{ + Matrix3d v_sqew; + v_sqew << 0, -v[2], v[1], + v[2], 0, -v[0], + -v[1], v[0], 0; + return v_sqew; +} + +inline double norm_max(const Eigen::VectorXd & v) +{ + double max = -1; + for (int i=0; imax){ + max = abs; + } + } + return max; +} + +inline Vector2d project2d(const Vector3d& v) +{ + return v.head<2>()/v[2]; +} + +inline Vector3d unproject2d(const Vector2d& v) +{ + return Vector3d(v[0], v[1], 1.0); +} + +inline Vector3d project3d(const Vector4d& v) +{ + return v.head<3>()/v[3]; +} + +inline Vector4d unproject3d(const Vector3d& v) +{ + return Vector4d(v[0], v[1], v[2], 1.0); +} + +template +T getMedian(vector& data_vec) +{ + assert(!data_vec.empty()); + typename vector::iterator it = data_vec.begin()+floor(data_vec.size()/2); + nth_element(data_vec.begin(), it, data_vec.end()); + return *it; +} + +inline double pyrFromZero_d(double x_0, int level) +{ + return x_0/(1< & frame_jac) +{ + const double x = xyz[0]; + const double y = xyz[1]; + const double z = xyz[2]; + const double z_2 = z*z; + + frame_jac(0,0) = -1./z *focal_length; + frame_jac(0,1) = 0; + frame_jac(0,2) = x/z_2 *focal_length; + frame_jac(0,3) = x*y/z_2 * focal_length; + frame_jac(0,4) = -(1+(x*x/z_2)) *focal_length; + frame_jac(0,5) = y/z *focal_length; + + frame_jac(1,0) = 0; + frame_jac(1,1) = -1./z *focal_length; + frame_jac(1,2) = y/z_2 *focal_length; + frame_jac(1,3) = (1+y*y/z_2) *focal_length; + frame_jac(1,4) = -x*y/z_2 *focal_length; + frame_jac(1,5) = -x/z *focal_length; +} + +} // end namespace vk + +#endif /* MATH_UTILS_H_ */ diff --git a/GPU_version/svo/include/gpu_svo/nlls_solver.h b/GPU_version/svo/include/gpu_svo/nlls_solver.h new file mode 100644 index 0000000..cb6320b --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/nlls_solver.h @@ -0,0 +1,169 @@ +/* + * Abstract Nonlinear Least-Squares Solver Class + * + * nlls_solver.h + * + * Created on: Nov 5, 2012 + * Author: cforster + */ + +#ifndef LM_SOLVER_H_ +#define LM_SOLVER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vk { + +using namespace std; +using namespace Eigen; + +/** + * \brief Abstract Class for solving nonlinear least-squares (NLLS) problems. + * + * The function implements two algorithms: Levenberg Marquardt and Gauss Newton + * + * Example implementations of this function can be found in the rpl_examples + * package: img_align_2d.cpp, img_align_3d.cpp + * + * Template Parameters: + * D : dimension of the residual + * T : type of the model, e.g. SE2, SE3 + */ + +template +class NLLSSolver { + +public: + typedef T ModelType; + enum Method{GaussNewton, LevenbergMarquardt}; + enum ScaleEstimatorType{UnitScale, TDistScale, MADScale, NormalScale}; + enum WeightFunctionType{UnitWeight, TDistWeight, TukeyWeight, HuberWeight}; + +protected: + Matrix H_; //!< Hessian approximation + Matrix Jres_; //!< Jacobian x Residual + Matrix x_; //!< update step + bool have_prior_; + ModelType prior_; + Matrix I_prior_; //!< Prior information matrix (inverse covariance) + double chi2_; + double rho_; + Method method_; + + /// If the flag linearize_system is set, the function must also compute the + /// Jacobian and set the member variables H_, Jres_ + virtual double + computeResiduals (const ModelType& model, + bool linearize_system, + bool compute_weight_scale) = 0; + + /// Solve the linear system H*x = Jres. This function must set the update + /// step in the member variable x_. Must return true if the system could be + /// solved and false if it was singular. + virtual int + solve () = 0; + + virtual void + update (const ModelType& old_model, ModelType& new_model) = 0; + + virtual void + applyPrior (const ModelType& current_model) { } + + virtual void + startIteration () { } + + virtual void + finishIteration () { } + + virtual void + finishTrial () { } + +public: + + /// Damping parameter. If mu > 0, coefficient matrix is positive definite, this + /// ensures that x is a descent direction. If mu is large, x is a short step in + /// the steepest direction. This is good if the current iterate is far from the + /// solution. If mu is small, LM approximates gauss newton iteration and we + /// have (almost) quadratic convergence in the final stages. + double mu_init_, mu_; + double nu_init_, nu_; //!< Increase factor of mu after fail + size_t n_iter_init_, n_iter_; //!< Number of Iterations + size_t n_trials_; //!< Number of trials + size_t n_trials_max_; //!< Max number of trials + size_t n_meas_; //!< Number of measurements + bool stop_; //!< Stop flag + bool verbose_; //!< Output Statistics + double eps_; //!< Stop if update norm is smaller than eps + size_t iter_; //!< Current Iteration + + // robust least squares + bool use_weights_; + float scale_; + robust_cost::ScaleEstimatorPtr scale_estimator_; + robust_cost::WeightFunctionPtr weight_function_; + + NLLSSolver() : + have_prior_(false), + method_(LevenbergMarquardt), + mu_init_(0.01f), + mu_(mu_init_), + nu_init_(2.0), + nu_(nu_init_), + n_iter_init_(15), + n_iter_(n_iter_init_), + n_trials_(0), + n_trials_max_(5), + n_meas_(0), + stop_(false), + verbose_(true), + eps_(0.0000000001), + iter_(0), + use_weights_(false), + scale_(0.0), + scale_estimator_(NULL), + weight_function_(NULL) + { } + + virtual ~NLLSSolver() {} + + /// Calls the GaussNewton or LevenbergMarquardt optimization strategy + void optimize(ModelType& model); + + /// Gauss Newton optimization strategy + void optimizeGaussNewton(ModelType& model); + + /// Levenberg Marquardt optimization strategy + void optimizeLevenbergMarquardt(ModelType& model); + + /// Specify the robust cost that should be used and the appropriate scale estimator + void setRobustCostFunction( + ScaleEstimatorType scale_estimator, + WeightFunctionType weight_function); + + /// Add prior to optimization. + void setPrior( + const ModelType& prior, + const Matrix& Information); + + /// Reset all parameters to restart the optimization + void reset(); + + /// Get the squared error + const double& getChi2() const; + + /// The Information matrix is equal to the inverse covariance matrix. + const Matrix& getInformationMatrix() const; +}; + +} // end namespace vk + +#include "gpu_svo/nlls_solver_impl.hpp" + +#endif /* LM_SOLVER_H_ */ diff --git a/GPU_version/svo/include/gpu_svo/nlls_solver_impl.hpp b/GPU_version/svo/include/gpu_svo/nlls_solver_impl.hpp new file mode 100644 index 0000000..ec36be8 --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/nlls_solver_impl.hpp @@ -0,0 +1,323 @@ +/* + * Abstract Nonlinear Least-Squares Solver Class + * + * nlls_solver.h + * + * Created on: Nov 5, 2012 + * Author: cforster + */ + +#ifndef LM_SOLVER_IMPL_HPP_ +#define LM_SOLVER_IMPL_HPP_ + +#include + +template +void vk::NLLSSolver::optimize(ModelType& model) +{ + if(method_ == GaussNewton) + optimizeGaussNewton(model); + else if(method_ == LevenbergMarquardt) + optimizeLevenbergMarquardt(model); +} + +template +void vk::NLLSSolver::optimizeGaussNewton(ModelType& model) +{ + // Compute weight scale + if(use_weights_) + computeResiduals(model, false, true); + + // Save the old model to rollback in case of unsuccessful update + ModelType old_model(model); + + // perform iterative estimation + for (iter_ = 0; iter_::Identity(D,D); + Jres_.setZero(); + + // compute initial error + n_meas_ = 0; + computeResiduals(model, true, false); + + // add damping term: + H_ += (H_.diagonal()*mu_).asDiagonal(); + + // add prior + if(have_prior_) + applyPrior(model); + + // solve the linear system + if(solve()) + { + // update the model + update(model, new_model); + + // compute error with new model and compare to old error + n_meas_ = 0; + new_chi2 = computeResiduals(new_model, false, false); + rho_ = chi2_-new_chi2; + } + else + { + // matrix was singular and could not be computed + cout << "Matrix is close to singular!" << endl; + cout << "H = " << H_ << endl; + cout << "Jres = " << Jres_ << endl; + rho_ = -1; + } + + if(rho_>0) + { + // update decrased the error -> success + model = new_model; + chi2_ = new_chi2; + stop_ = vk::norm_max(x_)<=eps_; + mu_ *= max(1./3., min(1.-pow(2*rho_-1,3), 2./3.)); + nu_ = 2.; + if(verbose_) + { + cout << "It. " << iter_ + << "\t Trial " << n_trials_ + << "\t Success" + << "\t n_meas = " << n_meas_ + << "\t new_chi2 = " << new_chi2 + << "\t mu = " << mu_ + << "\t nu = " << nu_ + << endl; + } + } + else + { + // update increased the error -> fail + mu_ *= nu_; + nu_ *= 2.; + ++n_trials_; + if (n_trials_ >= n_trials_max_) + stop_ = true; + + if(verbose_) + { + cout << "It. " << iter_ + << "\t Trial " << n_trials_ + << "\t Failure" + << "\t n_meas = " << n_meas_ + << "\t new_chi2 = " << new_chi2 + << "\t mu = " << mu_ + << "\t nu = " << nu_ + << endl; + } + } + + finishTrial(); + + } while(!(rho_>0 || stop_)); + if (stop_) + break; + + finishIteration(); + } +} + + +template +void vk::NLLSSolver::setRobustCostFunction( + ScaleEstimatorType scale_estimator, + WeightFunctionType weight_function) +{ + switch(scale_estimator) + { + case TDistScale: + if(verbose_) + printf("Using TDistribution Scale Estimator\n"); + scale_estimator_.reset(new robust_cost::TDistributionScaleEstimator()); + use_weights_=true; + break; + case MADScale: + if(verbose_) + printf("Using MAD Scale Estimator\n"); + scale_estimator_.reset(new robust_cost::MADScaleEstimator()); + use_weights_=true; + break; + case NormalScale: + if(verbose_) + printf("Using Normal Scale Estimator\n"); + scale_estimator_.reset(new robust_cost::NormalDistributionScaleEstimator()); + use_weights_=true; + break; + default: + if(verbose_) + printf("Using Unit Scale Estimator\n"); + scale_estimator_.reset(new robust_cost::UnitScaleEstimator()); + use_weights_=false; + } + + switch(weight_function) + { + case TDistWeight: + if(verbose_) + printf("Using TDistribution Weight Function\n"); + weight_function_.reset(new robust_cost::TDistributionWeightFunction()); + break; + case TukeyWeight: + if(verbose_) + printf("Using Tukey Weight Function\n"); + weight_function_.reset(new robust_cost::TukeyWeightFunction()); + break; + case HuberWeight: + if(verbose_) + printf("Using Huber Weight Function\n"); + weight_function_.reset(new robust_cost::HuberWeightFunction()); + break; + default: + if(verbose_) + printf("Using Unit Weight Function\n"); + weight_function_.reset(new robust_cost::UnitWeightFunction()); + } +} + +template +void vk::NLLSSolver::setPrior( + const T& prior, + const Matrix& Information) +{ + have_prior_ = true; + prior_ = prior; + I_prior_ = Information; +} + +template +void vk::NLLSSolver::reset() +{ + have_prior_ = false; + chi2_ = 1e10; + mu_ = mu_init_; + nu_ = nu_init_; + n_meas_ = 0; + n_iter_ = n_iter_init_; + iter_ = 0; + stop_ = false; +} + +template +inline const double& vk::NLLSSolver::getChi2() const +{ + return chi2_; +} + +template +inline const vk::Matrix& vk::NLLSSolver::getInformationMatrix() const +{ + return H_; +} + +#endif /* LM_SOLVER_IMPL_HPP_ */ diff --git a/GPU_version/svo/include/gpu_svo/params_helper.h b/GPU_version/svo/include/gpu_svo/params_helper.h new file mode 100644 index 0000000..f8a03dc --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/params_helper.h @@ -0,0 +1,57 @@ +// +// Created by root on 5/24/21. +// + +#ifndef GPU_SVO_PARAMS_HELPER_H +#define GPU_SVO_PARAMS_HELPER_H +/* + * ros_params_helper.h + * + * Created on: Feb 22, 2013 + * Author: cforster + * + * from libpointmatcher_ros + */ + +#include +#include + +namespace vk { + + inline + bool hasParam(const std::string& name) + { + return ros::param::has(name); + } + + template + T getParam(const std::string& name, const T& defaultValue) + { + T v; + if(ros::param::get(name, v)) + { + ROS_INFO_STREAM("Found parameter: " << name << ", value: " << v); + return v; + } + else + ROS_WARN_STREAM("Cannot find value for parameter: " << name << ", assigning default: " << defaultValue); + return defaultValue; + } + + template + T getParam(const std::string& name) + { + T v; + if(ros::param::get(name, v)) + { + ROS_INFO_STREAM("Found parameter: " << name << ", value: " << v); + return v; + } + else + ROS_ERROR_STREAM("Cannot find value for parameter: " << name); + return T(); + } + +} // namespace vk + +#endif //GPU_SVO_PARAMS_HELPER_H diff --git a/GPU_version/svo/include/gpu_svo/patch_score.h b/GPU_version/svo/include/gpu_svo/patch_score.h new file mode 100644 index 0000000..8f0516c --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/patch_score.h @@ -0,0 +1,225 @@ +/* + * patch_score.h + * + * Created on: Dec 5, 2013 + * Author: cforster + */ + +#ifndef VIKIT_PATCH_SCORE_H_ +#define VIKIT_PATCH_SCORE_H_ + +#include + +#if __SSE2__ +#include +#endif + +namespace vk { +namespace patch_score { + + +#if __SSE2__ +// Horizontal sum of uint16s stored in an XMM register +inline int SumXMM_16(__m128i &target) +{ + unsigned short int sums_store[8]; + _mm_storeu_si128((__m128i*)sums_store, target); + return sums_store[0] + sums_store[1] + sums_store[2] + sums_store[3] + + sums_store[4] + sums_store[5] + sums_store[6] + sums_store[7]; +} +// Horizontal sum of uint32s stored in an XMM register +inline int SumXMM_32(__m128i &target) +{ + unsigned int sums_store[4]; + _mm_storeu_si128((__m128i*)sums_store, target); + return sums_store[0] + sums_store[1] + sums_store[2] + sums_store[3]; +} +#endif + +/// Zero Mean Sum of Squared Differences Cost +template +class ZMSSD { +public: + + static const int patch_size_ = 2*HALF_PATCH_SIZE; + static const int patch_area_ = patch_size_*patch_size_; + static const int threshold_ = 2000*patch_area_; + uint8_t* ref_patch_; + int sumA_, sumAA_; + + ZMSSD(uint8_t* ref_patch) : + ref_patch_(ref_patch) + { + uint32_t sumA_uint=0, sumAA_uint=0; + for(int r = 0; r < patch_area_; r++) + { + uint8_t n = ref_patch_[r]; + sumA_uint += n; + sumAA_uint += n*n; + } + sumA_ = sumA_uint; + sumAA_ = sumAA_uint; + } + + static int threshold() { return threshold_; } + + int computeScore(uint8_t* cur_patch) const + { + uint32_t sumB_uint = 0; + uint32_t sumBB_uint = 0; + uint32_t sumAB_uint = 0; + for(int r = 0; r < patch_area_; r++) + { + const uint8_t cur_pixel = cur_patch[r]; + sumB_uint += cur_pixel; + sumBB_uint += cur_pixel*cur_pixel; + sumAB_uint += cur_pixel * ref_patch_[r]; + } + const int sumB = sumB_uint; + const int sumBB = sumBB_uint; + const int sumAB = sumAB_uint; + return sumAA_ - 2*sumAB + sumBB - (sumA_*sumA_ - 2*sumA_*sumB + sumB*sumB)/patch_area_; + } + + int computeScore(uint8_t* cur_patch, int stride) const + { + int sumB, sumBB, sumAB; +#if __SSE2__ + if(patch_size_ == 8) + { + // From PTAM-GPL, Copyright 2008 Isis Innovation Limited + __m128i xImageAsEightBytes; + __m128i xImageAsWords; + __m128i xTemplateAsEightBytes; + __m128i xTemplateAsWords; + __m128i xZero; + __m128i xImageSums; // These sums are 8xuint16 + __m128i xImageSqSums; // These sums are 4xint32 + __m128i xCrossSums; // These sums are 4xint32 + __m128i xProduct; + + xImageSums = _mm_setzero_si128(); + xImageSqSums = _mm_setzero_si128(); + xCrossSums = _mm_setzero_si128(); + xZero = _mm_setzero_si128(); + + uint8_t* imagepointer = cur_patch; + uint8_t* templatepointer = ref_patch_; + long unsigned int cur_stride = stride; + + xImageAsEightBytes=_mm_loadl_epi64((__m128i*) imagepointer); + imagepointer += cur_stride; + xImageAsWords = _mm_unpacklo_epi8(xImageAsEightBytes,xZero); + xImageSums = _mm_adds_epu16(xImageAsWords,xImageSums); + xProduct = _mm_madd_epi16(xImageAsWords, xImageAsWords); + xImageSqSums = _mm_add_epi32(xProduct, xImageSqSums); + xTemplateAsEightBytes=_mm_load_si128((__m128i*) templatepointer); + templatepointer += 16; + xTemplateAsWords = _mm_unpacklo_epi8(xTemplateAsEightBytes,xZero); + xProduct = _mm_madd_epi16(xImageAsWords, xTemplateAsWords); + xCrossSums = _mm_add_epi32(xProduct, xCrossSums); + xImageAsEightBytes=_mm_loadl_epi64((__m128i*) imagepointer); + imagepointer += cur_stride; + xImageAsWords = _mm_unpacklo_epi8(xImageAsEightBytes,xZero); + xImageSums = _mm_adds_epu16(xImageAsWords,xImageSums); + xProduct = _mm_madd_epi16(xImageAsWords, xImageAsWords); + xImageSqSums = _mm_add_epi32(xProduct, xImageSqSums); + xTemplateAsWords = _mm_unpackhi_epi8(xTemplateAsEightBytes,xZero); + xProduct = _mm_madd_epi16(xImageAsWords, xTemplateAsWords); + xCrossSums = _mm_add_epi32(xProduct, xCrossSums); + + xImageAsEightBytes=_mm_loadl_epi64((__m128i*) imagepointer); + imagepointer += cur_stride; + xImageAsWords = _mm_unpacklo_epi8(xImageAsEightBytes,xZero); + xImageSums = _mm_adds_epu16(xImageAsWords,xImageSums); + xProduct = _mm_madd_epi16(xImageAsWords, xImageAsWords); + xImageSqSums = _mm_add_epi32(xProduct, xImageSqSums); + xTemplateAsEightBytes=_mm_load_si128((__m128i*) templatepointer); + templatepointer += 16; + xTemplateAsWords = _mm_unpacklo_epi8(xTemplateAsEightBytes,xZero); + xProduct = _mm_madd_epi16(xImageAsWords, xTemplateAsWords); + xCrossSums = _mm_add_epi32(xProduct, xCrossSums); + xImageAsEightBytes=_mm_loadl_epi64((__m128i*) imagepointer); + imagepointer += cur_stride; + xImageAsWords = _mm_unpacklo_epi8(xImageAsEightBytes,xZero); + xImageSums = _mm_adds_epu16(xImageAsWords,xImageSums); + xProduct = _mm_madd_epi16(xImageAsWords, xImageAsWords); + xImageSqSums = _mm_add_epi32(xProduct, xImageSqSums); + xTemplateAsWords = _mm_unpackhi_epi8(xTemplateAsEightBytes,xZero); + xProduct = _mm_madd_epi16(xImageAsWords, xTemplateAsWords); + xCrossSums = _mm_add_epi32(xProduct, xCrossSums); + + xImageAsEightBytes=_mm_loadl_epi64((__m128i*) imagepointer); + imagepointer += cur_stride; + xImageAsWords = _mm_unpacklo_epi8(xImageAsEightBytes,xZero); + xImageSums = _mm_adds_epu16(xImageAsWords,xImageSums); + xProduct = _mm_madd_epi16(xImageAsWords, xImageAsWords); + xImageSqSums = _mm_add_epi32(xProduct, xImageSqSums); + xTemplateAsEightBytes=_mm_load_si128((__m128i*) templatepointer); + templatepointer += 16; + xTemplateAsWords = _mm_unpacklo_epi8(xTemplateAsEightBytes,xZero); + xProduct = _mm_madd_epi16(xImageAsWords, xTemplateAsWords); + xCrossSums = _mm_add_epi32(xProduct, xCrossSums); + xImageAsEightBytes=_mm_loadl_epi64((__m128i*) imagepointer); + imagepointer += cur_stride; + xImageAsWords = _mm_unpacklo_epi8(xImageAsEightBytes,xZero); + xImageSums = _mm_adds_epu16(xImageAsWords,xImageSums); + xProduct = _mm_madd_epi16(xImageAsWords, xImageAsWords); + xImageSqSums = _mm_add_epi32(xProduct, xImageSqSums); + xTemplateAsWords = _mm_unpackhi_epi8(xTemplateAsEightBytes,xZero); + xProduct = _mm_madd_epi16(xImageAsWords, xTemplateAsWords); + xCrossSums = _mm_add_epi32(xProduct, xCrossSums); + + xImageAsEightBytes=_mm_loadl_epi64((__m128i*) imagepointer); + imagepointer += cur_stride; + xImageAsWords = _mm_unpacklo_epi8(xImageAsEightBytes,xZero); + xImageSums = _mm_adds_epu16(xImageAsWords,xImageSums); + xProduct = _mm_madd_epi16(xImageAsWords, xImageAsWords); + xImageSqSums = _mm_add_epi32(xProduct, xImageSqSums); + xTemplateAsEightBytes=_mm_load_si128((__m128i*) templatepointer); + templatepointer += 16; + xTemplateAsWords = _mm_unpacklo_epi8(xTemplateAsEightBytes,xZero); + xProduct = _mm_madd_epi16(xImageAsWords, xTemplateAsWords); + xCrossSums = _mm_add_epi32(xProduct, xCrossSums); + xImageAsEightBytes=_mm_loadl_epi64((__m128i*) imagepointer); + xImageAsWords = _mm_unpacklo_epi8(xImageAsEightBytes,xZero); + xImageSums = _mm_adds_epu16(xImageAsWords,xImageSums); + xProduct = _mm_madd_epi16(xImageAsWords, xImageAsWords); + xImageSqSums = _mm_add_epi32(xProduct, xImageSqSums); + xTemplateAsWords = _mm_unpackhi_epi8(xTemplateAsEightBytes,xZero); + xProduct = _mm_madd_epi16(xImageAsWords, xTemplateAsWords); + xCrossSums = _mm_add_epi32(xProduct, xCrossSums); + + sumB = SumXMM_16(xImageSums); + sumAB = SumXMM_32(xCrossSums); + sumBB = SumXMM_32(xImageSqSums); + } + else +#endif + { + uint32_t sumB_uint = 0; + uint32_t sumBB_uint = 0; + uint32_t sumAB_uint = 0; + for(int y=0, r=0; y < patch_size_; ++y) + { + uint8_t* cur_patch_ptr = cur_patch + y*stride; + for(int x=0; x < patch_size_; ++x, ++r) + { + const uint8_t cur_px = cur_patch_ptr[x]; + sumB_uint += cur_px; + sumBB_uint += cur_px * cur_px; + sumAB_uint += cur_px * ref_patch_[r]; + } + } + sumB = sumB_uint; + sumBB = sumBB_uint; + sumAB = sumAB_uint; + } + return sumAA_ - 2*sumAB + sumBB - (sumA_*sumA_ - 2*sumA_*sumB + sumB*sumB)/patch_area_; + } +}; + +} // namespace patch_score +} // namespace vk + +#endif // VIKIT_PATCH_SCORE_H_ diff --git a/GPU_version/svo/include/gpu_svo/robust_cost.h b/GPU_version/svo/include/gpu_svo/robust_cost.h new file mode 100644 index 0000000..d03881a --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/robust_cost.h @@ -0,0 +1,156 @@ +/** +* This file is part of dvo. +* +* Copyright 2012 Christian Kerl (Technical University of Munich) +* For more information see . +* +* dvo is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* dvo is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with dvo. If not, see . +*/ + +#ifndef VIKIT_ROBUST_COST_H_ +#define VIKIT_ROBUST_COST_H_ + +#include +#include +#include +namespace vk { +namespace robust_cost { + +// interface for scale estimators +class ScaleEstimator +{ +public: + virtual ~ScaleEstimator() {}; + virtual float compute(std::vector& errors) const = 0; +}; +typedef std::shared_ptr ScaleEstimatorPtr; + +class UnitScaleEstimator : public ScaleEstimator +{ +public: + UnitScaleEstimator() {} + virtual ~UnitScaleEstimator() {} + virtual float compute(std::vector& errors) const { return 1.0f; }; +}; + +// estimates scale by fitting a t-distribution to the data with the given degrees of freedom +class TDistributionScaleEstimator : public ScaleEstimator +{ +public: + TDistributionScaleEstimator(const float dof = DEFAULT_DOF); + virtual ~TDistributionScaleEstimator() {}; + virtual float compute(std::vector& errors) const; + + static const float DEFAULT_DOF; + static const float INITIAL_SIGMA; +protected: + float dof_; + float initial_sigma_; +}; + +// estimates scale by computing the median absolute deviation +class MADScaleEstimator : public ScaleEstimator +{ +public: + MADScaleEstimator() {}; + virtual ~MADScaleEstimator() {}; + virtual float compute(std::vector& errors) const; + +private: + static const float NORMALIZER;; +}; + +// estimates scale by computing the standard deviation +class NormalDistributionScaleEstimator : public ScaleEstimator +{ +public: + NormalDistributionScaleEstimator() {}; + virtual ~NormalDistributionScaleEstimator() {}; + virtual float compute(std::vector& errors) const; +private: +}; + +/** + * Interface for weight functions. A weight function is the first derivative of a symmetric robust function p(sqrt(t)). + * The errors are assumed to be normalized to unit variance. + * + * See: + * "Lucas-Kanade 20 Years On: A Unifying Framework: Part 2" - Page 23, Equation (54) + */ +class WeightFunction +{ +public: + virtual ~WeightFunction() {}; + virtual float value(const float& x) const = 0; + virtual void configure(const float& param) {}; +}; +typedef std::shared_ptr WeightFunctionPtr; + +class UnitWeightFunction : public WeightFunction +{ +public: + UnitWeightFunction() {}; + virtual ~UnitWeightFunction() {}; + virtual float value(const float& x) const { return 1.0f; }; +}; + +/** + * Tukey's hard re-descending function. + * + * See: + * http://en.wikipedia.org/wiki/Redescending_M-estimator + */ +class TukeyWeightFunction : public WeightFunction +{ +public: + TukeyWeightFunction(const float b = DEFAULT_B); + virtual ~TukeyWeightFunction() {}; + virtual float value(const float& x) const; + virtual void configure(const float& param); + + static const float DEFAULT_B; +private: + float b_square; +}; + +class TDistributionWeightFunction : public WeightFunction +{ +public: + TDistributionWeightFunction(const float dof = DEFAULT_DOF); + virtual ~TDistributionWeightFunction() {}; + virtual float value(const float& x) const; + virtual void configure(const float& param); + + static const float DEFAULT_DOF; +private: + float dof_; + float normalizer_; +}; + +class HuberWeightFunction : public WeightFunction +{ +public: + HuberWeightFunction(const float k = DEFAULT_K); + virtual ~HuberWeightFunction() {}; + virtual float value(const float& x) const; + virtual void configure(const float& param); + + static const float DEFAULT_K; +private: + float k; +}; + +} // namespace robust_cost +} // namespace vk +#endif // VIKIT_ROBUST_COST_H_ diff --git a/GPU_version/svo/include/gpu_svo/sparse_img_align.h b/GPU_version/svo/include/gpu_svo/sparse_img_align.h index 58374be..6200066 100644 --- a/GPU_version/svo/include/gpu_svo/sparse_img_align.h +++ b/GPU_version/svo/include/gpu_svo/sparse_img_align.h @@ -17,8 +17,7 @@ #ifndef SVO_SPARSE_IMG_ALIGN_H_ #define SVO_SPARSE_IMG_ALIGN_H_ -#include -#include +#include #include namespace vk { @@ -32,8 +31,8 @@ class Feature; /// Optimize the pose of the frame by minimizing the photometric error of feature patches. class SparseImgAlign : public vk::NLLSSolver<6, SE3> { - static const int patch_halfsize_ = 2; - static const int patch_size_ = 2*patch_halfsize_; + static const int patch_halfsize_ = 6; + static const int patch_size_ = 6*patch_halfsize_; static const int patch_area_ = patch_size_*patch_size_; public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW diff --git a/GPU_version/svo/include/gpu_svo/svoVisionFactor.h b/GPU_version/svo/include/gpu_svo/svoVisionFactor.h index 738bd95..417357c 100644 --- a/GPU_version/svo/include/gpu_svo/svoVisionFactor.h +++ b/GPU_version/svo/include/gpu_svo/svoVisionFactor.h @@ -16,13 +16,11 @@ namespace svo { - class VisionFactor: public gtsam::NoiseModelFactor1 { + class VisionFactor: public gtsam::NoiseModelFactor2 { private: // measurement information gtsam::Point3 feature; /// body_P_sensor_; ///< TODO The pose of the sensor in the body frame int level; ///< Image pyramid level where feature was extracted. public: @@ -39,22 +37,27 @@ namespace svo { * @param body_P_sensor is the transform from body to sensor frame (default identity) * @param level Image pyramid level where feature was extracted. */ - VisionFactor(const gtsam::Point3& feature, const gtsam::Point3& landmark,const int level, const gtsam::SharedNoiseModel& Hp, - gtsam::Key poseKey,boost::optional body_P_sensor = boost::none) : - gtsam::NoiseModelFactor1(Hp, poseKey), feature(feature), landmark(landmark),body_P_sensor_(body_P_sensor),level(level){} + VisionFactor(const gtsam::Point3& feature,const int level, + const gtsam::SharedNoiseModel& H, + gtsam::Key poseKey,gtsam::Key landKey ) : + gtsam::NoiseModelFactor2(H, poseKey,landKey), feature(feature),level(level){} virtual ~VisionFactor(){} /// error function /// @param p the Estimated pose in Pose3 /// @param H the optional Jacobian matrix, which use boost optional and has default null pointer - gtsam::Vector evaluateError(const gtsam::Pose3& p, boost::optional Hp = boost::none) const { + gtsam::Vector evaluateError(const gtsam::Pose3& p,const gtsam::Point3& l, + boost::optional H1 = boost::none,boost::optional H2 = boost::none) const { // note that use boost optional like a pointer // only calculate jacobian matrix when non-null pointer exists - gtsam::Matrix26 J; - gtsam::Point3 point(p*landmark); - svo::Frame::jacobian_xyz2uv(point, J); - Vector2d e = (vk::project2d(feature) - vk::project2d(point))*1.0 / (1< +#include +#include +#include +#include +#include +#include + +namespace svo { + + class VisionFactorLandMark: public gtsam::NoiseModelFactor3 { + + private: + // measurement information + gtsam::Point3 feature_new; /// shared_ptr; + + /** + * Constructor + * @param feature Unit-bearing vector of the feature. + * @param model is the standard deviation + * @param pointKey is the index of the landmark + * @param poseKey is the index of the camera pose + * @param landmark 3D position of the landmark + * @param body_P_sensor is the transform from body to sensor frame (default identity) + * @param level Image pyramid level where feature was extracted. + */ + VisionFactorLandMark(const gtsam::Point3& feature_new,const gtsam::Point3& feature_ref, int level, + const gtsam::SharedNoiseModel& H, + gtsam::Key poseKey_ref, gtsam::Key poseKey_new,gtsam::Key landmarkKey ) : + gtsam::NoiseModelFactor3(H, poseKey_ref,poseKey_new,landmarkKey), feature_new(feature_new), + feature_ref(feature_ref),level(level){} + virtual ~VisionFactorLandMark(){} + + /// error function + /// @param p_new the Estimated pose in Pose3 + /// @param P_ref the Estimated point of landmark + /// @param l the Estimated point of landmark + /// @param H the optional Jacobian matrix, which use boost optional and has default null pointer + gtsam::Vector evaluateError(const gtsam::Pose3& p_ref,const gtsam::Pose3& p_new, const gtsam::Point3& l, + boost::optional H1 = boost::none,boost::optional H2 = boost::none, + boost::optional H3 = boost::none) const { + // note that use boost optional like a pointer + // only calculate jacobian matrix when non-null pointer exists + gtsam::Matrix26 J,J1; + gtsam::Matrix23 J2,J3; + + gtsam::Point3 point(p_ref*l); + svo::Frame::jacobian_xyz2uv(point, J); + svo::Frame::jacobian_l2uv(point,J2); + + gtsam::Point3 point2(p_new*l); + svo::Frame::jacobian_xyz2uv(point2, J1); + svo::Frame::jacobian_l2uv(point2,J3); + Vector2d e1=vk::project2d(feature_ref) - vk::project2d(point)*1.0 / (1<( + gtsam::NonlinearFactor::shared_ptr(new VisionFactorLandMark(*this))); } + + }; + +} // namespace gtsamexamples +#endif //SVO_SVOVISIONFACTOR_H diff --git a/GPU_version/svo/include/gpu_svo/svoVisionFactorSmall.h b/GPU_version/svo/include/gpu_svo/svoVisionFactorSmall.h new file mode 100644 index 0000000..738bd95 --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/svoVisionFactorSmall.h @@ -0,0 +1,70 @@ +// +// Created by root on 4/13/21. +// + +#ifndef SVO_SVOVISIONFACTOR_H +#define SVO_SVOVISIONFACTOR_H +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace svo { + + class VisionFactor: public gtsam::NoiseModelFactor1 { + + private: + // measurement information + gtsam::Point3 feature; /// body_P_sensor_; ///< TODO The pose of the sensor in the body frame + int level; ///< Image pyramid level where feature was extracted. + + public: + /// shorthand for a smart pointer to a factor + typedef boost::shared_ptr shared_ptr; + + /** + * Constructor + * @param feature Unit-bearing vector of the feature. + * @param model is the standard deviation + * @param pointKey is the index of the landmark + * @param poseKey is the index of the camera pose + * @param landmark 3D position of the landmark + * @param body_P_sensor is the transform from body to sensor frame (default identity) + * @param level Image pyramid level where feature was extracted. + */ + VisionFactor(const gtsam::Point3& feature, const gtsam::Point3& landmark,const int level, const gtsam::SharedNoiseModel& Hp, + gtsam::Key poseKey,boost::optional body_P_sensor = boost::none) : + gtsam::NoiseModelFactor1(Hp, poseKey), feature(feature), landmark(landmark),body_P_sensor_(body_P_sensor),level(level){} + virtual ~VisionFactor(){} + + /// error function + /// @param p the Estimated pose in Pose3 + /// @param H the optional Jacobian matrix, which use boost optional and has default null pointer + gtsam::Vector evaluateError(const gtsam::Pose3& p, boost::optional Hp = boost::none) const { + // note that use boost optional like a pointer + // only calculate jacobian matrix when non-null pointer exists + gtsam::Matrix26 J; + gtsam::Point3 point(p*landmark); + svo::Frame::jacobian_xyz2uv(point, J); + Vector2d e = (vk::project2d(feature) - vk::project2d(point))*1.0 / (1<( + gtsam::NonlinearFactor::shared_ptr(new VisionFactor(*this))); } + + }; + +} // namespace gtsamexamples +#endif //SVO_SVOVISIONFACTOR_H diff --git a/GPU_version/svo/include/gpu_svo/timer.h b/GPU_version/svo/include/gpu_svo/timer.h new file mode 100644 index 0000000..45bbc7f --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/timer.h @@ -0,0 +1,81 @@ +#ifndef TIMER_H +#define TIMER_H + +#include +#include +#include + +namespace vk +{ + +class Timer +{ +private: + timeval start_time_; + double time_; + double accumulated_; +public: + + /// The constructor directly starts the timer. + Timer() : + time_(0.0), + accumulated_(0.0) + { + start(); + } + + ~Timer() + {} + + inline void start() + { + accumulated_ = 0.0; + gettimeofday(&start_time_, NULL); + } + + inline void resume() + { + gettimeofday(&start_time_, NULL); + } + + inline double stop() + { + timeval end_time; + gettimeofday(&end_time, NULL); + long seconds = end_time.tv_sec - start_time_.tv_sec; + long useconds = end_time.tv_usec - start_time_.tv_usec; + time_ = ((seconds) + useconds*0.000001) + accumulated_; + accumulated_ = time_; + return time_; + } + + inline double getTime() const + { + return time_; + } + + inline void reset() + { + time_ = 0.0; + accumulated_ = 0.0; + } + + static double getCurrentTime() + { + timeval time_now; + gettimeofday(&time_now, NULL); + return time_now.tv_sec + time_now.tv_usec*0.000001; + } + + static double getCurrentSecond() + { + timeval time_now; + gettimeofday(&time_now, NULL); + return time_now.tv_sec; + } + +}; + +} // end namespace vk + +#endif diff --git a/GPU_version/svo/include/gpu_svo/vision.h b/GPU_version/svo/include/gpu_svo/vision.h new file mode 100644 index 0000000..1533775 --- /dev/null +++ b/GPU_version/svo/include/gpu_svo/vision.h @@ -0,0 +1,77 @@ +/* + * vision.h + * + * Created on: May 14, 2013 + * Author: cforster + */ + +#ifndef VIKIT_VISION_H_ +#define VIKIT_VISION_H_ + +#include +#include +#include + +namespace vk +{ + +//! Return value between 0 and 1 +//! WARNING This function does not check whether the x/y is within the border +inline float +interpolateMat_32f(const cv::Mat& mat, float u, float v) +{ + assert(mat.type()==CV_32F); + float x = floor(u); + float y = floor(v); + float subpix_x = u-x; + float subpix_y = v-y; + float wx0 = 1.0-subpix_x; + float wx1 = subpix_x; + float wy0 = 1.0-subpix_y; + float wy1 = subpix_y; + + float val00 = mat.at(y,x); + float val10 = mat.at(y,x+1); + float val01 = mat.at(y+1,x); + float val11 = mat.at(y+1,x+1); + return (wx0*wy0)*val00 + (wx1*wy0)*val10 + (wx0*wy1)*val01 + (wx1*wy1)*val11; +} + +//! Return value between 0 and 255 +//! WARNING This function does not check whether the x/y is within the border +inline float +interpolateMat_8u(const cv::Mat& mat, float u, float v) +{ + assert(mat.type()==CV_8U); + int x = floor(u); + int y = floor(v); + float subpix_x = u-x; + float subpix_y = v-y; + + float w00 = (1.0f-subpix_x)*(1.0f-subpix_y); + float w01 = (1.0f-subpix_x)*subpix_y; + float w10 = subpix_x*(1.0f-subpix_y); + float w11 = 1.0f - w00 - w01 - w10; + + const int stride = mat.step.p[0]; + unsigned char* ptr = mat.data + y*stride + x; + return w00*ptr[0] + w01*ptr[stride] + w10*ptr[1] + w11*ptr[stride+1]; +} + +void halfSample(const cv::Mat& in, cv::Mat& out); + +float shiTomasiScore(const cv::Mat& img, int u, int v); + +void calcSharrDeriv(const cv::Mat& src, cv::Mat& dst); + +#ifdef __SSE2__ + +/// Used to convert a Kinect depthmap +/// Code by Christian Kerl DVO, GPL Licence +void convertRawDepthImageSse_16u_to_32f(cv::Mat& depth_16u, cv::Mat& depth_32f, float scale); + +#endif + +} // namespace vk + +#endif // VIKIT_VISION_H_ diff --git a/GPU_version/svo/src/atan_camera.cpp b/GPU_version/svo/src/atan_camera.cpp new file mode 100644 index 0000000..c86f027 --- /dev/null +++ b/GPU_version/svo/src/atan_camera.cpp @@ -0,0 +1,82 @@ +/* + * atan_camera.cpp + * + * Created on: Aug 21, 2012 + * Author: cforster + */ + + +#include +#include +#include + +namespace vk { + +ATANCamera:: +ATANCamera(double width, double height, + double fx, double fy, + double cx, double cy, + double s) : + AbstractCamera(width, height), + fx_(width*fx), fy_(height*fy), + fx_inv_(1.0/fx_), fy_inv_(1.0/fy_), + cx_(cx*width - 0.5), cy_(cy*height - 0.5), + s_(s), s_inv_(1.0/s_) +{ + if(s_ != 0.0) + { + tans_ = 2.0 * tan(s_ / 2.0); + tans_inv_ = 1.0 / tans_; + s_inv_ = 1.0 / s_; + distortion_ = true; + } + else + { + s_inv_ = 0.0; + tans_ = 0.0; + distortion_ = false; + } +} + +ATANCamera:: +~ATANCamera() +{} + +Vector3d ATANCamera:: +cam2world(const double& x, const double& y) const +{ + Vector2d dist_cam((x - cx_) * fx_inv_, + (y - cy_) * fy_inv_); + double dist_r = dist_cam.norm(); + double r = invrtrans(dist_r); + double d_factor; + if(dist_r > 0.01) + d_factor = r / dist_r; + else + d_factor = 1.0; + return unproject2d(d_factor * dist_cam).normalized(); +} + +Vector3d ATANCamera:: +cam2world (const Vector2d& px) const +{ + return cam2world(px[0], px[1]); +} + +Vector2d ATANCamera:: +world2cam(const Vector3d& xyz_c) const +{ + return world2cam(project2d(xyz_c)); +} + +Vector2d ATANCamera:: +world2cam(const Vector2d& uv) const +{ + double r = uv.norm(); + double factor = rtrans_factor(r); + Vector2d dist_cam = factor * uv; + return Vector2d(cx_ + fx_ * dist_cam[0], + cy_ + fy_ * dist_cam[1]); +} + +} /* end vk */ diff --git a/GPU_version/svo/src/bundle_adjustment.cpp b/GPU_version/svo/src/bundle_adjustment.cpp index 883116f..9bebb61 100644 --- a/GPU_version/svo/src/bundle_adjustment.cpp +++ b/GPU_version/svo/src/bundle_adjustment.cpp @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include +#include #include #include #include diff --git a/GPU_version/svo/src/config.cpp b/GPU_version/svo/src/config.cpp index 2f09b60..8801d19 100644 --- a/GPU_version/svo/src/config.cpp +++ b/GPU_version/svo/src/config.cpp @@ -14,15 +14,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#ifdef SVO_USE_ROS -#include -#endif +#include #include namespace svo { Config::Config() : -#ifdef SVO_USE_ROS trace_name(vk::getParam("svo/trace_name", "svo")), trace_dir(vk::getParam("svo/trace_dir", "/tmp")), n_pyr_levels(vk::getParam("svo/n_pyr_levels", 3)), @@ -58,38 +55,11 @@ Config::Config() : abc(vk::getParam("svo/ABC", 1e-1)), gbc(vk::getParam("svo/GBC", 1e-1)), ebp(vk::getParam("svo/EBP", 1e-2)), - nrp(vk::getParam("svo/NRP", 1e-5)) -#else - trace_name("svo"), - trace_dir("/tmp"), - n_pyr_levels(3), - use_imu(false), - core_n_kfs(3), - map_scale(1.0), - grid_size(25), - init_min_disparity(50.0), - init_min_tracked(50), - init_min_inliers(40), - klt_max_level(4), - klt_min_level(2), - reproj_thresh(2.0), - poseoptim_thresh(2.0), - poseoptim_num_iter(10), - structureoptim_max_pts(20), - structureoptim_num_iter(5), - loba_thresh(2.0), - loba_robust_huber_width(1.0), - loba_num_iter(0), - kfselect_mindist(0.12), - triang_min_corner_score(20.0), - triang_half_patch_size(4), - subpix_n_iter(10), - max_n_kfs(0), - img_imu_delay(0.0), - max_fts(120), - quality_min_fts(50), - quality_max_drop_fts(40) -#endif + nrp(vk::getParam("svo/NRP", 1e-5)), + gravity(vk::getParam("svo/gravity", 9.8)), + acc_x_off(vk::getParam("svo/Acceleration_offset_x", 0.0)), + acc_y_off(vk::getParam("svo/Acceleration_offset_y", 0.0)), + gyr_z_off(vk::getParam("svo/Gyroscope_offset_z", 0.0)) {} Config& Config::getInstance() diff --git a/GPU_version/svo/src/depth_filter.cpp b/GPU_version/svo/src/depth_filter.cpp index f6fa977..da00ff0 100644 --- a/GPU_version/svo/src/depth_filter.cpp +++ b/GPU_version/svo/src/depth_filter.cpp @@ -15,9 +15,9 @@ // along with this program. If not, see . #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -340,13 +340,8 @@ double DepthFilter::computeTau( Vector3d t(T_ref_cur.translation()); Vector3d a = f*z-t; double t_norm = t.norm(); - double a_norm = a.norm(); - double alpha = acos(f.dot(t)/t_norm); // dot product - double beta = acos(a.dot(-t)/(t_norm*a_norm)); // dot product - double beta_plus = beta + px_error_angle; - double gamma_plus = PI-alpha-beta_plus; // triangle angles sum to PI - double z_plus = t_norm*sin(beta_plus)/sin(gamma_plus); // law of sines - return (z_plus - z); // tau + double beta_plus = acos(a.dot(-t)/(t_norm*a.norm())) + px_error_angle; + return (t_norm*sin(beta_plus)/sin(PI-acos(f.dot(t)/t_norm)-beta_plus) - z); // ( triangle angles sum to PI and law of sines ) tau } } // namespace svo diff --git a/GPU_version/svo/src/feature_alignment.cpp b/GPU_version/svo/src/feature_alignment.cpp index 3605333..496ce33 100644 --- a/GPU_version/svo/src/feature_alignment.cpp +++ b/GPU_version/svo/src/feature_alignment.cpp @@ -25,7 +25,7 @@ namespace svo { namespace feature_alignment { -#define SUBPIX_VERBOSE 0 +#define SUBPIX_VERBOSE 1 bool align1D( const cv::Mat& cur_img, @@ -258,7 +258,7 @@ bool align2D( #if SUBPIX_VERBOSE cout << "Iter " << iter << ":" << "\t u=" << u << ", v=" << v - << "\t update = " << update[0] << ", " << update[1] + << "\t update = " << update[0] << ", " << update[1]<< endl; // << "\t new chi2 = " << new_chi2 << endl; #endif diff --git a/GPU_version/svo/src/feature_detection.cpp b/GPU_version/svo/src/feature_detection.cpp index b5823dd..333e602 100644 --- a/GPU_version/svo/src/feature_detection.cpp +++ b/GPU_version/svo/src/feature_detection.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include namespace svo { namespace feature_detection { diff --git a/GPU_version/svo/src/frame.cpp b/GPU_version/svo/src/frame.cpp index 632e376..3aa9273 100644 --- a/GPU_version/svo/src/frame.cpp +++ b/GPU_version/svo/src/frame.cpp @@ -19,9 +19,8 @@ #include #include #include -#include -#include -#include +#include +#include namespace svo { diff --git a/GPU_version/svo/src/frame_handler_base.cpp b/GPU_version/svo/src/frame_handler_base.cpp index 6dcef82..2f22f65 100644 --- a/GPU_version/svo/src/frame_handler_base.cpp +++ b/GPU_version/svo/src/frame_handler_base.cpp @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include +#include #include #include #include @@ -30,48 +30,14 @@ namespace svo { // definition of global and static variables which were declared in the header -#ifdef SVO_TRACE -vk::PerformanceMonitor* g_permon = NULL; -#endif FrameHandlerBase::FrameHandlerBase() : stage_(STAGE_PAUSED), set_reset_(false), set_start_(false), - acc_frame_timings_(10), - acc_num_obs_(10), num_obs_last_(0), tracking_quality_(TRACKING_INSUFFICIENT) { -#ifdef SVO_TRACE - // Initialize Performance Monitor - g_permon = new vk::PerformanceMonitor(); - g_permon->addTimer("pyramid_creation"); - g_permon->addTimer("sparse_img_align"); - g_permon->addTimer("reproject"); - g_permon->addTimer("reproject_kfs"); - g_permon->addTimer("reproject_candidates"); - g_permon->addTimer("feature_align"); - g_permon->addTimer("pose_optimizer"); - g_permon->addTimer("point_optimizer"); - g_permon->addTimer("local_ba"); - g_permon->addTimer("tot_time"); - g_permon->addLog("timestamp"); - g_permon->addLog("img_align_n_tracked"); - g_permon->addLog("repr_n_mps"); - g_permon->addLog("repr_n_new_references"); - g_permon->addLog("sfba_thresh"); - g_permon->addLog("sfba_error_init"); - g_permon->addLog("sfba_error_final"); - g_permon->addLog("sfba_n_edges_final"); - g_permon->addLog("loba_n_erredges_init"); - g_permon->addLog("loba_n_erredges_fin"); - g_permon->addLog("loba_err_init"); - g_permon->addLog("loba_err_fin"); - g_permon->addLog("n_candidates"); - g_permon->addLog("dropout"); - g_permon->init(Config::traceName(), Config::traceDir()); -#endif SVO_INFO_STREAM("SVO initialized"); } @@ -79,9 +45,6 @@ FrameHandlerBase::FrameHandlerBase() : FrameHandlerBase::~FrameHandlerBase() { SVO_INFO_STREAM("SVO destructor invoked"); -#ifdef SVO_TRACE - delete g_permon; -#endif } bool FrameHandlerBase::startFrameProcessingCommon(const double timestamp) @@ -95,10 +58,7 @@ bool FrameHandlerBase::startFrameProcessingCommon(const double timestamp) if(stage_ == STAGE_PAUSED) return false; - SVO_LOG(timestamp); SVO_DEBUG_STREAM("New Frame"); - SVO_START_TIMER("tot_time"); - timer_.start(); // some cleanup from last iteration, can't do before because of visualization map_.emptyTrash(); @@ -110,24 +70,15 @@ int FrameHandlerBase::finishFrameProcessingCommon( const UpdateResult dropout, const size_t num_observations) { - SVO_DEBUG_STREAM("Frame: "<writeToFile(); - { - boost::unique_lock lock(map_.point_candidates_.mut_); - size_t n_candidates = map_.point_candidates_.candidates_.size(); - SVO_LOG(n_candidates); - } -#endif + // SVO_STOP_TIMER("tot_time"); if(dropout == RESULT_FAILURE && (stage_ == STAGE_DEFAULT_FRAME || stage_ == STAGE_RELOCALIZING )) @@ -181,10 +132,8 @@ void FrameHandlerBase::optimizeStructure( int max_iter) { deque pts; - for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it) - { - if((*it)->point != NULL) - pts.push_back((*it)->point); + for(auto&& it:frame->fts_){ + if(it->point!=NULL)pts.push_back(it->point); } max_n_pts = min(max_n_pts, pts.size()); nth_element(pts.begin(), pts.begin() + max_n_pts, pts.end(), ptLastOptimComparator); diff --git a/GPU_version/svo/src/frame_handler_mono.cpp b/GPU_version/svo/src/frame_handler_mono.cpp index cb4acf6..278c95b 100644 --- a/GPU_version/svo/src/frame_handler_mono.cpp +++ b/GPU_version/svo/src/frame_handler_mono.cpp @@ -22,8 +22,8 @@ #include #include #include -#include #include +#include #ifdef USE_BUNDLE_ADJUSTMENT #include #endif @@ -47,7 +47,7 @@ FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam,Sophus::SE3& SE_init) gpu_fast_->write_buf(0,3,(1 << 18)); klt_homography_init_=new initialization::KltHomographyInit(gpu_fast_); initialize(); - imu_integPtr_=std::make_unique(SE_init); + imu_integPtr_=std::make_shared(SE_init); } void FrameHandlerMono::initialize() @@ -111,21 +111,19 @@ FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() { + new_frame_->T_f_w_ = last_frame_->T_f_w_; initialization::InitResult res = klt_homography_init_->addSecondFrame(new_frame_); - if(res == initialization::FAILURE) - return RESULT_FAILURE; - else if(res == initialization::NO_KEYFRAME) + if(res == initialization::NO_KEYFRAME) return RESULT_NO_KEYFRAME; - // two-frame bundle adjustment -#ifdef USE_BUNDLE_ADJUSTMENT - ba::twoViewBA(new_frame_.get(), map_.lastKeyframe().get(), Config::lobaThresh(), &map_); -#endif - new_frame_->setKeyframe(); double depth_mean, depth_min; frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); + depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min); + if(!imu_integPtr_->init(new_frame_)){ + return RESULT_FAILURE; + } // add frame to map map_.addKeyframe(new_frame_); @@ -135,37 +133,49 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() return RESULT_IS_KEYFRAME; } + FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() { - // Set initial pose TODO use prior - new_frame_->T_f_w_ = last_frame_->T_f_w_; - + SE3 tem=imu_integPtr_->preintegrate_predict(); + Eigen::Quaternion q(tem.rotation_matrix()); + q.vec() *= 1/q.norm(); + q.w() *= 1/q.norm(); + q.x()=0.0; + q.z()=0.0; + tem.translation().y()=0.0; + new_frame_->T_f_w_ = SE3(q,tem.translation()); // sparse image align SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), - 30, SparseImgAlign::GaussNewton, false, false); + 30, SparseImgAlign::LevenbergMarquardt, false, true); img_align.run(last_frame_, new_frame_); // map reprojection & feature alignment reprojector_.reprojectMap(new_frame_, overlap_kfs_); - std::cerr<<"Reprojection Map:\t nPoints = "<T_f_w_ = last_frame_->T_f_w_; // reset to avoid crazy pose jumps - tracking_quality_ = TRACKING_INSUFFICIENT; - return RESULT_FAILURE; + std::cerr<<"Reprojection Map: "<<"\t nPoint:"<predict(new_frame_,last_frame_,sfba_n_edges_final,Config::poseOptimThresh())){ + std::cerr<<"imu failed\n"; + return RESULT_FAILURE; } + //usleep(5000); + double sfba_thresh, sfba_error_init, sfba_error_final; + pose_optimizer::optimizeGaussNewton( + Config::poseOptimThresh(), Config::poseOptimNumIter(), false, + new_frame_, sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final); // pose optimization subject to change for adding IMU - size_t sfba_n_edges_final; - if(!imu_integPtr_->predict(new_frame_,sfba_n_edges_final,Config::poseOptimThresh())) + /* + if(!imu_integPtr_->predict(new_frame_,last_frame_,sfba_n_edges_final,Config::poseOptimThresh())){ + std::cerr<<"imu failed\n"; return RESULT_FAILURE; - + }*/ std::cerr<<"Reprojected points after opmization: "<T_f_w_ = last_frame_->T_f_w_; // reset to avoid crazy pose jumps return RESULT_FAILURE; } double depth_mean, depth_min; @@ -187,28 +196,10 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() new_frame_->setKeyframe(); // new keyframe selected - for(Features::iterator it=new_frame_->fts_.begin(); it!=new_frame_->fts_.end(); ++it) - if((*it)->point != NULL) - (*it)->point->addFrameRef(*it); - map_.point_candidates_.addCandidatePointToFrame(new_frame_); - - // optional bundle adjustment -#ifdef USE_BUNDLE_ADJUSTMENT - if(Config::lobaNumIter() > 0) - { - SVO_START_TIMER("local_ba"); - setCoreKfs(Config::coreNKfs()); - size_t loba_n_erredges_init, loba_n_erredges_fin; - double loba_err_init, loba_err_fin; - ba::localBA(new_frame_.get(), &core_kfs_, &map_, - loba_n_erredges_init, loba_n_erredges_fin, - loba_err_init, loba_err_fin); - SVO_STOP_TIMER("local_ba"); - SVO_LOG4(loba_n_erredges_init, loba_n_erredges_fin, loba_err_init, loba_err_fin); - SVO_DEBUG_STREAM("Local BA:\t RemovedEdges {"<fts_){ + if(it->point != NULL)it->point->addFrameRef(it); } -#endif + map_.point_candidates_.addCandidatePointToFrame(new_frame_); // init new depth-filters depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min); @@ -294,12 +285,12 @@ void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame) bool FrameHandlerMono::needNewKf(double scene_depth_mean) { - for(auto it=overlap_kfs_.begin(), ite=overlap_kfs_.end(); it!=ite; ++it) + for(auto&& it:overlap_kfs_) { - Vector3d relpos = new_frame_->w2f(it->first->pos()); + Vector3d relpos = new_frame_->w2f(it.first->pos()); if(fabs(relpos.x())/scene_depth_mean < Config::kfSelectMinDist() && - fabs(relpos.y())/scene_depth_mean < Config::kfSelectMinDist()*0.8 && - fabs(relpos.z())/scene_depth_mean < Config::kfSelectMinDist()*1.3) + fabs(relpos.y())/scene_depth_mean < Config::kfSelectMinDist() && + fabs(relpos.z())/scene_depth_mean < Config::kfSelectMinDist()) return false; } return true; diff --git a/GPU_version/svo/src/homography.cpp b/GPU_version/svo/src/homography.cpp new file mode 100644 index 0000000..c73617d --- /dev/null +++ b/GPU_version/svo/src/homography.cpp @@ -0,0 +1,285 @@ +// +// Created by root on 5/24/21. +// +/* + * homography.cpp + * Adaptation of PTAM-GPL HomographyInit class. + * https://github.com/Oxford-PTAM/PTAM-GPL + * Licence: GPLv3 + * Copyright 2008 Isis Innovation Limited + * + * Created on: Sep 2, 2012 + * by: cforster + */ + +#include +#include +#include + +namespace vk { + + Homography:: + Homography(const vector >& _fts1, + const vector >& _fts2, + double _error_multiplier2, + double _thresh_in_px) : + thresh(_thresh_in_px), + error_multiplier2(_error_multiplier2), + fts_c1(_fts1), + fts_c2(_fts2) + { + } + + void Homography:: + calcFromPlaneParams(const Vector3d& n_c1, const Vector3d& xyz_c1) + { + double d = n_c1.dot(xyz_c1); // normal distance from plane to KF + H_c2_from_c1 = T_c2_from_c1.rotation_matrix() + (T_c2_from_c1.translation()*n_c1.transpose())/d; + } + + void Homography:: + calcFromMatches() + { + vector src_pts(fts_c1.size()), dst_pts(fts_c1.size()); + for(size_t i=0; i(0,0); + H_c2_from_c1(0,1) = cvH.at(0,1); + H_c2_from_c1(0,2) = cvH.at(0,2); + H_c2_from_c1(1,0) = cvH.at(1,0); + H_c2_from_c1(1,1) = cvH.at(1,1); + H_c2_from_c1(1,2) = cvH.at(1,2); + H_c2_from_c1(2,0) = cvH.at(2,0); + H_c2_from_c1(2,1) = cvH.at(2,1); + H_c2_from_c1(2,2) = cvH.at(2,2); + } + + size_t Homography:: + computeMatchesInliers() + { + inliers.clear(); inliers.resize(fts_c1.size()); + size_t n_inliers = 0; + for(size_t i=0; i q(decompositions.front().T.rotation_matrix()); + q.vec() *= 1/q.norm(); + q.w() *= 1/q.norm(); + q.x()=0.0; + q.z()=0.0; + T_c2_from_c1=Sophus::SE3(q.toRotationMatrix(),Eigen::Vector3d(decompositions.front().T.translation().x(),0.0,decompositions.front().T.translation().z())); + return true; + } + + bool Homography:: + decompose() + { + decompositions.clear(); + JacobiSVD svd(H_c2_from_c1, ComputeThinU | ComputeThinV); + + Vector3d singular_values = svd.singularValues(); + + double d1 = fabs(singular_values[0]); // The paper suggests the square of these (e.g. the evalues of AAT) + double d2 = fabs(singular_values[1]); // should be used, but this is wrong. c.f. Faugeras' book. + double d3 = fabs(singular_values[2]); + + Matrix3d U = svd.matrixU(); + Matrix3d V = svd.matrixV(); // VT^T + double s = U.determinant() * V.determinant(); + + if(!(d1 != d2 && d2 != d3)) + { + printf("FATAL Homography Initialization: This motion case is not implemented or is degenerate. Try again. "); + return false; + } + + double x1_PM; + double x3_PM; + + // All below deals with the case = 1 case. + // Case 1 implies (d1 != d3) + { // Eq. 12 + x1_PM = sqrt((d1*d1 - d2*d2) / (d1*d1 - d3*d3)); + x3_PM = sqrt((d2*d2 - d3*d3) / (d1*d1 - d3*d3)); + }; + + double e1[4] = {1.0,-1.0, 1.0,-1.0}; + double e3[4] = {1.0, 1.0,-1.0,-1.0}; + + Vector3d np; + HomographyDecomposition decomp; + + // Case 1, d' > 0: + decomp.d = s * d2; + for(size_t signs=0; signs<4; signs++) + { + // Eq 13 + decomp.R = Matrix3d::Identity(); + double dSinTheta = (d1 - d3) * x1_PM * x3_PM * e1[signs] * e3[signs] / d2; + double dCosTheta = (d1 * x3_PM * x3_PM + d3 * x1_PM * x1_PM) / d2; + /* + * correct the rotation matrix by Majid + */ + decomp.R(0,0) = dCosTheta; //1 + decomp.R(0,2) = -dSinTheta; //0 + decomp.R(2,0) = dSinTheta; + decomp.R(2,2) = dCosTheta; + + // Eq 14 + decomp.t[0] = (d1 - d3) * x1_PM * e1[signs]; + decomp.t[1] = 0.0; + decomp.t[2] = (d1 - d3) * -x3_PM * e3[signs]; + + np[0] = x1_PM * e1[signs]; + np[1] = 0.0; + np[2] = x3_PM * e3[signs]; + decomp.n = V * np; + + decompositions.push_back(decomp); + } + + // Case 1, d' < 0: + decomp.d = s * -d2; + for(size_t signs=0; signs<4; signs++) + { + // Eq 15 + decomp.R = -1 * Matrix3d::Identity(); + double dSinPhi = (d1 + d3) * x1_PM * x3_PM * e1[signs] * e3[signs] / d2; + double dCosPhi = (d3 * x1_PM * x1_PM - d1 * x3_PM * x3_PM) / d2; + /* + * correct the rotation matrix by Majid + */ + decomp.R(0,0) = dCosPhi; + decomp.R(0,2) = dSinPhi; + decomp.R(2,0) = dSinPhi; + decomp.R(2,2) = -dCosPhi; + + // Eq 16 + decomp.t[0] = (d1 + d3) * x1_PM * e1[signs]; + decomp.t[1] = 0.0; + decomp.t[2] = (d1 + d3) * x3_PM * e3[signs]; + + np[0] = x1_PM * e1[signs]; + np[1] = 0.0; + np[2] = x3_PM * e3[signs]; + decomp.n = V * np; + + decompositions.push_back(decomp); + } + + // Save rotation and translation of the decomposition + for(unsigned int i=0; i 0.0) + nPositive++; + } + decom.score = -nPositive; + } + + sort(decompositions.begin(), decompositions.end()); + decompositions.resize(4); + + for(size_t i=0; i 0.0) + nPositive++; + }; + decom.score = -nPositive; + } + + sort(decompositions.begin(), decompositions.end()); + decompositions.resize(2); + + // According to Faugeras and Lustman, ambiguity exists if the two scores are equal + // but in practive, better to look at the ratio! + double dRatio = (double) decompositions[1].score / (double) decompositions[0].score; + + if(dRatio < 0.9) // no ambiguity! + decompositions.erase(decompositions.begin() + 1); + else // two-way ambiguity. Resolve by sampsonus score of all points. + { + double dErrorSquaredLimit = thresh * thresh * 4; + double adSampsonusScores[2]; + for(size_t i=0; i<2; i++) + { + Sophus::SE3 T = decompositions[i].T; + Matrix3d Essential = T.rotation_matrix() * sqew(T.translation()); + double dSumError = 0; + for(size_t m=0; m < fts_c1.size(); m++ ) + { + double d = sampsonusError(fts_c1[m], Essential, fts_c2[m]); + if(d > dErrorSquaredLimit) + d = dErrorSquaredLimit; + dSumError += d; + } + adSampsonusScores[i] = dSumError; + } + + if(adSampsonusScores[0] <= adSampsonusScores[1]) + decompositions.erase(decompositions.begin() + 1); + else + decompositions.erase(decompositions.begin()); + } + } + + +} /* end namespace vk */ + diff --git a/GPU_version/svo/src/imu_integration.cpp b/GPU_version/svo/src/imu_integration.cpp index 922ef66..3b371d7 100644 --- a/GPU_version/svo/src/imu_integration.cpp +++ b/GPU_version/svo/src/imu_integration.cpp @@ -7,11 +7,14 @@ #include #include "gpu_svo/feature.h" #include "gpu_svo/point.h" -#include "gpu_svo/svoVisionFactor.h" +#include "gpu_svo/svoVisionFactorSmall.h" +//#include "gpu_svo/svoVisionFactor.h" +//#include "gpu_svo/svoVisionFactorLandMark.h" #include #include #include #include +#include Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ graphPtr=std::make_shared(); @@ -19,7 +22,7 @@ Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ // Example: pitch and roll of aircraft in an ENU Cartesian frame. // If pitch and roll are zero for an aerospace frame, // that means Z is pointing down, i.e., direction of Z = (0,0,-1) - gtsam::Vector4 g=SE_init.matrix()*gtsam::Vector4(0, 0, 9.8,1.0); + gtsam::Vector4 g=SE_init.matrix()*gtsam::Vector4(0, 0, svo::Config::Gravity(),1.0); parameterPtr = boost::shared_ptr(new gtsam::PreintegrationCombinedParams(gtsam::Vector3(g.x(),g.y(),g.z()))); parameterPtr->setBodyPSensor(gtsam::Pose3(SE_init.matrix()));// The pose of the sensor in the body frame parameterPtr->accelerometerCovariance=gtsam::I_3x3 * svo::Config::ACC_Noise(); // acc white noise in continuous @@ -34,7 +37,8 @@ Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ optimizerParamPtr=std::make_shared(); optimizerParamPtr->relinearizeThreshold = 0.1; optimizerParamPtr->relinearizeSkip = 1; - //optimizerParamPtr->evaluateNonlinearError=true; + optimizerParamPtr->evaluateNonlinearError=true; + optimizerParamPtr->enableDetailedResults=true; assert(preintegratedPtr); } Imu_Integration::~Imu_Integration(){ @@ -46,9 +50,9 @@ bool Imu_Integration::update(double* imu){ auto in=std::chrono::steady_clock::now(); if(std::chrono::duration(in-t_1).count()>20.0){ t_1=in; - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),0.005); + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0]-svo::Config::X_off(),imu[1]-svo::Config::Y_off(),imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]-svo::Config::Teta_off()),0.005); }else{ - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0],imu[1],imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]),std::chrono::duration(in-t_1).count()); + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0]-svo::Config::X_off(),imu[1]-svo::Config::Y_off(),imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]-svo::Config::Teta_off()),std::chrono::duration(in-t_1).count()); t_1=in; ++imu_n; } @@ -73,10 +77,18 @@ bool Imu_Integration::reset(gtsam::ISAM2& optimizer,boost::shared_ptraddPrior(P(imu_factor_id-1),statePtr->pose(),optimizer.marginalCovariance(P(imu_factor_id-1))); graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),optimizer.marginalCovariance(V(imu_factor_id-1))); graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,optimizer.marginalCovariance(B(imu_factor_id-1))); + for(auto&& f_n:_for(new_frame->fts_)){ + if(f_n.item->point == NULL)continue; + if(!result.exists(L(f_n.index)))continue; + f_n.item->point->pos_=result.at(L(f_n.index)); + // valuesPtr->insert(L(f_n.index),f_n.item->point->pos_); +// graphPtr->emplace_shared(f_n.item->f,f_n.item->level,ProjectNoisePtr,P(imu_factor_id),L(f_n.index)); + } return true; } bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr& new_frame){ gtsam::Values result = optimizer.optimize(); + optimizer.print(); // Overwrite the beginning of the preintegration for the next step. statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); @@ -84,6 +96,7 @@ bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost: ++imu_factor_id; syn=false; gtsam::Marginals marginals(*graphPtr,result); + marginals.print(); new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); new_frame->Cov_=marginals.marginalCovariance(P(imu_factor_id-1)); graphPtr->resize(0); @@ -94,50 +107,66 @@ bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost: graphPtr->addPrior(P(imu_factor_id-1),statePtr->pose(),marginals.marginalCovariance(P(imu_factor_id-1))); graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),marginals.marginalCovariance(V(imu_factor_id-1))); graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,marginals.marginalCovariance(B(imu_factor_id-1))); + /* + for(auto&& f_n:_for(new_frame->fts_)){ + if(f_n.item->point == NULL)continue; + if(!result.exists(L(f_n.index)))continue; + f_n.item->point->pos_=result.at(L(f_n.index)); + //valuesPtr->insert(L(f_n.index),f_n.item->point->pos_); + //graphPtr->emplace_shared(f_n.item->f,f_n.item->level,ProjectNoisePtr,P(imu_factor_id),L(f_n.index)); + } + //graphPtr->addPrior(L(0),new_frame->fts_.front()->point->pos_,gtsam::noiseModel::Isotropic::Sigma(3, 1e-4)); + */ return true; } -bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size_t& num_obs,const double reproj_thresh){ - usleep(5000); - syn=true; - if(imu_factor_id<1){ - statePtr=std::make_shared(gtsam::Pose3(new_frame->T_f_w_.matrix()), - gtsam::Vector3(1e-12,1e-12,1e-12)); - valuesPtr->insert(P(0),statePtr->pose()); - valuesPtr->insert(V(0),statePtr->v()); - valuesPtr->insert(B(0),*imu_biasPtr); - graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 1e-9, 1e-9, 1e-9, 1e-9, 1e-9, 1e-9).finished())); - graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 1e-4)); - graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-2)); +Sophus::SE3 Imu_Integration::preintegrate_predict() { + if(imu_n<1){ + syn= false; + usleep(10000); + syn=true; }else{ - if(imu_n<1)return false; - auto preint_imu_combined =dynamic_cast(*preintegratedPtr); - //preint_imu_combined.predict(*statePtr,*imu_biasPtr).print(); - //std::cerr<T_f_w_.matrix(); - valuesPtr->insert(P(imu_factor_id), gtsam::Pose3(new_frame->T_f_w_.matrix())); - valuesPtr->insert(V(imu_factor_id), statePtr->v()); - valuesPtr->insert(B(imu_factor_id), *imu_biasPtr); - gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), - preint_imu_combined); - graphPtr->emplace_shared(imu_factor); - imu_n=0; + syn=true; } + auto preint_imu_combined =dynamic_cast(*preintegratedPtr); + Integ_predict=preint_imu_combined.predict(*statePtr,*imu_biasPtr); + return Sophus::SE3(Integ_predict.R(),Integ_predict.t()); +} +bool Imu_Integration::predict(boost::shared_ptr& new_frame, + boost::shared_ptr& last_frame, + std::size_t& num_obs,const double reproj_thresh){ + + auto preint_imu_combined =dynamic_cast(*preintegratedPtr); + valuesPtr->insert(P(imu_factor_id), gtsam::Pose3(new_frame->T_f_w_.matrix())); + valuesPtr->insert(V(imu_factor_id), Integ_predict.v()); + valuesPtr->insert(B(imu_factor_id), *imu_biasPtr); + gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), + preint_imu_combined); + graphPtr->emplace_shared(imu_factor); + imu_n=0; - num_obs=0; for(auto&& f:new_frame->fts_){ - if(f->point==NULL)continue; + if(f->point==NULL)continue; graphPtr->emplace_shared(f->f, f->point->pos_,f->level, ProjectNoisePtr,P(imu_factor_id)); ++num_obs; } - // Now optimize. - gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr); + std::cout<<"------------------------------------------------------------------------------\n"; + std::cout<<"------------------------------------------------------------------------------\n"; + std::cout<<"------------------------------------------------------------------------------\n"; + graphPtr->print(); + gtsam::LevenbergMarquardtParams params0; + //params0.verbosity=gtsam::LevenbergMarquardtParams::LINEAR; + params0.verbosityLM = gtsam::LevenbergMarquardtParams::SUMMARY; + params0.setlambdaFactor(10.0); + gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr,params0); reset(optimizer,new_frame); + std::cout<<"------------------------------------------------------------------------------\n"; // Remove Measurements with too large reprojection error + /* double reproj_thresh_scaled = reproj_thresh / new_frame->cam_->errorMultiplier2(); for(auto&& f:new_frame->fts_) { - if(f->point == NULL) - continue; + if(f->point == NULL)continue; Eigen::Vector2d e = (vk::project2d(f->f) - vk::project2d(new_frame->T_f_w_ * f->point->pos_))*1.0 / (1<level); if(e.norm() > reproj_thresh_scaled) { @@ -146,5 +175,26 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame,std::size --num_obs; } } + */ + return true; +} +bool Imu_Integration::init(boost::shared_ptr& new_frame){ + statePtr=std::make_shared(gtsam::Pose3(new_frame->T_f_w_.matrix()), + gtsam::Vector3(1e-9,1e-9,1e-9)); + valuesPtr->insert(P(0),statePtr->pose()); + valuesPtr->insert(V(0),statePtr->v()); + valuesPtr->insert(B(0),*imu_biasPtr); + graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 1e-5, 1e-15, 1e-5, 1e-15, 1e-8, 1e-15).finished())); + graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 1e-4)); + graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-2)); + /* + for(auto&& f_n:_for(new_frame->fts_)){ + if(f_n.item->point == NULL)continue; + valuesPtr->insert(L(f_n.index),f_n.item->point->pos_); + graphPtr->emplace_shared(f_n.item->f,f_n.item->level,ProjectNoisePtr,P(imu_factor_id),L(f_n.index)); + } + graphPtr->addPrior(L(0),new_frame->fts_.front()->point->pos_,gtsam::noiseModel::Isotropic::Sigma(3, 1e-4)); + */ + ++imu_factor_id; return true; } \ No newline at end of file diff --git a/GPU_version/svo/src/initialization.cpp b/GPU_version/svo/src/initialization.cpp index ce04d24..88f1cb8 100644 --- a/GPU_version/svo/src/initialization.cpp +++ b/GPU_version/svo/src/initialization.cpp @@ -20,8 +20,8 @@ #include #include #include -#include -#include +#include +#include namespace svo { namespace initialization { @@ -43,26 +43,24 @@ InitResult KltHomographyInit::addFirstFrame(FramePtr frame_ref) InitResult KltHomographyInit::addSecondFrame(FramePtr frame_cur) { trackKlt(frame_ref_, frame_cur, px_ref_, px_cur_, f_ref_, f_cur_, disparities_); - SVO_INFO_STREAM("Init: KLT tracked "<< disparities_.size() <<" features"); - if(disparities_.size() < Config::initMinTracked()) - return FAILURE; - + return NO_KEYFRAME; double disparity = vk::getMedian(disparities_); - SVO_INFO_STREAM("Init: KLT "<cam_->errorMultiplier2(), Config::poseOptimThresh(), inliers_, xyz_in_cur_, T_cur_from_ref_); - SVO_INFO_STREAM("Init: Homography RANSAC "<T_f_w_ = T_cur_from_ref_ * frame_ref_->T_f_w_; - frame_cur->T_f_w_.translation() = - -frame_cur->T_f_w_.rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); + frame_cur->T_f_w_.translation() = -frame_cur->T_f_w_.rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); // For each inlier create 3D point and add feature in both frames SE3 T_world_cur = frame_cur->T_f_w_.inverse(); - for(vector::iterator it=inliers_.begin(); it!=inliers_.end(); ++it) - { - Vector2d px_cur(px_cur_[*it].x, px_cur_[*it].y); - Vector2d px_ref(px_ref_[*it].x, px_ref_[*it].y); - if(frame_ref_->cam_->isInFrame(px_cur.cast(), 10) && frame_ref_->cam_->isInFrame(px_ref.cast(), 10) && xyz_in_cur_[*it].z() > 0) + for(vector::iterator it=inliers_.begin(); it!=inliers_.end(); ++it) { - Vector3d pos = T_world_cur * (xyz_in_cur_[*it]*scale); - Point* new_point = new Point(pos); + Vector2d px_cur(px_cur_[*it].x, px_cur_[*it].y); + Vector2d px_ref(px_ref_[*it].x, px_ref_[*it].y); + if(frame_ref_->cam_->isInFrame(px_cur.cast(), 10) && frame_ref_->cam_->isInFrame(px_ref.cast(), 10) && xyz_in_cur_[*it].z() > 0) + { + Vector3d pos = T_world_cur * (xyz_in_cur_[*it]*scale); + Point* new_point = new Point(pos); - Feature* ftr_cur(new Feature(frame_cur.get(), new_point, px_cur, f_cur_[*it], 0)); - frame_cur->addFeature(ftr_cur); - new_point->addFrameRef(ftr_cur); + Feature* ftr_cur(new Feature(frame_cur.get(), new_point, px_cur, f_cur_[*it], 0)); + frame_cur->addFeature(ftr_cur); + new_point->addFrameRef(ftr_cur); - Feature* ftr_ref(new Feature(frame_ref_.get(), new_point, px_ref, f_ref_[*it], 0)); - frame_ref_->addFeature(ftr_ref); - new_point->addFrameRef(ftr_ref); + Feature* ftr_ref(new Feature(frame_ref_.get(), new_point, px_ref, f_ref_[*it], 0)); + frame_ref_->addFeature(ftr_ref); + new_point->addFrameRef(ftr_ref); + } } - } + SVO_INFO_STREAM("Init Homography RANSAC (inlier) is: "<fts_.size()); return SUCCESS; } @@ -118,11 +118,11 @@ void detectFeatures( // now for all maximum corners, initialize a new seed px_vec.clear(); px_vec.reserve(new_features.size()); f_vec.clear(); f_vec.reserve(new_features.size()); - std::for_each(new_features.begin(), new_features.end(), [&](Feature* ftr){ - px_vec.push_back(cv::Point2f(ftr->px[0], ftr->px[1])); - f_vec.push_back(ftr->f); - delete ftr; - }); + for(auto&& ftr:new_features){ + px_vec.push_back(cv::Point2f(ftr->px[0], ftr->px[1])); + f_vec.push_back(ftr->f); + delete ftr; + } } void trackKlt( @@ -134,8 +134,8 @@ void trackKlt( vector& f_cur, vector& disparities) { - const double klt_win_size = 30.0; - const int klt_max_iter = 30; + const double klt_win_size = 45.0;//30.0 + const int klt_max_iter = 30;//30 const double klt_eps = 0.001; vector status; vector error; diff --git a/GPU_version/svo/src/matcher.cpp b/GPU_version/svo/src/matcher.cpp index 9f44701..26e9dfc 100644 --- a/GPU_version/svo/src/matcher.cpp +++ b/GPU_version/svo/src/matcher.cpp @@ -15,10 +15,10 @@ // along with this program. If not, see . #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -139,7 +139,6 @@ bool Matcher::findMatchDirect( { if(!pt.getCloseViewObs(cur_frame.pos(), ref_ftr_)) return false; - if(!ref_ftr_->frame->cam_->isInFrame( ref_ftr_->px.cast()/(1<level), halfpatch_size_+2, ref_ftr_->level)) return false; diff --git a/GPU_version/svo/src/math_utils.cpp b/GPU_version/svo/src/math_utils.cpp new file mode 100644 index 0000000..9c265ec --- /dev/null +++ b/GPU_version/svo/src/math_utils.cpp @@ -0,0 +1,202 @@ +/* + * math_utils.cpp + * + * Created on: Jul 20, 2012 + * Author: cforster + */ + +#include + +namespace vk { + +using namespace Eigen; + +Vector3d +triangulateFeatureNonLin(const Matrix3d& R, const Vector3d& t, + const Vector3d& feature1, const Vector3d& feature2 ) +{ + Vector3d f2 = R * feature2; + Vector2d b; + b[0] = t.dot(feature1); + b[1] = t.dot(f2); + Matrix2d A; + A(0,0) = feature1.dot(feature1); + A(1,0) = feature1.dot(f2); + A(0,1) = -A(1,0); + A(1,1) = -f2.dot(f2); + Vector2d lambda = A.inverse() * b; + Vector3d xm = lambda[0] * feature1; + Vector3d xn = t + lambda[1] * f2; + return ( xm + xn )/2; +} + +bool +depthFromTriangulationExact( + const Matrix3d& R_r_c, + const Vector3d& t_r_c, + const Vector3d& f_r, + const Vector3d& f_c, + double& depth_in_r, + double& depth_in_c) +{ + // bearing vectors (f_r, f_c) do not need to be unit length + const Vector3d f_c_in_r(R_r_c*f_c); + const double a = f_c_in_r.dot(f_r) / t_r_c.dot(f_r); + const double b = f_c_in_r.dot(t_r_c); + const double denom = (a*b - f_c_in_r.dot(f_c_in_r)); + + if(abs(denom) < 0.000001) + return false; + + depth_in_c = (b-a*t_r_c.dot(t_r_c)) / denom; + depth_in_r = (t_r_c + f_c_in_r*depth_in_c).norm(); + return true; +} + +double +reprojError(const Vector3d& f1, + const Vector3d& f2, + double error_multiplier2) +{ + Vector2d e = project2d(f1) - project2d(f2); + return error_multiplier2 * e.norm(); +} + +double +computeInliers(const vector& features1, // c1 + const vector& features2, // c2 + const Matrix3d& R, // R_c1_c2 + const Vector3d& t, // c1_t + const double reproj_thresh, + double error_multiplier2, + vector& xyz_vec, // in frame c1 + vector& inliers, + vector& outliers) +{ + inliers.clear(); inliers.reserve(features1.size()); + outliers.clear(); outliers.reserve(features1.size()); + xyz_vec.clear(); xyz_vec.reserve(features1.size()); + double tot_error = 0; + //triangulate all features and compute reprojection errors and inliers + for(size_t j=0; j reproj_thresh || e2 > reproj_thresh) + outliers.push_back(j); + else + { + inliers.push_back(j); + tot_error += e1+e2; + } + } + return tot_error; +} + +void +computeInliersOneView(const vector & feature_sphere_vec, + const vector & xyz_vec, + const Matrix3d &R, + const Vector3d &t, + const double reproj_thresh, + const double error_multiplier2, + vector& inliers, + vector& outliers) +{ + inliers.clear(); inliers.reserve(xyz_vec.size()); + outliers.clear(); outliers.reserve(xyz_vec.size()); + for(size_t j = 0; j < xyz_vec.size(); j++ ) + { + double e = reprojError(feature_sphere_vec[j], + R.transpose() * ( xyz_vec[j] - t ), + error_multiplier2); + if(e < reproj_thresh) + inliers.push_back(j); + else + outliers.push_back(j); + } +} + +Vector3d +dcm2rpy(const Matrix3d &R) +{ + Vector3d rpy; + rpy[1] = atan2( -R(2,0), sqrt( pow( R(0,0), 2 ) + pow( R(1,0), 2 ) ) ); + if( fabs( rpy[1] - M_PI/2 ) < 0.00001 ) + { + rpy[2] = 0; + rpy[0] = -atan2( R(0,1), R(1,1) ); + } + else + { + if( fabs( rpy[1] + M_PI/2 ) < 0.00001 ) + { + rpy[2] = 0; + rpy[0] = -atan2( R(0,1), R(1,1) ); + } + else + { + rpy[2] = atan2( R(1,0)/cos(rpy[1]), R(0,0)/cos(rpy[1]) ); + rpy[0] = atan2( R(2,1)/cos(rpy[1]), R(2,2)/cos(rpy[1]) ); + } + } + return rpy; +} + +Matrix3d +rpy2dcm(const Vector3d &rpy) +{ + Matrix3d R1; + R1(0,0) = 1.0; R1(0,1) = 0.0; R1(0,2) = 0.0; + R1(1,0) = 0.0; R1(1,1) = cos(rpy[0]); R1(1,2) = -sin(rpy[0]); + R1(2,0) = 0.0; R1(2,1) = -R1(1,2); R1(2,2) = R1(1,1); + + Matrix3d R2; + R2(0,0) = cos(rpy[1]); R2(0,1) = 0.0; R2(0,2) = sin(rpy[1]); + R2(1,0) = 0.0; R2(1,1) = 1.0; R2(1,2) = 0.0; + R2(2,0) = -R2(0,2); R2(2,1) = 0.0; R2(2,2) = R2(0,0); + + Matrix3d R3; + R3(0,0) = cos(rpy[2]); R3(0,1) = -sin(rpy[2]); R3(0,2) = 0.0; + R3(1,0) = -R3(0,1); R3(1,1) = R3(0,0); R3(1,2) = 0.0; + R3(2,0) = 0.0; R3(2,1) = 0.0; R3(2,2) = 1.0; + + return R3 * R2 * R1; +} + +Quaterniond +angax2quat(const Vector3d& n, const double& angle) +{ + // n must be normalized! + double s(sin(angle/2)); + return Quaterniond( cos(angle/2), n[0]*s, n[1]*s, n[2]*s ); +} + + +Matrix3d +angax2dcm(const Vector3d& n, const double& angle) +{ + // n must be normalized + Matrix3d sqewn(sqew(n)); + return Matrix3d(Matrix3d::Identity() + sqewn*sin(angle) + sqewn*sqewn*(1-cos(angle))); +} + +double +sampsonusError(const Vector2d &v2Dash, const Matrix3d& Essential, const Vector2d& v2) +{ + Vector3d v3Dash = unproject2d(v2Dash); + Vector3d v3 = unproject2d(v2); + + double dError = v3Dash.transpose() * Essential * v3; + + Vector3d fv3 = Essential * v3; + Vector3d fTv3Dash = Essential.transpose() * v3Dash; + + Vector2d fv3Slice = fv3.head<2>(); + Vector2d fTv3DashSlice = fTv3Dash.head<2>(); + + return (dError * dError / (fv3Slice.dot(fv3Slice) + fTv3DashSlice.dot(fTv3DashSlice))); +} + +} // end namespace vk diff --git a/GPU_version/svo/src/point.cpp b/GPU_version/svo/src/point.cpp index 533bed4..24423eb 100644 --- a/GPU_version/svo/src/point.cpp +++ b/GPU_version/svo/src/point.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see . #include -#include +#include #include #include #include diff --git a/GPU_version/svo/src/pose_optimizer.cpp b/GPU_version/svo/src/pose_optimizer.cpp index 8af359f..3d89d1e 100644 --- a/GPU_version/svo/src/pose_optimizer.cpp +++ b/GPU_version/svo/src/pose_optimizer.cpp @@ -19,8 +19,8 @@ #include #include #include -#include -#include +#include +#include namespace svo { namespace pose_optimizer { diff --git a/GPU_version/svo/src/reprojector.cpp b/GPU_version/svo/src/reprojector.cpp index 888d3d2..0305797 100644 --- a/GPU_version/svo/src/reprojector.cpp +++ b/GPU_version/svo/src/reprojector.cpp @@ -24,9 +24,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include namespace svo { @@ -68,10 +68,11 @@ void Reprojector::reprojectMap( resetGrid(); // Identify those Keyframes which share a common field of view. - SVO_START_TIMER("reproject_kfs"); +// SVO_START_TIMER("reproject_kfs"); list< pair > close_kfs; map_.getCloseKeyframes(frame, close_kfs); + std::cout<<"The number of closed frames: "<::second, _1) < boost::bind(&std::pair::second, _2)); @@ -98,14 +99,16 @@ void Reprojector::reprojectMap( if((*it_ftr)->point->last_projected_kf_id_ == frame->id_) continue; (*it_ftr)->point->last_projected_kf_id_ = frame->id_; - if(reprojectPoint(frame, (*it_ftr)->point)) - overlap_kfs.back().second++; + if(reprojectPoint(frame, (*it_ftr)->point)){ + overlap_kfs.back().second++; + } + } } - SVO_STOP_TIMER("reproject_kfs"); + //SVO_STOP_TIMER("reproject_kfs"); // Now project all point candidates - SVO_START_TIMER("reproject_candidates"); + // SVO_START_TIMER("reproject_candidates"); { boost::unique_lock lock(map_.point_candidates_.mut_); auto it=map_.point_candidates_.candidates_.begin(); @@ -124,11 +127,11 @@ void Reprojector::reprojectMap( ++it; } } // unlock the mutex when out of scope - SVO_STOP_TIMER("reproject_candidates"); + //SVO_STOP_TIMER("reproject_candidates"); // Now we go through each grid cell and select one point to match. // At the end, we should have at maximum one reprojected point per cell. - SVO_START_TIMER("feature_align"); + //SVO_START_TIMER("feature_align"); for(size_t i=0; i (size_t) Config::maxFts()) break; } - SVO_STOP_TIMER("feature_align"); +// SVO_STOP_TIMER("feature_align"); } bool Reprojector::pointQualityComparator(Candidate& lhs, Candidate& rhs) @@ -161,7 +164,6 @@ bool Reprojector::reprojectCell(Cell& cell, FramePtr frame) it = cell.erase(it); continue; } - bool found_match = true; if(options_.find_match_direct) found_match = matcher_.findMatchDirect(*it->pt, *frame, it->px); diff --git a/GPU_version/svo/src/robust_cost.cpp b/GPU_version/svo/src/robust_cost.cpp new file mode 100644 index 0000000..ec771ae --- /dev/null +++ b/GPU_version/svo/src/robust_cost.cpp @@ -0,0 +1,162 @@ +/** +* This file is part of dvo. +* +* Copyright 2012 Christian Kerl (Technical University of Munich) +* For more information see . +* +* dvo is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* dvo is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with dvo. If not, see . +*/ + +#include +#include +#include +#include + +namespace vk { +namespace robust_cost { + +const float TDistributionScaleEstimator::INITIAL_SIGMA = 5.0f; +const float TDistributionScaleEstimator::DEFAULT_DOF = 5.0f; + +TDistributionScaleEstimator:: +TDistributionScaleEstimator(const float dof) : + dof_(dof), + initial_sigma_(INITIAL_SIGMA) +{} + +float TDistributionScaleEstimator:: +compute(std::vector& errors) const +{ + float initial_lamda = 1.0f / (initial_sigma_ * initial_sigma_); + int num = 0; + float lambda = initial_lamda; + int iterations = 0; + do + { + ++iterations; + initial_lamda = lambda; + num = 0; + lambda = 0.0f; + + for(std::vector::iterator it=errors.begin(); it!=errors.end(); ++it) + { + if(std::isfinite(*it)) + { + ++num; + const float error2 = (*it)*(*it); + lambda += error2 * ( (dof_ + 1.0f) / (dof_ + initial_lamda * error2) ); + } + } + lambda = float(num) / lambda; + } while(std::abs(lambda - initial_lamda) > 1e-3); + + return std::sqrt(1.0f / lambda); +} + +const float MADScaleEstimator::NORMALIZER = 1.48f; // 1 / 0.6745 + +float MADScaleEstimator:: +compute(std::vector& errors) const +{ + // error must be in absolute values! + return NORMALIZER * vk::getMedian(errors); +} + +float NormalDistributionScaleEstimator:: +compute(std::vector& errors) const +{ + const float mean = std::accumulate(errors.begin(), errors.end(), 0)/errors.size(); + float var = 0.0; + std::for_each(errors.begin(), errors.end(), [&](const float d) { + var += (d - mean) * (d - mean); + }); + return std::sqrt(var); // return standard deviation +} + +const float TukeyWeightFunction::DEFAULT_B = 4.6851f; + +TukeyWeightFunction::TukeyWeightFunction(const float b) +{ + configure(b); +} + +float TukeyWeightFunction::value(const float& x) const +{ + const float x_square = x * x; + if(x_square <= b_square) + { + const float tmp = 1.0f - x_square / b_square; + return tmp * tmp; + } + else + { + return 0.0f; + } +} + +void TukeyWeightFunction:: +configure(const float& param) +{ + b_square = param * param; +} + +const float TDistributionWeightFunction::DEFAULT_DOF = 5.0f; + +TDistributionWeightFunction:: +TDistributionWeightFunction(const float dof) +{ + configure(dof); +} + +float TDistributionWeightFunction:: +value(const float & x) const +{ + return ((dof_ + 1.0f) / (dof_ + (x * x))); +} + +void TDistributionWeightFunction:: +configure(const float& param) +{ + dof_ = param; + normalizer_ = dof_ / (dof_ + 1.0f); +} + +const float HuberWeightFunction::DEFAULT_K = 1.345f; + +HuberWeightFunction:: +HuberWeightFunction(const float k) +{ + configure(k); +} + +void HuberWeightFunction:: +configure(const float& param) +{ + k = param; +} + +float HuberWeightFunction:: +value(const float& t) const +{ + const float t_abs = std::abs(t); + if(t_abs < k) + return 1.0f; + else + return k / t_abs; +} + +} // namespace robust_cost +} // namespace vk + + diff --git a/GPU_version/svo/src/sparse_img_align.cpp b/GPU_version/svo/src/sparse_img_align.cpp index 21432c6..13ae449 100644 --- a/GPU_version/svo/src/sparse_img_align.cpp +++ b/GPU_version/svo/src/sparse_img_align.cpp @@ -20,9 +20,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include namespace svo { @@ -54,12 +54,12 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) cur_frame_ = cur_frame; ref_patch_cache_ = cv::Mat(ref_frame_->fts_.size(), patch_area_, CV_32F); jacobian_cache_.resize(Eigen::NoChange, ref_patch_cache_.rows*patch_area_); - visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? - + //visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? SE3 T_cur_from_ref(cur_frame_->T_f_w_ * ref_frame_->T_f_w_.inverse()); for(level_=max_level_; level_>=min_level_; --level_) { + visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? mu_ = 0.1; jacobian_cache_.setZero(); have_ref_patch_cache_ = false; @@ -69,8 +69,6 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) } cur_frame_->T_f_w_ = T_cur_from_ref * ref_frame_->T_f_w_; - - return n_meas_/patch_area_; } diff --git a/GPU_version/svo/src/vision.cpp b/GPU_version/svo/src/vision.cpp new file mode 100644 index 0000000..b6d5f58 --- /dev/null +++ b/GPU_version/svo/src/vision.cpp @@ -0,0 +1,295 @@ +/* + * vision.cpp + * + * Created on: May 14, 2013 + * Author: cforster + */ + +#include + +#if __SSE2__ +# include +#elif __ARM_NEON__ +# include +#endif + +namespace vk { + +#ifdef __SSE2__ +void halfSampleSSE2(const unsigned char* in, unsigned char* out, int w, int h) +{ + const unsigned long long mask[2] = {0x00FF00FF00FF00FFull, 0x00FF00FF00FF00FFull}; + const unsigned char* nextRow = in + w; + __m128i m = _mm_loadu_si128((const __m128i*)mask); + int sw = w >> 4; + int sh = h >> 1; + for (int i=0; i> 1)*out.cols; + for( int x = in.cols; x > 0 ; x-=16, in_top += 16, in_bottom += 16, out_data += 8) + { + uint8x8x2_t top = vld2_u8( (const uint8_t *)in_top ); + uint8x8x2_t bottom = vld2_u8( (const uint8_t *)in_bottom ); + uint16x8_t sum = vaddl_u8( top.val[0], top.val[1] ); + sum = vaddw_u8( sum, bottom.val[0] ); + sum = vaddw_u8( sum, bottom.val[1] ); + uint8x8_t final_sum = vshrn_n_u16(sum, 2); + vst1_u8(out_data, final_sum); + } + } +} +#endif + + +void +halfSample(const cv::Mat& in, cv::Mat& out) +{ + assert( in.rows/2==out.rows && in.cols/2==out.cols); + assert( in.type()==CV_8U && out.type()==CV_8U); + +#ifdef __SSE2__ + if(aligned_mem::is_aligned16(in.data) && aligned_mem::is_aligned16(out.data) && ((in.cols % 16) == 0)) + { + halfSampleSSE2(in.data, out.data, in.cols, in.rows); + return; + } +#endif +#ifdef __ARM_NEON__ + if( (in.cols % 16) == 0 ) + { + halfSampleNEON(in, out); + return; + } +#endif + + const int stride = in.step.p[0]; + uint8_t* top = (uint8_t*) in.data; + uint8_t* bottom = top + stride; + uint8_t* end = top + stride*in.rows; + const int out_width = out.cols; + uint8_t* p = (uint8_t*) out.data; + while (bottom < end) + { + for (int j=0; j( (uint16_t (top[0]) + top[1] + bottom[0] + bottom[1])/4 ); + p++; + top += 2; + bottom += 2; + } + top += stride; + bottom += stride; + } +} + + +float +shiTomasiScore(const cv::Mat& img, int u, int v) +{ + assert(img.type() == CV_8UC1); + + float dXX = 0.0; + float dYY = 0.0; + float dXY = 0.0; + const int halfbox_size = 4; + const int box_size = 2*halfbox_size; + const int box_area = box_size*box_size; + const int x_min = u-halfbox_size; + const int x_max = u+halfbox_size; + const int y_min = v-halfbox_size; + const int y_max = v+halfbox_size; + + if(x_min < 1 || x_max >= img.cols-1 || y_min < 1 || y_max >= img.rows-1) + return 0.0; // patch is too close to the boundary + + const int stride = img.step.p[0]; + for( int y=y_min; y::depth, cn*2)); + + int x, y, delta = (int)alignSize((cols + 2)*cn, 16); + AutoBuffer _tempBuf(delta*2 + 64); + deriv_type *trow0 = alignPtr(_tempBuf + cn, 16), *trow1 = alignPtr(trow0 + delta, 16); + +#ifdef __SSE2__ + __m128i z = _mm_setzero_si128(), c3 = _mm_set1_epi16(3), c10 = _mm_set1_epi16(10); +#endif + + for( y = 0; y < rows; y++ ) + { + const uchar* srow0 = src.ptr(y > 0 ? y-1 : rows > 1 ? 1 : 0); + const uchar* srow1 = src.ptr(y); + const uchar* srow2 = src.ptr(y < rows-1 ? y+1 : rows > 1 ? rows-2 : 0); + deriv_type* drow = dst.ptr(y); + + // do vertical convolution + x = 0; +#ifdef __SSE2__ + for( ; x <= colsn - 8; x += 8 ) + { + __m128i s0 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(srow0 + x)), z); + __m128i s1 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(srow1 + x)), z); + __m128i s2 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(srow2 + x)), z); + __m128i t0 = _mm_add_epi16(_mm_mullo_epi16(_mm_add_epi16(s0, s2), c3), _mm_mullo_epi16(s1, c10)); + __m128i t1 = _mm_sub_epi16(s2, s0); + _mm_store_si128((__m128i*)(trow0 + x), t0); + _mm_store_si128((__m128i*)(trow1 + x), t1); + } +#endif + for( ; x < colsn; x++ ) + { + int t0 = (srow0[x] + srow2[x])*3 + srow1[x]*10; + int t1 = srow2[x] - srow0[x]; + trow0[x] = (deriv_type)t0; + trow1[x] = (deriv_type)t1; + } + + // make border + int x0 = (cols > 1 ? 1 : 0)*cn, x1 = (cols > 1 ? cols-2 : 0)*cn; + for( int k = 0; k < cn; k++ ) + { + trow0[-cn + k] = trow0[x0 + k]; trow0[colsn + k] = trow0[x1 + k]; + trow1[-cn + k] = trow1[x0 + k]; trow1[colsn + k] = trow1[x1 + k]; + } + + // do horizontal convolution, interleave the results and store them to dst + x = 0; +#ifdef __SSE2__ + for( ; x <= colsn - 8; x += 8 ) + { + __m128i s0 = _mm_loadu_si128((const __m128i*)(trow0 + x - cn)); + __m128i s1 = _mm_loadu_si128((const __m128i*)(trow0 + x + cn)); + __m128i s2 = _mm_loadu_si128((const __m128i*)(trow1 + x - cn)); + __m128i s3 = _mm_load_si128((const __m128i*)(trow1 + x)); + __m128i s4 = _mm_loadu_si128((const __m128i*)(trow1 + x + cn)); + + __m128i t0 = _mm_sub_epi16(s1, s0); + __m128i t1 = _mm_add_epi16(_mm_mullo_epi16(_mm_add_epi16(s2, s4), c3), _mm_mullo_epi16(s3, c10)); + __m128i t2 = _mm_unpacklo_epi16(t0, t1); + t0 = _mm_unpackhi_epi16(t0, t1); + // this can probably be replaced with aligned stores if we aligned dst properly. + _mm_storeu_si128((__m128i*)(drow + x*2), t2); + _mm_storeu_si128((__m128i*)(drow + x*2 + 8), t0); + } +#endif + for( ; x < colsn; x++ ) + { + deriv_type t0 = (deriv_type)(trow0[x+cn] - trow0[x-cn]); + deriv_type t1 = (deriv_type)((trow1[x+cn] + trow1[x-cn])*3 + trow1[x]*10); + drow[x*2] = t0; drow[x*2+1] = t1; + } + } + +// vector vec_mat; +// cv::split(dst, vec_mat); +// cv::namedWindow("deriv"); +// cv::imshow("deriv", vec_mat[0]); +// cv::namedWindow("derivy"); +// cv::imshow("derivy", vec_mat[1]); +// cv::waitKey(0); +} + +#ifdef __SSE2__ +void convertRawDepthImageSse_16u_to_32f(cv::Mat& depth_16u, cv::Mat& depth_32f, float scale) +{ + depth_32f.create(depth_16u.rows, depth_16u.cols, CV_32FC1); + + const unsigned short* input_ptr = depth_16u.ptr(); + float* output_ptr = depth_32f.ptr(); + + __m128 _scale = _mm_set1_ps(scale); + __m128 _zero = _mm_setzero_ps(); + __m128 _nan = _mm_set1_ps(std::numeric_limits::quiet_NaN()); + + for(int idx = 0; idx < depth_16u.size().area(); idx += 8, input_ptr += 8, output_ptr += 8) + { + __m128 _input, mask; + __m128i _inputi = _mm_load_si128((__m128i*) input_ptr); + + // load low shorts and convert to float + _input = _mm_cvtepi32_ps(_mm_unpacklo_epi16(_inputi, _mm_setzero_si128())); + + mask = _mm_cmpeq_ps(_input, _zero); + + // zero to nan + _input = _mm_or_ps(_input, _mm_and_ps(mask, _nan)); + // scale + _input = _mm_mul_ps(_input, _scale); + // save + _mm_store_ps(output_ptr + 0, _input); + + // load high shorts and convert to float + _input = _mm_cvtepi32_ps(_mm_unpackhi_epi16(_inputi, _mm_setzero_si128())); + + mask = _mm_cmpeq_ps(_input, _zero); + + // zero to nan + _input = _mm_or_ps(_input, _mm_and_ps(mask, _nan)); + // scale + _input = _mm_mul_ps(_input, _scale); + // save + _mm_store_ps(output_ptr + 4, _input); + } +} +#endif + +} + + diff --git a/GPU_version/vio/include/vio_gpu/camera_loader.h b/GPU_version/vio/include/vio_gpu/camera_loader.h new file mode 100644 index 0000000..e9d5a94 --- /dev/null +++ b/GPU_version/vio/include/vio_gpu/camera_loader.h @@ -0,0 +1,46 @@ +/* + * camera_loader.h + * + * Created on: Feb 11, 2014 + * Author: cforster + */ + +#ifndef VIKIT_CAMERA_LOADER_H_ +#define VIKIT_CAMERA_LOADER_H_ + +#include +#include +#include +#include + +namespace vk { +namespace camera_loader { + +/// Load from ROS Namespace +bool loadFromRosNs(const std::string& ns, vk::AbstractCamera*& cam) +{ + bool res = true; + std::string cam_model(getParam(ns+"/cam_model")); + if(cam_model == "ATAN") + { + cam = new vk::ATANCamera( + getParam(ns+"/cam_width"), + getParam(ns+"/cam_height"), + getParam(ns+"/cam_fx"), + getParam(ns+"/cam_fy"), + getParam(ns+"/cam_cx"), + getParam(ns+"/cam_cy"), + getParam(ns+"/cam_d0")); + } + else + { + cam = NULL; + res = false; + } + return res; +} + +} // namespace camera_loader +} // namespace vk + +#endif // VIKIT_CAMERA_LOADER_H_ diff --git a/GPU_version/vio/include/vio_gpu/output_helper.h b/GPU_version/vio/include/vio_gpu/output_helper.h new file mode 100644 index 0000000..a835def --- /dev/null +++ b/GPU_version/vio/include/vio_gpu/output_helper.h @@ -0,0 +1,97 @@ +/* + * output_helper.h + * + * Created on: Jan 20, 2013 + * Author: cforster + */ + +#ifndef VIKIT_OUTPUT_HELPER_H_ +#define VIKIT_OUTPUT_HELPER_H_ + +#include +#include +#include +#include +#include + +namespace vk { +namespace output_helper { + +using namespace std; +using namespace Eigen; + +void +publishTfTransform (const Sophus::SE3& T, const ros::Time& stamp, + const string& frame_id, const string& child_frame_id, + tf::TransformBroadcaster& br); + +void +publishPointMarker (ros::Publisher pub, + const Vector3d& pos, + const string& ns, + const ros::Time& timestamp, + int id, + int action, + double marker_scale, + const Vector3d& color, + ros::Duration lifetime = ros::Duration(0.0)); + +void +publishLineMarker (ros::Publisher pub, + const Vector3d& start, + const Vector3d& end, + const string& ns, + const ros::Time& timestamp, + int id, + int action, + double marker_scale, + const Vector3d& color, + ros::Duration lifetime = ros::Duration(0.0)); + +void +publishArrowMarker (ros::Publisher pub, + const Vector3d& pos, + const Vector3d& dir, + double scale, + const string& ns, + const ros::Time& timestamp, + int id, + int action, + double marker_scale, + const Vector3d& color); + +void +publishHexacopterMarker (ros::Publisher pub, + const string& frame_id, + const string& ns, + const ros::Time& timestamp, + int id, + int action, + double marker_scale, + const Vector3d& color); + +void +publishCameraMarker(ros::Publisher pub, + const string& frame_id, + const string& ns, + const ros::Time& timestamp, + int id, + double marker_scale, + const Vector3d& color); +void +publishFrameMarker (ros::Publisher pub, + const Matrix3d& rot, + const Vector3d& pos, + const string& ns, + const ros::Time& timestamp, + int id, + int action, + double marker_scale, + ros::Duration lifetime = ros::Duration(0.0)); + + +} // namespace output_helper +} // namespace vk + + +#endif /* VIKIT_OUTPUT_HELPER_H_ */ diff --git a/GPU_version/vio/include/vio_gpu/params_helper.h b/GPU_version/vio/include/vio_gpu/params_helper.h new file mode 100644 index 0000000..1c8967f --- /dev/null +++ b/GPU_version/vio/include/vio_gpu/params_helper.h @@ -0,0 +1,54 @@ +/* + * ros_params_helper.h + * + * Created on: Feb 22, 2013 + * Author: cforster + * + * from libpointmatcher_ros + */ + +#ifndef ROS_PARAMS_HELPER_H_ +#define ROS_PARAMS_HELPER_H_ + +#include +#include + +namespace vk { + +inline +bool hasParam(const std::string& name) +{ + return ros::param::has(name); +} + +template +T getParam(const std::string& name, const T& defaultValue) +{ + T v; + if(ros::param::get(name, v)) + { + ROS_INFO_STREAM("Found parameter: " << name << ", value: " << v); + return v; + } + else + ROS_WARN_STREAM("Cannot find value for parameter: " << name << ", assigning default: " << defaultValue); + return defaultValue; +} + +template +T getParam(const std::string& name) +{ + T v; + if(ros::param::get(name, v)) + { + ROS_INFO_STREAM("Found parameter: " << name << ", value: " << v); + return v; + } + else + ROS_ERROR_STREAM("Cannot find value for parameter: " << name); + return T(); +} + +} // namespace vk + +#endif // ROS_PARAMS_HELPER_H_ diff --git a/GPU_version/vio/launch/Px30.launch b/GPU_version/vio/launch/Px30.launch index c02d6a2..67019b8 100644 --- a/GPU_version/vio/launch/Px30.launch +++ b/GPU_version/vio/launch/Px30.launch @@ -9,10 +9,10 @@ - - - - + + + + diff --git a/GPU_version/vio/param/camera_atan.yaml b/GPU_version/vio/param/camera_atan.yaml deleted file mode 100644 index e3c625c..0000000 --- a/GPU_version/vio/param/camera_atan.yaml +++ /dev/null @@ -1,8 +0,0 @@ -cam_model: ATAN -cam_width: 752 -cam_height: 480 -cam_fx: 0.509326 -cam_fy: 0.796651 -cam_cx: 0.45905 -cam_cy: 0.510056 -cam_d0: 0.9320 \ No newline at end of file diff --git a/GPU_version/vio/param/camera_pinhole.yaml b/GPU_version/vio/param/camera_pinhole.yaml deleted file mode 100644 index 506a856..0000000 --- a/GPU_version/vio/param/camera_pinhole.yaml +++ /dev/null @@ -1,11 +0,0 @@ -cam_model: Pinhole -cam_width: 640 -cam_height: 480 -cam_fx: 789.860721 -cam_fy: 790.097440 -cam_cx: 305.323524 -cam_cy: 260.464072 -cam_d0: 0.027470 -cam_d1: -0.051518 -cam_d2: 0.004375 -cam_d3: -0.004028 \ No newline at end of file diff --git a/GPU_version/vio/param/unity.yaml b/GPU_version/vio/param/unity.yaml deleted file mode 100644 index 023f378..0000000 --- a/GPU_version/vio/param/unity.yaml +++ /dev/null @@ -1,8 +0,0 @@ -cam_model: ATAN -cam_width: 1024 -cam_height: 720 -cam_fx: 1.98248 -cam_fy: 2.68212 -cam_cx: 0.502524 -cam_cy: 0.497744 -cam_d0: -0.000499999 \ No newline at end of file diff --git a/GPU_version/vio/param/vo_accurate.yaml b/GPU_version/vio/param/vo_accurate.yaml deleted file mode 100644 index 8446875..0000000 --- a/GPU_version/vio/param/vo_accurate.yaml +++ /dev/null @@ -1,4 +0,0 @@ -grid_size: 20 -max_n_kfs: 50 -loba_num_iter: 10 -max_fts: 200 \ No newline at end of file diff --git a/GPU_version/vio/param/vo_fast.yaml b/GPU_version/vio/param/vo_fast.yaml index e33b18a..a5f9cec 100644 --- a/GPU_version/vio/param/vo_fast.yaml +++ b/GPU_version/vio/param/vo_fast.yaml @@ -4,10 +4,19 @@ svo: loba_num_iter: 0 #Number of iterations in the local bundle adjustment. quality_min_fts: 10 #If the number of tracked features drops below this threshold. Tracking quality is bad. quality_max_drop_fts: 60 #If within one frame, this amount of features are dropped. Tracking quality is bad. - ACC_noise: 0.00001 #acc white noise in continuous - GYO_noise: 0.00001 #gyro white noise in continuous + init_min_tracked: 100 + init_min_disparity: 25 + structureoptim_max_pts: 50 + kfselect_mindist: 0.12 + poseoptim_thresh: 4.0 + ACC_noise: 0.0001 #acc white noise in continuous + GYO_noise: 0.0001 #gyro white noise in continuous IUC: 0.1 #integration uncertainty continuous ABC: 0.1 #acc bias in continuous GBC: 0.1 #gyro bias in continuous EBP: 0.1 #error in the bias used for preintegration NRP: 0.0000001 #noise used for projection in preintegration + gravity: 9.65 + Acceleration_offset_x: -0.05 + Acceleration_offset_y: -0.04 + Gyroscope_offset_z: 0.001 diff --git a/GPU_version/vio/src/output_helper.cpp b/GPU_version/vio/src/output_helper.cpp new file mode 100644 index 0000000..63b1a78 --- /dev/null +++ b/GPU_version/vio/src/output_helper.cpp @@ -0,0 +1,410 @@ +/* + * output_helper.cpp + * + * Created on: Jan 20, 2013 + * Author: chrigi + */ + +#include +#include + +namespace vk { +namespace output_helper { + +void +publishTfTransform(const Sophus::SE3& T, const ros::Time& stamp, + const string& frame_id, const string& child_frame_id, + tf::TransformBroadcaster& br) +{ + tf::Transform transform_msg; + Eigen::Quaterniond q(T.rotation_matrix()); + transform_msg.setOrigin(tf::Vector3(T.translation().x(), T.translation().y(), T.translation().z())); + tf::Quaternion tf_q; tf_q.setX(q.x()); tf_q.setY(q.y()); tf_q.setZ(q.z()); tf_q.setW(q.w()); + transform_msg.setRotation(tf_q); + br.sendTransform(tf::StampedTransform(transform_msg, stamp, frame_id, child_frame_id)); +} + +void +publishPointMarker(ros::Publisher pub, + const Vector3d& pos, + const string& ns, + const ros::Time& timestamp, + int id, + int action, + double marker_scale, + const Vector3d& color, + ros::Duration lifetime) +{ + visualization_msgs::Marker msg; + msg.header.frame_id = "/world"; + msg.header.stamp = timestamp; + msg.ns = ns; + msg.id = id; + msg.type = visualization_msgs::Marker::CUBE; + msg.action = action; // 0 = add/modify + msg.scale.x = marker_scale; + msg.scale.y = marker_scale; + msg.scale.z = marker_scale; + msg.color.a = 1.0; + msg.color.r = color[0]; + msg.color.g = color[1]; + msg.color.b = color[2]; + msg.lifetime = lifetime; + msg.pose.position.x = pos[0]; + msg.pose.position.y = pos[1]; + msg.pose.position.z = pos[2]; + pub.publish(msg); +} + +void +publishLineMarker(ros::Publisher pub, + const Vector3d& start, + const Vector3d& end, + const string& ns, + const ros::Time& timestamp, + int id, + int action, + double marker_scale, + const Vector3d& color, + ros::Duration lifetime) +{ + visualization_msgs::Marker msg; + msg.header.frame_id = "/world"; + msg.header.stamp = timestamp; + msg.ns = ns; + msg.id = id; + msg.type = visualization_msgs::Marker::LINE_STRIP; + msg.action = action; // 0 = add/modify + msg.scale.x = marker_scale; + msg.color.a = 1.0; + msg.color.r = color[0]; + msg.color.g = color[1]; + msg.color.b = color[2]; + msg.points.resize(2); + msg.lifetime = lifetime; + msg.points[0].x = start[0]; + msg.points[0].y = start[1]; + msg.points[0].z = start[2]; + msg.points[1].x = end[0]; + msg.points[1].y = end[1]; + msg.points[1].z = end[2]; + pub.publish(msg); +} + + +void +publishArrowMarker(ros::Publisher pub, + const Vector3d& pos, + const Vector3d& dir, + double scale, + const string& ns, + const ros::Time& timestamp, + int id, + int action, + double marker_scale, + const Vector3d& color) +{ + visualization_msgs::Marker msg; + msg.header.frame_id = "/world"; + msg.header.stamp = timestamp; + msg.ns = ns; + msg.id = id; + msg.type = visualization_msgs::Marker::ARROW; + msg.action = action; // 0 = add/modify + msg.scale.x = marker_scale; + msg.scale.y = marker_scale*0.35; + msg.scale.z = 0.0; + msg.color.a = 1.0; + msg.color.r = color[0]; + msg.color.g = color[1]; + msg.color.b = color[2]; + msg.points.resize(2); + msg.points[0].x = pos[0]; + msg.points[0].y = pos[1]; + msg.points[0].z = pos[2]; + msg.points[1].x = pos[0] + scale*dir[0]; + msg.points[1].y = pos[1] + scale*dir[1]; + msg.points[1].z = pos[2] + scale*dir[2]; + pub.publish(msg); +} + +void +publishHexacopterMarker(ros::Publisher pub, + const string& frame_id, + const string& ns, + const ros::Time& timestamp, + int id, + int action, + double marker_scale, + const Vector3d& color) +{ + /* + * Function by Markus Achtelik from libsfly_viz. + * Thank you. + */ + const double sqrt2_2 = sqrt(2) / 2; + + visualization_msgs::Marker marker; + + // the marker will be displayed in frame_id + marker.header.frame_id = frame_id; + marker.header.stamp = timestamp; + marker.ns = ns; + marker.action = 0; + marker.id = id; + + // make rotors + marker.type = visualization_msgs::Marker::CYLINDER; + marker.scale.x = 0.2*marker_scale; + marker.scale.y = 0.2*marker_scale; + marker.scale.z = 0.01*marker_scale; + marker.color.r = 0.4; + marker.color.g = 0.4; + marker.color.b = 0.4; + marker.color.a = 0.8; + marker.pose.position.z = 0; + + // front left/right + marker.pose.position.x = 0.19*marker_scale; + marker.pose.position.y = 0.11*marker_scale; + marker.id--; + pub.publish(marker); + + marker.pose.position.x = 0.19*marker_scale; + marker.pose.position.y = -0.11*marker_scale; + marker.id--; + pub.publish(marker); + + // left/right + marker.pose.position.x = 0; + marker.pose.position.y = 0.22*marker_scale; + marker.id--; + pub.publish(marker); + + marker.pose.position.x = 0; + marker.pose.position.y = -0.22*marker_scale; + marker.id--; + pub.publish(marker); + + // back left/right + marker.pose.position.x = -0.19*marker_scale; + marker.pose.position.y = 0.11*marker_scale; + marker.id--; + pub.publish(marker); + + marker.pose.position.x = -0.19*marker_scale; + marker.pose.position.y = -0.11*marker_scale; + marker.id--; + pub.publish(marker); + + // make arms + marker.type = visualization_msgs::Marker::CUBE; + marker.scale.x = 0.44*marker_scale; + marker.scale.y = 0.02*marker_scale; + marker.scale.z = 0.01*marker_scale; + marker.color.r = color[0]; + marker.color.g = color[1]; + marker.color.b = color[2]; + marker.color.a = 1; + + marker.pose.position.x = 0; + marker.pose.position.y = 0; + marker.pose.position.z = -0.015*marker_scale; + marker.pose.orientation.x = 0; + marker.pose.orientation.y = 0; + + marker.pose.orientation.w = sqrt2_2; + marker.pose.orientation.z = sqrt2_2; + marker.id--; + pub.publish(marker); + + // 30 deg rotation 0.9659 0 0 0.2588 + marker.pose.orientation.w = 0.9659; + marker.pose.orientation.z = 0.2588; + marker.id--; + pub.publish(marker); + + marker.pose.orientation.w = 0.9659; + marker.pose.orientation.z = -0.2588; + marker.id--; + pub.publish(marker); +} + +void +publishCameraMarker(ros::Publisher pub, + const string& frame_id, + const string& ns, + const ros::Time& timestamp, + int id, + double marker_scale, + const Vector3d& color) +{ + /* + * draw a pyramid as the camera marker + */ + const double sqrt2_2 = sqrt(2) / 2; + + visualization_msgs::Marker marker; + + // the marker will be displayed in frame_id + marker.header.frame_id = frame_id; + marker.header.stamp = timestamp; + marker.ns = ns; + marker.action = 0; + marker.id = id; + + // make rectangles as frame + double r_w = 1.0; + double z_plane = (r_w / 2.0)*marker_scale; + marker.pose.position.x = 0; + marker.pose.position.y = (r_w / 4.0) *marker_scale; + marker.pose.position.z = z_plane; + + marker.type = visualization_msgs::Marker::CUBE; + marker.scale.x = r_w*marker_scale; + marker.scale.y = 0.04*marker_scale; + marker.scale.z = 0.04*marker_scale; + marker.color.r = color[0]; + marker.color.g = color[1]; + marker.color.b = color[2]; + marker.color.a = 1; + + marker.pose.orientation.x = 0; + marker.pose.orientation.y = 0; + marker.pose.orientation.z = 0; + marker.pose.orientation.w = 1; + marker.id--; + pub.publish(marker); + marker.pose.position.y = -(r_w/ 4.0)*marker_scale; + marker.id--; + pub.publish(marker); + + marker.scale.x = (r_w/2.0)*marker_scale; + marker.pose.position.x = (r_w / 2.0) *marker_scale; + marker.pose.position.y = 0; + marker.pose.orientation.w = sqrt2_2; + marker.pose.orientation.z = sqrt2_2; + marker.id--; + pub.publish(marker); + marker.pose.position.x = -(r_w / 2.0) *marker_scale; + marker.id--; + pub.publish(marker); + + // make pyramid edges + marker.scale.x = (3.0*r_w/4.0)*marker_scale; + marker.pose.position.z = 0.5*z_plane; + + marker.pose.position.x = (r_w / 4.0) *marker_scale; + marker.pose.position.y = (r_w / 8.0) *marker_scale; + // 0.08198092, -0.34727674, 0.21462883, 0.9091823 + marker.pose.orientation.x = 0.08198092; + marker.pose.orientation.y = -0.34727674; + marker.pose.orientation.z = 0.21462883; + marker.pose.orientation.w = 0.9091823; + marker.id--; + pub.publish(marker); + + marker.pose.position.x = -(r_w / 4.0) *marker_scale; + marker.pose.position.y = (r_w / 8.0) *marker_scale; + // -0.27395078, -0.22863284, 0.9091823 , 0.21462883 + marker.pose.orientation.x = 0.08198092; + marker.pose.orientation.y = 0.34727674; + marker.pose.orientation.z = -0.21462883; + marker.pose.orientation.w = 0.9091823; + marker.id--; + pub.publish(marker); + + marker.pose.position.x = -(r_w / 4.0) *marker_scale; + marker.pose.position.y = -(r_w / 8.0) *marker_scale; + // -0.08198092, 0.34727674, 0.21462883, 0.9091823 + marker.pose.orientation.x = -0.08198092; + marker.pose.orientation.y = 0.34727674; + marker.pose.orientation.z = 0.21462883; + marker.pose.orientation.w = 0.9091823; + marker.id--; + pub.publish(marker); + + marker.pose.position.x = (r_w / 4.0) *marker_scale; + marker.pose.position.y = -(r_w / 8.0) *marker_scale; + // -0.08198092, -0.34727674, -0.21462883, 0.9091823 + marker.pose.orientation.x = -0.08198092; + marker.pose.orientation.y = -0.34727674; + marker.pose.orientation.z = -0.21462883; + marker.pose.orientation.w = 0.9091823; + marker.id--; + pub.publish(marker); +} + +void publishFrameMarker(ros::Publisher pub, + const Matrix3d& rot, + const Vector3d& pos, + const string& ns, + const ros::Time& timestamp, + int id, + int action, + double marker_scale, + ros::Duration lifetime) +{ + visualization_msgs::Marker marker; + marker.header.frame_id = "/world"; + marker.header.stamp = timestamp; + marker.ns = ns; + marker.id = id++; + marker.type = visualization_msgs::Marker::ARROW; + marker.action = action; // 0 = add/modify + marker.points.reserve(2); + geometry_msgs::Point point; + point.x = static_cast(pos.x()); + point.y = static_cast(pos.y()); + point.z = static_cast(pos.z()); + marker.points.push_back(point); + point.x = static_cast(pos.x() + marker_scale*rot(0, 2)); // Draw arrow in z-direction + point.y = static_cast(pos.y() + marker_scale*rot(1, 2)); // Draw arrow in z-direction + point.z = static_cast(pos.z() + marker_scale*rot(2, 2)); // Draw arrow in z-direction + marker.points.push_back(point); + marker.scale.x = 0.5*marker_scale; + marker.scale.y = 0.5*marker_scale; + marker.color.a = 1.0; + marker.color.r = 0.0; + marker.color.g = 0.0; + marker.color.b = 1.0; + marker.lifetime = lifetime; + pub.publish(marker); + + marker.id = id++; + marker.points.clear(); + point.x = static_cast(pos.x()); + point.y = static_cast(pos.y()); + point.z = static_cast(pos.z()); + marker.points.push_back(point); + point.x = static_cast(pos.x() + marker_scale*rot(0, 0)); // Draw arrow in x-direction + point.y = static_cast(pos.y() + marker_scale*rot(1, 0)); // Draw arrow in x-direction + point.z = static_cast(pos.z() + marker_scale*rot(2, 0)); // Draw arrow in x-direction + marker.points.push_back(point); + marker.color.r = 1.0; + marker.color.g = 0.0; + marker.color.b = 0.0; + marker.lifetime = lifetime; + pub.publish(marker); + + marker.id = id++; + marker.points.clear(); + point.x = static_cast(pos.x()); + point.y = static_cast(pos.y()); + point.z = static_cast(pos.z()); + marker.points.push_back(point); + point.x = static_cast(pos.x() + marker_scale*rot(0, 1)); // Draw arrow in y-direction + point.y = static_cast(pos.y() + marker_scale*rot(1, 1)); // Draw arrow in y-direction + point.z = static_cast(pos.z() + marker_scale*rot(2, 1)); // Draw arrow in y-direction + marker.points.push_back(point); + marker.color.r = 0.0; + marker.color.g = 1.0; + marker.color.b = 0.0; + marker.lifetime = lifetime; + pub.publish(marker); +} + +} // namespace output_helper +} // namespace vk + + diff --git a/GPU_version/vio/src/visualizer.cpp b/GPU_version/vio/src/visualizer.cpp index d2327f4..90ad7ab 100644 --- a/GPU_version/vio/src/visualizer.cpp +++ b/GPU_version/vio/src/visualizer.cpp @@ -21,8 +21,8 @@ #include #include #include -#include -#include +#include +#include #include namespace svo { @@ -57,16 +57,18 @@ void Visualizer::publishMinimal( { vio_gpu::Info msg_info; msg_info.header = header_msg; - msg_info.processing_time = slam.lastProcessingTime(); + //msg_info.processing_time = slam.lastProcessingTime(); msg_info.keyframes.reserve(slam.map().keyframes_.size()); for(list::const_iterator it=slam.map().keyframes_.begin(); it!=slam.map().keyframes_.end(); ++it) msg_info.keyframes.push_back((*it)->id_); msg_info.stage = static_cast(slam.stage()); msg_info.tracking_quality = static_cast(slam.trackingQuality()); + /* if(frame != NULL) msg_info.num_matches = slam.lastNumObservations(); else msg_info.num_matches = 0; + */ pub_info_.publish(msg_info); } if(pub_pose_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) diff --git a/GPU_version/vio/src/vo_node.cpp b/GPU_version/vio/src/vo_node.cpp index c11c6a0..b167282 100644 --- a/GPU_version/vio/src/vo_node.cpp +++ b/GPU_version/vio/src/vo_node.cpp @@ -17,15 +17,15 @@ #include #include #include -#include +#include #include #include #include #include #include #include -#include -#include +#include +#include #include From faf00a6aadd923b9c6f73111c03f2ce9768553c5 Mon Sep 17 00:00:00 2001 From: gfuse Date: Sat, 29 May 2021 16:53:00 +0200 Subject: [PATCH 200/215] track the trajectory with noise --- GPU_version/svo/include/gpu_svo/frame.h | 21 +++-- GPU_version/svo/include/gpu_svo/global.h | 73 +++++---------- .../svo/include/gpu_svo/imu_integration.h | 1 + .../svo/include/gpu_svo/svoVisionFactor.h | 37 +++----- GPU_version/svo/src/depth_filter.cpp | 4 +- GPU_version/svo/src/feature_alignment.cpp | 78 +++++++++------- GPU_version/svo/src/frame.cpp | 7 +- GPU_version/svo/src/frame_handler_base.cpp | 2 + GPU_version/svo/src/frame_handler_mono.cpp | 39 +++----- GPU_version/svo/src/imu_integration.cpp | 89 ++++++++----------- GPU_version/svo/src/initialization.cpp | 9 +- GPU_version/svo/src/map.cpp | 8 +- GPU_version/svo/src/matcher.cpp | 4 +- GPU_version/svo/src/point.cpp | 8 +- GPU_version/svo/src/pose_optimizer.cpp | 19 ++-- GPU_version/svo/src/sparse_img_align.cpp | 6 +- GPU_version/vio/launch/Px30.launch | 2 +- GPU_version/vio/param/vo_fast.yaml | 4 +- GPU_version/vio/src/visualizer.cpp | 35 ++------ GPU_version/vio/src/vo_node.cpp | 2 - 20 files changed, 201 insertions(+), 247 deletions(-) diff --git a/GPU_version/svo/include/gpu_svo/frame.h b/GPU_version/svo/include/gpu_svo/frame.h index 3a0fef6..4580be2 100644 --- a/GPU_version/svo/include/gpu_svo/frame.h +++ b/GPU_version/svo/include/gpu_svo/frame.h @@ -36,6 +36,7 @@ struct Feature; typedef list Features; typedef vector ImgPyr; + /// A frame saves the image, the associated features and the estimated pose. class Frame : boost::noncopyable { @@ -46,7 +47,7 @@ public: int id_; //!< Unique id of the frame. double timestamp_; //!< Timestamp of when the image was recorded. vk::AbstractCamera* cam_; //!< Camera model. - Sophus::SE3 T_f_w_; //!< Transform (f)rame from (w)orld. + SE2_5 T_f_w_; //!< Transform (f)rame from (w)orld. Matrix Cov_; //!< Covariance. ImgPyr img_pyr_; //!< Image Pyramid. Features fts_; //!< List of features in the image. @@ -91,7 +92,11 @@ public: inline bool isKeyframe() const { return is_keyframe_; } /// Transforms point coordinates in world-frame (w) to camera pixel coordinates (c). - inline Vector2d w2c(const Vector3d& xyz_w) const { return cam_->world2cam( T_f_w_ * xyz_w ); } + inline Vector2d w2c(const Vector3d& xyz_w) const { + return cam_->world2cam( Vector3d(xyz_w.x()*T_f_w_.cos_theta_+xyz_w.z()*T_f_w_.sin_theta_+T_f_w_.X_, + xyz_w.y(), + -xyz_w.x()*T_f_w_.sin_theta_+xyz_w.z()*T_f_w_.cos_theta_+T_f_w_.Z_) ); + } /// Transforms point coordinates in world-frame (w) to camera pixel coordinates (c). inline Vector2d w2px(const Vector3d& xyz_w) const { return cam_->world2cam( xyz_w ); } @@ -102,16 +107,22 @@ public: inline Vector3d c2f(const double x, const double y) const { return cam_->cam2world(x, y); } /// Transforms point coordinates in world-frame (w) to camera-frams (f). - inline Vector3d w2f(const Vector3d& xyz_w) const { return T_f_w_ * xyz_w; } + inline Vector3d w2f(const Vector3d& xyz_w) const { + return Vector3d(xyz_w.x()*T_f_w_.cos_theta_+xyz_w.z()*T_f_w_.sin_theta_+T_f_w_.X_, + xyz_w.y(), + -xyz_w.x()*T_f_w_.sin_theta_+xyz_w.z()*T_f_w_.cos_theta_+T_f_w_.Z_); + } /// Transforms point from frame unit sphere (f) frame to world coordinate frame (w). - inline Vector3d f2w(const Vector3d& f) const { return T_f_w_.inverse() * f; } + inline Vector3d f2w(const Vector3d& f) const { + return T_f_w_.T->inverse() * f; + } /// Projects Point from unit sphere (f) in camera pixels (c). inline Vector2d f2c(const Vector3d& f) const { return cam_->world2cam( f ); } /// Return the pose of the frame in the (w)orld coordinate frame. - inline Vector3d pos() const { return T_f_w_.inverse().translation(); } + inline Vector3d pos() const { return T_f_w_.T->inverse().translation(); } /// Frame jacobian for projection of 3D point in (f)rame coordinate to diff --git a/GPU_version/svo/include/gpu_svo/global.h b/GPU_version/svo/include/gpu_svo/global.h index f10358d..f5292c4 100644 --- a/GPU_version/svo/include/gpu_svo/global.h +++ b/GPU_version/svo/include/gpu_svo/global.h @@ -27,7 +27,6 @@ #include #include #include -//#include #include #include #ifndef RPG_SVO_VIKIT_IS_VECTOR_SPECIALIZED //Guard for rpg_vikit @@ -35,39 +34,13 @@ EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector3d) EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector2d) #endif +#include +#define SVO_DEBUG_STREAM(x) ROS_DEBUG_STREAM(x) +#define SVO_INFO_STREAM(x) ROS_INFO_STREAM(x) +#define SVO_WARN_STREAM(x) ROS_WARN_STREAM(x) +#define SVO_WARN_STREAM_THROTTLE(rate, x) ROS_WARN_STREAM_THROTTLE(rate, x) +#define SVO_ERROR_STREAM(x) ROS_ERROR_STREAM(x) -#ifdef SVO_USE_ROS - #include - #define SVO_DEBUG_STREAM(x) ROS_DEBUG_STREAM(x) - #define SVO_INFO_STREAM(x) ROS_INFO_STREAM(x) - #define SVO_WARN_STREAM(x) ROS_WARN_STREAM(x) - #define SVO_WARN_STREAM_THROTTLE(rate, x) ROS_WARN_STREAM_THROTTLE(rate, x) - #define SVO_ERROR_STREAM(x) ROS_ERROR_STREAM(x) -#else - #define SVO_INFO_STREAM(x) std::cerr<<"\033[0;0m[INFO] "< // Adapted from rosconsole. Copyright (c) 2008, Willow Garage, Inc. - #define SVO_WARN_STREAM_THROTTLE(rate, x) \ - do { \ - static double __log_stream_throttle__last_hit__ = 0.0; \ - std::chrono::time_point __log_stream_throttle__now__ = \ - std::chrono::system_clock::now(); \ - if (__log_stream_throttle__last_hit__ + rate <= \ - std::chrono::duration_cast( \ - __log_stream_throttle__now__.time_since_epoch()).count()) { \ - __log_stream_throttle__last_hit__ = \ - std::chrono::duration_cast( \ - __log_stream_throttle__now__.time_since_epoch()).count(); \ - SVO_WARN_STREAM(x); \ - } \ - } while(0) -#endif namespace svo { @@ -76,25 +49,21 @@ namespace svo const double EPS = 0.0000000001; const double PI = 3.14159265; - -#ifdef SVO_TRACE - /* - extern vk::PerformanceMonitor* g_permon; - #define SVO_LOG(value) g_permon->log(std::string((#value)),(value)) - #define SVO_LOG2(value1, value2) SVO_LOG(value1); SVO_LOG(value2) - #define SVO_LOG3(value1, value2, value3) SVO_LOG2(value1, value2); SVO_LOG(value3) - #define SVO_LOG4(value1, value2, value3, value4) SVO_LOG2(value1, value2); SVO_LOG2(value3, value4) - #define SVO_START_TIMER(name) g_permon->startTimer((name)) - #define SVO_STOP_TIMER(name) g_permon->stopTimer((name)) - */ -#else - #define SVO_LOG(v) - #define SVO_LOG2(v1, v2) - #define SVO_LOG3(v1, v2, v3) - #define SVO_LOG4(v1, v2, v3, v4) - #define SVO_START_TIMER(name) - #define SVO_STOP_TIMER(name) -#endif + class SE2_5{ + public: + double X_,Z_,tetha_,cos_theta_,sin_theta_; + SE3* T; + SE2_5(double x,double z,double tetha):X_(x),Z_(z),tetha_(tetha){ + cos_theta_=cos(tetha_); + sin_theta_=sin(tetha_); + Eigen::Matrix R; + R< FramePtr; diff --git a/GPU_version/svo/include/gpu_svo/imu_integration.h b/GPU_version/svo/include/gpu_svo/imu_integration.h index 738608f..2ff4a89 100644 --- a/GPU_version/svo/include/gpu_svo/imu_integration.h +++ b/GPU_version/svo/include/gpu_svo/imu_integration.h @@ -32,6 +32,7 @@ public: bool init(boost::shared_ptr&); Sophus::SE3 preintegrate_predict(); private: + FILE* logtime; std::shared_ptr statePtr; std::shared_ptr imu_biasPtr; std::shared_ptr valuesPtr; diff --git a/GPU_version/svo/include/gpu_svo/svoVisionFactor.h b/GPU_version/svo/include/gpu_svo/svoVisionFactor.h index 417357c..c81bdd5 100644 --- a/GPU_version/svo/include/gpu_svo/svoVisionFactor.h +++ b/GPU_version/svo/include/gpu_svo/svoVisionFactor.h @@ -16,12 +16,11 @@ namespace svo { - class VisionFactor: public gtsam::NoiseModelFactor2 { + class VisionFactor: public gtsam::NoiseModelFactor1 { private: // measurement information - gtsam::Point3 feature; ///(H, poseKey,landKey), feature(feature),level(level){} + gtsam::Key poseKey) : + gtsam::NoiseModelFactor1(H, poseKey), pose(pose){} virtual ~VisionFactor(){} /// error function /// @param p the Estimated pose in Pose3 /// @param H the optional Jacobian matrix, which use boost optional and has default null pointer - gtsam::Vector evaluateError(const gtsam::Pose3& p,const gtsam::Point3& l, - boost::optional H1 = boost::none,boost::optional H2 = boost::none) const { + gtsam::Vector evaluateError(const gtsam::Pose3& p + ,boost::optional H1 = boost::none) const { // note that use boost optional like a pointer // only calculate jacobian matrix when non-null pointer exists - gtsam::Matrix26 J1; - gtsam::Matrix23 J2; - gtsam::Point3 point(p*l); - svo::Frame::jacobian_xyz2uv(point, J1); - svo::Frame::jacobian_l2uv(point, J2); - Vector2d e=(vk::project2d(feature) - vk::project2d(point))*1.0 / (1< E_r=0.5*(p.rotation().matrix().transpose()*pose.rotation().matrix()-pose.rotation().matrix().transpose()*p.rotation().matrix()); + Vector3d e_t=p.translation()-pose.translation(); + if(H1)(*H1) = (gtsam::Matrix(3,6)<< 1,0,0,0,0,0, + 0,0,1,0,0,0, + 0,0,0,0,1,0).finished(); + return (gtsam::Matrix(3,1)<ftr->frame->T_f_w_ * frame->T_f_w_.inverse(); + SE3 T_ref_cur = *it->ftr->frame->T_f_w_.T * frame->T_f_w_.T->inverse(); const Vector3d xyz_f(T_ref_cur.inverse()*(1.0/it->mu * it->ftr->f) ); if(xyz_f.z() < 0.0) { ++it; // behind the camera @@ -261,7 +261,7 @@ void DepthFilter::updateSeeds(FramePtr frame) if(sqrt(it->sigma2) < it->z_range/options_.seed_convergence_sigma2_thresh) { assert(it->ftr->point == NULL); // TODO this should not happen anymore - Vector3d xyz_world(it->ftr->frame->T_f_w_.inverse() * (it->ftr->f * (1.0/it->mu))); + Vector3d xyz_world(it->ftr->frame->T_f_w_.T->inverse() * (it->ftr->f * (1.0/it->mu))); Point* point = new Point(xyz_world, it->ftr); it->ftr->point = point; /* FIXME it is not threadsafe to add a feature to the frame here. diff --git a/GPU_version/svo/src/feature_alignment.cpp b/GPU_version/svo/src/feature_alignment.cpp index 496ce33..a68f121 100644 --- a/GPU_version/svo/src/feature_alignment.cpp +++ b/GPU_version/svo/src/feature_alignment.cpp @@ -25,7 +25,7 @@ namespace svo { namespace feature_alignment { -#define SUBPIX_VERBOSE 1 +#define SUBPIX_VERBOSE 0 bool align1D( const cv::Mat& cur_img, @@ -77,11 +77,16 @@ bool align1D( { int u_r = floor(u); int v_r = floor(v); - if(u_r < halfpatch_size_ || v_r < halfpatch_size_ || u_r >= cur_img.cols-halfpatch_size_ || v_r >= cur_img.rows-halfpatch_size_) - break; + if(u_r < halfpatch_size_ || v_r < halfpatch_size_ || u_r >= cur_img.cols-halfpatch_size_ || v_r >= cur_img.rows-halfpatch_size_){ + std::cout<<"not in bach size\n"; + break; + } - if(isnan(u) || isnan(v)) // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check - return false; + if(isnan(u) || isnan(v)){ + // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check + std::cout<<"H singularity\n"; + return false; + } // compute interpolation weights float subpix_x = u-u_r; @@ -193,9 +198,12 @@ bool align2D( // Compute pixel location in new image: float u = cur_px_estimate.x(); float v = cur_px_estimate.y(); + double error=1000.0; + double scale=1.0; + bool sign=true;// + // termination condition - const float min_update_squared = 0.03*0.03; + const float min_update_squared = 0.05; const int cur_step = cur_img.step.p[0]; // float chi2 = 0; Vector3f update; update.setZero(); @@ -203,11 +211,14 @@ bool align2D( { int u_r = floor(u); int v_r = floor(v); - if(u_r < halfpatch_size_ || v_r < halfpatch_size_ || u_r >= cur_img.cols-halfpatch_size_ || v_r >= cur_img.rows-halfpatch_size_) - break; + if(u_r < halfpatch_size_ || v_r < halfpatch_size_ || u_r >= cur_img.cols-halfpatch_size_ || v_r >= cur_img.rows-halfpatch_size_){ + break; + } - if(isnan(u) || isnan(v)) // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check + if(isnan(u) || isnan(v)) { + // TODO very rarely this can happen, maybe H is singular? should not be at corner.. check return false; + } // compute interpolation weights float subpix_x = u-u_r; @@ -233,36 +244,39 @@ bool align2D( Jres[0] -= res*(*it_ref_dx); Jres[1] -= res*(*it_ref_dy); Jres[2] -= res; -// new_chi2 += res*res; } } - - -/* - if(iter > 0 && new_chi2 > chi2) - { -#if SUBPIX_VERBOSE - cout << "error increased." << endl; -#endif - u -= update[0]; - v -= update[1]; - break; - } - chi2 = new_chi2; -*/ update = Hinv * Jres; - u += update[0]; - v += update[1]; - mean_diff += update[2]; + double error_t=update[0]*update[0]+update[1]*update[1]; + double dt=error_t-error; + if(!signbit(dt))if(sign){ + sign=false; + scale*=0.5; + }else{ + sign=true; + scale*=0.5; + } + if(sign){ + u += scale*update[0]; + v += scale*update[1]; + mean_diff += scale*update[2]; + }else{ + u -= scale*update[0]; + v -= scale*update[1]; + mean_diff -= scale*update[2]; + } + error=error_t; + #if SUBPIX_VERBOSE cout << "Iter " << iter << ":" << "\t u=" << u << ", v=" << v - << "\t update = " << update[0] << ", " << update[1]<< endl; -// << "\t new chi2 = " << new_chi2 << endl; + << "\t error = " << error + << "\t delta error = " << dt + << "\t sign = " << sign << endl; #endif - if(update[0]*update[0]+update[1]*update[1] < min_update_squared) + if(error_t < min_update_squared) { #if SUBPIX_VERBOSE cout << "converged." << endl; @@ -271,7 +285,9 @@ bool align2D( break; } } - +#if SUBPIX_VERBOSE + if(!converged)cout << "not converged." << endl; +#endif cur_px_estimate << u, v; return converged; } diff --git a/GPU_version/svo/src/frame.cpp b/GPU_version/svo/src/frame.cpp index 3aa9273..b425646 100644 --- a/GPU_version/svo/src/frame.cpp +++ b/GPU_version/svo/src/frame.cpp @@ -32,7 +32,8 @@ Frame::Frame(vk::AbstractCamera* cam, const cv::Mat& img, double timestamp) : cam_(cam), key_pts_(5), is_keyframe_(false), - v_kf_(NULL) + v_kf_(NULL), + T_f_w_(SE2_5(0.0,0.0,0.0)) { initFrame(img); } @@ -137,7 +138,9 @@ void Frame::removeKeyPoint(Feature* ftr) bool Frame::isVisible(const Vector3d& xyz_w) const { - Vector3d xyz_f = T_f_w_*xyz_w; + Vector3d xyz_f = Vector3d(xyz_w.x()*T_f_w_.cos_theta_+xyz_w.z()*T_f_w_.sin_theta_+T_f_w_.X_, + xyz_w.y(), + -xyz_w.x()*T_f_w_.sin_theta_+xyz_w.z()*T_f_w_.cos_theta_+T_f_w_.Z_); if(xyz_f.z() < 0.0) return false; // point is behind the camera Vector2d px = f2c(xyz_f); diff --git a/GPU_version/svo/src/frame_handler_base.cpp b/GPU_version/svo/src/frame_handler_base.cpp index 2f22f65..3c77fca 100644 --- a/GPU_version/svo/src/frame_handler_base.cpp +++ b/GPU_version/svo/src/frame_handler_base.cpp @@ -86,8 +86,10 @@ int FrameHandlerBase::finishFrameProcessingCommon( stage_ = STAGE_RELOCALIZING; tracking_quality_ = TRACKING_INSUFFICIENT; } + /* else if (dropout == RESULT_FAILURE) resetAll(); + */ if(set_reset_) resetAll(); diff --git a/GPU_version/svo/src/frame_handler_mono.cpp b/GPU_version/svo/src/frame_handler_mono.cpp index 278c95b..92a6607 100644 --- a/GPU_version/svo/src/frame_handler_mono.cpp +++ b/GPU_version/svo/src/frame_handler_mono.cpp @@ -99,7 +99,7 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() { - new_frame_->T_f_w_ = SE3(Matrix3d::Identity(), Vector3d::Zero()); + new_frame_->T_f_w_ = SE2_5(0.0,0.0,0.0); if(klt_homography_init_->addFirstFrame(new_frame_) == initialization::FAILURE) return RESULT_NO_KEYFRAME; new_frame_->setKeyframe(); @@ -137,41 +137,30 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() { SE3 tem=imu_integPtr_->preintegrate_predict(); - Eigen::Quaternion q(tem.rotation_matrix()); - q.vec() *= 1/q.norm(); - q.w() *= 1/q.norm(); - q.x()=0.0; - q.z()=0.0; - tem.translation().y()=0.0; - new_frame_->T_f_w_ = SE3(q,tem.translation()); + new_frame_->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),atan(tem.rotation_matrix()(0,2)/tem.rotation_matrix()(0,0))); + //new_frame_->T_f_w_ = last_frame_->T_f_w_; // sparse image align SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), - 30, SparseImgAlign::LevenbergMarquardt, false, true); + 30, SparseImgAlign::LevenbergMarquardt, false, false); img_align.run(last_frame_, new_frame_); // map reprojection & feature alignment reprojector_.reprojectMap(new_frame_, overlap_kfs_); - std::cerr<<"Reprojection Map: "<<"\t nPoint:"<predict(new_frame_,last_frame_,sfba_n_edges_final,Config::poseOptimThresh())){ - std::cerr<<"imu failed\n"; + + double sfba_thresh, sfba_error_init, sfba_error_final; + if(!imu_integPtr_->predict(new_frame_,last_frame_,sfba_n_edges_final,reprojector_.n_matches_)){ return RESULT_FAILURE; } - - //usleep(5000); - double sfba_thresh, sfba_error_init, sfba_error_final; pose_optimizer::optimizeGaussNewton( - Config::poseOptimThresh(), Config::poseOptimNumIter(), false, + Config::poseOptimThresh(), Config::poseOptimNumIter(), true, new_frame_, sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final); - // pose optimization subject to change for adding IMU - /* - if(!imu_integPtr_->predict(new_frame_,last_frame_,sfba_n_edges_final,Config::poseOptimThresh())){ - std::cerr<<"imu failed\n"; - return RESULT_FAILURE; - }*/ - std::cerr<<"Reprojected points after opmization: "< Config::qualityMinFts()) { - SE3 T_f_w_last = last_frame_->T_f_w_; + SE2_5 T_f_w_last = last_frame_->T_f_w_; last_frame_ = ref_keyframe; FrameHandlerMono::UpdateResult res = processFrame(); if(res != RESULT_FAILURE) diff --git a/GPU_version/svo/src/imu_integration.cpp b/GPU_version/svo/src/imu_integration.cpp index 3b371d7..571ea4e 100644 --- a/GPU_version/svo/src/imu_integration.cpp +++ b/GPU_version/svo/src/imu_integration.cpp @@ -7,24 +7,25 @@ #include #include "gpu_svo/feature.h" #include "gpu_svo/point.h" -#include "gpu_svo/svoVisionFactorSmall.h" -//#include "gpu_svo/svoVisionFactor.h" +//#include "gpu_svo/svoVisionFactorSmall.h" +#include "gpu_svo/svoVisionFactor.h" //#include "gpu_svo/svoVisionFactorLandMark.h" #include #include #include #include #include - +#define debug 1 Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ graphPtr=std::make_shared(); valuesPtr=std::make_shared(); // Example: pitch and roll of aircraft in an ENU Cartesian frame. // If pitch and roll are zero for an aerospace frame, // that means Z is pointing down, i.e., direction of Z = (0,0,-1) - gtsam::Vector4 g=SE_init.matrix()*gtsam::Vector4(0, 0, svo::Config::Gravity(),1.0); - parameterPtr = boost::shared_ptr(new gtsam::PreintegrationCombinedParams(gtsam::Vector3(g.x(),g.y(),g.z()))); - parameterPtr->setBodyPSensor(gtsam::Pose3(SE_init.matrix()));// The pose of the sensor in the body frame + //gtsam::Vector4 g=SE_init.matrix()*gtsam::Vector4(0, 0, svo::Config::Gravity(),1.0); + //parameterPtr = boost::shared_ptr(new gtsam::PreintegrationCombinedParams(gtsam::Vector3(g.x(),g.y(),g.z()))); + parameterPtr = boost::shared_ptr(new gtsam::PreintegrationCombinedParams(gtsam::Vector3(0.0,0.0,0.0))); + //parameterPtr->setBodyPSensor(gtsam::Pose3(SE_init.matrix()));// The pose of the sensor in the body frame parameterPtr->accelerometerCovariance=gtsam::I_3x3 * svo::Config::ACC_Noise(); // acc white noise in continuous parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * svo::Config::GYO_Noise();// gyro white noise in continuous parameterPtr->integrationCovariance=gtsam::I_3x3 * svo::Config::IUC(); // integration uncertainty continuous @@ -39,6 +40,7 @@ Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ optimizerParamPtr->relinearizeSkip = 1; optimizerParamPtr->evaluateNonlinearError=true; optimizerParamPtr->enableDetailedResults=true; + if(debug)logtime = fopen((std::string(getenv("HOME"))+"/imu_preIntegrate.txt").c_str(), "w+"); assert(preintegratedPtr); } Imu_Integration::~Imu_Integration(){ @@ -50,9 +52,9 @@ bool Imu_Integration::update(double* imu){ auto in=std::chrono::steady_clock::now(); if(std::chrono::duration(in-t_1).count()>20.0){ t_1=in; - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0]-svo::Config::X_off(),imu[1]-svo::Config::Y_off(),imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]-svo::Config::Teta_off()),0.005); + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0]-svo::Config::X_off(),0.0,-1.0*imu[1]-svo::Config::Y_off()),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),0.005); }else{ - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0]-svo::Config::X_off(),imu[1]-svo::Config::Y_off(),imu[2]),Eigen::Vector3d(imu[3],imu[4],imu[5]-svo::Config::Teta_off()),std::chrono::duration(in-t_1).count()); + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0]-svo::Config::X_off(),0.0,-1.0*imu[1]-svo::Config::Y_off()),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),std::chrono::duration(in-t_1).count()); t_1=in; ++imu_n; } @@ -67,7 +69,7 @@ bool Imu_Integration::reset(gtsam::ISAM2& optimizer,boost::shared_ptrresetIntegrationAndSetBias(*imu_biasPtr); ++imu_factor_id; syn=false; - new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); + new_frame->T_f_w_=svo::SE2_5(statePtr->t().x(),statePtr->t().z(),atan(statePtr->R()(0,2)/statePtr->R()(0,0))); new_frame->Cov_=optimizer.marginalCovariance(P(imu_factor_id-1)); graphPtr->resize(0); valuesPtr->clear(); @@ -88,7 +90,7 @@ bool Imu_Integration::reset(gtsam::ISAM2& optimizer,boost::shared_ptr& new_frame){ gtsam::Values result = optimizer.optimize(); - optimizer.print(); + if(debug)optimizer.print(); // Overwrite the beginning of the preintegration for the next step. statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); @@ -96,8 +98,14 @@ bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost: ++imu_factor_id; syn=false; gtsam::Marginals marginals(*graphPtr,result); - marginals.print(); - new_frame->T_f_w_=Sophus::SE3(statePtr->R(),statePtr->t()); + if(debug)fprintf(logtime, "%f,%f,%f,%f,%f,%f,\n", + new_frame->T_f_w_.T->translation().x(), + new_frame->T_f_w_.T->translation().y(), + new_frame->T_f_w_.T->translation().z(), + statePtr->pose().x(), + statePtr->pose().y(), + statePtr->pose().z()); + new_frame->T_f_w_=svo::SE2_5(statePtr->t().x(),statePtr->t().z(),atan(statePtr->R()(0,2)/statePtr->R()(0,0))); new_frame->Cov_=marginals.marginalCovariance(P(imu_factor_id-1)); graphPtr->resize(0); valuesPtr->clear(); @@ -107,16 +115,6 @@ bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost: graphPtr->addPrior(P(imu_factor_id-1),statePtr->pose(),marginals.marginalCovariance(P(imu_factor_id-1))); graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),marginals.marginalCovariance(V(imu_factor_id-1))); graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,marginals.marginalCovariance(B(imu_factor_id-1))); - /* - for(auto&& f_n:_for(new_frame->fts_)){ - if(f_n.item->point == NULL)continue; - if(!result.exists(L(f_n.index)))continue; - f_n.item->point->pos_=result.at(L(f_n.index)); - //valuesPtr->insert(L(f_n.index),f_n.item->point->pos_); - //graphPtr->emplace_shared(f_n.item->f,f_n.item->level,ProjectNoisePtr,P(imu_factor_id),L(f_n.index)); - } - //graphPtr->addPrior(L(0),new_frame->fts_.front()->point->pos_,gtsam::noiseModel::Isotropic::Sigma(3, 1e-4)); - */ return true; } Sophus::SE3 Imu_Integration::preintegrate_predict() { @@ -133,54 +131,39 @@ Sophus::SE3 Imu_Integration::preintegrate_predict() { } bool Imu_Integration::predict(boost::shared_ptr& new_frame, boost::shared_ptr& last_frame, - std::size_t& num_obs,const double reproj_thresh){ - + std::size_t& num_obs,const double cell_match){ + if(debug)std::cout<<"----------------------------IMU infuse---------------------------------------\n"; + //if(debug)preintegratedPtr->print(); auto preint_imu_combined =dynamic_cast(*preintegratedPtr); - valuesPtr->insert(P(imu_factor_id), gtsam::Pose3(new_frame->T_f_w_.matrix())); + valuesPtr->insert(P(imu_factor_id), Integ_predict.pose()); valuesPtr->insert(V(imu_factor_id), Integ_predict.v()); valuesPtr->insert(B(imu_factor_id), *imu_biasPtr); gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), preint_imu_combined); graphPtr->emplace_shared(imu_factor); imu_n=0; - - for(auto&& f:new_frame->fts_){ - if(f->point==NULL)continue; - graphPtr->emplace_shared(f->f, f->point->pos_,f->level, ProjectNoisePtr,P(imu_factor_id)); - ++num_obs; - } - - std::cout<<"------------------------------------------------------------------------------\n"; - std::cout<<"------------------------------------------------------------------------------\n"; - std::cout<<"------------------------------------------------------------------------------\n"; - graphPtr->print(); + graphPtr->emplace_shared(gtsam::Pose3(new_frame->T_f_w_.T->matrix()), + gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(3) << 1.0, 1.0, 1.0).finished()/(cell_match+1)), + P(imu_factor_id)); gtsam::LevenbergMarquardtParams params0; //params0.verbosity=gtsam::LevenbergMarquardtParams::LINEAR; params0.verbosityLM = gtsam::LevenbergMarquardtParams::SUMMARY; params0.setlambdaFactor(10.0); + params0.setlambdaInitial(100); + params0.setlambdaUpperBound(1e10); gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr,params0); reset(optimizer,new_frame); - std::cout<<"------------------------------------------------------------------------------\n"; - // Remove Measurements with too large reprojection error - /* - double reproj_thresh_scaled = reproj_thresh / new_frame->cam_->errorMultiplier2(); - for(auto&& f:new_frame->fts_) - { - if(f->point == NULL)continue; - Eigen::Vector2d e = (vk::project2d(f->f) - vk::project2d(new_frame->T_f_w_ * f->point->pos_))*1.0 / (1<level); - if(e.norm() > reproj_thresh_scaled) - { - // we don't need to delete a reference in the point since it was not created yet - f->point = NULL; - --num_obs; - } - } - */ + + if(debug)std::cout<<"------------------------------------------------------------------------------\n"; return true; } bool Imu_Integration::init(boost::shared_ptr& new_frame){ - statePtr=std::make_shared(gtsam::Pose3(new_frame->T_f_w_.matrix()), + statePtr=std::make_shared(gtsam::Pose3(new_frame->T_f_w_.T->matrix()), gtsam::Vector3(1e-9,1e-9,1e-9)); + /* + statePtr=std::make_shared(gtsam::Pose3(gtsam::Rot3::RzRyRx(0.0,0.0,0.0),gtsam::Point3(0.0,0.0,0.0)), + gtsam::Vector3(1e-9,1e-9,1e-9)); + */ valuesPtr->insert(P(0),statePtr->pose()); valuesPtr->insert(V(0),statePtr->v()); valuesPtr->insert(B(0),*imu_biasPtr); diff --git a/GPU_version/svo/src/initialization.cpp b/GPU_version/svo/src/initialization.cpp index 88f1cb8..1681a9e 100644 --- a/GPU_version/svo/src/initialization.cpp +++ b/GPU_version/svo/src/initialization.cpp @@ -69,11 +69,14 @@ InitResult KltHomographyInit::addSecondFrame(FramePtr frame_cur) depth_vec.push_back((xyz_in_cur_[i]).z()); double scene_depth_median = vk::getMedian(depth_vec); double scale = Config::mapScale()/scene_depth_median; - frame_cur->T_f_w_ = T_cur_from_ref_ * frame_ref_->T_f_w_; - frame_cur->T_f_w_.translation() = -frame_cur->T_f_w_.rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); + SE3 tem=T_cur_from_ref_ * (*frame_ref_->T_f_w_.T); + frame_cur->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),atan(tem.rotation_matrix()(0,2)/tem.rotation_matrix()(0,0))); + tem.translation() = -frame_cur->T_f_w_.T->rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); + frame_cur->T_f_w_.X_ = tem.translation().x(); + frame_cur->T_f_w_.Z_ = tem.translation().z(); // For each inlier create 3D point and add feature in both frames - SE3 T_world_cur = frame_cur->T_f_w_.inverse(); + SE3 T_world_cur = frame_cur->T_f_w_.T->inverse(); for(vector::iterator it=inliers_.begin(); it!=inliers_.end(); ++it) { Vector2d px_cur(px_cur_[*it].x, px_cur_[*it].y); diff --git a/GPU_version/svo/src/map.cpp b/GPU_version/svo/src/map.cpp index 90c7416..e46f9b0 100644 --- a/GPU_version/svo/src/map.cpp +++ b/GPU_version/svo/src/map.cpp @@ -114,12 +114,11 @@ void Map::getCloseKeyframes( { if(keypoint == nullptr) continue; - if(frame->isVisible(keypoint->point->pos_)) { close_kfs.push_back( std::make_pair( - kf, (frame->T_f_w_.translation()-kf->T_f_w_.translation()).norm())); + kf, (frame->T_f_w_.T->translation()-kf->T_f_w_.T->translation()).norm())); break; // this keyframe has an overlapping field of view -> add to close_kfs } } @@ -178,8 +177,9 @@ void Map::transform(const Matrix3d& R, const Vector3d& t, const double& s) for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) { Vector3d pos = s*R*(*it)->pos() + t; - Matrix3d rot = R*(*it)->T_f_w_.rotation_matrix().inverse(); - (*it)->T_f_w_ = SE3(rot, pos).inverse(); + Matrix3d rot = R*(*it)->T_f_w_.T->rotation_matrix().inverse(); + SE3 inv=SE3(rot, pos).inverse(); + (*it)->T_f_w_ = SE2_5(inv.translation().x(),inv.translation().z(),atan(inv.rotation_matrix()(0,2)/inv.rotation_matrix()(0,0))); for(auto ftr=(*it)->fts_.begin(); ftr!=(*it)->fts_.end(); ++ftr) { if((*ftr)->point == NULL) diff --git a/GPU_version/svo/src/matcher.cpp b/GPU_version/svo/src/matcher.cpp index 26e9dfc..e4a236a 100644 --- a/GPU_version/svo/src/matcher.cpp +++ b/GPU_version/svo/src/matcher.cpp @@ -147,7 +147,7 @@ bool Matcher::findMatchDirect( warp::getWarpMatrixAffine( *ref_ftr_->frame->cam_, *cur_frame.cam_, ref_ftr_->px, ref_ftr_->f, (ref_ftr_->frame->pos() - pt.pos_).norm(), - cur_frame.T_f_w_ * ref_ftr_->frame->T_f_w_.inverse(), ref_ftr_->level, A_cur_ref_); + (*cur_frame.T_f_w_.T) * ref_ftr_->frame->T_f_w_.T->inverse(), ref_ftr_->level, A_cur_ref_); search_level_ = warp::getBestSearchLevel(A_cur_ref_, Config::nPyrLevels()-1); warp::warpAffine(A_cur_ref_, ref_ftr_->frame->img_pyr_[ref_ftr_->level], ref_ftr_->px, ref_ftr_->level, search_level_, halfpatch_size_+1, patch_with_border_); @@ -184,7 +184,7 @@ bool Matcher::findEpipolarMatchDirect( const double d_max, double& depth) { - SE3 T_cur_ref = cur_frame.T_f_w_ * ref_frame.T_f_w_.inverse(); + SE3 T_cur_ref = (*cur_frame.T_f_w_.T) * ref_frame.T_f_w_.T->inverse(); int zmssd_best = PatchScore::threshold(); Vector2d uv_best; diff --git a/GPU_version/svo/src/point.cpp b/GPU_version/svo/src/point.cpp index 24423eb..e7f1f21 100644 --- a/GPU_version/svo/src/point.cpp +++ b/GPU_version/svo/src/point.cpp @@ -89,7 +89,7 @@ void Point::initNormal() assert(!obs_.empty()); const Feature* ftr = obs_.back(); assert(ftr->frame != NULL); - normal_ = ftr->frame->T_f_w_.rotation_matrix().transpose()*(-ftr->f); + normal_ = ftr->frame->T_f_w_.T->rotation_matrix().transpose()*(-ftr->f); normal_information_ = DiagonalMatrix(pow(20/(pos_-ftr->frame->pos()).norm(),2), 1.0, 1.0); normal_set_ = true; } @@ -133,8 +133,10 @@ void Point::optimize(const size_t n_iter) for(auto it=obs_.begin(); it!=obs_.end(); ++it) { Matrix23d J; - const Vector3d p_in_f((*it)->frame->T_f_w_ * pos_); - Point::jacobian_xyz2uv(p_in_f, (*it)->frame->T_f_w_.rotation_matrix(), J); + const Vector3d p_in_f(pos_.x()*(*it)->frame->T_f_w_.cos_theta_+pos_.z()*(*it)->frame->T_f_w_.sin_theta_+(*it)->frame->T_f_w_.X_, + pos_.y(), + -pos_.x()*(*it)->frame->T_f_w_.sin_theta_+pos_.z()*(*it)->frame->T_f_w_.cos_theta_+(*it)->frame->T_f_w_.Z_); + Point::jacobian_xyz2uv(p_in_f, (*it)->frame->T_f_w_.T->rotation_matrix(), J); const Vector2d e(vk::project2d((*it)->f) - vk::project2d(p_in_f)); new_chi2 += e.squaredNorm(); A.noalias() += J.transpose() * J; diff --git a/GPU_version/svo/src/pose_optimizer.cpp b/GPU_version/svo/src/pose_optimizer.cpp index 3d89d1e..8e8e47c 100644 --- a/GPU_version/svo/src/pose_optimizer.cpp +++ b/GPU_version/svo/src/pose_optimizer.cpp @@ -39,7 +39,7 @@ void optimizeGaussNewton( double chi2(0.0); vector chi2_vec_init, chi2_vec_final; vk::robust_cost::TukeyWeightFunction weight_function; - SE3 T_old(frame->T_f_w_); + SE2_5 T_old(frame->T_f_w_.X_,frame->T_f_w_.Z_,frame->T_f_w_.tetha_); Matrix6d A; Vector6d b; @@ -51,7 +51,10 @@ void optimizeGaussNewton( continue; //Reprojection error Vector2d e = vk::project2d((*it)->f) - - vk::project2d(frame->T_f_w_ * (*it)->point->pos_); + - vk::project2d(Vector3d((*it)->point->pos_.x()*frame->T_f_w_.cos_theta_+(*it)->point->pos_.z()*frame->T_f_w_.sin_theta_+frame->T_f_w_.X_, + (*it)->point->pos_.y(), + -(*it)->point->pos_.x()*frame->T_f_w_.sin_theta_+(*it)->point->pos_.z()*frame->T_f_w_.cos_theta_+frame->T_f_w_.Z_)); + e *= 1.0 / (1<<(*it)->level); errors.push_back(e.norm()); } @@ -80,7 +83,9 @@ void optimizeGaussNewton( if((*it)->point == NULL) continue; Matrix26d J; - Vector3d xyz_f(frame->T_f_w_ * (*it)->point->pos_); + Vector3d xyz_f(Vector3d((*it)->point->pos_.x()*frame->T_f_w_.cos_theta_+(*it)->point->pos_.z()*frame->T_f_w_.sin_theta_+frame->T_f_w_.X_, + (*it)->point->pos_.y(), + -(*it)->point->pos_.x()*frame->T_f_w_.sin_theta_+(*it)->point->pos_.z()*frame->T_f_w_.cos_theta_+frame->T_f_w_.Z_)); Frame::jacobian_xyz2uv(xyz_f, J); Vector2d e = vk::project2d((*it)->f) - vk::project2d(xyz_f); double sqrt_inv_cov = 1.0 / (1<<(*it)->level); @@ -108,9 +113,9 @@ void optimizeGaussNewton( } // update the model - SE3 T_new = SE3::exp(dT)*frame->T_f_w_; + SE3 T_new = SE3::exp(dT)*(*frame->T_f_w_.T); T_old = frame->T_f_w_; - frame->T_f_w_ = T_new; + frame->T_f_w_ = SE2_5(T_new.translation().x(),T_new.translation().z(),atan(T_new.rotation_matrix()(0,2)/T_new.rotation_matrix()(0,0))); chi2 = new_chi2; if(verbose) std::cout << "it " << iter @@ -133,7 +138,9 @@ void optimizeGaussNewton( { if((*it)->point == NULL) continue; - Vector2d e = vk::project2d((*it)->f) - vk::project2d(frame->T_f_w_ * (*it)->point->pos_); + Vector2d e = vk::project2d((*it)->f) - vk::project2d(Vector3d((*it)->point->pos_.x()*frame->T_f_w_.cos_theta_+(*it)->point->pos_.z()*frame->T_f_w_.sin_theta_+frame->T_f_w_.X_, + (*it)->point->pos_.y(), + -(*it)->point->pos_.x()*frame->T_f_w_.sin_theta_+(*it)->point->pos_.z()*frame->T_f_w_.cos_theta_+frame->T_f_w_.Z_)); double sqrt_inv_cov = 1.0 / (1<<(*it)->level); e *= sqrt_inv_cov; chi2_vec_final.push_back(e.squaredNorm()); diff --git a/GPU_version/svo/src/sparse_img_align.cpp b/GPU_version/svo/src/sparse_img_align.cpp index 13ae449..b197181 100644 --- a/GPU_version/svo/src/sparse_img_align.cpp +++ b/GPU_version/svo/src/sparse_img_align.cpp @@ -55,8 +55,7 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) ref_patch_cache_ = cv::Mat(ref_frame_->fts_.size(), patch_area_, CV_32F); jacobian_cache_.resize(Eigen::NoChange, ref_patch_cache_.rows*patch_area_); //visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? - SE3 T_cur_from_ref(cur_frame_->T_f_w_ * ref_frame_->T_f_w_.inverse()); - + SE3 T_cur_from_ref(*cur_frame_->T_f_w_.T * ref_frame_->T_f_w_.T->inverse()); for(level_=max_level_; level_>=min_level_; --level_) { visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? @@ -67,7 +66,8 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) printf("\nPYRAMID LEVEL %i\n---------------\n", level_); optimize(T_cur_from_ref); } - cur_frame_->T_f_w_ = T_cur_from_ref * ref_frame_->T_f_w_; + SE3 tem=T_cur_from_ref * (*ref_frame_->T_f_w_.T); + cur_frame_->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),atan(tem.rotation_matrix()(0,2)/tem.rotation_matrix()(0,0))); return n_meas_/patch_area_; } diff --git a/GPU_version/vio/launch/Px30.launch b/GPU_version/vio/launch/Px30.launch index 67019b8..032feaf 100644 --- a/GPU_version/vio/launch/Px30.launch +++ b/GPU_version/vio/launch/Px30.launch @@ -10,7 +10,7 @@ - + diff --git a/GPU_version/vio/param/vo_fast.yaml b/GPU_version/vio/param/vo_fast.yaml index a5f9cec..13ada7a 100644 --- a/GPU_version/vio/param/vo_fast.yaml +++ b/GPU_version/vio/param/vo_fast.yaml @@ -15,8 +15,8 @@ svo: ABC: 0.1 #acc bias in continuous GBC: 0.1 #gyro bias in continuous EBP: 0.1 #error in the bias used for preintegration - NRP: 0.0000001 #noise used for projection in preintegration - gravity: 9.65 + NRP: 0.001 #noise used for projection in preintegration + gravity: -9.65 Acceleration_offset_x: -0.05 Acceleration_offset_y: -0.04 Gyroscope_offset_z: 0.001 diff --git a/GPU_version/vio/src/visualizer.cpp b/GPU_version/vio/src/visualizer.cpp index 90ad7ab..0264b03 100644 --- a/GPU_version/vio/src/visualizer.cpp +++ b/GPU_version/vio/src/visualizer.cpp @@ -34,10 +34,9 @@ Visualizer() : T_world_from_vision_(Matrix3d::Identity(), Vector3d::Zero()) { // Init ROS Marker Publishers - pub_frames_ = pnh_.advertise("keyframes", 10); - pub_points_ = pnh_.advertise("points", 1000); + //pub_frames_ = pnh_.advertise("keyframes", 10); + // pub_points_ = pnh_.advertise("points", 1000); pub_pose_ = pnh_.advertise("pose",10); - pub_info_ = pnh_.advertise("info", 10); } void Visualizer::publishMinimal( @@ -48,38 +47,18 @@ void Visualizer::publishMinimal( { ++trace_id_; std_msgs::Header header_msg; - header_msg.frame_id = "/cam"; + header_msg.frame_id = "/world"; header_msg.seq = trace_id_; header_msg.stamp = ros::Time(timestamp); - - // publish info msg. - if(pub_info_.getNumSubscribers() > 0) - { - vio_gpu::Info msg_info; - msg_info.header = header_msg; - //msg_info.processing_time = slam.lastProcessingTime(); - msg_info.keyframes.reserve(slam.map().keyframes_.size()); - for(list::const_iterator it=slam.map().keyframes_.begin(); it!=slam.map().keyframes_.end(); ++it) - msg_info.keyframes.push_back((*it)->id_); - msg_info.stage = static_cast(slam.stage()); - msg_info.tracking_quality = static_cast(slam.trackingQuality()); - /* - if(frame != NULL) - msg_info.num_matches = slam.lastNumObservations(); - else - msg_info.num_matches = 0; - */ - pub_info_.publish(msg_info); - } if(pub_pose_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) { Quaterniond q; Vector3d p; Matrix Cov; // publish cam in world frame (Estimated odometry in the worls frame) - SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse());// do not confused with inverse. the T_f_w_ is the from camera to initial position with reference of camera - q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); - p = T_world_from_cam.translation(); + SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.T->inverse());// do not confused with inverse. the T_f_w_ is the from camera to initial position with reference of camera + //q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); + //p = T_world_from_cam.translation(); Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj(); geometry_msgs::PoseWithCovarianceStampedPtr msg_pose(new geometry_msgs::PoseWithCovarianceStamped); msg_pose->header = header_msg; @@ -105,7 +84,7 @@ void Visualizer::visualizeMarkers( return; vk::output_helper::publishTfTransform( - frame->T_f_w_*T_world_from_vision_.inverse(), + *frame->T_f_w_.T*T_world_from_vision_.inverse(), ros::Time(frame->timestamp_), "cam_pos", "world", br_); if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) diff --git a/GPU_version/vio/src/vo_node.cpp b/GPU_version/vio/src/vo_node.cpp index b167282..0550d5a 100644 --- a/GPU_version/vio/src/vo_node.cpp +++ b/GPU_version/vio/src/vo_node.cpp @@ -95,8 +95,6 @@ void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) cv::Mat img=cv_bridge::toCvShare(msg, "mono8")->image; vo_->addImage(img, msg->header.stamp.toSec()); visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, msg->header.stamp.toSec()); - if(publish_markers_ && vo_->stage() != FrameHandlerBase::STAGE_PAUSED) - visualizer_.visualizeMarkers(vo_->lastFrame(), vo_->coreKeyframes(), vo_->map()); if(vo_->stage() == FrameHandlerMono::STAGE_PAUSED) usleep(100000); fprintf(logtime, "%s\n",std::to_string(std::chrono::duration(std::chrono::steady_clock::now()-start).count()).c_str()); From 982217598aecaf22e38dbee94f6390e80ccc44da Mon Sep 17 00:00:00 2001 From: gfuse Date: Tue, 1 Jun 2021 19:26:34 +0200 Subject: [PATCH 201/215] remove logs, trying to add more key frames by setting some situation for depth mean --- GPU_version/svo/include/gpu_svo/global.h | 7 ++++++ GPU_version/svo/src/frame_handler_mono.cpp | 25 ++++++++++++++++++---- GPU_version/svo/src/imu_integration.cpp | 15 +++++++------ GPU_version/svo/src/pose_optimizer.cpp | 1 - GPU_version/svo/src/reprojector.cpp | 2 +- GPU_version/vio/param/vo_fast.yaml | 6 +++--- GPU_version/vio/src/visualizer.cpp | 8 +++---- GPU_version/vio/src/vo_node.cpp | 12 +++++------ 8 files changed, 51 insertions(+), 25 deletions(-) diff --git a/GPU_version/svo/include/gpu_svo/global.h b/GPU_version/svo/include/gpu_svo/global.h index f5292c4..a307503 100644 --- a/GPU_version/svo/include/gpu_svo/global.h +++ b/GPU_version/svo/include/gpu_svo/global.h @@ -62,6 +62,13 @@ namespace svo -sin_theta_,0.0,cos_theta_; T=new SE3(R,Vector3d(X_,0.0,Z_)); }; + void set(){ + X_=T->translation().x(); + Z_=T->translation().z(); + tetha_=atan(T->matrix()(0,2)/T->matrix()(0,0)); + cos_theta_=cos(tetha_); + sin_theta_=sin(tetha_); + } ~SE2_5(){} }; diff --git a/GPU_version/svo/src/frame_handler_mono.cpp b/GPU_version/svo/src/frame_handler_mono.cpp index 92a6607..7dcaffc 100644 --- a/GPU_version/svo/src/frame_handler_mono.cpp +++ b/GPU_version/svo/src/frame_handler_mono.cpp @@ -137,24 +137,32 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() { SE3 tem=imu_integPtr_->preintegrate_predict(); - new_frame_->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),atan(tem.rotation_matrix()(0,2)/tem.rotation_matrix()(0,0))); + if((new_frame_->T_f_w_.T->translation()-tem.translation()).norm()>0.5){ + new_frame_->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),atan(tem.rotation_matrix()(0,2)/tem.rotation_matrix()(0,0))); + }else{ + new_frame_->T_f_w_ = last_frame_->T_f_w_; + } + new_frame_->T_f_w_.set(); //new_frame_->T_f_w_ = last_frame_->T_f_w_; // sparse image align SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), 30, SparseImgAlign::LevenbergMarquardt, false, false); img_align.run(last_frame_, new_frame_); + new_frame_->T_f_w_.set(); // map reprojection & feature alignment reprojector_.reprojectMap(new_frame_, overlap_kfs_); size_t sfba_n_edges_final=0; - + new_frame_->T_f_w_.set(); double sfba_thresh, sfba_error_init, sfba_error_final; if(!imu_integPtr_->predict(new_frame_,last_frame_,sfba_n_edges_final,reprojector_.n_matches_)){ return RESULT_FAILURE; } + new_frame_->T_f_w_.set(); pose_optimizer::optimizeGaussNewton( - Config::poseOptimThresh(), Config::poseOptimNumIter(), true, + Config::poseOptimThresh(), Config::poseOptimNumIter(), false, new_frame_, sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final); + new_frame_->T_f_w_.set(); std::cerr<<"Reprojection Map: "<<"\t nPoint:"<T_f_w_.set(); // select keyframe core_kfs_.insert(new_frame_); setTrackingQuality(sfba_n_edges_final); @@ -176,20 +185,26 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() return RESULT_FAILURE; } double depth_mean, depth_min; + + new_frame_->T_f_w_.set(); frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); - if(!needNewKf(depth_mean) || tracking_quality_ == TRACKING_BAD) + + new_frame_->T_f_w_.set(); + if(!needNewKf(depth_mean) || tracking_quality_ == TRACKING_BAD)//edited { depth_filter_->addFrame(new_frame_); return RESULT_NO_KEYFRAME; } new_frame_->setKeyframe(); + new_frame_->T_f_w_.set(); // new keyframe selected for(auto&& it:new_frame_->fts_){ if(it->point != NULL)it->point->addFrameRef(it); } map_.point_candidates_.addCandidatePointToFrame(new_frame_); + new_frame_->T_f_w_.set(); // init new depth-filters depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min); @@ -201,6 +216,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() map_.safeDeleteFrame(furthest_frame); } + new_frame_->T_f_w_.set(); // add keyframe to map map_.addKeyframe(new_frame_); std::cerr<<"Svo pipline was finished\n"; @@ -274,6 +290,7 @@ void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame) bool FrameHandlerMono::needNewKf(double scene_depth_mean) { + if(scene_depth_mean >10.0)return true; for(auto&& it:overlap_kfs_) { Vector3d relpos = new_frame_->w2f(it.first->pos()); diff --git a/GPU_version/svo/src/imu_integration.cpp b/GPU_version/svo/src/imu_integration.cpp index 571ea4e..4346c0d 100644 --- a/GPU_version/svo/src/imu_integration.cpp +++ b/GPU_version/svo/src/imu_integration.cpp @@ -15,7 +15,7 @@ #include #include #include -#define debug 1 +#define debug 0 Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ graphPtr=std::make_shared(); valuesPtr=std::make_shared(); @@ -52,9 +52,9 @@ bool Imu_Integration::update(double* imu){ auto in=std::chrono::steady_clock::now(); if(std::chrono::duration(in-t_1).count()>20.0){ t_1=in; - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0]-svo::Config::X_off(),0.0,-1.0*imu[1]-svo::Config::Y_off()),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),0.005); + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),0.005); }else{ - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(imu[0]-svo::Config::X_off(),0.0,-1.0*imu[1]-svo::Config::Y_off()),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),std::chrono::duration(in-t_1).count()); + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),std::chrono::duration(in-t_1).count()); t_1=in; ++imu_n; } @@ -98,13 +98,16 @@ bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost: ++imu_factor_id; syn=false; gtsam::Marginals marginals(*graphPtr,result); - if(debug)fprintf(logtime, "%f,%f,%f,%f,%f,%f,\n", + if(debug)fprintf(logtime, "%f,%f,%f,%f,%f,%f,%f,%f,\n", new_frame->T_f_w_.T->translation().x(), new_frame->T_f_w_.T->translation().y(), new_frame->T_f_w_.T->translation().z(), + atan(new_frame->T_f_w_.T->rotation_matrix()(0,2)/new_frame->T_f_w_.T->rotation_matrix()(0,0)), statePtr->pose().x(), statePtr->pose().y(), - statePtr->pose().z()); + statePtr->pose().z(), + atan(statePtr->R()(0,2)/statePtr->R()(0,0))); + if((statePtr->t()-new_frame->T_f_w_.T->translation()).norm()>2.0)return false; new_frame->T_f_w_=svo::SE2_5(statePtr->t().x(),statePtr->t().z(),atan(statePtr->R()(0,2)/statePtr->R()(0,0))); new_frame->Cov_=marginals.marginalCovariance(P(imu_factor_id-1)); graphPtr->resize(0); @@ -147,7 +150,7 @@ bool Imu_Integration::predict(boost::shared_ptr& new_frame, P(imu_factor_id)); gtsam::LevenbergMarquardtParams params0; //params0.verbosity=gtsam::LevenbergMarquardtParams::LINEAR; - params0.verbosityLM = gtsam::LevenbergMarquardtParams::SUMMARY; + params0.verbosityLM = gtsam::LevenbergMarquardtParams::SILENT; params0.setlambdaFactor(10.0); params0.setlambdaInitial(100); params0.setlambdaUpperBound(1e10); diff --git a/GPU_version/svo/src/pose_optimizer.cpp b/GPU_version/svo/src/pose_optimizer.cpp index 8e8e47c..5dcbee3 100644 --- a/GPU_version/svo/src/pose_optimizer.cpp +++ b/GPU_version/svo/src/pose_optimizer.cpp @@ -98,7 +98,6 @@ void optimizeGaussNewton( b.noalias() -= J.transpose()*e*weight; new_chi2 += e.squaredNorm()*weight; } - // solve linear system const Vector6d dT(A.ldlt().solve(b)); diff --git a/GPU_version/svo/src/reprojector.cpp b/GPU_version/svo/src/reprojector.cpp index 0305797..b7f9022 100644 --- a/GPU_version/svo/src/reprojector.cpp +++ b/GPU_version/svo/src/reprojector.cpp @@ -72,7 +72,7 @@ void Reprojector::reprojectMap( list< pair > close_kfs; map_.getCloseKeyframes(frame, close_kfs); - std::cout<<"The number of closed frames: "<::second, _1) < boost::bind(&std::pair::second, _2)); diff --git a/GPU_version/vio/param/vo_fast.yaml b/GPU_version/vio/param/vo_fast.yaml index 13ada7a..c2189bd 100644 --- a/GPU_version/vio/param/vo_fast.yaml +++ b/GPU_version/vio/param/vo_fast.yaml @@ -17,6 +17,6 @@ svo: EBP: 0.1 #error in the bias used for preintegration NRP: 0.001 #noise used for projection in preintegration gravity: -9.65 - Acceleration_offset_x: -0.05 - Acceleration_offset_y: -0.04 - Gyroscope_offset_z: 0.001 + Acceleration_offset_x: 0.0 #-0.05 + Acceleration_offset_y: 0.0 #-0.04 + Gyroscope_offset_z: 0.0 #0.001 diff --git a/GPU_version/vio/src/visualizer.cpp b/GPU_version/vio/src/visualizer.cpp index 0264b03..3d58393 100644 --- a/GPU_version/vio/src/visualizer.cpp +++ b/GPU_version/vio/src/visualizer.cpp @@ -65,10 +65,10 @@ void Visualizer::publishMinimal( msg_pose->pose.pose.position.x = p[0]; msg_pose->pose.pose.position.y = p[1]; msg_pose->pose.pose.position.z = p[2]; - msg_pose->pose.pose.orientation.x = q.x(); - msg_pose->pose.pose.orientation.y = q.y(); - msg_pose->pose.pose.orientation.z = q.z(); - msg_pose->pose.pose.orientation.w = q.w(); + msg_pose->pose.pose.orientation.x = q.x()/q.norm(); + msg_pose->pose.pose.orientation.y = q.y()/q.norm(); + msg_pose->pose.pose.orientation.z = q.z()/q.norm(); + msg_pose->pose.pose.orientation.w = q.w()/q.norm(); for(size_t i=0; i<36; ++i) msg_pose->pose.covariance[i] = Cov(i%6, i/6); pub_pose_.publish(msg_pose); diff --git a/GPU_version/vio/src/vo_node.cpp b/GPU_version/vio/src/vo_node.cpp index 0550d5a..0087b0c 100644 --- a/GPU_version/vio/src/vo_node.cpp +++ b/GPU_version/vio/src/vo_node.cpp @@ -105,12 +105,12 @@ void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) } void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { double imu_in[6]; - imu_in[0] = 0.1*imu_[0]+0.9*imu->linear_acceleration.x; - imu_in[1] = 0.1*imu_[1]+0.9*imu->linear_acceleration.y; - imu_in[2] = 0.1*imu_[2]+0.9*imu->linear_acceleration.z; - imu_in[3] = 0.1*imu_[3]+0.9*imu->angular_velocity.x; - imu_in[4] = 0.1*imu_[4]+0.9*imu->angular_velocity.y; - imu_in[5] = 0.1*imu_[5]+0.9*imu->angular_velocity.z; + imu_in[0] = 0.4*imu_[0]+0.6*imu->linear_acceleration.x; + imu_in[1] = 0.4*imu_[1]+0.6*imu->linear_acceleration.y; + imu_in[2] = 0.4*imu_[2]+0.6*imu->linear_acceleration.z; + imu_in[3] = 0.4*imu_[3]+0.6*imu->angular_velocity.x; + imu_in[4] = 0.4*imu_[4]+0.6*imu->angular_velocity.y; + imu_in[5] = 0.4*imu_[5]+0.6*imu->angular_velocity.z; memcpy(imu_, imu_in, static_cast(6*sizeof(double))); vo_->imu_integPtr_->update(imu_in); } From 27f92bc7e7cb9f96803f6d1fc452423d88573edb Mon Sep 17 00:00:00 2001 From: gfuse Date: Fri, 4 Jun 2021 14:59:02 +0200 Subject: [PATCH 202/215] calibrate imu --- .../svo/include/gpu_svo/depth_filter.h | 3 +- .../svo/include/gpu_svo/imu_integration.h | 6 +- GPU_version/svo/src/depth_filter.cpp | 43 ++++----- GPU_version/svo/src/feature_alignment.cpp | 2 +- GPU_version/svo/src/frame_handler_mono.cpp | 47 +++++----- GPU_version/svo/src/imu_integration.cpp | 89 +++++-------------- GPU_version/svo/src/matcher.cpp | 2 + GPU_version/svo/src/sparse_img_align.cpp | 4 +- GPU_version/vio/include/vio_gpu/visualizer.h | 2 +- GPU_version/vio/param/vo_fast.yaml | 12 +-- GPU_version/vio/src/visualizer.cpp | 38 ++++---- 11 files changed, 108 insertions(+), 140 deletions(-) diff --git a/GPU_version/svo/include/gpu_svo/depth_filter.h b/GPU_version/svo/include/gpu_svo/depth_filter.h index 07d71e5..9e82df4 100644 --- a/GPU_version/svo/include/gpu_svo/depth_filter.h +++ b/GPU_version/svo/include/gpu_svo/depth_filter.h @@ -138,7 +138,6 @@ public: protected: feature_detection::DetectorPtr feature_detector_; callback_t seed_converged_cb_; - //std::list seeds_; std::list> seeds_; boost::mutex seeds_mut_; bool seeds_updating_halt_; //!< Set this value to true when seeds updating should be interrupted. @@ -150,8 +149,8 @@ protected: bool new_keyframe_set_; //!< Do we have a new keyframe to process?. double new_keyframe_min_depth_; //!< Minimum depth in the new keyframe. Used for range in new seeds. double new_keyframe_mean_depth_; //!< Maximum depth in the new keyframe. Used for range in new seeds. - //vk::PerformanceMonitor permon_; //!< Separate performance monitor since the DepthFilter runs in a parallel thread. Matcher matcher_; + uint seeds_cont_=0; /// Initialize new seeds from a frame. void initializeSeeds(FramePtr frame); diff --git a/GPU_version/svo/include/gpu_svo/imu_integration.h b/GPU_version/svo/include/gpu_svo/imu_integration.h index 2ff4a89..11eb514 100644 --- a/GPU_version/svo/include/gpu_svo/imu_integration.h +++ b/GPU_version/svo/include/gpu_svo/imu_integration.h @@ -24,13 +24,13 @@ class Imu_Integration{ public: Imu_Integration(Sophus::SE3& SE_init); ~Imu_Integration(); - bool reset(gtsam::ISAM2& optimizer,boost::shared_ptr& new_frame); + void reset(); bool reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr& new_frame); bool update(double* imu= nullptr); bool predict(boost::shared_ptr&, - boost::shared_ptr& last_frame ,std::size_t&,const double reproj_thresh); + boost::shared_ptr& last_frame ,const double match); bool init(boost::shared_ptr&); - Sophus::SE3 preintegrate_predict(); + bool preintegrate_predict(svo::SE2_5& frame); private: FILE* logtime; std::shared_ptr statePtr; diff --git a/GPU_version/svo/src/depth_filter.cpp b/GPU_version/svo/src/depth_filter.cpp index a2132db..4e04b5f 100644 --- a/GPU_version/svo/src/depth_filter.cpp +++ b/GPU_version/svo/src/depth_filter.cpp @@ -92,14 +92,17 @@ void DepthFilter::addFrame(FramePtr frame) seeds_updating_halt_ = false; frame_queue_cond_.notify_one(); } - else - updateSeeds(frame); + else{ + updateSeeds(frame); + } + } void DepthFilter::addKeyframe(FramePtr frame, double depth_mean, double depth_min) { new_keyframe_min_depth_ = depth_min; new_keyframe_mean_depth_ = depth_mean; + ++seeds_cont_; if(thread_ != NULL) { new_keyframe_ = frame; @@ -108,7 +111,10 @@ void DepthFilter::addKeyframe(FramePtr frame, double depth_mean, double depth_mi frame_queue_cond_.notify_one(); } else - initializeSeeds(frame); + if(seeds_cont_>5){ + initializeSeeds(frame); + seeds_cont_=0; + } } void DepthFilter::initializeSeeds(FramePtr frame) @@ -178,7 +184,9 @@ void DepthFilter::updateSeedsLoop() if(new_keyframe_set_) { new_keyframe_set_ = false; - seeds_updating_halt_ = false; + if(seeds_cont_>5){ + seeds_updating_halt_ = false; + } clearFrameQueue(); frame = new_keyframe_; } @@ -189,8 +197,12 @@ void DepthFilter::updateSeedsLoop() } } updateSeeds(frame); - if(frame->isKeyframe()) - initializeSeeds(frame); + + if(frame->isKeyframe() && seeds_cont_>5){ + initializeSeeds(frame); + seeds_cont_=0; + } + } } @@ -233,6 +245,10 @@ void DepthFilter::updateSeeds(FramePtr frame) // we are using inverse depth coordinates float z_inv_min = it->mu + sqrt(it->sigma2); float z_inv_max = max(it->mu - sqrt(it->sigma2), 0.00000001f); + if(z_inv_min <0){ + ++it; + continue; + } double z; if(!matcher_.findEpipolarMatchDirect( *it->ftr->frame, *frame, *it->ftr, 1.0/it->mu, 1.0/z_inv_min, 1.0/z_inv_max, z)) @@ -264,20 +280,7 @@ void DepthFilter::updateSeeds(FramePtr frame) Vector3d xyz_world(it->ftr->frame->T_f_w_.T->inverse() * (it->ftr->f * (1.0/it->mu))); Point* point = new Point(xyz_world, it->ftr); it->ftr->point = point; - /* FIXME it is not threadsafe to add a feature to the frame here. - if(frame->isKeyframe()) - { - Feature* ftr = new Feature(frame.get(), matcher_.px_cur_, matcher_.search_level_); - ftr->point = point; - point->addFrameRef(ftr); - frame->addFeature(ftr); - it->ftr->frame->addFeature(it->ftr); - } - else - */ - { - seed_converged_cb_(point, it->sigma2); // put in candidate list - } + seed_converged_cb_(point, it->sigma2); // put in candidate list it = seeds_.erase(it); } else if(isnan(z_inv_min)) diff --git a/GPU_version/svo/src/feature_alignment.cpp b/GPU_version/svo/src/feature_alignment.cpp index a68f121..6232e00 100644 --- a/GPU_version/svo/src/feature_alignment.cpp +++ b/GPU_version/svo/src/feature_alignment.cpp @@ -203,7 +203,7 @@ bool align2D( bool sign=true;// + // termination condition - const float min_update_squared = 0.05; + const float min_update_squared = 0.3; const int cur_step = cur_img.step.p[0]; // float chi2 = 0; Vector3f update; update.setZero(); diff --git a/GPU_version/svo/src/frame_handler_mono.cpp b/GPU_version/svo/src/frame_handler_mono.cpp index 7dcaffc..a96ad9e 100644 --- a/GPU_version/svo/src/frame_handler_mono.cpp +++ b/GPU_version/svo/src/frame_handler_mono.cpp @@ -136,14 +136,15 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() { - SE3 tem=imu_integPtr_->preintegrate_predict(); - if((new_frame_->T_f_w_.T->translation()-tem.translation()).norm()>0.5){ - new_frame_->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),atan(tem.rotation_matrix()(0,2)/tem.rotation_matrix()(0,0))); + bool IMU=false; + SE2_5 tem(0.0,0.0,0.0); + if(imu_integPtr_->preintegrate_predict(tem))if((last_frame_->T_f_w_.T->translation()-tem.T->translation()).norm()>0.5){ + new_frame_->T_f_w_ = tem; + IMU=true; }else{ + imu_integPtr_->reset(); new_frame_->T_f_w_ = last_frame_->T_f_w_; } - new_frame_->T_f_w_.set(); - //new_frame_->T_f_w_ = last_frame_->T_f_w_; // sparse image align SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), 30, SparseImgAlign::LevenbergMarquardt, false, false); @@ -151,30 +152,32 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() new_frame_->T_f_w_.set(); // map reprojection & feature alignment reprojector_.reprojectMap(new_frame_, overlap_kfs_); - size_t sfba_n_edges_final=0; new_frame_->T_f_w_.set(); - double sfba_thresh, sfba_error_init, sfba_error_final; - if(!imu_integPtr_->predict(new_frame_,last_frame_,sfba_n_edges_final,reprojector_.n_matches_)){ - return RESULT_FAILURE; + if(IMU)if(!imu_integPtr_->predict(new_frame_,last_frame_,reprojector_.n_matches_)){ + return RESULT_FAILURE; } + size_t sfba_n_edges_final=0; + double sfba_thresh, sfba_error_init, sfba_error_final; new_frame_->T_f_w_.set(); pose_optimizer::optimizeGaussNewton( Config::poseOptimThresh(), Config::poseOptimNumIter(), false, new_frame_, sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final); new_frame_->T_f_w_.set(); - std::cerr<<"Reprojection Map: "<<"\t nPoint:"<T_f_w_.T->translation()-new_frame_->T_f_w_.T->translation()).norm()>1.0){ + new_frame_->T_f_w_ = last_frame_->T_f_w_; + return RESULT_NO_KEYFRAME; + } if(sfba_n_edges_final < Config::qualityMinFts() || reprojector_.n_matches_ < Config::qualityMinFts()){ return RESULT_NO_KEYFRAME; } - // structure optimization -// SVO_START_TIMER("point_optimizer"); optimizeStructure(new_frame_, Config::structureOptimMaxPts(), Config::structureOptimNumIter()); - //SVO_STOP_TIMER("point_optimizer"); new_frame_->T_f_w_.set(); // select keyframe @@ -188,8 +191,11 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() new_frame_->T_f_w_.set(); frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); + if(depth_mean > 50 || depth_mean < 0.0) + { + return RESULT_NO_KEYFRAME; + } - new_frame_->T_f_w_.set(); if(!needNewKf(depth_mean) || tracking_quality_ == TRACKING_BAD)//edited { depth_filter_->addFrame(new_frame_); @@ -197,14 +203,13 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() } new_frame_->setKeyframe(); - new_frame_->T_f_w_.set(); + new_frame_->T_f_w_.set(); // new keyframe selected for(auto&& it:new_frame_->fts_){ if(it->point != NULL)it->point->addFrameRef(it); } map_.point_candidates_.addCandidatePointToFrame(new_frame_); - new_frame_->T_f_w_.set(); // init new depth-filters depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min); @@ -219,7 +224,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() new_frame_->T_f_w_.set(); // add keyframe to map map_.addKeyframe(new_frame_); - std::cerr<<"Svo pipline was finished\n"; + std::cout<<"Svo pipline was finished\n"; return RESULT_IS_KEYFRAME; } @@ -294,10 +299,10 @@ bool FrameHandlerMono::needNewKf(double scene_depth_mean) for(auto&& it:overlap_kfs_) { Vector3d relpos = new_frame_->w2f(it.first->pos()); - if(fabs(relpos.x())/scene_depth_mean < Config::kfSelectMinDist() && - fabs(relpos.y())/scene_depth_mean < Config::kfSelectMinDist() && - fabs(relpos.z())/scene_depth_mean < Config::kfSelectMinDist()) - return false; + if(fabs(relpos.norm())/scene_depth_mean < Config::kfSelectMinDist()){ + return false; + } + } return true; } diff --git a/GPU_version/svo/src/imu_integration.cpp b/GPU_version/svo/src/imu_integration.cpp index 4346c0d..20d06f0 100644 --- a/GPU_version/svo/src/imu_integration.cpp +++ b/GPU_version/svo/src/imu_integration.cpp @@ -15,7 +15,7 @@ #include #include #include -#define debug 0 +#define debug 1 Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ graphPtr=std::make_shared(); valuesPtr=std::make_shared(); @@ -49,10 +49,12 @@ Imu_Integration::~Imu_Integration(){ bool Imu_Integration::update(double* imu){ if(syn)return false; if(imu_factor_id<1)return false; + if(abs(imu[0])<1.0)imu[0]=pow(imu[0],3); + if(abs(imu[1])<1.0)imu[0]=pow(imu[1],3); auto in=std::chrono::steady_clock::now(); if(std::chrono::duration(in-t_1).count()>20.0){ t_1=in; - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),0.005); + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),0.0005); }else{ preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),std::chrono::duration(in-t_1).count()); t_1=in; @@ -61,126 +63,79 @@ bool Imu_Integration::update(double* imu){ return true; } -bool Imu_Integration::reset(gtsam::ISAM2& optimizer,boost::shared_ptr& new_frame){ - gtsam::Values result = optimizer.calculateEstimate(); - // Overwrite the beginning of the preintegration for the next step. - statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); - imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); - preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr); - ++imu_factor_id; - syn=false; - new_frame->T_f_w_=svo::SE2_5(statePtr->t().x(),statePtr->t().z(),atan(statePtr->R()(0,2)/statePtr->R()(0,0))); - new_frame->Cov_=optimizer.marginalCovariance(P(imu_factor_id-1)); - graphPtr->resize(0); - valuesPtr->clear(); - valuesPtr->insert(P(imu_factor_id-1),statePtr->pose()); - valuesPtr->insert(V(imu_factor_id-1),statePtr->v()); - valuesPtr->insert(B(imu_factor_id-1),*imu_biasPtr); - graphPtr->addPrior(P(imu_factor_id-1),statePtr->pose(),optimizer.marginalCovariance(P(imu_factor_id-1))); - graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),optimizer.marginalCovariance(V(imu_factor_id-1))); - graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,optimizer.marginalCovariance(B(imu_factor_id-1))); - for(auto&& f_n:_for(new_frame->fts_)){ - if(f_n.item->point == NULL)continue; - if(!result.exists(L(f_n.index)))continue; - f_n.item->point->pos_=result.at(L(f_n.index)); - // valuesPtr->insert(L(f_n.index),f_n.item->point->pos_); -// graphPtr->emplace_shared(f_n.item->f,f_n.item->level,ProjectNoisePtr,P(imu_factor_id),L(f_n.index)); - } - return true; -} bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr& new_frame){ gtsam::Values result = optimizer.optimize(); - if(debug)optimizer.print(); - // Overwrite the beginning of the preintegration for the next step. statePtr=std::make_shared(result.at(P(imu_factor_id)), result.at(V(imu_factor_id))); imu_biasPtr=std::make_shared(result.at(B(imu_factor_id))); preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr); ++imu_factor_id; syn=false; gtsam::Marginals marginals(*graphPtr,result); - if(debug)fprintf(logtime, "%f,%f,%f,%f,%f,%f,%f,%f,\n", - new_frame->T_f_w_.T->translation().x(), - new_frame->T_f_w_.T->translation().y(), - new_frame->T_f_w_.T->translation().z(), - atan(new_frame->T_f_w_.T->rotation_matrix()(0,2)/new_frame->T_f_w_.T->rotation_matrix()(0,0)), + if(debug)fprintf(logtime, "%d,%f,%f,%f,%f,\n", + imu_factor_id-1, statePtr->pose().x(), statePtr->pose().y(), statePtr->pose().z(), - atan(statePtr->R()(0,2)/statePtr->R()(0,0))); - if((statePtr->t()-new_frame->T_f_w_.T->translation()).norm()>2.0)return false; - new_frame->T_f_w_=svo::SE2_5(statePtr->t().x(),statePtr->t().z(),atan(statePtr->R()(0,2)/statePtr->R()(0,0))); + statePtr->pose().rotation().pitch()); + new_frame->T_f_w_=svo::SE2_5(statePtr->pose().x(),statePtr->pose().z(),statePtr->pose().rotation().pitch()); new_frame->Cov_=marginals.marginalCovariance(P(imu_factor_id-1)); graphPtr->resize(0); valuesPtr->clear(); - valuesPtr->insert(P(imu_factor_id-1),statePtr->pose()); + valuesPtr->insert(P(imu_factor_id-1),gtsam::Pose3(new_frame->T_f_w_.T->matrix())); valuesPtr->insert(V(imu_factor_id-1),statePtr->v()); valuesPtr->insert(B(imu_factor_id-1),*imu_biasPtr); - graphPtr->addPrior(P(imu_factor_id-1),statePtr->pose(),marginals.marginalCovariance(P(imu_factor_id-1))); + graphPtr->addPrior(P(imu_factor_id-1),gtsam::Pose3(new_frame->T_f_w_.T->matrix()),marginals.marginalCovariance(P(imu_factor_id-1))); graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),marginals.marginalCovariance(V(imu_factor_id-1))); graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,marginals.marginalCovariance(B(imu_factor_id-1))); return true; } -Sophus::SE3 Imu_Integration::preintegrate_predict() { +bool Imu_Integration::preintegrate_predict(svo::SE2_5& frame) { if(imu_n<1){ syn= false; - usleep(10000); - syn=true; + return false; }else{ syn=true; } - auto preint_imu_combined =dynamic_cast(*preintegratedPtr); - Integ_predict=preint_imu_combined.predict(*statePtr,*imu_biasPtr); - return Sophus::SE3(Integ_predict.R(),Integ_predict.t()); + Integ_predict=preintegratedPtr->predict(*statePtr,*imu_biasPtr); + frame =svo::SE2_5(Integ_predict.pose().x(),Integ_predict.pose().z(),Integ_predict.pose().rotation().pitch()); + return true; +} +void Imu_Integration::reset() { + preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr); + imu_n=0; + syn=false; } bool Imu_Integration::predict(boost::shared_ptr& new_frame, boost::shared_ptr& last_frame, - std::size_t& num_obs,const double cell_match){ - if(debug)std::cout<<"----------------------------IMU infuse---------------------------------------\n"; - //if(debug)preintegratedPtr->print(); - auto preint_imu_combined =dynamic_cast(*preintegratedPtr); + const double cell_match){ valuesPtr->insert(P(imu_factor_id), Integ_predict.pose()); valuesPtr->insert(V(imu_factor_id), Integ_predict.v()); valuesPtr->insert(B(imu_factor_id), *imu_biasPtr); gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id), - preint_imu_combined); + *preintegratedPtr); graphPtr->emplace_shared(imu_factor); imu_n=0; graphPtr->emplace_shared(gtsam::Pose3(new_frame->T_f_w_.T->matrix()), gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(3) << 1.0, 1.0, 1.0).finished()/(cell_match+1)), P(imu_factor_id)); gtsam::LevenbergMarquardtParams params0; - //params0.verbosity=gtsam::LevenbergMarquardtParams::LINEAR; params0.verbosityLM = gtsam::LevenbergMarquardtParams::SILENT; params0.setlambdaFactor(10.0); params0.setlambdaInitial(100); params0.setlambdaUpperBound(1e10); gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr,params0); reset(optimizer,new_frame); - - if(debug)std::cout<<"------------------------------------------------------------------------------\n"; return true; } bool Imu_Integration::init(boost::shared_ptr& new_frame){ statePtr=std::make_shared(gtsam::Pose3(new_frame->T_f_w_.T->matrix()), gtsam::Vector3(1e-9,1e-9,1e-9)); - /* - statePtr=std::make_shared(gtsam::Pose3(gtsam::Rot3::RzRyRx(0.0,0.0,0.0),gtsam::Point3(0.0,0.0,0.0)), - gtsam::Vector3(1e-9,1e-9,1e-9)); - */ valuesPtr->insert(P(0),statePtr->pose()); valuesPtr->insert(V(0),statePtr->v()); valuesPtr->insert(B(0),*imu_biasPtr); graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 1e-5, 1e-15, 1e-5, 1e-15, 1e-8, 1e-15).finished())); graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 1e-4)); graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-2)); - /* - for(auto&& f_n:_for(new_frame->fts_)){ - if(f_n.item->point == NULL)continue; - valuesPtr->insert(L(f_n.index),f_n.item->point->pos_); - graphPtr->emplace_shared(f_n.item->f,f_n.item->level,ProjectNoisePtr,P(imu_factor_id),L(f_n.index)); - } - graphPtr->addPrior(L(0),new_frame->fts_.front()->point->pos_,gtsam::noiseModel::Isotropic::Sigma(3, 1e-4)); - */ ++imu_factor_id; return true; } \ No newline at end of file diff --git a/GPU_version/svo/src/matcher.cpp b/GPU_version/svo/src/matcher.cpp index e4a236a..b8b9d2d 100644 --- a/GPU_version/svo/src/matcher.cpp +++ b/GPU_version/svo/src/matcher.cpp @@ -184,6 +184,7 @@ bool Matcher::findEpipolarMatchDirect( const double d_max, double& depth) { + if(isnan(d_min) || isnan(d_max))return false; SE3 T_cur_ref = (*cur_frame.T_f_w_.T) * ref_frame.T_f_w_.T->inverse(); int zmssd_best = PatchScore::threshold(); Vector2d uv_best; @@ -217,6 +218,7 @@ bool Matcher::findEpipolarMatchDirect( Vector2d px_B(cur_frame.cam_->world2cam(B)); epi_length_ = (px_A-px_B).norm() / (1<fts_.size(), patch_area_, CV_32F); jacobian_cache_.resize(Eigen::NoChange, ref_patch_cache_.rows*patch_area_); - //visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? + visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? SE3 T_cur_from_ref(*cur_frame_->T_f_w_.T * ref_frame_->T_f_w_.T->inverse()); for(level_=max_level_; level_>=min_level_; --level_) { - visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? + //visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? mu_ = 0.1; jacobian_cache_.setZero(); have_ref_patch_cache_ = false; diff --git a/GPU_version/vio/include/vio_gpu/visualizer.h b/GPU_version/vio/include/vio_gpu/visualizer.h index 0ff8834..7c09cd1 100644 --- a/GPU_version/vio/include/vio_gpu/visualizer.h +++ b/GPU_version/vio/include/vio_gpu/visualizer.h @@ -44,7 +44,7 @@ public: size_t trace_id_; ros::Publisher pub_frames_; ros::Publisher pub_points_; - ros::Publisher pub_pose_; + ros::Publisher pub_pose_with_cov_; ros::Publisher pub_info_; tf::TransformBroadcaster br_; SE3 T_world_from_vision_; diff --git a/GPU_version/vio/param/vo_fast.yaml b/GPU_version/vio/param/vo_fast.yaml index c2189bd..0aa2c15 100644 --- a/GPU_version/vio/param/vo_fast.yaml +++ b/GPU_version/vio/param/vo_fast.yaml @@ -1,13 +1,13 @@ svo: grid_size: 30 #Feature grid size of a cell in [px]. - max_n_kfs: 10 #Limit the number of keyframes in the map. This makes nslam essentially. a Visual Odometry. Set to 0 if unlimited number of keyframes are allowed. Minimum number of keyframes is 3. + max_n_kfs: 20 #Limit the number of keyframes in the map. This makes nslam essentially. a Visual Odometry. Set to 0 if unlimited number of keyframes are allowed. Minimum number of keyframes is 3. loba_num_iter: 0 #Number of iterations in the local bundle adjustment. quality_min_fts: 10 #If the number of tracked features drops below this threshold. Tracking quality is bad. quality_max_drop_fts: 60 #If within one frame, this amount of features are dropped. Tracking quality is bad. init_min_tracked: 100 - init_min_disparity: 25 + init_min_disparity: 20 structureoptim_max_pts: 50 - kfselect_mindist: 0.12 + kfselect_mindist: 0.05 poseoptim_thresh: 4.0 ACC_noise: 0.0001 #acc white noise in continuous GYO_noise: 0.0001 #gyro white noise in continuous @@ -17,6 +17,6 @@ svo: EBP: 0.1 #error in the bias used for preintegration NRP: 0.001 #noise used for projection in preintegration gravity: -9.65 - Acceleration_offset_x: 0.0 #-0.05 - Acceleration_offset_y: 0.0 #-0.04 - Gyroscope_offset_z: 0.0 #0.001 + Acceleration_offset_x: 0.0 + Acceleration_offset_y: 0.0 + Gyroscope_offset_z: 0.0 diff --git a/GPU_version/vio/src/visualizer.cpp b/GPU_version/vio/src/visualizer.cpp index 3d58393..75047cc 100644 --- a/GPU_version/vio/src/visualizer.cpp +++ b/GPU_version/vio/src/visualizer.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -35,8 +36,8 @@ Visualizer() : { // Init ROS Marker Publishers //pub_frames_ = pnh_.advertise("keyframes", 10); - // pub_points_ = pnh_.advertise("points", 1000); - pub_pose_ = pnh_.advertise("pose",10); + pub_points_ = pnh_.advertise("points", 1000); + pub_pose_with_cov_ = pnh_.advertise("pose_cov",10); } void Visualizer::publishMinimal( @@ -50,28 +51,31 @@ void Visualizer::publishMinimal( header_msg.frame_id = "/world"; header_msg.seq = trace_id_; header_msg.stamp = ros::Time(timestamp); - if(pub_pose_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) + if(pub_pose_with_cov_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) { - Quaterniond q; - Vector3d p; + //Quaterniond q; Matrix Cov; // publish cam in world frame (Estimated odometry in the worls frame) SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.T->inverse());// do not confused with inverse. the T_f_w_ is the from camera to initial position with reference of camera //q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); - //p = T_world_from_cam.translation(); Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj(); - geometry_msgs::PoseWithCovarianceStampedPtr msg_pose(new geometry_msgs::PoseWithCovarianceStamped); - msg_pose->header = header_msg; - msg_pose->pose.pose.position.x = p[0]; - msg_pose->pose.pose.position.y = p[1]; - msg_pose->pose.pose.position.z = p[2]; - msg_pose->pose.pose.orientation.x = q.x()/q.norm(); - msg_pose->pose.pose.orientation.y = q.y()/q.norm(); - msg_pose->pose.pose.orientation.z = q.z()/q.norm(); - msg_pose->pose.pose.orientation.w = q.w()/q.norm(); + geometry_msgs::PoseWithCovarianceStampedPtr msg_pose_with_cov(new geometry_msgs::PoseWithCovarianceStamped); + msg_pose_with_cov->header = header_msg; + msg_pose_with_cov->pose.pose.position.x = T_world_from_cam.translation().x(); + msg_pose_with_cov->pose.pose.position.y = T_world_from_cam.translation().y(); + msg_pose_with_cov->pose.pose.position.z = T_world_from_cam.translation().z(); + msg_pose_with_cov->pose.pose.orientation.x = frame->T_f_w_.T->unit_quaternion().x()/frame->T_f_w_.T->unit_quaternion().norm(); + msg_pose_with_cov->pose.pose.orientation.y = frame->T_f_w_.T->unit_quaternion().y()/frame->T_f_w_.T->unit_quaternion().norm(); + msg_pose_with_cov->pose.pose.orientation.z = frame->T_f_w_.T->unit_quaternion().z()/frame->T_f_w_.T->unit_quaternion().norm(); + msg_pose_with_cov->pose.pose.orientation.w = frame->T_f_w_.T->unit_quaternion().w()/frame->T_f_w_.T->unit_quaternion().norm(); for(size_t i=0; i<36; ++i) - msg_pose->pose.covariance[i] = Cov(i%6, i/6); - pub_pose_.publish(msg_pose); + msg_pose_with_cov->pose.covariance[i] = Cov(i%6, i/6); + pub_pose_with_cov_.publish(msg_pose_with_cov); + } + if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0){ + vk::output_helper::publishPointMarker( + pub_points_, T_world_from_vision_*frame->pos(), "trajectory", + ros::Time::now(), trace_id_, 0, 0.01, Vector3d(0.,0.,0.5)); } } From 5fdc0c19d5e4f9831aa6d3cc567e0f49b57f4569 Mon Sep 17 00:00:00 2001 From: Majid Geravand <44868211+Gfuse@users.noreply.github.com> Date: Mon, 7 Jun 2021 08:32:49 +0200 Subject: [PATCH 203/215] Update README.md --- GPU_version/README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/GPU_version/README.md b/GPU_version/README.md index 00b6d87..0db9f73 100755 --- a/GPU_version/README.md +++ b/GPU_version/README.md @@ -1,7 +1,7 @@ SVO === -This code implements a semi-direct monocular visual odometry pipeline which has been integrated with GTSAM to infused IMU as well. +This code implements a semi-direct monocular visual odometry pipeline which has been integrated with GTSAM to infused IMU as well. The feature extraction part is implemented in OpenCL to take advantage of GPU. Paper svo: http://rpg.ifi.uzh.ch/docs/ICRA14_Forster.pdf @@ -31,15 +31,21 @@ If you use SVO in an academic context, please cite the following publication: #### Documentation - +OpenCL documentation The API is documented here: http://uzh-rpg.github.io/rpg_svo/doc/ The GTSAM documentation https://gtsam.org/tutorials/ #### Instructions +Please be sure that you have the OpenCL driver installed +First install gtsam library => https://github.com/borglab/gtsam + +Then follow the SVO instalation See the Wiki for more instructions. https://github.com/uzh-rpg/rpg_svo/wiki and https://gtsam.org/get_started/ -#### Contributing -You are very welcome to contribute to SVO by opening a pull request via Github. -I try to follow the ROS C++ style guide http://wiki.ros.org/CppStyleGuide +## Setting + +You can edit the algorithm parameters in the follwoing file, please look at the config file to underestand the meaning of the parameters (CPU_version/svo/include/svo/config.h) + +CPU_version/vio_svo/param/vo_fast.yaml From 8cce4040736599e0d08f1021b053d732e68bbb85 Mon Sep 17 00:00:00 2001 From: gfuse Date: Mon, 7 Jun 2021 09:48:47 +0200 Subject: [PATCH 204/215] Edit visual --- GPU_version/svo/include/gpu_svo/global.h | 3 +- GPU_version/svo/src/imu_integration.cpp | 12 ++------ GPU_version/svo/src/initialization.cpp | 3 +- GPU_version/svo/src/map.cpp | 3 +- GPU_version/vio/src/visualizer.cpp | 35 ++++++++++++++---------- 5 files changed, 29 insertions(+), 27 deletions(-) diff --git a/GPU_version/svo/include/gpu_svo/global.h b/GPU_version/svo/include/gpu_svo/global.h index a307503..2cfd63b 100644 --- a/GPU_version/svo/include/gpu_svo/global.h +++ b/GPU_version/svo/include/gpu_svo/global.h @@ -65,7 +65,8 @@ namespace svo void set(){ X_=T->translation().x(); Z_=T->translation().z(); - tetha_=atan(T->matrix()(0,2)/T->matrix()(0,0)); + tetha_=asin(2*(T->unit_quaternion().w()*T->unit_quaternion().y()- + T->unit_quaternion().z()*T->unit_quaternion().x())); cos_theta_=cos(tetha_); sin_theta_=sin(tetha_); } diff --git a/GPU_version/svo/src/imu_integration.cpp b/GPU_version/svo/src/imu_integration.cpp index 20d06f0..f7d47a2 100644 --- a/GPU_version/svo/src/imu_integration.cpp +++ b/GPU_version/svo/src/imu_integration.cpp @@ -15,17 +15,11 @@ #include #include #include -#define debug 1 +#define debug 0 Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){ graphPtr=std::make_shared(); valuesPtr=std::make_shared(); - // Example: pitch and roll of aircraft in an ENU Cartesian frame. - // If pitch and roll are zero for an aerospace frame, - // that means Z is pointing down, i.e., direction of Z = (0,0,-1) - //gtsam::Vector4 g=SE_init.matrix()*gtsam::Vector4(0, 0, svo::Config::Gravity(),1.0); - //parameterPtr = boost::shared_ptr(new gtsam::PreintegrationCombinedParams(gtsam::Vector3(g.x(),g.y(),g.z()))); parameterPtr = boost::shared_ptr(new gtsam::PreintegrationCombinedParams(gtsam::Vector3(0.0,0.0,0.0))); - //parameterPtr->setBodyPSensor(gtsam::Pose3(SE_init.matrix()));// The pose of the sensor in the body frame parameterPtr->accelerometerCovariance=gtsam::I_3x3 * svo::Config::ACC_Noise(); // acc white noise in continuous parameterPtr->gyroscopeCovariance=gtsam::I_3x3 * svo::Config::GYO_Noise();// gyro white noise in continuous parameterPtr->integrationCovariance=gtsam::I_3x3 * svo::Config::IUC(); // integration uncertainty continuous @@ -49,8 +43,8 @@ Imu_Integration::~Imu_Integration(){ bool Imu_Integration::update(double* imu){ if(syn)return false; if(imu_factor_id<1)return false; - if(abs(imu[0])<1.0)imu[0]=pow(imu[0],3); - if(abs(imu[1])<1.0)imu[0]=pow(imu[1],3); + if(abs(imu[0])<1.0)imu[0]=pow(imu[0],3);//picked up from your code + if(abs(imu[1])<1.0)imu[0]=pow(imu[1],3);//picked up from your code auto in=std::chrono::steady_clock::now(); if(std::chrono::duration(in-t_1).count()>20.0){ t_1=in; diff --git a/GPU_version/svo/src/initialization.cpp b/GPU_version/svo/src/initialization.cpp index 1681a9e..6d54a36 100644 --- a/GPU_version/svo/src/initialization.cpp +++ b/GPU_version/svo/src/initialization.cpp @@ -70,7 +70,8 @@ InitResult KltHomographyInit::addSecondFrame(FramePtr frame_cur) double scene_depth_median = vk::getMedian(depth_vec); double scale = Config::mapScale()/scene_depth_median; SE3 tem=T_cur_from_ref_ * (*frame_ref_->T_f_w_.T); - frame_cur->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),atan(tem.rotation_matrix()(0,2)/tem.rotation_matrix()(0,0))); + frame_cur->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),asin(2*(tem.unit_quaternion().w()*tem.unit_quaternion().y()- + tem.unit_quaternion().z()*tem.unit_quaternion().x()))); tem.translation() = -frame_cur->T_f_w_.T->rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); frame_cur->T_f_w_.X_ = tem.translation().x(); frame_cur->T_f_w_.Z_ = tem.translation().z(); diff --git a/GPU_version/svo/src/map.cpp b/GPU_version/svo/src/map.cpp index e46f9b0..6b27b1c 100644 --- a/GPU_version/svo/src/map.cpp +++ b/GPU_version/svo/src/map.cpp @@ -179,7 +179,8 @@ void Map::transform(const Matrix3d& R, const Vector3d& t, const double& s) Vector3d pos = s*R*(*it)->pos() + t; Matrix3d rot = R*(*it)->T_f_w_.T->rotation_matrix().inverse(); SE3 inv=SE3(rot, pos).inverse(); - (*it)->T_f_w_ = SE2_5(inv.translation().x(),inv.translation().z(),atan(inv.rotation_matrix()(0,2)/inv.rotation_matrix()(0,0))); + (*it)->T_f_w_ = SE2_5(inv.translation().x(),inv.translation().z(),asin(2*(inv.unit_quaternion().w()*inv.unit_quaternion().y()- + inv.unit_quaternion().z()*inv.unit_quaternion().x()))); for(auto ftr=(*it)->fts_.begin(); ftr!=(*it)->fts_.end(); ++ftr) { if((*ftr)->point == NULL) diff --git a/GPU_version/vio/src/visualizer.cpp b/GPU_version/vio/src/visualizer.cpp index 75047cc..b7f860f 100644 --- a/GPU_version/vio/src/visualizer.cpp +++ b/GPU_version/vio/src/visualizer.cpp @@ -53,30 +53,35 @@ void Visualizer::publishMinimal( header_msg.stamp = ros::Time(timestamp); if(pub_pose_with_cov_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) { - //Quaterniond q; Matrix Cov; // publish cam in world frame (Estimated odometry in the worls frame) - SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.T->inverse());// do not confused with inverse. the T_f_w_ is the from camera to initial position with reference of camera - //q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose()); + SE3 T_world_from_cam(frame->T_f_w_.T->inverse());// do not confused with inverse. the T_f_w_ is the from camera to initial position with reference of camera + double yaw=asin(2*(frame->T_f_w_.T->unit_quaternion().w()*frame->T_f_w_.T->unit_quaternion().y()- + frame->T_f_w_.T->unit_quaternion().z()*frame->T_f_w_.T->unit_quaternion().x())); + Quaterniond q; + q = AngleAxisd(0.0, Vector3d::UnitX()) + * AngleAxisd(0.0, Vector3d::UnitY()) + * AngleAxisd(yaw-1.5708, Vector3d::UnitZ()); Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj(); geometry_msgs::PoseWithCovarianceStampedPtr msg_pose_with_cov(new geometry_msgs::PoseWithCovarianceStamped); msg_pose_with_cov->header = header_msg; - msg_pose_with_cov->pose.pose.position.x = T_world_from_cam.translation().x(); - msg_pose_with_cov->pose.pose.position.y = T_world_from_cam.translation().y(); - msg_pose_with_cov->pose.pose.position.z = T_world_from_cam.translation().z(); - msg_pose_with_cov->pose.pose.orientation.x = frame->T_f_w_.T->unit_quaternion().x()/frame->T_f_w_.T->unit_quaternion().norm(); - msg_pose_with_cov->pose.pose.orientation.y = frame->T_f_w_.T->unit_quaternion().y()/frame->T_f_w_.T->unit_quaternion().norm(); - msg_pose_with_cov->pose.pose.orientation.z = frame->T_f_w_.T->unit_quaternion().z()/frame->T_f_w_.T->unit_quaternion().norm(); - msg_pose_with_cov->pose.pose.orientation.w = frame->T_f_w_.T->unit_quaternion().w()/frame->T_f_w_.T->unit_quaternion().norm(); + msg_pose_with_cov->pose.pose.position.x = -1.0*T_world_from_cam.translation().x(); + msg_pose_with_cov->pose.pose.position.y = -1.0*T_world_from_cam.translation().z(); + msg_pose_with_cov->pose.pose.position.z = 0.0; + msg_pose_with_cov->pose.pose.orientation.x = q.x()/q.norm(); + msg_pose_with_cov->pose.pose.orientation.y = q.y()/q.norm(); + msg_pose_with_cov->pose.pose.orientation.z = q.z()/q.norm(); + msg_pose_with_cov->pose.pose.orientation.w = q.w()/q.norm(); for(size_t i=0; i<36; ++i) msg_pose_with_cov->pose.covariance[i] = Cov(i%6, i/6); pub_pose_with_cov_.publish(msg_pose_with_cov); + if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0){ + vk::output_helper::publishPointMarker( + pub_points_, Eigen::Vector3d(-1.0*T_world_from_cam.translation().x(),-1.0*T_world_from_cam.translation().z(),0.0), "trajectory", + ros::Time::now(), trace_id_, 0, 0.01, Vector3d(0.,0.,0.5)); + } } - if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0){ - vk::output_helper::publishPointMarker( - pub_points_, T_world_from_vision_*frame->pos(), "trajectory", - ros::Time::now(), trace_id_, 0, 0.01, Vector3d(0.,0.,0.5)); - } + } void Visualizer::visualizeMarkers( From 30d06fd72762b4e09d7762dd04dc4e76a45b0e61 Mon Sep 17 00:00:00 2001 From: Majid Geravand <44868211+Gfuse@users.noreply.github.com> Date: Mon, 7 Jun 2021 09:56:36 +0200 Subject: [PATCH 205/215] Update README.md --- GPU_version/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GPU_version/README.md b/GPU_version/README.md index 0db9f73..53d8c38 100755 --- a/GPU_version/README.md +++ b/GPU_version/README.md @@ -32,11 +32,14 @@ If you use SVO in an academic context, please cite the following publication: #### Documentation OpenCL documentation + The API is documented here: http://uzh-rpg.github.io/rpg_svo/doc/ + The GTSAM documentation https://gtsam.org/tutorials/ #### Instructions Please be sure that you have the OpenCL driver installed + First install gtsam library => https://github.com/borglab/gtsam Then follow the SVO instalation From 901fbb14e88850b4d5ae1ef4e001c9c68ada6dd7 Mon Sep 17 00:00:00 2001 From: gfuse Date: Tue, 29 Jun 2021 07:51:42 +0200 Subject: [PATCH 206/215] new version under progress --- GPU_version/README.md | 15 + GPU_version/svo/.idea/.gitignore | 8 - GPU_version/svo/.idea/.name | 1 - GPU_version/svo/.idea/misc.xml | 4 - GPU_version/svo/.idea/modules.xml | 8 - GPU_version/svo/.idea/vcs.xml | 7 - GPU_version/svo/CMakeLists.txt | 99 - GPU_version/svo/package.xml | 27 - GPU_version/svo/src/bundle_adjustment.cpp | 435 - GPU_version/vio/.idea/.name | 2 +- GPU_version/vio/.idea/modules.xml | 2 +- GPU_version/{svo => vio}/.idea/svo.iml | 0 GPU_version/vio/.idea/svo_ros.iml | 2 - GPU_version/vio/CMakeLists.txt | 100 +- .../{svo => vio}/CMakeModules/FindEigen.cmake | 0 .../{svo => vio}/CMakeModules/FindG2O.cmake | 0 GPU_version/{svo => vio}/Doxyfile | 0 .../vio/cmake-build-debug/CATKIN_IGNORE | 0 .../vio/cmake-build-debug/CMakeCache.txt | 785 + .../CMakeFiles/3.17.5/CMakeCCompiler.cmake | 76 + .../CMakeFiles/3.17.5/CMakeCXXCompiler.cmake | 88 + .../3.17.5/CMakeDetermineCompilerABI_C.bin | Bin 0 -> 8248 bytes .../3.17.5/CMakeDetermineCompilerABI_CXX.bin | Bin 0 -> 8264 bytes .../CMakeFiles/3.17.5/CMakeSystem.cmake | 15 + .../3.17.5/CompilerIdC/CMakeCCompilerId.c | 671 + .../CMakeFiles/3.17.5/CompilerIdC/a.out | Bin 0 -> 8408 bytes .../CompilerIdCXX/CMakeCXXCompilerId.cpp | 660 + .../CMakeFiles/3.17.5/CompilerIdCXX/a.out | Bin 0 -> 8416 bytes .../CMakeFiles/CMakeError.log | 65 + .../CMakeFiles/CMakeOutput.log | 522 + .../CMakeFiles/clion-environment.txt | 3 + .../CMakeFiles/clion-log.txt | 70 + .../CMakeFiles/cmake.check_cache | 1 + .../cmake-build-debug/CTestConfiguration.ini | 107 + .../vio/cmake-build-debug/CTestCustom.cmake | 2 + .../atomic_configure/.rosinstall | 2 + .../atomic_configure/_setup_util.py | 304 + .../cmake-build-debug/atomic_configure/env.sh | 16 + .../atomic_configure/local_setup.bash | 8 + .../atomic_configure/local_setup.sh | 9 + .../atomic_configure/local_setup.zsh | 8 + .../atomic_configure/setup.bash | 8 + .../atomic_configure/setup.sh | 96 + .../atomic_configure/setup.zsh | 8 + .../catkin_generated/version/package.cmake | 24 + .../catkin_generated/env_cached.sh | 16 + .../catkin_generated/generate_cached_setup.py | 30 + .../catkin_generated/installspace/.rosinstall | 2 + .../installspace/_setup_util.py | 304 + .../catkin_generated/installspace/env.sh | 16 + .../installspace/local_setup.bash | 8 + .../installspace/local_setup.sh | 9 + .../installspace/local_setup.zsh | 8 + .../catkin_generated/installspace/setup.bash | 8 + .../catkin_generated/installspace/setup.sh | 96 + .../catkin_generated/installspace/setup.zsh | 8 + .../catkin_generated/setup_cached.sh | 13 + .../stamps/vio/_setup_util.py.stamp | 304 + .../vio/interrogate_setup_dot_py.py.stamp | 255 + .../stamps/vio/package.xml.stamp | 48 + .../vio/cmake-build-debug/devel/.catkin | 1 + .../vio/cmake-build-debug/devel/.rosinstall | 2 + .../cmake-build-debug/devel/_setup_util.py | 304 + .../vio/cmake-build-debug/devel/cmake.lock | 0 .../vio/cmake-build-debug/devel/env.sh | 16 + .../cmake-build-debug/devel/local_setup.bash | 8 + .../cmake-build-debug/devel/local_setup.sh | 9 + .../cmake-build-debug/devel/local_setup.zsh | 8 + .../vio/cmake-build-debug/devel/setup.bash | 8 + .../vio/cmake-build-debug/devel/setup.sh | 96 + .../vio/cmake-build-debug/devel/setup.zsh | 8 + GPU_version/{svo => vio}/doc/.gitignore | 0 GPU_version/{svo => vio}/doc/notation.ipe | 0 GPU_version/{svo => vio}/doc/notation.pdf | Bin GPU_version/{svo => vio}/doc/notation.png | Bin .../src => vio/gtsam}/imu_integration.cpp | 12 +- .../gpu_svo => vio/gtsam}/imu_integration.h | 0 .../gpu_svo => vio/gtsam}/svoVisionFactor.h | 4 +- .../gtsam}/svoVisionFactorLandMark.h | 0 .../gtsam}/svoVisionFactorSmall.h | 0 .../include/gpu_svo/abstract_camera.h | 0 .../include/gpu_svo/aligned_mem.h | 0 .../include/gpu_svo/atan_camera.h | 0 .../include/gpu_svo/bundle_adjustment.h | 0 .../{vio_gpu => gpu_svo}/camera_loader.h | 0 .../{svo => vio}/include/gpu_svo/cl.hpp | 0 .../{svo => vio}/include/gpu_svo/cl_class.h | 0 .../{svo => vio}/include/gpu_svo/config.h | 11 +- .../include/gpu_svo/depth_filter.h | 0 .../{svo => vio}/include/gpu_svo/feature.h | 0 .../include/gpu_svo/feature_alignment.h | 0 .../include/gpu_svo/feature_detection.h | 0 .../{svo => vio}/include/gpu_svo/for_it.hpp | 0 .../{svo => vio}/include/gpu_svo/frame.h | 67 +- .../include/gpu_svo/frame_handler_base.h | 0 .../include/gpu_svo/frame_handler_mono.h | 13 +- .../{svo => vio}/include/gpu_svo/global.h | 63 +- .../{svo => vio}/include/gpu_svo/homography.h | 0 .../include/gpu_svo/initialization.h | 8 +- .../{svo => vio}/include/gpu_svo/map.h | 4 +- .../{svo => vio}/include/gpu_svo/matcher.h | 0 .../{svo => vio}/include/gpu_svo/math_utils.h | 0 .../include/gpu_svo/nlls_solver.h | 0 .../include/gpu_svo/nlls_solver_impl.hpp | 73 +- .../{vio_gpu => gpu_svo}/output_helper.h | 7 - .../include/gpu_svo/params_helper.h | 0 .../include/gpu_svo/patch_score.h | 0 .../{svo => vio}/include/gpu_svo/point.h | 2 +- .../include/gpu_svo/pose_optimizer.h | 0 .../include/gpu_svo/reprojector.h | 0 .../include/gpu_svo/robust_cost.h | 0 .../include/gpu_svo/sparse_img_align.h | 13 +- .../{svo => vio}/include/gpu_svo/timer.h | 0 GPU_version/vio/include/gpu_svo/ukf.h | 136 + .../{svo => vio}/include/gpu_svo/vision.h | 0 .../include/{vio_gpu => gpu_svo}/visualizer.h | 0 .../vio/include/vio_gpu/params_helper.h | 54 - GPU_version/{svo => vio}/kernel/fast-gray.cl | 0 GPU_version/vio/launch/Px30.launch | 18 +- GPU_version/vio/out.txt | 26087 ++++++++++++++++ GPU_version/vio/package.xml | 25 +- GPU_version/vio/param/px30.yaml | 17 +- GPU_version/vio/param/vo_fast.yaml | 17 +- GPU_version/vio/rqt.perspective | 293 - GPU_version/vio/rviz_config.rviz | 153 - GPU_version/{svo => vio}/src/atan_camera.cpp | 0 GPU_version/{svo => vio}/src/cl_class.cpp | 0 GPU_version/{svo => vio}/src/config.cpp | 5 +- GPU_version/{svo => vio}/src/depth_filter.cpp | 52 +- .../{svo => vio}/src/feature_alignment.cpp | 4 +- .../{svo => vio}/src/feature_detection.cpp | 0 GPU_version/{svo => vio}/src/frame.cpp | 4 +- .../{svo => vio}/src/frame_handler_base.cpp | 0 .../{svo => vio}/src/frame_handler_mono.cpp | 84 +- GPU_version/{svo => vio}/src/homography.cpp | 0 .../{svo => vio}/src/initialization.cpp | 18 +- GPU_version/{svo => vio}/src/map.cpp | 24 +- GPU_version/{svo => vio}/src/matcher.cpp | 11 +- GPU_version/{svo => vio}/src/math_utils.cpp | 0 GPU_version/vio/src/output_helper.cpp | 7 +- GPU_version/{svo => vio}/src/point.cpp | 17 +- .../{svo => vio}/src/pose_optimizer.cpp | 49 +- GPU_version/{svo => vio}/src/reprojector.cpp | 3 +- GPU_version/{svo => vio}/src/robust_cost.cpp | 0 .../{svo => vio}/src/sparse_img_align.cpp | 37 +- GPU_version/{svo => vio}/src/vision.cpp | 2 +- GPU_version/vio/src/visualizer.cpp | 49 +- GPU_version/vio/src/vo_node.cpp | 119 +- GPU_version/{svo => vio}/test/README.md | 0 GPU_version/{svo => vio}/test/benchmark.csv | 0 GPU_version/{svo => vio}/test/data/.gitignore | 0 .../{svo => vio}/test/results/.gitignore | 0 .../{svo => vio}/test/test_depth_filter.cpp | 0 .../test/test_feature_alignment.cpp | 0 .../test/test_feature_detection.cpp | 0 .../{svo => vio}/test/test_matcher.cpp | 0 .../{svo => vio}/test/test_pipeline.cpp | 0 .../{svo => vio}/test/test_pose_optimizer.cpp | 0 .../test/test_sparse_img_align.cpp | 0 GPU_version/{svo => vio}/test/test_utils.h | 0 160 files changed, 31877 insertions(+), 1528 deletions(-) delete mode 100644 GPU_version/svo/.idea/.gitignore delete mode 100644 GPU_version/svo/.idea/.name delete mode 100644 GPU_version/svo/.idea/misc.xml delete mode 100644 GPU_version/svo/.idea/modules.xml delete mode 100644 GPU_version/svo/.idea/vcs.xml delete mode 100644 GPU_version/svo/CMakeLists.txt delete mode 100644 GPU_version/svo/package.xml delete mode 100644 GPU_version/svo/src/bundle_adjustment.cpp rename GPU_version/{svo => vio}/.idea/svo.iml (100%) delete mode 100644 GPU_version/vio/.idea/svo_ros.iml mode change 100644 => 100755 GPU_version/vio/CMakeLists.txt rename GPU_version/{svo => vio}/CMakeModules/FindEigen.cmake (100%) rename GPU_version/{svo => vio}/CMakeModules/FindG2O.cmake (100%) rename GPU_version/{svo => vio}/Doxyfile (100%) mode change 100644 => 100755 create mode 100644 GPU_version/vio/cmake-build-debug/CATKIN_IGNORE create mode 100644 GPU_version/vio/cmake-build-debug/CMakeCache.txt create mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCCompiler.cmake create mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCXXCompiler.cmake create mode 100755 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_C.bin create mode 100755 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_CXX.bin create mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeSystem.cmake create mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdC/CMakeCCompilerId.c create mode 100755 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdC/a.out create mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/CMakeCXXCompilerId.cpp create mode 100755 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/a.out create mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeError.log create mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeOutput.log create mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/clion-environment.txt create mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/clion-log.txt create mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/cmake.check_cache create mode 100644 GPU_version/vio/cmake-build-debug/CTestConfiguration.ini create mode 100644 GPU_version/vio/cmake-build-debug/CTestCustom.cmake create mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/.rosinstall create mode 100755 GPU_version/vio/cmake-build-debug/atomic_configure/_setup_util.py create mode 100755 GPU_version/vio/cmake-build-debug/atomic_configure/env.sh create mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.bash create mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.sh create mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.zsh create mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/setup.bash create mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/setup.sh create mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/setup.zsh create mode 100644 GPU_version/vio/cmake-build-debug/catkin/catkin_generated/version/package.cmake create mode 100755 GPU_version/vio/cmake-build-debug/catkin_generated/env_cached.sh create mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/generate_cached_setup.py create mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/.rosinstall create mode 100755 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/_setup_util.py create mode 100755 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/env.sh create mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.bash create mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.sh create mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.zsh create mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.bash create mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.sh create mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.zsh create mode 100755 GPU_version/vio/cmake-build-debug/catkin_generated/setup_cached.sh create mode 100755 GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/_setup_util.py.stamp create mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/interrogate_setup_dot_py.py.stamp create mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/package.xml.stamp create mode 100644 GPU_version/vio/cmake-build-debug/devel/.catkin create mode 100644 GPU_version/vio/cmake-build-debug/devel/.rosinstall create mode 100755 GPU_version/vio/cmake-build-debug/devel/_setup_util.py create mode 100644 GPU_version/vio/cmake-build-debug/devel/cmake.lock create mode 100755 GPU_version/vio/cmake-build-debug/devel/env.sh create mode 100644 GPU_version/vio/cmake-build-debug/devel/local_setup.bash create mode 100644 GPU_version/vio/cmake-build-debug/devel/local_setup.sh create mode 100644 GPU_version/vio/cmake-build-debug/devel/local_setup.zsh create mode 100644 GPU_version/vio/cmake-build-debug/devel/setup.bash create mode 100644 GPU_version/vio/cmake-build-debug/devel/setup.sh create mode 100644 GPU_version/vio/cmake-build-debug/devel/setup.zsh rename GPU_version/{svo => vio}/doc/.gitignore (100%) rename GPU_version/{svo => vio}/doc/notation.ipe (100%) rename GPU_version/{svo => vio}/doc/notation.pdf (100%) rename GPU_version/{svo => vio}/doc/notation.png (100%) rename GPU_version/{svo/src => vio/gtsam}/imu_integration.cpp (94%) mode change 100644 => 100755 rename GPU_version/{svo/include/gpu_svo => vio/gtsam}/imu_integration.h (100%) rename GPU_version/{svo/include/gpu_svo => vio/gtsam}/svoVisionFactor.h (97%) rename GPU_version/{svo/include/gpu_svo => vio/gtsam}/svoVisionFactorLandMark.h (100%) rename GPU_version/{svo/include/gpu_svo => vio/gtsam}/svoVisionFactorSmall.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/abstract_camera.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/aligned_mem.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/atan_camera.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/bundle_adjustment.h (100%) rename GPU_version/vio/include/{vio_gpu => gpu_svo}/camera_loader.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/cl.hpp (100%) rename GPU_version/{svo => vio}/include/gpu_svo/cl_class.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/config.h (94%) rename GPU_version/{svo => vio}/include/gpu_svo/depth_filter.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/feature.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/feature_alignment.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/feature_detection.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/for_it.hpp (100%) rename GPU_version/{svo => vio}/include/gpu_svo/frame.h (72%) rename GPU_version/{svo => vio}/include/gpu_svo/frame_handler_base.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/frame_handler_mono.h (91%) rename GPU_version/{svo => vio}/include/gpu_svo/global.h (51%) rename GPU_version/{svo => vio}/include/gpu_svo/homography.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/initialization.h (91%) rename GPU_version/{svo => vio}/include/gpu_svo/map.h (97%) rename GPU_version/{svo => vio}/include/gpu_svo/matcher.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/math_utils.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/nlls_solver.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/nlls_solver_impl.hpp (79%) rename GPU_version/vio/include/{vio_gpu => gpu_svo}/output_helper.h (97%) rename GPU_version/{svo => vio}/include/gpu_svo/params_helper.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/patch_score.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/point.h (98%) rename GPU_version/{svo => vio}/include/gpu_svo/pose_optimizer.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/reprojector.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/robust_cost.h (100%) rename GPU_version/{svo => vio}/include/gpu_svo/sparse_img_align.h (88%) rename GPU_version/{svo => vio}/include/gpu_svo/timer.h (100%) create mode 100644 GPU_version/vio/include/gpu_svo/ukf.h rename GPU_version/{svo => vio}/include/gpu_svo/vision.h (100%) rename GPU_version/vio/include/{vio_gpu => gpu_svo}/visualizer.h (100%) delete mode 100644 GPU_version/vio/include/vio_gpu/params_helper.h rename GPU_version/{svo => vio}/kernel/fast-gray.cl (100%) create mode 100644 GPU_version/vio/out.txt mode change 100644 => 100755 GPU_version/vio/package.xml delete mode 100644 GPU_version/vio/rqt.perspective delete mode 100644 GPU_version/vio/rviz_config.rviz rename GPU_version/{svo => vio}/src/atan_camera.cpp (100%) rename GPU_version/{svo => vio}/src/cl_class.cpp (100%) rename GPU_version/{svo => vio}/src/config.cpp (96%) rename GPU_version/{svo => vio}/src/depth_filter.cpp (90%) rename GPU_version/{svo => vio}/src/feature_alignment.cpp (99%) rename GPU_version/{svo => vio}/src/feature_detection.cpp (100%) rename GPU_version/{svo => vio}/src/frame.cpp (95%) rename GPU_version/{svo => vio}/src/frame_handler_base.cpp (100%) rename GPU_version/{svo => vio}/src/frame_handler_mono.cpp (81%) rename GPU_version/{svo => vio}/src/homography.cpp (100%) rename GPU_version/{svo => vio}/src/initialization.cpp (91%) rename GPU_version/{svo => vio}/src/map.cpp (92%) rename GPU_version/{svo => vio}/src/matcher.cpp (95%) rename GPU_version/{svo => vio}/src/math_utils.cpp (100%) rename GPU_version/{svo => vio}/src/point.cpp (84%) rename GPU_version/{svo => vio}/src/pose_optimizer.cpp (74%) rename GPU_version/{svo => vio}/src/reprojector.cpp (98%) rename GPU_version/{svo => vio}/src/robust_cost.cpp (100%) rename GPU_version/{svo => vio}/src/sparse_img_align.cpp (88%) rename GPU_version/{svo => vio}/src/vision.cpp (99%) rename GPU_version/{svo => vio}/test/README.md (100%) rename GPU_version/{svo => vio}/test/benchmark.csv (100%) rename GPU_version/{svo => vio}/test/data/.gitignore (100%) rename GPU_version/{svo => vio}/test/results/.gitignore (100%) rename GPU_version/{svo => vio}/test/test_depth_filter.cpp (100%) rename GPU_version/{svo => vio}/test/test_feature_alignment.cpp (100%) rename GPU_version/{svo => vio}/test/test_feature_detection.cpp (100%) rename GPU_version/{svo => vio}/test/test_matcher.cpp (100%) rename GPU_version/{svo => vio}/test/test_pipeline.cpp (100%) rename GPU_version/{svo => vio}/test/test_pose_optimizer.cpp (100%) rename GPU_version/{svo => vio}/test/test_sparse_img_align.cpp (100%) rename GPU_version/{svo => vio}/test/test_utils.h (100%) diff --git a/GPU_version/README.md b/GPU_version/README.md index 0db9f73..d429f6c 100755 --- a/GPU_version/README.md +++ b/GPU_version/README.md @@ -49,3 +49,18 @@ See the Wiki for more instructions. https://github.com/uzh-rpg/rpg_svo/wiki and You can edit the algorithm parameters in the follwoing file, please look at the config file to underestand the meaning of the parameters (CPU_version/svo/include/svo/config.h) CPU_version/vio_svo/param/vo_fast.yaml + +# the GPU_version + +Dose not have dependency with GTSAM, the dependencies are: +1. OpenCV 3 +2. Eigen +3. Sophus https://github.com/strasdat/Sophus.git +4. Boost +5. OpenCL + +if make fails in the build of Sophus with the error lvalue required as left operand of assignment in so2.cpp, see this issue: https://github.com/uzh-rpg/rpg_svo/issues/237 + + + + diff --git a/GPU_version/svo/.idea/.gitignore b/GPU_version/svo/.idea/.gitignore deleted file mode 100644 index 73f69e0..0000000 --- a/GPU_version/svo/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/GPU_version/svo/.idea/.name b/GPU_version/svo/.idea/.name deleted file mode 100644 index 4b0f94b..0000000 --- a/GPU_version/svo/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -gpu_svo \ No newline at end of file diff --git a/GPU_version/svo/.idea/misc.xml b/GPU_version/svo/.idea/misc.xml deleted file mode 100644 index 79b3c94..0000000 --- a/GPU_version/svo/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/GPU_version/svo/.idea/modules.xml b/GPU_version/svo/.idea/modules.xml deleted file mode 100644 index 4c8cf2b..0000000 --- a/GPU_version/svo/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/GPU_version/svo/.idea/vcs.xml b/GPU_version/svo/.idea/vcs.xml deleted file mode 100644 index 64713b8..0000000 --- a/GPU_version/svo/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/GPU_version/svo/CMakeLists.txt b/GPU_version/svo/CMakeLists.txt deleted file mode 100644 index ac021d6..0000000 --- a/GPU_version/svo/CMakeLists.txt +++ /dev/null @@ -1,99 +0,0 @@ -SET(PROJECT_NAME gpu_svo) -PROJECT(${PROJECT_NAME}) -CMAKE_MINIMUM_REQUIRED (VERSION 2.8.3) - -SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo -SET(CMAKE_VERBOSE_MAKEFILE OFF) -SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") -set(CMAKE_C_STANDARD 11) -set(CMAKE_CXX_STANDARD 11) - -# Set definitions -ADD_DEFINITIONS(-DSVO_TRACE) -ADD_DEFINITIONS(-DSVO_USE_ROS) - - -# Set build flags, set ARM_ARCHITECTURE environment variable on Odroid -# Set build flags. Set IS_ARM on odroid board as environment variable -SET(CMAKE_CXX_FLAGS "-Wall -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") -IF(DEFINED ENV{ARM_ARCHITECTURE}) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ") -ELSE() - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse -msse2 -msse3 -mssse3") -ENDIF() -SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -fsee -fomit-frame-pointer -fno-signed-zeros -fno-math-errno -funroll-loops") - -# Add plain cmake packages -FIND_PACKAGE(OpenCV REQUIRED) -FIND_PACKAGE(Eigen REQUIRED) -FIND_PACKAGE(Sophus REQUIRED) -FIND_PACKAGE(Boost REQUIRED COMPONENTS thread system) -FIND_PACKAGE(GTSAM REQUIRED) -FIND_PACKAGE(OpenCL REQUIRED) -FIND_PACKAGE(vikit_common REQUIRED) - -set(GTSAM_INCLUDE_DIRS "${GTSAM_INCLUDE_DIR}") -FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros) -catkin_package( - DEPENDS Eigen OpenCV Sophus Boost fast GTSAM - CATKIN_DEPENDS roscpp roslib vikit_common vikit_ros - INCLUDE_DIRS include - LIBRARIES ${PROJECT_NAME} -) - - -# Include dirs -INCLUDE_DIRECTORIES( - include - kernel - ${Eigen_INCLUDE_DIRS} - ${OpenCV_INCLUDE_DIRS} - ${Sophus_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${OpenCL_INCLUDE_DIRS} - ${GTSAM_INCLUDE_DIR} - ${catkin_INCLUDE_DIRS} -) - -# Set link libraries -LIST(APPEND LINK_LIBS - gtsam - ${OpenCV_LIBS} - ${Sophus_LIBRARIES} - ${Boost_LIBRARIES} - ${OpenCL_LIBRARIES} - ${catkin_LIBRARIES} -) - - -# Set sourcefiles -LIST(APPEND SOURCEFILES - src/frame_handler_mono.cpp - src/frame_handler_base.cpp - src/frame.cpp - src/point.cpp - src/map.cpp - src/pose_optimizer.cpp - src/initialization.cpp - src/matcher.cpp - src/reprojector.cpp - src/feature_alignment.cpp - src/feature_detection.cpp - src/depth_filter.cpp - src/config.cpp - src/sparse_img_align.cpp - src/imu_integration.cpp - src/cl_class.cpp - src/atan_camera.cpp - src/math_utils.cpp - src/robust_cost.cpp - src/vision.cpp - src/homography.cpp) - -# Create svo library -ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCEFILES}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LINK_LIBS} ) -set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11) -set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_range_for) -ADD_DEFINITIONS(-DKERNEL_DIR=\"${PROJECT_SOURCE_DIR}/kernel\") diff --git a/GPU_version/svo/package.xml b/GPU_version/svo/package.xml deleted file mode 100644 index 8aea0a7..0000000 --- a/GPU_version/svo/package.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - gpu_svo - 0.1.0 - - Monocular Visual Odometry - - Christian Forster - Christian Forster - GPLv3 - - - catkin - - - cmake_modules - roscpp - roslib - vikit_common - vikit_ros - - - roscpp - roslib - vikit_common - vikit_ros - \ No newline at end of file diff --git a/GPU_version/svo/src/bundle_adjustment.cpp b/GPU_version/svo/src/bundle_adjustment.cpp deleted file mode 100644 index 9bebb61..0000000 --- a/GPU_version/svo/src/bundle_adjustment.cpp +++ /dev/null @@ -1,435 +0,0 @@ -// This file is part of SVO - Semi-direct Visual Odometry. -// -// Copyright (C) 2014 Christian Forster -// (Robotics and Perception Group, University of Zurich, Switzerland). -// -// SVO is free software: you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the Free Software -// Foundation, either version 3 of the License, or any later version. -// -// SVO is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SCHUR_TRICK 1 - -namespace svo { -namespace ba { - -void twoViewBA( - Frame* frame1, - Frame* frame2, - double reproj_thresh, - Map* map) -{ - // scale reprojection threshold in pixels to unit plane - reproj_thresh /= frame1->cam_->errorMultiplier2(); - - // init g2o - g2o::SparseOptimizer optimizer; - setupG2o(&optimizer); - - list edges; - size_t v_id = 0; - - // New Keyframe Vertex 1: This Keyframe is set to fixed! - g2oFrameSE3* v_frame1 = createG2oFrameSE3(frame1, v_id++, true); - optimizer.addVertex(v_frame1); - - // New Keyframe Vertex 2 - g2oFrameSE3* v_frame2 = createG2oFrameSE3(frame2, v_id++, false); - optimizer.addVertex(v_frame2); - - // Create Point Vertices - for(Features::iterator it_ftr=frame1->fts_.begin(); it_ftr!=frame1->fts_.end(); ++it_ftr) - { - Point* pt = (*it_ftr)->point; - if(pt == NULL) - continue; - g2oPoint* v_pt = createG2oPoint(pt->pos_, v_id++, false); - optimizer.addVertex(v_pt); - pt->v_pt_ = v_pt; - g2oEdgeSE3* e = createG2oEdgeSE3(v_frame1, v_pt, vk::project2d((*it_ftr)->f), true, reproj_thresh*Config::lobaRobustHuberWidth()); - optimizer.addEdge(e); - edges.push_back(EdgeContainerSE3(e, frame1, *it_ftr)); // TODO feature now links to frame, so we can simplify edge container! - - // find at which index the second frame observes the point - Feature* ftr_frame2 = pt->findFrameRef(frame2); - e = createG2oEdgeSE3(v_frame2, v_pt, vk::project2d(ftr_frame2->f), true, reproj_thresh*Config::lobaRobustHuberWidth()); - optimizer.addEdge(e); - edges.push_back(EdgeContainerSE3(e, frame2, ftr_frame2)); - } - - // Optimization - double init_error, final_error; - runSparseBAOptimizer(&optimizer, Config::lobaNumIter(), init_error, final_error); - printf("2-View BA: Error before/after = %f / %f\n", init_error, final_error); - - // Update Keyframe Positions - frame1->T_f_w_.rotation_matrix() = v_frame1->estimate().rotation().toRotationMatrix(); - frame1->T_f_w_.translation() = v_frame1->estimate().translation(); - frame2->T_f_w_.rotation_matrix() = v_frame2->estimate().rotation().toRotationMatrix(); - frame2->T_f_w_.translation() = v_frame2->estimate().translation(); - - // Update Mappoint Positions - for(Features::iterator it=frame1->fts_.begin(); it!=frame1->fts_.end(); ++it) - { - if((*it)->point == NULL) - continue; - (*it)->point->pos_ = (*it)->point->v_pt_->estimate(); - (*it)->point->v_pt_ = NULL; - } - - // Find Mappoints with too large reprojection error - const double reproj_thresh_squared = reproj_thresh*reproj_thresh; - size_t n_incorrect_edges = 0; - for(list::iterator it_e = edges.begin(); it_e != edges.end(); ++it_e) - if(it_e->edge->chi2() > reproj_thresh_squared) - { - if(it_e->feature->point != NULL) - { - map->safeDeletePoint(it_e->feature->point); - it_e->feature->point = NULL; - } - ++n_incorrect_edges; - } - - printf("2-View BA: Wrong edges = %zu\n", n_incorrect_edges); -} - -void localBA( - Frame* center_kf, - set* core_kfs, - Map* map, - size_t& n_incorrect_edges_1, - size_t& n_incorrect_edges_2, - double& init_error, - double& final_error) -{ - - // init g2o - g2o::SparseOptimizer optimizer; - setupG2o(&optimizer); - - list edges; - set mps; - list neib_kfs; - size_t v_id = 0; - size_t n_mps = 0; - size_t n_fix_kfs = 0; - size_t n_var_kfs = 1; - size_t n_edges = 0; - n_incorrect_edges_1 = 0; - n_incorrect_edges_2 = 0; - - // Add all core keyframes - for(set::iterator it_kf = core_kfs->begin(); it_kf != core_kfs->end(); ++it_kf) - { - g2oFrameSE3* v_kf = createG2oFrameSE3(it_kf->get(), v_id++, false); - (*it_kf)->v_kf_ = v_kf; - ++n_var_kfs; - assert(optimizer.addVertex(v_kf)); - - // all points that the core keyframes observe are also optimized: - for(Features::iterator it_pt=(*it_kf)->fts_.begin(); it_pt!=(*it_kf)->fts_.end(); ++it_pt) - if((*it_pt)->point != NULL) - mps.insert((*it_pt)->point); - } - - // Now go throug all the points and add a measurement. Add a fixed neighbour - // Keyframe if it is not in the set of core kfs - double reproj_thresh_2 = Config::lobaThresh() / center_kf->cam_->errorMultiplier2(); - double reproj_thresh_1 = Config::poseOptimThresh() / center_kf->cam_->errorMultiplier2(); - double reproj_thresh_1_squared = reproj_thresh_1*reproj_thresh_1; - for(set::iterator it_pt = mps.begin(); it_pt!=mps.end(); ++it_pt) - { - // Create point vertex - g2oPoint* v_pt = createG2oPoint((*it_pt)->pos_, v_id++, false); - (*it_pt)->v_pt_ = v_pt; - assert(optimizer.addVertex(v_pt)); - ++n_mps; - - // Add edges - list::iterator it_obs=(*it_pt)->obs_.begin(); - while(it_obs!=(*it_pt)->obs_.end()) - { - Vector2d error = vk::project2d((*it_obs)->f) - vk::project2d((*it_obs)->frame->w2f((*it_pt)->pos_)); - - if((*it_obs)->frame->v_kf_ == NULL) - { - // frame does not have a vertex yet -> it belongs to the neib kfs and - // is fixed. create one: - g2oFrameSE3* v_kf = createG2oFrameSE3((*it_obs)->frame, v_id++, true); - (*it_obs)->frame->v_kf_ = v_kf; - ++n_fix_kfs; - assert(optimizer.addVertex(v_kf)); - neib_kfs.push_back((*it_obs)->frame); - } - - // create edge - g2oEdgeSE3* e = createG2oEdgeSE3((*it_obs)->frame->v_kf_, v_pt, - vk::project2d((*it_obs)->f), - true, - reproj_thresh_2*Config::lobaRobustHuberWidth(), - 1.0 / (1<<(*it_obs)->level)); - assert(optimizer.addEdge(e)); - edges.push_back(EdgeContainerSE3(e, (*it_obs)->frame, *it_obs)); - ++n_edges; - ++it_obs; - } - } - - // structure only - g2o::StructureOnlySolver<3> structure_only_ba; - g2o::OptimizableGraph::VertexContainer points; - for (g2o::OptimizableGraph::VertexIDMap::const_iterator it = optimizer.vertices().begin(); it != optimizer.vertices().end(); ++it) - { - g2o::OptimizableGraph::Vertex* v = static_cast(it->second); - if (v->dimension() == 3 && v->edges().size() >= 2) - points.push_back(v); - } - structure_only_ba.calc(points, 10); - - // Optimization - if(Config::lobaNumIter() > 0) - runSparseBAOptimizer(&optimizer, Config::lobaNumIter(), init_error, final_error); - - // Update Keyframes - for(set::iterator it = core_kfs->begin(); it != core_kfs->end(); ++it) - { - (*it)->T_f_w_ = SE3( (*it)->v_kf_->estimate().rotation(), - (*it)->v_kf_->estimate().translation()); - (*it)->v_kf_ = NULL; - } - - for(list::iterator it = neib_kfs.begin(); it != neib_kfs.end(); ++it) - (*it)->v_kf_ = NULL; - - // Update Mappoints - for(set::iterator it = mps.begin(); it != mps.end(); ++it) - { - (*it)->pos_ = (*it)->v_pt_->estimate(); - (*it)->v_pt_ = NULL; - } - - // Remove Measurements with too large reprojection error - double reproj_thresh_2_squared = reproj_thresh_2*reproj_thresh_2; - for(list::iterator it = edges.begin(); it != edges.end(); ++it) - { - if(it->edge->chi2() > reproj_thresh_2_squared) //*(1<feature_->level)) - { - map->removePtFrameRef(it->frame, it->feature); - ++n_incorrect_edges_2; - } - } - - // TODO: delete points and edges! - init_error = sqrt(init_error)*center_kf->cam_->errorMultiplier2(); - final_error = sqrt(final_error)*center_kf->cam_->errorMultiplier2(); -} - -void globalBA(Map* map) -{ - // init g2o - g2o::SparseOptimizer optimizer; - setupG2o(&optimizer); - - list edges; - list< pair > incorrect_edges; - - // Go through all Keyframes - size_t v_id = 0; - double reproj_thresh_2 = Config::lobaThresh() / map->lastKeyframe()->cam_->errorMultiplier2(); - double reproj_thresh_1_squared = Config::poseOptimThresh() / map->lastKeyframe()->cam_->errorMultiplier2(); - reproj_thresh_1_squared *= reproj_thresh_1_squared; - for(list::iterator it_kf = map->keyframes_.begin(); - it_kf != map->keyframes_.end(); ++it_kf) - { - // New Keyframe Vertex - g2oFrameSE3* v_kf = createG2oFrameSE3(it_kf->get(), v_id++, false); - (*it_kf)->v_kf_ = v_kf; - optimizer.addVertex(v_kf); - for(Features::iterator it_ftr=(*it_kf)->fts_.begin(); it_ftr!=(*it_kf)->fts_.end(); ++it_ftr) - { - // for each keyframe add edges to all observed mapoints - Point* mp = (*it_ftr)->point; - if(mp == NULL) - continue; - g2oPoint* v_mp = mp->v_pt_; - if(v_mp == NULL) - { - // mappoint-vertex doesn't exist yet. create a new one: - v_mp = createG2oPoint(mp->pos_, v_id++, false); - mp->v_pt_ = v_mp; - optimizer.addVertex(v_mp); - } - - // Due to merging of mappoints it is possible that references in kfs suddenly - // have a very large reprojection error which may result in distorted results. - Vector2d error = vk::project2d((*it_ftr)->f) - vk::project2d((*it_kf)->w2f(mp->pos_)); - if(error.squaredNorm() > reproj_thresh_1_squared) - incorrect_edges.push_back(pair(*it_kf, *it_ftr)); - else - { - g2oEdgeSE3* e = createG2oEdgeSE3(v_kf, v_mp, vk::project2d((*it_ftr)->f), - true, - reproj_thresh_2*Config::lobaRobustHuberWidth()); - - edges.push_back(EdgeContainerSE3(e, it_kf->get(), *it_ftr)); - optimizer.addEdge(e); - } - } - } - - // Optimization - double init_error=0.0, final_error=0.0; - if(Config::lobaNumIter() > 0) - runSparseBAOptimizer(&optimizer, Config::lobaNumIter(), init_error, final_error); - - // Update Keyframe and MapPoint Positions - for(list::iterator it_kf = map->keyframes_.begin(); - it_kf != map->keyframes_.end(); ++it_kf) - { - (*it_kf)->T_f_w_ = SE3( (*it_kf)->v_kf_->estimate().rotation(), - (*it_kf)->v_kf_->estimate().translation()); - (*it_kf)->v_kf_ = NULL; - for(Features::iterator it_ftr=(*it_kf)->fts_.begin(); it_ftr!=(*it_kf)->fts_.end(); ++it_ftr) - { - Point* mp = (*it_ftr)->point; - if(mp == NULL) - continue; - if(mp->v_pt_ == NULL) - continue; // mp was updated before - mp->pos_ = mp->v_pt_->estimate(); - mp->v_pt_ = NULL; - } - } - - // Remove Measurements with too large reprojection error - for(list< pair >::iterator it=incorrect_edges.begin(); - it!=incorrect_edges.end(); ++it) - map->removePtFrameRef(it->first.get(), it->second); - - double reproj_thresh_2_squared = reproj_thresh_2*reproj_thresh_2; - for(list::iterator it = edges.begin(); it != edges.end(); ++it) - { - if(it->edge->chi2() > reproj_thresh_2_squared) - { - map->removePtFrameRef(it->frame, it->feature); - } - } -} - -void setupG2o(g2o::SparseOptimizer * optimizer) -{ - // TODO: What's happening with all this HEAP stuff? Memory Leak? - optimizer->setVerbose(false); - -#if SCHUR_TRICK - // solver - g2o::BlockSolver_6_3::LinearSolverType* linearSolver; - linearSolver = new g2o::LinearSolverCholmod(); - //linearSolver = new g2o::LinearSolverCSparse(); - - g2o::BlockSolver_6_3 * solver_ptr = new g2o::BlockSolver_6_3(linearSolver); - g2o::OptimizationAlgorithmLevenberg * solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr); -#else - g2o::BlockSolverX::LinearSolverType * linearSolver; - linearSolver = new g2o::LinearSolverCholmod(); - //linearSolver = new g2o::LinearSolverCSparse(); - g2o::BlockSolverX * solver_ptr = new g2o::BlockSolverX(linearSolver); - g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg(solver_ptr); -#endif - - solver->setMaxTrialsAfterFailure(5); - optimizer->setAlgorithm(solver); - - // setup camera - g2o::CameraParameters * cam_params = new g2o::CameraParameters(1.0, Vector2d(0.,0.), 0.); - cam_params->setId(0); - if (!optimizer->addParameter(cam_params)) { - assert(false); - } -} - -void -runSparseBAOptimizer(g2o::SparseOptimizer* optimizer, - unsigned int num_iter, - double& init_error, double& final_error) -{ - optimizer->initializeOptimization(); - optimizer->computeActiveErrors(); - init_error = optimizer->activeChi2(); - optimizer->optimize(num_iter); - final_error = optimizer->activeChi2(); -} - -g2oFrameSE3* -createG2oFrameSE3(Frame* frame, size_t id, bool fixed) -{ - g2oFrameSE3* v = new g2oFrameSE3(); - v->setId(id); - v->setFixed(fixed); - v->setEstimate(g2o::SE3Quat(frame->T_f_w_.unit_quaternion(), frame->T_f_w_.translation())); - return v; -} - -g2oPoint* -createG2oPoint(Vector3d pos, - size_t id, - bool fixed) -{ - g2oPoint* v = new g2oPoint(); - v->setId(id); -#if SCHUR_TRICK - v->setMarginalized(true); -#endif - v->setFixed(fixed); - v->setEstimate(pos); - return v; -} - -g2oEdgeSE3* -createG2oEdgeSE3( g2oFrameSE3* v_frame, - g2oPoint* v_point, - const Vector2d& f_up, - bool robust_kernel, - double huber_width, - double weight) -{ - g2oEdgeSE3* e = new g2oEdgeSE3(); - e->setVertex(0, dynamic_cast(v_point)); - e->setVertex(1, dynamic_cast(v_frame)); - e->setMeasurement(f_up); - e->information() = weight * Eigen::Matrix2d::Identity(2,2); - g2o::RobustKernelHuber* rk = new g2o::RobustKernelHuber(); // TODO: memory leak - rk->setDelta(huber_width); - e->setRobustKernel(rk); - e->setParameterId(0, 0); //old: e->setId(v_point->id()); - return e; -} - -} // namespace ba -} // namespace svo diff --git a/GPU_version/vio/.idea/.name b/GPU_version/vio/.idea/.name index 06a578d..19d75c0 100644 --- a/GPU_version/vio/.idea/.name +++ b/GPU_version/vio/.idea/.name @@ -1 +1 @@ -vio_gpu \ No newline at end of file +vio \ No newline at end of file diff --git a/GPU_version/vio/.idea/modules.xml b/GPU_version/vio/.idea/modules.xml index eb3cacf..4c8cf2b 100644 --- a/GPU_version/vio/.idea/modules.xml +++ b/GPU_version/vio/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/GPU_version/svo/.idea/svo.iml b/GPU_version/vio/.idea/svo.iml similarity index 100% rename from GPU_version/svo/.idea/svo.iml rename to GPU_version/vio/.idea/svo.iml diff --git a/GPU_version/vio/.idea/svo_ros.iml b/GPU_version/vio/.idea/svo_ros.iml deleted file mode 100644 index f08604b..0000000 --- a/GPU_version/vio/.idea/svo_ros.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/GPU_version/vio/CMakeLists.txt b/GPU_version/vio/CMakeLists.txt old mode 100644 new mode 100755 index a9872a4..938c850 --- a/GPU_version/vio/CMakeLists.txt +++ b/GPU_version/vio/CMakeLists.txt @@ -1,92 +1,76 @@ -SET(PROJECT_NAME vio_gpu) +SET(PROJECT_NAME vio) PROJECT(${PROJECT_NAME}) CMAKE_MINIMUM_REQUIRED (VERSION 2.8.3) + SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo SET(CMAKE_VERBOSE_MAKEFILE OFF) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") +set(CMAKE_C_STANDARD 17) +set(CMAKE_CXX_STANDARD 17) +# Set definitions +ADD_DEFINITIONS(-DSVO_TRACE) +ADD_DEFINITIONS(-DSVO_USE_ROS) + + +# Set build flags, set ARM_ARCHITECTURE environment variable on Odroid # Set build flags. Set IS_ARM on odroid board as environment variable SET(CMAKE_CXX_FLAGS "-Wall -D_LINUX -D_REENTRANT -march=native -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unknown-pragmas") IF(DEFINED ENV{ARM_ARCHITECTURE}) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ") ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse -msse2 -msse3 -mssse3") ENDIF() -IF(CMAKE_COMPILER_IS_GNUCC) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") -ELSE() - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -ENDIF() SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -fsee -fomit-frame-pointer -fno-signed-zeros -fno-math-errno -funroll-loops") -# Add catkin and required ROS packages -FIND_PACKAGE(catkin REQUIRED COMPONENTS - geometry_msgs - roscpp - cmake_modules - nav_msgs - std_msgs - visualization_msgs - sensor_msgs - image_transport - cv_bridge - tf - gpu_svo - vikit_common - vikit_ros -) - # Add plain cmake packages -FIND_PACKAGE(OpenCV REQUIRED) +FIND_PACKAGE(OpenCV 3 REQUIRED) FIND_PACKAGE(Eigen REQUIRED) FIND_PACKAGE(Sophus REQUIRED) -FIND_PACKAGE(Boost REQUIRED COMPONENTS thread) -FIND_PACKAGE(GTSAM REQUIRED) +FIND_PACKAGE(Boost REQUIRED COMPONENTS thread system) FIND_PACKAGE(OpenCL REQUIRED) -# notify catkin to look at the previously found msg files -add_message_files( - FILES - Info.msg +set(GTSAM_INCLUDE_DIRS "${GTSAM_INCLUDE_DIR}") +FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules image_transport cv_bridge tf geometry_msgs) +catkin_package( + DEPENDS Eigen OpenCV Sophus Boost + CATKIN_DEPENDS roscpp roslib image_transport cv_bridge tf geometry_msgs + INCLUDE_DIRS include ) -# build the header files from the msg files, and notify catkin about the dependencies -generate_messages( - DEPENDENCIES - geometry_msgs - sensor_msgs -) -# Describe catkin Project -catkin_package( - DEPENDS Eigen OpenCV Sophus Boost - CATKIN_DEPENDS roscpp nav_msgs std_msgs visualization_msgs sensor_msgs image_transport cv_bridge tf gpu_svo vikit_common vikit_ros geometry_msgs - INCLUDE_DIRS include - LIBRARIES ${PROJECT_NAME}_visualizer -) # Include dirs INCLUDE_DIRECTORIES( include - ${Eigen_INCLUDE_DIRS} - ${OpenCV_INCLUDE_DIRS} - ${Sophus_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${catkin_INCLUDE_DIRS} + kernel + ${Eigen_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${Sophus_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${OpenCL_INCLUDE_DIRS} + ${catkin_INCLUDE_DIRS} ) # Set link libraries -LIST(APPEND LINK_LIBS +LIST(APPEND LINK_LIBS + #gtsam ${OpenCV_LIBS} ${Sophus_LIBRARIES} ${Boost_LIBRARIES} - ${catkin_LIBRARIES} ${OpenCL_LIBRARIES} + ${catkin_LIBRARIES} ) -# Create visualizer library -ADD_LIBRARY(${PROJECT_NAME}_visualizer src/visualizer.cpp) -TARGET_LINK_LIBRARIES(${PROJECT_NAME}_visualizer ${LINK_LIBS} gtsam) - -# Create Executables -ADD_EXECUTABLE(${PROJECT_NAME} src/vo_node.cpp) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${PROJECT_NAME}_visualizer ${LINK_LIBS}) +file(GLOB SRC CONFIGURE_DEPENDS "src/*.cpp") + + + +# Create svo library +ADD_EXECUTABLE(${PROJECT_NAME} ${SRC}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LINK_LIBS}) +set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17) +set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) +target_compile_features(${PROJECT_NAME} PRIVATE cxx_range_for) +ADD_DEFINITIONS(-DKERNEL_DIR=\"${PROJECT_SOURCE_DIR}/kernel\") + + diff --git a/GPU_version/svo/CMakeModules/FindEigen.cmake b/GPU_version/vio/CMakeModules/FindEigen.cmake similarity index 100% rename from GPU_version/svo/CMakeModules/FindEigen.cmake rename to GPU_version/vio/CMakeModules/FindEigen.cmake diff --git a/GPU_version/svo/CMakeModules/FindG2O.cmake b/GPU_version/vio/CMakeModules/FindG2O.cmake similarity index 100% rename from GPU_version/svo/CMakeModules/FindG2O.cmake rename to GPU_version/vio/CMakeModules/FindG2O.cmake diff --git a/GPU_version/svo/Doxyfile b/GPU_version/vio/Doxyfile old mode 100644 new mode 100755 similarity index 100% rename from GPU_version/svo/Doxyfile rename to GPU_version/vio/Doxyfile diff --git a/GPU_version/vio/cmake-build-debug/CATKIN_IGNORE b/GPU_version/vio/cmake-build-debug/CATKIN_IGNORE new file mode 100644 index 0000000..e69de29 diff --git a/GPU_version/vio/cmake-build-debug/CMakeCache.txt b/GPU_version/vio/cmake-build-debug/CMakeCache.txt new file mode 100644 index 0000000..d820937 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CMakeCache.txt @@ -0,0 +1,785 @@ +# This is the CMakeCache file. +# For build in directory: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug +# It was generated by CMake: /opt/clion-2020.3.2/bin/cmake/linux/bin/cmake +# You can edit this file to change values found and used by cmake. +# If you do not want to change any of the values, simply exit the editor. +# If you do want to change a value, simply edit, save, and exit the editor. +# The syntax for the file is as follows: +# KEY:TYPE=VALUE +# KEY is the name of a variable in the cache. +# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!. +# VALUE is the current value for the KEY. + +######################## +# EXTERNAL cache entries +######################## + +//Builds the googlemock subproject +BUILD_GMOCK:BOOL=ON + +//Builds the googletest subproject +BUILD_GTEST:BOOL=OFF + +//Build shared libraries (DLLs). +BUILD_SHARED_LIBS:BOOL=ON + +//Boost atomic library (debug) +Boost_ATOMIC_LIBRARY_DEBUG:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_atomic.so + +//Boost atomic library (release) +Boost_ATOMIC_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_atomic.so + +//Boost chrono library (debug) +Boost_CHRONO_LIBRARY_DEBUG:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_chrono.so + +//Boost chrono library (release) +Boost_CHRONO_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_chrono.so + +//Boost date_time library (debug) +Boost_DATE_TIME_LIBRARY_DEBUG:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_date_time.so + +//Boost date_time library (release) +Boost_DATE_TIME_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_date_time.so + +//The directory containing a CMake configuration file for Boost. +Boost_DIR:PATH=Boost_DIR-NOTFOUND + +//Path to a file. +Boost_INCLUDE_DIR:PATH=/usr/include + +//Boost library directory DEBUG +Boost_LIBRARY_DIR_DEBUG:PATH=/usr/lib/x86_64-linux-gnu + +//Boost library directory RELEASE +Boost_LIBRARY_DIR_RELEASE:PATH=/usr/lib/x86_64-linux-gnu + +//Boost system library (debug) +Boost_SYSTEM_LIBRARY_DEBUG:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_system.so + +//Boost system library (release) +Boost_SYSTEM_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_system.so + +//Boost thread library (debug) +Boost_THREAD_LIBRARY_DEBUG:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_thread.so + +//Boost thread library (release) +Boost_THREAD_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_thread.so + +//Catkin enable testing +CATKIN_ENABLE_TESTING:BOOL=ON + +//Prefix to apply to package generated via gendebian +CATKIN_PACKAGE_PREFIX:STRING= + +//Catkin skip testing +CATKIN_SKIP_TESTING:BOOL=OFF + +//Replace the CMake install command with a custom implementation +// using symlinks instead of copying resources +CATKIN_SYMLINK_INSTALL:BOOL=OFF + +//Path to a program. +CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line + +//Path to a program. +CMAKE_AR:FILEPATH=/usr/bin/ar + +//Choose the type of build, options are: None Debug Release RelWithDebInfo +// MinSizeRel ... +CMAKE_BUILD_TYPE:STRING=Debug + +//Id string of the compiler for the CodeBlocks IDE. Automatically +// detected when left empty +CMAKE_CODEBLOCKS_COMPILER_ID:STRING= + +//The CodeBlocks executable +CMAKE_CODEBLOCKS_EXECUTABLE:FILEPATH=/usr/bin/codeblocks + +//Additional command line arguments when CodeBlocks invokes make. +// Enter e.g. -j to get parallel builds +CMAKE_CODEBLOCKS_MAKE_ARGUMENTS:STRING=-j8 + +//Enable/Disable color output during build. +CMAKE_COLOR_MAKEFILE:BOOL=ON + +//CXX compiler +CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++ + +//A wrapper around 'ar' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-7 + +//A wrapper around 'ranlib' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-7 + +//Flags used by the CXX compiler during all build types. +CMAKE_CXX_FLAGS:STRING= + +//Flags used by the CXX compiler during DEBUG builds. +CMAKE_CXX_FLAGS_DEBUG:STRING=-g + +//Flags used by the CXX compiler during MINSIZEREL builds. +CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG + +//Flags used by the CXX compiler during RELEASE builds. +CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG + +//Flags used by the CXX compiler during RELWITHDEBINFO builds. +CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG + +//C compiler +CMAKE_C_COMPILER:FILEPATH=/usr/bin/cc + +//A wrapper around 'ar' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-7 + +//A wrapper around 'ranlib' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-7 + +//Flags used by the C compiler during all build types. +CMAKE_C_FLAGS:STRING= + +//Flags used by the C compiler during DEBUG builds. +CMAKE_C_FLAGS_DEBUG:STRING=-g + +//Flags used by the C compiler during MINSIZEREL builds. +CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG + +//Flags used by the C compiler during RELEASE builds. +CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG + +//Flags used by the C compiler during RELWITHDEBINFO builds. +CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG + +//Path to a program. +CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND + +//Flags used by the linker during all build types. +CMAKE_EXE_LINKER_FLAGS:STRING= + +//Flags used by the linker during DEBUG builds. +CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during MINSIZEREL builds. +CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during RELEASE builds. +CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during RELWITHDEBINFO builds. +CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Enable/Disable output of compile commands during generation. +CMAKE_EXPORT_COMPILE_COMMANDS:BOOL= + +//Install path prefix, prepended onto install directories. +CMAKE_INSTALL_PREFIX:PATH=/usr/local + +//Path to a program. +CMAKE_LINKER:FILEPATH=/usr/bin/ld + +//Path to a program. +CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make + +//Flags used by the linker during the creation of modules during +// all build types. +CMAKE_MODULE_LINKER_FLAGS:STRING= + +//Flags used by the linker during the creation of modules during +// DEBUG builds. +CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during the creation of modules during +// MINSIZEREL builds. +CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during the creation of modules during +// RELEASE builds. +CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during the creation of modules during +// RELWITHDEBINFO builds. +CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Path to a program. +CMAKE_NM:FILEPATH=/usr/bin/nm + +//Path to a program. +CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy + +//Path to a program. +CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump + +//Value Computed by CMake +CMAKE_PROJECT_DESCRIPTION:STATIC= + +//Value Computed by CMake +CMAKE_PROJECT_HOMEPAGE_URL:STATIC= + +//Value Computed by CMake +CMAKE_PROJECT_NAME:STATIC=vio + +//Path to a program. +CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib + +//Path to a program. +CMAKE_READELF:FILEPATH=/usr/bin/readelf + +//Flags used by the linker during the creation of shared libraries +// during all build types. +CMAKE_SHARED_LINKER_FLAGS:STRING= + +//Flags used by the linker during the creation of shared libraries +// during DEBUG builds. +CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during the creation of shared libraries +// during MINSIZEREL builds. +CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during the creation of shared libraries +// during RELEASE builds. +CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during the creation of shared libraries +// during RELWITHDEBINFO builds. +CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//If set, runtime paths are not added when installing shared libraries, +// but are added when building. +CMAKE_SKIP_INSTALL_RPATH:BOOL=NO + +//If set, runtime paths are not added when using shared libraries. +CMAKE_SKIP_RPATH:BOOL=NO + +//Flags used by the linker during the creation of static libraries +// during all build types. +CMAKE_STATIC_LINKER_FLAGS:STRING= + +//Flags used by the linker during the creation of static libraries +// during DEBUG builds. +CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during the creation of static libraries +// during MINSIZEREL builds. +CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during the creation of static libraries +// during RELEASE builds. +CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during the creation of static libraries +// during RELWITHDEBINFO builds. +CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Path to a program. +CMAKE_STRIP:FILEPATH=/usr/bin/strip + +//If this value is on, makefiles will be generated without the +// .SILENT directive, and all commands will be echoed to the console +// during the make. This is useful for debugging only. With Visual +// Studio IDE projects all commands are done without /nologo. +CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE + +//Path to a program. +DOXYGEN_EXECUTABLE:FILEPATH=/usr/bin/doxygen + +//Doxygen found +DOXYGEN_FOUND:BOOL=TRUE + +//Path to a file. +EIGEN_INCLUDE_DIR:PATH=/usr/include/eigen3 + +//Path to a program. +EMPY_EXECUTABLE:FILEPATH=/usr/bin/empy + +//Empy script +EMPY_SCRIPT:STRING=/usr/bin/empy + +//The directory containing a CMake configuration file for GMock. +GMock_DIR:PATH=GMock_DIR-NOTFOUND + +//Path to a file. +GTEST_INCLUDE_DIR:PATH=/usr/include + +//Path to a library. +GTEST_LIBRARY:FILEPATH=GTEST_LIBRARY-NOTFOUND + +//Path to a library. +GTEST_LIBRARY_DEBUG:FILEPATH=GTEST_LIBRARY_DEBUG-NOTFOUND + +//Path to a library. +GTEST_MAIN_LIBRARY:FILEPATH=GTEST_MAIN_LIBRARY-NOTFOUND + +//Path to a library. +GTEST_MAIN_LIBRARY_DEBUG:FILEPATH=GTEST_MAIN_LIBRARY_DEBUG-NOTFOUND + +//lsb_release executable was found +LSB_FOUND:BOOL=TRUE + +//Path to a program. +LSB_RELEASE_EXECUTABLE:FILEPATH=/usr/bin/lsb_release + +//Path to a program. +NOSETESTS:FILEPATH=/usr/bin/nosetests-2.7 + +//Path to a file. +OpenCL_INCLUDE_DIR:PATH=/usr/include + +//Path to a library. +OpenCL_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libOpenCL.so + +//The directory containing a CMake configuration file for OpenCV. +OpenCV_DIR:PATH=/usr/share/OpenCV + +//pkg-config executable +PKG_CONFIG_EXECUTABLE:FILEPATH=/usr/bin/pkg-config + +//Path to a program. +PYTHON_EXECUTABLE:FILEPATH=/usr/bin/python2 + +//Specify specific Python version to use ('major.minor' or 'major') +PYTHON_VERSION:STRING=2 + +//Path to a program. +ProcessorCount_cmd_nproc:FILEPATH=/usr/bin/nproc + +//Path to a program. +ProcessorCount_cmd_sysctl:FILEPATH=/sbin/sysctl + +//Path to a library. +RT_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/librt.so + +//Enable debian style python package layout +SETUPTOOLS_DEB_LAYOUT:BOOL=ON + +//Name of the computer/site where compile is being run +SITE:STRING=gfuse + +//The directory containing a CMake configuration file for Sophus. +Sophus_DIR:PATH=/root/workstation/Sophus/build + +//LSB Distrib tag +UBUNTU:BOOL=TRUE + +//LSB Distrib - codename tag +UBUNTU_BIONIC:BOOL=TRUE + +//Path to a file. +_gmock_INCLUDES:FILEPATH=/usr/include/gmock/gmock.h + +//Path to a file. +_gmock_SOURCES:FILEPATH=/usr/src/gmock/src/gmock.cc + +//Path to a file. +_gtest_INCLUDES:FILEPATH=/usr/include/gtest/gtest.h + +//Path to a file. +_gtest_SOURCES:FILEPATH=/usr/src/gtest/src/gtest.cc + +//The directory containing a CMake configuration file for catkin. +catkin_DIR:PATH=/opt/ros/melodic/share/catkin/cmake + +//The directory containing a CMake configuration file for cmake_modules. +cmake_modules_DIR:PATH=/opt/ros/melodic/share/cmake_modules/cmake + +//The directory containing a CMake configuration file for cpp_common. +cpp_common_DIR:PATH=/opt/ros/melodic/share/cpp_common/cmake + +//Value Computed by CMake +gmock_BINARY_DIR:STATIC=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/gtest/googlemock + +//Dependencies for the target +gmock_LIB_DEPENDS:STATIC=general;-lpthread; + +//Value Computed by CMake +gmock_SOURCE_DIR:STATIC=/usr/src/googletest/googlemock + +//Build all of Google Mock's own tests. +gmock_build_tests:BOOL=OFF + +//Dependencies for the target +gmock_main_LIB_DEPENDS:STATIC=general;-lpthread; + +//Value Computed by CMake +googletest-distribution_BINARY_DIR:STATIC=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/gtest + +//Value Computed by CMake +googletest-distribution_SOURCE_DIR:STATIC=/usr/src/googletest + +//Value Computed by CMake +gtest_BINARY_DIR:STATIC=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/gtest/googlemock/gtest + +//Dependencies for the target +gtest_LIB_DEPENDS:STATIC=general;-lpthread; + +//Value Computed by CMake +gtest_SOURCE_DIR:STATIC=/usr/src/googletest/googletest + +//Build gtest's sample programs. +gtest_build_samples:BOOL=OFF + +//Build all of gtest's own tests. +gtest_build_tests:BOOL=OFF + +//Disable uses of pthreads in gtest. +gtest_disable_pthreads:BOOL=OFF + +//Use shared (DLL) run-time lib even when Google Test is built +// as static lib. +gtest_force_shared_crt:BOOL=OFF + +//Build gtest with internal symbols hidden in shared libraries. +gtest_hide_internal_symbols:BOOL=OFF + +//Dependencies for the target +gtest_main_LIB_DEPENDS:STATIC=general;-lpthread;general;gtest; + +//Path to a library. +lib:FILEPATH=/opt/ros/melodic/lib/librospack.so + +//The directory containing a CMake configuration file for message_runtime. +message_runtime_DIR:PATH=/opt/ros/melodic/share/message_runtime/cmake + +//The directory containing a CMake configuration file for robot_localization. +robot_localization_DIR:PATH=robot_localization_DIR-NOTFOUND + +//The directory containing a CMake configuration file for rosconsole. +rosconsole_DIR:PATH=/opt/ros/melodic/share/rosconsole/cmake + +//The directory containing a CMake configuration file for roscpp. +roscpp_DIR:PATH=/opt/ros/melodic/share/roscpp/cmake + +//The directory containing a CMake configuration file for roscpp_serialization. +roscpp_serialization_DIR:PATH=/opt/ros/melodic/share/roscpp_serialization/cmake + +//The directory containing a CMake configuration file for roscpp_traits. +roscpp_traits_DIR:PATH=/opt/ros/melodic/share/roscpp_traits/cmake + +//The directory containing a CMake configuration file for rosgraph_msgs. +rosgraph_msgs_DIR:PATH=/opt/ros/melodic/share/rosgraph_msgs/cmake + +//The directory containing a CMake configuration file for roslib. +roslib_DIR:PATH=/opt/ros/melodic/share/roslib/cmake + +//The directory containing a CMake configuration file for rospack. +rospack_DIR:PATH=/opt/ros/melodic/share/rospack/cmake + +//The directory containing a CMake configuration file for rostime. +rostime_DIR:PATH=/opt/ros/melodic/share/rostime/cmake + +//The directory containing a CMake configuration file for std_msgs. +std_msgs_DIR:PATH=/opt/ros/melodic/share/std_msgs/cmake + +//Value Computed by CMake +vio_BINARY_DIR:STATIC=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug + +//Value Computed by CMake +vio_SOURCE_DIR:STATIC=/root/Project/ROS/src/vio_svo/GPU_version/svo + +//The directory containing a CMake configuration file for xmlrpcpp. +xmlrpcpp_DIR:PATH=/opt/ros/melodic/share/xmlrpcpp/cmake + + +######################## +# INTERNAL cache entries +######################## + +//ADVANCED property for variable: Boost_ATOMIC_LIBRARY_DEBUG +Boost_ATOMIC_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_ATOMIC_LIBRARY_RELEASE +Boost_ATOMIC_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_CHRONO_LIBRARY_DEBUG +Boost_CHRONO_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_CHRONO_LIBRARY_RELEASE +Boost_CHRONO_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_DATE_TIME_LIBRARY_DEBUG +Boost_DATE_TIME_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_DATE_TIME_LIBRARY_RELEASE +Boost_DATE_TIME_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_DIR +Boost_DIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_INCLUDE_DIR +Boost_INCLUDE_DIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_LIBRARY_DIR_DEBUG +Boost_LIBRARY_DIR_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_LIBRARY_DIR_RELEASE +Boost_LIBRARY_DIR_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_SYSTEM_LIBRARY_DEBUG +Boost_SYSTEM_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_SYSTEM_LIBRARY_RELEASE +Boost_SYSTEM_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_THREAD_LIBRARY_DEBUG +Boost_THREAD_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: Boost_THREAD_LIBRARY_RELEASE +Boost_THREAD_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 +//catkin environment +CATKIN_ENV:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/catkin_generated/env_cached.sh +CATKIN_TEST_RESULTS_DIR:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/test_results +//ADVANCED property for variable: CMAKE_ADDR2LINE +CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_AR +CMAKE_AR-ADVANCED:INTERNAL=1 +//This is the directory where this CMakeCache.txt was created +CMAKE_CACHEFILE_DIR:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug +//Major version of cmake used to create the current loaded cache +CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 +//Minor version of cmake used to create the current loaded cache +CMAKE_CACHE_MINOR_VERSION:INTERNAL=17 +//Patch version of cmake used to create the current loaded cache +CMAKE_CACHE_PATCH_VERSION:INTERNAL=5 +//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE +CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1 +//Path to CMake executable. +CMAKE_COMMAND:INTERNAL=/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake +//Path to cpack program executable. +CMAKE_CPACK_COMMAND:INTERNAL=/opt/clion-2020.3.2/bin/cmake/linux/bin/cpack +//Path to ctest program executable. +CMAKE_CTEST_COMMAND:INTERNAL=/opt/clion-2020.3.2/bin/cmake/linux/bin/ctest +//ADVANCED property for variable: CMAKE_CXX_COMPILER +CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR +CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB +CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS +CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG +CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL +CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE +CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO +CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER +CMAKE_C_COMPILER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER_AR +CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB +CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS +CMAKE_C_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG +CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL +CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE +CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO +CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_DLLTOOL +CMAKE_DLLTOOL-ADVANCED:INTERNAL=1 +//Executable file format +CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS +CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG +CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL +CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE +CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS +CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1 +//Name of external makefile project generator. +CMAKE_EXTRA_GENERATOR:INTERNAL=CodeBlocks +//CXX compiler system defined macros +CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS:INTERNAL=__STDC__;1;__STDC_VERSION__;201112L;__STDC_UTF_16__;1;__STDC_UTF_32__;1;__STDC_HOSTED__;1;__GNUC__;7;__GNUC_MINOR__;5;__GNUC_PATCHLEVEL__;0;__VERSION__;"7.5.0";__ATOMIC_RELAXED;0;__ATOMIC_SEQ_CST;5;__ATOMIC_ACQUIRE;2;__ATOMIC_RELEASE;3;__ATOMIC_ACQ_REL;4;__ATOMIC_CONSUME;1;__pic__;2;__PIC__;2;__pie__;2;__PIE__;2;__FINITE_MATH_ONLY__;0;_LP64;1;__LP64__;1;__SIZEOF_INT__;4;__SIZEOF_LONG__;8;__SIZEOF_LONG_LONG__;8;__SIZEOF_SHORT__;2;__SIZEOF_FLOAT__;4;__SIZEOF_DOUBLE__;8;__SIZEOF_LONG_DOUBLE__;16;__SIZEOF_SIZE_T__;8;__CHAR_BIT__;8;__BIGGEST_ALIGNMENT__;16;__ORDER_LITTLE_ENDIAN__;1234;__ORDER_BIG_ENDIAN__;4321;__ORDER_PDP_ENDIAN__;3412;__BYTE_ORDER__;__ORDER_LITTLE_ENDIAN__;__FLOAT_WORD_ORDER__;__ORDER_LITTLE_ENDIAN__;__SIZEOF_POINTER__;8;__SIZE_TYPE__;long unsigned int;__PTRDIFF_TYPE__;long int;__WCHAR_TYPE__;int;__WINT_TYPE__;unsigned int;__INTMAX_TYPE__;long int;__UINTMAX_TYPE__;long unsigned int;__CHAR16_TYPE__;short unsigned int;__CHAR32_TYPE__;unsigned int;__SIG_ATOMIC_TYPE__;int;__INT8_TYPE__;signed char;__INT16_TYPE__;short int;__INT32_TYPE__;int;__INT64_TYPE__;long int;__UINT8_TYPE__;unsigned char;__UINT16_TYPE__;short unsigned int;__UINT32_TYPE__;unsigned int;__UINT64_TYPE__;long unsigned int;__INT_LEAST8_TYPE__;signed char;__INT_LEAST16_TYPE__;short int;__INT_LEAST32_TYPE__;int;__INT_LEAST64_TYPE__;long int;__UINT_LEAST8_TYPE__;unsigned char;__UINT_LEAST16_TYPE__;short unsigned int;__UINT_LEAST32_TYPE__;unsigned int;__UINT_LEAST64_TYPE__;long unsigned int;__INT_FAST8_TYPE__;signed char;__INT_FAST16_TYPE__;long int;__INT_FAST32_TYPE__;long int;__INT_FAST64_TYPE__;long int;__UINT_FAST8_TYPE__;unsigned char;__UINT_FAST16_TYPE__;long unsigned int;__UINT_FAST32_TYPE__;long unsigned int;__UINT_FAST64_TYPE__;long unsigned int;__INTPTR_TYPE__;long int;__UINTPTR_TYPE__;long unsigned int;__has_include(STR);__has_include__(STR);__has_include_next(STR);__has_include_next__(STR);__GXX_ABI_VERSION;1011;__SCHAR_MAX__;0x7f;__SHRT_MAX__;0x7fff;__INT_MAX__;0x7fffffff;__LONG_MAX__;0x7fffffffffffffffL;__LONG_LONG_MAX__;0x7fffffffffffffffLL;__WCHAR_MAX__;0x7fffffff;__WCHAR_MIN__;(-__WCHAR_MAX__ - 1);__WINT_MAX__;0xffffffffU;__WINT_MIN__;0U;__PTRDIFF_MAX__;0x7fffffffffffffffL;__SIZE_MAX__;0xffffffffffffffffUL;__SCHAR_WIDTH__;8;__SHRT_WIDTH__;16;__INT_WIDTH__;32;__LONG_WIDTH__;64;__LONG_LONG_WIDTH__;64;__WCHAR_WIDTH__;32;__WINT_WIDTH__;32;__PTRDIFF_WIDTH__;64;__SIZE_WIDTH__;64;__INTMAX_MAX__;0x7fffffffffffffffL;__INTMAX_C(c);c ## L;__UINTMAX_MAX__;0xffffffffffffffffUL;__UINTMAX_C(c);c ## UL;__INTMAX_WIDTH__;64;__SIG_ATOMIC_MAX__;0x7fffffff;__SIG_ATOMIC_MIN__;(-__SIG_ATOMIC_MAX__ - 1);__SIG_ATOMIC_WIDTH__;32;__INT8_MAX__;0x7f;__INT16_MAX__;0x7fff;__INT32_MAX__;0x7fffffff;__INT64_MAX__;0x7fffffffffffffffL;__UINT8_MAX__;0xff;__UINT16_MAX__;0xffff;__UINT32_MAX__;0xffffffffU;__UINT64_MAX__;0xffffffffffffffffUL;__INT_LEAST8_MAX__;0x7f;__INT8_C(c);c;__INT_LEAST8_WIDTH__;8;__INT_LEAST16_MAX__;0x7fff;__INT16_C(c);c;__INT_LEAST16_WIDTH__;16;__INT_LEAST32_MAX__;0x7fffffff;__INT32_C(c);c;__INT_LEAST32_WIDTH__;32;__INT_LEAST64_MAX__;0x7fffffffffffffffL;__INT64_C(c);c ## L;__INT_LEAST64_WIDTH__;64;__UINT_LEAST8_MAX__;0xff;__UINT8_C(c);c;__UINT_LEAST16_MAX__;0xffff;__UINT16_C(c);c;__UINT_LEAST32_MAX__;0xffffffffU;__UINT32_C(c);c ## U;__UINT_LEAST64_MAX__;0xffffffffffffffffUL;__UINT64_C(c);c ## UL;__INT_FAST8_MAX__;0x7f;__INT_FAST8_WIDTH__;8;__INT_FAST16_MAX__;0x7fffffffffffffffL;__INT_FAST16_WIDTH__;64;__INT_FAST32_MAX__;0x7fffffffffffffffL;__INT_FAST32_WIDTH__;64;__INT_FAST64_MAX__;0x7fffffffffffffffL;__INT_FAST64_WIDTH__;64;__UINT_FAST8_MAX__;0xff;__UINT_FAST16_MAX__;0xffffffffffffffffUL;__UINT_FAST32_MAX__;0xffffffffffffffffUL;__UINT_FAST64_MAX__;0xffffffffffffffffUL;__INTPTR_MAX__;0x7fffffffffffffffL;__INTPTR_WIDTH__;64;__UINTPTR_MAX__;0xffffffffffffffffUL;__GCC_IEC_559;2;__GCC_IEC_559_COMPLEX;2;__FLT_EVAL_METHOD__;0;__FLT_EVAL_METHOD_TS_18661_3__;0;__DEC_EVAL_METHOD__;2;__FLT_RADIX__;2;__FLT_MANT_DIG__;24;__FLT_DIG__;6;__FLT_MIN_EXP__;(-125);__FLT_MIN_10_EXP__;(-37);__FLT_MAX_EXP__;128;__FLT_MAX_10_EXP__;38;__FLT_DECIMAL_DIG__;9;__FLT_MAX__;3.40282346638528859811704183484516925e+38F;__FLT_MIN__;1.17549435082228750796873653722224568e-38F;__FLT_EPSILON__;1.19209289550781250000000000000000000e-7F;__FLT_DENORM_MIN__;1.40129846432481707092372958328991613e-45F;__FLT_HAS_DENORM__;1;__FLT_HAS_INFINITY__;1;__FLT_HAS_QUIET_NAN__;1;__DBL_MANT_DIG__;53;__DBL_DIG__;15;__DBL_MIN_EXP__;(-1021);__DBL_MIN_10_EXP__;(-307);__DBL_MAX_EXP__;1024;__DBL_MAX_10_EXP__;308;__DBL_DECIMAL_DIG__;17;__DBL_MAX__;((double)1.79769313486231570814527423731704357e+308L);__DBL_MIN__;((double)2.22507385850720138309023271733240406e-308L);__DBL_EPSILON__;((double)2.22044604925031308084726333618164062e-16L);__DBL_DENORM_MIN__;((double)4.94065645841246544176568792868221372e-324L);__DBL_HAS_DENORM__;1;__DBL_HAS_INFINITY__;1;__DBL_HAS_QUIET_NAN__;1;__LDBL_MANT_DIG__;64;__LDBL_DIG__;18;__LDBL_MIN_EXP__;(-16381);__LDBL_MIN_10_EXP__;(-4931);__LDBL_MAX_EXP__;16384;__LDBL_MAX_10_EXP__;4932;__DECIMAL_DIG__;21;__LDBL_DECIMAL_DIG__;21;__LDBL_MAX__;1.18973149535723176502126385303097021e+4932L;__LDBL_MIN__;3.36210314311209350626267781732175260e-4932L;__LDBL_EPSILON__;1.08420217248550443400745280086994171e-19L;__LDBL_DENORM_MIN__;3.64519953188247460252840593361941982e-4951L;__LDBL_HAS_DENORM__;1;__LDBL_HAS_INFINITY__;1;__LDBL_HAS_QUIET_NAN__;1;__FLT32_MANT_DIG__;24;__FLT32_DIG__;6;__FLT32_MIN_EXP__;(-125);__FLT32_MIN_10_EXP__;(-37);__FLT32_MAX_EXP__;128;__FLT32_MAX_10_EXP__;38;__FLT32_DECIMAL_DIG__;9;__FLT32_MAX__;3.40282346638528859811704183484516925e+38F32;__FLT32_MIN__;1.17549435082228750796873653722224568e-38F32;__FLT32_EPSILON__;1.19209289550781250000000000000000000e-7F32;__FLT32_DENORM_MIN__;1.40129846432481707092372958328991613e-45F32;__FLT32_HAS_DENORM__;1;__FLT32_HAS_INFINITY__;1;__FLT32_HAS_QUIET_NAN__;1;__FLT64_MANT_DIG__;53;__FLT64_DIG__;15;__FLT64_MIN_EXP__;(-1021);__FLT64_MIN_10_EXP__;(-307);__FLT64_MAX_EXP__;1024;__FLT64_MAX_10_EXP__;308;__FLT64_DECIMAL_DIG__;17;__FLT64_MAX__;1.79769313486231570814527423731704357e+308F64;__FLT64_MIN__;2.22507385850720138309023271733240406e-308F64;__FLT64_EPSILON__;2.22044604925031308084726333618164062e-16F64;__FLT64_DENORM_MIN__;4.94065645841246544176568792868221372e-324F64;__FLT64_HAS_DENORM__;1;__FLT64_HAS_INFINITY__;1;__FLT64_HAS_QUIET_NAN__;1;__FLT128_MANT_DIG__;113;__FLT128_DIG__;33;__FLT128_MIN_EXP__;(-16381);__FLT128_MIN_10_EXP__;(-4931);__FLT128_MAX_EXP__;16384;__FLT128_MAX_10_EXP__;4932;__FLT128_DECIMAL_DIG__;36;__FLT128_MAX__;1.18973149535723176508575932662800702e+4932F128;__FLT128_MIN__;3.36210314311209350626267781732175260e-4932F128;__FLT128_EPSILON__;1.92592994438723585305597794258492732e-34F128;__FLT128_DENORM_MIN__;6.47517511943802511092443895822764655e-4966F128;__FLT128_HAS_DENORM__;1;__FLT128_HAS_INFINITY__;1;__FLT128_HAS_QUIET_NAN__;1;__FLT32X_MANT_DIG__;53;__FLT32X_DIG__;15;__FLT32X_MIN_EXP__;(-1021);__FLT32X_MIN_10_EXP__;(-307);__FLT32X_MAX_EXP__;1024;__FLT32X_MAX_10_EXP__;308;__FLT32X_DECIMAL_DIG__;17;__FLT32X_MAX__;1.79769313486231570814527423731704357e+308F32x;__FLT32X_MIN__;2.22507385850720138309023271733240406e-308F32x;__FLT32X_EPSILON__;2.22044604925031308084726333618164062e-16F32x;__FLT32X_DENORM_MIN__;4.94065645841246544176568792868221372e-324F32x;__FLT32X_HAS_DENORM__;1;__FLT32X_HAS_INFINITY__;1;__FLT32X_HAS_QUIET_NAN__;1;__FLT64X_MANT_DIG__;64;__FLT64X_DIG__;18;__FLT64X_MIN_EXP__;(-16381);__FLT64X_MIN_10_EXP__;(-4931);__FLT64X_MAX_EXP__;16384;__FLT64X_MAX_10_EXP__;4932;__FLT64X_DECIMAL_DIG__;21;__FLT64X_MAX__;1.18973149535723176502126385303097021e+4932F64x;__FLT64X_MIN__;3.36210314311209350626267781732175260e-4932F64x;__FLT64X_EPSILON__;1.08420217248550443400745280086994171e-19F64x;__FLT64X_DENORM_MIN__;3.64519953188247460252840593361941982e-4951F64x;__FLT64X_HAS_DENORM__;1;__FLT64X_HAS_INFINITY__;1;__FLT64X_HAS_QUIET_NAN__;1;__DEC32_MANT_DIG__;7;__DEC32_MIN_EXP__;(-94);__DEC32_MAX_EXP__;97;__DEC32_MIN__;1E-95DF;__DEC32_MAX__;9.999999E96DF;__DEC32_EPSILON__;1E-6DF;__DEC32_SUBNORMAL_MIN__;0.000001E-95DF;__DEC64_MANT_DIG__;16;__DEC64_MIN_EXP__;(-382);__DEC64_MAX_EXP__;385;__DEC64_MIN__;1E-383DD;__DEC64_MAX__;9.999999999999999E384DD;__DEC64_EPSILON__;1E-15DD;__DEC64_SUBNORMAL_MIN__;0.000000000000001E-383DD;__DEC128_MANT_DIG__;34;__DEC128_MIN_EXP__;(-6142);__DEC128_MAX_EXP__;6145;__DEC128_MIN__;1E-6143DL;__DEC128_MAX__;9.999999999999999999999999999999999E6144DL;__DEC128_EPSILON__;1E-33DL;__DEC128_SUBNORMAL_MIN__;0.000000000000000000000000000000001E-6143DL;__REGISTER_PREFIX__; ;__USER_LABEL_PREFIX__; ;__GNUC_STDC_INLINE__;1;__NO_INLINE__;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8;1;__GCC_ATOMIC_BOOL_LOCK_FREE;2;__GCC_ATOMIC_CHAR_LOCK_FREE;2;__GCC_ATOMIC_CHAR16_T_LOCK_FREE;2;__GCC_ATOMIC_CHAR32_T_LOCK_FREE;2;__GCC_ATOMIC_WCHAR_T_LOCK_FREE;2;__GCC_ATOMIC_SHORT_LOCK_FREE;2;__GCC_ATOMIC_INT_LOCK_FREE;2;__GCC_ATOMIC_LONG_LOCK_FREE;2;__GCC_ATOMIC_LLONG_LOCK_FREE;2;__GCC_ATOMIC_TEST_AND_SET_TRUEVAL;1;__GCC_ATOMIC_POINTER_LOCK_FREE;2;__GCC_HAVE_DWARF2_CFI_ASM;1;__PRAGMA_REDEFINE_EXTNAME;1;__SSP_STRONG__;3;__SIZEOF_INT128__;16;__SIZEOF_WCHAR_T__;4;__SIZEOF_WINT_T__;4;__SIZEOF_PTRDIFF_T__;8;__amd64;1;__amd64__;1;__x86_64;1;__x86_64__;1;__SIZEOF_FLOAT80__;16;__SIZEOF_FLOAT128__;16;__ATOMIC_HLE_ACQUIRE;65536;__ATOMIC_HLE_RELEASE;131072;__GCC_ASM_FLAG_OUTPUTS__;1;__k8;1;__k8__;1;__code_model_small__;1;__MMX__;1;__SSE__;1;__SSE2__;1;__FXSR__;1;__SSE_MATH__;1;__SSE2_MATH__;1;__SEG_FS;1;__SEG_GS;1;__gnu_linux__;1;__linux;1;__linux__;1;linux;1;__unix;1;__unix__;1;unix;1;__ELF__;1;__DECIMAL_BID_FORMAT__;1;_STDC_PREDEF_H;1;__STDC_IEC_559__;1;__STDC_IEC_559_COMPLEX__;1;__STDC_ISO_10646__;201706L;__STDC_NO_THREADS__;1;__STDC__;1;__cplusplus;201402L;__STDC_UTF_16__;1;__STDC_UTF_32__;1;__STDC_HOSTED__;1;__GNUC__;7;__GNUC_MINOR__;5;__GNUC_PATCHLEVEL__;0;__VERSION__;"7.5.0";__ATOMIC_RELAXED;0;__ATOMIC_SEQ_CST;5;__ATOMIC_ACQUIRE;2;__ATOMIC_RELEASE;3;__ATOMIC_ACQ_REL;4;__ATOMIC_CONSUME;1;__pic__;2;__PIC__;2;__pie__;2;__PIE__;2;__FINITE_MATH_ONLY__;0;_LP64;1;__LP64__;1;__SIZEOF_INT__;4;__SIZEOF_LONG__;8;__SIZEOF_LONG_LONG__;8;__SIZEOF_SHORT__;2;__SIZEOF_FLOAT__;4;__SIZEOF_DOUBLE__;8;__SIZEOF_LONG_DOUBLE__;16;__SIZEOF_SIZE_T__;8;__CHAR_BIT__;8;__BIGGEST_ALIGNMENT__;16;__ORDER_LITTLE_ENDIAN__;1234;__ORDER_BIG_ENDIAN__;4321;__ORDER_PDP_ENDIAN__;3412;__BYTE_ORDER__;__ORDER_LITTLE_ENDIAN__;__FLOAT_WORD_ORDER__;__ORDER_LITTLE_ENDIAN__;__SIZEOF_POINTER__;8;__GNUG__;7;__SIZE_TYPE__;long unsigned int;__PTRDIFF_TYPE__;long int;__WCHAR_TYPE__;int;__WINT_TYPE__;unsigned int;__INTMAX_TYPE__;long int;__UINTMAX_TYPE__;long unsigned int;__CHAR16_TYPE__;short unsigned int;__CHAR32_TYPE__;unsigned int;__SIG_ATOMIC_TYPE__;int;__INT8_TYPE__;signed char;__INT16_TYPE__;short int;__INT32_TYPE__;int;__INT64_TYPE__;long int;__UINT8_TYPE__;unsigned char;__UINT16_TYPE__;short unsigned int;__UINT32_TYPE__;unsigned int;__UINT64_TYPE__;long unsigned int;__INT_LEAST8_TYPE__;signed char;__INT_LEAST16_TYPE__;short int;__INT_LEAST32_TYPE__;int;__INT_LEAST64_TYPE__;long int;__UINT_LEAST8_TYPE__;unsigned char;__UINT_LEAST16_TYPE__;short unsigned int;__UINT_LEAST32_TYPE__;unsigned int;__UINT_LEAST64_TYPE__;long unsigned int;__INT_FAST8_TYPE__;signed char;__INT_FAST16_TYPE__;long int;__INT_FAST32_TYPE__;long int;__INT_FAST64_TYPE__;long int;__UINT_FAST8_TYPE__;unsigned char;__UINT_FAST16_TYPE__;long unsigned int;__UINT_FAST32_TYPE__;long unsigned int;__UINT_FAST64_TYPE__;long unsigned int;__INTPTR_TYPE__;long int;__UINTPTR_TYPE__;long unsigned int;__has_include(STR);__has_include__(STR);__has_include_next(STR);__has_include_next__(STR);__GXX_WEAK__;1;__DEPRECATED;1;__GXX_RTTI;1;__cpp_rtti;199711;__GXX_EXPERIMENTAL_CXX0X__;1;__cpp_binary_literals;201304;__cpp_hex_float;201603;__cpp_runtime_arrays;198712;__cpp_unicode_characters;200704;__cpp_raw_strings;200710;__cpp_unicode_literals;200710;__cpp_user_defined_literals;200809;__cpp_lambdas;200907;__cpp_range_based_for;200907;__cpp_static_assert;200410;__cpp_decltype;200707;__cpp_attributes;200809;__cpp_rvalue_reference;200610;__cpp_rvalue_references;200610;__cpp_variadic_templates;200704;__cpp_initializer_lists;200806;__cpp_delegating_constructors;200604;__cpp_nsdmi;200809;__cpp_inheriting_constructors;201511;__cpp_ref_qualifiers;200710;__cpp_alias_templates;200704;__cpp_return_type_deduction;201304;__cpp_init_captures;201304;__cpp_generic_lambdas;201304;__cpp_constexpr;201304;__cpp_decltype_auto;201304;__cpp_aggregate_nsdmi;201304;__cpp_variable_templates;201304;__cpp_digit_separators;201309;__cpp_sized_deallocation;201309;__cpp_threadsafe_static_init;200806;__EXCEPTIONS;1;__cpp_exceptions;199711;__GXX_ABI_VERSION;1011;__SCHAR_MAX__;0x7f;__SHRT_MAX__;0x7fff;__INT_MAX__;0x7fffffff;__LONG_MAX__;0x7fffffffffffffffL;__LONG_LONG_MAX__;0x7fffffffffffffffLL;__WCHAR_MAX__;0x7fffffff;__WCHAR_MIN__;(-__WCHAR_MAX__ - 1);__WINT_MAX__;0xffffffffU;__WINT_MIN__;0U;__PTRDIFF_MAX__;0x7fffffffffffffffL;__SIZE_MAX__;0xffffffffffffffffUL;__SCHAR_WIDTH__;8;__SHRT_WIDTH__;16;__INT_WIDTH__;32;__LONG_WIDTH__;64;__LONG_LONG_WIDTH__;64;__WCHAR_WIDTH__;32;__WINT_WIDTH__;32;__PTRDIFF_WIDTH__;64;__SIZE_WIDTH__;64;__GLIBCXX_TYPE_INT_N_0;__int128;__GLIBCXX_BITSIZE_INT_N_0;128;__INTMAX_MAX__;0x7fffffffffffffffL;__INTMAX_C(c);c ## L;__UINTMAX_MAX__;0xffffffffffffffffUL;__UINTMAX_C(c);c ## UL;__INTMAX_WIDTH__;64;__SIG_ATOMIC_MAX__;0x7fffffff;__SIG_ATOMIC_MIN__;(-__SIG_ATOMIC_MAX__ - 1);__SIG_ATOMIC_WIDTH__;32;__INT8_MAX__;0x7f;__INT16_MAX__;0x7fff;__INT32_MAX__;0x7fffffff;__INT64_MAX__;0x7fffffffffffffffL;__UINT8_MAX__;0xff;__UINT16_MAX__;0xffff;__UINT32_MAX__;0xffffffffU;__UINT64_MAX__;0xffffffffffffffffUL;__INT_LEAST8_MAX__;0x7f;__INT8_C(c);c;__INT_LEAST8_WIDTH__;8;__INT_LEAST16_MAX__;0x7fff;__INT16_C(c);c;__INT_LEAST16_WIDTH__;16;__INT_LEAST32_MAX__;0x7fffffff;__INT32_C(c);c;__INT_LEAST32_WIDTH__;32;__INT_LEAST64_MAX__;0x7fffffffffffffffL;__INT64_C(c);c ## L;__INT_LEAST64_WIDTH__;64;__UINT_LEAST8_MAX__;0xff;__UINT8_C(c);c;__UINT_LEAST16_MAX__;0xffff;__UINT16_C(c);c;__UINT_LEAST32_MAX__;0xffffffffU;__UINT32_C(c);c ## U;__UINT_LEAST64_MAX__;0xffffffffffffffffUL;__UINT64_C(c);c ## UL;__INT_FAST8_MAX__;0x7f;__INT_FAST8_WIDTH__;8;__INT_FAST16_MAX__;0x7fffffffffffffffL;__INT_FAST16_WIDTH__;64;__INT_FAST32_MAX__;0x7fffffffffffffffL;__INT_FAST32_WIDTH__;64;__INT_FAST64_MAX__;0x7fffffffffffffffL;__INT_FAST64_WIDTH__;64;__UINT_FAST8_MAX__;0xff;__UINT_FAST16_MAX__;0xffffffffffffffffUL;__UINT_FAST32_MAX__;0xffffffffffffffffUL;__UINT_FAST64_MAX__;0xffffffffffffffffUL;__INTPTR_MAX__;0x7fffffffffffffffL;__INTPTR_WIDTH__;64;__UINTPTR_MAX__;0xffffffffffffffffUL;__GCC_IEC_559;2;__GCC_IEC_559_COMPLEX;2;__FLT_EVAL_METHOD__;0;__FLT_EVAL_METHOD_TS_18661_3__;0;__DEC_EVAL_METHOD__;2;__FLT_RADIX__;2;__FLT_MANT_DIG__;24;__FLT_DIG__;6;__FLT_MIN_EXP__;(-125);__FLT_MIN_10_EXP__;(-37);__FLT_MAX_EXP__;128;__FLT_MAX_10_EXP__;38;__FLT_DECIMAL_DIG__;9;__FLT_MAX__;3.40282346638528859811704183484516925e+38F;__FLT_MIN__;1.17549435082228750796873653722224568e-38F;__FLT_EPSILON__;1.19209289550781250000000000000000000e-7F;__FLT_DENORM_MIN__;1.40129846432481707092372958328991613e-45F;__FLT_HAS_DENORM__;1;__FLT_HAS_INFINITY__;1;__FLT_HAS_QUIET_NAN__;1;__DBL_MANT_DIG__;53;__DBL_DIG__;15;__DBL_MIN_EXP__;(-1021);__DBL_MIN_10_EXP__;(-307);__DBL_MAX_EXP__;1024;__DBL_MAX_10_EXP__;308;__DBL_DECIMAL_DIG__;17;__DBL_MAX__;double(1.79769313486231570814527423731704357e+308L);__DBL_MIN__;double(2.22507385850720138309023271733240406e-308L);__DBL_EPSILON__;double(2.22044604925031308084726333618164062e-16L);__DBL_DENORM_MIN__;double(4.94065645841246544176568792868221372e-324L);__DBL_HAS_DENORM__;1;__DBL_HAS_INFINITY__;1;__DBL_HAS_QUIET_NAN__;1;__LDBL_MANT_DIG__;64;__LDBL_DIG__;18;__LDBL_MIN_EXP__;(-16381);__LDBL_MIN_10_EXP__;(-4931);__LDBL_MAX_EXP__;16384;__LDBL_MAX_10_EXP__;4932;__DECIMAL_DIG__;21;__LDBL_DECIMAL_DIG__;21;__LDBL_MAX__;1.18973149535723176502126385303097021e+4932L;__LDBL_MIN__;3.36210314311209350626267781732175260e-4932L;__LDBL_EPSILON__;1.08420217248550443400745280086994171e-19L;__LDBL_DENORM_MIN__;3.64519953188247460252840593361941982e-4951L;__LDBL_HAS_DENORM__;1;__LDBL_HAS_INFINITY__;1;__LDBL_HAS_QUIET_NAN__;1;__FLT32_MANT_DIG__;24;__FLT32_DIG__;6;__FLT32_MIN_EXP__;(-125);__FLT32_MIN_10_EXP__;(-37);__FLT32_MAX_EXP__;128;__FLT32_MAX_10_EXP__;38;__FLT32_DECIMAL_DIG__;9;__FLT32_MAX__;3.40282346638528859811704183484516925e+38F32;__FLT32_MIN__;1.17549435082228750796873653722224568e-38F32;__FLT32_EPSILON__;1.19209289550781250000000000000000000e-7F32;__FLT32_DENORM_MIN__;1.40129846432481707092372958328991613e-45F32;__FLT32_HAS_DENORM__;1;__FLT32_HAS_INFINITY__;1;__FLT32_HAS_QUIET_NAN__;1;__FLT64_MANT_DIG__;53;__FLT64_DIG__;15;__FLT64_MIN_EXP__;(-1021);__FLT64_MIN_10_EXP__;(-307);__FLT64_MAX_EXP__;1024;__FLT64_MAX_10_EXP__;308;__FLT64_DECIMAL_DIG__;17;__FLT64_MAX__;1.79769313486231570814527423731704357e+308F64;__FLT64_MIN__;2.22507385850720138309023271733240406e-308F64;__FLT64_EPSILON__;2.22044604925031308084726333618164062e-16F64;__FLT64_DENORM_MIN__;4.94065645841246544176568792868221372e-324F64;__FLT64_HAS_DENORM__;1;__FLT64_HAS_INFINITY__;1;__FLT64_HAS_QUIET_NAN__;1;__FLT128_MANT_DIG__;113;__FLT128_DIG__;33;__FLT128_MIN_EXP__;(-16381);__FLT128_MIN_10_EXP__;(-4931);__FLT128_MAX_EXP__;16384;__FLT128_MAX_10_EXP__;4932;__FLT128_DECIMAL_DIG__;36;__FLT128_MAX__;1.18973149535723176508575932662800702e+4932F128;__FLT128_MIN__;3.36210314311209350626267781732175260e-4932F128;__FLT128_EPSILON__;1.92592994438723585305597794258492732e-34F128;__FLT128_DENORM_MIN__;6.47517511943802511092443895822764655e-4966F128;__FLT128_HAS_DENORM__;1;__FLT128_HAS_INFINITY__;1;__FLT128_HAS_QUIET_NAN__;1;__FLT32X_MANT_DIG__;53;__FLT32X_DIG__;15;__FLT32X_MIN_EXP__;(-1021);__FLT32X_MIN_10_EXP__;(-307);__FLT32X_MAX_EXP__;1024;__FLT32X_MAX_10_EXP__;308;__FLT32X_DECIMAL_DIG__;17;__FLT32X_MAX__;1.79769313486231570814527423731704357e+308F32x;__FLT32X_MIN__;2.22507385850720138309023271733240406e-308F32x;__FLT32X_EPSILON__;2.22044604925031308084726333618164062e-16F32x;__FLT32X_DENORM_MIN__;4.94065645841246544176568792868221372e-324F32x;__FLT32X_HAS_DENORM__;1;__FLT32X_HAS_INFINITY__;1;__FLT32X_HAS_QUIET_NAN__;1;__FLT64X_MANT_DIG__;64;__FLT64X_DIG__;18;__FLT64X_MIN_EXP__;(-16381);__FLT64X_MIN_10_EXP__;(-4931);__FLT64X_MAX_EXP__;16384;__FLT64X_MAX_10_EXP__;4932;__FLT64X_DECIMAL_DIG__;21;__FLT64X_MAX__;1.18973149535723176502126385303097021e+4932F64x;__FLT64X_MIN__;3.36210314311209350626267781732175260e-4932F64x;__FLT64X_EPSILON__;1.08420217248550443400745280086994171e-19F64x;__FLT64X_DENORM_MIN__;3.64519953188247460252840593361941982e-4951F64x;__FLT64X_HAS_DENORM__;1;__FLT64X_HAS_INFINITY__;1;__FLT64X_HAS_QUIET_NAN__;1;__DEC32_MANT_DIG__;7;__DEC32_MIN_EXP__;(-94);__DEC32_MAX_EXP__;97;__DEC32_MIN__;1E-95DF;__DEC32_MAX__;9.999999E96DF;__DEC32_EPSILON__;1E-6DF;__DEC32_SUBNORMAL_MIN__;0.000001E-95DF;__DEC64_MANT_DIG__;16;__DEC64_MIN_EXP__;(-382);__DEC64_MAX_EXP__;385;__DEC64_MIN__;1E-383DD;__DEC64_MAX__;9.999999999999999E384DD;__DEC64_EPSILON__;1E-15DD;__DEC64_SUBNORMAL_MIN__;0.000000000000001E-383DD;__DEC128_MANT_DIG__;34;__DEC128_MIN_EXP__;(-6142);__DEC128_MAX_EXP__;6145;__DEC128_MIN__;1E-6143DL;__DEC128_MAX__;9.999999999999999999999999999999999E6144DL;__DEC128_EPSILON__;1E-33DL;__DEC128_SUBNORMAL_MIN__;0.000000000000000000000000000000001E-6143DL;__REGISTER_PREFIX__; ;__USER_LABEL_PREFIX__; ;__GNUC_STDC_INLINE__;1;__NO_INLINE__;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8;1;__GCC_ATOMIC_BOOL_LOCK_FREE;2;__GCC_ATOMIC_CHAR_LOCK_FREE;2;__GCC_ATOMIC_CHAR16_T_LOCK_FREE;2;__GCC_ATOMIC_CHAR32_T_LOCK_FREE;2;__GCC_ATOMIC_WCHAR_T_LOCK_FREE;2;__GCC_ATOMIC_SHORT_LOCK_FREE;2;__GCC_ATOMIC_INT_LOCK_FREE;2;__GCC_ATOMIC_LONG_LOCK_FREE;2;__GCC_ATOMIC_LLONG_LOCK_FREE;2;__GCC_ATOMIC_TEST_AND_SET_TRUEVAL;1;__GCC_ATOMIC_POINTER_LOCK_FREE;2;__GCC_HAVE_DWARF2_CFI_ASM;1;__PRAGMA_REDEFINE_EXTNAME;1;__SSP_STRONG__;3;__SIZEOF_INT128__;16;__SIZEOF_WCHAR_T__;4;__SIZEOF_WINT_T__;4;__SIZEOF_PTRDIFF_T__;8;__amd64;1;__amd64__;1;__x86_64;1;__x86_64__;1;__SIZEOF_FLOAT80__;16;__SIZEOF_FLOAT128__;16;__ATOMIC_HLE_ACQUIRE;65536;__ATOMIC_HLE_RELEASE;131072;__GCC_ASM_FLAG_OUTPUTS__;1;__k8;1;__k8__;1;__code_model_small__;1;__MMX__;1;__SSE__;1;__SSE2__;1;__FXSR__;1;__SSE_MATH__;1;__SSE2_MATH__;1;__SEG_FS;1;__SEG_GS;1;__gnu_linux__;1;__linux;1;__linux__;1;linux;1;__unix;1;__unix__;1;unix;1;__ELF__;1;__DECIMAL_BID_FORMAT__;1;_GNU_SOURCE;1;_STDC_PREDEF_H;1;__STDC_IEC_559__;1;__STDC_IEC_559_COMPLEX__;1;__STDC_ISO_10646__;201706L;__STDC_NO_THREADS__;1 +//CXX compiler system include directories +CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS:INTERNAL=/usr/include/c++/7;/usr/include/x86_64-linux-gnu/c++/7;/usr/include/c++/7/backward;/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include +//C compiler system defined macros +CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS:INTERNAL=__STDC__;1;__STDC_VERSION__;201112L;__STDC_UTF_16__;1;__STDC_UTF_32__;1;__STDC_HOSTED__;1;__GNUC__;7;__GNUC_MINOR__;5;__GNUC_PATCHLEVEL__;0;__VERSION__;"7.5.0";__ATOMIC_RELAXED;0;__ATOMIC_SEQ_CST;5;__ATOMIC_ACQUIRE;2;__ATOMIC_RELEASE;3;__ATOMIC_ACQ_REL;4;__ATOMIC_CONSUME;1;__pic__;2;__PIC__;2;__pie__;2;__PIE__;2;__FINITE_MATH_ONLY__;0;_LP64;1;__LP64__;1;__SIZEOF_INT__;4;__SIZEOF_LONG__;8;__SIZEOF_LONG_LONG__;8;__SIZEOF_SHORT__;2;__SIZEOF_FLOAT__;4;__SIZEOF_DOUBLE__;8;__SIZEOF_LONG_DOUBLE__;16;__SIZEOF_SIZE_T__;8;__CHAR_BIT__;8;__BIGGEST_ALIGNMENT__;16;__ORDER_LITTLE_ENDIAN__;1234;__ORDER_BIG_ENDIAN__;4321;__ORDER_PDP_ENDIAN__;3412;__BYTE_ORDER__;__ORDER_LITTLE_ENDIAN__;__FLOAT_WORD_ORDER__;__ORDER_LITTLE_ENDIAN__;__SIZEOF_POINTER__;8;__SIZE_TYPE__;long unsigned int;__PTRDIFF_TYPE__;long int;__WCHAR_TYPE__;int;__WINT_TYPE__;unsigned int;__INTMAX_TYPE__;long int;__UINTMAX_TYPE__;long unsigned int;__CHAR16_TYPE__;short unsigned int;__CHAR32_TYPE__;unsigned int;__SIG_ATOMIC_TYPE__;int;__INT8_TYPE__;signed char;__INT16_TYPE__;short int;__INT32_TYPE__;int;__INT64_TYPE__;long int;__UINT8_TYPE__;unsigned char;__UINT16_TYPE__;short unsigned int;__UINT32_TYPE__;unsigned int;__UINT64_TYPE__;long unsigned int;__INT_LEAST8_TYPE__;signed char;__INT_LEAST16_TYPE__;short int;__INT_LEAST32_TYPE__;int;__INT_LEAST64_TYPE__;long int;__UINT_LEAST8_TYPE__;unsigned char;__UINT_LEAST16_TYPE__;short unsigned int;__UINT_LEAST32_TYPE__;unsigned int;__UINT_LEAST64_TYPE__;long unsigned int;__INT_FAST8_TYPE__;signed char;__INT_FAST16_TYPE__;long int;__INT_FAST32_TYPE__;long int;__INT_FAST64_TYPE__;long int;__UINT_FAST8_TYPE__;unsigned char;__UINT_FAST16_TYPE__;long unsigned int;__UINT_FAST32_TYPE__;long unsigned int;__UINT_FAST64_TYPE__;long unsigned int;__INTPTR_TYPE__;long int;__UINTPTR_TYPE__;long unsigned int;__has_include(STR);__has_include__(STR);__has_include_next(STR);__has_include_next__(STR);__GXX_ABI_VERSION;1011;__SCHAR_MAX__;0x7f;__SHRT_MAX__;0x7fff;__INT_MAX__;0x7fffffff;__LONG_MAX__;0x7fffffffffffffffL;__LONG_LONG_MAX__;0x7fffffffffffffffLL;__WCHAR_MAX__;0x7fffffff;__WCHAR_MIN__;(-__WCHAR_MAX__ - 1);__WINT_MAX__;0xffffffffU;__WINT_MIN__;0U;__PTRDIFF_MAX__;0x7fffffffffffffffL;__SIZE_MAX__;0xffffffffffffffffUL;__SCHAR_WIDTH__;8;__SHRT_WIDTH__;16;__INT_WIDTH__;32;__LONG_WIDTH__;64;__LONG_LONG_WIDTH__;64;__WCHAR_WIDTH__;32;__WINT_WIDTH__;32;__PTRDIFF_WIDTH__;64;__SIZE_WIDTH__;64;__INTMAX_MAX__;0x7fffffffffffffffL;__INTMAX_C(c);c ## L;__UINTMAX_MAX__;0xffffffffffffffffUL;__UINTMAX_C(c);c ## UL;__INTMAX_WIDTH__;64;__SIG_ATOMIC_MAX__;0x7fffffff;__SIG_ATOMIC_MIN__;(-__SIG_ATOMIC_MAX__ - 1);__SIG_ATOMIC_WIDTH__;32;__INT8_MAX__;0x7f;__INT16_MAX__;0x7fff;__INT32_MAX__;0x7fffffff;__INT64_MAX__;0x7fffffffffffffffL;__UINT8_MAX__;0xff;__UINT16_MAX__;0xffff;__UINT32_MAX__;0xffffffffU;__UINT64_MAX__;0xffffffffffffffffUL;__INT_LEAST8_MAX__;0x7f;__INT8_C(c);c;__INT_LEAST8_WIDTH__;8;__INT_LEAST16_MAX__;0x7fff;__INT16_C(c);c;__INT_LEAST16_WIDTH__;16;__INT_LEAST32_MAX__;0x7fffffff;__INT32_C(c);c;__INT_LEAST32_WIDTH__;32;__INT_LEAST64_MAX__;0x7fffffffffffffffL;__INT64_C(c);c ## L;__INT_LEAST64_WIDTH__;64;__UINT_LEAST8_MAX__;0xff;__UINT8_C(c);c;__UINT_LEAST16_MAX__;0xffff;__UINT16_C(c);c;__UINT_LEAST32_MAX__;0xffffffffU;__UINT32_C(c);c ## U;__UINT_LEAST64_MAX__;0xffffffffffffffffUL;__UINT64_C(c);c ## UL;__INT_FAST8_MAX__;0x7f;__INT_FAST8_WIDTH__;8;__INT_FAST16_MAX__;0x7fffffffffffffffL;__INT_FAST16_WIDTH__;64;__INT_FAST32_MAX__;0x7fffffffffffffffL;__INT_FAST32_WIDTH__;64;__INT_FAST64_MAX__;0x7fffffffffffffffL;__INT_FAST64_WIDTH__;64;__UINT_FAST8_MAX__;0xff;__UINT_FAST16_MAX__;0xffffffffffffffffUL;__UINT_FAST32_MAX__;0xffffffffffffffffUL;__UINT_FAST64_MAX__;0xffffffffffffffffUL;__INTPTR_MAX__;0x7fffffffffffffffL;__INTPTR_WIDTH__;64;__UINTPTR_MAX__;0xffffffffffffffffUL;__GCC_IEC_559;2;__GCC_IEC_559_COMPLEX;2;__FLT_EVAL_METHOD__;0;__FLT_EVAL_METHOD_TS_18661_3__;0;__DEC_EVAL_METHOD__;2;__FLT_RADIX__;2;__FLT_MANT_DIG__;24;__FLT_DIG__;6;__FLT_MIN_EXP__;(-125);__FLT_MIN_10_EXP__;(-37);__FLT_MAX_EXP__;128;__FLT_MAX_10_EXP__;38;__FLT_DECIMAL_DIG__;9;__FLT_MAX__;3.40282346638528859811704183484516925e+38F;__FLT_MIN__;1.17549435082228750796873653722224568e-38F;__FLT_EPSILON__;1.19209289550781250000000000000000000e-7F;__FLT_DENORM_MIN__;1.40129846432481707092372958328991613e-45F;__FLT_HAS_DENORM__;1;__FLT_HAS_INFINITY__;1;__FLT_HAS_QUIET_NAN__;1;__DBL_MANT_DIG__;53;__DBL_DIG__;15;__DBL_MIN_EXP__;(-1021);__DBL_MIN_10_EXP__;(-307);__DBL_MAX_EXP__;1024;__DBL_MAX_10_EXP__;308;__DBL_DECIMAL_DIG__;17;__DBL_MAX__;((double)1.79769313486231570814527423731704357e+308L);__DBL_MIN__;((double)2.22507385850720138309023271733240406e-308L);__DBL_EPSILON__;((double)2.22044604925031308084726333618164062e-16L);__DBL_DENORM_MIN__;((double)4.94065645841246544176568792868221372e-324L);__DBL_HAS_DENORM__;1;__DBL_HAS_INFINITY__;1;__DBL_HAS_QUIET_NAN__;1;__LDBL_MANT_DIG__;64;__LDBL_DIG__;18;__LDBL_MIN_EXP__;(-16381);__LDBL_MIN_10_EXP__;(-4931);__LDBL_MAX_EXP__;16384;__LDBL_MAX_10_EXP__;4932;__DECIMAL_DIG__;21;__LDBL_DECIMAL_DIG__;21;__LDBL_MAX__;1.18973149535723176502126385303097021e+4932L;__LDBL_MIN__;3.36210314311209350626267781732175260e-4932L;__LDBL_EPSILON__;1.08420217248550443400745280086994171e-19L;__LDBL_DENORM_MIN__;3.64519953188247460252840593361941982e-4951L;__LDBL_HAS_DENORM__;1;__LDBL_HAS_INFINITY__;1;__LDBL_HAS_QUIET_NAN__;1;__FLT32_MANT_DIG__;24;__FLT32_DIG__;6;__FLT32_MIN_EXP__;(-125);__FLT32_MIN_10_EXP__;(-37);__FLT32_MAX_EXP__;128;__FLT32_MAX_10_EXP__;38;__FLT32_DECIMAL_DIG__;9;__FLT32_MAX__;3.40282346638528859811704183484516925e+38F32;__FLT32_MIN__;1.17549435082228750796873653722224568e-38F32;__FLT32_EPSILON__;1.19209289550781250000000000000000000e-7F32;__FLT32_DENORM_MIN__;1.40129846432481707092372958328991613e-45F32;__FLT32_HAS_DENORM__;1;__FLT32_HAS_INFINITY__;1;__FLT32_HAS_QUIET_NAN__;1;__FLT64_MANT_DIG__;53;__FLT64_DIG__;15;__FLT64_MIN_EXP__;(-1021);__FLT64_MIN_10_EXP__;(-307);__FLT64_MAX_EXP__;1024;__FLT64_MAX_10_EXP__;308;__FLT64_DECIMAL_DIG__;17;__FLT64_MAX__;1.79769313486231570814527423731704357e+308F64;__FLT64_MIN__;2.22507385850720138309023271733240406e-308F64;__FLT64_EPSILON__;2.22044604925031308084726333618164062e-16F64;__FLT64_DENORM_MIN__;4.94065645841246544176568792868221372e-324F64;__FLT64_HAS_DENORM__;1;__FLT64_HAS_INFINITY__;1;__FLT64_HAS_QUIET_NAN__;1;__FLT128_MANT_DIG__;113;__FLT128_DIG__;33;__FLT128_MIN_EXP__;(-16381);__FLT128_MIN_10_EXP__;(-4931);__FLT128_MAX_EXP__;16384;__FLT128_MAX_10_EXP__;4932;__FLT128_DECIMAL_DIG__;36;__FLT128_MAX__;1.18973149535723176508575932662800702e+4932F128;__FLT128_MIN__;3.36210314311209350626267781732175260e-4932F128;__FLT128_EPSILON__;1.92592994438723585305597794258492732e-34F128;__FLT128_DENORM_MIN__;6.47517511943802511092443895822764655e-4966F128;__FLT128_HAS_DENORM__;1;__FLT128_HAS_INFINITY__;1;__FLT128_HAS_QUIET_NAN__;1;__FLT32X_MANT_DIG__;53;__FLT32X_DIG__;15;__FLT32X_MIN_EXP__;(-1021);__FLT32X_MIN_10_EXP__;(-307);__FLT32X_MAX_EXP__;1024;__FLT32X_MAX_10_EXP__;308;__FLT32X_DECIMAL_DIG__;17;__FLT32X_MAX__;1.79769313486231570814527423731704357e+308F32x;__FLT32X_MIN__;2.22507385850720138309023271733240406e-308F32x;__FLT32X_EPSILON__;2.22044604925031308084726333618164062e-16F32x;__FLT32X_DENORM_MIN__;4.94065645841246544176568792868221372e-324F32x;__FLT32X_HAS_DENORM__;1;__FLT32X_HAS_INFINITY__;1;__FLT32X_HAS_QUIET_NAN__;1;__FLT64X_MANT_DIG__;64;__FLT64X_DIG__;18;__FLT64X_MIN_EXP__;(-16381);__FLT64X_MIN_10_EXP__;(-4931);__FLT64X_MAX_EXP__;16384;__FLT64X_MAX_10_EXP__;4932;__FLT64X_DECIMAL_DIG__;21;__FLT64X_MAX__;1.18973149535723176502126385303097021e+4932F64x;__FLT64X_MIN__;3.36210314311209350626267781732175260e-4932F64x;__FLT64X_EPSILON__;1.08420217248550443400745280086994171e-19F64x;__FLT64X_DENORM_MIN__;3.64519953188247460252840593361941982e-4951F64x;__FLT64X_HAS_DENORM__;1;__FLT64X_HAS_INFINITY__;1;__FLT64X_HAS_QUIET_NAN__;1;__DEC32_MANT_DIG__;7;__DEC32_MIN_EXP__;(-94);__DEC32_MAX_EXP__;97;__DEC32_MIN__;1E-95DF;__DEC32_MAX__;9.999999E96DF;__DEC32_EPSILON__;1E-6DF;__DEC32_SUBNORMAL_MIN__;0.000001E-95DF;__DEC64_MANT_DIG__;16;__DEC64_MIN_EXP__;(-382);__DEC64_MAX_EXP__;385;__DEC64_MIN__;1E-383DD;__DEC64_MAX__;9.999999999999999E384DD;__DEC64_EPSILON__;1E-15DD;__DEC64_SUBNORMAL_MIN__;0.000000000000001E-383DD;__DEC128_MANT_DIG__;34;__DEC128_MIN_EXP__;(-6142);__DEC128_MAX_EXP__;6145;__DEC128_MIN__;1E-6143DL;__DEC128_MAX__;9.999999999999999999999999999999999E6144DL;__DEC128_EPSILON__;1E-33DL;__DEC128_SUBNORMAL_MIN__;0.000000000000000000000000000000001E-6143DL;__REGISTER_PREFIX__; ;__USER_LABEL_PREFIX__; ;__GNUC_STDC_INLINE__;1;__NO_INLINE__;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8;1;__GCC_ATOMIC_BOOL_LOCK_FREE;2;__GCC_ATOMIC_CHAR_LOCK_FREE;2;__GCC_ATOMIC_CHAR16_T_LOCK_FREE;2;__GCC_ATOMIC_CHAR32_T_LOCK_FREE;2;__GCC_ATOMIC_WCHAR_T_LOCK_FREE;2;__GCC_ATOMIC_SHORT_LOCK_FREE;2;__GCC_ATOMIC_INT_LOCK_FREE;2;__GCC_ATOMIC_LONG_LOCK_FREE;2;__GCC_ATOMIC_LLONG_LOCK_FREE;2;__GCC_ATOMIC_TEST_AND_SET_TRUEVAL;1;__GCC_ATOMIC_POINTER_LOCK_FREE;2;__GCC_HAVE_DWARF2_CFI_ASM;1;__PRAGMA_REDEFINE_EXTNAME;1;__SSP_STRONG__;3;__SIZEOF_INT128__;16;__SIZEOF_WCHAR_T__;4;__SIZEOF_WINT_T__;4;__SIZEOF_PTRDIFF_T__;8;__amd64;1;__amd64__;1;__x86_64;1;__x86_64__;1;__SIZEOF_FLOAT80__;16;__SIZEOF_FLOAT128__;16;__ATOMIC_HLE_ACQUIRE;65536;__ATOMIC_HLE_RELEASE;131072;__GCC_ASM_FLAG_OUTPUTS__;1;__k8;1;__k8__;1;__code_model_small__;1;__MMX__;1;__SSE__;1;__SSE2__;1;__FXSR__;1;__SSE_MATH__;1;__SSE2_MATH__;1;__SEG_FS;1;__SEG_GS;1;__gnu_linux__;1;__linux;1;__linux__;1;linux;1;__unix;1;__unix__;1;unix;1;__ELF__;1;__DECIMAL_BID_FORMAT__;1;_STDC_PREDEF_H;1;__STDC_IEC_559__;1;__STDC_IEC_559_COMPLEX__;1;__STDC_ISO_10646__;201706L;__STDC_NO_THREADS__;1 +//C compiler system include directories +CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS:INTERNAL=/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include +//Name of generator. +CMAKE_GENERATOR:INTERNAL=Unix Makefiles +//Generator instance identifier. +CMAKE_GENERATOR_INSTANCE:INTERNAL= +//Name of generator platform. +CMAKE_GENERATOR_PLATFORM:INTERNAL= +//Name of generator toolset. +CMAKE_GENERATOR_TOOLSET:INTERNAL= +//Test CMAKE_HAVE_LIBC_PTHREAD +CMAKE_HAVE_LIBC_PTHREAD:INTERNAL= +//Have library pthreads +CMAKE_HAVE_PTHREADS_CREATE:INTERNAL= +//Have library pthread +CMAKE_HAVE_PTHREAD_CREATE:INTERNAL=1 +//Have include pthread.h +CMAKE_HAVE_PTHREAD_H:INTERNAL=1 +//Source directory with the top level CMakeLists.txt file for this +// project +CMAKE_HOME_DIRECTORY:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo +//Install .so files without execute permission. +CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1 +//ADVANCED property for variable: CMAKE_LINKER +CMAKE_LINKER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MAKE_PROGRAM +CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS +CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG +CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL +CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE +CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_NM +CMAKE_NM-ADVANCED:INTERNAL=1 +//number of local generators +CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=4 +//ADVANCED property for variable: CMAKE_OBJCOPY +CMAKE_OBJCOPY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_OBJDUMP +CMAKE_OBJDUMP-ADVANCED:INTERNAL=1 +//Platform information initialized +CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_RANLIB +CMAKE_RANLIB-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_READELF +CMAKE_READELF-ADVANCED:INTERNAL=1 +//Path to CMake installation. +CMAKE_ROOT:INTERNAL=/opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS +CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG +CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL +CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE +CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH +CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SKIP_RPATH +CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS +CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG +CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL +CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE +CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STRIP +CMAKE_STRIP-ADVANCED:INTERNAL=1 +//uname command +CMAKE_UNAME:INTERNAL=/bin/uname +//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE +CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: EIGEN_INCLUDE_DIR +EIGEN_INCLUDE_DIR-ADVANCED:INTERNAL=1 +//Details about finding Boost +FIND_PACKAGE_MESSAGE_DETAILS_Boost:INTERNAL=[/usr/include][cfound components: thread system chrono date_time atomic ][v1.65.1()] +//Details about finding Eigen +FIND_PACKAGE_MESSAGE_DETAILS_Eigen:INTERNAL=[/usr/include/eigen3][v()] +//Details about finding OpenCL +FIND_PACKAGE_MESSAGE_DETAILS_OpenCL:INTERNAL=[/usr/lib/x86_64-linux-gnu/libOpenCL.so][/usr/include][v2.2()] +//Details about finding OpenCV +FIND_PACKAGE_MESSAGE_DETAILS_OpenCV:INTERNAL=[/usr][v3.2.0(3)] +//Details about finding PkgConfig +FIND_PACKAGE_MESSAGE_DETAILS_PkgConfig:INTERNAL=[/usr/bin/pkg-config][v0.29.1()] +//Details about finding PythonInterp +FIND_PACKAGE_MESSAGE_DETAILS_PythonInterp:INTERNAL=[/usr/bin/python2][v2.7.17()] +//Details about finding Threads +FIND_PACKAGE_MESSAGE_DETAILS_Threads:INTERNAL=[TRUE][v()] +GMOCK_FROM_SOURCE_FOUND:INTERNAL=TRUE +GMOCK_FROM_SOURCE_INCLUDE_DIRS:INTERNAL=/usr/include +GMOCK_FROM_SOURCE_LIBRARIES:INTERNAL=gmock +GMOCK_FROM_SOURCE_LIBRARY_DIRS:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/gmock +GMOCK_FROM_SOURCE_MAIN_LIBRARIES:INTERNAL=gmock_main +GTEST_FROM_SOURCE_FOUND:INTERNAL=TRUE +GTEST_FROM_SOURCE_INCLUDE_DIRS:INTERNAL=/usr/include +GTEST_FROM_SOURCE_LIBRARIES:INTERNAL=gtest +GTEST_FROM_SOURCE_LIBRARY_DIRS:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/gtest +GTEST_FROM_SOURCE_MAIN_LIBRARIES:INTERNAL=gtest_main +//ADVANCED property for variable: GTEST_INCLUDE_DIR +GTEST_INCLUDE_DIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: GTEST_LIBRARY +GTEST_LIBRARY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: GTEST_LIBRARY_DEBUG +GTEST_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: GTEST_MAIN_LIBRARY +GTEST_MAIN_LIBRARY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: GTEST_MAIN_LIBRARY_DEBUG +GTEST_MAIN_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 +//Have symbol CL_VERSION_2_2 +OPENCL_VERSION_2_2:INTERNAL=1 +//ADVANCED property for variable: OpenCL_INCLUDE_DIR +OpenCL_INCLUDE_DIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: OpenCL_LIBRARY +OpenCL_LIBRARY-ADVANCED:INTERNAL=1 +PC_EIGEN_CFLAGS:INTERNAL=-I/usr/include/eigen3 +PC_EIGEN_CFLAGS_I:INTERNAL= +PC_EIGEN_CFLAGS_OTHER:INTERNAL= +PC_EIGEN_FOUND:INTERNAL=1 +PC_EIGEN_INCLUDEDIR:INTERNAL= +PC_EIGEN_INCLUDE_DIRS:INTERNAL=/usr/include/eigen3 +PC_EIGEN_LDFLAGS:INTERNAL= +PC_EIGEN_LDFLAGS_OTHER:INTERNAL= +PC_EIGEN_LIBDIR:INTERNAL= +PC_EIGEN_LIBRARIES:INTERNAL= +PC_EIGEN_LIBRARY_DIRS:INTERNAL= +PC_EIGEN_LIBS:INTERNAL= +PC_EIGEN_LIBS_L:INTERNAL= +PC_EIGEN_LIBS_OTHER:INTERNAL= +PC_EIGEN_LIBS_PATHS:INTERNAL= +PC_EIGEN_MODULE_NAME:INTERNAL=eigen3 +PC_EIGEN_PREFIX:INTERNAL=/usr +PC_EIGEN_STATIC_CFLAGS:INTERNAL=-I/usr/include/eigen3 +PC_EIGEN_STATIC_CFLAGS_I:INTERNAL= +PC_EIGEN_STATIC_CFLAGS_OTHER:INTERNAL= +PC_EIGEN_STATIC_INCLUDE_DIRS:INTERNAL=/usr/include/eigen3 +PC_EIGEN_STATIC_LDFLAGS:INTERNAL= +PC_EIGEN_STATIC_LDFLAGS_OTHER:INTERNAL= +PC_EIGEN_STATIC_LIBDIR:INTERNAL= +PC_EIGEN_STATIC_LIBRARIES:INTERNAL= +PC_EIGEN_STATIC_LIBRARY_DIRS:INTERNAL= +PC_EIGEN_STATIC_LIBS:INTERNAL= +PC_EIGEN_STATIC_LIBS_L:INTERNAL= +PC_EIGEN_STATIC_LIBS_OTHER:INTERNAL= +PC_EIGEN_STATIC_LIBS_PATHS:INTERNAL= +PC_EIGEN_VERSION:INTERNAL=3.3.4 +PC_EIGEN_eigen3_INCLUDEDIR:INTERNAL= +PC_EIGEN_eigen3_LIBDIR:INTERNAL= +PC_EIGEN_eigen3_PREFIX:INTERNAL= +PC_EIGEN_eigen3_VERSION:INTERNAL= +//ADVANCED property for variable: PKG_CONFIG_EXECUTABLE +PKG_CONFIG_EXECUTABLE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: PYTHON_EXECUTABLE +PYTHON_EXECUTABLE-ADVANCED:INTERNAL=1 +//This needs to be in PYTHONPATH when 'setup.py install' is called. +// And it needs to match. But setuptools won't tell us where +// it will install things. +PYTHON_INSTALL_DIR:INTERNAL=lib/python2.7/dist-packages +//ADVANCED property for variable: ProcessorCount_cmd_nproc +ProcessorCount_cmd_nproc-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: ProcessorCount_cmd_sysctl +ProcessorCount_cmd_sysctl-ADVANCED:INTERNAL=1 +//Components requested for this build tree. +_Boost_COMPONENTS_SEARCHED:INTERNAL=atomic;chrono;date_time;system;thread +//Last used Boost_INCLUDE_DIR value. +_Boost_INCLUDE_DIR_LAST:INTERNAL=/usr/include +//Last used Boost_LIBRARY_DIR_DEBUG value. +_Boost_LIBRARY_DIR_DEBUG_LAST:INTERNAL=/usr/lib/x86_64-linux-gnu +//Last used Boost_LIBRARY_DIR_RELEASE value. +_Boost_LIBRARY_DIR_RELEASE_LAST:INTERNAL=/usr/lib/x86_64-linux-gnu +//Last used Boost_NAMESPACE value. +_Boost_NAMESPACE_LAST:INTERNAL=boost +//Last used Boost_USE_MULTITHREADED value. +_Boost_USE_MULTITHREADED_LAST:INTERNAL=TRUE +__pkg_config_arguments_PC_EIGEN:INTERNAL=eigen3 +__pkg_config_checked_PC_EIGEN:INTERNAL=1 +prefix_result:INTERNAL= + diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCCompiler.cmake b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCCompiler.cmake new file mode 100644 index 0000000..5e07ef4 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCCompiler.cmake @@ -0,0 +1,76 @@ +set(CMAKE_C_COMPILER "/usr/bin/cc") +set(CMAKE_C_COMPILER_ARG1 "") +set(CMAKE_C_COMPILER_ID "GNU") +set(CMAKE_C_COMPILER_VERSION "7.5.0") +set(CMAKE_C_COMPILER_VERSION_INTERNAL "") +set(CMAKE_C_COMPILER_WRAPPER "") +set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "11") +set(CMAKE_C_COMPILE_FEATURES "c_std_90;c_function_prototypes;c_std_99;c_restrict;c_variadic_macros;c_std_11;c_static_assert") +set(CMAKE_C90_COMPILE_FEATURES "c_std_90;c_function_prototypes") +set(CMAKE_C99_COMPILE_FEATURES "c_std_99;c_restrict;c_variadic_macros") +set(CMAKE_C11_COMPILE_FEATURES "c_std_11;c_static_assert") + +set(CMAKE_C_PLATFORM_ID "Linux") +set(CMAKE_C_SIMULATE_ID "") +set(CMAKE_C_COMPILER_FRONTEND_VARIANT "") +set(CMAKE_C_SIMULATE_VERSION "") + + + +set(CMAKE_AR "/usr/bin/ar") +set(CMAKE_C_COMPILER_AR "/usr/bin/gcc-ar-7") +set(CMAKE_RANLIB "/usr/bin/ranlib") +set(CMAKE_C_COMPILER_RANLIB "/usr/bin/gcc-ranlib-7") +set(CMAKE_LINKER "/usr/bin/ld") +set(CMAKE_MT "") +set(CMAKE_COMPILER_IS_GNUCC 1) +set(CMAKE_C_COMPILER_LOADED 1) +set(CMAKE_C_COMPILER_WORKS TRUE) +set(CMAKE_C_ABI_COMPILED TRUE) +set(CMAKE_COMPILER_IS_MINGW ) +set(CMAKE_COMPILER_IS_CYGWIN ) +if(CMAKE_COMPILER_IS_CYGWIN) + set(CYGWIN 1) + set(UNIX 1) +endif() + +set(CMAKE_C_COMPILER_ENV_VAR "CC") + +if(CMAKE_COMPILER_IS_MINGW) + set(MINGW 1) +endif() +set(CMAKE_C_COMPILER_ID_RUN 1) +set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m) +set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) +set(CMAKE_C_LINKER_PREFERENCE 10) + +# Save compiler ABI information. +set(CMAKE_C_SIZEOF_DATA_PTR "8") +set(CMAKE_C_COMPILER_ABI "ELF") +set(CMAKE_C_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") + +if(CMAKE_C_SIZEOF_DATA_PTR) + set(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}") +endif() + +if(CMAKE_C_COMPILER_ABI) + set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}") +endif() + +if(CMAKE_C_LIBRARY_ARCHITECTURE) + set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") +endif() + +set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "") +if(CMAKE_C_CL_SHOWINCLUDES_PREFIX) + set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}") +endif() + + + + + +set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include") +set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "gcc;gcc_s;c;gcc;gcc_s") +set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/7;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") +set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCXXCompiler.cmake b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCXXCompiler.cmake new file mode 100644 index 0000000..1ff034b --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCXXCompiler.cmake @@ -0,0 +1,88 @@ +set(CMAKE_CXX_COMPILER "/usr/bin/c++") +set(CMAKE_CXX_COMPILER_ARG1 "") +set(CMAKE_CXX_COMPILER_ID "GNU") +set(CMAKE_CXX_COMPILER_VERSION "7.5.0") +set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "") +set(CMAKE_CXX_COMPILER_WRAPPER "") +set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "14") +set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17") +set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters") +set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates") +set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates") +set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17") +set(CMAKE_CXX20_COMPILE_FEATURES "") + +set(CMAKE_CXX_PLATFORM_ID "Linux") +set(CMAKE_CXX_SIMULATE_ID "") +set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "") +set(CMAKE_CXX_SIMULATE_VERSION "") + + + +set(CMAKE_AR "/usr/bin/ar") +set(CMAKE_CXX_COMPILER_AR "/usr/bin/gcc-ar-7") +set(CMAKE_RANLIB "/usr/bin/ranlib") +set(CMAKE_CXX_COMPILER_RANLIB "/usr/bin/gcc-ranlib-7") +set(CMAKE_LINKER "/usr/bin/ld") +set(CMAKE_MT "") +set(CMAKE_COMPILER_IS_GNUCXX 1) +set(CMAKE_CXX_COMPILER_LOADED 1) +set(CMAKE_CXX_COMPILER_WORKS TRUE) +set(CMAKE_CXX_ABI_COMPILED TRUE) +set(CMAKE_COMPILER_IS_MINGW ) +set(CMAKE_COMPILER_IS_CYGWIN ) +if(CMAKE_COMPILER_IS_CYGWIN) + set(CYGWIN 1) + set(UNIX 1) +endif() + +set(CMAKE_CXX_COMPILER_ENV_VAR "CXX") + +if(CMAKE_COMPILER_IS_MINGW) + set(MINGW 1) +endif() +set(CMAKE_CXX_COMPILER_ID_RUN 1) +set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;CPP) +set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC) + +foreach (lang C OBJC OBJCXX) + if (CMAKE_${lang}_COMPILER_ID_RUN) + foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS) + list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension}) + endforeach() + endif() +endforeach() + +set(CMAKE_CXX_LINKER_PREFERENCE 30) +set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1) + +# Save compiler ABI information. +set(CMAKE_CXX_SIZEOF_DATA_PTR "8") +set(CMAKE_CXX_COMPILER_ABI "ELF") +set(CMAKE_CXX_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") + +if(CMAKE_CXX_SIZEOF_DATA_PTR) + set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}") +endif() + +if(CMAKE_CXX_COMPILER_ABI) + set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}") +endif() + +if(CMAKE_CXX_LIBRARY_ARCHITECTURE) + set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") +endif() + +set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "") +if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX) + set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}") +endif() + + + + + +set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include/c++/7;/usr/include/x86_64-linux-gnu/c++/7;/usr/include/c++/7/backward;/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include") +set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;gcc_s;gcc;c;gcc_s;gcc") +set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/7;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") +set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_C.bin b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_C.bin new file mode 100755 index 0000000000000000000000000000000000000000..b1860a3dd40b90b19fab68ce7a4bf1a8fee6135d GIT binary patch literal 8248 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 literal 0 HcmV?d00001 diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_CXX.bin b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_CXX.bin new file mode 100755 index 0000000000000000000000000000000000000000..19a9ccae8956d20ea78fcbaa929a195ae4089300 GIT binary patch literal 8264 zcmeHMeQZ#_ndP--+kvEKOPLVIUNqc$t4~TSjx{am}aU_mr@3xSu}|%_+25E z3lyu6oKfFw0Mr_3noKjgiFW~_UX#-xthj>Y7`catl~iX3-n$HzQ3#(TP!Ib$RU?al zKABbEUaHj`RA}6ZgKj=){g{ti$o3&RqD8 zdq>>jo`qHJii(=2Dnv8ZRlyhA2?T$4^*~k2?_a$9?4jzdKbZHz7cS@j`0C|j>wDg~ zcJV8FR~&f!xkEo6yY8u8`1Y~)UVEQc5;V&b&a1DS7R!KJV8h3O^V#q}o`s(W{3;vy zy})_J-NNhjmDFm)3k(08AHt-8Xjqnm5g)$~Y z!C-V%eOZm3)nWRh5bNMx*3C;xO?> zE&RfM>&5NWC^W5iD6I9xlHqvlU=)g2rDgPRTGtZcSdy9EOcteLLTm5r&?3=vv_F>7 zqv_6$mUt=|?F{$CK|2}=>tRqqFpNN^ux`@C?!@6k`U&+FN>gZLsdZegb=Rc6Wxx zDt`psSI25LNZ9rc2o@IIaQnpHYge{n&9~&p1@XT%Ao%T6dc?1TYxTg?QPIk&)jyYxheI`K9ijQhXjf2ck8 zy1&a0b9vuyD&2(7&$*X+zK*W~uwg@XFTHQm?n29Gb4`)4S3qc!)w zzp(I4b#%g^Zh0&F7hKbQ-Tp`Y-TwW4ZDM?8K0kn^miB1X9mTf*e?h{r+;u;m-MD`*-YOKH0-OXq1vm|e=c^ND>19Bi&q=`3 zfc3Q5@qL8Jad3}t40#>PtLM7M9do_NuYm7Su)${_%Gt{cv6|#nkjHnE@OaxiOFmya z?`!T6v3=S7pWd)q9{;Eh%O~nV&W&=Eu&qboyB?-io}qq^_ep0<%^YVl^vKXT1oeBN zK8iX4kN0V3z_aALuAs*^RuS;5`A((ksef{g>S-FC+u>7dcS8)z~ciskPmp= z^1XQ$)JMRM`ME}ucha31xHAL)pEJPz0s8~|u4k;KVY9zR*QKIA#@9f;H!UZ5KEu#Y z#>D;yo@bc2{vWpsDJ&nQLx+8V=PQt<8{>Y1!&q)76tr>RI1rWs_20w;?M_4c}~NQtCIZHQ4{AITv`6e6KglyWkzq z_u*3BC3KsYkqd5=ykAP?D~tQ2l%FGbKb7)x1+Pmf?-snCrF>O!-<0y@_Zh5r!R|bc z4u~bWM720&%g@}e%qlKnbN>MWm+AgiD(@}E3rhL> z`~-Mkxwv=CM|F8=Z^$y?(ue+AyIpKds3 zSK0Lcb!o@ueCti?89m$Ar}T=MP>QA}v|bFRWH5q~()#16o^V`?=&5u@3ulK!Zz?eu zkLuBgvbk|flf94((rDpyIy?-q6g@pG`qJSF;Q7DHW43C!ipRsRdOsr?&0^3W7{*ct>bgz#r0fwY5DM?9@8_flv^e zlToXW7NfERx|*BK0i}-|r&511tMp`J5K4|kgo34kaArU#k>MoRGf+<(HD8UUGqF^%q@Y1vIvNk7 zf>2~kP8p2r0)LeL6lC=15d6wmpps6>fS(c_pp7*U0evnR`o<13G&m2&!--fgbO+;w z3WWQF0=qi_JJ#kg`p6Xe(eUUMqaW-yF|r@chEdj>?u7!r`q+J9|BBIP7KS{z+eNkk za%O$@!x&c=C5?<#zZK{k;Olbx?5{CmOal}9`|MvEtPndPgT6iMPg92R6b%@UL(H;1 zdkzl)hdwszv;W7)_XiM>$vS`gfkj`Q_1RBk?IRcph|XP5OL) zpQZo+%YleYTxNU|SX?r0zvwrTBb%rG^ZsN#p2zQjE{d=|-z)OiDM-!ocjkxn8LvQ< zS->24 & 0x00FF) +# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) +# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF) + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + /* __BORLANDC__ = 0xVRR */ +# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) +# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) + +#elif defined(__WATCOMC__) && __WATCOMC__ < 1200 +# define COMPILER_ID "Watcom" + /* __WATCOMC__ = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) +# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) +# if (__WATCOMC__ % 10) > 0 +# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) +# endif + +#elif defined(__WATCOMC__) +# define COMPILER_ID "OpenWatcom" + /* __WATCOMC__ = VVRP + 1100 */ +# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100) +# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) +# if (__WATCOMC__ % 10) > 0 +# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) +# endif + +#elif defined(__SUNPRO_C) +# define COMPILER_ID "SunPro" +# if __SUNPRO_C >= 0x5100 + /* __SUNPRO_C = 0xVRRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) +# else + /* __SUNPRO_CC = 0xVRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) +# endif + +#elif defined(__HP_cc) +# define COMPILER_ID "HP" + /* __HP_cc = VVRRPP */ +# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000) +# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100) +# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100) + +#elif defined(__DECC) +# define COMPILER_ID "Compaq" + /* __DECC_VER = VVRRTPPPP */ +# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000) +# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100) +# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000) + +#elif defined(__IBMC__) && defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" + /* __IBMC__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) + +#elif defined(__ibmxl__) && defined(__clang__) +# define COMPILER_ID "XLClang" +# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__) +# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__) +# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__) +# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__) + + +#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800 +# define COMPILER_ID "XL" + /* __IBMC__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) + +#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800 +# define COMPILER_ID "VisualAge" + /* __IBMC__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) + +#elif defined(__PGI) +# define COMPILER_ID "PGI" +# define COMPILER_VERSION_MAJOR DEC(__PGIC__) +# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) +# endif + +#elif defined(_CRAYC) +# define COMPILER_ID "Cray" +# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR) +# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) + +#elif defined(__TI_COMPILER_VERSION__) +# define COMPILER_ID "TI" + /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ +# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) +# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) +# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) + +#elif defined(__FUJITSU) || defined(__FCC_VERSION) || defined(__fcc_version) +# define COMPILER_ID "Fujitsu" + +#elif defined(__ghs__) +# define COMPILER_ID "GHS" +/* __GHS_VERSION_NUMBER = VVVVRP */ +# ifdef __GHS_VERSION_NUMBER +# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100) +# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10) +# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10) +# endif + +#elif defined(__TINYC__) +# define COMPILER_ID "TinyCC" + +#elif defined(__BCC__) +# define COMPILER_ID "Bruce" + +#elif defined(__SCO_VERSION__) +# define COMPILER_ID "SCO" + +#elif defined(__ARMCC_VERSION) && !defined(__clang__) +# define COMPILER_ID "ARMCC" +#if __ARMCC_VERSION >= 1000000 + /* __ARMCC_VERSION = VRRPPPP */ + # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000) + # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100) + # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) +#else + /* __ARMCC_VERSION = VRPPPP */ + # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000) + # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10) + # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) +#endif + + +#elif defined(__clang__) && defined(__apple_build_version__) +# define COMPILER_ID "AppleClang" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif +# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__) + +#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION) +# define COMPILER_ID "ARMClang" + # define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000) + # define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100) + # define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000) +# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION) + +#elif defined(__clang__) +# define COMPILER_ID "Clang" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif + +#elif defined(__GNUC__) +# define COMPILER_ID "GNU" +# define COMPILER_VERSION_MAJOR DEC(__GNUC__) +# if defined(__GNUC_MINOR__) +# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) +# endif +# if defined(__GNUC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + /* _MSC_VER = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) +# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) +# if defined(_MSC_FULL_VER) +# if _MSC_VER >= 1400 + /* _MSC_FULL_VER = VVRRPPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) +# else + /* _MSC_FULL_VER = VVRRPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) +# endif +# endif +# if defined(_MSC_BUILD) +# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) +# endif + +#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) +# define COMPILER_ID "ADSP" +#if defined(__VISUALDSPVERSION__) + /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ +# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24) +# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF) +#endif + +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) +# define COMPILER_ID "IAR" +# if defined(__VER__) && defined(__ICCARM__) +# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000) +# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000) +# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000) +# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) +# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__)) +# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100) +# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100)) +# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__) +# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) +# endif + +#elif defined(__SDCC_VERSION_MAJOR) || defined(SDCC) +# define COMPILER_ID "SDCC" +# if defined(__SDCC_VERSION_MAJOR) +# define COMPILER_VERSION_MAJOR DEC(__SDCC_VERSION_MAJOR) +# define COMPILER_VERSION_MINOR DEC(__SDCC_VERSION_MINOR) +# define COMPILER_VERSION_PATCH DEC(__SDCC_VERSION_PATCH) +# else + /* SDCC = VRP */ +# define COMPILER_VERSION_MAJOR DEC(SDCC/100) +# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10) +# define COMPILER_VERSION_PATCH DEC(SDCC % 10) +# endif + + +/* These compilers are either not known or too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; +#ifdef SIMULATE_ID +char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; +#endif + +#ifdef __QNXNTO__ +char const* qnxnto = "INFO" ":" "qnxnto[]"; +#endif + +#if defined(__CRAYXE) || defined(__CRAYXC) +char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]"; +#endif + +#define STRINGIFY_HELPER(X) #X +#define STRINGIFY(X) STRINGIFY_HELPER(X) + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU__) +# define PLATFORM_ID "Haiku" + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#elif defined(__WATCOMC__) +# if defined(__LINUX__) +# define PLATFORM_ID "Linux" + +# elif defined(__DOS__) +# define PLATFORM_ID "DOS" + +# elif defined(__OS2__) +# define PLATFORM_ID "OS2" + +# elif defined(__WINDOWS__) +# define PLATFORM_ID "Windows3x" + +# else /* unknown platform */ +# define PLATFORM_ID +# endif + +#elif defined(__INTEGRITY) +# if defined(INT_178B) +# define PLATFORM_ID "Integrity178" + +# else /* regular Integrity */ +# define PLATFORM_ID "Integrity" +# endif + +#else /* unknown platform */ +# define PLATFORM_ID + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is because + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# elif defined(_M_ARM64) +# define ARCHITECTURE_ID "ARM64" + +# elif defined(_M_ARM) +# if _M_ARM == 4 +# define ARCHITECTURE_ID "ARMV4I" +# elif _M_ARM == 5 +# define ARCHITECTURE_ID "ARMV5I" +# else +# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM) +# endif + +# elif defined(_M_MIPS) +# define ARCHITECTURE_ID "MIPS" + +# elif defined(_M_SH) +# define ARCHITECTURE_ID "SHx" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__WATCOMC__) +# if defined(_M_I86) +# define ARCHITECTURE_ID "I86" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) +# if defined(__ICCARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__ICCRX__) +# define ARCHITECTURE_ID "RX" + +# elif defined(__ICCRH850__) +# define ARCHITECTURE_ID "RH850" + +# elif defined(__ICCRL78__) +# define ARCHITECTURE_ID "RL78" + +# elif defined(__ICCRISCV__) +# define ARCHITECTURE_ID "RISCV" + +# elif defined(__ICCAVR__) +# define ARCHITECTURE_ID "AVR" + +# elif defined(__ICC430__) +# define ARCHITECTURE_ID "MSP430" + +# elif defined(__ICCV850__) +# define ARCHITECTURE_ID "V850" + +# elif defined(__ICC8051__) +# define ARCHITECTURE_ID "8051" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__ghs__) +# if defined(__PPC64__) +# define ARCHITECTURE_ID "PPC64" + +# elif defined(__ppc__) +# define ARCHITECTURE_ID "PPC" + +# elif defined(__ARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__x86_64__) +# define ARCHITECTURE_ID "x64" + +# elif defined(__i386__) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif +#else +# define ARCHITECTURE_ID +#endif + +/* Convert integer to decimal digit literals. */ +#define DEC(n) \ + ('0' + (((n) / 10000000)%10)), \ + ('0' + (((n) / 1000000)%10)), \ + ('0' + (((n) / 100000)%10)), \ + ('0' + (((n) / 10000)%10)), \ + ('0' + (((n) / 1000)%10)), \ + ('0' + (((n) / 100)%10)), \ + ('0' + (((n) / 10)%10)), \ + ('0' + ((n) % 10)) + +/* Convert integer to hex digit literals. */ +#define HEX(n) \ + ('0' + ((n)>>28 & 0xF)), \ + ('0' + ((n)>>24 & 0xF)), \ + ('0' + ((n)>>20 & 0xF)), \ + ('0' + ((n)>>16 & 0xF)), \ + ('0' + ((n)>>12 & 0xF)), \ + ('0' + ((n)>>8 & 0xF)), \ + ('0' + ((n)>>4 & 0xF)), \ + ('0' + ((n) & 0xF)) + +/* Construct a string literal encoding the version number components. */ +#ifdef COMPILER_VERSION_MAJOR +char const info_version[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', + COMPILER_VERSION_MAJOR, +# ifdef COMPILER_VERSION_MINOR + '.', COMPILER_VERSION_MINOR, +# ifdef COMPILER_VERSION_PATCH + '.', COMPILER_VERSION_PATCH, +# ifdef COMPILER_VERSION_TWEAK + '.', COMPILER_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct a string literal encoding the internal version number. */ +#ifdef COMPILER_VERSION_INTERNAL +char const info_version_internal[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_', + 'i','n','t','e','r','n','a','l','[', + COMPILER_VERSION_INTERNAL,']','\0'}; +#endif + +/* Construct a string literal encoding the version number components. */ +#ifdef SIMULATE_VERSION_MAJOR +char const info_simulate_version[] = { + 'I', 'N', 'F', 'O', ':', + 's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[', + SIMULATE_VERSION_MAJOR, +# ifdef SIMULATE_VERSION_MINOR + '.', SIMULATE_VERSION_MINOR, +# ifdef SIMULATE_VERSION_PATCH + '.', SIMULATE_VERSION_PATCH, +# ifdef SIMULATE_VERSION_TWEAK + '.', SIMULATE_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + + +#if !defined(__STDC__) +# if (defined(_MSC_VER) && !defined(__clang__)) \ + || (defined(__ibmxl__) || defined(__IBMC__)) +# define C_DIALECT "90" +# else +# define C_DIALECT +# endif +#elif __STDC_VERSION__ >= 201000L +# define C_DIALECT "11" +#elif __STDC_VERSION__ >= 199901L +# define C_DIALECT "99" +#else +# define C_DIALECT "90" +#endif +const char* info_language_dialect_default = + "INFO" ":" "dialect_default[" C_DIALECT "]"; + +/*--------------------------------------------------------------------------*/ + +#ifdef ID_VOID_MAIN +void main() {} +#else +# if defined(__CLASSIC_C__) +int main(argc, argv) int argc; char *argv[]; +# else +int main(int argc, char* argv[]) +# endif +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; + require += info_arch[argc]; +#ifdef COMPILER_VERSION_MAJOR + require += info_version[argc]; +#endif +#ifdef COMPILER_VERSION_INTERNAL + require += info_version_internal[argc]; +#endif +#ifdef SIMULATE_ID + require += info_simulate[argc]; +#endif +#ifdef SIMULATE_VERSION_MAJOR + require += info_simulate_version[argc]; +#endif +#if defined(__CRAYXE) || defined(__CRAYXC) + require += info_cray[argc]; +#endif + require += info_language_dialect_default[argc]; + (void)argv; + return require; +} +#endif diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdC/a.out b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdC/a.out new file mode 100755 index 0000000000000000000000000000000000000000..11b7df452ad29dfd7bf1d9b188856c9e33182403 GIT binary patch literal 8408 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 D$)0nc literal 0 HcmV?d00001 diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/CMakeCXXCompilerId.cpp b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/CMakeCXXCompilerId.cpp new file mode 100644 index 0000000..69cfdba --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/CMakeCXXCompilerId.cpp @@ -0,0 +1,660 @@ +/* This source file must have a .cpp extension so that all C++ compilers + recognize the extension without flags. Borland does not know .cxx for + example. */ +#ifndef __cplusplus +# error "A C compiler has been selected for C++." +#endif + + +/* Version number components: V=Version, R=Revision, P=Patch + Version date components: YYYY=Year, MM=Month, DD=Day */ + +#if defined(__COMO__) +# define COMPILER_ID "Comeau" + /* __COMO_VERSION__ = VRR */ +# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100) +# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100) + +#elif defined(__INTEL_COMPILER) || defined(__ICC) +# define COMPILER_ID "Intel" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# if defined(__GNUC__) +# define SIMULATE_ID "GNU" +# endif + /* __INTEL_COMPILER = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) +# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) +# if defined(__INTEL_COMPILER_UPDATE) +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE) +# else +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) +# endif +# if defined(__INTEL_COMPILER_BUILD_DATE) + /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */ +# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) +# endif +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif +# if defined(__GNUC__) +# define SIMULATE_VERSION_MAJOR DEC(__GNUC__) +# elif defined(__GNUG__) +# define SIMULATE_VERSION_MAJOR DEC(__GNUG__) +# endif +# if defined(__GNUC_MINOR__) +# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__) +# endif +# if defined(__GNUC_PATCHLEVEL__) +# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif + +#elif defined(__PATHCC__) +# define COMPILER_ID "PathScale" +# define COMPILER_VERSION_MAJOR DEC(__PATHCC__) +# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) +# if defined(__PATHCC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) +# endif + +#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) +# define COMPILER_ID "Embarcadero" +# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) +# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) +# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF) + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + /* __BORLANDC__ = 0xVRR */ +# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) +# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) + +#elif defined(__WATCOMC__) && __WATCOMC__ < 1200 +# define COMPILER_ID "Watcom" + /* __WATCOMC__ = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) +# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) +# if (__WATCOMC__ % 10) > 0 +# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) +# endif + +#elif defined(__WATCOMC__) +# define COMPILER_ID "OpenWatcom" + /* __WATCOMC__ = VVRP + 1100 */ +# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100) +# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) +# if (__WATCOMC__ % 10) > 0 +# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) +# endif + +#elif defined(__SUNPRO_CC) +# define COMPILER_ID "SunPro" +# if __SUNPRO_CC >= 0x5100 + /* __SUNPRO_CC = 0xVRRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) +# else + /* __SUNPRO_CC = 0xVRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) +# endif + +#elif defined(__HP_aCC) +# define COMPILER_ID "HP" + /* __HP_aCC = VVRRPP */ +# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000) +# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100) +# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100) + +#elif defined(__DECCXX) +# define COMPILER_ID "Compaq" + /* __DECCXX_VER = VVRRTPPPP */ +# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000) +# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100) +# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000) + +#elif defined(__IBMCPP__) && defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" + /* __IBMCPP__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) + +#elif defined(__ibmxl__) && defined(__clang__) +# define COMPILER_ID "XLClang" +# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__) +# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__) +# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__) +# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__) + + +#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800 +# define COMPILER_ID "XL" + /* __IBMCPP__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) + +#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800 +# define COMPILER_ID "VisualAge" + /* __IBMCPP__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) + +#elif defined(__PGI) +# define COMPILER_ID "PGI" +# define COMPILER_VERSION_MAJOR DEC(__PGIC__) +# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) +# endif + +#elif defined(_CRAYC) +# define COMPILER_ID "Cray" +# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR) +# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) + +#elif defined(__TI_COMPILER_VERSION__) +# define COMPILER_ID "TI" + /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ +# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) +# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) +# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) + +#elif defined(__FUJITSU) || defined(__FCC_VERSION) || defined(__fcc_version) +# define COMPILER_ID "Fujitsu" + +#elif defined(__ghs__) +# define COMPILER_ID "GHS" +/* __GHS_VERSION_NUMBER = VVVVRP */ +# ifdef __GHS_VERSION_NUMBER +# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100) +# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10) +# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10) +# endif + +#elif defined(__SCO_VERSION__) +# define COMPILER_ID "SCO" + +#elif defined(__ARMCC_VERSION) && !defined(__clang__) +# define COMPILER_ID "ARMCC" +#if __ARMCC_VERSION >= 1000000 + /* __ARMCC_VERSION = VRRPPPP */ + # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000) + # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100) + # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) +#else + /* __ARMCC_VERSION = VRPPPP */ + # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000) + # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10) + # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) +#endif + + +#elif defined(__clang__) && defined(__apple_build_version__) +# define COMPILER_ID "AppleClang" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif +# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__) + +#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION) +# define COMPILER_ID "ARMClang" + # define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000) + # define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100) + # define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000) +# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION) + +#elif defined(__clang__) +# define COMPILER_ID "Clang" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif + +#elif defined(__GNUC__) || defined(__GNUG__) +# define COMPILER_ID "GNU" +# if defined(__GNUC__) +# define COMPILER_VERSION_MAJOR DEC(__GNUC__) +# else +# define COMPILER_VERSION_MAJOR DEC(__GNUG__) +# endif +# if defined(__GNUC_MINOR__) +# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) +# endif +# if defined(__GNUC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + /* _MSC_VER = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) +# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) +# if defined(_MSC_FULL_VER) +# if _MSC_VER >= 1400 + /* _MSC_FULL_VER = VVRRPPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) +# else + /* _MSC_FULL_VER = VVRRPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) +# endif +# endif +# if defined(_MSC_BUILD) +# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) +# endif + +#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) +# define COMPILER_ID "ADSP" +#if defined(__VISUALDSPVERSION__) + /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ +# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24) +# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF) +#endif + +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) +# define COMPILER_ID "IAR" +# if defined(__VER__) && defined(__ICCARM__) +# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000) +# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000) +# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000) +# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) +# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__)) +# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100) +# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100)) +# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__) +# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) +# endif + + +/* These compilers are either not known or too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; +#ifdef SIMULATE_ID +char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; +#endif + +#ifdef __QNXNTO__ +char const* qnxnto = "INFO" ":" "qnxnto[]"; +#endif + +#if defined(__CRAYXE) || defined(__CRAYXC) +char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]"; +#endif + +#define STRINGIFY_HELPER(X) #X +#define STRINGIFY(X) STRINGIFY_HELPER(X) + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU__) +# define PLATFORM_ID "Haiku" + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#elif defined(__WATCOMC__) +# if defined(__LINUX__) +# define PLATFORM_ID "Linux" + +# elif defined(__DOS__) +# define PLATFORM_ID "DOS" + +# elif defined(__OS2__) +# define PLATFORM_ID "OS2" + +# elif defined(__WINDOWS__) +# define PLATFORM_ID "Windows3x" + +# else /* unknown platform */ +# define PLATFORM_ID +# endif + +#elif defined(__INTEGRITY) +# if defined(INT_178B) +# define PLATFORM_ID "Integrity178" + +# else /* regular Integrity */ +# define PLATFORM_ID "Integrity" +# endif + +#else /* unknown platform */ +# define PLATFORM_ID + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is because + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# elif defined(_M_ARM64) +# define ARCHITECTURE_ID "ARM64" + +# elif defined(_M_ARM) +# if _M_ARM == 4 +# define ARCHITECTURE_ID "ARMV4I" +# elif _M_ARM == 5 +# define ARCHITECTURE_ID "ARMV5I" +# else +# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM) +# endif + +# elif defined(_M_MIPS) +# define ARCHITECTURE_ID "MIPS" + +# elif defined(_M_SH) +# define ARCHITECTURE_ID "SHx" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__WATCOMC__) +# if defined(_M_I86) +# define ARCHITECTURE_ID "I86" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) +# if defined(__ICCARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__ICCRX__) +# define ARCHITECTURE_ID "RX" + +# elif defined(__ICCRH850__) +# define ARCHITECTURE_ID "RH850" + +# elif defined(__ICCRL78__) +# define ARCHITECTURE_ID "RL78" + +# elif defined(__ICCRISCV__) +# define ARCHITECTURE_ID "RISCV" + +# elif defined(__ICCAVR__) +# define ARCHITECTURE_ID "AVR" + +# elif defined(__ICC430__) +# define ARCHITECTURE_ID "MSP430" + +# elif defined(__ICCV850__) +# define ARCHITECTURE_ID "V850" + +# elif defined(__ICC8051__) +# define ARCHITECTURE_ID "8051" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__ghs__) +# if defined(__PPC64__) +# define ARCHITECTURE_ID "PPC64" + +# elif defined(__ppc__) +# define ARCHITECTURE_ID "PPC" + +# elif defined(__ARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__x86_64__) +# define ARCHITECTURE_ID "x64" + +# elif defined(__i386__) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif +#else +# define ARCHITECTURE_ID +#endif + +/* Convert integer to decimal digit literals. */ +#define DEC(n) \ + ('0' + (((n) / 10000000)%10)), \ + ('0' + (((n) / 1000000)%10)), \ + ('0' + (((n) / 100000)%10)), \ + ('0' + (((n) / 10000)%10)), \ + ('0' + (((n) / 1000)%10)), \ + ('0' + (((n) / 100)%10)), \ + ('0' + (((n) / 10)%10)), \ + ('0' + ((n) % 10)) + +/* Convert integer to hex digit literals. */ +#define HEX(n) \ + ('0' + ((n)>>28 & 0xF)), \ + ('0' + ((n)>>24 & 0xF)), \ + ('0' + ((n)>>20 & 0xF)), \ + ('0' + ((n)>>16 & 0xF)), \ + ('0' + ((n)>>12 & 0xF)), \ + ('0' + ((n)>>8 & 0xF)), \ + ('0' + ((n)>>4 & 0xF)), \ + ('0' + ((n) & 0xF)) + +/* Construct a string literal encoding the version number components. */ +#ifdef COMPILER_VERSION_MAJOR +char const info_version[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', + COMPILER_VERSION_MAJOR, +# ifdef COMPILER_VERSION_MINOR + '.', COMPILER_VERSION_MINOR, +# ifdef COMPILER_VERSION_PATCH + '.', COMPILER_VERSION_PATCH, +# ifdef COMPILER_VERSION_TWEAK + '.', COMPILER_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct a string literal encoding the internal version number. */ +#ifdef COMPILER_VERSION_INTERNAL +char const info_version_internal[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_', + 'i','n','t','e','r','n','a','l','[', + COMPILER_VERSION_INTERNAL,']','\0'}; +#endif + +/* Construct a string literal encoding the version number components. */ +#ifdef SIMULATE_VERSION_MAJOR +char const info_simulate_version[] = { + 'I', 'N', 'F', 'O', ':', + 's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[', + SIMULATE_VERSION_MAJOR, +# ifdef SIMULATE_VERSION_MINOR + '.', SIMULATE_VERSION_MINOR, +# ifdef SIMULATE_VERSION_PATCH + '.', SIMULATE_VERSION_PATCH, +# ifdef SIMULATE_VERSION_TWEAK + '.', SIMULATE_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + + +#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG) && _MSVC_LANG < 201403L +# if defined(__INTEL_CXX11_MODE__) +# if defined(__cpp_aggregate_nsdmi) +# define CXX_STD 201402L +# else +# define CXX_STD 201103L +# endif +# else +# define CXX_STD 199711L +# endif +#elif defined(_MSC_VER) && defined(_MSVC_LANG) +# define CXX_STD _MSVC_LANG +#else +# define CXX_STD __cplusplus +#endif + +const char* info_language_dialect_default = "INFO" ":" "dialect_default[" +#if CXX_STD > 201703L + "20" +#elif CXX_STD >= 201703L + "17" +#elif CXX_STD >= 201402L + "14" +#elif CXX_STD >= 201103L + "11" +#else + "98" +#endif +"]"; + +/*--------------------------------------------------------------------------*/ + +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; +#ifdef COMPILER_VERSION_MAJOR + require += info_version[argc]; +#endif +#ifdef COMPILER_VERSION_INTERNAL + require += info_version_internal[argc]; +#endif +#ifdef SIMULATE_ID + require += info_simulate[argc]; +#endif +#ifdef SIMULATE_VERSION_MAJOR + require += info_simulate_version[argc]; +#endif +#if defined(__CRAYXE) || defined(__CRAYXC) + require += info_cray[argc]; +#endif + require += info_language_dialect_default[argc]; + (void)argv; + return require; +} diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/a.out b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/a.out new file mode 100755 index 0000000000000000000000000000000000000000..71c2ceda86a2fae89d661d131b89af3990e37838 GIT binary patch literal 8416 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 L;1d=k>el}!^A2#R literal 0 HcmV?d00001 diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeError.log b/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeError.log new file mode 100644 index 0000000..3f8570b --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeError.log @@ -0,0 +1,65 @@ +Performing C SOURCE FILE Test CMAKE_HAVE_LIBC_PTHREAD failed with the following output: +Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp + +Run Build Command(s):/usr/bin/make cmTC_6ff0d/fast && /usr/bin/make -f CMakeFiles/cmTC_6ff0d.dir/build.make CMakeFiles/cmTC_6ff0d.dir/build +make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Building C object CMakeFiles/cmTC_6ff0d.dir/src.c.o +/usr/bin/cc -DCMAKE_HAVE_LIBC_PTHREAD -o CMakeFiles/cmTC_6ff0d.dir/src.c.o -c /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/src.c +Linking C executable cmTC_6ff0d +/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_6ff0d.dir/link.txt --verbose=1 +/usr/bin/cc -DCMAKE_HAVE_LIBC_PTHREAD -rdynamic CMakeFiles/cmTC_6ff0d.dir/src.c.o -o cmTC_6ff0d +CMakeFiles/cmTC_6ff0d.dir/src.c.o: In function `main': +src.c:(.text+0x3e): undefined reference to `pthread_create' +src.c:(.text+0x4a): undefined reference to `pthread_detach' +src.c:(.text+0x56): undefined reference to `pthread_cancel' +src.c:(.text+0x67): undefined reference to `pthread_join' +src.c:(.text+0x7b): undefined reference to `pthread_atfork' +collect2: error: ld returned 1 exit status +CMakeFiles/cmTC_6ff0d.dir/build.make:106: recipe for target 'cmTC_6ff0d' failed +make[1]: *** [cmTC_6ff0d] Error 1 +make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Makefile:141: recipe for target 'cmTC_6ff0d/fast' failed +make: *** [cmTC_6ff0d/fast] Error 2 + + +Source file was: +#include + +void* test_func(void* data) +{ + return data; +} + +int main(void) +{ + pthread_t thread; + pthread_create(&thread, NULL, test_func, NULL); + pthread_detach(thread); + pthread_cancel(thread); + pthread_join(thread, NULL); + pthread_atfork(NULL, NULL, NULL); + pthread_exit(NULL); + + return 0; +} + +Determining if the function pthread_create exists in the pthreads failed with the following output: +Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp + +Run Build Command(s):/usr/bin/make cmTC_ce6d0/fast && /usr/bin/make -f CMakeFiles/cmTC_ce6d0.dir/build.make CMakeFiles/cmTC_ce6d0.dir/build +make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Building C object CMakeFiles/cmTC_ce6d0.dir/CheckFunctionExists.c.o +/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -o CMakeFiles/cmTC_ce6d0.dir/CheckFunctionExists.c.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CheckFunctionExists.c +Linking C executable cmTC_ce6d0 +/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_ce6d0.dir/link.txt --verbose=1 +/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -rdynamic CMakeFiles/cmTC_ce6d0.dir/CheckFunctionExists.c.o -o cmTC_ce6d0 -lpthreads +/usr/bin/ld: cannot find -lpthreads +collect2: error: ld returned 1 exit status +CMakeFiles/cmTC_ce6d0.dir/build.make:106: recipe for target 'cmTC_ce6d0' failed +make[1]: *** [cmTC_ce6d0] Error 1 +make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Makefile:141: recipe for target 'cmTC_ce6d0/fast' failed +make: *** [cmTC_ce6d0/fast] Error 2 + + + diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeOutput.log b/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeOutput.log new file mode 100644 index 0000000..73cebf5 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeOutput.log @@ -0,0 +1,522 @@ +The system is: Linux - 5.8.0-48-generic - x86_64 +Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded. +Compiler: /usr/bin/cc +Build flags: +Id flags: + +The output was: +0 + + +Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "a.out" + +The C compiler identification is GNU, found in "/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdC/a.out" + +Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded. +Compiler: /usr/bin/c++ +Build flags: +Id flags: + +The output was: +0 + + +Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out" + +The CXX compiler identification is GNU, found in "/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/a.out" + +Determining if the C compiler works passed with the following output: +Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp + +Run Build Command(s):/usr/bin/make cmTC_06aef/fast && /usr/bin/make -f CMakeFiles/cmTC_06aef.dir/build.make CMakeFiles/cmTC_06aef.dir/build +make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Building C object CMakeFiles/cmTC_06aef.dir/testCCompiler.c.o +/usr/bin/cc -o CMakeFiles/cmTC_06aef.dir/testCCompiler.c.o -c /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/testCCompiler.c +Linking C executable cmTC_06aef +/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_06aef.dir/link.txt --verbose=1 +/usr/bin/cc -rdynamic CMakeFiles/cmTC_06aef.dir/testCCompiler.c.o -o cmTC_06aef +make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' + + + +Detecting C compiler ABI info compiled with the following output: +Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp + +Run Build Command(s):/usr/bin/make cmTC_4d3e9/fast && /usr/bin/make -f CMakeFiles/cmTC_4d3e9.dir/build.make CMakeFiles/cmTC_4d3e9.dir/build +make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Building C object CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o +/usr/bin/cc -v -o CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCCompilerABI.c +Using built-in specs. +COLLECT_GCC=/usr/bin/cc +OFFLOAD_TARGET_NAMES=nvptx-none +OFFLOAD_TARGET_DEFAULT=1 +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) +COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' + /usr/lib/gcc/x86_64-linux-gnu/7/cc1 -quiet -v -imultiarch x86_64-linux-gnu /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCCompilerABI.c -quiet -dumpbase CMakeCCompilerABI.c -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccW0mWjy.s +GNU C11 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu) + compiled by GNU C version 7.5.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP + +GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" +ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/7/../../../../x86_64-linux-gnu/include" +#include "..." search starts here: +#include <...> search starts here: + /usr/lib/gcc/x86_64-linux-gnu/7/include + /usr/local/include + /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed + /usr/include/x86_64-linux-gnu + /usr/include +End of search list. +GNU C11 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu) + compiled by GNU C version 7.5.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP + +GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +Compiler executable checksum: b62ed4a2880cd4159476ea8293b72fa8 +COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' + as -v --64 -o CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o /tmp/ccW0mWjy.s +GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.30 +COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' +Linking C executable cmTC_4d3e9 +/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_4d3e9.dir/link.txt --verbose=1 +/usr/bin/cc -v -rdynamic CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -o cmTC_4d3e9 +Using built-in specs. +COLLECT_GCC=/usr/bin/cc +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper +OFFLOAD_TARGET_NAMES=nvptx-none +OFFLOAD_TARGET_DEFAULT=1 +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) +COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_4d3e9' '-mtune=generic' '-march=x86-64' + /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/cckCIR5B.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_4d3e9 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o +COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_4d3e9' '-mtune=generic' '-march=x86-64' +make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' + + + +Parsed C implicit include dir info from above output: rv=done + found start of include info + found start of implicit include info + add: [/usr/lib/gcc/x86_64-linux-gnu/7/include] + add: [/usr/local/include] + add: [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] + add: [/usr/include/x86_64-linux-gnu] + add: [/usr/include] + end of search list found + collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/7/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/7/include] + collapse include dir [/usr/local/include] ==> [/usr/local/include] + collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] ==> [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] + collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu] + collapse include dir [/usr/include] ==> [/usr/include] + implicit include dirs: [/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include] + + +Parsed C implicit link information from above output: + link line regex: [^( *|.*[/\])(ld|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)] + ignore line: [Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp] + ignore line: [] + ignore line: [Run Build Command(s):/usr/bin/make cmTC_4d3e9/fast && /usr/bin/make -f CMakeFiles/cmTC_4d3e9.dir/build.make CMakeFiles/cmTC_4d3e9.dir/build] + ignore line: [make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp'] + ignore line: [Building C object CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o] + ignore line: [/usr/bin/cc -v -o CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCCompilerABI.c] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/cc] + ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none] + ignore line: [OFFLOAD_TARGET_DEFAULT=1] + ignore line: [Target: x86_64-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] + ignore line: [Thread model: posix] + ignore line: [gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) ] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'] + ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/cc1 -quiet -v -imultiarch x86_64-linux-gnu /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCCompilerABI.c -quiet -dumpbase CMakeCCompilerABI.c -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccW0mWjy.s] + ignore line: [GNU C11 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu)] + ignore line: [ compiled by GNU C version 7.5.0 GMP version 6.1.2 MPFR version 4.0.1 MPC version 1.1.0 isl version isl-0.19-GMP] + ignore line: [] + ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072] + ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"] + ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/7/../../../../x86_64-linux-gnu/include"] + ignore line: [#include "..." search starts here:] + ignore line: [#include <...> search starts here:] + ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/include] + ignore line: [ /usr/local/include] + ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] + ignore line: [ /usr/include/x86_64-linux-gnu] + ignore line: [ /usr/include] + ignore line: [End of search list.] + ignore line: [GNU C11 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu)] + ignore line: [ compiled by GNU C version 7.5.0 GMP version 6.1.2 MPFR version 4.0.1 MPC version 1.1.0 isl version isl-0.19-GMP] + ignore line: [] + ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072] + ignore line: [Compiler executable checksum: b62ed4a2880cd4159476ea8293b72fa8] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'] + ignore line: [ as -v --64 -o CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o /tmp/ccW0mWjy.s] + ignore line: [GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.30] + ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'] + ignore line: [Linking C executable cmTC_4d3e9] + ignore line: [/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_4d3e9.dir/link.txt --verbose=1] + ignore line: [/usr/bin/cc -v -rdynamic CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -o cmTC_4d3e9 ] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/cc] + ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper] + ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none] + ignore line: [OFFLOAD_TARGET_DEFAULT=1] + ignore line: [Target: x86_64-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] + ignore line: [Thread model: posix] + ignore line: [gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) ] + ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_4d3e9' '-mtune=generic' '-march=x86-64'] + link line: [ /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/cckCIR5B.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_4d3e9 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o] + arg [/usr/lib/gcc/x86_64-linux-gnu/7/collect2] ==> ignore + arg [-plugin] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so] ==> ignore + arg [-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper] ==> ignore + arg [-plugin-opt=-fresolution=/tmp/cckCIR5B.res] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore + arg [-plugin-opt=-pass-through=-lc] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore + arg [--build-id] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-m] ==> ignore + arg [elf_x86_64] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [--as-needed] ==> ignore + arg [-export-dynamic] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib64/ld-linux-x86-64.so.2] ==> ignore + arg [-pie] ==> ignore + arg [-znow] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTC_4d3e9] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o] ==> ignore + arg [-L/usr/lib/gcc/x86_64-linux-gnu/7] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] + arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu] + arg [-L/lib/../lib] ==> dir [/lib/../lib] + arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu] + arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../..] + arg [CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o] ==> ignore + arg [-lgcc] ==> lib [gcc] + arg [--push-state] ==> ignore + arg [--as-needed] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [--pop-state] ==> ignore + arg [-lc] ==> lib [c] + arg [-lgcc] ==> lib [gcc] + arg [--push-state] ==> ignore + arg [--as-needed] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [--pop-state] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o] ==> ignore + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7] ==> [/usr/lib/gcc/x86_64-linux-gnu/7] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] ==> [/usr/lib] + collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu] + collapse library dir [/lib/../lib] ==> [/lib] + collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse library dir [/usr/lib/../lib] ==> [/usr/lib] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../..] ==> [/usr/lib] + implicit libs: [gcc;gcc_s;c;gcc;gcc_s] + implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/7;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib] + implicit fwks: [] + + +Determining if the CXX compiler works passed with the following output: +Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp + +Run Build Command(s):/usr/bin/make cmTC_36240/fast && /usr/bin/make -f CMakeFiles/cmTC_36240.dir/build.make CMakeFiles/cmTC_36240.dir/build +make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Building CXX object CMakeFiles/cmTC_36240.dir/testCXXCompiler.cxx.o +/usr/bin/c++ -o CMakeFiles/cmTC_36240.dir/testCXXCompiler.cxx.o -c /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/testCXXCompiler.cxx +Linking CXX executable cmTC_36240 +/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_36240.dir/link.txt --verbose=1 +/usr/bin/c++ -rdynamic CMakeFiles/cmTC_36240.dir/testCXXCompiler.cxx.o -o cmTC_36240 +make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' + + + +Detecting CXX compiler ABI info compiled with the following output: +Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp + +Run Build Command(s):/usr/bin/make cmTC_bddc5/fast && /usr/bin/make -f CMakeFiles/cmTC_bddc5.dir/build.make CMakeFiles/cmTC_bddc5.dir/build +make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Building CXX object CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o +/usr/bin/c++ -v -o CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCXXCompilerABI.cpp +Using built-in specs. +COLLECT_GCC=/usr/bin/c++ +OFFLOAD_TARGET_NAMES=nvptx-none +OFFLOAD_TARGET_DEFAULT=1 +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) +COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' + /usr/lib/gcc/x86_64-linux-gnu/7/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpbase CMakeCXXCompilerABI.cpp -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccEVgspL.s +GNU C++14 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu) + compiled by GNU C version 7.5.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP + +GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/7" +ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" +ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/7/../../../../x86_64-linux-gnu/include" +#include "..." search starts here: +#include <...> search starts here: + /usr/include/c++/7 + /usr/include/x86_64-linux-gnu/c++/7 + /usr/include/c++/7/backward + /usr/lib/gcc/x86_64-linux-gnu/7/include + /usr/local/include + /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed + /usr/include/x86_64-linux-gnu + /usr/include +End of search list. +GNU C++14 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu) + compiled by GNU C version 7.5.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP + +GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +Compiler executable checksum: 3eb3dc290cd5714c3e1c3ae751116f07 +COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' + as -v --64 -o CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccEVgspL.s +GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.30 +COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' +Linking CXX executable cmTC_bddc5 +/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_bddc5.dir/link.txt --verbose=1 +/usr/bin/c++ -v -rdynamic CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_bddc5 +Using built-in specs. +COLLECT_GCC=/usr/bin/c++ +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper +OFFLOAD_TARGET_NAMES=nvptx-none +OFFLOAD_TARGET_DEFAULT=1 +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) +COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_bddc5' '-shared-libgcc' '-mtune=generic' '-march=x86-64' + /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/cckr006M.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_bddc5 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o +COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_bddc5' '-shared-libgcc' '-mtune=generic' '-march=x86-64' +make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' + + + +Parsed CXX implicit include dir info from above output: rv=done + found start of include info + found start of implicit include info + add: [/usr/include/c++/7] + add: [/usr/include/x86_64-linux-gnu/c++/7] + add: [/usr/include/c++/7/backward] + add: [/usr/lib/gcc/x86_64-linux-gnu/7/include] + add: [/usr/local/include] + add: [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] + add: [/usr/include/x86_64-linux-gnu] + add: [/usr/include] + end of search list found + collapse include dir [/usr/include/c++/7] ==> [/usr/include/c++/7] + collapse include dir [/usr/include/x86_64-linux-gnu/c++/7] ==> [/usr/include/x86_64-linux-gnu/c++/7] + collapse include dir [/usr/include/c++/7/backward] ==> [/usr/include/c++/7/backward] + collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/7/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/7/include] + collapse include dir [/usr/local/include] ==> [/usr/local/include] + collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] ==> [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] + collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu] + collapse include dir [/usr/include] ==> [/usr/include] + implicit include dirs: [/usr/include/c++/7;/usr/include/x86_64-linux-gnu/c++/7;/usr/include/c++/7/backward;/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include] + + +Parsed CXX implicit link information from above output: + link line regex: [^( *|.*[/\])(ld|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)] + ignore line: [Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp] + ignore line: [] + ignore line: [Run Build Command(s):/usr/bin/make cmTC_bddc5/fast && /usr/bin/make -f CMakeFiles/cmTC_bddc5.dir/build.make CMakeFiles/cmTC_bddc5.dir/build] + ignore line: [make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp'] + ignore line: [Building CXX object CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o] + ignore line: [/usr/bin/c++ -v -o CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCXXCompilerABI.cpp] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/c++] + ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none] + ignore line: [OFFLOAD_TARGET_DEFAULT=1] + ignore line: [Target: x86_64-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] + ignore line: [Thread model: posix] + ignore line: [gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) ] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'] + ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpbase CMakeCXXCompilerABI.cpp -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccEVgspL.s] + ignore line: [GNU C++14 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu)] + ignore line: [ compiled by GNU C version 7.5.0 GMP version 6.1.2 MPFR version 4.0.1 MPC version 1.1.0 isl version isl-0.19-GMP] + ignore line: [] + ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072] + ignore line: [ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/7"] + ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"] + ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/7/../../../../x86_64-linux-gnu/include"] + ignore line: [#include "..." search starts here:] + ignore line: [#include <...> search starts here:] + ignore line: [ /usr/include/c++/7] + ignore line: [ /usr/include/x86_64-linux-gnu/c++/7] + ignore line: [ /usr/include/c++/7/backward] + ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/include] + ignore line: [ /usr/local/include] + ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] + ignore line: [ /usr/include/x86_64-linux-gnu] + ignore line: [ /usr/include] + ignore line: [End of search list.] + ignore line: [GNU C++14 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu)] + ignore line: [ compiled by GNU C version 7.5.0 GMP version 6.1.2 MPFR version 4.0.1 MPC version 1.1.0 isl version isl-0.19-GMP] + ignore line: [] + ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072] + ignore line: [Compiler executable checksum: 3eb3dc290cd5714c3e1c3ae751116f07] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'] + ignore line: [ as -v --64 -o CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccEVgspL.s] + ignore line: [GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.30] + ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'] + ignore line: [Linking CXX executable cmTC_bddc5] + ignore line: [/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_bddc5.dir/link.txt --verbose=1] + ignore line: [/usr/bin/c++ -v -rdynamic CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_bddc5 ] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/c++] + ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper] + ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none] + ignore line: [OFFLOAD_TARGET_DEFAULT=1] + ignore line: [Target: x86_64-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] + ignore line: [Thread model: posix] + ignore line: [gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) ] + ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_bddc5' '-shared-libgcc' '-mtune=generic' '-march=x86-64'] + link line: [ /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/cckr006M.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_bddc5 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o] + arg [/usr/lib/gcc/x86_64-linux-gnu/7/collect2] ==> ignore + arg [-plugin] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so] ==> ignore + arg [-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper] ==> ignore + arg [-plugin-opt=-fresolution=/tmp/cckr006M.res] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc] ==> ignore + arg [-plugin-opt=-pass-through=-lc] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc] ==> ignore + arg [--build-id] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-m] ==> ignore + arg [elf_x86_64] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [--as-needed] ==> ignore + arg [-export-dynamic] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib64/ld-linux-x86-64.so.2] ==> ignore + arg [-pie] ==> ignore + arg [-znow] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTC_bddc5] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o] ==> ignore + arg [-L/usr/lib/gcc/x86_64-linux-gnu/7] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] + arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu] + arg [-L/lib/../lib] ==> dir [/lib/../lib] + arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu] + arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../..] + arg [CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore + arg [-lstdc++] ==> lib [stdc++] + arg [-lm] ==> lib [m] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [-lc] ==> lib [c] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o] ==> ignore + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7] ==> [/usr/lib/gcc/x86_64-linux-gnu/7] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] ==> [/usr/lib] + collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu] + collapse library dir [/lib/../lib] ==> [/lib] + collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse library dir [/usr/lib/../lib] ==> [/usr/lib] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../..] ==> [/usr/lib] + implicit libs: [stdc++;m;gcc_s;gcc;c;gcc_s;gcc] + implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/7;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib] + implicit fwks: [] + + +Determining if the include file pthread.h exists passed with the following output: +Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp + +Run Build Command(s):/usr/bin/make cmTC_7a980/fast && /usr/bin/make -f CMakeFiles/cmTC_7a980.dir/build.make CMakeFiles/cmTC_7a980.dir/build +make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Building C object CMakeFiles/cmTC_7a980.dir/CheckIncludeFile.c.o +/usr/bin/cc -o CMakeFiles/cmTC_7a980.dir/CheckIncludeFile.c.o -c /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/CheckIncludeFile.c +Linking C executable cmTC_7a980 +/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_7a980.dir/link.txt --verbose=1 +/usr/bin/cc -rdynamic CMakeFiles/cmTC_7a980.dir/CheckIncludeFile.c.o -o cmTC_7a980 +make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' + + + +Determining if the function pthread_create exists in the pthread passed with the following output: +Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp + +Run Build Command(s):/usr/bin/make cmTC_1a96d/fast && /usr/bin/make -f CMakeFiles/cmTC_1a96d.dir/build.make CMakeFiles/cmTC_1a96d.dir/build +make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Building C object CMakeFiles/cmTC_1a96d.dir/CheckFunctionExists.c.o +/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -o CMakeFiles/cmTC_1a96d.dir/CheckFunctionExists.c.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CheckFunctionExists.c +Linking C executable cmTC_1a96d +/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_1a96d.dir/link.txt --verbose=1 +/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -rdynamic CMakeFiles/cmTC_1a96d.dir/CheckFunctionExists.c.o -o cmTC_1a96d -lpthread +make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' + + + +Determining if the CL_VERSION_2_2 exist passed with the following output: +Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp + +Run Build Command(s):/usr/bin/make cmTC_fdf34/fast && /usr/bin/make -f CMakeFiles/cmTC_fdf34.dir/build.make CMakeFiles/cmTC_fdf34.dir/build +make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' +Building C object CMakeFiles/cmTC_fdf34.dir/CheckSymbolExists.c.o +/usr/bin/cc -o CMakeFiles/cmTC_fdf34.dir/CheckSymbolExists.c.o -c /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/CheckSymbolExists.c +Linking C executable cmTC_fdf34 +/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_fdf34.dir/link.txt --verbose=1 +/usr/bin/cc -rdynamic CMakeFiles/cmTC_fdf34.dir/CheckSymbolExists.c.o -o cmTC_fdf34 +make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' + + +File /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/CheckSymbolExists.c: +/* */ +#include + +int main(int argc, char** argv) +{ + (void)argv; +#ifndef CL_VERSION_2_2 + return ((int*)(&CL_VERSION_2_2))[argc]; +#else + (void)argc; + return 0; +#endif +} diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-environment.txt b/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-environment.txt new file mode 100644 index 0000000..270d93c --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-environment.txt @@ -0,0 +1,3 @@ +ToolSet: 1.0 (local)Options: + +Options: \ No newline at end of file diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-log.txt b/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-log.txt new file mode 100644 index 0000000..1363506 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-log.txt @@ -0,0 +1,70 @@ +/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - Unix Makefiles" /root/Project/ROS/src/vio_svo/GPU_version/svo +-- The C compiler identification is GNU 7.5.0 +-- The CXX compiler identification is GNU 7.5.0 +-- Check for working C compiler: /usr/bin/cc +-- Check for working C compiler: /usr/bin/cc - works +-- Detecting C compiler ABI info +-- Detecting C compiler ABI info - done +-- Detecting C compile features +-- Detecting C compile features - done +-- Check for working CXX compiler: /usr/bin/c++ +-- Check for working CXX compiler: /usr/bin/c++ - works +-- Detecting CXX compiler ABI info +-- Detecting CXX compiler ABI info - done +-- Detecting CXX compile features +-- Detecting CXX compile features - done +-- Found OpenCV: /usr (found suitable version "3.2.0", minimum required is "3") +-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1") +-- Checking for module 'eigen3' +-- Found eigen3, version 3.3.4 +-- Found Eigen: /usr/include/eigen3 +-- Eigen found (include: /usr/include/eigen3) +-- Looking for pthread.h +-- Looking for pthread.h - found +-- Performing Test CMAKE_HAVE_LIBC_PTHREAD +-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed +-- Looking for pthread_create in pthreads +-- Looking for pthread_create in pthreads - not found +-- Looking for pthread_create in pthread +-- Looking for pthread_create in pthread - found +-- Found Threads: TRUE +-- Found Boost: /usr/include (found version "1.65.1") found components: thread system chrono date_time atomic +-- Looking for CL_VERSION_2_2 +-- Looking for CL_VERSION_2_2 - found +-- Found OpenCL: /usr/lib/x86_64-linux-gnu/libOpenCL.so (found version "2.2") +-- Using CATKIN_DEVEL_PREFIX: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel +-- Using CMAKE_PREFIX_PATH: /opt/ros/melodic +-- This workspace overlays: /opt/ros/melodic +-- Found PythonInterp: /usr/bin/python2 (found suitable version "2.7.17", minimum required is "2") +-- Using PYTHON_EXECUTABLE: /usr/bin/python2 +-- Using Debian Python package layout +-- Using empy: /usr/bin/empy +-- Using CATKIN_ENABLE_TESTING: ON +-- Call enable_testing() +-- Using CATKIN_TEST_RESULTS_DIR: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/test_results +-- Found gtest sources under '/usr/src/googletest': gtests will be built +-- Found gmock sources under '/usr/src/googletest': gmock will be built +-- Found PythonInterp: /usr/bin/python2 (found version "2.7.17") +-- Using Python nosetests: /usr/bin/nosetests-2.7 +-- catkin 0.7.28 +-- BUILD_SHARED_LIBS is on +-- Could NOT find robot_localization (missing: robot_localization_DIR) +-- Could not find the required component 'robot_localization'. The following CMake error indicates that you either need to install the package with the same name or change your environment so that it can be found. +CMake Error at /opt/ros/melodic/share/catkin/cmake/catkinConfig.cmake:83 (find_package): + Could not find a package configuration file provided by + "robot_localization" with any of the following names: + + robot_localizationConfig.cmake + robot_localization-config.cmake + + Add the installation prefix of "robot_localization" to CMAKE_PREFIX_PATH or + set "robot_localization_DIR" to a directory containing one of the above + files. If "robot_localization" provides a separate development package or + SDK, be sure it has been installed. +Call Stack (most recent call first): + CMakeLists.txt:34 (FIND_PACKAGE) + + +-- Configuring incomplete, errors occurred! +See also "/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeOutput.log". +See also "/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeError.log". diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/cmake.check_cache b/GPU_version/vio/cmake-build-debug/CMakeFiles/cmake.check_cache new file mode 100644 index 0000000..3dccd73 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CMakeFiles/cmake.check_cache @@ -0,0 +1 @@ +# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/GPU_version/vio/cmake-build-debug/CTestConfiguration.ini b/GPU_version/vio/cmake-build-debug/CTestConfiguration.ini new file mode 100644 index 0000000..38e6ab1 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CTestConfiguration.ini @@ -0,0 +1,107 @@ +# This file is configured by CMake automatically as DartConfiguration.tcl +# If you choose not to use CMake, this file may be hand configured, by +# filling in the required variables. + + +# Configuration directories and files +SourceDirectory: /root/Project/ROS/src/vio_svo/GPU_version/svo +BuildDirectory: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug + +# Where to place the cost data store +CostDataFile: + +# Site is something like machine.domain, i.e. pragmatic.crd +Site: gfuse + +# Build name is osname-revision-compiler, i.e. Linux-2.4.2-2smp-c++ +BuildName: + +# Subprojects +LabelsForSubprojects: + +# Submission information +SubmitURL: + +# Dashboard start time +NightlyStartTime: + +# Commands for the build/test/submit cycle +ConfigureCommand: "/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake" "/root/Project/ROS/src/vio_svo/GPU_version/svo" +MakeCommand: +DefaultCTestConfigurationType: + +# version control +UpdateVersionOnly: + +# CVS options +# Default is "-d -P -A" +CVSCommand: +CVSUpdateOptions: + +# Subversion options +SVNCommand: +SVNOptions: +SVNUpdateOptions: + +# Git options +GITCommand: +GITInitSubmodules: +GITUpdateOptions: +GITUpdateCustom: + +# Perforce options +P4Command: +P4Client: +P4Options: +P4UpdateOptions: +P4UpdateCustom: + +# Generic update command +UpdateCommand: +UpdateOptions: +UpdateType: + +# Compiler info +Compiler: /usr/bin/c++ +CompilerVersion: 7.5.0 + +# Dynamic analysis (MemCheck) +PurifyCommand: +ValgrindCommand: +ValgrindCommandOptions: +DrMemoryCommand: +DrMemoryCommandOptions: +MemoryCheckType: +MemoryCheckSanitizerOptions: +MemoryCheckCommand: +MemoryCheckCommandOptions: +MemoryCheckSuppressionFile: + +# Coverage +CoverageCommand: +CoverageExtraFlags: + +# Cluster commands +SlurmBatchCommand: +SlurmRunCommand: + +# Testing options +# TimeOut is the amount of time in seconds to wait for processes +# to complete during testing. After TimeOut seconds, the +# process will be summarily terminated. +# Currently set to 25 minutes +TimeOut: + +# During parallel testing CTest will not start a new test if doing +# so would cause the system load to exceed this value. +TestLoad: + +UseLaunchers: +CurlOptions: +# warning, if you add new options here that have to do with submit, +# you have to update cmCTestSubmitCommand.cxx + +# For CTest submissions that timeout, these options +# specify behavior for retrying the submission +CTestSubmitRetryDelay: +CTestSubmitRetryCount: diff --git a/GPU_version/vio/cmake-build-debug/CTestCustom.cmake b/GPU_version/vio/cmake-build-debug/CTestCustom.cmake new file mode 100644 index 0000000..14956f3 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/CTestCustom.cmake @@ -0,0 +1,2 @@ +set(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 0) +set(CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE 0) diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/.rosinstall b/GPU_version/vio/cmake-build-debug/atomic_configure/.rosinstall new file mode 100644 index 0000000..b61ff9e --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/atomic_configure/.rosinstall @@ -0,0 +1,2 @@ +- setup-file: + local-name: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel/setup.sh diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/_setup_util.py b/GPU_version/vio/cmake-build-debug/atomic_configure/_setup_util.py new file mode 100755 index 0000000..760f26f --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/atomic_configure/_setup_util.py @@ -0,0 +1,304 @@ +#!/usr/bin/python2 +# -*- coding: utf-8 -*- + +# Software License Agreement (BSD License) +# +# Copyright (c) 2012, Willow Garage, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Willow Garage, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +"""This file generates shell code for the setup.SHELL scripts to set environment variables.""" + +from __future__ import print_function + +import argparse +import copy +import errno +import os +import platform +import sys + +CATKIN_MARKER_FILE = '.catkin' + +system = platform.system() +IS_DARWIN = (system == 'Darwin') +IS_WINDOWS = (system == 'Windows') + +PATH_TO_ADD_SUFFIX = ['bin'] +if IS_WINDOWS: + # while catkin recommends putting dll's into bin, 3rd party packages often put dll's into lib + # since Windows finds dll's via the PATH variable, prepend it with path to lib + PATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'x86_64-linux-gnu')]]) + +# subfolder of workspace prepended to CMAKE_PREFIX_PATH +ENV_VAR_SUBFOLDERS = { + 'CMAKE_PREFIX_PATH': '', + 'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'x86_64-linux-gnu')], + 'PATH': PATH_TO_ADD_SUFFIX, + 'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'x86_64-linux-gnu', 'pkgconfig')], + 'PYTHONPATH': 'lib/python2.7/dist-packages', +} + + +def rollback_env_variables(environ, env_var_subfolders): + """ + Generate shell code to reset environment variables. + + by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH. + This does not cover modifications performed by environment hooks. + """ + lines = [] + unmodified_environ = copy.copy(environ) + for key in sorted(env_var_subfolders.keys()): + subfolders = env_var_subfolders[key] + if not isinstance(subfolders, list): + subfolders = [subfolders] + value = _rollback_env_variable(unmodified_environ, key, subfolders) + if value is not None: + environ[key] = value + lines.append(assignment(key, value)) + if lines: + lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH')) + return lines + + +def _rollback_env_variable(environ, name, subfolders): + """ + For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder. + + :param subfolders: list of str '' or subfoldername that may start with '/' + :returns: the updated value of the environment variable. + """ + value = environ[name] if name in environ else '' + env_paths = [path for path in value.split(os.pathsep) if path] + value_modified = False + for subfolder in subfolders: + if subfolder: + if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)): + subfolder = subfolder[1:] + if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)): + subfolder = subfolder[:-1] + for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True): + path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path + path_to_remove = None + for env_path in env_paths: + env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path + if env_path_clean == path_to_find: + path_to_remove = env_path + break + if path_to_remove: + env_paths.remove(path_to_remove) + value_modified = True + new_value = os.pathsep.join(env_paths) + return new_value if value_modified else None + + +def _get_workspaces(environ, include_fuerte=False, include_non_existing=False): + """ + Based on CMAKE_PREFIX_PATH return all catkin workspaces. + + :param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool`` + """ + # get all cmake prefix paths + env_name = 'CMAKE_PREFIX_PATH' + value = environ[env_name] if env_name in environ else '' + paths = [path for path in value.split(os.pathsep) if path] + # remove non-workspace paths + workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))] + return workspaces + + +def prepend_env_variables(environ, env_var_subfolders, workspaces): + """Generate shell code to prepend environment variables for the all workspaces.""" + lines = [] + lines.append(comment('prepend folders of workspaces to environment variables')) + + paths = [path for path in workspaces.split(os.pathsep) if path] + + prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '') + lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix)) + + for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'): + subfolder = env_var_subfolders[key] + prefix = _prefix_env_variable(environ, key, paths, subfolder) + lines.append(prepend(environ, key, prefix)) + return lines + + +def _prefix_env_variable(environ, name, paths, subfolders): + """ + Return the prefix to prepend to the environment variable NAME. + + Adding any path in NEW_PATHS_STR without creating duplicate or empty items. + """ + value = environ[name] if name in environ else '' + environ_paths = [path for path in value.split(os.pathsep) if path] + checked_paths = [] + for path in paths: + if not isinstance(subfolders, list): + subfolders = [subfolders] + for subfolder in subfolders: + path_tmp = path + if subfolder: + path_tmp = os.path.join(path_tmp, subfolder) + # skip nonexistent paths + if not os.path.exists(path_tmp): + continue + # exclude any path already in env and any path we already added + if path_tmp not in environ_paths and path_tmp not in checked_paths: + checked_paths.append(path_tmp) + prefix_str = os.pathsep.join(checked_paths) + if prefix_str != '' and environ_paths: + prefix_str += os.pathsep + return prefix_str + + +def assignment(key, value): + if not IS_WINDOWS: + return 'export %s="%s"' % (key, value) + else: + return 'set %s=%s' % (key, value) + + +def comment(msg): + if not IS_WINDOWS: + return '# %s' % msg + else: + return 'REM %s' % msg + + +def prepend(environ, key, prefix): + if key not in environ or not environ[key]: + return assignment(key, prefix) + if not IS_WINDOWS: + return 'export %s="%s$%s"' % (key, prefix, key) + else: + return 'set %s=%s%%%s%%' % (key, prefix, key) + + +def find_env_hooks(environ, cmake_prefix_path): + """Generate shell code with found environment hooks for the all workspaces.""" + lines = [] + lines.append(comment('found environment hooks in workspaces')) + + generic_env_hooks = [] + generic_env_hooks_workspace = [] + specific_env_hooks = [] + specific_env_hooks_workspace = [] + generic_env_hooks_by_filename = {} + specific_env_hooks_by_filename = {} + generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh' + specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None + # remove non-workspace paths + workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))] + for workspace in reversed(workspaces): + env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d') + if os.path.isdir(env_hook_dir): + for filename in sorted(os.listdir(env_hook_dir)): + if filename.endswith('.%s' % generic_env_hook_ext): + # remove previous env hook with same name if present + if filename in generic_env_hooks_by_filename: + i = generic_env_hooks.index(generic_env_hooks_by_filename[filename]) + generic_env_hooks.pop(i) + generic_env_hooks_workspace.pop(i) + # append env hook + generic_env_hooks.append(os.path.join(env_hook_dir, filename)) + generic_env_hooks_workspace.append(workspace) + generic_env_hooks_by_filename[filename] = generic_env_hooks[-1] + elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext): + # remove previous env hook with same name if present + if filename in specific_env_hooks_by_filename: + i = specific_env_hooks.index(specific_env_hooks_by_filename[filename]) + specific_env_hooks.pop(i) + specific_env_hooks_workspace.pop(i) + # append env hook + specific_env_hooks.append(os.path.join(env_hook_dir, filename)) + specific_env_hooks_workspace.append(workspace) + specific_env_hooks_by_filename[filename] = specific_env_hooks[-1] + env_hooks = generic_env_hooks + specific_env_hooks + env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace + count = len(env_hooks) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count)) + for i in range(count): + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i])) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i])) + return lines + + +def _parse_arguments(args=None): + parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.') + parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context') + parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment') + return parser.parse_known_args(args=args)[0] + + +if __name__ == '__main__': + try: + try: + args = _parse_arguments() + except Exception as e: + print(e, file=sys.stderr) + sys.exit(1) + + if not args.local: + # environment at generation time + CMAKE_PREFIX_PATH = '/opt/ros/melodic'.split(';') + else: + # don't consider any other prefix path than this one + CMAKE_PREFIX_PATH = [] + # prepend current workspace if not already part of CPP + base_path = os.path.dirname(__file__) + # CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent + # base_path on Windows contains backward slashes, need to be converted to forward slashes before comparison + if os.path.sep != '/': + base_path = base_path.replace(os.path.sep, '/') + + if base_path not in CMAKE_PREFIX_PATH: + CMAKE_PREFIX_PATH.insert(0, base_path) + CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH) + + environ = dict(os.environ) + lines = [] + if not args.extend: + lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS) + lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH) + lines += find_env_hooks(environ, CMAKE_PREFIX_PATH) + print('\n'.join(lines)) + + # need to explicitly flush the output + sys.stdout.flush() + except IOError as e: + # and catch potential "broken pipe" if stdout is not writable + # which can happen when piping the output to a file but the disk is full + if e.errno == errno.EPIPE: + print(e, file=sys.stderr) + sys.exit(2) + raise + + sys.exit(0) diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/env.sh b/GPU_version/vio/cmake-build-debug/atomic_configure/env.sh new file mode 100755 index 0000000..8aa9d24 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/atomic_configure/env.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/templates/env.sh.in + +if [ $# -eq 0 ] ; then + /bin/echo "Usage: env.sh COMMANDS" + /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." + exit 1 +fi + +# ensure to not use different shell type which was set before +CATKIN_SHELL=sh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" +exec "$@" diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.bash b/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.bash new file mode 100644 index 0000000..7da0d97 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# generated from catkin/cmake/templates/local_setup.bash.in + +CATKIN_SHELL=bash + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" --extend --local diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.sh b/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.sh new file mode 100644 index 0000000..d29ab41 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/template/local_setup.sh.in + +# since this file is sourced either use the provided _CATKIN_SETUP_DIR +# or fall back to the destination set at configure time +: ${_CATKIN_SETUP_DIR:=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel} +CATKIN_SETUP_UTIL_ARGS="--extend --local" +. "$_CATKIN_SETUP_DIR/setup.sh" +unset CATKIN_SETUP_UTIL_ARGS diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.zsh b/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.zsh new file mode 100644 index 0000000..e692acc --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.zsh @@ -0,0 +1,8 @@ +#!/usr/bin/env zsh +# generated from catkin/cmake/templates/local_setup.zsh.in + +CATKIN_SHELL=zsh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) +emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh" --extend --local' diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/setup.bash b/GPU_version/vio/cmake-build-debug/atomic_configure/setup.bash new file mode 100644 index 0000000..ff47af8 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/atomic_configure/setup.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# generated from catkin/cmake/templates/setup.bash.in + +CATKIN_SHELL=bash + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/setup.sh b/GPU_version/vio/cmake-build-debug/atomic_configure/setup.sh new file mode 100644 index 0000000..1764d84 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/atomic_configure/setup.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/template/setup.sh.in + +# Sets various environment variables and sources additional environment hooks. +# It tries it's best to undo changes from a previously sourced setup file before. +# Supported command line options: +# --extend: skips the undoing of changes from a previously sourced setup file +# --local: only considers this workspace but not the chained ones +# In plain sh shell which doesn't support arguments for sourced scripts you can +# set the environment variable `CATKIN_SETUP_UTIL_ARGS=--extend/--local` instead. + +# since this file is sourced either use the provided _CATKIN_SETUP_DIR +# or fall back to the destination set at configure time +: ${_CATKIN_SETUP_DIR:=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel} +_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py" +unset _CATKIN_SETUP_DIR + +if [ ! -f "$_SETUP_UTIL" ]; then + echo "Missing Python script: $_SETUP_UTIL" + return 22 +fi + +# detect if running on Darwin platform +_UNAME=`uname -s` +_IS_DARWIN=0 +if [ "$_UNAME" = "Darwin" ]; then + _IS_DARWIN=1 +fi +unset _UNAME + +# make sure to export all environment variables +export CMAKE_PREFIX_PATH +if [ $_IS_DARWIN -eq 0 ]; then + export LD_LIBRARY_PATH +else + export DYLD_LIBRARY_PATH +fi +unset _IS_DARWIN +export PATH +export PKG_CONFIG_PATH +export PYTHONPATH + +# remember type of shell if not already set +if [ -z "$CATKIN_SHELL" ]; then + CATKIN_SHELL=sh +fi + +# invoke Python script to generate necessary exports of environment variables +# use TMPDIR if it exists, otherwise fall back to /tmp +if [ -d "${TMPDIR:-}" ]; then + _TMPDIR="${TMPDIR}" +else + _TMPDIR=/tmp +fi +_SETUP_TMP=`mktemp "${_TMPDIR}/setup.sh.XXXXXXXXXX"` +unset _TMPDIR +if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; then + echo "Could not create temporary file: $_SETUP_TMP" + return 1 +fi +CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ ${CATKIN_SETUP_UTIL_ARGS:-} >> "$_SETUP_TMP" +_RC=$? +if [ $_RC -ne 0 ]; then + if [ $_RC -eq 2 ]; then + echo "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?" + else + echo "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC" + fi + unset _RC + unset _SETUP_UTIL + rm -f "$_SETUP_TMP" + unset _SETUP_TMP + return 1 +fi +unset _RC +unset _SETUP_UTIL +. "$_SETUP_TMP" +rm -f "$_SETUP_TMP" +unset _SETUP_TMP + +# source all environment hooks +_i=0 +while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; do + eval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_i + unset _CATKIN_ENVIRONMENT_HOOKS_$_i + eval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE + unset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE + # set workspace for environment hook + CATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace + . "$_envfile" + unset CATKIN_ENV_HOOK_WORKSPACE + _i=$((_i + 1)) +done +unset _i + +unset _CATKIN_ENVIRONMENT_HOOKS_COUNT diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/setup.zsh b/GPU_version/vio/cmake-build-debug/atomic_configure/setup.zsh new file mode 100644 index 0000000..9f780b7 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/atomic_configure/setup.zsh @@ -0,0 +1,8 @@ +#!/usr/bin/env zsh +# generated from catkin/cmake/templates/setup.zsh.in + +CATKIN_SHELL=zsh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) +emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh"' diff --git a/GPU_version/vio/cmake-build-debug/catkin/catkin_generated/version/package.cmake b/GPU_version/vio/cmake-build-debug/catkin/catkin_generated/version/package.cmake new file mode 100644 index 0000000..b3278c8 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin/catkin_generated/version/package.cmake @@ -0,0 +1,24 @@ +set(_CATKIN_CURRENT_PACKAGE "catkin") +set(catkin_VERSION "0.7.28") +set(catkin_MAINTAINER "Dirk Thomas ") +set(catkin_PACKAGE_FORMAT "3") +set(catkin_BUILD_DEPENDS "python-argparse" "python-catkin-pkg" "python3-catkin-pkg" "python-empy" "python3-empy") +set(catkin_BUILD_DEPENDS_python-catkin-pkg_VERSION_GT "0.4.3") +set(catkin_BUILD_DEPENDS_python3-catkin-pkg_VERSION_GT "0.4.3") +set(catkin_BUILD_EXPORT_DEPENDS "google-mock" "gtest" "python-nose" "python3-nose" "python-argparse" "python-catkin-pkg" "python3-catkin-pkg" "python-empy" "python3-empy") +set(catkin_BUILD_EXPORT_DEPENDS_python-catkin-pkg_VERSION_GT "0.4.3") +set(catkin_BUILD_EXPORT_DEPENDS_python3-catkin-pkg_VERSION_GT "0.4.3") +set(catkin_BUILDTOOL_DEPENDS "cmake" "python-setuptools" "python3-setuptools") +set(catkin_BUILDTOOL_EXPORT_DEPENDS "cmake" "python3-setuptools") +set(catkin_EXEC_DEPENDS "python-argparse" "python-catkin-pkg" "python3-catkin-pkg" "python-empy" "python3-empy") +set(catkin_EXEC_DEPENDS_python-catkin-pkg_VERSION_GT "0.4.3") +set(catkin_EXEC_DEPENDS_python3-catkin-pkg_VERSION_GT "0.4.3") +set(catkin_RUN_DEPENDS "python-argparse" "python-catkin-pkg" "python3-catkin-pkg" "python-empy" "python3-empy" "google-mock" "gtest" "python-nose" "python3-nose") +set(catkin_RUN_DEPENDS_python-catkin-pkg_VERSION_GT "0.4.3") +set(catkin_RUN_DEPENDS_python3-catkin-pkg_VERSION_GT "0.4.3") +set(catkin_TEST_DEPENDS "python-mock" "python3-mock" "python-nose" "python3-nose") +set(catkin_DOC_DEPENDS ) +set(catkin_URL_WEBSITE "http://wiki.ros.org/catkin") +set(catkin_URL_BUGTRACKER "https://github.com/ros/catkin/issues") +set(catkin_URL_REPOSITORY "https://github.com/ros/catkin") +set(catkin_DEPRECATED "") \ No newline at end of file diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/env_cached.sh b/GPU_version/vio/cmake-build-debug/catkin_generated/env_cached.sh new file mode 100755 index 0000000..d6be91d --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/env_cached.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/templates/env.sh.in + +if [ $# -eq 0 ] ; then + /bin/echo "Usage: env.sh COMMANDS" + /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." + exit 1 +fi + +# ensure to not use different shell type which was set before +CATKIN_SHELL=sh + +# source setup_cached.sh from same directory as this file +_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup_cached.sh" +exec "$@" diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/generate_cached_setup.py b/GPU_version/vio/cmake-build-debug/catkin_generated/generate_cached_setup.py new file mode 100644 index 0000000..b1f2d17 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/generate_cached_setup.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function + +import os +import stat +import sys + +# find the import for catkin's python package - either from source space or from an installed underlay +if os.path.exists(os.path.join('/opt/ros/melodic/share/catkin/cmake', 'catkinConfig.cmake.in')): + sys.path.insert(0, os.path.join('/opt/ros/melodic/share/catkin/cmake', '..', 'python')) +try: + from catkin.environment_cache import generate_environment_script +except ImportError: + # search for catkin package in all workspaces and prepend to path + for workspace in '/opt/ros/melodic'.split(';'): + python_path = os.path.join(workspace, 'lib/python2.7/dist-packages') + if os.path.isdir(os.path.join(python_path, 'catkin')): + sys.path.insert(0, python_path) + break + from catkin.environment_cache import generate_environment_script + +code = generate_environment_script('/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel/env.sh') + +output_filename = '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/catkin_generated/setup_cached.sh' +with open(output_filename, 'w') as f: + # print('Generate script for cached setup "%s"' % output_filename) + f.write('\n'.join(code)) + +mode = os.stat(output_filename).st_mode +os.chmod(output_filename, mode | stat.S_IXUSR) diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/.rosinstall b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/.rosinstall new file mode 100644 index 0000000..6fb13af --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/.rosinstall @@ -0,0 +1,2 @@ +- setup-file: + local-name: /usr/local/setup.sh diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/_setup_util.py b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/_setup_util.py new file mode 100755 index 0000000..760f26f --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/_setup_util.py @@ -0,0 +1,304 @@ +#!/usr/bin/python2 +# -*- coding: utf-8 -*- + +# Software License Agreement (BSD License) +# +# Copyright (c) 2012, Willow Garage, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Willow Garage, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +"""This file generates shell code for the setup.SHELL scripts to set environment variables.""" + +from __future__ import print_function + +import argparse +import copy +import errno +import os +import platform +import sys + +CATKIN_MARKER_FILE = '.catkin' + +system = platform.system() +IS_DARWIN = (system == 'Darwin') +IS_WINDOWS = (system == 'Windows') + +PATH_TO_ADD_SUFFIX = ['bin'] +if IS_WINDOWS: + # while catkin recommends putting dll's into bin, 3rd party packages often put dll's into lib + # since Windows finds dll's via the PATH variable, prepend it with path to lib + PATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'x86_64-linux-gnu')]]) + +# subfolder of workspace prepended to CMAKE_PREFIX_PATH +ENV_VAR_SUBFOLDERS = { + 'CMAKE_PREFIX_PATH': '', + 'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'x86_64-linux-gnu')], + 'PATH': PATH_TO_ADD_SUFFIX, + 'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'x86_64-linux-gnu', 'pkgconfig')], + 'PYTHONPATH': 'lib/python2.7/dist-packages', +} + + +def rollback_env_variables(environ, env_var_subfolders): + """ + Generate shell code to reset environment variables. + + by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH. + This does not cover modifications performed by environment hooks. + """ + lines = [] + unmodified_environ = copy.copy(environ) + for key in sorted(env_var_subfolders.keys()): + subfolders = env_var_subfolders[key] + if not isinstance(subfolders, list): + subfolders = [subfolders] + value = _rollback_env_variable(unmodified_environ, key, subfolders) + if value is not None: + environ[key] = value + lines.append(assignment(key, value)) + if lines: + lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH')) + return lines + + +def _rollback_env_variable(environ, name, subfolders): + """ + For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder. + + :param subfolders: list of str '' or subfoldername that may start with '/' + :returns: the updated value of the environment variable. + """ + value = environ[name] if name in environ else '' + env_paths = [path for path in value.split(os.pathsep) if path] + value_modified = False + for subfolder in subfolders: + if subfolder: + if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)): + subfolder = subfolder[1:] + if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)): + subfolder = subfolder[:-1] + for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True): + path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path + path_to_remove = None + for env_path in env_paths: + env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path + if env_path_clean == path_to_find: + path_to_remove = env_path + break + if path_to_remove: + env_paths.remove(path_to_remove) + value_modified = True + new_value = os.pathsep.join(env_paths) + return new_value if value_modified else None + + +def _get_workspaces(environ, include_fuerte=False, include_non_existing=False): + """ + Based on CMAKE_PREFIX_PATH return all catkin workspaces. + + :param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool`` + """ + # get all cmake prefix paths + env_name = 'CMAKE_PREFIX_PATH' + value = environ[env_name] if env_name in environ else '' + paths = [path for path in value.split(os.pathsep) if path] + # remove non-workspace paths + workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))] + return workspaces + + +def prepend_env_variables(environ, env_var_subfolders, workspaces): + """Generate shell code to prepend environment variables for the all workspaces.""" + lines = [] + lines.append(comment('prepend folders of workspaces to environment variables')) + + paths = [path for path in workspaces.split(os.pathsep) if path] + + prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '') + lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix)) + + for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'): + subfolder = env_var_subfolders[key] + prefix = _prefix_env_variable(environ, key, paths, subfolder) + lines.append(prepend(environ, key, prefix)) + return lines + + +def _prefix_env_variable(environ, name, paths, subfolders): + """ + Return the prefix to prepend to the environment variable NAME. + + Adding any path in NEW_PATHS_STR without creating duplicate or empty items. + """ + value = environ[name] if name in environ else '' + environ_paths = [path for path in value.split(os.pathsep) if path] + checked_paths = [] + for path in paths: + if not isinstance(subfolders, list): + subfolders = [subfolders] + for subfolder in subfolders: + path_tmp = path + if subfolder: + path_tmp = os.path.join(path_tmp, subfolder) + # skip nonexistent paths + if not os.path.exists(path_tmp): + continue + # exclude any path already in env and any path we already added + if path_tmp not in environ_paths and path_tmp not in checked_paths: + checked_paths.append(path_tmp) + prefix_str = os.pathsep.join(checked_paths) + if prefix_str != '' and environ_paths: + prefix_str += os.pathsep + return prefix_str + + +def assignment(key, value): + if not IS_WINDOWS: + return 'export %s="%s"' % (key, value) + else: + return 'set %s=%s' % (key, value) + + +def comment(msg): + if not IS_WINDOWS: + return '# %s' % msg + else: + return 'REM %s' % msg + + +def prepend(environ, key, prefix): + if key not in environ or not environ[key]: + return assignment(key, prefix) + if not IS_WINDOWS: + return 'export %s="%s$%s"' % (key, prefix, key) + else: + return 'set %s=%s%%%s%%' % (key, prefix, key) + + +def find_env_hooks(environ, cmake_prefix_path): + """Generate shell code with found environment hooks for the all workspaces.""" + lines = [] + lines.append(comment('found environment hooks in workspaces')) + + generic_env_hooks = [] + generic_env_hooks_workspace = [] + specific_env_hooks = [] + specific_env_hooks_workspace = [] + generic_env_hooks_by_filename = {} + specific_env_hooks_by_filename = {} + generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh' + specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None + # remove non-workspace paths + workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))] + for workspace in reversed(workspaces): + env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d') + if os.path.isdir(env_hook_dir): + for filename in sorted(os.listdir(env_hook_dir)): + if filename.endswith('.%s' % generic_env_hook_ext): + # remove previous env hook with same name if present + if filename in generic_env_hooks_by_filename: + i = generic_env_hooks.index(generic_env_hooks_by_filename[filename]) + generic_env_hooks.pop(i) + generic_env_hooks_workspace.pop(i) + # append env hook + generic_env_hooks.append(os.path.join(env_hook_dir, filename)) + generic_env_hooks_workspace.append(workspace) + generic_env_hooks_by_filename[filename] = generic_env_hooks[-1] + elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext): + # remove previous env hook with same name if present + if filename in specific_env_hooks_by_filename: + i = specific_env_hooks.index(specific_env_hooks_by_filename[filename]) + specific_env_hooks.pop(i) + specific_env_hooks_workspace.pop(i) + # append env hook + specific_env_hooks.append(os.path.join(env_hook_dir, filename)) + specific_env_hooks_workspace.append(workspace) + specific_env_hooks_by_filename[filename] = specific_env_hooks[-1] + env_hooks = generic_env_hooks + specific_env_hooks + env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace + count = len(env_hooks) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count)) + for i in range(count): + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i])) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i])) + return lines + + +def _parse_arguments(args=None): + parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.') + parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context') + parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment') + return parser.parse_known_args(args=args)[0] + + +if __name__ == '__main__': + try: + try: + args = _parse_arguments() + except Exception as e: + print(e, file=sys.stderr) + sys.exit(1) + + if not args.local: + # environment at generation time + CMAKE_PREFIX_PATH = '/opt/ros/melodic'.split(';') + else: + # don't consider any other prefix path than this one + CMAKE_PREFIX_PATH = [] + # prepend current workspace if not already part of CPP + base_path = os.path.dirname(__file__) + # CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent + # base_path on Windows contains backward slashes, need to be converted to forward slashes before comparison + if os.path.sep != '/': + base_path = base_path.replace(os.path.sep, '/') + + if base_path not in CMAKE_PREFIX_PATH: + CMAKE_PREFIX_PATH.insert(0, base_path) + CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH) + + environ = dict(os.environ) + lines = [] + if not args.extend: + lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS) + lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH) + lines += find_env_hooks(environ, CMAKE_PREFIX_PATH) + print('\n'.join(lines)) + + # need to explicitly flush the output + sys.stdout.flush() + except IOError as e: + # and catch potential "broken pipe" if stdout is not writable + # which can happen when piping the output to a file but the disk is full + if e.errno == errno.EPIPE: + print(e, file=sys.stderr) + sys.exit(2) + raise + + sys.exit(0) diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/env.sh b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/env.sh new file mode 100755 index 0000000..8aa9d24 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/env.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/templates/env.sh.in + +if [ $# -eq 0 ] ; then + /bin/echo "Usage: env.sh COMMANDS" + /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." + exit 1 +fi + +# ensure to not use different shell type which was set before +CATKIN_SHELL=sh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" +exec "$@" diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.bash b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.bash new file mode 100644 index 0000000..7da0d97 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# generated from catkin/cmake/templates/local_setup.bash.in + +CATKIN_SHELL=bash + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" --extend --local diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.sh b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.sh new file mode 100644 index 0000000..f021098 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/template/local_setup.sh.in + +# since this file is sourced either use the provided _CATKIN_SETUP_DIR +# or fall back to the destination set at configure time +: ${_CATKIN_SETUP_DIR:=/usr/local} +CATKIN_SETUP_UTIL_ARGS="--extend --local" +. "$_CATKIN_SETUP_DIR/setup.sh" +unset CATKIN_SETUP_UTIL_ARGS diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.zsh b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.zsh new file mode 100644 index 0000000..e692acc --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.zsh @@ -0,0 +1,8 @@ +#!/usr/bin/env zsh +# generated from catkin/cmake/templates/local_setup.zsh.in + +CATKIN_SHELL=zsh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) +emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh" --extend --local' diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.bash b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.bash new file mode 100644 index 0000000..ff47af8 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# generated from catkin/cmake/templates/setup.bash.in + +CATKIN_SHELL=bash + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.sh b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.sh new file mode 100644 index 0000000..b5a330e --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/template/setup.sh.in + +# Sets various environment variables and sources additional environment hooks. +# It tries it's best to undo changes from a previously sourced setup file before. +# Supported command line options: +# --extend: skips the undoing of changes from a previously sourced setup file +# --local: only considers this workspace but not the chained ones +# In plain sh shell which doesn't support arguments for sourced scripts you can +# set the environment variable `CATKIN_SETUP_UTIL_ARGS=--extend/--local` instead. + +# since this file is sourced either use the provided _CATKIN_SETUP_DIR +# or fall back to the destination set at configure time +: ${_CATKIN_SETUP_DIR:=/usr/local} +_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py" +unset _CATKIN_SETUP_DIR + +if [ ! -f "$_SETUP_UTIL" ]; then + echo "Missing Python script: $_SETUP_UTIL" + return 22 +fi + +# detect if running on Darwin platform +_UNAME=`uname -s` +_IS_DARWIN=0 +if [ "$_UNAME" = "Darwin" ]; then + _IS_DARWIN=1 +fi +unset _UNAME + +# make sure to export all environment variables +export CMAKE_PREFIX_PATH +if [ $_IS_DARWIN -eq 0 ]; then + export LD_LIBRARY_PATH +else + export DYLD_LIBRARY_PATH +fi +unset _IS_DARWIN +export PATH +export PKG_CONFIG_PATH +export PYTHONPATH + +# remember type of shell if not already set +if [ -z "$CATKIN_SHELL" ]; then + CATKIN_SHELL=sh +fi + +# invoke Python script to generate necessary exports of environment variables +# use TMPDIR if it exists, otherwise fall back to /tmp +if [ -d "${TMPDIR:-}" ]; then + _TMPDIR="${TMPDIR}" +else + _TMPDIR=/tmp +fi +_SETUP_TMP=`mktemp "${_TMPDIR}/setup.sh.XXXXXXXXXX"` +unset _TMPDIR +if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; then + echo "Could not create temporary file: $_SETUP_TMP" + return 1 +fi +CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ ${CATKIN_SETUP_UTIL_ARGS:-} >> "$_SETUP_TMP" +_RC=$? +if [ $_RC -ne 0 ]; then + if [ $_RC -eq 2 ]; then + echo "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?" + else + echo "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC" + fi + unset _RC + unset _SETUP_UTIL + rm -f "$_SETUP_TMP" + unset _SETUP_TMP + return 1 +fi +unset _RC +unset _SETUP_UTIL +. "$_SETUP_TMP" +rm -f "$_SETUP_TMP" +unset _SETUP_TMP + +# source all environment hooks +_i=0 +while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; do + eval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_i + unset _CATKIN_ENVIRONMENT_HOOKS_$_i + eval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE + unset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE + # set workspace for environment hook + CATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace + . "$_envfile" + unset CATKIN_ENV_HOOK_WORKSPACE + _i=$((_i + 1)) +done +unset _i + +unset _CATKIN_ENVIRONMENT_HOOKS_COUNT diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.zsh b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.zsh new file mode 100644 index 0000000..9f780b7 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.zsh @@ -0,0 +1,8 @@ +#!/usr/bin/env zsh +# generated from catkin/cmake/templates/setup.zsh.in + +CATKIN_SHELL=zsh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) +emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh"' diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/setup_cached.sh b/GPU_version/vio/cmake-build-debug/catkin_generated/setup_cached.sh new file mode 100755 index 0000000..619a325 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/setup_cached.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env sh +# generated from catkin/python/catkin/environment_cache.py + +# based on a snapshot of the environment before and after calling the setup script +# it emulates the modifications of the setup script without recurring computations + +# new environment variables + +# modified environment variables +export CMAKE_PREFIX_PATH="/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel:$CMAKE_PREFIX_PATH" +export PATH='/opt/ros/melodic/bin:/opt/cmake-3.20.0-rc4-linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' +export ROSLISP_PACKAGE_DIRECTORIES='/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel/share/common-lisp' +export ROS_PACKAGE_PATH="/root/Project/ROS/src/vio_svo/GPU_version/svo:$ROS_PACKAGE_PATH" \ No newline at end of file diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/_setup_util.py.stamp b/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/_setup_util.py.stamp new file mode 100755 index 0000000..760f26f --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/_setup_util.py.stamp @@ -0,0 +1,304 @@ +#!/usr/bin/python2 +# -*- coding: utf-8 -*- + +# Software License Agreement (BSD License) +# +# Copyright (c) 2012, Willow Garage, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Willow Garage, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +"""This file generates shell code for the setup.SHELL scripts to set environment variables.""" + +from __future__ import print_function + +import argparse +import copy +import errno +import os +import platform +import sys + +CATKIN_MARKER_FILE = '.catkin' + +system = platform.system() +IS_DARWIN = (system == 'Darwin') +IS_WINDOWS = (system == 'Windows') + +PATH_TO_ADD_SUFFIX = ['bin'] +if IS_WINDOWS: + # while catkin recommends putting dll's into bin, 3rd party packages often put dll's into lib + # since Windows finds dll's via the PATH variable, prepend it with path to lib + PATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'x86_64-linux-gnu')]]) + +# subfolder of workspace prepended to CMAKE_PREFIX_PATH +ENV_VAR_SUBFOLDERS = { + 'CMAKE_PREFIX_PATH': '', + 'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'x86_64-linux-gnu')], + 'PATH': PATH_TO_ADD_SUFFIX, + 'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'x86_64-linux-gnu', 'pkgconfig')], + 'PYTHONPATH': 'lib/python2.7/dist-packages', +} + + +def rollback_env_variables(environ, env_var_subfolders): + """ + Generate shell code to reset environment variables. + + by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH. + This does not cover modifications performed by environment hooks. + """ + lines = [] + unmodified_environ = copy.copy(environ) + for key in sorted(env_var_subfolders.keys()): + subfolders = env_var_subfolders[key] + if not isinstance(subfolders, list): + subfolders = [subfolders] + value = _rollback_env_variable(unmodified_environ, key, subfolders) + if value is not None: + environ[key] = value + lines.append(assignment(key, value)) + if lines: + lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH')) + return lines + + +def _rollback_env_variable(environ, name, subfolders): + """ + For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder. + + :param subfolders: list of str '' or subfoldername that may start with '/' + :returns: the updated value of the environment variable. + """ + value = environ[name] if name in environ else '' + env_paths = [path for path in value.split(os.pathsep) if path] + value_modified = False + for subfolder in subfolders: + if subfolder: + if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)): + subfolder = subfolder[1:] + if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)): + subfolder = subfolder[:-1] + for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True): + path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path + path_to_remove = None + for env_path in env_paths: + env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path + if env_path_clean == path_to_find: + path_to_remove = env_path + break + if path_to_remove: + env_paths.remove(path_to_remove) + value_modified = True + new_value = os.pathsep.join(env_paths) + return new_value if value_modified else None + + +def _get_workspaces(environ, include_fuerte=False, include_non_existing=False): + """ + Based on CMAKE_PREFIX_PATH return all catkin workspaces. + + :param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool`` + """ + # get all cmake prefix paths + env_name = 'CMAKE_PREFIX_PATH' + value = environ[env_name] if env_name in environ else '' + paths = [path for path in value.split(os.pathsep) if path] + # remove non-workspace paths + workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))] + return workspaces + + +def prepend_env_variables(environ, env_var_subfolders, workspaces): + """Generate shell code to prepend environment variables for the all workspaces.""" + lines = [] + lines.append(comment('prepend folders of workspaces to environment variables')) + + paths = [path for path in workspaces.split(os.pathsep) if path] + + prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '') + lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix)) + + for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'): + subfolder = env_var_subfolders[key] + prefix = _prefix_env_variable(environ, key, paths, subfolder) + lines.append(prepend(environ, key, prefix)) + return lines + + +def _prefix_env_variable(environ, name, paths, subfolders): + """ + Return the prefix to prepend to the environment variable NAME. + + Adding any path in NEW_PATHS_STR without creating duplicate or empty items. + """ + value = environ[name] if name in environ else '' + environ_paths = [path for path in value.split(os.pathsep) if path] + checked_paths = [] + for path in paths: + if not isinstance(subfolders, list): + subfolders = [subfolders] + for subfolder in subfolders: + path_tmp = path + if subfolder: + path_tmp = os.path.join(path_tmp, subfolder) + # skip nonexistent paths + if not os.path.exists(path_tmp): + continue + # exclude any path already in env and any path we already added + if path_tmp not in environ_paths and path_tmp not in checked_paths: + checked_paths.append(path_tmp) + prefix_str = os.pathsep.join(checked_paths) + if prefix_str != '' and environ_paths: + prefix_str += os.pathsep + return prefix_str + + +def assignment(key, value): + if not IS_WINDOWS: + return 'export %s="%s"' % (key, value) + else: + return 'set %s=%s' % (key, value) + + +def comment(msg): + if not IS_WINDOWS: + return '# %s' % msg + else: + return 'REM %s' % msg + + +def prepend(environ, key, prefix): + if key not in environ or not environ[key]: + return assignment(key, prefix) + if not IS_WINDOWS: + return 'export %s="%s$%s"' % (key, prefix, key) + else: + return 'set %s=%s%%%s%%' % (key, prefix, key) + + +def find_env_hooks(environ, cmake_prefix_path): + """Generate shell code with found environment hooks for the all workspaces.""" + lines = [] + lines.append(comment('found environment hooks in workspaces')) + + generic_env_hooks = [] + generic_env_hooks_workspace = [] + specific_env_hooks = [] + specific_env_hooks_workspace = [] + generic_env_hooks_by_filename = {} + specific_env_hooks_by_filename = {} + generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh' + specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None + # remove non-workspace paths + workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))] + for workspace in reversed(workspaces): + env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d') + if os.path.isdir(env_hook_dir): + for filename in sorted(os.listdir(env_hook_dir)): + if filename.endswith('.%s' % generic_env_hook_ext): + # remove previous env hook with same name if present + if filename in generic_env_hooks_by_filename: + i = generic_env_hooks.index(generic_env_hooks_by_filename[filename]) + generic_env_hooks.pop(i) + generic_env_hooks_workspace.pop(i) + # append env hook + generic_env_hooks.append(os.path.join(env_hook_dir, filename)) + generic_env_hooks_workspace.append(workspace) + generic_env_hooks_by_filename[filename] = generic_env_hooks[-1] + elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext): + # remove previous env hook with same name if present + if filename in specific_env_hooks_by_filename: + i = specific_env_hooks.index(specific_env_hooks_by_filename[filename]) + specific_env_hooks.pop(i) + specific_env_hooks_workspace.pop(i) + # append env hook + specific_env_hooks.append(os.path.join(env_hook_dir, filename)) + specific_env_hooks_workspace.append(workspace) + specific_env_hooks_by_filename[filename] = specific_env_hooks[-1] + env_hooks = generic_env_hooks + specific_env_hooks + env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace + count = len(env_hooks) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count)) + for i in range(count): + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i])) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i])) + return lines + + +def _parse_arguments(args=None): + parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.') + parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context') + parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment') + return parser.parse_known_args(args=args)[0] + + +if __name__ == '__main__': + try: + try: + args = _parse_arguments() + except Exception as e: + print(e, file=sys.stderr) + sys.exit(1) + + if not args.local: + # environment at generation time + CMAKE_PREFIX_PATH = '/opt/ros/melodic'.split(';') + else: + # don't consider any other prefix path than this one + CMAKE_PREFIX_PATH = [] + # prepend current workspace if not already part of CPP + base_path = os.path.dirname(__file__) + # CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent + # base_path on Windows contains backward slashes, need to be converted to forward slashes before comparison + if os.path.sep != '/': + base_path = base_path.replace(os.path.sep, '/') + + if base_path not in CMAKE_PREFIX_PATH: + CMAKE_PREFIX_PATH.insert(0, base_path) + CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH) + + environ = dict(os.environ) + lines = [] + if not args.extend: + lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS) + lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH) + lines += find_env_hooks(environ, CMAKE_PREFIX_PATH) + print('\n'.join(lines)) + + # need to explicitly flush the output + sys.stdout.flush() + except IOError as e: + # and catch potential "broken pipe" if stdout is not writable + # which can happen when piping the output to a file but the disk is full + if e.errno == errno.EPIPE: + print(e, file=sys.stderr) + sys.exit(2) + raise + + sys.exit(0) diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/interrogate_setup_dot_py.py.stamp b/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/interrogate_setup_dot_py.py.stamp new file mode 100644 index 0000000..5e25fbf --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/interrogate_setup_dot_py.py.stamp @@ -0,0 +1,255 @@ +# Software License Agreement (BSD License) +# +# Copyright (c) 2012, Willow Garage, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Willow Garage, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from __future__ import print_function + +import os +import runpy +import sys +from argparse import ArgumentParser + +setup_modules = [] + +try: + import distutils.core + setup_modules.append(distutils.core) +except ImportError: + pass + +try: + import setuptools + setup_modules.append(setuptools) +except ImportError: + pass + +assert setup_modules, 'Must have distutils or setuptools installed' + + +def _get_locations(pkgs, package_dir): + """ + Based on setuptools logic and the package_dir dict, builds a dict of location roots for each pkg in pkgs. + + See http://docs.python.org/distutils/setupscript.html + + :returns: a dict {pkgname: root} for each pkgname in pkgs (and each of their parents) + """ + # package_dir contains a dict {package_name: relativepath} + # Example {'': 'src', 'foo': 'lib', 'bar': 'lib2'} + # + # '' means where to look for any package unless a parent package + # is listed so package bar.pot is expected at lib2/bar/pot, + # whereas package sup.dee is expected at src/sup/dee + # + # if package_dir does not state anything about a package, + # setuptool expects the package folder to be in the root of the + # project + locations = {} + allprefix = package_dir.get('', '') + for pkg in pkgs: + parent_location = None + splits = pkg.split('.') + # we iterate over compound name from parent to child + # so once we found parent, children just append to their parent + for key_len in range(len(splits)): + key = '.'.join(splits[:key_len + 1]) + if key not in locations: + if key in package_dir: + locations[key] = package_dir[key] + elif parent_location is not None: + locations[key] = os.path.join(parent_location, splits[key_len]) + else: + locations[key] = os.path.join(allprefix, key) + parent_location = locations[key] + return locations + + +def generate_cmake_file(package_name, version, scripts, package_dir, pkgs, modules, setup_module=None): + """ + Generate lines to add to a cmake file which will set variables. + + :param version: str, format 'int.int.int' + :param scripts: [list of str]: relative paths to scripts + :param package_dir: {modulename: path} + :param pkgs: [list of str] python_packages declared in catkin package + :param modules: [list of str] python modules + :param setup_module: str, setuptools or distutils + """ + prefix = '%s_SETUP_PY' % package_name + result = [] + if setup_module: + result.append(r'set(%s_SETUP_MODULE "%s")' % (prefix, setup_module)) + result.append(r'set(%s_VERSION "%s")' % (prefix, version)) + result.append(r'set(%s_SCRIPTS "%s")' % (prefix, ';'.join(scripts))) + + # Remove packages with '.' separators. + # + # setuptools allows specifying submodules in other folders than + # their parent + # + # The symlink approach of catkin does not work with such submodules. + # In the common case, this does not matter as the submodule is + # within the containing module. We verify this assumption, and if + # it passes, we remove submodule packages. + locations = _get_locations(pkgs, package_dir) + for pkgname, location in locations.items(): + if '.' not in pkgname: + continue + splits = pkgname.split('.') + # hack: ignore write-combining setup.py files for msg and srv files + if splits[1] in ['msg', 'srv']: + continue + # check every child has the same root folder as its parent + root_name = splits[0] + root_location = location + for _ in range(len(splits) - 1): + root_location = os.path.dirname(root_location) + if root_location != locations[root_name]: + raise RuntimeError( + 'catkin_export_python does not support setup.py files that combine across multiple directories: %s in %s, %s in %s' % (pkgname, location, root_name, locations[root_name])) + + # If checks pass, remove all submodules + pkgs = [p for p in pkgs if '.' not in p] + + resolved_pkgs = [] + for pkg in pkgs: + resolved_pkgs += [locations[pkg]] + + result.append(r'set(%s_PACKAGES "%s")' % (prefix, ';'.join(pkgs))) + result.append(r'set(%s_PACKAGE_DIRS "%s")' % (prefix, ';'.join(resolved_pkgs).replace('\\', '/'))) + + # skip modules which collide with package names + filtered_modules = [] + for modname in modules: + splits = modname.split('.') + # check all parents too + equals_package = [('.'.join(splits[:-i]) in locations) for i in range(len(splits))] + if any(equals_package): + continue + filtered_modules.append(modname) + module_locations = _get_locations(filtered_modules, package_dir) + + result.append(r'set(%s_MODULES "%s")' % (prefix, ';'.join(['%s.py' % m.replace('.', '/') for m in filtered_modules]))) + result.append(r'set(%s_MODULE_DIRS "%s")' % (prefix, ';'.join([module_locations[m] for m in filtered_modules]).replace('\\', '/'))) + + return result + + +def _create_mock_setup_function(setup_module, package_name, outfile): + """ + Create a function to call instead of distutils.core.setup or setuptools.setup. + + It just captures some args and writes them into a file that can be used from cmake. + + :param package_name: name of the package + :param outfile: filename that cmake will use afterwards + :returns: a function to replace disutils.core.setup and setuptools.setup + """ + + def setup(*args, **kwargs): + """Check kwargs and write a scriptfile.""" + if 'version' not in kwargs: + sys.stderr.write("\n*** Unable to find 'version' in setup.py of %s\n" % package_name) + raise RuntimeError('version not found in setup.py') + version = kwargs['version'] + package_dir = kwargs.get('package_dir', {}) + + pkgs = kwargs.get('packages', []) + scripts = kwargs.get('scripts', []) + modules = kwargs.get('py_modules', []) + + unsupported_args = [ + 'entry_points', + 'exclude_package_data', + 'ext_modules ', + 'ext_package', + 'include_package_data', + 'namespace_packages', + 'setup_requires', + 'use_2to3', + 'zip_safe'] + used_unsupported_args = [arg for arg in unsupported_args if arg in kwargs] + if used_unsupported_args: + sys.stderr.write('*** Arguments %s to setup() not supported in catkin devel space in setup.py of %s\n' % (used_unsupported_args, package_name)) + + result = generate_cmake_file(package_name=package_name, + version=version, + scripts=scripts, + package_dir=package_dir, + pkgs=pkgs, + modules=modules, + setup_module=setup_module) + with open(outfile, 'w') as out: + out.write('\n'.join(result)) + + return setup + + +def main(): + """Script main, parses arguments and invokes Dummy.setup indirectly.""" + parser = ArgumentParser(description='Utility to read setup.py values from cmake macros. Creates a file with CMake set commands setting variables.') + parser.add_argument('package_name', help='Name of catkin package') + parser.add_argument('setupfile_path', help='Full path to setup.py') + parser.add_argument('outfile', help='Where to write result to') + + args = parser.parse_args() + + # print("%s" % sys.argv) + # PACKAGE_NAME = sys.argv[1] + # OUTFILE = sys.argv[3] + # print("Interrogating setup.py for package %s into %s " % (PACKAGE_NAME, OUTFILE), + # file=sys.stderr) + + # print("executing %s" % args.setupfile_path) + + # be sure you're in the directory containing + # setup.py so the sys.path manipulation works, + # so the import of __version__ works + os.chdir(os.path.dirname(os.path.abspath(args.setupfile_path))) + + # patch setup() function of distutils and setuptools for the + # context of evaluating setup.py + backup_modules = {} + try: + + for module in setup_modules: + backup_modules[id(module)] = module.setup + module.setup = _create_mock_setup_function( + setup_module=module.__name__, package_name=args.package_name, outfile=args.outfile) + + runpy.run_path(args.setupfile_path) + finally: + for module in setup_modules: + module.setup = backup_modules[id(module)] + + +if __name__ == '__main__': + main() diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/package.xml.stamp b/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/package.xml.stamp new file mode 100644 index 0000000..bfd7934 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/package.xml.stamp @@ -0,0 +1,48 @@ + + + + catkin + 0.7.28 + Low-level build system macros and infrastructure for ROS. + Dirk Thomas + BSD + + http://wiki.ros.org/catkin + https://github.com/ros/catkin/issues + https://github.com/ros/catkin + + Troy Straszheim + Morten Kjaergaard + Brian Gerkey + Dirk Thomas + + python-argparse + python-catkin-pkg + python3-catkin-pkg + python-empy + python3-empy + + cmake + python-setuptools + python3-setuptools + + cmake + python3-setuptools + + google-mock + gtest + python-nose + python3-nose + + python-mock + python3-mock + python-nose + python3-nose + + + + + + diff --git a/GPU_version/vio/cmake-build-debug/devel/.catkin b/GPU_version/vio/cmake-build-debug/devel/.catkin new file mode 100644 index 0000000..749f40c --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/devel/.catkin @@ -0,0 +1 @@ +/root/Project/ROS/src/vio_svo/GPU_version/svo \ No newline at end of file diff --git a/GPU_version/vio/cmake-build-debug/devel/.rosinstall b/GPU_version/vio/cmake-build-debug/devel/.rosinstall new file mode 100644 index 0000000..b61ff9e --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/devel/.rosinstall @@ -0,0 +1,2 @@ +- setup-file: + local-name: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel/setup.sh diff --git a/GPU_version/vio/cmake-build-debug/devel/_setup_util.py b/GPU_version/vio/cmake-build-debug/devel/_setup_util.py new file mode 100755 index 0000000..760f26f --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/devel/_setup_util.py @@ -0,0 +1,304 @@ +#!/usr/bin/python2 +# -*- coding: utf-8 -*- + +# Software License Agreement (BSD License) +# +# Copyright (c) 2012, Willow Garage, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Willow Garage, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +"""This file generates shell code for the setup.SHELL scripts to set environment variables.""" + +from __future__ import print_function + +import argparse +import copy +import errno +import os +import platform +import sys + +CATKIN_MARKER_FILE = '.catkin' + +system = platform.system() +IS_DARWIN = (system == 'Darwin') +IS_WINDOWS = (system == 'Windows') + +PATH_TO_ADD_SUFFIX = ['bin'] +if IS_WINDOWS: + # while catkin recommends putting dll's into bin, 3rd party packages often put dll's into lib + # since Windows finds dll's via the PATH variable, prepend it with path to lib + PATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'x86_64-linux-gnu')]]) + +# subfolder of workspace prepended to CMAKE_PREFIX_PATH +ENV_VAR_SUBFOLDERS = { + 'CMAKE_PREFIX_PATH': '', + 'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'x86_64-linux-gnu')], + 'PATH': PATH_TO_ADD_SUFFIX, + 'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'x86_64-linux-gnu', 'pkgconfig')], + 'PYTHONPATH': 'lib/python2.7/dist-packages', +} + + +def rollback_env_variables(environ, env_var_subfolders): + """ + Generate shell code to reset environment variables. + + by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH. + This does not cover modifications performed by environment hooks. + """ + lines = [] + unmodified_environ = copy.copy(environ) + for key in sorted(env_var_subfolders.keys()): + subfolders = env_var_subfolders[key] + if not isinstance(subfolders, list): + subfolders = [subfolders] + value = _rollback_env_variable(unmodified_environ, key, subfolders) + if value is not None: + environ[key] = value + lines.append(assignment(key, value)) + if lines: + lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH')) + return lines + + +def _rollback_env_variable(environ, name, subfolders): + """ + For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder. + + :param subfolders: list of str '' or subfoldername that may start with '/' + :returns: the updated value of the environment variable. + """ + value = environ[name] if name in environ else '' + env_paths = [path for path in value.split(os.pathsep) if path] + value_modified = False + for subfolder in subfolders: + if subfolder: + if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)): + subfolder = subfolder[1:] + if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)): + subfolder = subfolder[:-1] + for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True): + path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path + path_to_remove = None + for env_path in env_paths: + env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path + if env_path_clean == path_to_find: + path_to_remove = env_path + break + if path_to_remove: + env_paths.remove(path_to_remove) + value_modified = True + new_value = os.pathsep.join(env_paths) + return new_value if value_modified else None + + +def _get_workspaces(environ, include_fuerte=False, include_non_existing=False): + """ + Based on CMAKE_PREFIX_PATH return all catkin workspaces. + + :param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool`` + """ + # get all cmake prefix paths + env_name = 'CMAKE_PREFIX_PATH' + value = environ[env_name] if env_name in environ else '' + paths = [path for path in value.split(os.pathsep) if path] + # remove non-workspace paths + workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))] + return workspaces + + +def prepend_env_variables(environ, env_var_subfolders, workspaces): + """Generate shell code to prepend environment variables for the all workspaces.""" + lines = [] + lines.append(comment('prepend folders of workspaces to environment variables')) + + paths = [path for path in workspaces.split(os.pathsep) if path] + + prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '') + lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix)) + + for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'): + subfolder = env_var_subfolders[key] + prefix = _prefix_env_variable(environ, key, paths, subfolder) + lines.append(prepend(environ, key, prefix)) + return lines + + +def _prefix_env_variable(environ, name, paths, subfolders): + """ + Return the prefix to prepend to the environment variable NAME. + + Adding any path in NEW_PATHS_STR without creating duplicate or empty items. + """ + value = environ[name] if name in environ else '' + environ_paths = [path for path in value.split(os.pathsep) if path] + checked_paths = [] + for path in paths: + if not isinstance(subfolders, list): + subfolders = [subfolders] + for subfolder in subfolders: + path_tmp = path + if subfolder: + path_tmp = os.path.join(path_tmp, subfolder) + # skip nonexistent paths + if not os.path.exists(path_tmp): + continue + # exclude any path already in env and any path we already added + if path_tmp not in environ_paths and path_tmp not in checked_paths: + checked_paths.append(path_tmp) + prefix_str = os.pathsep.join(checked_paths) + if prefix_str != '' and environ_paths: + prefix_str += os.pathsep + return prefix_str + + +def assignment(key, value): + if not IS_WINDOWS: + return 'export %s="%s"' % (key, value) + else: + return 'set %s=%s' % (key, value) + + +def comment(msg): + if not IS_WINDOWS: + return '# %s' % msg + else: + return 'REM %s' % msg + + +def prepend(environ, key, prefix): + if key not in environ or not environ[key]: + return assignment(key, prefix) + if not IS_WINDOWS: + return 'export %s="%s$%s"' % (key, prefix, key) + else: + return 'set %s=%s%%%s%%' % (key, prefix, key) + + +def find_env_hooks(environ, cmake_prefix_path): + """Generate shell code with found environment hooks for the all workspaces.""" + lines = [] + lines.append(comment('found environment hooks in workspaces')) + + generic_env_hooks = [] + generic_env_hooks_workspace = [] + specific_env_hooks = [] + specific_env_hooks_workspace = [] + generic_env_hooks_by_filename = {} + specific_env_hooks_by_filename = {} + generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh' + specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None + # remove non-workspace paths + workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))] + for workspace in reversed(workspaces): + env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d') + if os.path.isdir(env_hook_dir): + for filename in sorted(os.listdir(env_hook_dir)): + if filename.endswith('.%s' % generic_env_hook_ext): + # remove previous env hook with same name if present + if filename in generic_env_hooks_by_filename: + i = generic_env_hooks.index(generic_env_hooks_by_filename[filename]) + generic_env_hooks.pop(i) + generic_env_hooks_workspace.pop(i) + # append env hook + generic_env_hooks.append(os.path.join(env_hook_dir, filename)) + generic_env_hooks_workspace.append(workspace) + generic_env_hooks_by_filename[filename] = generic_env_hooks[-1] + elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext): + # remove previous env hook with same name if present + if filename in specific_env_hooks_by_filename: + i = specific_env_hooks.index(specific_env_hooks_by_filename[filename]) + specific_env_hooks.pop(i) + specific_env_hooks_workspace.pop(i) + # append env hook + specific_env_hooks.append(os.path.join(env_hook_dir, filename)) + specific_env_hooks_workspace.append(workspace) + specific_env_hooks_by_filename[filename] = specific_env_hooks[-1] + env_hooks = generic_env_hooks + specific_env_hooks + env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace + count = len(env_hooks) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count)) + for i in range(count): + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i])) + lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i])) + return lines + + +def _parse_arguments(args=None): + parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.') + parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context') + parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment') + return parser.parse_known_args(args=args)[0] + + +if __name__ == '__main__': + try: + try: + args = _parse_arguments() + except Exception as e: + print(e, file=sys.stderr) + sys.exit(1) + + if not args.local: + # environment at generation time + CMAKE_PREFIX_PATH = '/opt/ros/melodic'.split(';') + else: + # don't consider any other prefix path than this one + CMAKE_PREFIX_PATH = [] + # prepend current workspace if not already part of CPP + base_path = os.path.dirname(__file__) + # CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent + # base_path on Windows contains backward slashes, need to be converted to forward slashes before comparison + if os.path.sep != '/': + base_path = base_path.replace(os.path.sep, '/') + + if base_path not in CMAKE_PREFIX_PATH: + CMAKE_PREFIX_PATH.insert(0, base_path) + CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH) + + environ = dict(os.environ) + lines = [] + if not args.extend: + lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS) + lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH) + lines += find_env_hooks(environ, CMAKE_PREFIX_PATH) + print('\n'.join(lines)) + + # need to explicitly flush the output + sys.stdout.flush() + except IOError as e: + # and catch potential "broken pipe" if stdout is not writable + # which can happen when piping the output to a file but the disk is full + if e.errno == errno.EPIPE: + print(e, file=sys.stderr) + sys.exit(2) + raise + + sys.exit(0) diff --git a/GPU_version/vio/cmake-build-debug/devel/cmake.lock b/GPU_version/vio/cmake-build-debug/devel/cmake.lock new file mode 100644 index 0000000..e69de29 diff --git a/GPU_version/vio/cmake-build-debug/devel/env.sh b/GPU_version/vio/cmake-build-debug/devel/env.sh new file mode 100755 index 0000000..8aa9d24 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/devel/env.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/templates/env.sh.in + +if [ $# -eq 0 ] ; then + /bin/echo "Usage: env.sh COMMANDS" + /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." + exit 1 +fi + +# ensure to not use different shell type which was set before +CATKIN_SHELL=sh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" +exec "$@" diff --git a/GPU_version/vio/cmake-build-debug/devel/local_setup.bash b/GPU_version/vio/cmake-build-debug/devel/local_setup.bash new file mode 100644 index 0000000..7da0d97 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/devel/local_setup.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# generated from catkin/cmake/templates/local_setup.bash.in + +CATKIN_SHELL=bash + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" --extend --local diff --git a/GPU_version/vio/cmake-build-debug/devel/local_setup.sh b/GPU_version/vio/cmake-build-debug/devel/local_setup.sh new file mode 100644 index 0000000..d29ab41 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/devel/local_setup.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/template/local_setup.sh.in + +# since this file is sourced either use the provided _CATKIN_SETUP_DIR +# or fall back to the destination set at configure time +: ${_CATKIN_SETUP_DIR:=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel} +CATKIN_SETUP_UTIL_ARGS="--extend --local" +. "$_CATKIN_SETUP_DIR/setup.sh" +unset CATKIN_SETUP_UTIL_ARGS diff --git a/GPU_version/vio/cmake-build-debug/devel/local_setup.zsh b/GPU_version/vio/cmake-build-debug/devel/local_setup.zsh new file mode 100644 index 0000000..e692acc --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/devel/local_setup.zsh @@ -0,0 +1,8 @@ +#!/usr/bin/env zsh +# generated from catkin/cmake/templates/local_setup.zsh.in + +CATKIN_SHELL=zsh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) +emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh" --extend --local' diff --git a/GPU_version/vio/cmake-build-debug/devel/setup.bash b/GPU_version/vio/cmake-build-debug/devel/setup.bash new file mode 100644 index 0000000..ff47af8 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/devel/setup.bash @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# generated from catkin/cmake/templates/setup.bash.in + +CATKIN_SHELL=bash + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) +. "$_CATKIN_SETUP_DIR/setup.sh" diff --git a/GPU_version/vio/cmake-build-debug/devel/setup.sh b/GPU_version/vio/cmake-build-debug/devel/setup.sh new file mode 100644 index 0000000..1764d84 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/devel/setup.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env sh +# generated from catkin/cmake/template/setup.sh.in + +# Sets various environment variables and sources additional environment hooks. +# It tries it's best to undo changes from a previously sourced setup file before. +# Supported command line options: +# --extend: skips the undoing of changes from a previously sourced setup file +# --local: only considers this workspace but not the chained ones +# In plain sh shell which doesn't support arguments for sourced scripts you can +# set the environment variable `CATKIN_SETUP_UTIL_ARGS=--extend/--local` instead. + +# since this file is sourced either use the provided _CATKIN_SETUP_DIR +# or fall back to the destination set at configure time +: ${_CATKIN_SETUP_DIR:=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel} +_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py" +unset _CATKIN_SETUP_DIR + +if [ ! -f "$_SETUP_UTIL" ]; then + echo "Missing Python script: $_SETUP_UTIL" + return 22 +fi + +# detect if running on Darwin platform +_UNAME=`uname -s` +_IS_DARWIN=0 +if [ "$_UNAME" = "Darwin" ]; then + _IS_DARWIN=1 +fi +unset _UNAME + +# make sure to export all environment variables +export CMAKE_PREFIX_PATH +if [ $_IS_DARWIN -eq 0 ]; then + export LD_LIBRARY_PATH +else + export DYLD_LIBRARY_PATH +fi +unset _IS_DARWIN +export PATH +export PKG_CONFIG_PATH +export PYTHONPATH + +# remember type of shell if not already set +if [ -z "$CATKIN_SHELL" ]; then + CATKIN_SHELL=sh +fi + +# invoke Python script to generate necessary exports of environment variables +# use TMPDIR if it exists, otherwise fall back to /tmp +if [ -d "${TMPDIR:-}" ]; then + _TMPDIR="${TMPDIR}" +else + _TMPDIR=/tmp +fi +_SETUP_TMP=`mktemp "${_TMPDIR}/setup.sh.XXXXXXXXXX"` +unset _TMPDIR +if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; then + echo "Could not create temporary file: $_SETUP_TMP" + return 1 +fi +CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ ${CATKIN_SETUP_UTIL_ARGS:-} >> "$_SETUP_TMP" +_RC=$? +if [ $_RC -ne 0 ]; then + if [ $_RC -eq 2 ]; then + echo "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?" + else + echo "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC" + fi + unset _RC + unset _SETUP_UTIL + rm -f "$_SETUP_TMP" + unset _SETUP_TMP + return 1 +fi +unset _RC +unset _SETUP_UTIL +. "$_SETUP_TMP" +rm -f "$_SETUP_TMP" +unset _SETUP_TMP + +# source all environment hooks +_i=0 +while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; do + eval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_i + unset _CATKIN_ENVIRONMENT_HOOKS_$_i + eval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE + unset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE + # set workspace for environment hook + CATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace + . "$_envfile" + unset CATKIN_ENV_HOOK_WORKSPACE + _i=$((_i + 1)) +done +unset _i + +unset _CATKIN_ENVIRONMENT_HOOKS_COUNT diff --git a/GPU_version/vio/cmake-build-debug/devel/setup.zsh b/GPU_version/vio/cmake-build-debug/devel/setup.zsh new file mode 100644 index 0000000..9f780b7 --- /dev/null +++ b/GPU_version/vio/cmake-build-debug/devel/setup.zsh @@ -0,0 +1,8 @@ +#!/usr/bin/env zsh +# generated from catkin/cmake/templates/setup.zsh.in + +CATKIN_SHELL=zsh + +# source setup.sh from same directory as this file +_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) +emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh"' diff --git a/GPU_version/svo/doc/.gitignore b/GPU_version/vio/doc/.gitignore similarity index 100% rename from GPU_version/svo/doc/.gitignore rename to GPU_version/vio/doc/.gitignore diff --git a/GPU_version/svo/doc/notation.ipe b/GPU_version/vio/doc/notation.ipe similarity index 100% rename from GPU_version/svo/doc/notation.ipe rename to GPU_version/vio/doc/notation.ipe diff --git a/GPU_version/svo/doc/notation.pdf b/GPU_version/vio/doc/notation.pdf similarity index 100% rename from GPU_version/svo/doc/notation.pdf rename to GPU_version/vio/doc/notation.pdf diff --git a/GPU_version/svo/doc/notation.png b/GPU_version/vio/doc/notation.png similarity index 100% rename from GPU_version/svo/doc/notation.png rename to GPU_version/vio/doc/notation.png diff --git a/GPU_version/svo/src/imu_integration.cpp b/GPU_version/vio/gtsam/imu_integration.cpp old mode 100644 new mode 100755 similarity index 94% rename from GPU_version/svo/src/imu_integration.cpp rename to GPU_version/vio/gtsam/imu_integration.cpp index f7d47a2..d2e751b --- a/GPU_version/svo/src/imu_integration.cpp +++ b/GPU_version/vio/gtsam/imu_integration.cpp @@ -2,17 +2,15 @@ // Created by gfuse on 4/9/21. // //#define NDEBUG -#include "gpu_svo/imu_integration.h" +#include "imu_integration.h" #include #include #include "gpu_svo/feature.h" #include "gpu_svo/point.h" -//#include "gpu_svo/svoVisionFactorSmall.h" #include "gpu_svo/svoVisionFactor.h" -//#include "gpu_svo/svoVisionFactorLandMark.h" #include #include -#include +#include #include #include #define debug 0 @@ -43,14 +41,12 @@ Imu_Integration::~Imu_Integration(){ bool Imu_Integration::update(double* imu){ if(syn)return false; if(imu_factor_id<1)return false; - if(abs(imu[0])<1.0)imu[0]=pow(imu[0],3);//picked up from your code - if(abs(imu[1])<1.0)imu[0]=pow(imu[1],3);//picked up from your code auto in=std::chrono::steady_clock::now(); if(std::chrono::duration(in-t_1).count()>20.0){ t_1=in; - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),0.0005); + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[2]-svo::Config::Teta_off(),0.0),0.0005); }else{ - preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),std::chrono::duration(in-t_1).count()); + preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[2]-svo::Config::Teta_off(),0.0),std::chrono::duration(in-t_1).count()); t_1=in; ++imu_n; } diff --git a/GPU_version/svo/include/gpu_svo/imu_integration.h b/GPU_version/vio/gtsam/imu_integration.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/imu_integration.h rename to GPU_version/vio/gtsam/imu_integration.h diff --git a/GPU_version/svo/include/gpu_svo/svoVisionFactor.h b/GPU_version/vio/gtsam/svoVisionFactor.h similarity index 97% rename from GPU_version/svo/include/gpu_svo/svoVisionFactor.h rename to GPU_version/vio/gtsam/svoVisionFactor.h index c81bdd5..01ad6da 100644 --- a/GPU_version/svo/include/gpu_svo/svoVisionFactor.h +++ b/GPU_version/vio/gtsam/svoVisionFactor.h @@ -10,8 +10,8 @@ #include #include #include -#include -#include +#include +#include #include namespace svo { diff --git a/GPU_version/svo/include/gpu_svo/svoVisionFactorLandMark.h b/GPU_version/vio/gtsam/svoVisionFactorLandMark.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/svoVisionFactorLandMark.h rename to GPU_version/vio/gtsam/svoVisionFactorLandMark.h diff --git a/GPU_version/svo/include/gpu_svo/svoVisionFactorSmall.h b/GPU_version/vio/gtsam/svoVisionFactorSmall.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/svoVisionFactorSmall.h rename to GPU_version/vio/gtsam/svoVisionFactorSmall.h diff --git a/GPU_version/svo/include/gpu_svo/abstract_camera.h b/GPU_version/vio/include/gpu_svo/abstract_camera.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/abstract_camera.h rename to GPU_version/vio/include/gpu_svo/abstract_camera.h diff --git a/GPU_version/svo/include/gpu_svo/aligned_mem.h b/GPU_version/vio/include/gpu_svo/aligned_mem.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/aligned_mem.h rename to GPU_version/vio/include/gpu_svo/aligned_mem.h diff --git a/GPU_version/svo/include/gpu_svo/atan_camera.h b/GPU_version/vio/include/gpu_svo/atan_camera.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/atan_camera.h rename to GPU_version/vio/include/gpu_svo/atan_camera.h diff --git a/GPU_version/svo/include/gpu_svo/bundle_adjustment.h b/GPU_version/vio/include/gpu_svo/bundle_adjustment.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/bundle_adjustment.h rename to GPU_version/vio/include/gpu_svo/bundle_adjustment.h diff --git a/GPU_version/vio/include/vio_gpu/camera_loader.h b/GPU_version/vio/include/gpu_svo/camera_loader.h similarity index 100% rename from GPU_version/vio/include/vio_gpu/camera_loader.h rename to GPU_version/vio/include/gpu_svo/camera_loader.h diff --git a/GPU_version/svo/include/gpu_svo/cl.hpp b/GPU_version/vio/include/gpu_svo/cl.hpp similarity index 100% rename from GPU_version/svo/include/gpu_svo/cl.hpp rename to GPU_version/vio/include/gpu_svo/cl.hpp diff --git a/GPU_version/svo/include/gpu_svo/cl_class.h b/GPU_version/vio/include/gpu_svo/cl_class.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/cl_class.h rename to GPU_version/vio/include/gpu_svo/cl_class.h diff --git a/GPU_version/svo/include/gpu_svo/config.h b/GPU_version/vio/include/gpu_svo/config.h similarity index 94% rename from GPU_version/svo/include/gpu_svo/config.h rename to GPU_version/vio/include/gpu_svo/config.h index 9b3c26f..f6d710d 100644 --- a/GPU_version/svo/include/gpu_svo/config.h +++ b/GPU_version/vio/include/gpu_svo/config.h @@ -134,10 +134,11 @@ public: static double& EBP() { return getInstance().ebp; } /// the noise used for projection static double& NRP() { return getInstance().nrp; } - static double& Gravity() { return getInstance().gravity; } - static double& X_off() { return getInstance().acc_x_off; } - static double& Y_off() { return getInstance().acc_y_off; } - static double& Teta_off() { return getInstance().gyr_z_off; } + static double& Svo_Ekf() { return getInstance().svo_ekf; } + static double& X_off() { return getInstance().acc_x_off; } + static double& Y_off() { return getInstance().acc_y_off; } + static double& Teta_off() { return getInstance().gyr_z_off; } + static double& Cmd_Cov() { return getInstance().cmd_cov; } private: @@ -173,7 +174,7 @@ private: size_t max_fts; size_t quality_min_fts; int quality_max_drop_fts; - double nrp,ebp,gbc,abc,iuc,ACC_noise,GYO_noise,gravity,acc_x_off,acc_y_off,gyr_z_off; + double nrp,ebp,gbc,abc,iuc,ACC_noise,GYO_noise,svo_ekf,acc_x_off,acc_y_off,gyr_z_off,cmd_cov; }; } // namespace svo diff --git a/GPU_version/svo/include/gpu_svo/depth_filter.h b/GPU_version/vio/include/gpu_svo/depth_filter.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/depth_filter.h rename to GPU_version/vio/include/gpu_svo/depth_filter.h diff --git a/GPU_version/svo/include/gpu_svo/feature.h b/GPU_version/vio/include/gpu_svo/feature.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/feature.h rename to GPU_version/vio/include/gpu_svo/feature.h diff --git a/GPU_version/svo/include/gpu_svo/feature_alignment.h b/GPU_version/vio/include/gpu_svo/feature_alignment.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/feature_alignment.h rename to GPU_version/vio/include/gpu_svo/feature_alignment.h diff --git a/GPU_version/svo/include/gpu_svo/feature_detection.h b/GPU_version/vio/include/gpu_svo/feature_detection.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/feature_detection.h rename to GPU_version/vio/include/gpu_svo/feature_detection.h diff --git a/GPU_version/svo/include/gpu_svo/for_it.hpp b/GPU_version/vio/include/gpu_svo/for_it.hpp similarity index 100% rename from GPU_version/svo/include/gpu_svo/for_it.hpp rename to GPU_version/vio/include/gpu_svo/for_it.hpp diff --git a/GPU_version/svo/include/gpu_svo/frame.h b/GPU_version/vio/include/gpu_svo/frame.h similarity index 72% rename from GPU_version/svo/include/gpu_svo/frame.h rename to GPU_version/vio/include/gpu_svo/frame.h index 4580be2..e02f1c6 100644 --- a/GPU_version/svo/include/gpu_svo/frame.h +++ b/GPU_version/vio/include/gpu_svo/frame.h @@ -48,7 +48,7 @@ public: double timestamp_; //!< Timestamp of when the image was recorded. vk::AbstractCamera* cam_; //!< Camera model. SE2_5 T_f_w_; //!< Transform (f)rame from (w)orld. - Matrix Cov_; //!< Covariance. + Matrix Cov_; //!< Covariance. ImgPyr img_pyr_; //!< Image Pyramid. Features fts_; //!< List of features in the image. vector key_pts_; //!< Five features and associated 3D points which are used to detect if two frames have overlapping field of view. @@ -93,9 +93,11 @@ public: /// Transforms point coordinates in world-frame (w) to camera pixel coordinates (c). inline Vector2d w2c(const Vector3d& xyz_w) const { - return cam_->world2cam( Vector3d(xyz_w.x()*T_f_w_.cos_theta_+xyz_w.z()*T_f_w_.sin_theta_+T_f_w_.X_, - xyz_w.y(), - -xyz_w.x()*T_f_w_.sin_theta_+xyz_w.z()*T_f_w_.cos_theta_+T_f_w_.Z_) ); + Eigen::Matrix R; + R<world2cam( SE3(R,Vector3d(T_f_w_.T2_.translation()(0),1e-19,T_f_w_.T2_.translation()(1)))*xyz_w); } /// Transforms point coordinates in world-frame (w) to camera pixel coordinates (c). inline Vector2d w2px(const Vector3d& xyz_w) const { return cam_->world2cam( xyz_w ); } @@ -108,28 +110,53 @@ public: /// Transforms point coordinates in world-frame (w) to camera-frams (f). inline Vector3d w2f(const Vector3d& xyz_w) const { - return Vector3d(xyz_w.x()*T_f_w_.cos_theta_+xyz_w.z()*T_f_w_.sin_theta_+T_f_w_.X_, - xyz_w.y(), - -xyz_w.x()*T_f_w_.sin_theta_+xyz_w.z()*T_f_w_.cos_theta_+T_f_w_.Z_); + Eigen::Matrix R; + R<inverse() * f; + Eigen::Matrix R; + R<world2cam( f ); } /// Return the pose of the frame in the (w)orld coordinate frame. - inline Vector3d pos() const { return T_f_w_.T->inverse().translation(); } + inline Vector2d pos() const { return T_f_w_.T2_.translation(); } + + inline SE3 se3() const{ + Eigen::Matrix R; + R< R; + R<& J) + Matrix& J) { const double x = xyz_in_f[0]; const double y = xyz_in_f[1]; @@ -137,18 +164,12 @@ public: const double z_inv_2 = z_inv*z_inv; J(0,0) = -z_inv; // -1/z - J(0,1) = 0.0; // 0 - J(0,2) = x*z_inv_2; // x/z^2 - J(0,3) = y*J(0,2); // x*y/z^2 - J(0,4) = -(1.0 + x*J(0,2)); // -(1.0 + x^2/z^2) - J(0,5) = y*z_inv; // y/z + J(0,1) = x*z_inv_2; // x/z^2 + J(0,2) = -(1.0 + pow(x,2)/z_inv_2); // -(1.0 + x^2/z^2) - J(1,0) = 0.0; // 0 - J(1,1) = -z_inv; // -1/z - J(1,2) = y*z_inv_2; // y/z^2 - J(1,3) = 1.0 + y*J(1,2); // 1.0 + y^2/z^2 - J(1,4) = -J(0,3); // -x*y/z^2 - J(1,5) = -x*z_inv; // x/z + J(1,0) = 1e-19; // 0 + J(1,1) = y*z_inv_2; // y/z^2 + J(1,2) = -x*y/z_inv_2; // -x*y/z^2 } inline static void jacobian_l2uv( const Matrix& p, @@ -156,10 +177,10 @@ public: double A = -1.0*sqrt(p.z()); double z_inv = -1/p.z(); J(0,0) = z_inv; - J(0,1) = 0.0; + J(0,1) = 1e-19; J(0,2) = p.x()*A; - J(1,0) = 0.0; + J(1,0) = 1e-19; J(1,1) = z_inv; J(1,2) =A*p.y(); } diff --git a/GPU_version/svo/include/gpu_svo/frame_handler_base.h b/GPU_version/vio/include/gpu_svo/frame_handler_base.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/frame_handler_base.h rename to GPU_version/vio/include/gpu_svo/frame_handler_base.h diff --git a/GPU_version/svo/include/gpu_svo/frame_handler_mono.h b/GPU_version/vio/include/gpu_svo/frame_handler_mono.h similarity index 91% rename from GPU_version/svo/include/gpu_svo/frame_handler_mono.h rename to GPU_version/vio/include/gpu_svo/frame_handler_mono.h index 22180d8..3faa24f 100644 --- a/GPU_version/svo/include/gpu_svo/frame_handler_mono.h +++ b/GPU_version/vio/include/gpu_svo/frame_handler_mono.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include namespace svo { @@ -33,11 +33,11 @@ class FrameHandlerMono : public FrameHandlerBase public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW - FrameHandlerMono(vk::AbstractCamera* cam,Sophus::SE3& SE_init); + FrameHandlerMono(vk::AbstractCamera* cam,Eigen::Matrix& init); virtual ~FrameHandlerMono(); /// Provide an image. - void addImage(const cv::Mat& img, double timestamp); + void addImage(const cv::Mat& img, double timestamp,const ros::Time& time); /// Set the first frame (used for synthetic datasets in benchmark node) void setFirstFrame(const FramePtr& first_frame); @@ -61,7 +61,9 @@ public: const SE3& T_kf_f, const cv::Mat& img, const double timestamp); - std::shared_ptr imu_integPtr_; //Integration of IMU + //std::shared_ptr imu_integPtr_; //Integration of IMU + void UpdateIMU(double* value,const ros::Time& time); + void UpdateCmd(double* value,const ros::Time& time); protected: vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit). @@ -73,7 +75,8 @@ protected: initialization::KltHomographyInit* klt_homography_init_; //!< Used to estimate pose of the first two keyframes by estimating a homography. DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. opencl* gpu_fast_; - uint image_count_=0; + ros::Time time_; + UKF ukfPtr_; /// Initialize the visual odometry algorithm. virtual void initialize(); diff --git a/GPU_version/svo/include/gpu_svo/global.h b/GPU_version/vio/include/gpu_svo/global.h similarity index 51% rename from GPU_version/svo/include/gpu_svo/global.h rename to GPU_version/vio/include/gpu_svo/global.h index 2cfd63b..e522a69 100644 --- a/GPU_version/svo/include/gpu_svo/global.h +++ b/GPU_version/vio/include/gpu_svo/global.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -49,26 +50,52 @@ namespace svo const double EPS = 0.0000000001; const double PI = 3.14159265; - class SE2_5{ + class SE2_5: public SE2{ public: - double X_,Z_,tetha_,cos_theta_,sin_theta_; - SE3* T; - SE2_5(double x,double z,double tetha):X_(x),Z_(z),tetha_(tetha){ - cos_theta_=cos(tetha_); - sin_theta_=sin(tetha_); - Eigen::Matrix R; - R<= 1) + pitch = std::copysign(M_PI / 2.0, pitch); // use 90 degrees if out of range + else + pitch = std::asin(pitch); + Eigen::Matrix R; + R<= 1) + pitch = std::copysign(M_PI / 2.0, pitch); // use 90 degrees if out of range + else + pitch = std::asin(pitch); + Eigen::Matrix R; + R< R; + R<translation().x(); - Z_=T->translation().z(); - tetha_=asin(2*(T->unit_quaternion().w()*T->unit_quaternion().y()- - T->unit_quaternion().z()*T->unit_quaternion().x())); - cos_theta_=cos(tetha_); - sin_theta_=sin(tetha_); + SE2 getSE2() const{ + return T2_; + } + SE2 inverse() const{ + double yaw=atan(T2_.rotation_matrix()(0,1)/T2_.rotation_matrix()(0,0)); + return SE2(yaw+PI,T2_.translation()); + } + double pitch()const{ + return atan(T2_.rotation_matrix()(0,1)/T2_.rotation_matrix()(0,0)); } ~SE2_5(){} }; diff --git a/GPU_version/svo/include/gpu_svo/homography.h b/GPU_version/vio/include/gpu_svo/homography.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/homography.h rename to GPU_version/vio/include/gpu_svo/homography.h diff --git a/GPU_version/svo/include/gpu_svo/initialization.h b/GPU_version/vio/include/gpu_svo/initialization.h similarity index 91% rename from GPU_version/svo/include/gpu_svo/initialization.h rename to GPU_version/vio/include/gpu_svo/initialization.h index 6c3b3b5..28fddbf 100644 --- a/GPU_version/svo/include/gpu_svo/initialization.h +++ b/GPU_version/vio/include/gpu_svo/initialization.h @@ -19,7 +19,7 @@ #include #include -#include +//#include "../../gtsam/imu_integration.h" namespace svo { @@ -37,7 +37,7 @@ public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW FramePtr frame_ref_; - KltHomographyInit(opencl* gpu_fast_):gpu_fast_(gpu_fast_) {}; + KltHomographyInit(opencl* gpu_fast_):gpu_fast_(gpu_fast_),T_cur_from_ref_(0.0,0.0,0.0) {}; ~KltHomographyInit() {}; InitResult addFirstFrame(FramePtr frame_ref); InitResult addSecondFrame(FramePtr frame_ref); @@ -51,7 +51,7 @@ protected: vector disparities_; //!< disparity between first and second frame. vector inliers_; //!< inliers after the geometric check (e.g., Homography). vector xyz_in_cur_; //!< 3D points computed during the geometric check. - SE3 T_cur_from_ref_; //!< computed transformation between the first two frames. + SE2_5 T_cur_from_ref_; //!< computed transformation between the first two frames. opencl* gpu_fast_; }; @@ -79,7 +79,7 @@ void computeHomography( double reprojection_threshold, vector& inliers, vector& xyz_in_cur, - SE3& T_cur_from_ref); + SE2_5& T_cur_from_ref); } // namespace initialization } // namespace svo diff --git a/GPU_version/svo/include/gpu_svo/map.h b/GPU_version/vio/include/gpu_svo/map.h similarity index 97% rename from GPU_version/svo/include/gpu_svo/map.h rename to GPU_version/vio/include/gpu_svo/map.h index 3bee80b..e554088 100644 --- a/GPU_version/svo/include/gpu_svo/map.h +++ b/GPU_version/vio/include/gpu_svo/map.h @@ -103,12 +103,12 @@ public: FramePtr getClosestKeyframe(const FramePtr& frame) const; /// Return the keyframe which is furthest apart from pos. - FramePtr getFurthestKeyframe(const Vector3d& pos) const; + FramePtr getFurthestKeyframe(const Vector2d& pos) const; bool getKeyframeById(const int id, FramePtr& frame) const; /// Transform the whole map with rotation R, translation t and scale s. - void transform(const Matrix3d& R, const Vector3d& t, const double& s); + void transform(const Matrix2d& R, const Vector2d& t, const double& s); /// Empty trash bin of deleted keyframes and map points. We don't delete the /// points immediately to ensure proper cleanup and to provide the visualizer diff --git a/GPU_version/svo/include/gpu_svo/matcher.h b/GPU_version/vio/include/gpu_svo/matcher.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/matcher.h rename to GPU_version/vio/include/gpu_svo/matcher.h diff --git a/GPU_version/svo/include/gpu_svo/math_utils.h b/GPU_version/vio/include/gpu_svo/math_utils.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/math_utils.h rename to GPU_version/vio/include/gpu_svo/math_utils.h diff --git a/GPU_version/svo/include/gpu_svo/nlls_solver.h b/GPU_version/vio/include/gpu_svo/nlls_solver.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/nlls_solver.h rename to GPU_version/vio/include/gpu_svo/nlls_solver.h diff --git a/GPU_version/svo/include/gpu_svo/nlls_solver_impl.hpp b/GPU_version/vio/include/gpu_svo/nlls_solver_impl.hpp similarity index 79% rename from GPU_version/svo/include/gpu_svo/nlls_solver_impl.hpp rename to GPU_version/vio/include/gpu_svo/nlls_solver_impl.hpp index ec36be8..2ce9302 100644 --- a/GPU_version/svo/include/gpu_svo/nlls_solver_impl.hpp +++ b/GPU_version/vio/include/gpu_svo/nlls_solver_impl.hpp @@ -66,8 +66,9 @@ void vk::NLLSSolver::optimizeGaussNewton(ModelType& model) std::cout << "It. " << iter_ << "\t Failure" << "\t new_chi2 = " << new_chi2 - << "\t Error increased. Stop optimizing." - << std::endl; + << "\t Error increased. Stop optimizing.\n"; + // << "H = " << H_ << std::endl + //<< "Jres = " << Jres_ << std::endl; } model = old_model; // rollback break; @@ -87,8 +88,9 @@ void vk::NLLSSolver::optimizeGaussNewton(ModelType& model) << "\t Success" << "\t new_chi2 = " << new_chi2 << "\t n_meas = " << n_meas_ - << "\t x_norm = " << vk::norm_max(x_) - << std::endl; + << "\t x_norm = " << vk::norm_max(x_)<<'\n'; + //<< "\n H = " << H_ << std::endl + //<< "Jres = " << Jres_ << std::endl; } finishIteration(); @@ -133,7 +135,7 @@ void vk::NLLSSolver::optimizeLevenbergMarquardt(ModelType& model) { rho_ = 0; startIteration(); - + bool sign=false; // try to compute and update, if it fails, try with increased mu n_trials_ = 0; do @@ -164,7 +166,7 @@ void vk::NLLSSolver::optimizeLevenbergMarquardt(ModelType& model) // compute error with new model and compare to old error n_meas_ = 0; - new_chi2 = computeResiduals(new_model, false, false); + new_chi2 = computeResiduals(new_model, true, false); rho_ = chi2_-new_chi2; } else @@ -181,7 +183,7 @@ void vk::NLLSSolver::optimizeLevenbergMarquardt(ModelType& model) // update decrased the error -> success model = new_model; chi2_ = new_chi2; - stop_ = vk::norm_max(x_)<=eps_; + stop_ = vk::norm_max(x_)<=eps_ ? true : false; mu_ *= max(1./3., min(1.-pow(2*rho_-1,3), 2./3.)); nu_ = 2.; if(verbose_) @@ -193,29 +195,52 @@ void vk::NLLSSolver::optimizeLevenbergMarquardt(ModelType& model) << "\t new_chi2 = " << new_chi2 << "\t mu = " << mu_ << "\t nu = " << nu_ + << "\t x_norm = " << vk::norm_max(x_) << endl; } } else { - // update increased the error -> fail - mu_ *= nu_; - nu_ *= 2.; - ++n_trials_; - if (n_trials_ >= n_trials_max_) - stop_ = true; - - if(verbose_) - { - cout << "It. " << iter_ - << "\t Trial " << n_trials_ - << "\t Failure" - << "\t n_meas = " << n_meas_ - << "\t new_chi2 = " << new_chi2 - << "\t mu = " << mu_ - << "\t nu = " << nu_ - << endl; + if(sign){ + if(verbose_) + { + cout << "It. " << iter_ + << "\t Trial " << n_trials_ + << "\t Failure" + << "\t n_meas = " << n_meas_ + << "\t new_chi2 = " << new_chi2 + << "\t mu = " << mu_ + << "\t nu = " << nu_ + << "\t x_norm = " << vk::norm_max(x_) + << endl; + } + mu_ /= nu_; + nu_ /= 2.; + ++n_trials_; + if (n_trials_ >= n_trials_max_) + stop_ = true; + sign=false; + }else{ + if(verbose_) + { + cout << "It. " << iter_ + << "\t Trial " << n_trials_ + << "\t Failure" + << "\t n_meas = " << n_meas_ + << "\t new_chi2 = " << new_chi2 + << "\t mu = " << mu_ + << "\t nu = " << nu_ + << "\t x_norm = " << vk::norm_max(x_) + << endl; + } + mu_ *= nu_; + nu_ *= 2.; + ++n_trials_; + if (n_trials_ >= n_trials_max_) + stop_ = true; + sign=true; } + } finishTrial(); diff --git a/GPU_version/vio/include/vio_gpu/output_helper.h b/GPU_version/vio/include/gpu_svo/output_helper.h similarity index 97% rename from GPU_version/vio/include/vio_gpu/output_helper.h rename to GPU_version/vio/include/gpu_svo/output_helper.h index a835def..b1572a8 100644 --- a/GPU_version/vio/include/vio_gpu/output_helper.h +++ b/GPU_version/vio/include/gpu_svo/output_helper.h @@ -14,9 +14,6 @@ #include #include -namespace vk { -namespace output_helper { - using namespace std; using namespace Eigen; @@ -90,8 +87,4 @@ publishFrameMarker (ros::Publisher pub, ros::Duration lifetime = ros::Duration(0.0)); -} // namespace output_helper -} // namespace vk - - #endif /* VIKIT_OUTPUT_HELPER_H_ */ diff --git a/GPU_version/svo/include/gpu_svo/params_helper.h b/GPU_version/vio/include/gpu_svo/params_helper.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/params_helper.h rename to GPU_version/vio/include/gpu_svo/params_helper.h diff --git a/GPU_version/svo/include/gpu_svo/patch_score.h b/GPU_version/vio/include/gpu_svo/patch_score.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/patch_score.h rename to GPU_version/vio/include/gpu_svo/patch_score.h diff --git a/GPU_version/svo/include/gpu_svo/point.h b/GPU_version/vio/include/gpu_svo/point.h similarity index 98% rename from GPU_version/svo/include/gpu_svo/point.h rename to GPU_version/vio/include/gpu_svo/point.h index 81d2769..6b0f900 100644 --- a/GPU_version/svo/include/gpu_svo/point.h +++ b/GPU_version/vio/include/gpu_svo/point.h @@ -77,7 +77,7 @@ public: Feature* findFrameRef(Frame* frame); /// Get Frame with similar viewpoint. - bool getCloseViewObs(const Vector3d& pos, Feature*& obs) const; + bool getCloseViewObs(const Vector2d& pos, Feature*& obs) const; /// Get number of observations. inline size_t nRefs() const { return obs_.size(); } diff --git a/GPU_version/svo/include/gpu_svo/pose_optimizer.h b/GPU_version/vio/include/gpu_svo/pose_optimizer.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/pose_optimizer.h rename to GPU_version/vio/include/gpu_svo/pose_optimizer.h diff --git a/GPU_version/svo/include/gpu_svo/reprojector.h b/GPU_version/vio/include/gpu_svo/reprojector.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/reprojector.h rename to GPU_version/vio/include/gpu_svo/reprojector.h diff --git a/GPU_version/svo/include/gpu_svo/robust_cost.h b/GPU_version/vio/include/gpu_svo/robust_cost.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/robust_cost.h rename to GPU_version/vio/include/gpu_svo/robust_cost.h diff --git a/GPU_version/svo/include/gpu_svo/sparse_img_align.h b/GPU_version/vio/include/gpu_svo/sparse_img_align.h similarity index 88% rename from GPU_version/svo/include/gpu_svo/sparse_img_align.h rename to GPU_version/vio/include/gpu_svo/sparse_img_align.h index 6200066..1fbaace 100644 --- a/GPU_version/svo/include/gpu_svo/sparse_img_align.h +++ b/GPU_version/vio/include/gpu_svo/sparse_img_align.h @@ -20,6 +20,7 @@ #include #include + namespace vk { class AbstractCamera; } @@ -29,10 +30,10 @@ namespace svo { class Feature; /// Optimize the pose of the frame by minimizing the photometric error of feature patches. -class SparseImgAlign : public vk::NLLSSolver<6, SE3> +class SparseImgAlign : public vk::NLLSSolver<3, SE2> { - static const int patch_halfsize_ = 6; - static const int patch_size_ = 6*patch_halfsize_; + static const int patch_halfsize_ = 12; + static const int patch_size_ = 12*patch_halfsize_; static const int patch_area_ = patch_size_*patch_size_; public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW @@ -53,7 +54,7 @@ public: /// Return fisher information matrix, i.e. the Hessian of the log-likelihood /// at the converged state. - Matrix getFisherInformation(); + Matrix getFisherInformation(); protected: FramePtr ref_frame_; //!< reference frame, has depth for gradient pixels. @@ -64,13 +65,13 @@ protected: int min_level_; //!< finest pyramid level for the alignment. // cache: - Matrix jacobian_cache_; + Matrix jacobian_cache_; bool have_ref_patch_cache_; cv::Mat ref_patch_cache_; std::vector visible_fts_; void precomputeReferencePatches(); - virtual double computeResiduals(const SE3& model, bool linearize_system, bool compute_weight_scale = false); + virtual double computeResiduals(const SE2& model, bool linearize_system, bool compute_weight_scale = false); virtual int solve(); virtual void update (const ModelType& old_model, ModelType& new_model); virtual void startIteration(); diff --git a/GPU_version/svo/include/gpu_svo/timer.h b/GPU_version/vio/include/gpu_svo/timer.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/timer.h rename to GPU_version/vio/include/gpu_svo/timer.h diff --git a/GPU_version/vio/include/gpu_svo/ukf.h b/GPU_version/vio/include/gpu_svo/ukf.h new file mode 100644 index 0000000..7919c32 --- /dev/null +++ b/GPU_version/vio/include/gpu_svo/ukf.h @@ -0,0 +1,136 @@ +// +// Created by root on 6/8/21. +// +#ifndef GPU_SVO_UKF_H +#define GPU_SVO_UKF_H + +#include +#include +#include "gpu_svo/config.h" +#include +class Base{ +public: + Base(const Eigen::Matrix &init) { + state_=init; + cov_.setIdentity(); + cov_*=0.0001; + }; + virtual ~Base(){ + }; + void predict(double ddx,double ddz,double dpitch,double time){ + if(t_==0.0){ + t_=time; + return; + } + double t=time-t_; + t_=time; + state_h_< G; + G<<1.0,0,t,0,-0.5*pow(t,2)*(ddz*cos(state_(4))+ddx*sin(state_(4))),0, + 0,1.0,0,t,0.5*pow(t,2)*(ddx*cos(state_(4))-ddz*sin(state_(4))),0, + 0,0,1.0,0,-t*(ddz*cos(state_(4))+ddx*sin(state_(4))),0, + 0,0,0,1.0,t*(ddx*cos(state_(4))-ddz*sin(state_(4))),0, + 0,0,0,0,1.0,t*dpitch, + 0,0,0,0,0,1.0; + Eigen::Matrix R; + R<<10.0*svo::Config::ACC_Noise(),0,0,0,0,0, + 0,10.0*svo::Config::ACC_Noise(),0,0,0,0, + 0,0,svo::Config::ACC_Noise(),0,0,0, + 0,0,0,svo::Config::ACC_Noise(),0,0, + 0,0,0,0,10.0*svo::Config::GYO_Noise(),0, + 0,0,0,0,0,svo::Config::GYO_Noise(); + cov_h_=G*cov_*G.transpose()+R; + predict_up=true; + } + void correct(double x, double z, double pitch, double time){ + Eigen::Matrix H; + Eigen::Matrix Q; + Eigen::Matrix E; + Eigen::Matrix k; + t_=time; + H<<0,0,1.0,0,0,0, + 0,0,0,1.0,0,0, + 0,0,0,0,0,1.0; + Q< H; + Eigen::Matrix Q; + Eigen::Matrix E; + Eigen::Matrix k; + t_=time; + ++match; + H<<1.0,0,0,0,0,0, + 0,1.0,0,0,0,0, + 0,0,0,0,1.0,0; + Q< cov_; + Eigen::Matrix state_; + bool predict_up=false; +private: + double t_=0.0; + Eigen::Matrix cov_h_; + Eigen::Matrix state_h_;//state{x,z,dx,dv,pitch} + +}; + +class UKF { +public: + UKF(const Eigen::Matrix& init) : filter_(new Base(init)) { + }; + virtual ~UKF() { + delete filter_; + }; + void UpdateIMU(double x,double z,double pitch,const ros::Time& time) { + while(lock)usleep(5); + lock=true; + //if(abs(x)<1.0)x=pow(x,3);//picked up from your code + //if(abs(z)<1.0)z=pow(z,3);//picked up from your code + if(!filter_->predict_up)filter_->predict(x,z,pitch,1e-9*time.toNSec()); + lock=false; + }; + void UpdateCmd(double x,double z,double pitch,const ros::Time& time) { + while(lock)usleep(5); + lock=true; + filter_->correct(x,z,pitch,1e-9*time.toNSec()); + lock=false; + }; + std::pair,svo::SE2> UpdateSvo(double x,double z,double pitch,size_t match,ros::Time& time) { + while(lock)usleep(5); + lock=true; + filter_->correct(-1.0*x,-1.0*z,pitch,match,1e-9*time.toNSec()); + lock=false; + //std::cout<<"filter cov\n"<cov_<<'\n'; + //std::cout<<"filter state\n"<state_<<'\n'; + Eigen::Matrix cov; + cov<cov_(0,0),filter_->cov_(0,1),filter_->cov_(0,4), + filter_->cov_(1,0),filter_->cov_(1,1),filter_->cov_(1,4), + filter_->cov_(4,0),filter_->cov_(4,1),filter_->cov_(4,4); + svo::SE2 out(filter_->state_(4),Eigen::Vector2d(-1.0*filter_->state_(0),-1.0*filter_->state_(1))); + return std::pair,svo::SE2>(cov,out); + }; +private: + Base* filter_= nullptr; + bool lock=false; +}; +#endif //GPU_SVO_UKF_H diff --git a/GPU_version/svo/include/gpu_svo/vision.h b/GPU_version/vio/include/gpu_svo/vision.h similarity index 100% rename from GPU_version/svo/include/gpu_svo/vision.h rename to GPU_version/vio/include/gpu_svo/vision.h diff --git a/GPU_version/vio/include/vio_gpu/visualizer.h b/GPU_version/vio/include/gpu_svo/visualizer.h similarity index 100% rename from GPU_version/vio/include/vio_gpu/visualizer.h rename to GPU_version/vio/include/gpu_svo/visualizer.h diff --git a/GPU_version/vio/include/vio_gpu/params_helper.h b/GPU_version/vio/include/vio_gpu/params_helper.h deleted file mode 100644 index 1c8967f..0000000 --- a/GPU_version/vio/include/vio_gpu/params_helper.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ros_params_helper.h - * - * Created on: Feb 22, 2013 - * Author: cforster - * - * from libpointmatcher_ros - */ - -#ifndef ROS_PARAMS_HELPER_H_ -#define ROS_PARAMS_HELPER_H_ - -#include -#include - -namespace vk { - -inline -bool hasParam(const std::string& name) -{ - return ros::param::has(name); -} - -template -T getParam(const std::string& name, const T& defaultValue) -{ - T v; - if(ros::param::get(name, v)) - { - ROS_INFO_STREAM("Found parameter: " << name << ", value: " << v); - return v; - } - else - ROS_WARN_STREAM("Cannot find value for parameter: " << name << ", assigning default: " << defaultValue); - return defaultValue; -} - -template -T getParam(const std::string& name) -{ - T v; - if(ros::param::get(name, v)) - { - ROS_INFO_STREAM("Found parameter: " << name << ", value: " << v); - return v; - } - else - ROS_ERROR_STREAM("Cannot find value for parameter: " << name); - return T(); -} - -} // namespace vk - -#endif // ROS_PARAMS_HELPER_H_ diff --git a/GPU_version/svo/kernel/fast-gray.cl b/GPU_version/vio/kernel/fast-gray.cl similarity index 100% rename from GPU_version/svo/kernel/fast-gray.cl rename to GPU_version/vio/kernel/fast-gray.cl diff --git a/GPU_version/vio/launch/Px30.launch b/GPU_version/vio/launch/Px30.launch index 032feaf..581e4b1 100644 --- a/GPU_version/vio/launch/Px30.launch +++ b/GPU_version/vio/launch/Px30.launch @@ -1,22 +1,18 @@ - + - - + + + - + - - - - - - + - + diff --git a/GPU_version/vio/out.txt b/GPU_version/vio/out.txt new file mode 100644 index 0000000..b027790 --- /dev/null +++ b/GPU_version/vio/out.txt @@ -0,0 +1,26087 @@ +header: + seq: 0 + stamp: + secs: 1624875191 + nsecs: 558718920 + frame_id: "/world" +pose: + pose: + position: + x: 0.0626414404632 + y: -0.0114145588813 + z: 0.0 + orientation: + x: 0.0 + y: 0.0405619092502 + z: 0.0 + w: 0.999177027117 + covariance: [0.07868209584252406, -9.461082738964364e-19, 0.0, 0.0, 3.330677936045202e-14, 0.0, -9.461082738975269e-19, 0.07868209584252475, 0.0, 0.0, -1.9069085356217147e-12, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 3.3306779360448494e-14, -1.906908535621978e-12, 0.0, 0.0, 0.07868205381370827, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 1 + stamp: + secs: 1624875193 + nsecs: 318856001 + frame_id: "/world" +pose: + pose: + position: + x: 0.0277667589782 + y: -0.02601682998 + z: 0.0 + orientation: + x: 0.0 + y: 0.116883729185 + z: 0.0 + w: 0.993145605564 + covariance: [3.9857697567496766, -1.9086436829079788e-06, 0.0, 0.0, -0.001240613762362176, 0.0, -1.9086436829079516e-06, 3.985767469007555, 0.0, 0.0, 0.0007026569307809167, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0012406137623621864, 0.0007026569307809231, 0.0, 0.0, 2.745309716392042, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 2 + stamp: + secs: 1624875196 + nsecs: 599162102 + frame_id: "/world" +pose: + pose: + position: + x: 0.0166163353051 + y: -0.0430530963954 + z: 0.0 + orientation: + x: -0.0 + y: -0.0822472404752 + z: -0.0 + w: 0.996611956297 + covariance: [2.648854370068479, -5.4919736476426895e-06, 0.0, 0.0, -0.00048189566741691197, 0.0, -5.491973647643477e-06, 2.648847894412179, 0.0, 0.0, 0.0002940932594437838, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00048189566741691566, 0.0002940932594437862, 0.0, 0.0, 2.1038345230631976, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 3 + stamp: + secs: 1624875196 + nsecs: 679157019 + frame_id: "/world" +pose: + pose: + position: + x: 0.0185721548702 + y: -0.021561037511 + z: 0.0 + orientation: + x: 0.0 + y: 0.0301557821628 + z: 0.0 + w: 0.999545210985 + covariance: [2.2650572600435086, -6.206231117237778e-07, 0.0, 0.0, -5.1855607892080387e-05, 0.0, -6.206231117238479e-07, 2.265056535524967, 0.0, 0.0, 3.204631952791545e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.185560789208069e-05, 3.204631952791566e-05, 0.0, 0.0, 2.205627128639379, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 4 + stamp: + secs: 1624875196 + nsecs: 759172916 + frame_id: "/world" +pose: + pose: + position: + x: 0.0177732846889 + y: -0.021611066444 + z: 0.0 + orientation: + x: -0.0 + y: -0.00465191474583 + z: -0.0 + w: 0.999989179786 + covariance: [2.970371492501345, -2.361407898433349e-07, 0.0, 0.0, -1.2170615535642942e-05, 0.0, -2.3614078984334695e-07, 2.970371223555147, 0.0, 0.0, 1.0536763116137051e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2170615535642988e-05, 1.0536763116137083e-05, 0.0, 0.0, 2.9516132984610235, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 5 + stamp: + secs: 1624875196 + nsecs: 839164019 + frame_id: "/world" +pose: + pose: + position: + x: -0.00310131463006 + y: 0.0211506595427 + z: 0.0 + orientation: + x: 0.0 + y: 0.0035474838215 + z: 0.0 + w: 0.999993707659 + covariance: [2.5812404954914494, -7.110686924094391e-08, 0.0, 0.0, -4.216770829268579e-06, 0.0, -7.110686924094516e-08, 2.5812404162307985, 0.0, 0.0, 3.0142217862990555e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.216770829268589e-06, 3.0142217862990584e-06, 0.0, 0.0, 2.5755160780979995, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 6 + stamp: + secs: 1624875196 + nsecs: 919202089 + frame_id: "/world" +pose: + pose: + position: + x: 0.000477166316428 + y: 0.0384757898906 + z: 0.0 + orientation: + x: -0.0 + y: -0.00126263206941 + z: -0.0 + w: 0.99999920288 + covariance: [2.537205330000075, -2.527215897142597e-08, 0.0, 0.0, -1.7133958960150043e-06, 0.0, -2.5272158971426105e-08, 2.537205302204348, 0.0, 0.0, 7.931589233478379e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7133958960150049e-06, 7.931589233478382e-07, 0.0, 0.0, 2.5348276350127437, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 7 + stamp: + secs: 1624875196 + nsecs: 999176979 + frame_id: "/world" +pose: + pose: + position: + x: -0.00841003601336 + y: 0.0445356374802 + z: 0.0 + orientation: + x: 0.0 + y: 0.000264512627741 + z: 0.0 + w: 0.999999965017 + covariance: [1.7166537101529034, -4.74156415987445e-09, 0.0, 0.0, -4.6331904613388105e-07, 0.0, -4.741564159874444e-09, 1.7166537049789405, 0.0, 0.0, 2.2821098956012866e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.633190461338812e-07, 2.28210989560129e-07, 0.0, 0.0, 1.716099172882871, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 8 + stamp: + secs: 1624875197 + nsecs: 79178095 + frame_id: "/world" +pose: + pose: + position: + x: -0.0106598057741 + y: -0.000272719281852 + z: 0.0 + orientation: + x: -0.0 + y: -0.00109045418478 + z: -0.0 + w: 0.999999405455 + covariance: [2.97412162957741, -9.030197073518596e-09, 0.0, 0.0, -6.52621086885288e-07, 0.0, -9.030197073518579e-09, 2.974121619781132, 0.0, 0.0, 5.009301948222319e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.52621086885288e-07, 5.009301948222322e-07, 0.0, 0.0, 2.97269104584511, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 9 + stamp: + secs: 1624875197 + nsecs: 159200907 + frame_id: "/world" +pose: + pose: + position: + x: -0.0110024714484 + y: -0.000454368531155 + z: 0.0 + orientation: + x: 0.0 + y: 0.000391571405235 + z: 0.0 + w: 0.999999923336 + covariance: [3.2019225668767475, -3.150000231885707e-08, 0.0, 0.0, -5.4152226047997e-07, 0.0, -3.150000231885696e-08, 3.201922537539638, 0.0, 0.0, 5.376111404939688e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.415222604799701e-07, 5.3761114049396896e-05, 0.0, 0.0, 3.1956213759867746, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 10 + stamp: + secs: 1624875197 + nsecs: 239206076 + frame_id: "/world" +pose: + pose: + position: + x: -0.0154062289642 + y: 0.00489890487622 + z: 0.0 + orientation: + x: 0.0 + y: 9.93034279586e-05 + z: 0.0 + w: 0.999999995069 + covariance: [2.785900300607663, -2.0825685832678915e-08, 0.0, 0.0, -1.1811200678641733e-05, 0.0, -2.0825685832678872e-08, 2.785900289763596, 0.0, 0.0, 3.514303452296117e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1811200678641733e-05, 3.514303452296115e-05, 0.0, 0.0, 2.7815324820862957, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 11 + stamp: + secs: 1624875197 + nsecs: 319202900 + frame_id: "/world" +pose: + pose: + position: + x: -0.0154715009505 + y: 0.0045443071716 + z: 0.0 + orientation: + x: 0.0 + y: 0.000283981783532 + z: 0.0 + w: 0.999999959677 + covariance: [2.4808350941025124, -1.2165864201800308e-08, 0.0, 0.0, -7.225990872024654e-06, 0.0, -1.216586420180026e-08, 2.4808350909881196, 0.0, 0.0, 1.2033121906349419e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.225990872024646e-06, 1.203312190634942e-05, 0.0, 0.0, 2.478277299746955, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 12 + stamp: + secs: 1624875197 + nsecs: 399205923 + frame_id: "/world" +pose: + pose: + position: + x: -0.0156086820159 + y: 0.00447412807491 + z: 0.0 + orientation: + x: 0.0 + y: 0.000243722180649 + z: 0.0 + w: 0.9999999703 + covariance: [2.998512383676597, -9.051111680390655e-09, 0.0, 0.0, -3.5665094589854947e-06, 0.0, -9.051111680390632e-09, 2.998512382287478, 0.0, 0.0, 4.628005164744784e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.566509458985493e-06, 4.628005164744786e-06, 0.0, 0.0, 2.996544542977281, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 13 + stamp: + secs: 1624875197 + nsecs: 479234934 + frame_id: "/world" +pose: + pose: + position: + x: -0.00753809395827 + y: -0.013918683117 + z: 0.0 + orientation: + x: 0.0 + y: 7.98221087963e-05 + z: 0.0 + w: 0.999999996814 + covariance: [3.0802457190027672, -1.5789072296466504e-08, 0.0, 0.0, -9.523338022074358e-06, 0.0, -1.578907229646647e-08, 3.0802457174258118, 0.0, 0.0, 3.35105621493877e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.523338022074358e-06, 3.3510562149387676e-06, 0.0, 0.0, 3.0764571790267463, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 14 + stamp: + secs: 1624875197 + nsecs: 559230089 + frame_id: "/world" +pose: + pose: + position: + x: -0.00865124083866 + y: -0.0117786464916 + z: 0.0 + orientation: + x: 0.0 + y: 0.000113053577061 + z: 0.0 + w: 0.999999993609 + covariance: [2.9750188485756457, -6.46668939815125e-09, 0.0, 0.0, -3.5521739086318263e-06, 0.0, -6.466689398151236e-09, 2.975018847913869, 0.0, 0.0, 9.573491194190574e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.5521739086318254e-06, 9.573491194190576e-07, 0.0, 0.0, 2.9733936909736176, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 15 + stamp: + secs: 1624875197 + nsecs: 639235020 + frame_id: "/world" +pose: + pose: + position: + x: 0.0122449486726 + y: 0.0206285034035 + z: 0.0 + orientation: + x: -0.0 + y: -0.00165594184217 + z: -0.0 + w: 0.999998628927 + covariance: [2.497795840650686, -1.5216582773403297e-09, 0.0, 0.0, -6.322098562405417e-07, 0.0, -1.521658277340327e-09, 2.497795840489801, 0.0, 0.0, 1.5909211054305536e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.322098562405412e-07, 1.5909211054305533e-07, 0.0, 0.0, 2.497395812876691, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 16 + stamp: + secs: 1624875197 + nsecs: 719242096 + frame_id: "/world" +pose: + pose: + position: + x: 0.0121887815088 + y: 0.0205940943095 + z: 0.0 + orientation: + x: 0.0 + y: 0.000218444049936 + z: 0.0 + w: 0.999999976141 + covariance: [3.2431991179042714, -1.5322275059058665e-09, 0.0, 0.0, -3.968414989115551e-07, 0.0, -1.5322275059058626e-09, 3.2431991177342256, 0.0, 0.0, 7.016327791980096e-08, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.96841498911555e-07, 7.016327791980096e-08, 0.0, 0.0, 3.2427560585507944, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 17 + stamp: + secs: 1624875197 + nsecs: 799248934 + frame_id: "/world" +pose: + pose: + position: + x: 0.016367676523 + y: 0.0220660175989 + z: 0.0 + orientation: + x: -0.0 + y: -6.22874647356e-05 + z: -0.0 + w: 0.99999999806 + covariance: [2.889313343455879, -5.444253147615977e-09, 0.0, 0.0, -1.5612749740107182e-06, 0.0, -5.444253147615965e-09, 2.8893133428248454, 0.0, 0.0, 1.7149417702318355e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.561274974010718e-06, 1.7149417702318358e-07, 0.0, 0.0, 2.8875144824557153, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 18 + stamp: + secs: 1624875197 + nsecs: 879255056 + frame_id: "/world" +pose: + pose: + position: + x: 0.0161051003639 + y: 0.0218814048318 + z: 0.0 + orientation: + x: 0.0 + y: 0.000196843413986 + z: 0.0 + w: 0.999999980626 + covariance: [3.4595888930318353, -7.92738684852753e-09, 0.0, 0.0, -1.6410666325730565e-06, 0.0, -7.927386848527507e-09, 3.4595888920979974, 0.0, 0.0, 1.3307795397788244e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.6410666325730558e-06, 1.3307795397788252e-06, 0.0, 0.0, 3.4568423557996124, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 19 + stamp: + secs: 1624875197 + nsecs: 959276915 + frame_id: "/world" +pose: + pose: + position: + x: 0.0130993629182 + y: 0.0250284135089 + z: 0.0 + orientation: + x: 0.0 + y: 0.00066997042759 + z: 0.0 + w: 0.99999977557 + covariance: [3.912394148645007, -6.332127865566567e-09, 0.0, 0.0, -8.786893683355767e-07, 0.0, -6.332127865566549e-09, 3.9123941478991178, 0.0, 0.0, 1.1393342997112697e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.786893683355764e-07, 1.1393342997112695e-06, 0.0, 0.0, 3.91012073471249, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 20 + stamp: + secs: 1624875198 + nsecs: 39307117 + frame_id: "/world" +pose: + pose: + position: + x: 0.00833075308554 + y: 0.0317229185638 + z: 0.0 + orientation: + x: 0.0 + y: 0.00027808093495 + z: 0.0 + w: 0.999999961335 + covariance: [5.01015990711351, -9.080446634843297e-09, 0.0, 0.0, -6.972112514446612e-07, 0.0, -9.080446634843274e-09, 5.010159906045985, 0.0, 0.0, 1.1130939871191168e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.97211251444661e-07, 1.1130939871191164e-06, 0.0, 0.0, 5.00671884952045, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 21 + stamp: + secs: 1624875198 + nsecs: 119277000 + frame_id: "/world" +pose: + pose: + position: + x: 0.00823993144951 + y: 0.0316700863355 + z: 0.0 + orientation: + x: -0.0 + y: -5.58432567746e-05 + z: -0.0 + w: 0.999999998441 + covariance: [5.004386410861576, -6.851749157573967e-09, 0.0, 0.0, -3.0935299231502707e-07, 0.0, -6.85174915757395e-09, 5.004386410057005, 0.0, 0.0, 5.81077222483251e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.0935299231502707e-07, 5.81077222483251e-07, 0.0, 0.0, 5.001676088404593, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 22 + stamp: + secs: 1624875198 + nsecs: 199289083 + frame_id: "/world" +pose: + pose: + position: + x: 0.00827987548645 + y: 0.031693332903 + z: 0.0 + orientation: + x: 0.0 + y: 8.51195637217e-05 + z: 0.0 + w: 0.999999996377 + covariance: [6.66802314523911, -1.569710539431659e-09, 0.0, 0.0, -5.539167690567263e-07, 0.0, -1.569710539431655e-09, 6.668023145054946, 0.0, 0.0, 1.0173250208534339e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.539167690567263e-07, 1.017325020853434e-06, 0.0, 0.0, 6.667412684419782, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 23 + stamp: + secs: 1624875198 + nsecs: 279292107 + frame_id: "/world" +pose: + pose: + position: + x: -0.00601672476321 + y: 0.0597962557111 + z: 0.0 + orientation: + x: -0.0 + y: -0.000182427478844 + z: -0.0 + w: 0.99999998336 + covariance: [5.773828017096222, -1.1100559383853702e-09, 0.0, 0.0, 2.10490979463681e-07, 0.0, -1.1100559383853677e-09, 5.7738280169660925, 0.0, 0.0, -3.4896775196976567e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 2.1049097946368103e-07, -3.4896775196976546e-07, 0.0, 0.0, 5.773379186049659, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 24 + stamp: + secs: 1624875198 + nsecs: 359307051 + frame_id: "/world" +pose: + pose: + position: + x: -0.00596939635664 + y: 0.0546731450517 + z: 0.0 + orientation: + x: 0.0 + y: 0.000179420412757 + z: 0.0 + w: 0.999999983904 + covariance: [4.870448395193584, -2.715895373187792e-11, 0.0, 0.0, -9.458401783861916e-07, 0.0, -2.715895373187782e-11, 4.870448395190856, 0.0, 0.0, 7.909643535115203e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.458401783861919e-07, 7.909643535115208e-07, 0.0, 0.0, 4.870414096763582, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 25 + stamp: + secs: 1624875198 + nsecs: 439341068 + frame_id: "/world" +pose: + pose: + position: + x: -0.00402204831515 + y: 0.0564710529867 + z: 0.0 + orientation: + x: 0.0 + y: 7.87603672793e-05 + z: 0.0 + w: 0.999999996898 + covariance: [4.419267489978145, -1.1171516780614223e-09, 0.0, 0.0, -2.0239861397417157e-06, 0.0, -1.1171516780614192e-09, 4.419267489849727, 0.0, 0.0, 2.060603675568863e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.023986139741715e-06, 2.0606036755688636e-06, 0.0, 0.0, 4.418661799397737, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 26 + stamp: + secs: 1624875198 + nsecs: 519325018 + frame_id: "/world" +pose: + pose: + position: + x: -0.00539573052245 + y: 0.0492981006915 + z: 0.0 + orientation: + x: 0.0 + y: 1.23684445111e-05 + z: 0.0 + w: 0.999999999924 + covariance: [5.51978421669653, -3.180136437192512e-10, 0.0, 0.0, -6.154035046796035e-07, 0.0, -3.180136437192502e-10, 5.5197842166599465, 0.0, 0.0, 6.139961769247182e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.15403504679603e-07, 6.139961769247183e-07, 0.0, 0.0, 5.5196107542858615, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 27 + stamp: + secs: 1624875198 + nsecs: 599320889 + frame_id: "/world" +pose: + pose: + position: + x: -0.00353864683181 + y: 0.0508350238058 + z: 0.0 + orientation: + x: -0.0 + y: -1.93948657842e-05 + z: -0.0 + w: 0.999999999812 + covariance: [5.478221361043458, -1.0789933998159499e-09, 0.0, 0.0, -1.5158996146087268e-06, 0.0, -1.0789933998159466e-09, 5.478221360919302, 0.0, 0.0, 8.868260064139848e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5158996146087268e-06, 8.868260064139852e-07, 0.0, 0.0, 5.477634604668419, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 28 + stamp: + secs: 1624875198 + nsecs: 679327011 + frame_id: "/world" +pose: + pose: + position: + x: -0.00218483209211 + y: 0.0511190010454 + z: 0.0 + orientation: + x: 0.0 + y: 3.32196708283e-05 + z: 0.0 + w: 0.999999999448 + covariance: [5.467158230533972, -1.661966266679308e-09, 0.0, 0.0, -1.8198609214126284e-06, 0.0, -1.661966266679303e-09, 5.467158230340817, 0.0, 0.0, 8.615414251639713e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8198609214126289e-06, 8.615414251639717e-07, 0.0, 0.0, 5.4662322915130686, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 29 + stamp: + secs: 1624875198 + nsecs: 759337902 + frame_id: "/world" +pose: + pose: + position: + x: -0.00152390603179 + y: 0.0512636655905 + z: 0.0 + orientation: + x: 0.0 + y: 7.71127429373e-06 + z: 0.0 + w: 0.99999999997 + covariance: [5.8648786261082435, -2.331664130147377e-09, 0.0, 0.0, -2.3820189290707838e-06, 0.0, -2.3316641301473703e-09, 5.86487862583418, 0.0, 0.0, 8.776682654593583e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.3820189290707833e-06, 8.776682654593584e-07, 0.0, 0.0, 5.863543396083182, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 30 + stamp: + secs: 1624875198 + nsecs: 839340925 + frame_id: "/world" +pose: + pose: + position: + x: 0.0011554025041 + y: 0.0530192721025 + z: 0.0 + orientation: + x: 0.0 + y: 0.000139748276753 + z: 0.0 + w: 0.999999990235 + covariance: [7.044799202883239, -8.478551110188377e-09, 0.0, 0.0, -5.012356389703555e-06, 0.0, -8.478551110188356e-09, 7.04479920186819, 0.0, 0.0, 1.4697270129322411e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.012356389703555e-06, 1.469727012932241e-06, 0.0, 0.0, 7.039731729255961, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 31 + stamp: + secs: 1624875198 + nsecs: 919356108 + frame_id: "/world" +pose: + pose: + position: + x: 0.00269970605271 + y: 0.0535692293035 + z: 0.0 + orientation: + x: 0.0 + y: 8.12446361621e-05 + z: 0.0 + w: 0.9999999967 + covariance: [5.865526536324696, -4.009301911530781e-09, 0.0, 0.0, -1.788656659783739e-06, 0.0, -4.009301911530773e-09, 5.865526535843565, 0.0, 0.0, 6.326158745551525e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7886566597837392e-06, 6.326158745551528e-07, 0.0, 0.0, 5.863097758433728, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 32 + stamp: + secs: 1624875198 + nsecs: 999368906 + frame_id: "/world" +pose: + pose: + position: + x: 0.000421112315937 + y: 0.050847345662 + z: 0.0 + orientation: + x: 0.0 + y: 0.000191866996085 + z: 0.0 + w: 0.999999981594 + covariance: [5.573063470694434, -5.9085955978354e-09, 0.0, 0.0, -1.2104428003757742e-06, 0.0, -5.908595597835388e-09, 5.5730634699821735, 0.0, 0.0, 2.8792081789548466e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2104428003757736e-06, 2.879208178954846e-07, 0.0, 0.0, 5.569342875920074, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 33 + stamp: + secs: 1624875199 + nsecs: 79366922 + frame_id: "/world" +pose: + pose: + position: + x: -0.00156417319524 + y: 0.0410298336757 + z: 0.0 + orientation: + x: 0.0 + y: 0.000130407421243 + z: 0.0 + w: 0.999999991497 + covariance: [7.571954289010189, -4.237598046875895e-09, 0.0, 0.0, -7.460709969432444e-07, 0.0, -4.237598046875886e-09, 7.571954288499087, 0.0, 0.0, 1.2687838593861394e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.460709969432439e-07, 1.2687838593861388e-07, 0.0, 0.0, 7.569264328726531, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 34 + stamp: + secs: 1624875199 + nsecs: 159377098 + frame_id: "/world" +pose: + pose: + position: + x: -0.00122771819987 + y: 0.0396489609107 + z: 0.0 + orientation: + x: 0.0 + y: 0.000123348167764 + z: 0.0 + w: 0.999999992393 + covariance: [6.473580227328412, -5.363980208289023e-09, 0.0, 0.0, -2.0225825376281164e-06, 0.0, -5.363980208289009e-09, 6.473580226679866, 0.0, 0.0, 1.437545984320914e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.0225825376281156e-06, 1.4375459843209138e-06, 0.0, 0.0, 6.470020128622338, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 35 + stamp: + secs: 1624875199 + nsecs: 239401102 + frame_id: "/world" +pose: + pose: + position: + x: 0.0051781728797 + y: 0.0351760222334 + z: 0.0 + orientation: + x: 0.0 + y: 0.000100643935232 + z: 0.0 + w: 0.999999994935 + covariance: [7.2935232724597325, -5.909388020211995e-09, 0.0, 0.0, -4.024387795638281e-06, 0.0, -5.90938802021198e-09, 7.29352327174132, 0.0, 0.0, 2.0485951522887395e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.02438779563828e-06, 2.0485951522887382e-06, 0.0, 0.0, 7.289493575011101, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 36 + stamp: + secs: 1624875199 + nsecs: 319385052 + frame_id: "/world" +pose: + pose: + position: + x: 0.0103827542099 + y: 0.00999221418783 + z: 0.0 + orientation: + x: 0.0 + y: 0.0003627373181 + z: 0.0 + w: 0.999999934211 + covariance: [8.421403995211696, -1.2500644469310046e-08, 0.0, 0.0, -8.238106675534144e-06, 0.0, -1.2500644469310014e-08, 8.421403993664072, 0.0, 0.0, 3.0276717194640595e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.238106675534142e-06, 3.0276717194640574e-06, 0.0, 0.0, 8.412570672956345, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 37 + stamp: + secs: 1624875199 + nsecs: 399395943 + frame_id: "/world" +pose: + pose: + position: + x: 0.0105383052281 + y: 0.0100450272921 + z: 0.0 + orientation: + x: 0.0 + y: 0.000656240017072 + z: 0.0 + w: 0.999999784674 + covariance: [10.059449134368599, -2.055039118497138e-08, 0.0, 0.0, -1.8867792152113142e-05, 0.0, -2.0550391184971324e-08, 10.059449131755892, 0.0, 0.0, 4.502900959104725e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.886779215211314e-05, 4.502900959104724e-06, 0.0, 0.0, 10.044621476619097, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 38 + stamp: + secs: 1624875199 + nsecs: 479382038 + frame_id: "/world" +pose: + pose: + position: + x: 0.0106460562493 + y: 0.0099990778026 + z: 0.0 + orientation: + x: 0.0 + y: 0.000497412762367 + z: 0.0 + w: 0.99999987629 + covariance: [10.947172175722772, -1.9727848714141727e-08, 0.0, 0.0, -2.1405640273161004e-05, 0.0, -1.9727848714141674e-08, 10.947172173138343, 0.0, 0.0, 4.8710773357471715e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1405640273161007e-05, 4.8710773357471715e-06, 0.0, 0.0, 10.932711711383535, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 39 + stamp: + secs: 1624875199 + nsecs: 559417963 + frame_id: "/world" +pose: + pose: + position: + x: 0.0183208528313 + y: 0.00821377788867 + z: 0.0 + orientation: + x: 0.0 + y: 3.29001507659e-05 + z: 0.0 + w: 0.999999999459 + covariance: [11.420217134486125, -3.418769972795095e-08, 0.0, 0.0, -3.163393196271123e-05, 0.0, -3.418769972795087e-08, 11.420217129744085, 0.0, 0.0, 7.82972515259146e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.163393196271123e-05, 7.82972515259146e-06, 0.0, 0.0, 11.394160540528814, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 40 + stamp: + secs: 1624875199 + nsecs: 639408112 + frame_id: "/world" +pose: + pose: + position: + x: -0.000715318423737 + y: 0.00496986031106 + z: 0.0 + orientation: + x: -0.0 + y: -2.2172795399e-05 + z: -0.0 + w: 0.999999999754 + covariance: [8.114031492796547, -2.1333618529755705e-08, 0.0, 0.0, -1.4699975136932473e-05, 0.0, -2.1333618529755646e-08, 8.114031489771032, 0.0, 0.0, 7.256197278731696e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4699975136932478e-05, 7.256197278731695e-06, 0.0, 0.0, 8.09735712011555, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 41 + stamp: + secs: 1624875199 + nsecs: 719436884 + frame_id: "/world" +pose: + pose: + position: + x: -0.00140749099762 + y: 0.00484300107616 + z: 0.0 + orientation: + x: -0.0 + y: -0.000116152639797 + z: -0.0 + w: 0.999999993254 + covariance: [8.805861136832347, -2.794979980724563e-08, 0.0, 0.0, -1.3585168096472849e-05, 0.0, -2.7949799807245557e-08, 8.80586113282478, 0.0, 0.0, 1.2441321253646953e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3585168096472852e-05, 1.2441321253646958e-05, 0.0, 0.0, 8.783403422518505, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 42 + stamp: + secs: 1624875199 + nsecs: 799429893 + frame_id: "/world" +pose: + pose: + position: + x: -0.00208705541652 + y: 0.0051879453949 + z: 0.0 + orientation: + x: 0.0 + y: 0.000305811394084 + z: 0.0 + w: 0.99999995324 + covariance: [9.11153103833801, -3.017494058291259e-08, 0.0, 0.0, -1.3293412437218361e-05, 0.0, -3.0174940582912515e-08, 9.111531033987271, 0.0, 0.0, 1.1866143304580043e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3293412437218363e-05, 1.1866143304580048e-05, 0.0, 0.0, 9.086726718793535, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 43 + stamp: + secs: 1624875199 + nsecs: 879475117 + frame_id: "/world" +pose: + pose: + position: + x: 0.000833026600846 + y: 0.0164104680495 + z: 0.0 + orientation: + x: -0.0 + y: -0.000341267352612 + z: -0.0 + w: 0.999999941768 + covariance: [10.429549924358632, -1.4239469457389318e-08, 0.0, 0.0, -6.3328065618231e-06, 0.0, -1.4239469457389285e-08, 10.429549922307963, 0.0, 0.0, 5.834703781534976e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.3328065618231036e-06, 5.834703781534978e-06, 0.0, 0.0, 10.417878557067265, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 44 + stamp: + secs: 1624875199 + nsecs: 959450006 + frame_id: "/world" +pose: + pose: + position: + x: 0.00117863922695 + y: 0.0163072606007 + z: 0.0 + orientation: + x: 0.0 + y: 0.000148209862774 + z: 0.0 + w: 0.999999989017 + covariance: [8.716945349140108, -1.2633551845756085e-08, 0.0, 0.0, -9.01127956118428e-06, 0.0, -1.2633551845756057e-08, 8.71694534730184, 0.0, 0.0, 5.786114230873473e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.01127956118428e-06, 5.786114230873476e-06, 0.0, 0.0, 8.706295560327522, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 45 + stamp: + secs: 1624875200 + nsecs: 39455891 + frame_id: "/world" +pose: + pose: + position: + x: 0.00191347018293 + y: 0.0303008315088 + z: 0.0 + orientation: + x: -0.0 + y: -1.89652015222e-05 + z: -0.0 + w: 0.99999999982 + covariance: [9.071013981238169, -2.0391317329312797e-08, 0.0, 0.0, -1.9993804152798187e-05, 0.0, -2.0391317329312747e-08, 9.071013978193548, 0.0, 0.0, 1.2356219059953533e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9993804152798187e-05, 1.235621905995354e-05, 0.0, 0.0, 9.053185736361623, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 46 + stamp: + secs: 1624875200 + nsecs: 119455099 + frame_id: "/world" +pose: + pose: + position: + x: 0.00522871971408 + y: 0.0127281908142 + z: 0.0 + orientation: + x: 0.0 + y: 5.58547897419e-05 + z: 0.0 + w: 0.99999999844 + covariance: [6.850193881378459, -9.301507255491722e-09, 0.0, 0.0, -9.716836926241863e-06, 0.0, -9.301507255491697e-09, 6.850193879970645, 0.0, 0.0, 5.857141325473772e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.716836926241866e-06, 5.8571413254737795e-06, 0.0, 0.0, 6.841899640798484, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 47 + stamp: + secs: 1624875200 + nsecs: 199474096 + frame_id: "/world" +pose: + pose: + position: + x: 0.00692046202895 + y: 0.00831617702429 + z: 0.0 + orientation: + x: -0.0 + y: -0.00017924013968 + z: -0.0 + w: 0.999999983936 + covariance: [6.813636944206522, -9.165813940183094e-09, 0.0, 0.0, -8.504696513851456e-06, 0.0, -9.16581394018307e-09, 6.8136369427833, 0.0, 0.0, 5.018490966792904e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.504696513851464e-06, 5.01849096679291e-06, 0.0, 0.0, 6.8052296475089475, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 48 + stamp: + secs: 1624875200 + nsecs: 279485941 + frame_id: "/world" +pose: + pose: + position: + x: 0.00350393720251 + y: 0.0279228469351 + z: 0.0 + orientation: + x: 0.0 + y: 0.000139258630048 + z: 0.0 + w: 0.999999990304 + covariance: [6.80397922008437, -1.1487301687072829e-08, 0.0, 0.0, -6.8872417429891e-06, 0.0, -1.1487301687072796e-08, 6.803979218264553, 0.0, 0.0, 4.246626583476236e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.887241742989105e-06, 4.24662658347624e-06, 0.0, 0.0, 6.793111744317717, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 49 + stamp: + secs: 1624875200 + nsecs: 359488964 + frame_id: "/world" +pose: + pose: + position: + x: 0.00411981504066 + y: 0.0278321183957 + z: 0.0 + orientation: + x: 0.0 + y: 6.70055884419e-05 + z: 0.0 + w: 0.999999997755 + covariance: [6.263785616830026, -6.0212980423773e-09, 0.0, 0.0, -3.97246087593067e-06, 0.0, -6.021298042377284e-09, 6.263785615868659, 0.0, 0.0, 2.3303442376061175e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.972460875930671e-06, 2.330344237606118e-06, 0.0, 0.0, 6.258009766210611, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 50 + stamp: + secs: 1624875200 + nsecs: 439486027 + frame_id: "/world" +pose: + pose: + position: + x: 0.00170615913537 + y: 0.0227744893462 + z: 0.0 + orientation: + x: 0.0 + y: 9.95140267022e-05 + z: 0.0 + w: 0.999999995048 + covariance: [6.612827744697019, -4.670546484113974e-09, 0.0, 0.0, -3.6402228387361465e-06, 0.0, -4.67054648411396e-09, 6.612827743941922, 0.0, 0.0, 1.909185784228944e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.640222838736148e-06, 1.9091857842289445e-06, 0.0, 0.0, 6.608272718282844, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 51 + stamp: + secs: 1624875200 + nsecs: 519515038 + frame_id: "/world" +pose: + pose: + position: + x: 0.00169110298905 + y: 0.0227685736552 + z: 0.0 + orientation: + x: -0.0 + y: -8.95433212223e-06 + z: -0.0 + w: 0.99999999996 + covariance: [8.08927721725767, -1.6891452036913866e-09, 0.0, 0.0, -1.2708184239368811e-06, 0.0, -1.6891452036913808e-09, 8.089277216985941, 0.0, 0.0, 7.187257386142542e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2708184239368815e-06, 7.187257386142546e-07, 0.0, 0.0, 8.087637278832627, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 52 + stamp: + secs: 1624875200 + nsecs: 599533081 + frame_id: "/world" +pose: + pose: + position: + x: 0.00311351073892 + y: 0.0430950522637 + z: 0.0 + orientation: + x: 0.0 + y: 0.000259467151856 + z: 0.0 + w: 0.999999966338 + covariance: [9.867491828635, -6.219476929989891e-09, 0.0, 0.0, -3.671787789530499e-06, 0.0, -6.219476929989876e-09, 9.867491827611309, 0.0, 0.0, 3.180515435328955e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.671787789530501e-06, 3.180515435328955e-06, 0.0, 0.0, 9.86117128550643, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 53 + stamp: + secs: 1624875200 + nsecs: 679512978 + frame_id: "/world" +pose: + pose: + position: + x: 0.00697223945168 + y: 0.0797212810187 + z: 0.0 + orientation: + x: -0.0 + y: -0.000397378624356 + z: -0.0 + w: 0.999999921045 + covariance: [8.53537921340122, -8.990785794317857e-09, 0.0, 0.0, -2.963454538326025e-06, 0.0, -8.990785794317835e-09, 8.535379211910438, 0.0, 0.0, 3.6671407348286737e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.963454538326025e-06, 3.667140734828673e-06, 0.0, 0.0, 8.525912122733539, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 54 + stamp: + secs: 1624875200 + nsecs: 759515047 + frame_id: "/world" +pose: + pose: + position: + x: 0.00710837077299 + y: 0.0798090072252 + z: 0.0 + orientation: + x: -0.0 + y: -0.000107432669544 + z: -0.0 + w: 0.999999994229 + covariance: [8.989838112870954, -1.4613674772677515e-08, 0.0, 0.0, -2.815725423658808e-06, 0.0, -1.4613674772677473e-08, 8.989838110448014, 0.0, 0.0, 7.145359338246082e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.815725423658809e-06, 7.1453593382460825e-06, 0.0, 0.0, 8.974076526306552, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 55 + stamp: + secs: 1624875200 + nsecs: 839543104 + frame_id: "/world" +pose: + pose: + position: + x: 0.00859331568175 + y: 0.103013890972 + z: 0.0 + orientation: + x: 0.0 + y: 0.0022884793268 + z: 0.0 + w: 0.999997381428 + covariance: [9.189678237325923, -1.8658923711305735e-08, 0.0, 0.0, -8.668323780503765e-06, 0.0, -1.865892371130568e-08, 9.1896782342381, 0.0, 0.0, 9.343818663895769e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.668323780503763e-06, 9.343818663895767e-06, 0.0, 0.0, 9.169177335594483, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 56 + stamp: + secs: 1624875200 + nsecs: 919538975 + frame_id: "/world" +pose: + pose: + position: + x: 0.00428757485044 + y: 0.11077822985 + z: 0.0 + orientation: + x: 0.0 + y: 0.000504456930103 + z: 0.0 + w: 0.999999872762 + covariance: [7.530283569338185, -1.4107957036767555e-08, 0.0, 0.0, -1.2473398889976944e-05, 0.0, -1.4107957036767514e-08, 7.530283566963214, 0.0, 0.0, 5.511335954322725e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2473398889976943e-05, 5.511335954322724e-06, 0.0, 0.0, 7.514519150095854, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 57 + stamp: + secs: 1624875200 + nsecs: 999536991 + frame_id: "/world" +pose: + pose: + position: + x: 0.00151663760433 + y: 0.0811101772075 + z: 0.0 + orientation: + x: -0.0 + y: -5.61993155065e-05 + z: -0.0 + w: 0.999999998421 + covariance: [8.519030551815368, -1.4853078972163737e-09, 0.0, 0.0, -7.695498016380804e-07, 0.0, -1.4853078972163686e-09, 8.519030551566688, 0.0, 0.0, 7.780477217188373e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.695498016380817e-07, 7.780477217188366e-07, 0.0, 0.0, 8.517372433936337, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 58 + stamp: + secs: 1624875201 + nsecs: 79540968 + frame_id: "/world" +pose: + pose: + position: + x: 0.00291423774383 + y: 0.0714232394328 + z: 0.0 + orientation: + x: 0.0 + y: 4.80716095452e-05 + z: 0.0 + w: 0.999999998845 + covariance: [7.327921697120641, -7.038941843246094e-10, 0.0, 0.0, -4.0854791091300086e-07, 0.0, -7.03894184324607e-10, 7.327921697004113, 0.0, 0.0, 3.679089009349502e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.085479109130009e-07, 3.6790890093495e-07, 0.0, 0.0, 7.327140188449183, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 59 + stamp: + secs: 1624875201 + nsecs: 159560919 + frame_id: "/world" +pose: + pose: + position: + x: -0.00323561132099 + y: 0.0777530353866 + z: 0.0 + orientation: + x: 0.0 + y: 0.000172843880588 + z: 0.0 + w: 0.999999985062 + covariance: [7.632862195453625, -5.396386791882401e-09, 0.0, 0.0, -1.98587669485776e-06, 0.0, -5.396386791882387e-09, 7.6328621945144075, 0.0, 0.0, 1.5511758753030348e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9858766948577596e-06, 1.5511758753030348e-06, 0.0, 0.0, 7.6264959731959285, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 60 + stamp: + secs: 1624875201 + nsecs: 239557981 + frame_id: "/world" +pose: + pose: + position: + x: -0.0102893451605 + y: 0.0737500433133 + z: 0.0 + orientation: + x: -0.0 + y: -0.000276517209936 + z: -0.0 + w: 0.999999961769 + covariance: [8.584408983084927, -1.2642446357245383e-08, 0.0, 0.0, -4.038700503584341e-06, 0.0, -1.2642446357245352e-08, 8.584408980842381, 0.0, 0.0, 2.7363723425999526e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.038700503584339e-06, 2.7363723425999526e-06, 0.0, 0.0, 8.569116971122988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 61 + stamp: + secs: 1624875201 + nsecs: 319547892 + frame_id: "/world" +pose: + pose: + position: + x: -0.010261107154 + y: 0.0739101693853 + z: 0.0 + orientation: + x: -0.0 + y: -5.95845939277e-05 + z: -0.0 + w: 0.999999998225 + covariance: [8.091584179325764, -6.003352241560462e-09, 0.0, 0.0, -1.9086220101898923e-06, 0.0, -6.003352241560447e-09, 8.091584178258362, 0.0, 0.0, 1.2097003053667123e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.908622010189891e-06, 1.209700305366712e-06, 0.0, 0.0, 8.084284323254858, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 62 + stamp: + secs: 1624875201 + nsecs: 399564028 + frame_id: "/world" +pose: + pose: + position: + x: -0.00385669686624 + y: 0.0672982451832 + z: 0.0 + orientation: + x: -0.0 + y: -0.000738125484401 + z: -0.0 + w: 0.999999727585 + covariance: [8.797555779431198, -1.600774559183516e-08, 0.0, 0.0, -8.431719548659337e-06, 0.0, -1.600774559183512e-08, 8.797555776546139, 0.0, 0.0, 3.184758622294765e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.431719548659337e-06, 3.184758622294765e-06, 0.0, 0.0, 8.777563454693103, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 63 + stamp: + secs: 1624875201 + nsecs: 479578972 + frame_id: "/world" +pose: + pose: + position: + x: -0.00350858971035 + y: 0.067701371288 + z: 0.0 + orientation: + x: -0.0 + y: -0.000345703414971 + z: -0.0 + w: 0.999999940245 + covariance: [8.18183584110367, -1.883703010278204e-08, 0.0, 0.0, -9.578913580447987e-06, 0.0, -1.8837030102781997e-08, 8.181835837672871, 0.0, 0.0, 3.182161552695932e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.57891358044799e-06, 3.1821615526959317e-06, 0.0, 0.0, 8.157835581057473, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 64 + stamp: + secs: 1624875201 + nsecs: 559628963 + frame_id: "/world" +pose: + pose: + position: + x: -0.0111300352788 + y: 0.067056245337 + z: 0.0 + orientation: + x: 0.0 + y: 0.000128814391306 + z: 0.0 + w: 0.999999991703 + covariance: [7.241779245825406, -1.663592656885984e-08, 0.0, 0.0, -6.593230475229682e-06, 0.0, -1.6635926568859794e-08, 7.241779242773938, 0.0, 0.0, 1.6264059237312903e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.5932304752296835e-06, 1.6264059237312895e-06, 0.0, 0.0, 7.220188521838424, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 65 + stamp: + secs: 1624875201 + nsecs: 639638901 + frame_id: "/world" +pose: + pose: + position: + x: -0.00929179928672 + y: 0.0578352446516 + z: 0.0 + orientation: + x: 0.0 + y: 8.59037006861e-05 + z: 0.0 + w: 0.99999999631 + covariance: [7.600496343640866, -1.1505592590481727e-08, 0.0, 0.0, -3.873183760455839e-06, 0.0, -1.15055925904817e-08, 7.600496341523942, 0.0, 0.0, 7.956870880153922e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.873183760455842e-06, 7.956870880153921e-07, 0.0, 0.0, 7.585424968516159, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 66 + stamp: + secs: 1624875201 + nsecs: 719597101 + frame_id: "/world" +pose: + pose: + position: + x: -0.0194372786599 + y: 0.0736482208398 + z: 0.0 + orientation: + x: -0.0 + y: -0.000165875077853 + z: -0.0 + w: 0.999999986243 + covariance: [8.568504390771684, -1.3788963894632275e-08, 0.0, 0.0, -3.974822469017283e-06, 0.0, -1.3788963894632245e-08, 8.5685043882266, 0.0, 0.0, 3.407900477125552e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.974822469017285e-06, 3.4079004771255523e-06, 0.0, 0.0, 8.550165670015407, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 67 + stamp: + secs: 1624875201 + nsecs: 799607038 + frame_id: "/world" +pose: + pose: + position: + x: -0.0189989177182 + y: 0.0739950149124 + z: 0.0 + orientation: + x: -0.0 + y: -0.000383313890377 + z: -0.0 + w: 0.999999926535 + covariance: [8.098124631112075, -1.5159058190265913e-08, 0.0, 0.0, -6.4103104581784824e-06, 0.0, -1.5159058190265883e-08, 8.098124628315821, 0.0, 0.0, 6.729358811134934e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.4103104581784824e-06, 6.729358811134931e-06, 0.0, 0.0, 8.077564574050317, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 68 + stamp: + secs: 1624875201 + nsecs: 879617929 + frame_id: "/world" +pose: + pose: + position: + x: -0.0239214889737 + y: 0.0713017685962 + z: 0.0 + orientation: + x: -0.0 + y: -0.000150143592512 + z: -0.0 + w: 0.999999988728 + covariance: [6.623175627488095, -1.5173527259693928e-08, 0.0, 0.0, -6.4085129237086795e-06, 0.0, -1.5173527259693895e-08, 6.62317562468812, 0.0, 0.0, 5.7301476360502045e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.408512923708683e-06, 5.730147636050202e-06, 0.0, 0.0, 6.602152181844446, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 69 + stamp: + secs: 1624875201 + nsecs: 959651947 + frame_id: "/world" +pose: + pose: + position: + x: -0.0224349219106 + y: 0.0719322817239 + z: 0.0 + orientation: + x: -0.0 + y: -0.000190531457338 + z: -0.0 + w: 0.999999981849 + covariance: [6.222725174686373, -1.3381555984559277e-08, 0.0, 0.0, -5.424212123960663e-06, 0.0, -1.3381555984559242e-08, 6.222725172211248, 0.0, 0.0, 3.416152921665299e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.4242121239606604e-06, 3.4161529216652967e-06, 0.0, 0.0, 6.203848129824357, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 70 + stamp: + secs: 1624875202 + nsecs: 39701939 + frame_id: "/world" +pose: + pose: + position: + x: -0.0249211441792 + y: 0.0686466062594 + z: 0.0 + orientation: + x: -0.0 + y: -2.38326114436e-05 + z: -0.0 + w: 0.999999999716 + covariance: [6.099456279905903, -7.960471946582176e-09, 0.0, 0.0, -3.04103704253204e-06, 0.0, -7.960471946582161e-09, 6.0994562784294635, 0.0, 0.0, 1.5209934075323622e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.0410370425320393e-06, 1.520993407532361e-06, 0.0, 0.0, 6.088089134366699, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 71 + stamp: + secs: 1624875202 + nsecs: 119643927 + frame_id: "/world" +pose: + pose: + position: + x: -0.0243534614371 + y: 0.0705517257814 + z: 0.0 + orientation: + x: -0.0 + y: -1.13757055991e-05 + z: -0.0 + w: 0.999999999935 + covariance: [6.561078424409695, -8.07391982956032e-09, 0.0, 0.0, -3.5291716057884617e-06, 0.0, -8.073919829560303e-09, 6.561078422904348, 0.0, 0.0, 1.0175506089896602e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.529171605788462e-06, 1.01755060898966e-06, 0.0, 0.0, 6.549351964106195, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 72 + stamp: + secs: 1624875202 + nsecs: 199664116 + frame_id: "/world" +pose: + pose: + position: + x: -0.025419868889 + y: 0.0693357429654 + z: 0.0 + orientation: + x: -0.0 + y: -4.80184683067e-05 + z: -0.0 + w: 0.999999998847 + covariance: [6.7252134227399125, -1.1866666244636634e-08, 0.0, 0.0, -4.75954256596035e-06, 0.0, -1.1866666244636614e-08, 6.725213420512024, 0.0, 0.0, 3.4063648153580773e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.759542565960349e-06, 3.4063648153580756e-06, 0.0, 0.0, 6.7075861958796175, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 73 + stamp: + secs: 1624875202 + nsecs: 279659033 + frame_id: "/world" +pose: + pose: + position: + x: -0.0253446741531 + y: 0.0694086183036 + z: 0.0 + orientation: + x: -0.0 + y: -0.000100761670914 + z: -0.0 + w: 0.999999994924 + covariance: [6.77842123012036, -1.1774321664977542e-08, 0.0, 0.0, -7.82425314367777e-07, 0.0, -1.1774321664977517e-08, 6.7784212279133165, 0.0, 0.0, 3.899854464605632e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.824253143677766e-07, 3.899854464605631e-06, 0.0, 0.0, 6.760663426466538, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 74 + stamp: + secs: 1624875202 + nsecs: 359657049 + frame_id: "/world" +pose: + pose: + position: + x: -0.0252920790212 + y: 0.0694601097115 + z: 0.0 + orientation: + x: -0.0 + y: -0.000125277904577 + z: -0.0 + w: 0.999999992153 + covariance: [9.108895719258024, -1.3400596682813527e-08, 0.0, 0.0, 1.398736772090177e-06, 0.0, -1.3400596682813499e-08, 9.108895716746556, 0.0, 0.0, 4.010259942346317e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 1.3987367720901762e-06, 4.010259942346316e-06, 0.0, 0.0, 9.088497017582053, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 75 + stamp: + secs: 1624875202 + nsecs: 439666033 + frame_id: "/world" +pose: + pose: + position: + x: -0.0245682481402 + y: 0.0683523318375 + z: 0.0 + orientation: + x: 0.0 + y: 1.69631372461e-05 + z: 0.0 + w: 0.999999999856 + covariance: [6.3192041936226095, -5.999413326056214e-09, 0.0, 0.0, -5.653885152104655e-07, 0.0, -5.999413326056206e-09, 6.319204192501843, 0.0, 0.0, 3.7769954710761027e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.653885152104661e-07, 3.776995471076103e-06, 0.0, 0.0, 6.309947517610192, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 76 + stamp: + secs: 1624875202 + nsecs: 519676924 + frame_id: "/world" +pose: + pose: + position: + x: -0.0248253198229 + y: 0.0678310434513 + z: 0.0 + orientation: + x: 0.0 + y: 0.000908551780223 + z: 0.0 + w: 0.999999587267 + covariance: [6.6461358273646, -1.2636131845770824e-08, 0.0, 0.0, -3.5843337853883538e-06, 0.0, -1.2636131845770797e-08, 6.646135825062068, 0.0, 0.0, 9.228018464882356e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.5843337853883555e-06, 9.228018464882356e-06, 0.0, 0.0, 6.626136639460119, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 77 + stamp: + secs: 1624875202 + nsecs: 599704027 + frame_id: "/world" +pose: + pose: + position: + x: -0.0246557397701 + y: 0.0680612655764 + z: 0.0 + orientation: + x: 0.0 + y: 0.000148794474769 + z: 0.0 + w: 0.99999998893 + covariance: [6.757613583721207, -1.5035661073238473e-08, 0.0, 0.0, -3.364742899821791e-06, 0.0, -1.5035661073238433e-08, 6.757613581010451, 0.0, 0.0, 6.922522447066454e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.364742899821792e-06, 6.922522447066457e-06, 0.0, 0.0, 6.733409954662621, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 78 + stamp: + secs: 1624875202 + nsecs: 679709911 + frame_id: "/world" +pose: + pose: + position: + x: -0.0391279068951 + y: 0.0686073061185 + z: 0.0 + orientation: + x: 0.0 + y: 0.000241586721999 + z: 0.0 + w: 0.999999970818 + covariance: [9.121360969018584, -3.0099151060539856e-08, 0.0, 0.0, -5.616379266345125e-06, 0.0, -3.0099151060539776e-08, 9.121360963623529, 0.0, 0.0, 8.197711330131567e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.616379266345128e-06, 8.197711330131568e-06, 0.0, 0.0, 9.072211631705299, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 79 + stamp: + secs: 1624875202 + nsecs: 759694099 + frame_id: "/world" +pose: + pose: + position: + x: -0.0357354233791 + y: 0.0703866815002 + z: 0.0 + orientation: + x: -0.0 + y: -8.57534647727e-05 + z: -0.0 + w: 0.999999996323 + covariance: [7.517635917918099, -1.845248168703214e-08, 0.0, 0.0, -9.1783229220357e-06, 0.0, -1.8452481687032093e-08, 7.517635914602209, 0.0, 0.0, 5.182350111917112e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.1783229220357e-06, 5.182350111917112e-06, 0.0, 0.0, 7.487159214400504, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 80 + stamp: + secs: 1624875202 + nsecs: 839711905 + frame_id: "/world" +pose: + pose: + position: + x: -0.0358494481744 + y: 0.0733075810375 + z: 0.0 + orientation: + x: 0.0 + y: 0.000129061164933 + z: 0.0 + w: 0.999999991672 + covariance: [7.0448275793123525, -1.8677459267813282e-08, 0.0, 0.0, -1.1823782523226391e-05, 0.0, -1.8677459267813226e-08, 7.044827575879366, 0.0, 0.0, 5.142632493651937e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1823782523226395e-05, 5.142632493651941e-06, 0.0, 0.0, 7.013503044290827, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 81 + stamp: + secs: 1624875202 + nsecs: 919713974 + frame_id: "/world" +pose: + pose: + position: + x: -0.0319756613284 + y: 0.0836901609972 + z: 0.0 + orientation: + x: -0.0 + y: -8.64613818563e-06 + z: -0.0 + w: 0.999999999963 + covariance: [8.318771696901253, -2.1501370798348492e-08, 0.0, 0.0, -1.3802808737078841e-05, 0.0, -2.1501370798348432e-08, 8.318771692873073, 0.0, 0.0, 3.786312426854718e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3802808737078838e-05, 3.7863124268547194e-06, 0.0, 0.0, 8.282280046217688, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 82 + stamp: + secs: 1624875202 + nsecs: 999722004 + frame_id: "/world" +pose: + pose: + position: + x: -0.0334419058191 + y: 0.0839242132844 + z: 0.0 + orientation: + x: -0.0 + y: -0.000124270968843 + z: -0.0 + w: 0.999999992278 + covariance: [7.285612154395065, -1.6342063560385515e-08, 0.0, 0.0, -1.0141404376069271e-05, 0.0, -1.6342063560385462e-08, 7.285612151289366, 0.0, 0.0, 8.922283412928617e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0141404376069268e-05, 8.922283412928615e-06, 0.0, 0.0, 7.25751311151408, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 83 + stamp: + secs: 1624875203 + nsecs: 79710960 + frame_id: "/world" +pose: + pose: + position: + x: -0.0303143634306 + y: 0.0833411030182 + z: 0.0 + orientation: + x: -0.0 + y: -0.000128054513425 + z: -0.0 + w: 0.999999991801 + covariance: [8.431441274547014, -1.95115995774335e-08, 0.0, 0.0, -1.1274742519905508e-05, 0.0, -1.9511599577433442e-08, 8.4314412708876, 0.0, 0.0, 1.594044930932453e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1274742519905505e-05, 1.5940449309324528e-05, 0.0, 0.0, 8.397533699243569, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 84 + stamp: + secs: 1624875203 + nsecs: 159800053 + frame_id: "/world" +pose: + pose: + position: + x: -0.0333926767638 + y: 0.0837905940273 + z: 0.0 + orientation: + x: -0.0 + y: -4.15998685284e-06 + z: -0.0 + w: 0.999999999991 + covariance: [7.314944221099614, -1.318445115279974e-08, 0.0, 0.0, -9.331533933212873e-06, 0.0, -1.31844511527997e-08, 7.314944218648792, 0.0, 0.0, 9.750010452442614e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.331533933212872e-06, 9.750010452442615e-06, 0.0, 0.0, 7.291785464543493, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 85 + stamp: + secs: 1624875203 + nsecs: 239774942 + frame_id: "/world" +pose: + pose: + position: + x: -0.0360141124574 + y: 0.0790400687962 + z: 0.0 + orientation: + x: 0.0 + y: 0.000293510242743 + z: 0.0 + w: 0.999999956926 + covariance: [6.978099933885809, -1.4952354418531818e-08, 0.0, 0.0, -1.0655198054753374e-05, 0.0, -1.4952354418531775e-08, 6.9780999311261, 0.0, 0.0, 9.98428926432431e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0655198054753369e-05, 9.98428926432431e-06, 0.0, 0.0, 6.951495230131825, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 86 + stamp: + secs: 1624875203 + nsecs: 319755077 + frame_id: "/world" +pose: + pose: + position: + x: -0.0355504228923 + y: 0.077667870848 + z: 0.0 + orientation: + x: 0.0 + y: 0.000376245096193 + z: 0.0 + w: 0.99999992922 + covariance: [7.504243794219253, -1.2935522286394913e-08, 0.0, 0.0, -1.1915271432441385e-05, 0.0, -1.2935522286394876e-08, 7.5042437918469505, 0.0, 0.0, 1.1468752133489334e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1915271432441378e-05, 1.1468752133489331e-05, 0.0, 0.0, 7.481082809492836, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 87 + stamp: + secs: 1624875203 + nsecs: 399734974 + frame_id: "/world" +pose: + pose: + position: + x: -0.0349862402678 + y: 0.0739927356118 + z: 0.0 + orientation: + x: 0.0 + y: 0.000607947744483 + z: 0.0 + w: 0.9999998152 + covariance: [7.713897496531171, -1.5901087807584802e-08, 0.0, 0.0, -1.8105505661713887e-05, 0.0, -1.590108780758476e-08, 7.713897493613873, 0.0, 0.0, 1.4801147127398404e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8105505661713887e-05, 1.4801147127398399e-05, 0.0, 0.0, 7.685198230770616, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 88 + stamp: + secs: 1624875203 + nsecs: 479762077 + frame_id: "/world" +pose: + pose: + position: + x: -0.0347605880696 + y: 0.0701045180516 + z: 0.0 + orientation: + x: 0.0 + y: 0.000505360135904 + z: 0.0 + w: 0.999999872306 + covariance: [7.101440844022547, -1.419990563435143e-08, 0.0, 0.0, -1.3402881791117292e-05, 0.0, -1.4199905634351396e-08, 7.101440841400693, 0.0, 0.0, 1.0734608052494551e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.340288179111729e-05, 1.073460805249455e-05, 0.0, 0.0, 7.075585879977653, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 89 + stamp: + secs: 1624875203 + nsecs: 559773922 + frame_id: "/world" +pose: + pose: + position: + x: -0.0280624079141 + y: 0.0599279721018 + z: 0.0 + orientation: + x: 0.0 + y: 0.000294375979358 + z: 0.0 + w: 0.999999956671 + covariance: [8.33925833512028, -1.4982528737658184e-08, 0.0, 0.0, -1.0793047900885696e-05, 0.0, -1.4982528737658145e-08, 8.33925833234873, 0.0, 0.0, 9.173222276566887e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0793047900885698e-05, 9.173222276566883e-06, 0.0, 0.0, 8.311750911733496, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 90 + stamp: + secs: 1624875203 + nsecs: 639780045 + frame_id: "/world" +pose: + pose: + position: + x: -0.0335914191368 + y: 0.068271664857 + z: 0.0 + orientation: + x: 0.0 + y: 0.000299552264821 + z: 0.0 + w: 0.999999955134 + covariance: [10.039272299912353, -2.764161774070556e-08, 0.0, 0.0, -1.5610417568628978e-05, 0.0, -2.7641617740705484e-08, 10.039272294772228, 0.0, 0.0, 1.0877050641572195e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.561041756862898e-05, 1.087705064157219e-05, 0.0, 0.0, 9.987924799465647, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 91 + stamp: + secs: 1624875203 + nsecs: 719793081 + frame_id: "/world" +pose: + pose: + position: + x: -0.0374426645985 + y: 0.0911020852136 + z: 0.0 + orientation: + x: 0.0 + y: 0.000196891644747 + z: 0.0 + w: 0.999999980617 + covariance: [9.639342151606105, -2.35957948317196e-08, 0.0, 0.0, -1.1672919145424246e-05, 0.0, -2.3595794831719533e-08, 9.63934214720756, 0.0, 0.0, 9.183323248734129e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.167291914542425e-05, 9.183323248734127e-06, 0.0, 0.0, 9.59505936700601, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 92 + stamp: + secs: 1624875203 + nsecs: 799793005 + frame_id: "/world" +pose: + pose: + position: + x: -0.0375681665693 + y: 0.0913249069635 + z: 0.0 + orientation: + x: 0.0 + y: 0.000226810757925 + z: 0.0 + w: 0.999999974278 + covariance: [9.482085923006688, -2.6060272628416725e-08, 0.0, 0.0, -9.934435716555884e-06, 0.0, -2.606027262841666e-08, 9.48208591814944, 0.0, 0.0, 9.88806944555719e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.934435716555889e-06, 9.888069445557187e-06, 0.0, 0.0, 9.432571381436997, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 93 + stamp: + secs: 1624875203 + nsecs: 879812002 + frame_id: "/world" +pose: + pose: + position: + x: -0.0334300742323 + y: 0.0806404033139 + z: 0.0 + orientation: + x: 0.0 + y: 0.000223402172281 + z: 0.0 + w: 0.999999975046 + covariance: [8.433778160851855, -2.629951011160394e-08, 0.0, 0.0, -4.844915937276256e-05, 0.0, -2.6299510111603877e-08, 8.433778155450582, 0.0, 0.0, 9.269780866550429e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.8449159372762576e-05, 9.269780866550427e-06, 0.0, 0.0, 8.383086340861613, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 94 + stamp: + secs: 1624875203 + nsecs: 959813118 + frame_id: "/world" +pose: + pose: + position: + x: -0.0336253723319 + y: 0.0805512368916 + z: 0.0 + orientation: + x: 0.0 + y: 9.42333835948e-05 + z: 0.0 + w: 0.99999999556 + covariance: [8.045179990062792, -1.4100781995689595e-08, 0.0, 0.0, -3.517744781753176e-05, 0.0, -1.4100781995689559e-08, 8.045179986809439, 0.0, 0.0, 4.873501403325072e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.5177447817531774e-05, 4.873501403325073e-06, 0.0, 0.0, 8.017902386431224, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 95 + stamp: + secs: 1624875204 + nsecs: 39814949 + frame_id: "/world" +pose: + pose: + position: + x: -0.0334344133328 + y: 0.0802346128939 + z: 0.0 + orientation: + x: 0.0 + y: 0.000279779220882 + z: 0.0 + w: 0.999999960862 + covariance: [7.921664405493227, -1.8614460351733513e-08, 0.0, 0.0, -5.850218631517861e-05, 0.0, -1.861446035173346e-08, 7.921664399043073, 0.0, 0.0, 7.040418938267963e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.8502186315178614e-05, 7.040418938267966e-06, 0.0, 0.0, 7.885373897412788, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 96 + stamp: + secs: 1624875204 + nsecs: 119822979 + frame_id: "/world" +pose: + pose: + position: + x: -0.0330891247788 + y: 0.0797503087314 + z: 0.0 + orientation: + x: 0.0 + y: 5.24634781386e-05 + z: 0.0 + w: 0.999999998624 + covariance: [8.746755316105848, -3.0247501594423685e-08, 0.0, 0.0, -7.565537696330997e-05, 0.0, -3.024750159442359e-08, 8.746755302479208, 0.0, 0.0, 1.5179242466294636e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.565537696330998e-05, 1.5179242466294638e-05, 0.0, 0.0, 8.687530581197112, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 97 + stamp: + secs: 1624875204 + nsecs: 199822903 + frame_id: "/world" +pose: + pose: + position: + x: -0.0348103293266 + y: 0.080537289134 + z: 0.0 + orientation: + x: 0.0 + y: 1.57452694423e-05 + z: 0.0 + w: 0.999999999876 + covariance: [7.416206619207253, -1.9980174270606337e-08, 0.0, 0.0, -3.75835439344141e-05, 0.0, -1.9980174270606288e-08, 7.4162066093967285, 0.0, 0.0, 9.768748634105246e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.758354393441413e-05, 9.768748634105249e-06, 0.0, 0.0, 7.3768559733558074, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 98 + stamp: + secs: 1624875204 + nsecs: 279830933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0426732865265 + y: 0.0632944030238 + z: 0.0 + orientation: + x: 0.0 + y: 0.000435899205198 + z: 0.0 + w: 0.999999904996 + covariance: [9.509712700464613, -2.907689202292338e-08, 0.0, 0.0, -3.798967154278551e-05, 0.0, -2.9076892022923294e-08, 9.509712685214032, 0.0, 0.0, 1.2972023288238188e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.798967154278552e-05, 1.2972023288238194e-05, 0.0, 0.0, 9.452222309105554, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 99 + stamp: + secs: 1624875204 + nsecs: 359844923 + frame_id: "/world" +pose: + pose: + position: + x: -0.0364095085237 + y: 0.0735433905239 + z: 0.0 + orientation: + x: 0.0 + y: 0.000302572321777 + z: 0.0 + w: 0.999999954225 + covariance: [7.62001667319008, -1.3378280079389074e-08, 0.0, 0.0, -1.4994116984846813e-05, 0.0, -1.3378280079389032e-08, 7.620016666000185, 0.0, 0.0, 5.724949435110537e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4994116984846822e-05, 5.7249494351105385e-06, 0.0, 0.0, 7.593463948315021, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 100 + stamp: + secs: 1624875204 + nsecs: 439868927 + frame_id: "/world" +pose: + pose: + position: + x: -0.0313737162804 + y: 0.0760022367155 + z: 0.0 + orientation: + x: 0.0 + y: 0.000506162606537 + z: 0.0 + w: 0.9999998719 + covariance: [7.769324931388732, -2.0662753242132215e-08, 0.0, 0.0, -1.4849010551710104e-05, 0.0, -2.0662753242132162e-08, 7.769324919759799, 0.0, 0.0, 5.980376331816624e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4849010551710111e-05, 5.980376331816627e-06, 0.0, 0.0, 7.727817200270315, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 101 + stamp: + secs: 1624875204 + nsecs: 519855022 + frame_id: "/world" +pose: + pose: + position: + x: -0.031551637875 + y: 0.0725291640665 + z: 0.0 + orientation: + x: 0.0 + y: 0.000290982160143 + z: 0.0 + w: 0.999999957665 + covariance: [7.115523193047412, -1.315038054970947e-08, 0.0, 0.0, -7.1096587583041725e-06, 0.0, -1.3150380549709435e-08, 7.115523185551469, 0.0, 0.0, 4.059976341087383e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.109658758304175e-06, 4.059976341087384e-06, 0.0, 0.0, 7.088808932343369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 102 + stamp: + secs: 1624875204 + nsecs: 599853039 + frame_id: "/world" +pose: + pose: + position: + x: -0.0323597773349 + y: 0.0696835169043 + z: 0.0 + orientation: + x: -0.0 + y: -0.000106701835415 + z: -0.0 + w: 0.999999994307 + covariance: [7.573943875723878, -1.9028743410787258e-08, 0.0, 0.0, -1.4372466872498991e-05, 0.0, -1.90287434107872e-08, 7.5739438646998645, 0.0, 0.0, 6.8748125203851776e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4372466872498993e-05, 6.874812520385176e-06, 0.0, 0.0, 7.534610411005288, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 103 + stamp: + secs: 1624875204 + nsecs: 679869890 + frame_id: "/world" +pose: + pose: + position: + x: -0.03228643597 + y: 0.109915818393 + z: 0.0 + orientation: + x: -0.0 + y: -0.000447712695107 + z: -0.0 + w: 0.999999899777 + covariance: [6.480988369349932, -9.671406094890439e-09, 0.0, 0.0, -8.33087495299004e-06, 0.0, -9.67140609489041e-09, 6.480988363702931, 0.0, 0.0, 3.694727035042329e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.330874952990043e-06, 3.694727035042329e-06, 0.0, 0.0, 6.460823805900393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 104 + stamp: + secs: 1624875204 + nsecs: 759877920 + frame_id: "/world" +pose: + pose: + position: + x: -0.0323303498459 + y: 0.110033152689 + z: 0.0 + orientation: + x: -0.0 + y: -2.00787093161e-05 + z: -0.0 + w: 0.999999999798 + covariance: [6.693914934352689, -7.735936145291188e-09, 0.0, 0.0, -5.931417913245355e-06, 0.0, -7.735936145291164e-09, 6.693914929798057, 0.0, 0.0, 2.8129797925213293e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.931417913245358e-06, 2.8129797925213284e-06, 0.0, 0.0, 6.677637570372443, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 105 + stamp: + secs: 1624875204 + nsecs: 839879036 + frame_id: "/world" +pose: + pose: + position: + x: -0.0369019408 + y: 0.0912384053109 + z: 0.0 + orientation: + x: -0.0 + y: -0.000178014710985 + z: -0.0 + w: 0.999999984155 + covariance: [7.402095031194055, -1.3693514381237084e-08, 0.0, 0.0, -1.33606260220477e-05, 0.0, -1.3693514381237045e-08, 7.402095023018279, 0.0, 0.0, 3.1850208178896675e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3360626022047705e-05, 3.1850208178896675e-06, 0.0, 0.0, 7.372820948617109, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 106 + stamp: + secs: 1624875204 + nsecs: 919888020 + frame_id: "/world" +pose: + pose: + position: + x: -0.0377105370856 + y: 0.0987327387627 + z: 0.0 + orientation: + x: -0.0 + y: -0.000387741925565 + z: -0.0 + w: 0.999999924828 + covariance: [6.987321788197188, -4.687965056701079e-09, 0.0, 0.0, -4.668391382497971e-06, 0.0, -4.687965056701063e-09, 6.987321785397244, 0.0, 0.0, 1.0611954546734462e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.668391382497971e-06, 1.0611954546734462e-06, 0.0, 0.0, 6.9772828530380036, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 107 + stamp: + secs: 1624875204 + nsecs: 999908924 + frame_id: "/world" +pose: + pose: + position: + x: -0.0371838858774 + y: 0.118426473796 + z: 0.0 + orientation: + x: -0.0 + y: -0.000100235213112 + z: -0.0 + w: 0.999999994976 + covariance: [8.28620479495662, -9.716063064200675e-09, 0.0, 0.0, -1.1998637802450901e-05, 0.0, -9.71606306420064e-09, 8.286204789043293, 0.0, 0.0, 2.3004634007116598e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1998637802450901e-05, 2.30046340071166e-06, 0.0, 0.0, 8.265107038820284, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 108 + stamp: + secs: 1624875205 + nsecs: 79900026 + frame_id: "/world" +pose: + pose: + position: + x: -0.0295876315872 + y: 0.118669524871 + z: 0.0 + orientation: + x: 0.0 + y: 0.000221306682333 + z: 0.0 + w: 0.999999975512 + covariance: [8.896149225125173, -1.7042592842124988e-08, 0.0, 0.0, -1.9703407152141874e-05, 0.0, -1.7042592842124925e-08, 8.896149214577948, 0.0, 0.0, 3.4618500107663594e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.970340715214187e-05, 3.4618500107663602e-06, 0.0, 0.0, 8.858579547283219, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 109 + stamp: + secs: 1624875205 + nsecs: 159907103 + frame_id: "/world" +pose: + pose: + position: + x: -0.0272439622515 + y: 0.120752394253 + z: 0.0 + orientation: + x: -0.0 + y: -0.000216381988245 + z: -0.0 + w: 0.999999976589 + covariance: [8.230910041996028, -2.0015263906443513e-08, 0.0, 0.0, -2.464919371328051e-05, 0.0, -2.0015263906443443e-08, 8.230910029432133, 0.0, 0.0, 7.478190350609672e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.464919371328051e-05, 7.478190350609667e-06, 0.0, 0.0, 8.186214640661008, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 110 + stamp: + secs: 1624875205 + nsecs: 239924908 + frame_id: "/world" +pose: + pose: + position: + x: -0.0300047123936 + y: 0.122337701584 + z: 0.0 + orientation: + x: -0.0 + y: -8.54557996142e-05 + z: -0.0 + w: 0.999999996349 + covariance: [7.267089404091235, -1.6983701117622025e-08, 0.0, 0.0, -1.929684868601596e-05, 0.0, -1.6983701117621962e-08, 7.267089393312902, 0.0, 0.0, 7.235859684014616e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9296848686015954e-05, 7.235859684014615e-06, 0.0, 0.0, 7.2287205260432135, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 111 + stamp: + secs: 1624875205 + nsecs: 319930077 + frame_id: "/world" +pose: + pose: + position: + x: -0.0254589001811 + y: 0.119233956743 + z: 0.0 + orientation: + x: 0.0 + y: 0.00121346093124 + z: 0.0 + w: 0.999999263756 + covariance: [8.527085347302895, -6.211006211196333e-08, 0.0, 0.0, -3.9416274697805474e-05, 0.0, -6.211006211196311e-08, 8.527085307316467, 0.0, 0.0, 1.646837849440847e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.941627469780548e-05, 1.646837849440847e-05, 0.0, 0.0, 8.384022995161962, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 112 + stamp: + secs: 1624875205 + nsecs: 399924994 + frame_id: "/world" +pose: + pose: + position: + x: -0.0191717968258 + y: 0.112081331784 + z: 0.0 + orientation: + x: 0.0 + y: 0.00050703342535 + z: 0.0 + w: 0.999999871459 + covariance: [8.205524875819822, -7.948871951901189e-08, 0.0, 0.0, -3.113575069020661e-05, 0.0, -7.948871951901161e-08, 8.205524824426247, 0.0, 0.0, 1.3754513718484028e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.113575069020662e-05, 1.375451371848403e-05, 0.0, 0.0, 8.01831685956801, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 113 + stamp: + secs: 1624875205 + nsecs: 479929924 + frame_id: "/world" +pose: + pose: + position: + x: -0.019027565437 + y: 0.112177657429 + z: 0.0 + orientation: + x: 0.0 + y: 0.000822530400298 + z: 0.0 + w: 0.999999661722 + covariance: [11.441073211862467, -1.0316439306056284e-07, 0.0, 0.0, -3.12743268416472e-05, 0.0, -1.0316439306056246e-07, 11.44107314508102, 0.0, 0.0, 1.4195929844540016e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.127432684164722e-05, 1.419592984454002e-05, 0.0, 0.0, 11.196687897264052, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 114 + stamp: + secs: 1624875205 + nsecs: 559950113 + frame_id: "/world" +pose: + pose: + position: + x: -0.0210576933732 + y: 0.115665354138 + z: 0.0 + orientation: + x: 0.0 + y: 0.000270276464025 + z: 0.0 + w: 0.999999963475 + covariance: [8.13774550442011, -3.696702205566356e-08, 0.0, 0.0, -9.934176703571233e-06, 0.0, -3.696702205566345e-08, 8.137745480476646, 0.0, 0.0, 4.359854061065982e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.934176703571243e-06, 4.359854061065983e-06, 0.0, 0.0, 8.049011402189779, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 115 + stamp: + secs: 1624875205 + nsecs: 639954090 + frame_id: "/world" +pose: + pose: + position: + x: -0.0164297639932 + y: 0.107676307495 + z: 0.0 + orientation: + x: -0.0 + y: -5.65932394491e-06 + z: -0.0 + w: 0.999999999984 + covariance: [11.387100179643973, -6.911797980429505e-08, 0.0, 0.0, -1.639183956934392e-05, 0.0, -6.911797980429483e-08, 11.387100134818729, 0.0, 0.0, 1.0726704392408861e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.6391839569343927e-05, 1.0726704392408861e-05, 0.0, 0.0, 11.219362372714695, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 116 + stamp: + secs: 1624875205 + nsecs: 719960928 + frame_id: "/world" +pose: + pose: + position: + x: -0.0213398656461 + y: 0.114773469669 + z: 0.0 + orientation: + x: 0.0 + y: 6.31732850517e-05 + z: 0.0 + w: 0.999999998005 + covariance: [9.01729915379195, -2.4985298102972893e-08, 0.0, 0.0, -6.866929554495262e-06, 0.0, -2.498529810297281e-08, 9.017299137584967, 0.0, 0.0, 4.271105721858221e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.866929554495267e-06, 4.27110572185822e-06, 0.0, 0.0, 8.956213470836927, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 117 + stamp: + secs: 1624875205 + nsecs: 799964905 + frame_id: "/world" +pose: + pose: + position: + x: -0.0150689309174 + y: 0.119041533162 + z: 0.0 + orientation: + x: -0.0 + y: -0.000747142303102 + z: -0.0 + w: 0.999999720889 + covariance: [10.446460046645145, -4.0231689299839674e-08, 0.0, 0.0, -1.7154389453283383e-05, 0.0, -4.0231689299839535e-08, 10.44646002048617, 0.0, 0.0, 7.874826912710021e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.715438945328339e-05, 7.87482691271002e-06, 0.0, 0.0, 10.346312721684747, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 118 + stamp: + secs: 1624875205 + nsecs: 879976034 + frame_id: "/world" +pose: + pose: + position: + x: -0.0152028905119 + y: 0.118913917244 + z: 0.0 + orientation: + x: 0.0 + y: 0.000154696188932 + z: 0.0 + w: 0.999999988035 + covariance: [7.173005164257486, -1.5223530251365087e-08, 0.0, 0.0, -5.9585109362328016e-06, 0.0, -1.522353025136503e-08, 7.173005154350345, 0.0, 0.0, 2.734125064774302e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.958510936232805e-06, 2.734125064774304e-06, 0.0, 0.0, 7.134628513457068, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 119 + stamp: + secs: 1624875205 + nsecs: 959978104 + frame_id: "/world" +pose: + pose: + position: + x: -0.00801960073402 + y: 0.100663937289 + z: 0.0 + orientation: + x: 0.0 + y: 0.000629390214359 + z: 0.0 + w: 0.999999801934 + covariance: [6.945884318211814, -1.7463299561609653e-08, 0.0, 0.0, -5.793947836373753e-06, 0.0, -1.7463299561609587e-08, 6.945884306831183, 0.0, 0.0, 4.304443611337498e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.793947836373758e-06, 4.304443611337499e-06, 0.0, 0.0, 6.901133612232493, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 120 + stamp: + secs: 1624875206 + nsecs: 40004015 + frame_id: "/world" +pose: + pose: + position: + x: -0.00414912958592 + y: 0.0878300958002 + z: 0.0 + orientation: + x: 0.0 + y: 0.000438251637767 + z: 0.0 + w: 0.999999903968 + covariance: [7.4926129271462845, -1.2096210836197932e-08, 0.0, 0.0, -4.043765942228804e-06, 0.0, -1.2096210836197886e-08, 7.492612919262481, 0.0, 0.0, 3.4372724017956937e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.043765942228807e-06, 3.437272401795693e-06, 0.0, 0.0, 7.461317550273498, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 121 + stamp: + secs: 1624875206 + nsecs: 119993925 + frame_id: "/world" +pose: + pose: + position: + x: -0.0073795802927 + y: 0.0967339621749 + z: 0.0 + orientation: + x: -0.0 + y: -0.000439794111542 + z: -0.0 + w: 0.999999903291 + covariance: [7.701036946058357, -8.93633875679909e-09, 0.0, 0.0, -3.774665092942195e-06, 0.0, -8.936338756799057e-09, 7.701036940235576, 0.0, 0.0, 3.673966288812995e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.774665092942195e-06, 3.6739662888129945e-06, 0.0, 0.0, 7.677656206381975, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 122 + stamp: + secs: 1624875206 + nsecs: 199990988 + frame_id: "/world" +pose: + pose: + position: + x: 0.00590296657193 + y: 0.0870611630806 + z: 0.0 + orientation: + x: -0.0 + y: -0.000245233237902 + z: -0.0 + w: 0.99999996993 + covariance: [9.673842735264099, -1.7750030812507113e-08, 0.0, 0.0, -8.611322265545378e-06, 0.0, -1.7750030812507047e-08, 9.673842723715985, 0.0, 0.0, 8.398941009656522e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.61132226554538e-06, 8.398941009656518e-06, 0.0, 0.0, 9.62657252735015, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 123 + stamp: + secs: 1624875206 + nsecs: 280004025 + frame_id: "/world" +pose: + pose: + position: + x: 0.00604095125703 + y: 0.0870582844085 + z: 0.0 + orientation: + x: -0.0 + y: -0.00050761321999 + z: -0.0 + w: 0.999999871164 + covariance: [12.43677419595611, -2.6447421051599345e-08, 0.0, 0.0, -1.1174048995145272e-05, 0.0, -2.644742105159925e-08, 12.436774178763578, 0.0, 0.0, 1.0984735170862596e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1174048995145272e-05, 1.098473517086259e-05, 0.0, 0.0, 12.36575019592895, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 124 + stamp: + secs: 1624875206 + nsecs: 360021114 + frame_id: "/world" +pose: + pose: + position: + x: 0.00622219065922 + y: 0.0870520009727 + z: 0.0 + orientation: + x: -0.0 + y: -0.000699498887091 + z: -0.0 + w: 0.999999755351 + covariance: [14.372975523073068, -3.856813577255185e-08, 0.0, 0.0, -3.4103785618229964e-05, 0.0, -3.856813577255169e-08, 14.372975497948964, 0.0, 0.0, 1.5607064444001132e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.4103785618229964e-05, 1.5607064444001125e-05, 0.0, 0.0, 14.268464567103893, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 125 + stamp: + secs: 1624875206 + nsecs: 440040112 + frame_id: "/world" +pose: + pose: + position: + x: 0.00648388920499 + y: 0.087039142216 + z: 0.0 + orientation: + x: -0.0 + y: -0.000364052463476 + z: -0.0 + w: 0.999999933733 + covariance: [15.698147203980811, -6.205182949796135e-08, 0.0, 0.0, -8.625247049311097e-05, 0.0, -6.205182949796108e-08, 15.698147162920892, 0.0, 0.0, 2.2846529007194405e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.625247049311096e-05, 2.2846529007194394e-05, 0.0, 0.0, 15.52835409385362, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 126 + stamp: + secs: 1624875206 + nsecs: 520046949 + frame_id: "/world" +pose: + pose: + position: + x: 0.00673856730769 + y: 0.0870258019752 + z: 0.0 + orientation: + x: -0.0 + y: -0.000219481712455 + z: -0.0 + w: 0.999999975914 + covariance: [16.562788976924928, -8.196982293205892e-08, 0.0, 0.0, -0.00011212846635116913, 0.0, -8.196982293205858e-08, 16.562788921847304, 0.0, 0.0, 2.520918204595399e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001121284663511691, 2.5209182045953984e-05, 0.0, 0.0, 16.336381408256706, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 127 + stamp: + secs: 1624875206 + nsecs: 600040913 + frame_id: "/world" +pose: + pose: + position: + x: -0.0118226743684 + y: 0.125534539005 + z: 0.0 + orientation: + x: -0.0 + y: -0.000179863940087 + z: -0.0 + w: 0.999999983824 + covariance: [11.98557641008186, -4.735377711478341e-08, 0.0, 0.0, -6.182260793324025e-05, 0.0, -4.735377711478322e-08, 11.985576377936805, 0.0, 0.0, 1.2120700309714208e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.182260793324025e-05, 1.2120700309714203e-05, 0.0, 0.0, 11.852829574845542, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 128 + stamp: + secs: 1624875206 + nsecs: 680032969 + frame_id: "/world" +pose: + pose: + position: + x: -0.00358778358862 + y: 0.121348575434 + z: 0.0 + orientation: + x: -0.0 + y: -0.00021148952336 + z: -0.0 + w: 0.999999977636 + covariance: [12.002886937248846, -5.137843157222523e-08, 0.0, 0.0, -5.9351638173244137e-05, 0.0, -5.1378431572225e-08, 12.00288690192099, 0.0, 0.0, 1.8407112533970862e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.935163817324413e-05, 1.8407112533970856e-05, 0.0, 0.0, 11.857166640922612, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 129 + stamp: + secs: 1624875206 + nsecs: 760040998 + frame_id: "/world" +pose: + pose: + position: + x: -0.0034342642929 + y: 0.121457433822 + z: 0.0 + orientation: + x: -0.0 + y: -0.000203036045378 + z: -0.0 + w: 0.999999979388 + covariance: [14.110864609412767, -6.561860154883016e-08, 0.0, 0.0, -6.286107217317734e-05, 0.0, -6.561860154882986e-08, 14.110864564015765, 0.0, 0.0, 2.680153089562183e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.286107217317735e-05, 2.680153089562182e-05, 0.0, 0.0, 13.923339626447135, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 130 + stamp: + secs: 1624875206 + nsecs: 840075016 + frame_id: "/world" +pose: + pose: + position: + x: -0.00324231239711 + y: 0.121585841705 + z: 0.0 + orientation: + x: -0.0 + y: -0.000292935295582 + z: -0.0 + w: 0.999999957094 + covariance: [15.54312003188267, -8.304185618653361e-08, 0.0, 0.0, -6.592128498099272e-05, 0.0, -8.304185618653324e-08, 15.54311997410282, 0.0, 0.0, 2.921173627178575e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.592128498099274e-05, 2.921173627178575e-05, 0.0, 0.0, 15.30349213562298, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 131 + stamp: + secs: 1624875206 + nsecs: 920078039 + frame_id: "/world" +pose: + pose: + position: + x: -0.00302361249356 + y: 0.121731778987 + z: 0.0 + orientation: + x: -0.0 + y: -0.000450632305206 + z: -0.0 + w: 0.999999898465 + covariance: [16.497130769741215, -1.0409295814226703e-07, 0.0, 0.0, -8.077191472153303e-05, 0.0, -1.0409295814226658e-07, 16.497130697044557, 0.0, 0.0, 4.856964973052148e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.077191472153306e-05, 4.856964973052148e-05, 0.0, 0.0, 16.193760451356805, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 132 + stamp: + secs: 1624875207 + nsecs: 104904 + frame_id: "/world" +pose: + pose: + position: + x: -0.00285189389597 + y: 0.121843772701 + z: 0.0 + orientation: + x: -0.0 + y: -0.00039333393658 + z: -0.0 + w: 0.999999922644 + covariance: [17.07133732929121, -1.0780789463311362e-07, 0.0, 0.0, -0.00011627017603990898, 0.0, -1.0780789463311314e-07, 17.07133725356757, 0.0, 0.0, 6.163202288238802e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011627017603990895, 6.163202288238802e-05, 0.0, 0.0, 16.755001242382612, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 133 + stamp: + secs: 1624875207 + nsecs: 80077887 + frame_id: "/world" +pose: + pose: + position: + x: -0.000899907061973 + y: 0.101518237692 + z: 0.0 + orientation: + x: 0.0 + y: 0.000278561093999 + z: 0.0 + w: 0.999999961202 + covariance: [17.453667445252414, -1.1853761274752016e-07, 0.0, 0.0, -0.00016843024170309969, 0.0, -1.1853761274751966e-07, 17.45366736053163, 0.0, 0.0, 6.896404912057336e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00016843024170309966, 6.896404912057336e-05, 0.0, 0.0, 17.103765371456525, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 134 + stamp: + secs: 1624875207 + nsecs: 160103083 + frame_id: "/world" +pose: + pose: + position: + x: -0.00103902445065 + y: 0.101253517056 + z: 0.0 + orientation: + x: 0.0 + y: 5.84115800298e-05 + z: 0.0 + w: 0.999999998294 + covariance: [12.273625864956246, -6.271352525529773e-08, 0.0, 0.0, -0.0001137816747960645, 0.0, -6.271352525529745e-08, 12.273625818985993, 0.0, 0.0, 3.4367307116886763e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001137816747960645, 3.436730711688677e-05, 0.0, 0.0, 12.08590181160497, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 135 + stamp: + secs: 1624875207 + nsecs: 240103006 + frame_id: "/world" +pose: + pose: + position: + x: -0.000390043920062 + y: 0.101927319247 + z: 0.0 + orientation: + x: -0.0 + y: -0.000336182994033 + z: -0.0 + w: 0.99999994349 + covariance: [10.562844906216656, -4.9939961183818776e-08, 0.0, 0.0, -0.00010868681370867, 0.0, -4.993996118381856e-08, 10.562844868391801, 0.0, 0.0, 5.461641748247413e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00010868681370866999, 5.4616417482474135e-05, 0.0, 0.0, 10.413738693653256, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 136 + stamp: + secs: 1624875207 + nsecs: 320096970 + frame_id: "/world" +pose: + pose: + position: + x: 0.00127437919955 + y: 0.0816681951608 + z: 0.0 + orientation: + x: 0.0 + y: 0.000112415035063 + z: 0.0 + w: 0.999999993681 + covariance: [7.208099421191652, -1.987133450625604e-08, 0.0, 0.0, -4.144300592438179e-05, 0.0, -1.987133450625596e-08, 7.208099406236338, 0.0, 0.0, 3.270464772036236e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.144300592438176e-05, 3.270464772036236e-05, 0.0, 0.0, 7.149154372130515, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 137 + stamp: + secs: 1624875207 + nsecs: 400090933 + frame_id: "/world" +pose: + pose: + position: + x: -0.00289825132248 + y: 0.0525498229613 + z: 0.0 + orientation: + x: 0.0 + y: 7.18132574679e-05 + z: 0.0 + w: 0.999999997421 + covariance: [8.412196626844693, -2.26810057297239e-08, 0.0, 0.0, -4.313746439650783e-05, 0.0, -2.2681005729723805e-08, 8.412196610223987, 0.0, 0.0, 4.2618769181704716e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.313746439650783e-05, 4.261876918170472e-05, 0.0, 0.0, 8.346581736285472, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 138 + stamp: + secs: 1624875207 + nsecs: 480118990 + frame_id: "/world" +pose: + pose: + position: + x: 0.00720479302003 + y: 0.0443325749279 + z: 0.0 + orientation: + x: -0.0 + y: -1.55225316731e-05 + z: -0.0 + w: 0.99999999988 + covariance: [8.928652463750794, -1.1724424424484668e-08, 0.0, 0.0, -2.2108597970937403e-05, 0.0, -1.1724424424484618e-08, 8.928652455190523, 0.0, 0.0, 2.203688228467378e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.21085979709374e-05, 2.203688228467378e-05, 0.0, 0.0, 8.894787787891726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 139 + stamp: + secs: 1624875207 + nsecs: 560122967 + frame_id: "/world" +pose: + pose: + position: + x: -0.0128096386582 + y: 0.0378178580138 + z: 0.0 + orientation: + x: -0.0 + y: -8.07911457483e-05 + z: -0.0 + w: 0.999999996736 + covariance: [6.8336848919233, -1.0477567063887202e-08, 0.0, 0.0, -1.4151740789859036e-05, 0.0, -1.0477567063887161e-08, 6.833684884585229, 0.0, 0.0, 1.5226295966830767e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.415174078985903e-05, 1.5226295966830768e-05, 0.0, 0.0, 6.80412691156414, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 140 + stamp: + secs: 1624875207 + nsecs: 640136957 + frame_id: "/world" +pose: + pose: + position: + x: -0.0149143323978 + y: 0.0415490026648 + z: 0.0 + orientation: + x: -0.0 + y: -0.000222483247492 + z: -0.0 + w: 0.999999975251 + covariance: [7.466843865013546, -1.569206218808295e-08, 0.0, 0.0, -1.2777970616101708e-05, 0.0, -1.569206218808288e-08, 7.466843854346528, 0.0, 0.0, 1.4216596824294303e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2777970616101698e-05, 1.4216596824294303e-05, 0.0, 0.0, 7.423020443978329, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 141 + stamp: + secs: 1624875207 + nsecs: 720158100 + frame_id: "/world" +pose: + pose: + position: + x: -0.014823062599 + y: 0.0413551887415 + z: 0.0 + orientation: + x: -0.0 + y: -3.37122084418e-05 + z: -0.0 + w: 0.999999999432 + covariance: [9.553263868468989, -2.6688680375918763e-08, 0.0, 0.0, -3.835948170575854e-05, 0.0, -2.6688680375918644e-08, 9.553263850427031, 0.0, 0.0, 1.863547431942443e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.835948170575853e-05, 1.863547431942443e-05, 0.0, 0.0, 9.479063959603724, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 142 + stamp: + secs: 1624875207 + nsecs: 800143957 + frame_id: "/world" +pose: + pose: + position: + x: -0.0147698730563 + y: 0.0412368251038 + z: 0.0 + orientation: + x: 0.0 + y: 6.13761816821e-05 + z: 0.0 + w: 0.999999998116 + covariance: [9.443064280565821, -2.1318077353931887e-08, 0.0, 0.0, -4.5051341660735395e-05, 0.0, -2.131807735393178e-08, 9.443064265887031, 0.0, 0.0, 1.546688931973036e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.5051341660735395e-05, 1.5466889319730363e-05, 0.0, 0.0, 9.383922568145994, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 143 + stamp: + secs: 1624875207 + nsecs: 880158901 + frame_id: "/world" +pose: + pose: + position: + x: -0.0146794294455 + y: 0.041025942505 + z: 0.0 + orientation: + x: 0.0 + y: 2.56824550383e-05 + z: 0.0 + w: 0.99999999967 + covariance: [9.418669112098017, -2.7242793037898744e-08, 0.0, 0.0, -8.908288263019422e-05, 0.0, -2.7242793037898608e-08, 9.418669091703258, 0.0, 0.0, 2.103907998509946e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.908288263019419e-05, 2.1039079985099462e-05, 0.0, 0.0, 9.343869076775565, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 144 + stamp: + secs: 1624875207 + nsecs: 960160017 + frame_id: "/world" +pose: + pose: + position: + x: -0.0135377177133 + y: 0.037605237358 + z: 0.0 + orientation: + x: 0.0 + y: 7.22420081113e-05 + z: 0.0 + w: 0.999999997391 + covariance: [6.946199450456184, -1.3227450350216998e-08, 0.0, 0.0, -4.7335576120779765e-05, 0.0, -1.3227450350216937e-08, 6.946199439813389, 0.0, 0.0, 1.0948916472548836e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.733557612077979e-05, 1.0948916472548836e-05, 0.0, 0.0, 6.910079001408521, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 145 + stamp: + secs: 1624875208 + nsecs: 40215015 + frame_id: "/world" +pose: + pose: + position: + x: -0.0128195939237 + y: 0.042806257001 + z: 0.0 + orientation: + x: 0.0 + y: 0.000119064320668 + z: 0.0 + w: 0.999999992912 + covariance: [6.8769808631577405, -1.833722385114722e-08, 0.0, 0.0, -4.8028451951369065e-05, 0.0, -1.8337223851147134e-08, 6.876980846675615, 0.0, 0.0, 1.4201792930430281e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.8028451951369085e-05, 1.4201792930430286e-05, 0.0, 0.0, 6.8277012541151505, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 146 + stamp: + secs: 1624875208 + nsecs: 120165110 + frame_id: "/world" +pose: + pose: + position: + x: -0.015793247659 + y: 0.0427431204849 + z: 0.0 + orientation: + x: 0.0 + y: 7.89602271637e-05 + z: 0.0 + w: 0.999999996883 + covariance: [6.824536148661112, -8.935442863584124e-09, 0.0, 0.0, -2.1303478040974663e-05, 0.0, -8.935442863584079e-09, 6.824536140481649, 0.0, 0.0, 6.469423811725233e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.130347804097467e-05, 6.469423811725235e-06, 0.0, 0.0, 6.800542259752465, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 147 + stamp: + secs: 1624875208 + nsecs: 200181961 + frame_id: "/world" +pose: + pose: + position: + x: -0.0181206641222 + y: 0.0418335898525 + z: 0.0 + orientation: + x: 0.0 + y: 0.0001691767861 + z: 0.0 + w: 0.99999998569 + covariance: [6.822896802966476, -1.172489813112443e-08, 0.0, 0.0, -2.3567356382524365e-05, 0.0, -1.1724898131124386e-08, 6.822896791598783, 0.0, 0.0, 6.277272593692823e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.356735638252437e-05, 6.277272593692824e-06, 0.0, 0.0, 6.791585393541631, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 148 + stamp: + secs: 1624875208 + nsecs: 280190945 + frame_id: "/world" +pose: + pose: + position: + x: -0.0114746649269 + y: 0.0399861298173 + z: 0.0 + orientation: + x: 0.0 + y: 6.25935319439e-05 + z: 0.0 + w: 0.999999998041 + covariance: [7.436668502707751, -6.96273578148777e-09, 0.0, 0.0, -1.2690245022702874e-05, 0.0, -6.962735781487745e-09, 7.436668495878887, 0.0, 0.0, 3.583747509979331e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2690245022702877e-05, 3.583747509979332e-06, 0.0, 0.0, 7.418049160128272, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 149 + stamp: + secs: 1624875208 + nsecs: 360193968 + frame_id: "/world" +pose: + pose: + position: + x: -0.0118367842192 + y: 0.0402448295915 + z: 0.0 + orientation: + x: 0.0 + y: 5.87744669989e-05 + z: 0.0 + w: 0.999999998273 + covariance: [7.677567474879912, -6.109812028818983e-09, 0.0, 0.0, -9.058449846653822e-06, 0.0, -6.1098120288189595e-09, 7.677567468775152, 0.0, 0.0, 2.8870314009206156e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.058449846653824e-06, 2.8870314009206156e-06, 0.0, 0.0, 7.661213300609898, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 150 + stamp: + secs: 1624875208 + nsecs: 440201998 + frame_id: "/world" +pose: + pose: + position: + x: -0.0117660978114 + y: 0.0400731898197 + z: 0.0 + orientation: + x: 0.0 + y: 0.000156091439701 + z: 0.0 + w: 0.999999987818 + covariance: [6.519531624775144, -9.315369936048031e-09, 0.0, 0.0, -7.461677622000863e-06, 0.0, -9.315369936048002e-09, 6.519531615252853, 0.0, 0.0, 2.5551696638479396e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.461677622000863e-06, 2.5551696638479383e-06, 0.0, 0.0, 6.494293773235496, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 151 + stamp: + secs: 1624875208 + nsecs: 520207882 + frame_id: "/world" +pose: + pose: + position: + x: -0.00830707602976 + y: 0.0319101061725 + z: 0.0 + orientation: + x: 0.0 + y: 0.000789109207757 + z: 0.0 + w: 0.999999688653 + covariance: [10.104087688943478, -1.9780659259029803e-08, 0.0, 0.0, -3.8125742951822444e-05, 0.0, -1.9780659259029727e-08, 10.104087668389345, 0.0, 0.0, 7.1031826286766625e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.812574295182243e-05, 7.103182628676659e-06, 0.0, 0.0, 10.050337764322126, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 152 + stamp: + secs: 1624875208 + nsecs: 600233078 + frame_id: "/world" +pose: + pose: + position: + x: -0.00798108363877 + y: 0.0309254449279 + z: 0.0 + orientation: + x: 0.0 + y: 9.9627700789e-05 + z: 0.0 + w: 0.999999995037 + covariance: [7.77877960755447, -8.605921583893514e-09, 0.0, 0.0, -2.5420089739485696e-05, 0.0, -8.605921583893489e-09, 7.778779598426011, 0.0, 0.0, 3.7428013481683887e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.54200897394857e-05, 3.742801348168388e-06, 0.0, 0.0, 7.755329523436467, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 153 + stamp: + secs: 1624875208 + nsecs: 680222988 + frame_id: "/world" +pose: + pose: + position: + x: -0.00465251031109 + y: 0.0416688568682 + z: 0.0 + orientation: + x: -0.0 + y: -0.000199636142007 + z: -0.0 + w: 0.999999980073 + covariance: [9.75932562145142, -3.252206519308464e-08, 0.0, 0.0, -0.00011377786124882633, 0.0, -3.252206519308453e-08, 9.75932558264222, 0.0, 0.0, 2.0772904785948194e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011377786124882636, 2.077290478594819e-05, 0.0, 0.0, 9.671461838633698, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 154 + stamp: + secs: 1624875208 + nsecs: 760227919 + frame_id: "/world" +pose: + pose: + position: + x: -0.00424379613653 + y: 0.0399870587937 + z: 0.0 + orientation: + x: 0.0 + y: 0.000162811533582 + z: 0.0 + w: 0.999999986746 + covariance: [6.45689552331072, -1.2026399411211204e-08, 0.0, 0.0, -3.761811464999286e-05, 0.0, -1.2026399411211159e-08, 6.456895508614034, 0.0, 0.0, 7.881078605519454e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.761811464999285e-05, 7.881078605519456e-06, 0.0, 0.0, 6.424317185702538, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 155 + stamp: + secs: 1624875208 + nsecs: 840251923 + frame_id: "/world" +pose: + pose: + position: + x: -0.00431322281044 + y: 0.0398971164949 + z: 0.0 + orientation: + x: 0.0 + y: 0.000419285998979 + z: 0.0 + w: 0.9999999121 + covariance: [6.723897587035414, -2.167886026853318e-08, 0.0, 0.0, -3.968381954455601e-05, 0.0, -2.1678860268533102e-08, 6.723897559220825, 0.0, 0.0, 1.1995946268085832e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.968381954455599e-05, 1.1995946268085827e-05, 0.0, 0.0, 6.665457954348747, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 156 + stamp: + secs: 1624875208 + nsecs: 920262098 + frame_id: "/world" +pose: + pose: + position: + x: -0.0194397291655 + y: 0.0457855225935 + z: 0.0 + orientation: + x: 0.0 + y: 0.00059028538488 + z: 0.0 + w: 0.999999825782 + covariance: [8.177748985634265, -2.3050020999189632e-08, 0.0, 0.0, -3.102764957761143e-05, 0.0, -2.305002099918955e-08, 8.177748955725175, 0.0, 0.0, 1.121717729421225e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.102764957761141e-05, 1.1217177294212246e-05, 0.0, 0.0, 8.11546869637249, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 157 + stamp: + secs: 1624875209 + nsecs: 256062 + frame_id: "/world" +pose: + pose: + position: + x: -0.022799208238 + y: 0.0640961202877 + z: 0.0 + orientation: + x: 0.0 + y: 0.000164304591471 + z: 0.0 + w: 0.999999986502 + covariance: [7.970174626408329, -1.806620810150319e-08, 0.0, 0.0, -1.785617020234456e-05, 0.0, -1.8066208101503122e-08, 7.970174602809171, 0.0, 0.0, 9.102517258967023e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7856170202344555e-05, 9.102517258967021e-06, 0.0, 0.0, 7.921067409416407, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 158 + stamp: + secs: 1624875209 + nsecs: 80250978 + frame_id: "/world" +pose: + pose: + position: + x: -0.0128529516545 + y: 0.0666497969411 + z: 0.0 + orientation: + x: 0.0 + y: 6.59608430512e-06 + z: 0.0 + w: 0.999999999978 + covariance: [7.192435082014609, -1.6092744115661282e-08, 0.0, 0.0, -1.2837964162613844e-05, 0.0, -1.609274411566122e-08, 7.192435060897825, 0.0, 0.0, 9.414629565172762e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2837964162613835e-05, 9.414629565172762e-06, 0.0, 0.0, 7.148339944325768, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 159 + stamp: + secs: 1624875209 + nsecs: 160267115 + frame_id: "/world" +pose: + pose: + position: + x: -0.00709496494856 + y: 0.0591973623407 + z: 0.0 + orientation: + x: 0.0 + y: 5.35825546367e-05 + z: 0.0 + w: 0.999999998564 + covariance: [6.935599725676636, -1.0980864186474564e-08, 0.0, 0.0, -8.85161870391562e-06, 0.0, -1.0980864186474526e-08, 6.935599711244111, 0.0, 0.0, 6.104560762904957e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.851618703915614e-06, 6.104560762904956e-06, 0.0, 0.0, 6.905335931120634, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 160 + stamp: + secs: 1624875209 + nsecs: 240287066 + frame_id: "/world" +pose: + pose: + position: + x: -0.00704366296217 + y: 0.0591708539645 + z: 0.0 + orientation: + x: 0.0 + y: 0.000270673281179 + z: 0.0 + w: 0.999999963368 + covariance: [8.286701073151663, -2.01395338418274e-08, 0.0, 0.0, -2.176702469744414e-05, 0.0, -2.013953384182733e-08, 8.28670104660332, 0.0, 0.0, 9.55985668628129e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.176702469744413e-05, 9.559856686281287e-06, 0.0, 0.0, 8.230845060153573, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 161 + stamp: + secs: 1624875209 + nsecs: 320278883 + frame_id: "/world" +pose: + pose: + position: + x: -0.00815993705308 + y: 0.0522132462525 + z: 0.0 + orientation: + x: 0.0 + y: 0.00111350575419 + z: 0.0 + w: 0.999999380052 + covariance: [8.059664631671845, -3.4515022172870804e-08, 0.0, 0.0, -5.309597041293203e-05, 0.0, -3.451502217287069e-08, 8.059664585794687, 0.0, 0.0, 2.0224659245168253e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.309597041293202e-05, 2.022465924516825e-05, 0.0, 0.0, 7.963233806229068, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 162 + stamp: + secs: 1624875209 + nsecs: 400302887 + frame_id: "/world" +pose: + pose: + position: + x: -0.00674425295535 + y: 0.0515928980872 + z: 0.0 + orientation: + x: 0.0 + y: 0.000322014702566 + z: 0.0 + w: 0.999999948153 + covariance: [7.215389769771783, -1.9288686350532923e-08, 0.0, 0.0, -2.9640276755799692e-05, 0.0, -1.928868635053286e-08, 7.215389744040491, 0.0, 0.0, 1.1888709420833739e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.964027675579968e-05, 1.188870942083374e-05, 0.0, 0.0, 7.161419847327116, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 163 + stamp: + secs: 1624875209 + nsecs: 480295897 + frame_id: "/world" +pose: + pose: + position: + x: -0.00535171029442 + y: 0.0444656954088 + z: 0.0 + orientation: + x: 0.0 + y: 0.000670480367451 + z: 0.0 + w: 0.999999775228 + covariance: [7.621855067512566, -2.1048786529035143e-08, 0.0, 0.0, -2.4997800392939763e-05, 0.0, -2.104878652903508e-08, 7.6218550394146956, 0.0, 0.0, 1.7625882324868487e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.499780039293976e-05, 1.762588232486848e-05, 0.0, 0.0, 7.562905277445575, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 164 + stamp: + secs: 1624875209 + nsecs: 560297012 + frame_id: "/world" +pose: + pose: + position: + x: -0.00490622434128 + y: 0.0484797995982 + z: 0.0 + orientation: + x: 0.0 + y: 0.000295624809824 + z: 0.0 + w: 0.999999956303 + covariance: [7.761939811123906, -1.633199719560009e-08, 0.0, 0.0, -2.1521513190144015e-05, 0.0, -1.6331997195600037e-08, 7.7619397893694995, 0.0, 0.0, 1.4715830111992615e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.152151319014401e-05, 1.4715830111992619e-05, 0.0, 0.0, 7.716103918308565, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 165 + stamp: + secs: 1624875209 + nsecs: 640314102 + frame_id: "/world" +pose: + pose: + position: + x: -0.00440278462669 + y: 0.04736773214 + z: 0.0 + orientation: + x: 0.0 + y: 0.000174758488617 + z: 0.0 + w: 0.99999998473 + covariance: [7.117648981047658, -1.1559468581547875e-08, 0.0, 0.0, -1.6568145915942416e-05, 0.0, -1.1559468581547839e-08, 7.117648965642969, 0.0, 0.0, 8.801286873490394e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.656814591594241e-05, 8.801286873490399e-06, 0.0, 0.0, 7.085164771971066, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 166 + stamp: + secs: 1624875209 + nsecs: 720318079 + frame_id: "/world" +pose: + pose: + position: + x: -0.000384015334056 + y: 0.0177155005967 + z: 0.0 + orientation: + x: 0.0 + y: 0.000105118395626 + z: 0.0 + w: 0.999999994475 + covariance: [8.360350492667594, -1.563637914132273e-08, 0.0, 0.0, -1.8340262477343687e-05, 0.0, -1.563637914132268e-08, 8.360350471807404, 0.0, 0.0, 8.916055667387592e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8340262477343683e-05, 8.916055667387596e-06, 0.0, 0.0, 8.316287821734402, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 167 + stamp: + secs: 1624875209 + nsecs: 800335884 + frame_id: "/world" +pose: + pose: + position: + x: 0.000954561760729 + y: 0.0180908254226 + z: 0.0 + orientation: + x: 0.0 + y: 0.000546314680005 + z: 0.0 + w: 0.99999985077 + covariance: [8.010118066408628, -5.759492792130526e-09, 0.0, 0.0, -6.7259655290054475e-06, 0.0, -5.7594927921305085e-09, 8.010118058725244, 0.0, 0.0, 3.2685854132455958e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.725965529005443e-06, 3.268585413245596e-06, 0.0, 0.0, 7.993861289832357, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 168 + stamp: + secs: 1624875209 + nsecs: 880331039 + frame_id: "/world" +pose: + pose: + position: + x: 0.00246137562442 + y: 0.0163296260352 + z: 0.0 + orientation: + x: 0.0 + y: 0.000461138848796 + z: 0.0 + w: 0.999999893675 + covariance: [7.915962973102289, -1.3814425604921042e-08, 0.0, 0.0, -1.2481285532515644e-05, 0.0, -1.3814425604920996e-08, 7.915962954634977, 0.0, 0.0, 4.755891430606253e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2481285532515647e-05, 4.755891430606255e-06, 0.0, 0.0, 7.8765833916579915, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 169 + stamp: + secs: 1624875209 + nsecs: 960352898 + frame_id: "/world" +pose: + pose: + position: + x: -0.0100773542362 + y: 0.0292824050552 + z: 0.0 + orientation: + x: 0.0 + y: 0.000681116345361 + z: 0.0 + w: 0.99999976804 + covariance: [7.88103457757156, -1.6574580942594496e-08, 0.0, 0.0, -1.3353977609426377e-05, 0.0, -1.657458094259444e-08, 7.881034555376621, 0.0, 0.0, 4.191392305688272e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3353977609426373e-05, 4.191392305688273e-06, 0.0, 0.0, 7.83357285830948, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 170 + stamp: + secs: 1624875210 + nsecs: 40358067 + frame_id: "/world" +pose: + pose: + position: + x: -0.0106618125587 + y: 0.0306947329199 + z: 0.0 + orientation: + x: 0.0 + y: 0.000113066445526 + z: 0.0 + w: 0.999999993608 + covariance: [7.860281241850908, -1.4813807787364622e-08, 0.0, 0.0, -9.203507645808067e-06, 0.0, -1.4813807787364577e-08, 7.860281221994587, 0.0, 0.0, 3.108933218997189e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.203507645808065e-06, 3.1089332189971894e-06, 0.0, 0.0, 7.81742965562886, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 171 + stamp: + secs: 1624875210 + nsecs: 120342016 + frame_id: "/world" +pose: + pose: + position: + x: -0.0105325979795 + y: 0.0269727787451 + z: 0.0 + orientation: + x: 0.0 + y: 4.78080583843e-05 + z: 0.0 + w: 0.999999998857 + covariance: [7.178235052669103, -2.094325874554809e-08, 0.0, 0.0, -8.272576998437199e-06, 0.0, -2.0943258745548025e-08, 7.178235024612341, 0.0, 0.0, 9.326132816017948e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.272576998437197e-06, 9.32613281601795e-06, 0.0, 0.0, 7.116532876488781, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 172 + stamp: + secs: 1624875210 + nsecs: 200356007 + frame_id: "/world" +pose: + pose: + position: + x: -0.0105313098903 + y: 0.0199832932663 + z: 0.0 + orientation: + x: 0.0 + y: 0.000120603740297 + z: 0.0 + w: 0.999999992727 + covariance: [8.386959631370619, -1.882487925237094e-08, 0.0, 0.0, -8.261540415933233e-06, 0.0, -1.8824879252370885e-08, 8.386959606186826, 0.0, 0.0, 9.442580125905483e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.261540415933235e-06, 9.442580125905483e-06, 0.0, 0.0, 8.33113875301727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 173 + stamp: + secs: 1624875210 + nsecs: 280395031 + frame_id: "/world" +pose: + pose: + position: + x: -0.00318740072793 + y: 0.00800981619549 + z: 0.0 + orientation: + x: 0.0 + y: 0.000138945189056 + z: 0.0 + w: 0.999999990347 + covariance: [10.093679037491674, -3.172278331174134e-08, 0.0, 0.0, -2.2952756596027054e-05, 0.0, -3.172278331174123e-08, 10.093678995110102, 0.0, 0.0, 1.2813862961293596e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.295275659602706e-05, 1.2813862961293596e-05, 0.0, 0.0, 9.998830977887543, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 174 + stamp: + secs: 1624875210 + nsecs: 360379934 + frame_id: "/world" +pose: + pose: + position: + x: -0.000534101832514 + y: 0.0230027238806 + z: 0.0 + orientation: + x: 0.0 + y: 0.000279899939588 + z: 0.0 + w: 0.999999960828 + covariance: [12.797062347486403, -5.528143333264437e-08, 0.0, 0.0, -6.918497148058396e-05, 0.0, -5.52814333326442e-08, 12.797062273278796, 0.0, 0.0, 1.7922257878854964e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.918497148058396e-05, 1.7922257878854964e-05, 0.0, 0.0, 12.6309421780887, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 175 + stamp: + secs: 1624875210 + nsecs: 440391064 + frame_id: "/world" +pose: + pose: + position: + x: -0.0078481121437 + y: 0.0243956875063 + z: 0.0 + orientation: + x: 0.0 + y: 0.000394373064062 + z: 0.0 + w: 0.999999922235 + covariance: [12.358742729768982, -4.0223120905861544e-08, 0.0, 0.0, -6.137175667704506e-05, 0.0, -4.022312090586141e-08, 12.35874267548251, 0.0, 0.0, 1.3245993654007504e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.137175667704506e-05, 1.3245993654007506e-05, 0.0, 0.0, 12.237382167404583, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 176 + stamp: + secs: 1624875210 + nsecs: 520392895 + frame_id: "/world" +pose: + pose: + position: + x: -0.0120751952342 + y: 0.0486421515121 + z: 0.0 + orientation: + x: 0.0 + y: 0.000809691648214 + z: 0.0 + w: 0.9999996722 + covariance: [10.604469579166993, -4.4040793329149745e-08, 0.0, 0.0, -6.85467312260383e-05, 0.0, -4.404079332914959e-08, 10.604469518741816, 0.0, 0.0, 1.3460924401926606e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.85467312260383e-05, 1.3460924401926606e-05, 0.0, 0.0, 10.470433491022542, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 177 + stamp: + secs: 1624875210 + nsecs: 600393057 + frame_id: "/world" +pose: + pose: + position: + x: -0.0125715066798 + y: 0.0495557071975 + z: 0.0 + orientation: + x: 0.0 + y: 0.000616659473777 + z: 0.0 + w: 0.999999809866 + covariance: [8.830694496468327, -3.481588787436093e-08, 0.0, 0.0, -4.771327164654715e-05, 0.0, -3.481588787436081e-08, 8.830694448220122, 0.0, 0.0, 1.349508943510053e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.7713271646547164e-05, 1.3495089435100534e-05, 0.0, 0.0, 8.723359106133234, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 178 + stamp: + secs: 1624875210 + nsecs: 680402040 + frame_id: "/world" +pose: + pose: + position: + x: -0.0155446334977 + y: 0.049998122813 + z: 0.0 + orientation: + x: 0.0 + y: 0.000326282442666 + z: 0.0 + w: 0.99999994677 + covariance: [7.470306373454512, -2.652542158956627e-08, 0.0, 0.0, -2.9973022287421443e-05, 0.0, -2.6525421589566175e-08, 7.470306336436203, 0.0, 0.0, 1.1188769963264152e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.997302228742145e-05, 1.118876996326415e-05, 0.0, 0.0, 7.38731131466513, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 179 + stamp: + secs: 1624875210 + nsecs: 760426044 + frame_id: "/world" +pose: + pose: + position: + x: -0.0231732609881 + y: 0.0760459258295 + z: 0.0 + orientation: + x: 0.0 + y: 6.8375235061e-05 + z: 0.0 + w: 0.999999997662 + covariance: [7.015894259568247, -1.0808900369121554e-08, 0.0, 0.0, -1.1697762616268786e-05, 0.0, -1.0808900369121514e-08, 7.015894244462713, 0.0, 0.0, 4.367502749136635e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.169776261626879e-05, 4.367502749136633e-06, 0.0, 0.0, 6.981881317409915, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 180 + stamp: + secs: 1624875210 + nsecs: 840425968 + frame_id: "/world" +pose: + pose: + position: + x: -0.0231729148197 + y: 0.0760328953711 + z: 0.0 + orientation: + x: 0.0 + y: 5.01324258526e-06 + z: 0.0 + w: 0.999999999987 + covariance: [6.323785466256531, -4.1214081507936595e-09, 0.0, 0.0, -4.364186846968509e-06, 0.0, -4.121408150793644e-09, 6.323785460485989, 0.0, 0.0, 1.5417406418444905e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.3641868469685115e-06, 1.5417406418444897e-06, 0.0, 0.0, 6.310769432678757, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 181 + stamp: + secs: 1624875210 + nsecs: 920433044 + frame_id: "/world" +pose: + pose: + position: + x: -0.0224087644207 + y: 0.0800141599579 + z: 0.0 + orientation: + x: -0.0 + y: -3.86937353458e-05 + z: -0.0 + w: 0.999999999251 + covariance: [7.974362316814121, -1.0078204788437789e-08, 0.0, 0.0, -7.967838132593319e-06, 0.0, -1.0078204788437756e-08, 7.974362302603188, 0.0, 0.0, 2.0747548364531703e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.967838132593322e-06, 2.07475483645317e-06, 0.0, 0.0, 7.942087164310923, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 182 + stamp: + secs: 1624875211 + nsecs: 436068 + frame_id: "/world" +pose: + pose: + position: + x: -0.00983568301505 + y: 0.0687038501986 + z: 0.0 + orientation: + x: -0.0 + y: -0.00106431326412 + z: -0.0 + w: 0.999999433618 + covariance: [7.186002704088982, -9.655327196667142e-09, 0.0, 0.0, -5.2320802207445285e-06, 0.0, -9.655327196667107e-09, 7.186002690457327, 0.0, 0.0, 5.954146985832429e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.23208022074453e-06, 5.9541469858324275e-06, 0.0, 0.0, 7.154754573597556, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 183 + stamp: + secs: 1624875211 + nsecs: 80427885 + frame_id: "/world" +pose: + pose: + position: + x: -0.00902950411389 + y: 0.0664716435005 + z: 0.0 + orientation: + x: -0.0 + y: -0.000238657832247 + z: -0.0 + w: 0.999999971521 + covariance: [7.599574518277454, -1.2058403267867718e-08, 0.0, 0.0, -4.079508322704058e-06, 0.0, -1.2058403267867677e-08, 7.599574501301535, 0.0, 0.0, 1.0464486040981578e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.07950832270406e-06, 1.046448604098158e-05, 0.0, 0.0, 7.560158302250148, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 184 + stamp: + secs: 1624875211 + nsecs: 160442114 + frame_id: "/world" +pose: + pose: + position: + x: -0.00826873224254 + y: 0.0615008751875 + z: 0.0 + orientation: + x: 0.0 + y: 0.000293545088177 + z: 0.0 + w: 0.999999956916 + covariance: [7.764955093872776, -1.510382358741674e-08, 0.0, 0.0, -4.766024887494078e-06, 0.0, -1.5103823587416694e-08, 7.764955072681582, 0.0, 0.0, 1.0898716002070731e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.766024887494079e-06, 1.0898716002070731e-05, 0.0, 0.0, 7.715086290107682, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 185 + stamp: + secs: 1624875211 + nsecs: 240469933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0232321340134 + y: 0.0805863922666 + z: 0.0 + orientation: + x: 0.0 + y: 0.000138567496037 + z: 0.0 + w: 0.9999999904 + covariance: [7.132146166063532, -1.4179419684333335e-08, 0.0, 0.0, -8.057110570101356e-06, 0.0, -1.4179419684333286e-08, 7.132146146252177, 0.0, 0.0, 1.1450649000165187e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.057110570101356e-06, 1.1450649000165191e-05, 0.0, 0.0, 7.08490380640583, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 186 + stamp: + secs: 1624875211 + nsecs: 320468903 + frame_id: "/world" +pose: + pose: + position: + x: -0.023177810942 + y: 0.0810181460981 + z: 0.0 + orientation: + x: -0.0 + y: -0.000302191601472 + z: -0.0 + w: 0.99999995434 + covariance: [7.584216297599288, -1.522399334008695e-08, 0.0, 0.0, -1.0100333061746702e-05, 0.0, -1.52239933400869e-08, 7.5842162764387355, 0.0, 0.0, 1.1846198010126057e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.01003330617467e-05, 1.1846198010126057e-05, 0.0, 0.0, 7.533084367899911, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 187 + stamp: + secs: 1624875211 + nsecs: 400448084 + frame_id: "/world" +pose: + pose: + position: + x: -0.0246157225004 + y: 0.0803188923408 + z: 0.0 + orientation: + x: 0.0 + y: 1.63249101386e-05 + z: 0.0 + w: 0.999999999867 + covariance: [7.7705336038552755, -1.9363699405482024e-08, 0.0, 0.0, -9.796078137347503e-06, 0.0, -1.936369940548196e-08, 7.770533577068504, 0.0, 0.0, 1.1383578260260003e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.796078137347506e-06, 1.138357826026e-05, 0.0, 0.0, 7.704808591826622, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 188 + stamp: + secs: 1624875211 + nsecs: 480456114 + frame_id: "/world" +pose: + pose: + position: + x: -0.0191191003109 + y: 0.0824786301304 + z: 0.0 + orientation: + x: -0.0 + y: -0.000250565596069 + z: -0.0 + w: 0.999999968608 + covariance: [6.537203639118754, -9.202816322008706e-09, 0.0, 0.0, -3.7663284783790862e-06, 0.0, -9.202816322008675e-09, 6.537203626416594, 0.0, 0.0, 5.915890205915832e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.7663284783790896e-06, 5.915890205915833e-06, 0.0, 0.0, 6.505742829300434, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 189 + stamp: + secs: 1624875211 + nsecs: 560573101 + frame_id: "/world" +pose: + pose: + position: + x: -0.019123401819 + y: 0.0824317893342 + z: 0.0 + orientation: + x: -0.0 + y: -0.000146822538995 + z: -0.0 + w: 0.999999989222 + covariance: [8.083099985978045, -1.3173391486577902e-08, 0.0, 0.0, -6.174259060755e-06, 0.0, -1.3173391486577859e-08, 8.083099967897114, 0.0, 0.0, 1.0973876197864512e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.1742590607550024e-06, 1.0973876197864512e-05, 0.0, 0.0, 8.03774063242927, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 190 + stamp: + secs: 1624875211 + nsecs: 640486956 + frame_id: "/world" +pose: + pose: + position: + x: -0.0186038963151 + y: 0.0820760558576 + z: 0.0 + orientation: + x: -0.0 + y: -7.81217568574e-05 + z: -0.0 + w: 0.999999996948 + covariance: [7.918804186049428, -7.568744729070334e-09, 0.0, 0.0, -4.3117852134978584e-06, 0.0, -7.568744729070311e-09, 7.918804175684448, 0.0, 0.0, 6.3473499389384234e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.31178521349786e-06, 6.347349938938423e-06, 0.0, 0.0, 7.892638009446651, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 191 + stamp: + secs: 1624875211 + nsecs: 720500946 + frame_id: "/world" +pose: + pose: + position: + x: -0.0220251127769 + y: 0.0839647553845 + z: 0.0 + orientation: + x: -0.0 + y: -0.000266515418573 + z: -0.0 + w: 0.999999964485 + covariance: [8.747097927012694, -1.6088407155295003e-08, 0.0, 0.0, -8.921766863993656e-06, 0.0, -1.608840715529495e-08, 8.747097905117393, 0.0, 0.0, 9.208106051768979e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.921766863993656e-06, 9.20810605176898e-06, 0.0, 0.0, 8.690934778510362, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 192 + stamp: + secs: 1624875211 + nsecs: 800513029 + frame_id: "/world" +pose: + pose: + position: + x: -0.0231022602129 + y: 0.0879211128612 + z: 0.0 + orientation: + x: -0.0 + y: -0.000147930642053 + z: -0.0 + w: 0.999999989058 + covariance: [7.416607864763635, -1.0989477567228006e-08, 0.0, 0.0, -3.5401927362533585e-06, 0.0, -1.0989477567227964e-08, 7.416607849838129, 0.0, 0.0, 4.5129310973093975e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.540192736253358e-06, 4.512931097309397e-06, 0.0, 0.0, 7.377840802223861, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 193 + stamp: + secs: 1624875211 + nsecs: 880506992 + frame_id: "/world" +pose: + pose: + position: + x: -0.0181176998161 + y: 0.0698117593498 + z: 0.0 + orientation: + x: 0.0 + y: 0.000127562472115 + z: 0.0 + w: 0.999999991864 + covariance: [6.469281351674116, -1.4026887184188946e-08, 0.0, 0.0, -8.396399080925909e-07, 0.0, -1.4026887184188905e-08, 6.469281332665043, 0.0, 0.0, 2.866599864404733e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.39639908092591e-07, 2.8665998644047324e-06, 0.0, 0.0, 6.418913450761649, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 194 + stamp: + secs: 1624875211 + nsecs: 960508108 + frame_id: "/world" +pose: + pose: + position: + x: -0.0181175366193 + y: 0.0697404555457 + z: 0.0 + orientation: + x: 0.0 + y: 0.00011070477273 + z: 0.0 + w: 0.999999993872 + covariance: [8.943509735937656, -1.6738549308010085e-08, 0.0, 0.0, -7.665533679942136e-07, 0.0, -1.6738549308010035e-08, 8.943509713271787, 0.0, 0.0, 5.3342649241086245e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.665533679942135e-07, 5.334264924108624e-06, 0.0, 0.0, 8.883042584457487, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 195 + stamp: + secs: 1624875212 + nsecs: 40527105 + frame_id: "/world" +pose: + pose: + position: + x: -0.0180712202289 + y: 0.0698714420166 + z: 0.0 + orientation: + x: 0.0 + y: 2.20533420624e-05 + z: 0.0 + w: 0.999999999757 + covariance: [6.830264513086506, -7.943505349507593e-09, 0.0, 0.0, -1.3650081557621468e-06, 0.0, -7.943505349507571e-09, 6.8302645023438595, 0.0, 0.0, 3.949112682261664e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.365008155762146e-06, 3.949112682261662e-06, 0.0, 0.0, 6.801318237749353, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 196 + stamp: + secs: 1624875212 + nsecs: 120568991 + frame_id: "/world" +pose: + pose: + position: + x: -0.0160408975811 + y: 0.0863791249241 + z: 0.0 + orientation: + x: -0.0 + y: -0.000698906897176 + z: -0.0 + w: 0.999999755765 + covariance: [8.262555377865864, -2.206724991237872e-08, 0.0, 0.0, -5.07491280887148e-06, 0.0, -2.206724991237865e-08, 8.262555348126636, 0.0, 0.0, 9.165867744559197e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.074912808871479e-06, 9.165867744559192e-06, 0.0, 0.0, 8.180907733998044, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 197 + stamp: + secs: 1624875212 + nsecs: 200536013 + frame_id: "/world" +pose: + pose: + position: + x: -0.0158797585815 + y: 0.0866600514372 + z: 0.0 + orientation: + x: -0.0 + y: -0.000497181814508 + z: -0.0 + w: 0.999999876405 + covariance: [10.004591957841006, -2.4370478338748635e-08, 0.0, 0.0, -2.5904599937744524e-05, 0.0, -2.4370478338748556e-08, 10.004591925019659, 0.0, 0.0, 1.4754146576318153e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.590459993774452e-05, 1.475414657631815e-05, 0.0, 0.0, 9.914049336899938, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 198 + stamp: + secs: 1624875212 + nsecs: 280575037 + frame_id: "/world" +pose: + pose: + position: + x: -0.020683404716 + y: 0.109502357081 + z: 0.0 + orientation: + x: -0.0 + y: -0.000286065089184 + z: -0.0 + w: 0.999999959083 + covariance: [9.665004642755298, -2.6996371155788128e-08, 0.0, 0.0, -5.1635517617148555e-05, 0.0, -2.699637115578804e-08, 9.665004606124663, 0.0, 0.0, 2.107338243741557e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.1635517617148534e-05, 2.1073382437415567e-05, 0.0, 0.0, 9.56474020391021, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 199 + stamp: + secs: 1624875212 + nsecs: 360554934 + frame_id: "/world" +pose: + pose: + position: + x: -0.0331409833412 + y: 0.104252469362 + z: 0.0 + orientation: + x: -0.0 + y: -0.000168912280692 + z: -0.0 + w: 0.999999985734 + covariance: [7.028999668278716, -1.8211507761816688e-08, 0.0, 0.0, -2.9159456314371464e-05, 0.0, -1.8211507761816628e-08, 7.028999643355398, 0.0, 0.0, 1.1763427240111754e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.915945631437147e-05, 1.1763427240111754e-05, 0.0, 0.0, 6.961001765197858, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 200 + stamp: + secs: 1624875212 + nsecs: 440562963 + frame_id: "/world" +pose: + pose: + position: + x: -0.0291194286024 + y: 0.104704058283 + z: 0.0 + orientation: + x: -0.0 + y: -0.000387441630365 + z: -0.0 + w: 0.999999924944 + covariance: [10.560805584308309, -4.1754072877182755e-08, 0.0, 0.0, -4.503214115392472e-05, 0.0, -4.175407287718263e-08, 10.560805527113844, 0.0, 0.0, 3.4709356772770977e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.5032141153924736e-05, 3.4709356772770977e-05, 0.0, 0.0, 10.405326384711078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 201 + stamp: + secs: 1624875212 + nsecs: 520561934 + frame_id: "/world" +pose: + pose: + position: + x: -0.0291437757307 + y: 0.104708406448 + z: 0.0 + orientation: + x: -0.0 + y: -0.000191813442701 + z: -0.0 + w: 0.999999981604 + covariance: [13.065046913214923, -3.950434849077144e-08, 0.0, 0.0, -3.849022642119572e-05, 0.0, -3.950434849077131e-08, 13.065046859200244, 0.0, 0.0, 3.541656264387066e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.8490226421195736e-05, 3.541656264387066e-05, 0.0, 0.0, 12.91773969736562, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 202 + stamp: + secs: 1624875212 + nsecs: 600589991 + frame_id: "/world" +pose: + pose: + position: + x: -0.0213544731109 + y: 0.124756651907 + z: 0.0 + orientation: + x: 0.0 + y: 0.000486766932246 + z: 0.0 + w: 0.999999881529 + covariance: [10.851156603513438, -3.569154189017329e-08, 0.0, 0.0, -1.4103411899669695e-05, 0.0, -3.5691541890173165e-08, 10.851156554988238, 0.0, 0.0, 3.208936534005192e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4103411899669693e-05, 3.208936534005193e-05, 0.0, 0.0, 10.71697564074222, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 203 + stamp: + secs: 1624875212 + nsecs: 680576086 + frame_id: "/world" +pose: + pose: + position: + x: -0.021796526766 + y: 0.126181732667 + z: 0.0 + orientation: + x: 0.0 + y: 0.000501677365425 + z: 0.0 + w: 0.99999987416 + covariance: [10.026919660392476, -3.626922363175355e-08, 0.0, 0.0, 1.3632207344308284e-06, 0.0, -3.6269223631753416e-08, 10.026919611209731, 0.0, 0.0, 2.4659614455371135e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 1.3632207344308278e-06, 2.465961445537114e-05, 0.0, 0.0, 9.888687388754795, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 204 + stamp: + secs: 1624875212 + nsecs: 760581970 + frame_id: "/world" +pose: + pose: + position: + x: -0.0127766377848 + y: 0.10640089455 + z: 0.0 + orientation: + x: 0.0 + y: 0.000400220092614 + z: 0.0 + w: 0.999999919912 + covariance: [9.681160290342383, -3.2869746090759e-08, 0.0, 0.0, 3.670244806653676e-06, 0.0, -3.286974609075887e-08, 9.681160245911615, 0.0, 0.0, 2.9211805918098226e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 3.670244806653674e-06, 2.9211805918098236e-05, 0.0, 0.0, 9.554493378684269, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 205 + stamp: + secs: 1624875212 + nsecs: 840596914 + frame_id: "/world" +pose: + pose: + position: + x: -0.0130636162653 + y: 0.107370504727 + z: 0.0 + orientation: + x: 0.0 + y: 0.000567141096636 + z: 0.0 + w: 0.999999839175 + covariance: [9.535723199858577, -3.0766073407375036e-08, 0.0, 0.0, -1.935334815062944e-07, 0.0, -3.076607340737493e-08, 9.535723158675706, 0.0, 0.0, 3.936674862646941e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9353348150629506e-07, 3.9366748626469405e-05, 0.0, 0.0, 9.415676704162546, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 206 + stamp: + secs: 1624875212 + nsecs: 920597076 + frame_id: "/world" +pose: + pose: + position: + x: -0.00856008411143 + y: 0.0815715804821 + z: 0.0 + orientation: + x: 0.0 + y: 0.000451971559954 + z: 0.0 + w: 0.999999897861 + covariance: [9.493107801503454, -3.43300801299575e-08, 0.0, 0.0, -6.8368000403997145e-06, 0.0, -3.433008012995739e-08, 9.493107756311513, 0.0, 0.0, 4.4907949426489564e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.836800040399719e-06, 4.4907949426489564e-05, 0.0, 0.0, 9.357324384951845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 207 + stamp: + secs: 1624875213 + nsecs: 623941 + frame_id: "/world" +pose: + pose: + position: + x: -0.0095098528835 + y: 0.0811611875532 + z: 0.0 + orientation: + x: 0.0 + y: 0.000292108769076 + z: 0.0 + w: 0.999999957336 + covariance: [9.424085494430916, -2.2937212227709485e-08, 0.0, 0.0, -5.645977868463417e-06, 0.0, -2.2937212227709413e-08, 9.424085464436235, 0.0, 0.0, 2.755101245260627e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.645977868463418e-06, 2.755101245260627e-05, 0.0, 0.0, 9.332700389819948, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 208 + stamp: + secs: 1624875213 + nsecs: 80640078 + frame_id: "/world" +pose: + pose: + position: + x: -0.0107032806713 + y: 0.0843095749305 + z: 0.0 + orientation: + x: 0.0 + y: 0.000381248297151 + z: 0.0 + w: 0.999999927325 + covariance: [7.614198492987615, -1.338441152398738e-08, 0.0, 0.0, -3.5673819162171517e-06, 0.0, -1.3384411523987333e-08, 7.614198475664542, 0.0, 0.0, 1.4584542206871601e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.5673819162171517e-06, 1.4584542206871596e-05, 0.0, 0.0, 7.5606288718635515, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 209 + stamp: + secs: 1624875213 + nsecs: 160621881 + frame_id: "/world" +pose: + pose: + position: + x: -0.0114452163989 + y: 0.0828675430336 + z: 0.0 + orientation: + x: 0.0 + y: 0.00114520196392 + z: 0.0 + w: 0.999999344256 + covariance: [10.995937424932654, -3.446494769125035e-08, 0.0, 0.0, -1.8472173072267833e-05, 0.0, -3.446494769125023e-08, 10.995937381006696, 0.0, 0.0, 2.8672191032091034e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8472173072267833e-05, 2.8672191032091034e-05, 0.0, 0.0, 10.856320962188638, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 210 + stamp: + secs: 1624875213 + nsecs: 240650892 + frame_id: "/world" +pose: + pose: + position: + x: -0.0114378374222 + y: 0.0828176699206 + z: 0.0 + orientation: + x: 0.0 + y: 0.000866994304709 + z: 0.0 + w: 0.99999962416 + covariance: [13.369654023691988, -3.348623619622862e-08, 0.0, 0.0, -2.1080803192592627e-05, 0.0, -3.34862361962285e-08, 13.369653981126522, 0.0, 0.0, 2.4863090645364298e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.108080319259263e-05, 2.48630906453643e-05, 0.0, 0.0, 13.233522825016742, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 211 + stamp: + secs: 1624875213 + nsecs: 320632935 + frame_id: "/world" +pose: + pose: + position: + x: -0.0149587019424 + y: 0.06639876558 + z: 0.0 + orientation: + x: 0.0 + y: 0.000348596337149 + z: 0.0 + w: 0.99999993924 + covariance: [9.623103450494243, -2.0690116865032264e-08, 0.0, 0.0, -4.3512497805511696e-05, 0.0, -2.0690116865032198e-08, 9.62310342407196, 0.0, 0.0, 1.0656564438337907e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.35124978055117e-05, 1.0656564438337909e-05, 0.0, 0.0, 9.538166052409322, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 212 + stamp: + secs: 1624875213 + nsecs: 400671005 + frame_id: "/world" +pose: + pose: + position: + x: -0.0140596128258 + y: 0.0662089599225 + z: 0.0 + orientation: + x: 0.0 + y: 0.000979610305584 + z: 0.0 + w: 0.999999520182 + covariance: [7.695561784228927, -1.943456818954749e-08, 0.0, 0.0, -6.297347425260782e-05, 0.0, -1.943456818954743e-08, 7.695561759209189, 0.0, 0.0, 4.169279890360219e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.29734742526078e-05, 4.1692798903602195e-05, 0.0, 0.0, 7.617158977765893, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 213 + stamp: + secs: 1624875213 + nsecs: 480642080 + frame_id: "/world" +pose: + pose: + position: + x: -0.00980882101926 + y: 0.0908215280766 + z: 0.0 + orientation: + x: 0.0 + y: 0.00016383257526 + z: 0.0 + w: 0.999999986579 + covariance: [7.79071536291052, -1.3791290563832538e-08, 0.0, 0.0, -4.1218383287498905e-05, 0.0, -1.37912905638325e-08, 7.790715345798184, 0.0, 0.0, 3.781940856050122e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.1218383287498905e-05, 3.7819408560501204e-05, 0.0, 0.0, 7.73655047101038, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 214 + stamp: + secs: 1624875213 + nsecs: 560708046 + frame_id: "/world" +pose: + pose: + position: + x: -0.00919102742584 + y: 0.0904681647563 + z: 0.0 + orientation: + x: 0.0 + y: 0.000168351273657 + z: 0.0 + w: 0.999999985829 + covariance: [8.684801218346973, -1.7269911272970548e-08, 0.0, 0.0, -3.9409482674005705e-05, 0.0, -1.7269911272970505e-08, 8.68480119816773, 0.0, 0.0, 4.125013032872227e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.9409482674005705e-05, 4.125013032872225e-05, 0.0, 0.0, 8.619751679963834, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 215 + stamp: + secs: 1624875213 + nsecs: 640685081 + frame_id: "/world" +pose: + pose: + position: + x: -0.00549337978693 + y: 0.0758198585554 + z: 0.0 + orientation: + x: 0.0 + y: 0.000330666118897 + z: 0.0 + w: 0.99999994533 + covariance: [8.146471604595344, -1.1932778198038118e-08, 0.0, 0.0, -2.2309730947958627e-05, 0.0, -1.1932778198038087e-08, 8.146471591087437, 0.0, 0.0, 2.3099622957807657e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.230973094795863e-05, 2.3099622957807654e-05, 0.0, 0.0, 8.102327828421888, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 216 + stamp: + secs: 1624875213 + nsecs: 720674992 + frame_id: "/world" +pose: + pose: + position: + x: -0.00159734613872 + y: 0.0490004319276 + z: 0.0 + orientation: + x: 0.0 + y: 0.000569733312645 + z: 0.0 + w: 0.999999837702 + covariance: [8.838515911004842, -1.4564324044184868e-08, 0.0, 0.0, -2.431473893225501e-05, 0.0, -1.4564324044184828e-08, 8.83851589509928, 0.0, 0.0, 1.9013181663671565e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4314738932255016e-05, 1.9013181663671565e-05, 0.0, 0.0, 8.785757962602657, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 217 + stamp: + secs: 1624875213 + nsecs: 800682068 + frame_id: "/world" +pose: + pose: + position: + x: -0.0113349313614 + y: 0.0498066920242 + z: 0.0 + orientation: + x: 0.0 + y: 0.000161658865196 + z: 0.0 + w: 0.999999986933 + covariance: [8.218064706592152, -1.59587688256641e-08, 0.0, 0.0, -2.1820647267454723e-05, 0.0, -1.595876882566406e-08, 8.21806468957466, 0.0, 0.0, 1.2594309781348223e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.182064726745473e-05, 1.2594309781348223e-05, 0.0, 0.0, 8.160951204947706, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 218 + stamp: + secs: 1624875213 + nsecs: 880716085 + frame_id: "/world" +pose: + pose: + position: + x: -0.0113277372242 + y: 0.0497100834728 + z: 0.0 + orientation: + x: 0.0 + y: 0.000819836949795 + z: 0.0 + w: 0.999999663934 + covariance: [10.000153394096245, -2.7302082810878932e-08, 0.0, 0.0, -3.8725182392431846e-05, 0.0, -2.7302082810878866e-08, 10.000153365396978, 0.0, 0.0, 2.355109328767587e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.872518239243185e-05, 2.3551093287675875e-05, 0.0, 0.0, 9.903709583206593, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 219 + stamp: + secs: 1624875213 + nsecs: 960705042 + frame_id: "/world" +pose: + pose: + position: + x: -0.0192124000355 + y: 0.0450494807384 + z: 0.0 + orientation: + x: 0.0 + y: 0.00101346587396 + z: 0.0 + w: 0.999999486443 + covariance: [10.984120929045536, -3.575181782387615e-08, 0.0, 0.0, -7.026926182898199e-05, 0.0, -3.575181782387608e-08, 10.984120891673602, 0.0, 0.0, 3.909286675599668e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.026926182898199e-05, 3.9092866755996665e-05, 0.0, 0.0, 10.858493164311907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 220 + stamp: + secs: 1624875214 + nsecs: 40746927 + frame_id: "/world" +pose: + pose: + position: + x: -0.0165467783032 + y: 0.0466394932217 + z: 0.0 + orientation: + x: -0.0 + y: -0.00065006089166 + z: -0.0 + w: 0.99999978871 + covariance: [13.428276980904421, -5.5804333688649894e-08, 0.0, 0.0, -0.00011541124358577878, 0.0, -5.5804333688649775e-08, 13.428276923161008, 0.0, 0.0, 8.351877369994101e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011541124358577878, 8.3518773699941e-05, 0.0, 0.0, 13.235014532351718, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 221 + stamp: + secs: 1624875214 + nsecs: 120723009 + frame_id: "/world" +pose: + pose: + position: + x: -0.0190028365585 + y: 0.0471179168186 + z: 0.0 + orientation: + x: 0.0 + y: 0.00033460438045 + z: 0.0 + w: 0.99999994402 + covariance: [15.161411125037562, -9.157607069873001e-08, 0.0, 0.0, -0.00015562112856633566, 0.0, -9.157607069872987e-08, 15.161411033008541, 0.0, 0.0, 0.0001471009557213077, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00015562112856633568, 0.00014710095572130767, 0.0, 0.0, 14.850608433289601, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 222 + stamp: + secs: 1624875214 + nsecs: 200736046 + frame_id: "/world" +pose: + pose: + position: + x: -0.0181089283459 + y: 0.0481035964141 + z: 0.0 + orientation: + x: -0.0 + y: -0.00016222116632 + z: -0.0 + w: 0.999999986842 + covariance: [16.286124003398502, -1.1312095212792795e-07, 0.0, 0.0, -0.00015770875301688168, 0.0, -1.1312095212792777e-07, 16.28612389163296, 0.0, 0.0, 0.00015914704463789315, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00015770875301688173, 0.0001591470446378931, 0.0, 0.0, 15.905335213399297, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 223 + stamp: + secs: 1624875214 + nsecs: 280742884 + frame_id: "/world" +pose: + pose: + position: + x: -0.018159104865 + y: 0.0477963223956 + z: 0.0 + orientation: + x: 0.0 + y: 0.000393143595934 + z: 0.0 + w: 0.999999922719 + covariance: [17.001206967230225, -1.270972969660823e-07, 0.0, 0.0, -0.00017441715812368725, 0.0, -1.2709729696608206e-07, 17.00120684276304, 0.0, 0.0, 0.00015121756151262295, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001744171581236873, 0.00015121756151262295, 0.0, 0.0, 16.574725994275816, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 224 + stamp: + secs: 1624875214 + nsecs: 360743999 + frame_id: "/world" +pose: + pose: + position: + x: -0.0182160652014 + y: 0.0474449960682 + z: 0.0 + orientation: + x: 0.0 + y: 0.00076112912509 + z: 0.0 + w: 0.999999710341 + covariance: [17.483140787206395, -1.4646384395349095e-07, 0.0, 0.0, -0.00020523705177009923, 0.0, -1.4646384395349066e-07, 17.483140644015865, 0.0, 0.0, 0.00013999709851596158, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00020523705177009926, 0.0001399970985159616, 0.0, 0.0, 16.993534431385132, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 225 + stamp: + secs: 1624875214 + nsecs: 440733910 + frame_id: "/world" +pose: + pose: + position: + x: -0.0186621167391 + y: 0.0487912904748 + z: 0.0 + orientation: + x: 0.0 + y: 0.00093784764219 + z: 0.0 + w: 0.999999560221 + covariance: [12.306867833443702, -7.524491212127605e-08, 0.0, 0.0, -0.00014436643544157884, 0.0, -7.52449121212759e-08, 12.306867759049144, 0.0, 0.0, 6.646470767904184e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001443664354415789, 6.646470767904186e-05, 0.0, 0.0, 12.05431817702347, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 226 + stamp: + secs: 1624875214 + nsecs: 520785093 + frame_id: "/world" +pose: + pose: + position: + x: -0.0235126651708 + y: 0.0482636666767 + z: 0.0 + orientation: + x: 0.0 + y: 0.00308402012799 + z: 0.0 + w: 0.999995244399 + covariance: [14.41018854653725, -1.0641739309206826e-07, 0.0, 0.0, -0.0002561515041211722, 0.0, -1.0641739309206805e-07, 14.410188436424312, 0.0, 0.0, 8.501234222329104e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00025615150412117225, 8.501234222329105e-05, 0.0, 0.0, 14.056829144237353, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 227 + stamp: + secs: 1624875214 + nsecs: 600769043 + frame_id: "/world" +pose: + pose: + position: + x: -0.0247792706345 + y: 0.0476411217211 + z: 0.0 + orientation: + x: 0.0 + y: 0.000924290035299 + z: 0.0 + w: 0.999999572844 + covariance: [11.336553398099136, -6.678087185206585e-08, 0.0, 0.0, -0.0001578443214773427, 0.0, -6.678087185206572e-08, 11.336553326787596, 0.0, 0.0, 5.074488717051578e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00015784432147734271, 5.074488717051581e-05, 0.0, 0.0, 11.114057832786154, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 228 + stamp: + secs: 1624875214 + nsecs: 680773020 + frame_id: "/world" +pose: + pose: + position: + x: -0.0293357788352 + y: 0.0523418514678 + z: 0.0 + orientation: + x: -0.0 + y: -0.00017183197794 + z: -0.0 + w: 0.999999985237 + covariance: [10.227518496429008, -5.517297893350526e-08, 0.0, 0.0, -0.00011469416191763879, 0.0, -5.5172978933505145e-08, 10.227518435415199, 0.0, 0.0, 3.8249608310407525e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001146941619176388, 3.824960831040753e-05, 0.0, 0.0, 10.044433244315645, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 229 + stamp: + secs: 1624875214 + nsecs: 760782957 + frame_id: "/world" +pose: + pose: + position: + x: -0.0294784160203 + y: 0.0520255801178 + z: 0.0 + orientation: + x: -0.0 + y: -0.000157881443796 + z: -0.0 + w: 0.999999987537 + covariance: [12.957890067993716, -8.960211435010073e-08, 0.0, 0.0, -0.00015545473005135034, 0.0, -8.960211435010056e-08, 12.957889965407121, 0.0, 0.0, 4.879861993829889e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00015545473005135034, 4.879861993829891e-05, 0.0, 0.0, 12.663062897119918, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 230 + stamp: + secs: 1624875214 + nsecs: 840786934 + frame_id: "/world" +pose: + pose: + position: + x: -0.0295271723573 + y: 0.051917083446 + z: 0.0 + orientation: + x: -0.0 + y: -2.49930357664e-05 + z: -0.0 + w: 0.999999999688 + covariance: [12.444671490057745, -5.810325962447611e-08, 0.0, 0.0, -9.463280036044766e-05, 0.0, -5.8103259624475994e-08, 12.444671422900962, 0.0, 0.0, 2.8699086210446023e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.463280036044762e-05, 2.8699086210446033e-05, 0.0, 0.0, 12.252614001490857, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 231 + stamp: + secs: 1624875214 + nsecs: 920783043 + frame_id: "/world" +pose: + pose: + position: + x: -0.0173604112871 + y: 0.0647574094903 + z: 0.0 + orientation: + x: 0.0 + y: 2.79474916125e-05 + z: 0.0 + w: 0.999999999609 + covariance: [14.474684288166884, -8.5613008527528e-08, 0.0, 0.0, -0.00011501018415212504, 0.0, -8.56130085275278e-08, 14.474684186858815, 0.0, 0.0, 3.2267958810366445e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011501018415212503, 3.226795881036646e-05, 0.0, 0.0, 14.192049147471753, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 232 + stamp: + secs: 1624875215 + nsecs: 812054 + frame_id: "/world" +pose: + pose: + position: + x: -0.0162211578552 + y: 0.0652148119595 + z: 0.0 + orientation: + x: -0.0 + y: -0.000409377389836 + z: -0.0 + w: 0.999999916205 + covariance: [9.932377933449597, -4.1451160095002954e-08, 0.0, 0.0, -4.670969070906065e-05, 0.0, -4.1451160095002854e-08, 9.932377883825563, 0.0, 0.0, 1.7024134839142332e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.670969070906064e-05, 1.7024134839142325e-05, 0.0, 0.0, 9.79393297325805, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 233 + stamp: + secs: 1624875215 + nsecs: 80796003 + frame_id: "/world" +pose: + pose: + position: + x: -0.0140489176671 + y: 0.0653343496659 + z: 0.0 + orientation: + x: -0.0 + y: -0.00114260654068 + z: -0.0 + w: 0.999999347225 + covariance: [9.692137105855485, -5.242785158759063e-08, 0.0, 0.0, -3.884050898243834e-05, 0.0, -5.2427851587590514e-08, 9.692137042278011, 0.0, 0.0, 2.239779602353155e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.8840508982438344e-05, 2.2397796023531548e-05, 0.0, 0.0, 9.515179846888241, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 234 + stamp: + secs: 1624875215 + nsecs: 160804033 + frame_id: "/world" +pose: + pose: + position: + x: -0.0140146482188 + y: 0.0646526973958 + z: 0.0 + orientation: + x: -0.0 + y: -0.000409120996199 + z: -0.0 + w: 0.99999991631 + covariance: [8.5422467352846, -3.83885710319484e-08, 0.0, 0.0, -2.4084581860038875e-05, 0.0, -3.838857103194832e-08, 8.542246688446985, 0.0, 0.0, 1.3588046848154355e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4084581860038885e-05, 1.358804684815435e-05, 0.0, 0.0, 8.410903328986965, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 235 + stamp: + secs: 1624875215 + nsecs: 240817070 + frame_id: "/world" +pose: + pose: + position: + x: -0.0140491346804 + y: 0.0644322652712 + z: 0.0 + orientation: + x: -0.0 + y: -0.000373032452539 + z: -0.0 + w: 0.999999930423 + covariance: [11.72363589418439, -6.912360917656791e-08, 0.0, 0.0, -3.813410017622279e-05, 0.0, -6.912360917656778e-08, 11.723635809402596, 0.0, 0.0, 1.8337400887682836e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.8134100176222804e-05, 1.8337400887682833e-05, 0.0, 0.0, 11.485542216007612, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 236 + stamp: + secs: 1624875215 + nsecs: 320810080 + frame_id: "/world" +pose: + pose: + position: + x: -0.00851616063149 + y: 0.0642177750238 + z: 0.0 + orientation: + x: -0.0 + y: -0.000423519112991 + z: -0.0 + w: 0.999999910316 + covariance: [14.210323805794355, -1.5511871991266888e-07, 0.0, 0.0, -0.00011215151708580078, 0.0, -1.551187199126686e-07, 14.210323613875508, 0.0, 0.0, 2.627655946248338e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011215151708580079, 2.6276559462483374e-05, 0.0, 0.0, 13.668816405323348, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 237 + stamp: + secs: 1624875215 + nsecs: 400810003 + frame_id: "/world" +pose: + pose: + position: + x: -0.00877059495051 + y: 0.0659161507532 + z: 0.0 + orientation: + x: 0.0 + y: 0.000179595577218 + z: 0.0 + w: 0.999999983873 + covariance: [8.79974717572571, -5.130803723864651e-08, 0.0, 0.0, -4.784474728330341e-05, 0.0, -5.130803723864639e-08, 8.799747111986104, 0.0, 0.0, 1.3939714740681665e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.784474728330342e-05, 1.3939714740681672e-05, 0.0, 0.0, 8.615848765149087, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 238 + stamp: + secs: 1624875215 + nsecs: 480870008 + frame_id: "/world" +pose: + pose: + position: + x: -0.00845969109738 + y: 0.0659351495679 + z: 0.0 + orientation: + x: 0.0 + y: 0.000185490076511 + z: 0.0 + w: 0.999999982797 + covariance: [9.210114708680772, -5.443961286757261e-08, 0.0, 0.0, -7.705167037827037e-05, 0.0, -5.4439612867572476e-08, 9.210114640144267, 0.0, 0.0, 2.4469464161682183e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.70516703782704e-05, 2.4469464161682183e-05, 0.0, 0.0, 9.013585999339064, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 239 + stamp: + secs: 1624875215 + nsecs: 560842037 + frame_id: "/world" +pose: + pose: + position: + x: -0.0051985662262 + y: 0.0659274276258 + z: 0.0 + orientation: + x: -0.0 + y: -0.00195858210414 + z: -0.0 + w: 0.999998081976 + covariance: [12.215267207716787, -8.055490695554372e-08, 0.0, 0.0, -0.00012161242400084725, 0.0, -8.055490695554352e-08, 12.215267104588495, 0.0, 0.0, 3.559297496412426e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00012161242400084726, 3.559297496412425e-05, 0.0, 0.0, 11.924876873559459, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 240 + stamp: + secs: 1624875215 + nsecs: 640876055 + frame_id: "/world" +pose: + pose: + position: + x: -0.00327553492845 + y: 0.0663960617926 + z: 0.0 + orientation: + x: -0.0 + y: -0.00156285755483 + z: -0.0 + w: 0.999998778737 + covariance: [10.55054359885904, -5.4152738420484285e-08, 0.0, 0.0, -8.784640589624779e-05, 0.0, -5.4152738420484146e-08, 10.550543528577931, 0.0, 0.0, 2.4345226219172533e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.784640589624779e-05, 2.434522621917253e-05, 0.0, 0.0, 10.353573181533516, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 241 + stamp: + secs: 1624875215 + nsecs: 720865965 + frame_id: "/world" +pose: + pose: + position: + x: -0.00434722958263 + y: 0.06423670905 + z: 0.0 + orientation: + x: -0.0 + y: -6.38446039172e-05 + z: -0.0 + w: 0.999999997962 + covariance: [8.828169644815633, -3.902870911971071e-08, 0.0, 0.0, -7.134134492095369e-05, 0.0, -3.902870911971062e-08, 8.828169593198318, 0.0, 0.0, 2.594494988387849e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.134134492095365e-05, 2.594494988387848e-05, 0.0, 0.0, 8.685790638101329, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 242 + stamp: + secs: 1624875215 + nsecs: 800864935 + frame_id: "/world" +pose: + pose: + position: + x: -0.00297010914268 + y: 0.0647492858916 + z: 0.0 + orientation: + x: -0.0 + y: -0.00076509924747 + z: -0.0 + w: 0.999999707312 + covariance: [9.17954416560928, -3.7234061100837046e-08, 0.0, 0.0, -6.408638828874446e-05, 0.0, -3.723406110083696e-08, 9.179544115803964, 0.0, 0.0, 2.83640195133529e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.408638828874441e-05, 2.8364019513352903e-05, 0.0, 0.0, 9.04414332849416, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 243 + stamp: + secs: 1624875215 + nsecs: 880872965 + frame_id: "/world" +pose: + pose: + position: + x: -0.0036990268919 + y: 0.0651792634514 + z: 0.0 + orientation: + x: 0.0 + y: 0.000173045211764 + z: 0.0 + w: 0.999999985028 + covariance: [8.352152273720842, -2.791866130978887e-08, 0.0, 0.0, -4.3799434993384336e-05, 0.0, -2.7918661309788822e-08, 8.352152236021958, 0.0, 0.0, 1.8509253724775445e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.379943499338434e-05, 1.850925372477544e-05, 0.0, 0.0, 8.250548869313363, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 244 + stamp: + secs: 1624875215 + nsecs: 960884094 + frame_id: "/world" +pose: + pose: + position: + x: -0.0051950953878 + y: 0.0654242392408 + z: 0.0 + orientation: + x: 0.0 + y: 0.000745254998048 + z: 0.0 + w: 0.999999722297 + covariance: [8.961322293318196, -3.00283817178981e-08, 0.0, 0.0, -3.9949602005538735e-05, 0.0, -3.0028381717898045e-08, 8.961322252392279, 0.0, 0.0, 1.5287486886346224e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.994960200553875e-05, 1.5287486886346227e-05, 0.0, 0.0, 8.852036184758443, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 245 + stamp: + secs: 1624875216 + nsecs: 40893078 + frame_id: "/world" +pose: + pose: + position: + x: -0.00462501474052 + y: 0.0570189132863 + z: 0.0 + orientation: + x: 0.0 + y: 0.000339209737102 + z: 0.0 + w: 0.999999942468 + covariance: [9.227803356502848, -3.054075899487807e-08, 0.0, 0.0, -3.5462707163230826e-05, 0.0, -3.054075899487801e-08, 9.227803314752151, 0.0, 0.0, 2.2000972444372317e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.5462707163230826e-05, 2.200097244437232e-05, 0.0, 0.0, 9.116464924661317, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 246 + stamp: + secs: 1624875216 + nsecs: 120889902 + frame_id: "/world" +pose: + pose: + position: + x: -0.00474314028046 + y: 0.0580832813365 + z: 0.0 + orientation: + x: -0.0 + y: -5.64664644595e-05 + z: -0.0 + w: 0.999999998406 + covariance: [7.561712211729876, -1.6953993885667214e-08, 0.0, 0.0, -1.7867531518259483e-05, 0.0, -1.6953993885667177e-08, 7.561712188600815, 0.0, 0.0, 1.4742806683286563e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7867531518259466e-05, 1.4742806683286557e-05, 0.0, 0.0, 7.4996740251886, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 247 + stamp: + secs: 1624875216 + nsecs: 200895071 + frame_id: "/world" +pose: + pose: + position: + x: -0.00952733263024 + y: 0.0624660762898 + z: 0.0 + orientation: + x: -0.0 + y: -3.49796891346e-05 + z: -0.0 + w: 0.999999999388 + covariance: [9.624967807753034, -2.772411411376943e-08, 0.0, 0.0, -3.556741596344105e-05, 0.0, -2.7724114113769373e-08, 9.624967770016786, 0.0, 0.0, 2.0345766301141725e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.5567415963441026e-05, 2.0345766301141722e-05, 0.0, 0.0, 9.523615842787363, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 248 + stamp: + secs: 1624875216 + nsecs: 280922890 + frame_id: "/world" +pose: + pose: + position: + x: -0.00968246941909 + y: 0.0628698965267 + z: 0.0 + orientation: + x: -0.0 + y: -1.9143100464e-05 + z: -0.0 + w: 0.999999999817 + covariance: [7.657982433235563, -1.2256123116096942e-08, 0.0, 0.0, -2.0001014487176816e-05, 0.0, -1.2256123116096925e-08, 7.657982416551683, 0.0, 0.0, 1.0810327728259119e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.0001014487176812e-05, 1.0810327728259119e-05, 0.0, 0.0, 7.6130521195637355, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 249 + stamp: + secs: 1624875216 + nsecs: 360913038 + frame_id: "/world" +pose: + pose: + position: + x: -0.0175889191978 + y: 0.070601657139 + z: 0.0 + orientation: + x: -0.0 + y: -0.000114967754822 + z: -0.0 + w: 0.999999993391 + covariance: [7.799800514213597, -1.7765688985013408e-08, 0.0, 0.0, -2.4113895835383272e-05, 0.0, -1.776568898501339e-08, 7.799800490144185, 0.0, 0.0, 1.779217385452581e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4113895835383262e-05, 1.779217385452581e-05, 0.0, 0.0, 7.73497596581193, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 250 + stamp: + secs: 1624875216 + nsecs: 440912962 + frame_id: "/world" +pose: + pose: + position: + x: -0.0111347615334 + y: 0.0720797402101 + z: 0.0 + orientation: + x: -0.0 + y: -0.00313113339479 + z: -0.0 + w: 0.99999509799 + covariance: [11.086264808328348, -2.7451609546839754e-08, 0.0, 0.0, -2.5393042739386356e-05, 0.0, -2.7451609546839717e-08, 11.086264771241598, 0.0, 0.0, 2.231606862979602e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5393042739386336e-05, 2.2316068629796017e-05, 0.0, 0.0, 10.986202199779125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 251 + stamp: + secs: 1624875216 + nsecs: 520924091 + frame_id: "/world" +pose: + pose: + position: + x: -0.0176145459004 + y: 0.0952932995625 + z: 0.0 + orientation: + x: -0.0 + y: -0.000539994284706 + z: -0.0 + w: 0.999999854203 + covariance: [8.957720488420737, -1.9913520809775903e-08, 0.0, 0.0, -1.3186543950569981e-05, 0.0, -1.991352080977587e-08, 8.957720461628089, 0.0, 0.0, 1.8129654095901322e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.318654395056997e-05, 1.8129654095901315e-05, 0.0, 0.0, 8.884689190699593, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 252 + stamp: + secs: 1624875216 + nsecs: 600929976 + frame_id: "/world" +pose: + pose: + position: + x: -0.00227311510975 + y: 0.0856314424076 + z: 0.0 + orientation: + x: -0.0 + y: -0.000571691948247 + z: -0.0 + w: 0.999999836584 + covariance: [9.249217489578697, -3.214591485542136e-08, 0.0, 0.0, -2.669066316909474e-05, 0.0, -3.21459148554213e-08, 9.24921744684516, 0.0, 0.0, 3.4796363510082736e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.669066316909473e-05, 3.479636351008273e-05, 0.0, 0.0, 9.130697227271575, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 253 + stamp: + secs: 1624875216 + nsecs: 680928946 + frame_id: "/world" +pose: + pose: + position: + x: -0.00407794366128 + y: 0.0821168499716 + z: 0.0 + orientation: + x: -0.0 + y: -0.000270479546038 + z: -0.0 + w: 0.99999996342 + covariance: [9.28130171182913, -1.2152334580806941e-08, 0.0, 0.0, -1.0872731885630971e-05, 0.0, -1.215233458080692e-08, 9.28130169563849, 0.0, 0.0, 1.3310922499452967e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0872731885630968e-05, 1.3310922499452959e-05, 0.0, 0.0, 9.23636468046703, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 254 + stamp: + secs: 1624875216 + nsecs: 760956049 + frame_id: "/world" +pose: + pose: + position: + x: -0.00293510007491 + y: 0.0816278190751 + z: 0.0 + orientation: + x: 0.0 + y: 0.000215235737207 + z: 0.0 + w: 0.999999976837 + covariance: [8.370450718232606, -1.4457045498095123e-08, 0.0, 0.0, -6.25518563050342e-06, 0.0, -1.4457045498095094e-08, 8.370450699149815, 0.0, 0.0, 1.2192957973476712e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.25518563050342e-06, 1.2192957973476712e-05, 0.0, 0.0, 8.316493186861369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 255 + stamp: + secs: 1624875216 + nsecs: 840961933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0171471293749 + y: 0.0712330221549 + z: 0.0 + orientation: + x: 0.0 + y: 0.000280165973088 + z: 0.0 + w: 0.999999960754 + covariance: [6.713941878726659, -1.3621562469917298e-08, 0.0, 0.0, -5.93445102532608e-06, 0.0, -1.3621562469917268e-08, 6.713941860848399, 0.0, 0.0, 7.480209401786917e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.934451025326083e-06, 7.480209401786922e-06, 0.0, 0.0, 6.662499164396891, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 256 + stamp: + secs: 1624875216 + nsecs: 920965910 + frame_id: "/world" +pose: + pose: + position: + x: -0.0162324440825 + y: 0.0705944233176 + z: 0.0 + orientation: + x: 0.0 + y: 0.000470254718033 + z: 0.0 + w: 0.99999988943 + covariance: [8.17245387035625, -1.5381028822196277e-08, 0.0, 0.0, -5.166583246871375e-06, 0.0, -1.538102882219625e-08, 8.172453850212307, 0.0, 0.0, 6.080520172012385e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.166583246871377e-06, 6.080520172012387e-06, 0.0, 0.0, 8.11397794221845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 257 + stamp: + secs: 1624875217 + nsecs: 967979 + frame_id: "/world" +pose: + pose: + position: + x: -0.0241125071193 + y: 0.0840498281046 + z: 0.0 + orientation: + x: 0.0 + y: 0.000283471962543 + z: 0.0 + w: 0.999999959822 + covariance: [7.25094580332763, -1.1441669771911934e-08, 0.0, 0.0, -2.5177522174211317e-06, 0.0, -1.144166977191191e-08, 7.250945788365458, 0.0, 0.0, 3.091392209867352e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5177522174211326e-06, 3.0913922098673513e-06, 0.0, 0.0, 7.207096967173331, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 258 + stamp: + secs: 1624875217 + nsecs: 80965996 + frame_id: "/world" +pose: + pose: + position: + x: -0.0241688069637 + y: 0.0839436861047 + z: 0.0 + orientation: + x: 0.0 + y: 0.000460681419104 + z: 0.0 + w: 0.999999893886 + covariance: [9.436493746824015, -2.1560195130023e-08, 0.0, 0.0, -2.4052885787123106e-06, 0.0, -2.1560195130022954e-08, 9.43649371865951, 0.0, 0.0, -2.76934132889672e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4052885787123123e-06, -2.7693413288967194e-06, 0.0, 0.0, 9.352887104348817, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 259 + stamp: + secs: 1624875217 + nsecs: 160985947 + frame_id: "/world" +pose: + pose: + position: + x: -0.0241411081453 + y: 0.084122340971 + z: 0.0 + orientation: + x: 0.0 + y: 0.000531346590116 + z: 0.0 + w: 0.999999858835 + covariance: [8.436984782275893, -2.0531034005104698e-08, 0.0, 0.0, -5.212591808795111e-06, 0.0, -2.0531034005104665e-08, 8.436984755475983, 0.0, 0.0, -6.592266707913469e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.212591808795113e-06, -6.592266707913466e-06, 0.0, 0.0, 8.356424664524289, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 260 + stamp: + secs: 1624875217 + nsecs: 240998983 + frame_id: "/world" +pose: + pose: + position: + x: -0.0252538267731 + y: 0.0874980426231 + z: 0.0 + orientation: + x: 0.0 + y: 0.000432292809821 + z: 0.0 + w: 0.999999906561 + covariance: [7.356601899518692, -1.920943968622396e-08, 0.0, 0.0, -2.592706261830272e-05, 0.0, -1.920943968622393e-08, 7.356601874216965, 0.0, 0.0, -4.924689770982821e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.592706261830273e-05, -4.924689770982818e-06, 0.0, 0.0, 7.279908667478952, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 261 + stamp: + secs: 1624875217 + nsecs: 320986986 + frame_id: "/world" +pose: + pose: + position: + x: -0.0217531034728 + y: 0.0881097431874 + z: 0.0 + orientation: + x: 0.0 + y: 0.000334791440941 + z: 0.0 + w: 0.999999943957 + covariance: [10.75306856667875, -2.6608138860369167e-08, 0.0, 0.0, -4.6659721097720626e-05, 0.0, -2.660813886036911e-08, 10.75306853104519, 0.0, 0.0, -5.327562974131941e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.665972109772062e-05, -5.3275629741319374e-06, 0.0, 0.0, 10.646055575762476, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 262 + stamp: + secs: 1624875217 + nsecs: 400985956 + frame_id: "/world" +pose: + pose: + position: + x: -0.0218563625432 + y: 0.0879927508321 + z: 0.0 + orientation: + x: 0.0 + y: 0.000338186469781 + z: 0.0 + w: 0.999999942815 + covariance: [11.347516422114746, -2.475000148122466e-08, 0.0, 0.0, -4.257785933597125e-05, 0.0, -2.4750001481224614e-08, 11.347516388460528, 0.0, 0.0, -3.890403036416949e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.257785933597124e-05, -3.8904030364169465e-06, 0.0, 0.0, 11.246997731326996, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 263 + stamp: + secs: 1624875217 + nsecs: 481002092 + frame_id: "/world" +pose: + pose: + position: + x: -0.014028992128 + y: 0.0846464230234 + z: 0.0 + orientation: + x: 0.0 + y: 0.000469277313099 + z: 0.0 + w: 0.999999889889 + covariance: [10.21196899125339, -2.8039177571170695e-08, 0.0, 0.0, -6.1188805334025e-05, 0.0, -2.8039177571170626e-08, 10.211968951882042, 0.0, 0.0, 2.305113504930296e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.118880533402497e-05, 2.3051135049302984e-06, 0.0, 0.0, 10.096346062494673, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 264 + stamp: + secs: 1624875217 + nsecs: 561059952 + frame_id: "/world" +pose: + pose: + position: + x: -0.0144321910938 + y: 0.0848011778457 + z: 0.0 + orientation: + x: 0.0 + y: 0.000294406595817 + z: 0.0 + w: 0.999999956662 + covariance: [8.692478145507991, -2.1424637800399577e-08, 0.0, 0.0, -4.9723440631133514e-05, 0.0, -2.1424637800399524e-08, 8.692478114596213, 0.0, 0.0, 4.502069410925643e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.972344063113353e-05, 4.502069410925643e-06, 0.0, 0.0, 8.60291855181104, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 265 + stamp: + secs: 1624875217 + nsecs: 641020060 + frame_id: "/world" +pose: + pose: + position: + x: -0.0158168247522 + y: 0.110145320944 + z: 0.0 + orientation: + x: -0.0 + y: -0.000246962277513 + z: -0.0 + w: 0.999999969505 + covariance: [9.105591692913698, -2.2984388471479632e-08, 0.0, 0.0, -5.037639655991242e-05, 0.0, -2.2984388471479582e-08, 9.105591658718529, 0.0, 0.0, -6.487841183486836e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.037639655991244e-05, -6.487841183486838e-06, 0.0, 0.0, 9.007905997274118, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 266 + stamp: + secs: 1624875217 + nsecs: 721040964 + frame_id: "/world" +pose: + pose: + position: + x: -0.0163910006196 + y: 0.10997282385 + z: 0.0 + orientation: + x: 0.0 + y: 0.000504698130175 + z: 0.0 + w: 0.99999987264 + covariance: [10.476532926547655, -2.3728347597892907e-08, 0.0, 0.0, -5.480030347788705e-05, 0.0, -2.3728347597892854e-08, 10.476532890473688, 0.0, 0.0, 9.39089268945085e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.480030347788706e-05, 9.390892689450846e-07, 0.0, 0.0, 10.375182415363529, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 267 + stamp: + secs: 1624875217 + nsecs: 801040888 + frame_id: "/world" +pose: + pose: + position: + x: -0.0157819679493 + y: 0.10356212302 + z: 0.0 + orientation: + x: 0.0 + y: 0.000707661733369 + z: 0.0 + w: 0.999999749607 + covariance: [8.765977667677582, -1.704787079257099e-08, 0.0, 0.0, -3.759672604481405e-05, 0.0, -1.704787079257095e-08, 8.765977641454265, 0.0, 0.0, 1.4020459532891577e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.759672604481405e-05, 1.4020459532891572e-05, 0.0, 0.0, 8.692711181407114, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 268 + stamp: + secs: 1624875217 + nsecs: 881045103 + frame_id: "/world" +pose: + pose: + position: + x: -0.0157617936655 + y: 0.103537593058 + z: 0.0 + orientation: + x: 0.0 + y: 0.00023024572507 + z: 0.0 + w: 0.999999973493 + covariance: [9.127118255804017, -1.8589753929306925e-08, 0.0, 0.0, -3.834930374885794e-05, 0.0, -1.858975392930688e-08, 9.12711822714422, 0.0, 0.0, 2.3249747638941744e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.834930374885794e-05, 2.3249747638941744e-05, 0.0, 0.0, 9.047146788471325, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 269 + stamp: + secs: 1624875217 + nsecs: 961061954 + frame_id: "/world" +pose: + pose: + position: + x: -0.0160022069674 + y: 0.101264606954 + z: 0.0 + orientation: + x: -0.0 + y: -2.05955976219e-06 + z: -0.0 + w: 0.999999999998 + covariance: [9.280148608135404, -1.853655774619999e-08, 0.0, 0.0, -3.393871719767575e-05, 0.0, -1.853655774619995e-08, 9.280148579657743, 0.0, 0.0, 2.3649423924133597e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.393871719767576e-05, 2.364942392413359e-05, 0.0, 0.0, 9.200572872772808, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 270 + stamp: + secs: 1624875218 + nsecs: 41070938 + frame_id: "/world" +pose: + pose: + position: + x: -0.0166786285013 + y: 0.101258173606 + z: 0.0 + orientation: + x: 0.0 + y: 4.00811291363e-05 + z: 0.0 + w: 0.999999999197 + covariance: [7.573238550013201, -1.1599592163956767e-08, 0.0, 0.0, -1.9306425249721244e-05, 0.0, -1.1599592163956737e-08, 7.57323853224109, 0.0, 0.0, 1.2136398932431394e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9306425249721248e-05, 1.2136398932431394e-05, 0.0, 0.0, 7.523366607453662, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 271 + stamp: + secs: 1624875218 + nsecs: 121073961 + frame_id: "/world" +pose: + pose: + position: + x: -0.0310024038017 + y: 0.123518610006 + z: 0.0 + orientation: + x: 0.0 + y: 2.28278189278e-05 + z: 0.0 + w: 0.999999999739 + covariance: [8.611350154351175, -2.0922805244139845e-08, 0.0, 0.0, -3.360651221799119e-05, 0.0, -2.0922805244139802e-08, 8.61135012239874, 0.0, 0.0, 1.7682404887827358e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.36065122179912e-05, 1.7682404887827355e-05, 0.0, 0.0, 8.521660623371176, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 272 + stamp: + secs: 1624875218 + nsecs: 201076984 + frame_id: "/world" +pose: + pose: + position: + x: -0.0295473596786 + y: 0.122755551436 + z: 0.0 + orientation: + x: -0.0 + y: -0.000174224676154 + z: -0.0 + w: 0.999999984823 + covariance: [8.137870649464606, -1.6359401516603505e-08, 0.0, 0.0, -2.435632795036903e-05, 0.0, -1.6359401516603472e-08, 8.137870624513376, 0.0, 0.0, 1.229064719502848e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4356327950369032e-05, 1.229064719502848e-05, 0.0, 0.0, 8.067570042218467, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 273 + stamp: + secs: 1624875218 + nsecs: 281084061 + frame_id: "/world" +pose: + pose: + position: + x: -0.0413032629031 + y: 0.124896552262 + z: 0.0 + orientation: + x: 0.0 + y: 0.000336973830841 + z: 0.0 + w: 0.999999943224 + covariance: [9.966079966340287, -2.697620301510589e-08, 0.0, 0.0, -4.8079123576179595e-05, 0.0, -2.6976203015105838e-08, 9.966079925033428, 0.0, 0.0, 1.3908743027610083e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.807912357617959e-05, 1.3908743027610076e-05, 0.0, 0.0, 9.850077924132883, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 274 + stamp: + secs: 1624875218 + nsecs: 361097097 + frame_id: "/world" +pose: + pose: + position: + x: -0.0404537513774 + y: 0.121312596848 + z: 0.0 + orientation: + x: 0.0 + y: 0.000235917738546 + z: 0.0 + w: 0.999999972171 + covariance: [7.774236493718708, -1.6656342044344385e-08, 0.0, 0.0, -3.073700647049805e-05, 0.0, -1.665634204434434e-08, 7.774236467995816, 0.0, 0.0, 5.92645014369391e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.073700647049804e-05, 5.92645014369391e-06, 0.0, 0.0, 7.701916927177735, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 275 + stamp: + secs: 1624875218 + nsecs: 441102982 + frame_id: "/world" +pose: + pose: + position: + x: -0.0417942331941 + y: 0.123835068238 + z: 0.0 + orientation: + x: 0.0 + y: 3.14010999258e-05 + z: 0.0 + w: 0.999999999507 + covariance: [7.854946947060816, -1.970889987304746e-08, 0.0, 0.0, -2.7456760721409598e-05, 0.0, -1.9708899873047416e-08, 7.854946916286739, 0.0, 0.0, 3.626418537073347e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.7456760721409587e-05, 3.626418537073347e-06, 0.0, 0.0, 7.768245371350959, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 276 + stamp: + secs: 1624875218 + nsecs: 521126986 + frame_id: "/world" +pose: + pose: + position: + x: -0.0405717424084 + y: 0.13558013802 + z: 0.0 + orientation: + x: -0.0 + y: -4.84430042242e-05 + z: -0.0 + w: 0.999999998827 + covariance: [8.729551391164732, -2.1489390754909866e-08, 0.0, 0.0, -2.5533321877220025e-05, 0.0, -2.1489390754909826e-08, 8.729551357365079, 0.0, 0.0, 2.262257605360362e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5533321877220008e-05, 2.262257605360362e-06, 0.0, 0.0, 8.634244638027033, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 277 + stamp: + secs: 1624875218 + nsecs: 601133108 + frame_id: "/world" +pose: + pose: + position: + x: -0.0491459520337 + y: 0.140117946717 + z: 0.0 + orientation: + x: 0.0 + y: 0.000189809280159 + z: 0.0 + w: 0.999999981986 + covariance: [9.115796598182168, -2.102238871220785e-08, 0.0, 0.0, -3.6303744557460175e-05, 0.0, -2.1022388712207814e-08, 9.11579656475338, 0.0, 0.0, 1.7719671767232925e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.630374455746016e-05, 1.7719671767232919e-06, 0.0, 0.0, 9.021709465624518, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 278 + stamp: + secs: 1624875218 + nsecs: 681112051 + frame_id: "/world" +pose: + pose: + position: + x: -0.0352096968992 + y: 0.149100843891 + z: 0.0 + orientation: + x: 0.0 + y: 0.000313488462214 + z: 0.0 + w: 0.999999950862 + covariance: [10.521102410110904, -3.0689420227105474e-08, 0.0, 0.0, -6.187476188549111e-05, 0.0, -3.0689420227105434e-08, 10.521102360220619, 0.0, 0.0, 2.5528904946696843e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.187476188549111e-05, 2.5528904946696835e-06, 0.0, 0.0, 10.38264195141639, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 279 + stamp: + secs: 1624875218 + nsecs: 761149883 + frame_id: "/world" +pose: + pose: + position: + x: -0.03534098592 + y: 0.149286543155 + z: 0.0 + orientation: + x: 0.0 + y: 0.000844725026851 + z: 0.0 + w: 0.99999964322 + covariance: [11.294115144251242, -4.029153742967264e-08, 0.0, 0.0, -7.445542228972995e-05, 0.0, -4.029153742967259e-08, 11.294115077580472, 0.0, 0.0, 7.270024378021731e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.445542228972996e-05, 7.2700243780217315e-06, 0.0, 0.0, 11.111232566026207, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 280 + stamp: + secs: 1624875218 + nsecs: 841130018 + frame_id: "/world" +pose: + pose: + position: + x: -0.0354464900307 + y: 0.149434071783 + z: 0.0 + orientation: + x: 0.0 + y: 0.000960975370219 + z: 0.0 + w: 0.999999538263 + covariance: [11.672857023527532, -4.081922672465459e-08, 0.0, 0.0, -6.683877956246246e-05, 0.0, -4.081922672465455e-08, 11.672856955283638, 0.0, 0.0, 1.0013183260459795e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.683877956246249e-05, 1.0013183260459795e-05, 0.0, 0.0, 11.486050684066587, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 281 + stamp: + secs: 1624875218 + nsecs: 921133995 + frame_id: "/world" +pose: + pose: + position: + x: -0.0357860045865 + y: 0.151722708619 + z: 0.0 + orientation: + x: 0.0 + y: 6.71629794451e-06 + z: 0.0 + w: 0.999999999977 + covariance: [8.22779942780541, -2.316269969148566e-08, 0.0, 0.0, -3.674960538501994e-05, 0.0, -2.3162699691485644e-08, 8.227799388786872, 0.0, 0.0, 1.2992120337523732e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.674960538501995e-05, 1.299212033752373e-05, 0.0, 0.0, 8.119437360492938, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 282 + stamp: + secs: 1624875219 + nsecs: 1161098 + frame_id: "/world" +pose: + pose: + position: + x: -0.0359471147765 + y: 0.15195411062 + z: 0.0 + orientation: + x: -0.0 + y: -0.000491861364237 + z: -0.0 + w: 0.999999879036 + covariance: [11.494299815047237, -4.762118831298934e-08, 0.0, 0.0, -4.9055425024230915e-05, 0.0, -4.76211883129893e-08, 11.494299734782413, 0.0, 0.0, 3.500129792175325e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.905542502423091e-05, 3.500129792175325e-05, 0.0, 0.0, 11.270982545901205, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 283 + stamp: + secs: 1624875219 + nsecs: 81146002 + frame_id: "/world" +pose: + pose: + position: + x: -0.0366984363367 + y: 0.151700355494 + z: 0.0 + orientation: + x: 0.0 + y: 0.000262541183048 + z: 0.0 + w: 0.999999965536 + covariance: [10.262376702020225, -3.312905331430495e-08, 0.0, 0.0, -2.0144639796169324e-05, 0.0, -3.312905331430493e-08, 10.26237664619625, 0.0, 0.0, 2.2122363025372166e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.014463979616933e-05, 2.212236302537217e-05, 0.0, 0.0, 10.105191890081077, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 284 + stamp: + secs: 1624875219 + nsecs: 161160946 + frame_id: "/world" +pose: + pose: + position: + x: -0.0401339948277 + y: 0.134152669667 + z: 0.0 + orientation: + x: 0.0 + y: 7.53329863328e-05 + z: 0.0 + w: 0.999999997162 + covariance: [7.870386796872362, -2.0839167897119414e-08, 0.0, 0.0, -6.048299715137678e-06, 0.0, -2.0839167897119394e-08, 7.870386761751339, 0.0, 0.0, 1.0571023990326054e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.048299715137681e-06, 1.057102399032605e-05, 0.0, 0.0, 7.769861519823542, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 285 + stamp: + secs: 1624875219 + nsecs: 241172075 + frame_id: "/world" +pose: + pose: + position: + x: -0.0419956496837 + y: 0.133349295471 + z: 0.0 + orientation: + x: 0.0 + y: 3.8919773273e-05 + z: 0.0 + w: 0.999999999243 + covariance: [9.757901201824362, -1.615013858566068e-08, 0.0, 0.0, -3.905498453618557e-06, 0.0, -1.615013858566066e-08, 9.757901174604209, 0.0, 0.0, 7.3169956535761965e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.905498453618559e-06, 7.3169956535761965e-06, 0.0, 0.0, 9.679662175491416, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 286 + stamp: + secs: 1624875219 + nsecs: 321162939 + frame_id: "/world" +pose: + pose: + position: + x: -0.0420276855955 + y: 0.120683444408 + z: 0.0 + orientation: + x: 0.0 + y: 0.000256109132191 + z: 0.0 + w: 0.999999967204 + covariance: [10.823373759355457, -1.7367828654690994e-08, 0.0, 0.0, -1.592441507760842e-05, 0.0, -1.736782865469097e-08, 10.823373730072234, 0.0, 0.0, 7.157799035097808e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5924415077608422e-05, 7.157799035097807e-06, 0.0, 0.0, 10.738663322249108, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 287 + stamp: + secs: 1624875219 + nsecs: 401169062 + frame_id: "/world" +pose: + pose: + position: + x: -0.0507467133355 + y: 0.0938097956612 + z: 0.0 + orientation: + x: 0.0 + y: 0.00018453424974 + z: 0.0 + w: 0.999999982974 + covariance: [11.437187084941213, -2.8901893232344862e-08, 0.0, 0.0, -4.3524269510643165e-05, 0.0, -2.8901893232344825e-08, 11.43718703590184, 0.0, 0.0, 9.79693011595575e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.3524269510643165e-05, 9.796930115955749e-06, 0.0, 0.0, 11.294640879337265, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 288 + stamp: + secs: 1624875219 + nsecs: 481182098 + frame_id: "/world" +pose: + pose: + position: + x: -0.0506857715807 + y: 0.0942720548888 + z: 0.0 + orientation: + x: -0.0 + y: -8.74122999981e-05 + z: -0.0 + w: 0.99999999618 + covariance: [11.739959508623494, -3.257103593075112e-08, 0.0, 0.0, -9.294943096418808e-05, 0.0, -3.257103593075107e-08, 11.739959452359033, 0.0, 0.0, 1.204969520079699e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.294943096418808e-05, 1.2049695200796989e-05, 0.0, 0.0, 11.5781916668335, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 289 + stamp: + secs: 1624875219 + nsecs: 561197996 + frame_id: "/world" +pose: + pose: + position: + x: -0.0509143516252 + y: 0.0943352868521 + z: 0.0 + orientation: + x: -0.0 + y: -5.92030544848e-05 + z: -0.0 + w: 0.999999998247 + covariance: [9.167023623234195, -2.0478284458541065e-08, 0.0, 0.0, -8.290888327183702e-05, 0.0, -2.0478284458541022e-08, 9.167023586338006, 0.0, 0.0, 7.986376467238491e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.290888327183702e-05, 7.986376467238493e-06, 0.0, 0.0, 9.06449808532327, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 290 + stamp: + secs: 1624875219 + nsecs: 641206980 + frame_id: "/world" +pose: + pose: + position: + x: -0.0511430949886 + y: 0.094181785855 + z: 0.0 + orientation: + x: 0.0 + y: 0.000241381877212 + z: 0.0 + w: 0.999999970867 + covariance: [9.353654567295555, -2.8959586566399096e-08, 0.0, 0.0, -0.00011722356317028861, 0.0, -2.895958656639905e-08, 9.353654510850925, 0.0, 0.0, 9.291887180752112e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001172235631702886, 9.291887180752112e-06, 0.0, 0.0, 9.208057042642073, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 291 + stamp: + secs: 1624875219 + nsecs: 721213102 + frame_id: "/world" +pose: + pose: + position: + x: -0.050830567826 + y: 0.0943375293178 + z: 0.0 + orientation: + x: 0.0 + y: 0.000331138239506 + z: 0.0 + w: 0.999999945174 + covariance: [8.403328624832772, -1.9044157169744098e-08, 0.0, 0.0, -6.843436980133473e-05, 0.0, -1.904415716974407e-08, 8.403328586434307, 0.0, 0.0, 5.201724966056587e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.843436980133473e-05, 5.201724966056586e-06, 0.0, 0.0, 8.306848301619763, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 292 + stamp: + secs: 1624875219 + nsecs: 801218987 + frame_id: "/world" +pose: + pose: + position: + x: -0.0508578682909 + y: 0.0941211765351 + z: 0.0 + orientation: + x: 0.0 + y: 5.21441833382e-05 + z: 0.0 + w: 0.99999999864 + covariance: [8.08015777626766, -1.7567855022527648e-08, 0.0, 0.0, -4.650740645991955e-05, 0.0, -1.756785502252762e-08, 8.08015773949523, 0.0, 0.0, 4.166463138912054e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.650740645991952e-05, 4.166463138912054e-06, 0.0, 0.0, 7.990455010738556, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 293 + stamp: + secs: 1624875219 + nsecs: 881227016 + frame_id: "/world" +pose: + pose: + position: + x: -0.0507480716805 + y: 0.0940406008887 + z: 0.0 + orientation: + x: 0.0 + y: 7.20921506875e-05 + z: 0.0 + w: 0.999999997401 + covariance: [9.936361020735706, -2.5390082679973924e-08, 0.0, 0.0, -4.776805727068017e-05, 0.0, -2.5390082679973887e-08, 9.936360966201422, 0.0, 0.0, 4.262076606348141e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.776805727068014e-05, 4.262076606348142e-06, 0.0, 0.0, 9.805963393961004, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 294 + stamp: + secs: 1624875219 + nsecs: 961224079 + frame_id: "/world" +pose: + pose: + position: + x: -0.0509077950302 + y: 0.0939293788225 + z: 0.0 + orientation: + x: 0.0 + y: 0.000143551224914 + z: 0.0 + w: 0.999999989697 + covariance: [10.956125884437435, -2.8958589000604986e-08, 0.0, 0.0, -4.1490499612089104e-05, 0.0, -2.8958589000604943e-08, 10.956125821305882, 0.0, 0.0, 2.987127645119009e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.149049961208909e-05, 2.98712764511901e-06, 0.0, 0.0, 10.806078681936123, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 295 + stamp: + secs: 1624875220 + nsecs: 41249990 + frame_id: "/world" +pose: + pose: + position: + x: -0.0530612294007 + y: 0.0915742887627 + z: 0.0 + orientation: + x: 0.0 + y: 0.000187613908266 + z: 0.0 + w: 0.999999982401 + covariance: [11.484871785570213, -2.976972514142668e-08, 0.0, 0.0, -5.993975313747133e-05, 0.0, -2.976972514142664e-08, 11.484871719720353, 0.0, 0.0, 3.5720020391979653e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.993975313747131e-05, 3.5720020391979657e-06, 0.0, 0.0, 11.32934237189766, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 296 + stamp: + secs: 1624875220 + nsecs: 121259928 + frame_id: "/world" +pose: + pose: + position: + x: -0.0440826894036 + y: 0.0826286869839 + z: 0.0 + orientation: + x: 0.0 + y: 0.000172882266807 + z: 0.0 + w: 0.999999985056 + covariance: [9.108335692150984, -2.2387113586914255e-08, 0.0, 0.0, -6.179075216859556e-05, 0.0, -2.2387113586914225e-08, 9.10833564131358, 0.0, 0.0, 2.981889370687656e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.179075216859557e-05, 2.981889370687656e-06, 0.0, 0.0, 8.989635544123699, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 297 + stamp: + secs: 1624875220 + nsecs: 201256037 + frame_id: "/world" +pose: + pose: + position: + x: -0.04364657404 + y: 0.0878379821386 + z: 0.0 + orientation: + x: 0.0 + y: 8.16192947917e-05 + z: 0.0 + w: 0.999999996669 + covariance: [8.31225010077153, -1.503888141954269e-08, 0.0, 0.0, -4.005553518492027e-05, 0.0, -1.503888141954267e-08, 8.312250066045534, 0.0, 0.0, 2.3590728638680935e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.005553518492028e-05, 2.3590728638680935e-06, 0.0, 0.0, 8.231721709126264, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 298 + stamp: + secs: 1624875220 + nsecs: 281263113 + frame_id: "/world" +pose: + pose: + position: + x: -0.0402217839338 + y: 0.0988122246293 + z: 0.0 + orientation: + x: 0.0 + y: 0.000268627049241 + z: 0.0 + w: 0.99999996392 + covariance: [7.305062166783383, -1.1574652741335422e-08, 0.0, 0.0, -4.003355845117491e-05, 0.0, -1.1574652741335406e-08, 7.305062139284948, 0.0, 0.0, 2.103506726880203e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.003355845117491e-05, 2.1035067268802043e-06, 0.0, 0.0, 7.242470541656813, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 299 + stamp: + secs: 1624875220 + nsecs: 361269951 + frame_id: "/world" +pose: + pose: + position: + x: -0.0420152515519 + y: 0.102702965718 + z: 0.0 + orientation: + x: 0.0 + y: 0.000143539446017 + z: 0.0 + w: 0.999999989698 + covariance: [8.444681606362355, -9.967363868672109e-09, 0.0, 0.0, -3.807250272708009e-05, 0.0, -9.967363868672097e-09, 8.444681582097752, 0.0, 0.0, 1.6902185979647448e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.80725027270801e-05, 1.6902185979647455e-06, 0.0, 0.0, 8.390504493613426, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 300 + stamp: + secs: 1624875220 + nsecs: 441265106 + frame_id: "/world" +pose: + pose: + position: + x: -0.0386827177282 + y: 0.121875523491 + z: 0.0 + orientation: + x: -0.0 + y: -0.00030935597492 + z: -0.0 + w: 0.999999952149 + covariance: [8.076866386553156, -1.0250932619542888e-08, 0.0, 0.0, -3.146828803862271e-05, 0.0, -1.0250932619542877e-08, 8.076866360724768, 0.0, 0.0, 1.3176934142929505e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.146828803862272e-05, 1.317693414292951e-06, 0.0, 0.0, 8.020519312994516, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 301 + stamp: + secs: 1624875220 + nsecs: 521287918 + frame_id: "/world" +pose: + pose: + position: + x: -0.0392771954222 + y: 0.123831444139 + z: 0.0 + orientation: + x: 0.0 + y: 3.61263976611e-05 + z: 0.0 + w: 0.999999999347 + covariance: [6.623998264349917, -6.5677722763286285e-09, 0.0, 0.0, -1.642587479189633e-05, 0.0, -6.567772276328617e-09, 6.6239982474547965, 0.0, 0.0, 1.389356026604102e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.6425874791896334e-05, 1.3893560266041028e-06, 0.0, 0.0, 6.587538557310554, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 302 + stamp: + secs: 1624875220 + nsecs: 601290941 + frame_id: "/world" +pose: + pose: + position: + x: -0.0386279976936 + y: 0.131041876207 + z: 0.0 + orientation: + x: -0.0 + y: -2.56956272488e-05 + z: -0.0 + w: 0.99999999967 + covariance: [7.392537469691228, -9.958020728081738e-09, 0.0, 0.0, -3.8946570057107736e-05, 0.0, -9.958020728081729e-09, 7.3925374432495525, 0.0, 0.0, 2.7477995639328975e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.8946570057107736e-05, 2.7477995639328983e-06, 0.0, 0.0, 7.336783314601888, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 303 + stamp: + secs: 1624875220 + nsecs: 681297064 + frame_id: "/world" +pose: + pose: + position: + x: -0.0414422589829 + y: 0.138639221643 + z: 0.0 + orientation: + x: 0.0 + y: 0.000373988484053 + z: 0.0 + w: 0.999999930066 + covariance: [7.684249052048632, -9.92226702661323e-09, 0.0, 0.0, -4.5007794470416434e-05, 0.0, -9.922267026613224e-09, 7.6842490258649505, 0.0, 0.0, 2.8190060223778648e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.5007794470416434e-05, 2.819006022377864e-05, 0.0, 0.0, 7.630183713578768, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 304 + stamp: + secs: 1624875220 + nsecs: 761307001 + frame_id: "/world" +pose: + pose: + position: + x: -0.0373052896417 + y: 0.154477511254 + z: 0.0 + orientation: + x: 0.0 + y: 5.52525407851e-05 + z: 0.0 + w: 0.999999998474 + covariance: [8.650166895199602, -1.614123769359958e-08, 0.0, 0.0, -6.811219698180215e-05, 0.0, -1.614123769359957e-08, 8.650166857197721, 0.0, 0.0, 7.063440669719506e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.811219698180218e-05, 7.063440669719505e-05, 0.0, 0.0, 8.570785952443588, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 305 + stamp: + secs: 1624875220 + nsecs: 841311932 + frame_id: "/world" +pose: + pose: + position: + x: -0.0455832535158 + y: 0.169073571052 + z: 0.0 + orientation: + x: -0.0 + y: -7.20760201515e-05 + z: -0.0 + w: 0.999999997403 + covariance: [8.172929668619382, -1.9442834853130295e-08, 0.0, 0.0, -6.163821957454615e-05, 0.0, -1.9442834853130285e-08, 8.172929627341622, 0.0, 0.0, 6.527255561400155e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.163821957454616e-05, 6.527255561400157e-05, 0.0, 0.0, 8.084878567895604, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 306 + stamp: + secs: 1624875220 + nsecs: 921345949 + frame_id: "/world" +pose: + pose: + position: + x: -0.0405702054442 + y: 0.172153590049 + z: 0.0 + orientation: + x: -0.0 + y: -0.000136196987495 + z: -0.0 + w: 0.999999990725 + covariance: [8.876226691480298, -2.2655033872161156e-08, 0.0, 0.0, -5.0760949525738725e-05, 0.0, -2.265503387216114e-08, 8.876226646114478, 0.0, 0.0, 5.451091389335607e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.076094952573874e-05, 5.451091389335609e-05, 0.0, 0.0, 8.777801002290708, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 307 + stamp: + secs: 1624875221 + nsecs: 1331091 + frame_id: "/world" +pose: + pose: + position: + x: -0.0500341407528 + y: 0.186118424945 + z: 0.0 + orientation: + x: -0.0 + y: -4.19403585529e-05 + z: -0.0 + w: 0.999999999121 + covariance: [6.837278091313184, -1.4689432244921367e-08, 0.0, 0.0, -6.040516710851096e-05, 0.0, -1.4689432244921354e-08, 6.837278062620064, 0.0, 0.0, 2.3808039153338415e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.040516710851095e-05, 2.3808039153338425e-05, 0.0, 0.0, 6.776001203295684, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 308 + stamp: + secs: 1624875221 + nsecs: 81346989 + frame_id: "/world" +pose: + pose: + position: + x: -0.0499181508243 + y: 0.191301984421 + z: 0.0 + orientation: + x: -0.0 + y: -0.000287204368998 + z: -0.0 + w: 0.999999958757 + covariance: [6.295347389948719, -1.0531651607812786e-08, 0.0, 0.0, -5.497852019346576e-05, 0.0, -1.0531651607812775e-08, 6.295347368435783, 0.0, 0.0, 1.2673757263606595e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.4978520193465764e-05, 1.2673757263606599e-05, 0.0, 0.0, 6.2531948160421456, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 309 + stamp: + secs: 1624875221 + nsecs: 161340952 + frame_id: "/world" +pose: + pose: + position: + x: -0.0529618996259 + y: 0.196186894873 + z: 0.0 + orientation: + x: -0.0 + y: -0.000186089707945 + z: -0.0 + w: 0.999999982685 + covariance: [6.652382209711909, -1.198051344399224e-08, 0.0, 0.0, -4.813290781989206e-05, 0.0, -1.1980513443992225e-08, 6.652382183989336, 0.0, 0.0, 1.680000708657885e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.8132907819892074e-05, 1.680000708657885e-05, 0.0, 0.0, 6.60666057624035, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 310 + stamp: + secs: 1624875221 + nsecs: 241344929 + frame_id: "/world" +pose: + pose: + position: + x: -0.0528704522124 + y: 0.1963531912 + z: 0.0 + orientation: + x: -0.0 + y: -0.000229931966781 + z: -0.0 + w: 0.999999973566 + covariance: [7.382100257126343, -1.0107633865919422e-08, 0.0, 0.0, -3.430761923445087e-05, 0.0, -1.010763386591941e-08, 7.382100235074146, 0.0, 0.0, 1.4442856987379058e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.4307619234450875e-05, 1.444285698737906e-05, 0.0, 0.0, 7.344463663332957, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 311 + stamp: + secs: 1624875221 + nsecs: 321346045 + frame_id: "/world" +pose: + pose: + position: + x: -0.0533593469362 + y: 0.196500725456 + z: 0.0 + orientation: + x: -0.0 + y: -2.63955654781e-05 + z: -0.0 + w: 0.999999999652 + covariance: [7.695303181027461, -1.726936916128343e-08, 0.0, 0.0, -4.298376217503588e-05, 0.0, -1.7269369161283424e-08, 7.695303142567898, 0.0, 0.0, 1.9442973310061736e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.2983762175035885e-05, 1.9442973310061743e-05, 0.0, 0.0, 7.633119312841269, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 312 + stamp: + secs: 1624875221 + nsecs: 401350975 + frame_id: "/world" +pose: + pose: + position: + x: -0.0560189669171 + y: 0.231673164043 + z: 0.0 + orientation: + x: -0.0 + y: -0.000105766038888 + z: -0.0 + w: 0.999999994407 + covariance: [7.825738821258574, -2.3382484454757755e-08, 0.0, 0.0, -3.770039274386143e-05, 0.0, -2.3382484454757738e-08, 7.825738768825556, 0.0, 0.0, 1.841927894040702e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.7700392743861414e-05, 1.8419278940407032e-05, 0.0, 0.0, 7.742514152839822, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 313 + stamp: + secs: 1624875221 + nsecs: 481375933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0566678028165 + y: 0.232508391451 + z: 0.0 + orientation: + x: 0.0 + y: 7.64249724257e-05 + z: 0.0 + w: 0.99999999708 + covariance: [7.147004456028989, -1.5061677602219725e-08, 0.0, 0.0, -1.7693586672381528e-05, 0.0, -1.5061677602219712e-08, 7.147004422186928, 0.0, 0.0, 9.59770172978949e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7693586672381514e-05, 9.597701729789495e-06, 0.0, 0.0, 7.093333154081446, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 314 + stamp: + secs: 1624875221 + nsecs: 561382055 + frame_id: "/world" +pose: + pose: + position: + x: -0.0701676750194 + y: 0.249377442953 + z: 0.0 + orientation: + x: 0.0 + y: 0.000458451283096 + z: 0.0 + w: 0.999999894911 + covariance: [9.40326995384146, -3.292029368329633e-08, 0.0, 0.0, -2.1176431612586124e-05, 0.0, -3.29202936832963e-08, 9.403269879784174, 0.0, 0.0, 1.3740445097146178e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.117643161258612e-05, 1.3740445097146183e-05, 0.0, 0.0, 9.286026718342473, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 315 + stamp: + secs: 1624875221 + nsecs: 641385078 + frame_id: "/world" +pose: + pose: + position: + x: -0.0705068605907 + y: 0.249980716333 + z: 0.0 + orientation: + x: 0.0 + y: 0.000293310785133 + z: 0.0 + w: 0.999999956984 + covariance: [7.632448783993459, -2.3666454482574033e-08, 0.0, 0.0, -1.0942832580317297e-05, 0.0, -2.366645448257401e-08, 7.632448730854225, 0.0, 0.0, 1.7022433590610865e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0942832580317299e-05, 1.7022433590610882e-05, 0.0, 0.0, 7.547443882691174, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 316 + stamp: + secs: 1624875221 + nsecs: 721393108 + frame_id: "/world" +pose: + pose: + position: + x: -0.0706053455488 + y: 0.25080279629 + z: 0.0 + orientation: + x: 0.0 + y: 0.000404046725976 + z: 0.0 + w: 0.999999918373 + covariance: [8.669472644573155, -3.779404832558173e-08, 0.0, 0.0, -2.213674850989822e-05, 0.0, -3.7794048325581693e-08, 8.669472560468591, 0.0, 0.0, 3.300031701119948e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.213674850989822e-05, 3.300031701119949e-05, 0.0, 0.0, 8.532626873262812, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 317 + stamp: + secs: 1624875221 + nsecs: 801403046 + frame_id: "/world" +pose: + pose: + position: + x: -0.0712796480039 + y: 0.251550515907 + z: 0.0 + orientation: + x: 0.0 + y: 0.000218163124004 + z: 0.0 + w: 0.999999976202 + covariance: [9.124203499853934, -4.032077708106989e-08, 0.0, 0.0, -2.6019624311797317e-05, 0.0, -4.032077708106986e-08, 9.124203410627832, 0.0, 0.0, 2.8094152066056154e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.6019624311797317e-05, 2.809415206605617e-05, 0.0, 0.0, 8.977156517061232, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 318 + stamp: + secs: 1624875221 + nsecs: 881417036 + frame_id: "/world" +pose: + pose: + position: + x: -0.0716627308374 + y: 0.252220441949 + z: 0.0 + orientation: + x: 0.0 + y: 0.000575995011715 + z: 0.0 + w: 0.999999834115 + covariance: [9.320979289029747, -4.085185402064913e-08, 0.0, 0.0, -2.6688982727458233e-05, 0.0, -4.08518540206491e-08, 9.320979198973179, 0.0, 0.0, 2.0781558009068097e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.668898272745822e-05, 2.0781558009068097e-05, 0.0, 0.0, 9.171325414587248, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 319 + stamp: + secs: 1624875221 + nsecs: 961416006 + frame_id: "/world" +pose: + pose: + position: + x: -0.0741272547439 + y: 0.260007364409 + z: 0.0 + orientation: + x: 0.0 + y: 0.000502093568935 + z: 0.0 + w: 0.999999873951 + covariance: [7.605938570201902, -2.4410787895315712e-08, 0.0, 0.0, -1.5458357850416515e-05, 0.0, -2.44107878953157e-08, 7.605938516544692, 0.0, 0.0, 1.2013740223274786e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.54583578504165e-05, 1.2013740223274786e-05, 0.0, 0.0, 7.515572972427861, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 320 + stamp: + secs: 1624875222 + nsecs: 41435957 + frame_id: "/world" +pose: + pose: + position: + x: -0.0744895320578 + y: 0.260706318685 + z: 0.0 + orientation: + x: 0.0 + y: 0.00094011842317 + z: 0.0 + w: 0.999999558089 + covariance: [8.644542766133092, -4.218829134512626e-08, 0.0, 0.0, -0.00035438970629395045, 0.0, -4.218829134512624e-08, 8.644542665709478, 0.0, 0.0, 0.00010375213230725927, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00035438970629395034, 0.0001037521323072593, 0.0, 0.0, 8.519318948187347, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 321 + stamp: + secs: 1624875222 + nsecs: 121417046 + frame_id: "/world" +pose: + pose: + position: + x: -0.073728448516 + y: 0.262463043371 + z: 0.0 + orientation: + x: 0.0 + y: 0.000850540625029 + z: 0.0 + w: 0.99999963829 + covariance: [9.09027759180096, -6.255757708703855e-08, 0.0, 0.0, -0.0004861411611669955, 0.0, -6.25575770870385e-08, 9.090277420476971, 0.0, 0.0, 0.00013646891887184132, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004861411611669956, 0.00013646891887184132, 0.0, 0.0, 8.972100546676437, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 322 + stamp: + secs: 1624875222 + nsecs: 201446056 + frame_id: "/world" +pose: + pose: + position: + x: -0.0753196083749 + y: 0.267610544528 + z: 0.0 + orientation: + x: 0.0 + y: 0.000393453177922 + z: 0.0 + w: 0.999999922597 + covariance: [6.895115540837979, -5.360725015969211e-08, 0.0, 0.0, -0.00026284689757416713, 0.0, -5.360725015969213e-08, 6.8951153836708645, 0.0, 0.0, 7.340802493458177e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002628468975741673, 7.340802493458174e-05, 0.0, 0.0, 6.823016386639036, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 323 + stamp: + secs: 1624875222 + nsecs: 281445026 + frame_id: "/world" +pose: + pose: + position: + x: -0.0734415834068 + y: 0.29507902126 + z: 0.0 + orientation: + x: 0.0 + y: 0.000593674156915 + z: 0.0 + w: 0.999999823775 + covariance: [7.534053966213511, -9.971996965262691e-08, 0.0, 0.0, -0.00024255588304807237, 0.0, -9.971996965262695e-08, 7.534053662589303, 0.0, 0.0, 6.731662594109268e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002425558830480725, 6.731662594109269e-05, 0.0, 0.0, 7.430677072130171, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 324 + stamp: + secs: 1624875222 + nsecs: 361438990 + frame_id: "/world" +pose: + pose: + position: + x: -0.0734114036026 + y: 0.29502116852 + z: 0.0 + orientation: + x: 0.0 + y: 0.000126201824366 + z: 0.0 + w: 0.999999992037 + covariance: [7.7002047367825135, -3.2072169031116545e-08, 0.0, 0.0, -8.4765710421603e-05, 0.0, -3.207216903111656e-08, 7.700204639426623, 0.0, 0.0, 2.352651037624412e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.476571042160307e-05, 2.3526510376244127e-05, 0.0, 0.0, 7.6659920243540025, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 325 + stamp: + secs: 1624875222 + nsecs: 441457987 + frame_id: "/world" +pose: + pose: + position: + x: -0.0678767945351 + y: 0.303147965681 + z: 0.0 + orientation: + x: 0.0 + y: 0.00031941876975 + z: 0.0 + w: 0.999999948986 + covariance: [8.636056714967788, -5.198217792309791e-08, 0.0, 0.0, -8.63692644685609e-05, 0.0, -5.1982177923097924e-08, 8.636056554528057, 0.0, 0.0, 2.1734303233260745e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.636926446856094e-05, 2.173430323326075e-05, 0.0, 0.0, 8.587403754695718, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 326 + stamp: + secs: 1624875222 + nsecs: 521461964 + frame_id: "/world" +pose: + pose: + position: + x: -0.0621833640211 + y: 0.336508937675 + z: 0.0 + orientation: + x: 0.0 + y: 0.000635639197206 + z: 0.0 + w: 0.999999797981 + covariance: [9.070598577447228, -7.931084137326388e-08, 0.0, 0.0, -8.678226849145769e-05, 0.0, -7.931084137326391e-08, 9.070598330232837, 0.0, 0.0, 1.9335342194866675e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.678226849145773e-05, 1.9335342194866678e-05, 0.0, 0.0, 9.001373717743919, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 327 + stamp: + secs: 1624875222 + nsecs: 601474047 + frame_id: "/world" +pose: + pose: + position: + x: -0.0623837086329 + y: 0.337075790511 + z: 0.0 + orientation: + x: 0.0 + y: 0.000451844646753 + z: 0.0 + w: 0.999999897918 + covariance: [8.302296091171941, -7.775308406371298e-08, 0.0, 0.0, -5.8226418642442735e-05, 0.0, -7.7753084063713e-08, 8.302295846732251, 0.0, 0.0, -9.216887637069781e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.822641864244275e-05, -9.21688763706978e-06, 0.0, 0.0, 8.236104343427451, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 328 + stamp: + secs: 1624875222 + nsecs: 681476116 + frame_id: "/world" +pose: + pose: + position: + x: -0.0625364672207 + y: 0.33751475565 + z: 0.0 + orientation: + x: 0.0 + y: 0.000429052156149 + z: 0.0 + w: 0.999999907957 + covariance: [8.909126762059172, -7.482994955748239e-08, 0.0, 0.0, -4.204084262683748e-05, 0.0, -7.482994955748243e-08, 8.909126525466055, 0.0, 0.0, -2.0212838297227278e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.204084262683748e-05, -2.0212838297227278e-05, 0.0, 0.0, 8.845828868368212, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 329 + stamp: + secs: 1624875222 + nsecs: 761483908 + frame_id: "/world" +pose: + pose: + position: + x: -0.0627955663497 + y: 0.338256560486 + z: 0.0 + orientation: + x: 0.0 + y: 0.000465092037453 + z: 0.0 + w: 0.999999891845 + covariance: [9.204780727098646, -1.0711861295766547e-07, 0.0, 0.0, -3.619643051856173e-05, 0.0, -1.0711861295766551e-07, 9.204780386750997, 0.0, 0.0, -2.318316722172198e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.619643051856173e-05, -2.3183167221721975e-05, 0.0, 0.0, 9.113979317800156, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 330 + stamp: + secs: 1624875222 + nsecs: 841490030 + frame_id: "/world" +pose: + pose: + position: + x: -0.0651227037236 + y: 0.320830954365 + z: 0.0 + orientation: + x: 0.0 + y: 0.000313570598697 + z: 0.0 + w: 0.999999950837 + covariance: [8.361413088388046, -1.0125985508007369e-07, 0.0, 0.0, -5.500657122677622e-05, 0.0, -1.0125985508007372e-07, 8.361412764955512, 0.0, 0.0, -1.5152068014055596e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.5006571226776216e-05, -1.5152068014055595e-05, 0.0, 0.0, 8.274720290646979, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 331 + stamp: + secs: 1624875222 + nsecs: 921515942 + frame_id: "/world" +pose: + pose: + position: + x: -0.0646208761191 + y: 0.32416092022 + z: 0.0 + orientation: + x: 0.0 + y: 0.000317717078799 + z: 0.0 + w: 0.999999949528 + covariance: [8.966726082088062, -1.1996895793346052e-07, 0.0, 0.0, -8.433926386177825e-05, 0.0, -1.1996895793346055e-07, 8.966725695543238, 0.0, 0.0, -9.316358500895577e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.433926386177823e-05, -9.316358500895577e-06, 0.0, 0.0, 8.862964883489235, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 332 + stamp: + secs: 1624875223 + nsecs: 1523018 + frame_id: "/world" +pose: + pose: + position: + x: -0.0658835556938 + y: 0.337906631567 + z: 0.0 + orientation: + x: 0.0 + y: 0.000587621290282 + z: 0.0 + w: 0.999999827351 + covariance: [9.229032920166272, -1.232099331002996e-07, 0.0, 0.0, -8.19285831594335e-05, 0.0, -1.2320993310029963e-07, 9.229032520551815, 0.0, 0.0, -4.058841957947574e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.192858315943351e-05, -4.058841957947574e-06, 0.0, 0.0, 9.121672774134353, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 333 + stamp: + secs: 1624875223 + nsecs: 81501961 + frame_id: "/world" +pose: + pose: + position: + x: -0.069203341017 + y: 0.34006367145 + z: 0.0 + orientation: + x: 0.0 + y: 0.000813057020261 + z: 0.0 + w: 0.999999669469 + covariance: [12.157248010754182, -1.7558846239713752e-07, 0.0, 0.0, -0.00010673123921938789, 0.0, -1.7558846239713757e-07, 12.157247438527804, 0.0, 0.0, -2.34114332405368e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00010673123921938793, -2.34114332405368e-06, 0.0, 0.0, 12.003279449536482, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 334 + stamp: + secs: 1624875223 + nsecs: 161525011 + frame_id: "/world" +pose: + pose: + position: + x: -0.0693657006604 + y: 0.340799368792 + z: 0.0 + orientation: + x: 0.0 + y: 0.000722942604006 + z: 0.0 + w: 0.999999738677 + covariance: [12.093213434935516, -1.8206623153716278e-07, 0.0, 0.0, -0.00011073141573720632, 0.0, -1.8206623153716283e-07, 12.093212838747968, 0.0, 0.0, -1.895119625532828e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011073141573720637, -1.8951196255328243e-07, 0.0, 0.0, 11.932131934464108, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 335 + stamp: + secs: 1624875223 + nsecs: 241575956 + frame_id: "/world" +pose: + pose: + position: + x: -0.0697381382869 + y: 0.34195934196 + z: 0.0 + orientation: + x: 0.0 + y: 0.000631559302689 + z: 0.0 + w: 0.999999800566 + covariance: [14.280000533580713, -3.406816818038498e-07, 0.0, 0.0, -0.00023024376023090894, 0.0, -3.4068168180384984e-07, 14.279999411712417, 0.0, 0.0, 3.2199412355009094e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00023024376023090897, 3.219941235500909e-05, 0.0, 0.0, 13.973858167995894, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 336 + stamp: + secs: 1624875223 + nsecs: 321557045 + frame_id: "/world" +pose: + pose: + position: + x: -0.0701717253844 + y: 0.343023846795 + z: 0.0 + orientation: + x: 0.0 + y: 0.000356152247158 + z: 0.0 + w: 0.999999936578 + covariance: [15.76460857596211, -4.727094483077425e-07, 0.0, 0.0, -0.00030937324363199695, 0.0, -4.727094483077426e-07, 15.764607016955637, 0.0, 0.0, 7.163994069681146e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000309373243631997, 7.163994069681149e-05, 0.0, 0.0, 15.33683048198695, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 337 + stamp: + secs: 1624875223 + nsecs: 401560068 + frame_id: "/world" +pose: + pose: + position: + x: -0.0704692251728 + y: 0.360169756152 + z: 0.0 + orientation: + x: 0.0 + y: 0.00064712384885 + z: 0.0 + w: 0.999999790615 + covariance: [13.854876294733163, -4.050278640898932e-07, 0.0, 0.0, -0.00022914265546270928, 0.0, -4.050278640898932e-07, 13.854874958395841, 0.0, 0.0, 6.314003060075603e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00022914265546270928, 6.314003060075604e-05, 0.0, 0.0, 13.483065814507711, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 338 + stamp: + secs: 1624875223 + nsecs: 481564999 + frame_id: "/world" +pose: + pose: + position: + x: -0.0705699397618 + y: 0.362710170686 + z: 0.0 + orientation: + x: 0.0 + y: 0.000621131358231 + z: 0.0 + w: 0.999999807098 + covariance: [12.967204210861714, -3.49083889458625e-07, 0.0, 0.0, -0.0001626999543611177, 0.0, -3.490838894586251e-07, 12.96720305912684, 0.0, 0.0, 5.136585646895393e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00016269995436111768, 5.136585646895394e-05, 0.0, 0.0, 12.641905057413314, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 339 + stamp: + secs: 1624875223 + nsecs: 561572075 + frame_id: "/world" +pose: + pose: + position: + x: -0.068787866807 + y: 0.372067101979 + z: 0.0 + orientation: + x: 0.0 + y: 0.000470538980241 + z: 0.0 + w: 0.999999889297 + covariance: [12.533945560971482, -3.0826397614108764e-07, 0.0, 0.0, -0.00011467459842231617, 0.0, -3.0826397614108785e-07, 12.533944544110868, 0.0, 0.0, 4.066191340006121e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011467459842231616, 4.066191340006121e-05, 0.0, 0.0, 12.242795787264717, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 340 + stamp: + secs: 1624875223 + nsecs: 641552925 + frame_id: "/world" +pose: + pose: + position: + x: -0.0694551623308 + y: 0.380344444866 + z: 0.0 + orientation: + x: -0.0 + y: -4.31660451494e-06 + z: -0.0 + w: 0.999999999991 + covariance: [10.672652883360165, -2.0899801332322308e-07, 0.0, 0.0, -5.905030165743652e-05, 0.0, -2.0899801332322324e-07, 10.672652194069105, 0.0, 0.0, 2.313907842850232e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.905030165743651e-05, 2.3139078428502313e-05, 0.0, 0.0, 10.472877705886955, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 341 + stamp: + secs: 1624875223 + nsecs: 721590996 + frame_id: "/world" +pose: + pose: + position: + x: -0.0697592506779 + y: 0.3821145809 + z: 0.0 + orientation: + x: 0.0 + y: 0.000446846969259 + z: 0.0 + w: 0.999999900164 + covariance: [9.963280810372211, -1.762266148385074e-07, 0.0, 0.0, -3.962079761236776e-05, 0.0, -1.7622661483850754e-07, 9.96328022937786, 0.0, 0.0, 1.8463638106541703e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.962079761236775e-05, 1.84636381065417e-05, 0.0, 0.0, 9.791638843563495, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 342 + stamp: + secs: 1624875223 + nsecs: 801577091 + frame_id: "/world" +pose: + pose: + position: + x: -0.0699514428173 + y: 0.382744144491 + z: 0.0 + orientation: + x: -0.0 + y: -7.08845780061e-05 + z: -0.0 + w: 0.999999997488 + covariance: [8.614075062602394, -1.121599225656727e-07, 0.0, 0.0, -2.2852860885762814e-05, 0.0, -1.121599225656728e-07, 8.614074692986938, 0.0, 0.0, 1.2401014936802568e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.2852860885762817e-05, 1.240101493680257e-05, 0.0, 0.0, 8.502789714436894, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 343 + stamp: + secs: 1624875223 + nsecs: 881587982 + frame_id: "/world" +pose: + pose: + position: + x: -0.0700948848444 + y: 0.382116359299 + z: 0.0 + orientation: + x: -0.0 + y: -0.000121981069032 + z: -0.0 + w: 0.99999999256 + covariance: [10.212136106804353, -1.1695983749492324e-07, 0.0, 0.0, -1.7114160958084713e-05, 0.0, -1.1695983749492334e-07, 10.212135721535725, 0.0, 0.0, 1.2451135503490522e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7114160958084713e-05, 1.2451135503490518e-05, 0.0, 0.0, 10.095079544308506, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 344 + stamp: + secs: 1624875223 + nsecs: 961596966 + frame_id: "/world" +pose: + pose: + position: + x: -0.0686621355694 + y: 0.37761580648 + z: 0.0 + orientation: + x: 0.0 + y: 0.000143443260228 + z: 0.0 + w: 0.999999989712 + covariance: [8.69938758283204, -9.52651771473012e-08, 0.0, 0.0, -7.127289439481347e-06, 0.0, -9.526517714730122e-08, 8.69938726916294, 0.0, 0.0, 8.12198392334184e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.127289439481345e-06, 8.12198392334184e-06, 0.0, 0.0, 8.602372198026739, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 345 + stamp: + secs: 1624875224 + nsecs: 41613102 + frame_id: "/world" +pose: + pose: + position: + x: -0.0725725092447 + y: 0.392341001892 + z: 0.0 + orientation: + x: -0.0 + y: -0.000254005470476 + z: -0.0 + w: 0.999999967741 + covariance: [11.837529307277148, -2.0577091937207197e-07, 0.0, 0.0, -2.631822022711801e-05, 0.0, -2.057709193720721e-07, 11.837528631998463, 0.0, 0.0, 8.647397170279372e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.6318220227118007e-05, 8.647397170279372e-05, 0.0, 0.0, 11.625755524119516, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 346 + stamp: + secs: 1624875224 + nsecs: 121651888 + frame_id: "/world" +pose: + pose: + position: + x: -0.0726942620622 + y: 0.392858842387 + z: 0.0 + orientation: + x: -0.0 + y: -0.000122817541876 + z: -0.0 + w: 0.999999992458 + covariance: [11.919719292399972, -1.6906101267684928e-07, 0.0, 0.0, -2.8819327098212878e-05, 0.0, -1.6906101267684944e-07, 11.919718740364443, 0.0, 0.0, 9.684947510231869e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.881932709821287e-05, 9.684947510231865e-05, 0.0, 0.0, 11.744279707719501, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 347 + stamp: + secs: 1624875224 + nsecs: 201616049 + frame_id: "/world" +pose: + pose: + position: + x: -0.0729600217053 + y: 0.393852434867 + z: 0.0 + orientation: + x: 0.0 + y: 0.000230666891688 + z: 0.0 + w: 0.999999973396 + covariance: [12.032248808643285, -2.181652894311769e-07, 0.0, 0.0, -3.7116170078336047e-05, 0.0, -2.1816528943117713e-07, 12.032248104056672, 0.0, 0.0, 0.0001294811160826817, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.711617007833606e-05, 0.0001294811160826817, 0.0, 0.0, 11.803380448987108, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 348 + stamp: + secs: 1624875224 + nsecs: 281644106 + frame_id: "/world" +pose: + pose: + position: + x: -0.0983638863424 + y: 0.425511903584 + z: 0.0 + orientation: + x: 0.0 + y: 0.000127631664554 + z: 0.0 + w: 0.999999991855 + covariance: [9.278861892401041, -1.3810404388755638e-07, 0.0, 0.0, -1.7414469365337476e-05, 0.0, -1.381040438875565e-07, 9.278861449377686, 0.0, 0.0, 7.078120159241848e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.741446936533748e-05, 7.078120159241846e-05, 0.0, 0.0, 9.131441625410883, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 349 + stamp: + secs: 1624875224 + nsecs: 361641884 + frame_id: "/world" +pose: + pose: + position: + x: -0.114701411821 + y: 0.412892094524 + z: 0.0 + orientation: + x: -0.0 + y: -2.79064920339e-05 + z: -0.0 + w: 0.999999999611 + covariance: [10.569562727004243, -1.1855939959797986e-07, 0.0, 0.0, -3.029122129510336e-05, 0.0, -1.1855939959797997e-07, 10.569562348377358, 0.0, 0.0, 5.341100264562707e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.0291221295103358e-05, 5.341100264562704e-05, 0.0, 0.0, 10.442302538443398, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 350 + stamp: + secs: 1624875224 + nsecs: 441647053 + frame_id: "/world" +pose: + pose: + position: + x: -0.1285625064 + y: 0.426571812637 + z: 0.0 + orientation: + x: -0.0 + y: -0.00023764640296 + z: -0.0 + w: 0.999999971762 + covariance: [11.318156544880997, -1.6362578260493432e-07, 0.0, 0.0, -7.718662600196792e-05, 0.0, -1.6362578260493446e-07, 11.318156026426857, 0.0, 0.0, 5.207460781633408e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.718662600196793e-05, 5.207460781633405e-05, 0.0, 0.0, 11.14117313337056, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 351 + stamp: + secs: 1624875224 + nsecs: 521675110 + frame_id: "/world" +pose: + pose: + position: + x: -0.131194836122 + y: 0.442669384252 + z: 0.0 + orientation: + x: -0.0 + y: -2.17147421976e-05 + z: -0.0 + w: 0.999999999764 + covariance: [10.157720115807134, -9.423300018594445e-08, 0.0, 0.0, -4.325519143880495e-05, 0.0, -9.423300018594452e-08, 10.157719817735416, 0.0, 0.0, 2.5521526889059653e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.3255191438804965e-05, 2.552152688905965e-05, 0.0, 0.0, 10.054975559029144, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 352 + stamp: + secs: 1624875224 + nsecs: 601653099 + frame_id: "/world" +pose: + pose: + position: + x: -0.133730208068 + y: 0.465857526376 + z: 0.0 + orientation: + x: -0.0 + y: -0.000161431709407 + z: -0.0 + w: 0.99999998697 + covariance: [9.740738678569233, -1.0707704913033173e-07, 0.0, 0.0, -3.748400169940448e-05, 0.0, -1.0707704913033179e-07, 9.740738341035321, 0.0, 0.0, 1.848821102694957e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.7484001699404495e-05, 1.8488211026949563e-05, 0.0, 0.0, 9.6224985210987, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 353 + stamp: + secs: 1624875224 + nsecs: 681679964 + frame_id: "/world" +pose: + pose: + position: + x: -0.142604821067 + y: 0.499071612825 + z: 0.0 + orientation: + x: 0.0 + y: 0.000183186326505 + z: 0.0 + w: 0.999999983221 + covariance: [9.553909834272904, -9.843639901154941e-08, 0.0, 0.0, -2.5689686397782692e-05, 0.0, -9.84363990115495e-08, 9.55390952460988, 0.0, 0.0, 1.81460683067981e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5689686397782702e-05, 1.8146068306798096e-05, 0.0, 0.0, 9.444147274282557, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 354 + stamp: + secs: 1624875224 + nsecs: 761667967 + frame_id: "/world" +pose: + pose: + position: + x: -0.144381117273 + y: 0.529757328938 + z: 0.0 + orientation: + x: -0.0 + y: -1.28946384761e-05 + z: -0.0 + w: 0.999999999917 + covariance: [8.471908279868877, -7.509595130723793e-08, 0.0, 0.0, -1.454712573912018e-05, 0.0, -7.5095951307238e-08, 8.471908044003355, 0.0, 0.0, 1.1212345283605675e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.454712573912019e-05, 1.121234528360567e-05, 0.0, 0.0, 8.386995271024034, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 355 + stamp: + secs: 1624875224 + nsecs: 841675043 + frame_id: "/world" +pose: + pose: + position: + x: -0.160874007077 + y: 0.547938912535 + z: 0.0 + orientation: + x: 0.0 + y: 6.47192376774e-07 + z: 0.0 + w: 1.0 + covariance: [10.161570372295873, -1.1480585178628265e-07, 0.0, 0.0, -1.5162914631454634e-05, 0.0, -1.1480585178628274e-07, 10.161570012110717, 0.0, 0.0, 9.687245826512182e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5162914631454643e-05, 9.687245826512179e-06, 0.0, 0.0, 10.030163434674373, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 356 + stamp: + secs: 1624875224 + nsecs: 921693087 + frame_id: "/world" +pose: + pose: + position: + x: -0.161143634263 + y: 0.556924835669 + z: 0.0 + orientation: + x: -0.0 + y: -2.89179919235e-06 + z: -0.0 + w: 0.999999999996 + covariance: [11.080594515691619, -1.343597891202892e-07, 0.0, 0.0, -1.363306255479795e-05, 0.0, -1.343597891202893e-07, 11.080594094437158, 0.0, 0.0, 9.868533320030194e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3633062554797957e-05, 9.868533320030194e-06, 0.0, 0.0, 10.925027509615884, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 357 + stamp: + secs: 1624875225 + nsecs: 1673937 + frame_id: "/world" +pose: + pose: + position: + x: -0.161950279257 + y: 0.552020811867 + z: 0.0 + orientation: + x: -0.0 + y: -1.32209872708e-05 + z: -0.0 + w: 0.999999999913 + covariance: [11.582470001269169, -1.6380472716747376e-07, 0.0, 0.0, -1.9671855853085452e-05, 0.0, -1.6380472716747386e-07, 11.582469487991977, 0.0, 0.0, 1.2588569852036307e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.967185585308546e-05, 1.2588569852036307e-05, 0.0, 0.0, 11.390271295181835, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 358 + stamp: + secs: 1624875225 + nsecs: 81682920 + frame_id: "/world" +pose: + pose: + position: + x: -0.162897562736 + y: 0.554161113985 + z: 0.0 + orientation: + x: 0.0 + y: 0.000220170646348 + z: 0.0 + w: 0.999999975762 + covariance: [11.869575903055772, -2.041998786732822e-07, 0.0, 0.0, -5.108365763462048e-05, 0.0, -2.0419987867328235e-07, 11.86957526341433, 0.0, 0.0, 1.5425154128382768e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.108365763462048e-05, 1.542515412838277e-05, 0.0, 0.0, 11.6265164103252, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 359 + stamp: + secs: 1624875225 + nsecs: 161689043 + frame_id: "/world" +pose: + pose: + position: + x: -0.177711297241 + y: 0.574386563885 + z: 0.0 + orientation: + x: 0.0 + y: 0.000552647289358 + z: 0.0 + w: 0.99999984729 + covariance: [10.472466484688828, -1.902887938046337e-07, 0.0, 0.0, -8.115756972827287e-05, 0.0, -1.9028879380463385e-07, 10.472465888065429, 0.0, 0.0, 1.2353087221543493e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.115756972827284e-05, 1.2353087221543495e-05, 0.0, 0.0, 10.241694015015582, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 360 + stamp: + secs: 1624875225 + nsecs: 241738081 + frame_id: "/world" +pose: + pose: + position: + x: -0.180267181783 + y: 0.576128156744 + z: 0.0 + orientation: + x: 0.0 + y: 0.000208904227602 + z: 0.0 + w: 0.99999997818 + covariance: [7.928410979047397, -9.895478466629902e-08, 0.0, 0.0, -4.6469391095149245e-05, 0.0, -9.895478466629909e-08, 7.928410668330679, 0.0, 0.0, 4.833938508812419e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.646939109514923e-05, 4.833938508812422e-06, 0.0, 0.0, 7.805878311938307, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 361 + stamp: + secs: 1624875225 + nsecs: 321708918 + frame_id: "/world" +pose: + pose: + position: + x: -0.189360453649 + y: 0.58314547212 + z: 0.0 + orientation: + x: -0.0 + y: -9.16137666315e-06 + z: -0.0 + w: 0.999999999958 + covariance: [7.930556862594567, -9.789072318594848e-08, 0.0, 0.0, -3.7780772698384546e-05, 0.0, -9.789072318594851e-08, 7.930556554572722, 0.0, 0.0, 3.162167871378955e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.778077269838456e-05, 3.1621678713789566e-06, 0.0, 0.0, 7.807071637030449, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 362 + stamp: + secs: 1624875225 + nsecs: 401716948 + frame_id: "/world" +pose: + pose: + position: + x: -0.18468946814 + y: 0.56495545159 + z: 0.0 + orientation: + x: -0.0 + y: -1.80402428233e-05 + z: -0.0 + w: 0.999999999837 + covariance: [7.200568251844677, -6.805492426616184e-08, 0.0, 0.0, -2.0753108702676678e-05, 0.0, -6.805492426616181e-08, 7.200568037417854, 0.0, 0.0, 1.755557067332549e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.0753108702676688e-05, 1.7555570673325494e-06, 0.0, 0.0, 7.113284739346214, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 363 + stamp: + secs: 1624875225 + nsecs: 481729984 + frame_id: "/world" +pose: + pose: + position: + x: -0.185906801087 + y: 0.564100881368 + z: 0.0 + orientation: + x: -0.0 + y: -9.39911019981e-05 + z: -0.0 + w: 0.999999995583 + covariance: [6.9557298201287105, -4.7533123801963326e-08, 0.0, 0.0, -1.4908134027288337e-05, 0.0, -4.75331238019633e-08, 6.955729670213413, 0.0, 0.0, 2.678204183174966e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.490813402728834e-05, 2.6782041831749666e-06, 0.0, 0.0, 6.893983458533737, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 364 + stamp: + secs: 1624875225 + nsecs: 561794043 + frame_id: "/world" +pose: + pose: + position: + x: -0.190268248354 + y: 0.565948529528 + z: 0.0 + orientation: + x: -0.0 + y: -0.000241187370367 + z: -0.0 + w: 0.999999970914 + covariance: [7.524969679637956, -5.057104967667379e-08, 0.0, 0.0, -1.8298720107927982e-05, 0.0, -5.057104967667379e-08, 7.5249695200217905, 0.0, 0.0, 5.37323231982993e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8298720107927982e-05, 5.373232319829931e-06, 0.0, 0.0, 7.458508376205469, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 365 + stamp: + secs: 1624875225 + nsecs: 641766071 + frame_id: "/world" +pose: + pose: + position: + x: -0.198183678603 + y: 0.574181840895 + z: 0.0 + orientation: + x: -0.0 + y: -0.000393421950723 + z: -0.0 + w: 0.99999992261 + covariance: [8.573615207581721, -6.184656379969588e-08, 0.0, 0.0, -2.1336455382742915e-05, 0.0, -6.184656379969586e-08, 8.573615012325165, 0.0, 0.0, 7.412962511879811e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1336455382742905e-05, 7.41296251187981e-06, 0.0, 0.0, 8.491519850374287, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 0 + stamp: + secs: 1624875191 + nsecs: 558718920 + frame_id: "/world" +pose: + pose: + position: + x: 0.0571035703916 + y: 0.00315463918406 + z: 0.0 + orientation: + x: 0.0 + y: 0.0381997500533 + z: 0.0 + w: 0.999270123188 + covariance: [0.07868257137427125, -3.1287751511516264e-18, 0.0, 0.0, -9.23949708639102e-14, 0.0, -3.1287751511525547e-18, 0.07868257137427095, 0.0, 0.0, -1.2423631706158793e-11, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.239497086387514e-14, -1.2423631706166987e-11, 0.0, 0.0, 0.07868240390552253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 1 + stamp: + secs: 1624875193 + nsecs: 478880882 + frame_id: "/world" +pose: + pose: + position: + x: 0.0507313510621 + y: -0.00158473660589 + z: 0.0 + orientation: + x: 0.0 + y: 0.169155284695 + z: 0.0 + w: 0.985589412311 + covariance: [6.211025765057356, -2.98303555690518e-08, 0.0, 0.0, -0.0005081579330980388, 0.0, -2.983035556905237e-08, 6.211025382718034, 0.0, 0.0, 3.940367165693649e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000508157933098038, 3.940367165693634e-05, 0.0, 0.0, 3.5886318727646787, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 2 + stamp: + secs: 1624875196 + nsecs: 999176979 + frame_id: "/world" +pose: + pose: + position: + x: 0.0451611590508 + y: -0.0179105370755 + z: 0.0 + orientation: + x: -0.0 + y: -0.106772826692 + z: -0.0 + w: 0.994283442224 + covariance: [5.0096076248019, -5.15621462510236e-07, 0.0, 0.0, -0.00016191940413651335, 0.0, -5.156214625102602e-07, 5.009609915240668, 0.0, 0.0, 0.001596169422619378, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00016191940413651403, 0.0015961694226193882, 0.0, 0.0, 3.3309570652863276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 3 + stamp: + secs: 1624875197 + nsecs: 79178095 + frame_id: "/world" +pose: + pose: + position: + x: 0.0377764644393 + y: -0.00306683378159 + z: 0.0 + orientation: + x: 0.0 + y: 0.0477493565262 + z: 0.0 + w: 0.998859348933 + covariance: [2.5081276200271065, -3.22240183167372e-08, 0.0, 0.0, -8.619376352622657e-06, 0.0, -3.2224018316738664e-08, 2.5081279015124385, 0.0, 0.0, 0.00015168363099147067, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.619376352622693e-06, 0.00015168363099147156, 0.0, 0.0, 2.3807376271643834, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 4 + stamp: + secs: 1624875197 + nsecs: 159200907 + frame_id: "/world" +pose: + pose: + position: + x: -0.0131433378256 + y: 0.00821948006192 + z: 0.0 + orientation: + x: -0.0 + y: -0.0180341339558 + z: -0.0 + w: 0.999837371782 + covariance: [2.309908363639027, -2.5193417265201506e-09, 0.0, 0.0, -1.3347482328264928e-06, 0.0, -2.5193417265202883e-09, 2.309908427964202, 0.0, 0.0, 2.1799391351520684e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3347482328264964e-06, 2.179939135152077e-05, 0.0, 0.0, 2.2962705407554513, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 5 + stamp: + secs: 1624875197 + nsecs: 239206076 + frame_id: "/world" +pose: + pose: + position: + x: 0.000543487927512 + y: 0.0350821055088 + z: 0.0 + orientation: + x: 0.0 + y: 0.00454061773021 + z: 0.0 + w: 0.999989691342 + covariance: [2.291761457426893, 4.8219680025796345e-09, 0.0, 0.0, -1.94605367740911e-06, 0.0, 4.821968002579627e-09, 2.291761562228787, 0.0, 0.0, 9.542539842601038e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9460536774091117e-06, 9.542539842601044e-06, 0.0, 0.0, 2.288012008504549, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 6 + stamp: + secs: 1624875197 + nsecs: 319202900 + frame_id: "/world" +pose: + pose: + position: + x: 0.00424691416398 + y: 0.0387103438511 + z: 0.0 + orientation: + x: -0.0 + y: -0.00136584271109 + z: -0.0 + w: 0.999999067236 + covariance: [2.4280312608077583, 5.522600448733182e-09, 0.0, 0.0, -8.314918566420752e-07, 0.0, 5.522600448733187e-09, 2.4280313495129335, 0.0, 0.0, 3.421093060758751e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.314918566420768e-07, 3.4210930607587543e-06, 0.0, 0.0, 2.425943938710083, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 7 + stamp: + secs: 1624875197 + nsecs: 399205923 + frame_id: "/world" +pose: + pose: + position: + x: 0.0127919068701 + y: 0.010687868281 + z: 0.0 + orientation: + x: 0.0 + y: 0.000341635110456 + z: 0.0 + w: 0.999999941643 + covariance: [2.0640181003276816, 2.092001718790631e-09, 0.0, 0.0, -1.5428550176788322e-07, 0.0, 2.092001718790636e-09, 2.064018131511998, 0.0, 0.0, 6.26587794232119e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5428550176788338e-07, 6.265877942321197e-07, 0.0, 0.0, 2.063300495209764, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 8 + stamp: + secs: 1624875197 + nsecs: 479234934 + frame_id: "/world" +pose: + pose: + position: + x: 0.0125905766811 + y: 0.0106400234545 + z: 0.0 + orientation: + x: 0.0 + y: 0.000363135692089 + z: 0.0 + w: 0.999999934066 + covariance: [2.639570295779254, 4.030463239533952e-09, 0.0, 0.0, -3.1032599801913304e-06, 0.0, 4.030463239533951e-09, 2.6395703537779887, 0.0, 0.0, 4.231594465888948e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.103259980191329e-06, 4.2315944658889475e-06, 0.0, 0.0, 2.6380171399151124, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 9 + stamp: + secs: 1624875197 + nsecs: 559230089 + frame_id: "/world" +pose: + pose: + position: + x: -0.0103437313582 + y: 0.0443447242232 + z: 0.0 + orientation: + x: -0.0 + y: -2.09887935548e-06 + z: -0.0 + w: 0.999999999998 + covariance: [3.024753363075542, 6.320434768351333e-09, 0.0, 0.0, -3.865234278879151e-06, 0.0, 6.320434768351334e-09, 3.0247534561500014, 0.0, 0.0, 4.822653440249248e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.865234278879149e-06, 4.8226534402492505e-06, 0.0, 0.0, 3.021844583449544, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 10 + stamp: + secs: 1624875197 + nsecs: 639235020 + frame_id: "/world" +pose: + pose: + position: + x: -0.000817313549928 + y: 0.0492779640487 + z: 0.0 + orientation: + x: -0.0 + y: -3.36054114594e-05 + z: -0.0 + w: 0.999999999435 + covariance: [2.356746611094799, 3.6820830805114973e-09, 0.0, 0.0, -1.8950899977606846e-06, 0.0, 3.682083080511501e-09, 2.356746666017282, 0.0, 0.0, 1.331039239378389e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8950899977606844e-06, 1.3310392393783887e-06, 0.0, 0.0, 2.354826895956701, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 11 + stamp: + secs: 1624875197 + nsecs: 719242096 + frame_id: "/world" +pose: + pose: + position: + x: -0.000249524194457 + y: 0.0511987066654 + z: 0.0 + orientation: + x: 0.0 + y: 0.000109412086021 + z: 0.0 + w: 0.999999994014 + covariance: [2.771210290960315, 1.5399705991262075e-09, 0.0, 0.0, -1.3010764903438397e-06, 0.0, 1.5399705991262088e-09, 2.7712103140325426, 0.0, 0.0, 3.4059294247831616e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3010764903438399e-06, 3.405929424783159e-07, 0.0, 0.0, 2.7703507271527275, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 12 + stamp: + secs: 1624875197 + nsecs: 799248934 + frame_id: "/world" +pose: + pose: + position: + x: 0.00030803333952 + y: 0.0434742855753 + z: 0.0 + orientation: + x: -0.0 + y: -0.00139369046807 + z: -0.0 + w: 0.999999028813 + covariance: [2.8301534924817684, 4.2018939779731815e-09, 0.0, 0.0, -2.3891358723818905e-06, 0.0, 4.201893977973179e-09, 2.8301535569435914, 0.0, 0.0, 1.2034743398134568e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.389135872381889e-06, 1.2034743398134557e-05, 0.0, 0.0, 2.827303718254319, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 13 + stamp: + secs: 1624875197 + nsecs: 879255056 + frame_id: "/world" +pose: + pose: + position: + x: 0.00243272400426 + y: -0.00289064506479 + z: 0.0 + orientation: + x: -0.0 + y: -0.000631090799384 + z: -0.0 + w: 0.999999800862 + covariance: [2.412518466694912, 5.663303596419025e-09, 0.0, 0.0, -1.0548273114510905e-06, 0.0, 5.663303596419018e-09, 2.412518557060573, 0.0, 0.0, 9.252846578140756e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0548273114510894e-06, 9.252846578140756e-06, 0.0, 0.0, 2.408212355571004, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 14 + stamp: + secs: 1624875197 + nsecs: 959276915 + frame_id: "/world" +pose: + pose: + position: + x: 0.00648756359306 + y: -0.00677924013791 + z: 0.0 + orientation: + x: 0.0 + y: 0.000575936445333 + z: 0.0 + w: 0.999999834149 + covariance: [2.0657306614961364, 4.5214192777843376e-09, 0.0, 0.0, 2.4588679716224843e-07, 0.0, 4.521419277784338e-09, 2.0657307344434694, 0.0, 0.0, 2.784540917356526e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 2.458867971622487e-07, 2.7845409173565203e-06, 0.0, 0.0, 2.0619193009595698, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 15 + stamp: + secs: 1624875198 + nsecs: 39307117 + frame_id: "/world" +pose: + pose: + position: + x: 0.0117163591387 + y: 0.00605252899946 + z: 0.0 + orientation: + x: 0.0 + y: 0.000304343618596 + z: 0.0 + w: 0.999999953687 + covariance: [2.146005064704313, 3.1565177059080497e-09, 0.0, 0.0, 8.270026924315442e-08, 0.0, 3.1565177059080485e-09, 2.1460051157429993, 0.0, 0.0, 7.604544669657427e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 8.27002692431543e-08, 7.604544669657414e-07, 0.0, 0.0, 2.1431432590691086, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 16 + stamp: + secs: 1624875198 + nsecs: 119277000 + frame_id: "/world" +pose: + pose: + position: + x: -0.000830828838583 + y: -0.0151919619832 + z: 0.0 + orientation: + x: 0.0 + y: 7.64437083169e-05 + z: 0.0 + w: 0.999999997078 + covariance: [2.490115747923964, 5.6119789052339174e-09, 0.0, 0.0, -1.053042834164992e-05, 0.0, 5.611978905233925e-09, 2.490115838937755, 0.0, 0.0, 1.0135261941182732e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.053042834164991e-05, 1.0135261941182715e-06, 0.0, 0.0, 2.4845445357063447, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 17 + stamp: + secs: 1624875198 + nsecs: 199289083 + frame_id: "/world" +pose: + pose: + position: + x: 0.00608578348289 + y: 0.0355035563829 + z: 0.0 + orientation: + x: -0.0 + y: -0.00362889972962 + z: -0.0 + w: 0.999993415522 + covariance: [2.6139474494902166, 6.503246709211537e-09, 0.0, 0.0, -9.149965389149485e-06, 0.0, 6.503246709211527e-09, 2.613947556012985, 0.0, 0.0, 2.758495337887368e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.149965389149485e-06, 2.7584953378873694e-06, 0.0, 0.0, 2.6069391815521645, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 18 + stamp: + secs: 1624875198 + nsecs: 279292107 + frame_id: "/world" +pose: + pose: + position: + x: 0.0057862759564 + y: 0.0354299542607 + z: 0.0 + orientation: + x: -0.0 + y: -0.000113806703477 + z: -0.0 + w: 0.999999993524 + covariance: [3.5629365969266176, 8.511129411512787e-09, 0.0, 0.0, -5.161293433126136e-06, 0.0, 8.511129411512782e-09, 3.562936738284586, 0.0, 0.0, 4.214092510970849e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.161293433126138e-06, 4.2140925109708515e-06, 0.0, 0.0, 3.5529071707948505, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 19 + stamp: + secs: 1624875198 + nsecs: 359307051 + frame_id: "/world" +pose: + pose: + position: + x: 0.00443116249069 + y: 0.044019377542 + z: 0.0 + orientation: + x: 0.0 + y: 0.000330729206714 + z: 0.0 + w: 0.999999945309 + covariance: [3.0388732862699315, 2.6405539809565164e-09, 0.0, 0.0, -9.377688714154101e-07, 0.0, 2.640553980956514e-09, 3.0388733303159587, 0.0, 0.0, 1.179743040237987e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.377688714154109e-07, 1.1797430402379878e-06, 0.0, 0.0, 3.0356510790043285, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 20 + stamp: + secs: 1624875198 + nsecs: 439341068 + frame_id: "/world" +pose: + pose: + position: + x: 0.00487458581203 + y: 0.0414893885128 + z: 0.0 + orientation: + x: -0.0 + y: -5.71892453277e-05 + z: -0.0 + w: 0.999999998365 + covariance: [2.671211977417257, 4.774715948597809e-10, 0.0, 0.0, -1.4077558481331576e-07, 0.0, 4.774715948597801e-10, 2.671211985395572, 0.0, 0.0, 1.9441207304537183e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4077558481331592e-07, 1.9441207304537212e-07, 0.0, 0.0, 2.6706159013387882, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 21 + stamp: + secs: 1624875198 + nsecs: 519325018 + frame_id: "/world" +pose: + pose: + position: + x: 0.0154616264841 + y: 0.0162499846793 + z: 0.0 + orientation: + x: -0.0 + y: -0.00228571508401 + z: -0.0 + w: 0.99999738775 + covariance: [2.814422923123372, 3.211664870708064e-10, 0.0, 0.0, -9.55297304870148e-10, 0.0, 3.211664870708062e-10, 2.8144229285088986, 0.0, 0.0, 1.4029059611017004e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.552973048701933e-10, 1.4029059611017023e-07, 0.0, 0.0, 2.8139877949403083, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 22 + stamp: + secs: 1624875198 + nsecs: 599320889 + frame_id: "/world" +pose: + pose: + position: + x: 0.00925735035741 + y: 0.0194015825112 + z: 0.0 + orientation: + x: 0.0 + y: 0.000222849544262 + z: 0.0 + w: 0.999999975169 + covariance: [3.4446712527437735, 1.3437496944213191e-09, 0.0, 0.0, -6.103195180550493e-07, 0.0, 1.343749694421319e-09, 3.444671275334528, 0.0, 0.0, 6.486316161245206e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.103195180550495e-07, 6.486316161245209e-07, 0.0, 0.0, 3.4426348987163298, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 23 + stamp: + secs: 1624875198 + nsecs: 679327011 + frame_id: "/world" +pose: + pose: + position: + x: 0.00984220473555 + y: 0.0198808960337 + z: 0.0 + orientation: + x: 0.0 + y: 0.000111783694732 + z: 0.0 + w: 0.999999993752 + covariance: [3.9097553635596474, 1.6941249213005866e-09, 0.0, 0.0, -7.00012148333959e-07, 0.0, 1.6941249213005853e-09, 3.9097553920792247, 0.0, 0.0, 8.1507404019409e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.000121483339592e-07, 8.150740401940902e-07, 0.0, 0.0, 3.9070711390157964, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 24 + stamp: + secs: 1624875198 + nsecs: 759337902 + frame_id: "/world" +pose: + pose: + position: + x: 0.00665082160728 + y: 0.0122950704865 + z: 0.0 + orientation: + x: 0.0 + y: 0.000351481241339 + z: 0.0 + w: 0.99999993823 + covariance: [6.6796998779875505, 1.7460354444889173e-09, 0.0, 0.0, -6.315717337636585e-07, 0.0, 1.7460354444889163e-09, 6.679699907393659, 0.0, 0.0, 1.0018533043681738e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.315717337636585e-07, 1.001853304368174e-06, 0.0, 0.0, 6.67689229937404, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 25 + stamp: + secs: 1624875198 + nsecs: 839340925 + frame_id: "/world" +pose: + pose: + position: + x: 0.00656131283759 + y: 0.0125133306089 + z: 0.0 + orientation: + x: -0.0 + y: -5.14725098349e-05 + z: -0.0 + w: 0.999999998675 + covariance: [5.387434231009007, 3.98167033673926e-10, 0.0, 0.0, -1.4294278264433425e-07, 0.0, 3.981670336739258e-10, 5.38743423771501, 0.0, 0.0, 2.3542011596029729e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.429427826443343e-07, 2.3542011596029752e-07, 0.0, 0.0, 5.38679284692647, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 26 + stamp: + secs: 1624875198 + nsecs: 919356108 + frame_id: "/world" +pose: + pose: + position: + x: -0.0160066391523 + y: 0.0395563881879 + z: 0.0 + orientation: + x: 0.0 + y: 0.00109229560804 + z: 0.0 + w: 0.999999403445 + covariance: [5.4422867159825, 3.9994871656092023e-10, 0.0, 0.0, 6.007764198111168e-08, 0.0, 3.999487165609199e-10, 5.442286722737885, 0.0, 0.0, -5.529028106468523e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 6.007764198111167e-08, -5.529028106468525e-07, 0.0, 0.0, 5.441405981137459, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 27 + stamp: + secs: 1624875198 + nsecs: 999368906 + frame_id: "/world" +pose: + pose: + position: + x: -0.0166945672149 + y: 0.0395493916865 + z: 0.0 + orientation: + x: 0.0 + y: 0.000177400966647 + z: 0.0 + w: 0.999999984264 + covariance: [5.109337181940768, 6.726220234085786e-10, 0.0, 0.0, -2.49758378141529e-07, 0.0, 6.726220234085784e-10, 5.109337193292254, 0.0, 0.0, -3.1305949533610187e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4975837814152896e-07, -3.1305949533610187e-07, 0.0, 0.0, 5.107978719315799, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 28 + stamp: + secs: 1624875199 + nsecs: 79366922 + frame_id: "/world" +pose: + pose: + position: + x: -0.0164363631371 + y: 0.0388459344108 + z: 0.0 + orientation: + x: 0.0 + y: 0.000197205335015 + z: 0.0 + w: 0.999999980555 + covariance: [5.7516503046821015, 1.1223317941243867e-09, 0.0, 0.0, -1.1372293472360282e-06, 0.0, 1.122331794124386e-09, 5.751650323615462, 0.0, 0.0, -1.9020327776458715e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1372293472360278e-06, -1.902032777645871e-07, 0.0, 0.0, 5.749389146998635, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 29 + stamp: + secs: 1624875199 + nsecs: 159377098 + frame_id: "/world" +pose: + pose: + position: + x: -0.0215932483286 + y: 0.0412181976543 + z: 0.0 + orientation: + x: 0.0 + y: 0.000111532776806 + z: 0.0 + w: 0.99999999378 + covariance: [5.183216023943926, 1.277800157654343e-09, 0.0, 0.0, -2.1977935560395288e-06, 0.0, 1.2778001576543428e-09, 5.183216045511387, 0.0, 0.0, 8.667208147067255e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1977935560395288e-06, 8.667208147067252e-07, 0.0, 0.0, 5.18058626469247, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 30 + stamp: + secs: 1624875199 + nsecs: 239401102 + frame_id: "/world" +pose: + pose: + position: + x: -0.0181430761731 + y: 0.0460998360207 + z: 0.0 + orientation: + x: 0.0 + y: 0.00152025696064 + z: 0.0 + w: 0.999998844409 + covariance: [6.229618965950779, 3.6573356537969314e-09, 0.0, 0.0, -6.94017505485088e-06, 0.0, 3.657335653796928e-09, 6.229619027903319, 0.0, 0.0, 2.5709755827457238e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.94017505485088e-06, 2.5709755827457246e-06, 0.0, 0.0, 6.2218008521219215, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 31 + stamp: + secs: 1624875199 + nsecs: 319385052 + frame_id: "/world" +pose: + pose: + position: + x: -0.0200555592676 + y: 0.0464923871201 + z: 0.0 + orientation: + x: 0.0 + y: 0.000329085060907 + z: 0.0 + w: 0.999999945852 + covariance: [6.094364670457917, 4.620258576101434e-10, 0.0, 0.0, -7.35171280082033e-07, 0.0, 4.62025857610143e-10, 6.094364678269983, 0.0, 0.0, 4.216738498793818e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.351712800820328e-07, 4.216738498793821e-07, 0.0, 0.0, 6.093382005283262, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 32 + stamp: + secs: 1624875199 + nsecs: 399395943 + frame_id: "/world" +pose: + pose: + position: + x: -0.0204530749926 + y: 0.046592377435 + z: 0.0 + orientation: + x: 0.0 + y: 0.000436204332822 + z: 0.0 + w: 0.999999904863 + covariance: [5.6315466847125615, 1.0279844172009881e-09, 0.0, 0.0, -4.5241419325170345e-06, 0.0, 1.0279844172009877e-09, 5.63154670216875, 0.0, 0.0, 8.404521412827395e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.5241419325170345e-06, 8.404521412827396e-07, 0.0, 0.0, 5.629272692341887, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 33 + stamp: + secs: 1624875199 + nsecs: 479382038 + frame_id: "/world" +pose: + pose: + position: + x: -0.0481946387613 + y: 0.0779569295575 + z: 0.0 + orientation: + x: 0.0 + y: 0.00159488830561 + z: 0.0 + w: 0.999998728165 + covariance: [5.914592729255935, 1.0677418681924041e-10, 0.0, 0.0, 8.203175573547793e-08, 0.0, 1.0677418681924036e-10, 5.914592731064431, 0.0, 0.0, 5.67256028978185e-08, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 8.203175573547784e-08, 5.672560289781845e-08, 0.0, 0.0, 5.9143626984012565, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 34 + stamp: + secs: 1624875199 + nsecs: 559417963 + frame_id: "/world" +pose: + pose: + position: + x: -0.0425653970002 + y: 0.0719048334437 + z: 0.0 + orientation: + x: 0.0 + y: 0.000240983283111 + z: 0.0 + w: 0.999999970964 + covariance: [6.003188840221803, 6.569169194160187e-10, 0.0, 0.0, -5.742061837434037e-06, 0.0, 6.569169194160184e-10, 6.003188851462168, 0.0, 0.0, 1.6363338419308646e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.742061837434035e-06, 1.6363338419308648e-06, 0.0, 0.0, 6.001594705419577, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 35 + stamp: + secs: 1624875199 + nsecs: 639408112 + frame_id: "/world" +pose: + pose: + position: + x: -0.0410990112364 + y: 0.0719800145286 + z: 0.0 + orientation: + x: 0.0 + y: 0.00010879362278 + z: 0.0 + w: 0.999999994082 + covariance: [5.6101639750458965, 1.7785246406660766e-09, 0.0, 0.0, -8.752189204696292e-06, 0.0, 1.7785246406660758e-09, 5.610164006001768, 0.0, 0.0, 4.729550871230466e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.752189204696287e-06, 4.729550871230465e-06, 0.0, 0.0, 5.605519588565328, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 36 + stamp: + secs: 1624875199 + nsecs: 719436884 + frame_id: "/world" +pose: + pose: + position: + x: -0.0401195417187 + y: 0.0670482200886 + z: 0.0 + orientation: + x: 0.0 + y: 0.000216858671016 + z: 0.0 + w: 0.999999976486 + covariance: [6.386812761949125, 3.2593319426826862e-09, 0.0, 0.0, -8.504556696385084e-06, 0.0, 3.259331942682683e-09, 6.386812819296, 0.0, 0.0, 6.7749615507815e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.504556696385078e-06, 6.774961550781498e-06, 0.0, 0.0, 6.377946141106799, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 37 + stamp: + secs: 1624875199 + nsecs: 799429893 + frame_id: "/world" +pose: + pose: + position: + x: -0.0405598251814 + y: 0.0713097189718 + z: 0.0 + orientation: + x: -0.0 + y: -9.9057749344e-05 + z: -0.0 + w: 0.999999995094 + covariance: [5.709537982053482, 2.8313268758692186e-09, 0.0, 0.0, -5.529404307570489e-06, 0.0, 2.8313268758692157e-09, 5.709538032151099, 0.0, 0.0, 4.01521949535703e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.5294043075704864e-06, 4.01521949535703e-06, 0.0, 0.0, 5.701616842724652, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 38 + stamp: + secs: 1624875199 + nsecs: 879475117 + frame_id: "/world" +pose: + pose: + position: + x: -0.0398704875567 + y: 0.069053248926 + z: 0.0 + orientation: + x: -0.0 + y: -0.000203556136595 + z: -0.0 + w: 0.999999979282 + covariance: [5.526693142097694, 4.255586883963843e-12, 0.0, 0.0, -4.5132191059445734e-06, 0.0, 4.255586883964016e-12, 5.526693142182814, 0.0, 0.0, 2.505823886958543e-08, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.513219105944572e-06, 2.5058238869586035e-08, 0.0, 0.0, 5.526573460970315, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 39 + stamp: + secs: 1624875199 + nsecs: 959450006 + frame_id: "/world" +pose: + pose: + position: + x: -0.0401841519955 + y: 0.0694097698125 + z: 0.0 + orientation: + x: 0.0 + y: 0.000263672124928 + z: 0.0 + w: 0.999999965239 + covariance: [7.551207693363225, 1.303695306552285e-09, 0.0, 0.0, -1.1850278072583487e-05, 0.0, 1.3036953065522837e-09, 7.55120771663648, 0.0, 0.0, 3.893577771968103e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1850278072583487e-05, 3.893577771968102e-06, 0.0, 0.0, 7.54731873547034, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 40 + stamp: + secs: 1624875200 + nsecs: 39455891 + frame_id: "/world" +pose: + pose: + position: + x: -0.0407192884216 + y: 0.0658396173474 + z: 0.0 + orientation: + x: 0.0 + y: 0.000311074769417 + z: 0.0 + w: 0.999999951616 + covariance: [6.470666822640793, 2.044422661463085e-09, 0.0, 0.0, -1.546516645505898e-05, 0.0, 2.044422661463084e-09, 6.470666859806525, 0.0, 0.0, 5.6520764732966e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5465166455058987e-05, 5.652076473296599e-06, 0.0, 0.0, 6.464229080615675, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 41 + stamp: + secs: 1624875200 + nsecs: 119455099 + frame_id: "/world" +pose: + pose: + position: + x: -0.040758059268 + y: 0.0663591785889 + z: 0.0 + orientation: + x: 0.0 + y: 0.000198145056707 + z: 0.0 + w: 0.999999980369 + covariance: [6.686734301054004, 2.421447987331603e-09, 0.0, 0.0, -1.261190725114951e-05, 0.0, 2.4214479873316006e-09, 6.686734345648609, 0.0, 0.0, 5.240250269802687e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2611907251149507e-05, 5.240250269802685e-06, 0.0, 0.0, 6.6787868837067785, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 42 + stamp: + secs: 1624875200 + nsecs: 199474096 + frame_id: "/world" +pose: + pose: + position: + x: -0.0427481375305 + y: 0.0686205314535 + z: 0.0 + orientation: + x: 0.0 + y: 0.00157855889501 + z: 0.0 + w: 0.999998754075 + covariance: [10.214724526931724, 6.949799205207544e-09, 0.0, 0.0, -2.1709971848932613e-05, 0.0, 6.949799205207538e-09, 10.214724656235257, 0.0, 0.0, 1.0564532821262854e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1709971848932606e-05, 1.0564532821262852e-05, 0.0, 0.0, 10.191059131040246, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 43 + stamp: + secs: 1624875200 + nsecs: 279485941 + frame_id: "/world" +pose: + pose: + position: + x: -0.0461353770764 + y: 0.0750991273274 + z: 0.0 + orientation: + x: 0.0 + y: 2.27294127948e-05 + z: 0.0 + w: 0.999999999742 + covariance: [7.115794788594093, 4.2698502284685e-09, 0.0, 0.0, -9.3485773612271e-06, 0.0, 4.269850228468494e-09, 7.1157948684045875, 0.0, 0.0, 4.810212745920324e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.348577361227091e-06, 4.810212745920324e-06, 0.0, 0.0, 7.100861313674602, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 44 + stamp: + secs: 1624875200 + nsecs: 359488964 + frame_id: "/world" +pose: + pose: + position: + x: -0.0459706816566 + y: 0.0755646189941 + z: 0.0 + orientation: + x: 0.0 + y: 7.35061542155e-05 + z: 0.0 + w: 0.999999997298 + covariance: [6.360788862154457, 4.739118446556409e-09, 0.0, 0.0, -6.2154256363205885e-06, 0.0, 4.739118446556404e-09, 6.360788951102866, 0.0, 0.0, 2.763714303121092e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.215425636320585e-06, 2.7637143031210908e-06, 0.0, 0.0, 6.343620944125503, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 45 + stamp: + secs: 1624875200 + nsecs: 439486027 + frame_id: "/world" +pose: + pose: + position: + x: -0.0483345495148 + y: 0.0697634574365 + z: 0.0 + orientation: + x: 0.0 + y: 0.000132947803853 + z: 0.0 + w: 0.999999991162 + covariance: [7.2569149361046295, 5.028048368338878e-09, 0.0, 0.0, -8.0228583800563e-06, 0.0, 5.028048368338874e-09, 7.256915030947338, 0.0, 0.0, 7.82658008949263e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.022858380056298e-06, 7.826580089492628e-06, 0.0, 0.0, 7.238246444032866, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 46 + stamp: + secs: 1624875200 + nsecs: 519515038 + frame_id: "/world" +pose: + pose: + position: + x: -0.0496301948357 + y: 0.0671863823306 + z: 0.0 + orientation: + x: -0.0 + y: -0.000319716627028 + z: -0.0 + w: 0.999999948891 + covariance: [6.9499229082950436, 4.078389832455526e-09, 0.0, 0.0, -7.431792576628252e-06, 0.0, 4.078389832455522e-09, 6.949922986097483, 0.0, 0.0, 9.352490053057065e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.431792576628253e-06, 9.352490053057066e-06, 0.0, 0.0, 6.934322640108893, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 47 + stamp: + secs: 1624875200 + nsecs: 599533081 + frame_id: "/world" +pose: + pose: + position: + x: -0.0425630466069 + y: 0.0675904847021 + z: 0.0 + orientation: + x: -0.0 + y: -0.00328455842331 + z: -0.0 + w: 0.999994605823 + covariance: [10.41146376244531, 6.7002540307274514e-09, 0.0, 0.0, -1.0803901104319076e-05, 0.0, 6.700254030727445e-09, 10.411463891579308, 0.0, 0.0, 1.6023921031234494e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0803901104319076e-05, 1.6023921031234497e-05, 0.0, 0.0, 10.385138575876372, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 48 + stamp: + secs: 1624875200 + nsecs: 679512978 + frame_id: "/world" +pose: + pose: + position: + x: -0.0423935786645 + y: 0.067603029362 + z: 0.0 + orientation: + x: -0.0 + y: -0.00192923746179 + z: -0.0 + w: 0.99999813902 + covariance: [12.955510211644269, 1.2736549722631535e-08, 0.0, 0.0, -1.5241051401261352e-05, 0.0, 1.273654972263152e-08, 12.955510459888291, 0.0, 0.0, 2.667368822936255e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5241051401261348e-05, 2.667368822936256e-05, 0.0, 0.0, 12.903634646722526, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 49 + stamp: + secs: 1624875200 + nsecs: 759515047 + frame_id: "/world" +pose: + pose: + position: + x: -0.0426505379339 + y: 0.0669876828773 + z: 0.0 + orientation: + x: 0.0 + y: 0.000479012840667 + z: 0.0 + w: 0.999999885273 + covariance: [7.665896446027593, 5.664701585346499e-09, 0.0, 0.0, -4.744013488578911e-06, 0.0, 5.6647015853464936e-09, 7.665896557102793, 0.0, 0.0, 8.955189757203733e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.7440134885789085e-06, 8.955189757203735e-06, 0.0, 0.0, 7.642131971376101, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 50 + stamp: + secs: 1624875200 + nsecs: 839543104 + frame_id: "/world" +pose: + pose: + position: + x: -0.0588304358 + y: 0.0450252071109 + z: 0.0 + orientation: + x: 0.0 + y: 0.000648590300192 + z: 0.0 + w: 0.999999789665 + covariance: [8.614999654858222, 8.844085364858197e-09, 0.0, 0.0, -2.158894333484208e-05, 0.0, 8.844085364858187e-09, 8.614999829907196, 0.0, 0.0, 8.814683423298341e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1588943334842082e-05, 8.814683423298341e-06, 0.0, 0.0, 8.576365638627754, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 51 + stamp: + secs: 1624875200 + nsecs: 919538975 + frame_id: "/world" +pose: + pose: + position: + x: -0.0541823858418 + y: 0.0456605715875 + z: 0.0 + orientation: + x: 0.0 + y: 3.15360215819e-05 + z: 0.0 + w: 0.999999999503 + covariance: [6.222070375101623, 3.780578819864481e-09, 0.0, 0.0, -1.4664955078387986e-05, 0.0, 3.780578819864477e-09, 6.222070450273468, 0.0, 0.0, 2.821905098360188e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4664955078387976e-05, 2.8219050983601865e-06, 0.0, 0.0, 6.2051154114586975, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 52 + stamp: + secs: 1624875200 + nsecs: 999536991 + frame_id: "/world" +pose: + pose: + position: + x: -0.0531786683828 + y: 0.0403424874 + z: 0.0 + orientation: + x: 0.0 + y: 0.00018449922361 + z: 0.0 + w: 0.99999998298 + covariance: [6.1055759692069005, 3.671988605059042e-09, 0.0, 0.0, -1.5659576223284996e-05, 0.0, 3.6719886050590356e-09, 6.105576042573671, 0.0, 0.0, 1.6348478455932145e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.565957622328498e-05, 1.6348478455932128e-06, 0.0, 0.0, 6.0885095263994256, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 53 + stamp: + secs: 1624875201 + nsecs: 79540968 + frame_id: "/world" +pose: + pose: + position: + x: -0.0531232260178 + y: 0.040599696997 + z: 0.0 + orientation: + x: 0.0 + y: 0.000356252945077 + z: 0.0 + w: 0.999999936542 + covariance: [6.071049224299907, 3.5584730208169503e-09, 0.0, 0.0, -2.593993779712038e-05, 0.0, 3.5584730208169457e-09, 6.071049295600293, 0.0, 0.0, 1.6868381304866595e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.593993779712037e-05, 1.6868381304866578e-06, 0.0, 0.0, 6.053941826995994, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 54 + stamp: + secs: 1624875201 + nsecs: 159560919 + frame_id: "/world" +pose: + pose: + position: + x: -0.0515965310653 + y: 0.0372558069186 + z: 0.0 + orientation: + x: 0.0 + y: 0.000153353581862 + z: 0.0 + w: 0.999999988241 + covariance: [6.5554202023576496, 3.6009724891127334e-09, 0.0, 0.0, -2.918246218302701e-05, 0.0, 3.60097248911273e-09, 6.555420274714578, 0.0, 0.0, 2.02520348314083e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.9182462183027015e-05, 2.0252034831408287e-06, 0.0, 0.0, 6.537423109724161, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 55 + stamp: + secs: 1624875201 + nsecs: 239557981 + frame_id: "/world" +pose: + pose: + position: + x: -0.0513899309889 + y: 0.0373689933971 + z: 0.0 + orientation: + x: -0.0 + y: -0.000125327146441 + z: -0.0 + w: 0.999999992147 + covariance: [6.725715574215326, 4.257847881272714e-09, 0.0, 0.0, -2.457511235408253e-05, 0.0, 4.257847881272708e-09, 6.725715660107967, 0.0, 0.0, 2.1564461196761063e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.457511235408253e-05, 2.156446119676106e-06, 0.0, 0.0, 6.703552068996524, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 56 + stamp: + secs: 1624875201 + nsecs: 319547892 + frame_id: "/world" +pose: + pose: + position: + x: -0.051178895169 + y: 0.0373314905614 + z: 0.0 + orientation: + x: -0.0 + y: -0.000187392577384 + z: -0.0 + w: 0.999999982442 + covariance: [6.2532333187585785, 3.7711712382568555e-09, 0.0, 0.0, -1.8484614504827182e-05, 0.0, 3.77117123825685e-09, 6.253233396060383, 0.0, 0.0, 8.419443995651417e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8484614504827182e-05, 8.41944399565142e-06, 0.0, 0.0, 6.232703571208513, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 57 + stamp: + secs: 1624875201 + nsecs: 399564028 + frame_id: "/world" +pose: + pose: + position: + x: -0.0516672682339 + y: 0.0372582110394 + z: 0.0 + orientation: + x: -0.0 + y: -0.000300714830524 + z: -0.0 + w: 0.999999954785 + covariance: [7.215885306648708, 4.0094139766186375e-09, 0.0, 0.0, -1.718400311106283e-05, 0.0, 4.009413976618631e-09, 7.215885391289209, 0.0, 0.0, 1.2279148296227846e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7184003111062826e-05, 1.227914829622785e-05, 0.0, 0.0, 7.192954859396255, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 58 + stamp: + secs: 1624875201 + nsecs: 479578972 + frame_id: "/world" +pose: + pose: + position: + x: -0.0463846568532 + y: 0.034449837009 + z: 0.0 + orientation: + x: -0.0 + y: -0.000291602490515 + z: -0.0 + w: 0.999999957484 + covariance: [6.942387329995982, 3.766883062573668e-09, 0.0, 0.0, -1.1645312894036364e-05, 0.0, 3.766883062573661e-09, 6.942387411624815, 0.0, 0.0, 9.320348310627923e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1645312894036365e-05, 9.320348310627926e-06, 0.0, 0.0, 6.919730340593574, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 59 + stamp: + secs: 1624875201 + nsecs: 559628963 + frame_id: "/world" +pose: + pose: + position: + x: -0.050313590207 + y: 0.0364422263493 + z: 0.0 + orientation: + x: -0.0 + y: -6.74025135932e-05 + z: -0.0 + w: 0.999999997728 + covariance: [8.269295601044773, 5.0633002183049215e-09, 0.0, 0.0, -1.1141725625904428e-05, 0.0, 5.063300218304914e-09, 8.269295712758788, 0.0, 0.0, 8.279242589009173e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1141725625904422e-05, 8.279242589009175e-06, 0.0, 0.0, 8.237591680135125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 60 + stamp: + secs: 1624875201 + nsecs: 639638901 + frame_id: "/world" +pose: + pose: + position: + x: -0.0523279458706 + y: 0.0403151390048 + z: 0.0 + orientation: + x: -0.0 + y: -0.000128558494539 + z: -0.0 + w: 0.999999991736 + covariance: [7.267469987131691, 3.6127629809668462e-09, 0.0, 0.0, -5.862203389266706e-06, 0.0, 3.612762980966841e-09, 7.267470067813911, 0.0, 0.0, 8.23287470678679e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.862203389266702e-06, 8.232874706786788e-06, 0.0, 0.0, 7.244150463127268, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 61 + stamp: + secs: 1624875201 + nsecs: 719597101 + frame_id: "/world" +pose: + pose: + position: + x: -0.0535547339662 + y: 0.0474406387205 + z: 0.0 + orientation: + x: -0.0 + y: -0.000438105913474 + z: -0.0 + w: 0.999999904032 + covariance: [5.932813146227613, 3.2084962805613845e-09, 0.0, 0.0, -5.00333159799478e-06, 0.0, 3.2084962805613787e-09, 5.932813219124593, 0.0, 0.0, 8.906028565149512e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.003331597994779e-06, 8.906028565149518e-06, 0.0, 0.0, 5.911171074567173, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 62 + stamp: + secs: 1624875201 + nsecs: 799607038 + frame_id: "/world" +pose: + pose: + position: + x: -0.0534598721022 + y: 0.0532877116065 + z: 0.0 + orientation: + x: -0.0 + y: -0.000521656647675 + z: -0.0 + w: 0.999999863937 + covariance: [6.504336092489083, 2.4571207468102597e-09, 0.0, 0.0, -8.757518636529195e-06, 0.0, 2.457120746810255e-09, 6.504336149267221, 0.0, 0.0, 9.047287197048292e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.757518636529195e-06, 9.047287197048297e-06, 0.0, 0.0, 6.487246933962467, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 63 + stamp: + secs: 1624875201 + nsecs: 879617929 + frame_id: "/world" +pose: + pose: + position: + x: -0.0527863464063 + y: 0.0472389370468 + z: 0.0 + orientation: + x: -0.0 + y: -0.000355931574645 + z: -0.0 + w: 0.999999936656 + covariance: [7.315057613172727, 2.52588729759037e-09, 0.0, 0.0, -1.2806505930258351e-05, 0.0, 2.5258872975903656e-09, 7.315057673794041, 0.0, 0.0, 1.0020109497711254e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2806505930258356e-05, 1.0020109497711258e-05, 0.0, 0.0, 7.296463017625533, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 64 + stamp: + secs: 1624875201 + nsecs: 959651947 + frame_id: "/world" +pose: + pose: + position: + x: -0.0553721450718 + y: 0.0476276052518 + z: 0.0 + orientation: + x: 0.0 + y: 0.000713764730188 + z: 0.0 + w: 0.99999974527 + covariance: [6.420786851635034, 2.983555028656739e-09, 0.0, 0.0, -1.3479858205933047e-05, 0.0, 2.983555028656736e-09, 6.420786926876147, 0.0, 0.0, 8.319095440942036e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3479858205933052e-05, 8.31909544094204e-06, 0.0, 0.0, 6.396988071389522, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 65 + stamp: + secs: 1624875202 + nsecs: 39701939 + frame_id: "/world" +pose: + pose: + position: + x: -0.0505424992249 + y: 0.0420103651189 + z: 0.0 + orientation: + x: 0.0 + y: 0.000309630907703 + z: 0.0 + w: 0.999999952064 + covariance: [8.006214149031438, 2.6478274883291098e-09, 0.0, 0.0, -1.0734195141003443e-05, 0.0, 2.6478274883291065e-09, 8.006214216856797, 0.0, 0.0, 6.2795935048806865e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0734195141003446e-05, 6.279593504880689e-06, 0.0, 0.0, 7.984505363981563, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 66 + stamp: + secs: 1624875202 + nsecs: 119643927 + frame_id: "/world" +pose: + pose: + position: + x: -0.0501580458513 + y: 0.0387541645839 + z: 0.0 + orientation: + x: -0.0 + y: -0.000165980270893 + z: -0.0 + w: 0.999999986225 + covariance: [7.190651972500992, 2.6737075389517348e-09, 0.0, 0.0, -7.304364844612394e-06, 0.0, 2.673707538951729e-09, 7.190652042550782, 0.0, 0.0, 4.073280221994479e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.3043648446123945e-06, 4.07328022199448e-06, 0.0, 0.0, 7.167706080416155, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 67 + stamp: + secs: 1624875202 + nsecs: 199664116 + frame_id: "/world" +pose: + pose: + position: + x: -0.0412033955723 + y: 0.0354541879602 + z: 0.0 + orientation: + x: -0.0 + y: -0.000245033191543 + z: -0.0 + w: 0.999999969979 + covariance: [9.362953637872767, 3.773190564883567e-09, 0.0, 0.0, -7.224994950347488e-06, 0.0, 3.77319056488356e-09, 9.362953737826746, 0.0, 0.0, 5.095413983632075e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.22499495034749e-06, 5.0954139836320754e-06, 0.0, 0.0, 9.329693527137698, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 68 + stamp: + secs: 1624875202 + nsecs: 279659033 + frame_id: "/world" +pose: + pose: + position: + x: -0.041060057264 + y: 0.0355073582177 + z: 0.0 + orientation: + x: -0.0 + y: -0.000232948524201 + z: -0.0 + w: 0.999999972867 + covariance: [7.584865306773077, 2.8058400145141555e-09, 0.0, 0.0, -3.5006137706194913e-06, 0.0, 2.80584001451415e-09, 7.584865381725598, 0.0, 0.0, 3.375959124298395e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.5006137706194925e-06, 3.3759591242983956e-06, 0.0, 0.0, 7.559479723969458, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 69 + stamp: + secs: 1624875202 + nsecs: 359657049 + frame_id: "/world" +pose: + pose: + position: + x: -0.0404039482262 + y: 0.0353750873619 + z: 0.0 + orientation: + x: -0.0 + y: -0.000711396476627 + z: -0.0 + w: 0.999999746957 + covariance: [8.585839850028128, 5.0895258425857525e-09, 0.0, 0.0, -1.1252708141983462e-05, 0.0, 5.089525842585744e-09, 8.585839987085345, 0.0, 0.0, 3.910806942593836e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1252708141983459e-05, 3.910806942593835e-06, 0.0, 0.0, 8.538218282212535, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 70 + stamp: + secs: 1624875202 + nsecs: 439666033 + frame_id: "/world" +pose: + pose: + position: + x: -0.0315414354144 + y: 0.0273564513163 + z: 0.0 + orientation: + x: 0.0 + y: 0.000257207155249 + z: 0.0 + w: 0.999999966922 + covariance: [8.11543617546917, 4.401690257225256e-09, 0.0, 0.0, -1.70659158640482e-05, 0.0, 4.401690257225249e-09, 8.115436294504347, 0.0, 0.0, 2.622992345158675e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7065915864048196e-05, 2.6229923451586745e-06, 0.0, 0.0, 8.073323166893184, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 71 + stamp: + secs: 1624875202 + nsecs: 519676924 + frame_id: "/world" +pose: + pose: + position: + x: -0.0294889970601 + y: 0.0257043828476 + z: 0.0 + orientation: + x: -0.0 + y: -6.40165308618e-05 + z: -0.0 + w: 0.999999997951 + covariance: [6.617887252911708, 1.7419234692831292e-09, 0.0, 0.0, -7.674655692363111e-06, 0.0, 1.741923469283126e-09, 6.617887300099801, 0.0, 0.0, 1.0195600230152164e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.674655692363113e-06, 1.0195600230152166e-06, 0.0, 0.0, 6.601034847664122, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 72 + stamp: + secs: 1624875202 + nsecs: 599704027 + frame_id: "/world" +pose: + pose: + position: + x: -0.0310287804562 + y: 0.032576968248 + z: 0.0 + orientation: + x: -0.0 + y: -0.000200619858165 + z: -0.0 + w: 0.999999979876 + covariance: [9.04002268348431, 4.7064963420103356e-09, 0.0, 0.0, -2.1525093731838417e-05, 0.0, 4.706496342010327e-09, 9.0400228116581, 0.0, 0.0, 2.1265924271434974e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1525093731838414e-05, 2.126592427143498e-06, 0.0, 0.0, 8.99286459162443, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 73 + stamp: + secs: 1624875202 + nsecs: 679709911 + frame_id: "/world" +pose: + pose: + position: + x: -0.0305069613398 + y: 0.0324097247277 + z: 0.0 + orientation: + x: -0.0 + y: -0.000114345083341 + z: -0.0 + w: 0.999999993463 + covariance: [6.855397335203499, 2.7201766585751314e-09, 0.0, 0.0, -1.1168567830275513e-05, 0.0, 2.720176658575126e-09, 6.855397409411203, 0.0, 0.0, 8.955674969571368e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1168567830275501e-05, 8.955674969571367e-07, 0.0, 0.0, 6.827569170775016, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 74 + stamp: + secs: 1624875202 + nsecs: 759694099 + frame_id: "/world" +pose: + pose: + position: + x: -0.0310316035302 + y: 0.0345282069086 + z: 0.0 + orientation: + x: 0.0 + y: 0.000195885261343 + z: 0.0 + w: 0.999999980814 + covariance: [5.441105053245132, 2.130878965044021e-09, 0.0, 0.0, -1.421210686898517e-05, 0.0, 2.130878965044017e-09, 5.441105111549796, 0.0, 0.0, 1.0340587415476813e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4212106868985169e-05, 1.0340587415476815e-06, 0.0, 0.0, 5.41866101270838, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 75 + stamp: + secs: 1624875202 + nsecs: 839711905 + frame_id: "/world" +pose: + pose: + position: + x: -0.0305541396172 + y: 0.0344195586272 + z: 0.0 + orientation: + x: 0.0 + y: 9.25634465759e-06 + z: 0.0 + w: 0.999999999957 + covariance: [5.869253540416316, 1.9139537695164687e-09, 0.0, 0.0, -1.3593708831389645e-05, 0.0, 1.913953769516465e-09, 5.869253592960617, 0.0, 0.0, 8.124658923472049e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3593708831389643e-05, 8.124658923472047e-07, 0.0, 0.0, 5.848584138772741, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 76 + stamp: + secs: 1624875202 + nsecs: 919713974 + frame_id: "/world" +pose: + pose: + position: + x: -0.03053133315 + y: 0.0340973068443 + z: 0.0 + orientation: + x: -0.0 + y: -3.17773453847e-05 + z: -0.0 + w: 0.999999999495 + covariance: [5.584295297516872, 1.6968167117566195e-09, 0.0, 0.0, -1.081074008616176e-05, 0.0, 1.6968167117566166e-09, 5.584295344138557, 0.0, 0.0, -6.84372826467214e-09, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0810740086161763e-05, -6.8437282646722635e-09, 0.0, 0.0, 5.56551204844527, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 77 + stamp: + secs: 1624875202 + nsecs: 999722004 + frame_id: "/world" +pose: + pose: + position: + x: -0.0300844483032 + y: 0.0339645587905 + z: 0.0 + orientation: + x: -0.0 + y: -0.000250040778057 + z: -0.0 + w: 0.99999996874 + covariance: [5.905692866487078, 9.938148436884699e-10, 0.0, 0.0, -5.804361844078661e-06, 0.0, 9.938148436884678e-10, 5.9056928937699285, 0.0, 0.0, -1.3304189995864723e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.804361844078661e-06, -1.3304189995864726e-07, 0.0, 0.0, 5.894575719238433, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 78 + stamp: + secs: 1624875203 + nsecs: 79710960 + frame_id: "/world" +pose: + pose: + position: + x: -0.0299044154196 + y: 0.0339138416884 + z: 0.0 + orientation: + x: -0.0 + y: -0.000222228545996 + z: -0.0 + w: 0.999999975307 + covariance: [7.761056264466418, 2.3078668151540547e-09, 0.0, 0.0, -1.0423470741179285e-05, 0.0, 2.3078668151540506e-09, 7.761056327672684, 0.0, 0.0, -2.7298197904686335e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0423470741179285e-05, -2.729819790468634e-07, 0.0, 0.0, 7.734622557341135, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 79 + stamp: + secs: 1624875203 + nsecs: 159800053 + frame_id: "/world" +pose: + pose: + position: + x: -0.0297611656214 + y: 0.0338090250099 + z: 0.0 + orientation: + x: 0.0 + y: 2.67723357009e-05 + z: 0.0 + w: 0.999999999642 + covariance: [6.034103821854874, 9.463211493416067e-10, 0.0, 0.0, -3.9484974617219715e-06, 0.0, 9.463211493416046e-10, 6.034103847766836, 0.0, 0.0, 2.452769377681723e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.948497461721972e-06, 2.452769377681724e-07, 0.0, 0.0, 6.02314969427104, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 80 + stamp: + secs: 1624875203 + nsecs: 239774942 + frame_id: "/world" +pose: + pose: + position: + x: -0.029368901455 + y: 0.0334426816863 + z: 0.0 + orientation: + x: 0.0 + y: 0.000253896548854 + z: 0.0 + w: 0.999999967768 + covariance: [5.625516576044126, 1.2095090240363255e-09, 0.0, 0.0, -3.5803580570908878e-06, 0.0, 1.2095090240363234e-09, 5.625516609284909, 0.0, 0.0, 2.5886630369631993e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.580358057090885e-06, 2.588663036963198e-06, 0.0, 0.0, 5.611147056000919, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 81 + stamp: + secs: 1624875203 + nsecs: 319755077 + frame_id: "/world" +pose: + pose: + position: + x: -0.0288780504803 + y: 0.0330889115738 + z: 0.0 + orientation: + x: 0.0 + y: 0.000415168978518 + z: 0.0 + w: 0.999999913817 + covariance: [5.924961329181338, 1.326524476628111e-09, 0.0, 0.0, -4.744901958268899e-06, 0.0, 1.3265244766281084e-09, 5.9249613659268405, 0.0, 0.0, 3.6999389075925713e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.744901958268899e-06, 3.699938907592571e-06, 0.0, 0.0, 5.908836708098841, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 82 + stamp: + secs: 1624875203 + nsecs: 399734974 + frame_id: "/world" +pose: + pose: + position: + x: -0.0286848291693 + y: 0.0331075847418 + z: 0.0 + orientation: + x: 0.0 + y: 0.000231751579465 + z: 0.0 + w: 0.999999973146 + covariance: [5.23112092223076, 1.096030935197983e-09, 0.0, 0.0, -4.797796254306697e-06, 0.0, 1.0960309351979815e-09, 5.231120952943339, 0.0, 0.0, 2.491463821786028e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.797796254306702e-06, 2.49146382178603e-06, 0.0, 0.0, 5.217371473415765, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 83 + stamp: + secs: 1624875203 + nsecs: 479762077 + frame_id: "/world" +pose: + pose: + position: + x: -0.02845367271 + y: 0.0333090233077 + z: 0.0 + orientation: + x: 0.0 + y: 0.000300143343316 + z: 0.0 + w: 0.999999954957 + covariance: [5.413716993569173, 1.473620758809044e-09, 0.0, 0.0, -4.8548570901298915e-06, 0.0, 1.4736207588090415e-09, 5.413717035367392, 0.0, 0.0, 2.691387981209663e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.854857090129894e-06, 2.691387981209665e-06, 0.0, 0.0, 5.3946013215805015, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 84 + stamp: + secs: 1624875203 + nsecs: 559773922 + frame_id: "/world" +pose: + pose: + position: + x: -0.0286786877919 + y: 0.0322730615972 + z: 0.0 + orientation: + x: 0.0 + y: 0.000191329093887 + z: 0.0 + w: 0.999999981697 + covariance: [5.46024166863482, 1.2571694277641156e-09, 0.0, 0.0, -3.0228783784282006e-06, 0.0, 1.2571694277641133e-09, 5.460241704522545, 0.0, 0.0, 1.8095042841270815e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.0228783784282014e-06, 1.8095042841270815e-06, 0.0, 0.0, 5.443551179157265, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 85 + stamp: + secs: 1624875203 + nsecs: 639780045 + frame_id: "/world" +pose: + pose: + position: + x: -0.0285804901255 + y: 0.0320538731409 + z: 0.0 + orientation: + x: 0.0 + y: 3.80904171056e-05 + z: 0.0 + w: 0.999999999275 + covariance: [5.464698330818288, 5.787897154344925e-10, 0.0, 0.0, -1.2347589206645487e-06, 0.0, 5.787897154344914e-10, 5.464698347376211, 0.0, 0.0, 7.254049284124402e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2347589206645485e-06, 7.254049284124404e-07, 0.0, 0.0, 5.456947512630863, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 86 + stamp: + secs: 1624875203 + nsecs: 719793081 + frame_id: "/world" +pose: + pose: + position: + x: -0.0312620632254 + y: 0.03965032995 + z: 0.0 + orientation: + x: 0.0 + y: 9.28232736998e-05 + z: 0.0 + w: 0.999999995692 + covariance: [6.341274492878904, 1.2595089286139686e-09, 0.0, 0.0, -1.9505573017544705e-06, 0.0, 1.259508928613967e-09, 6.341274529095355, 0.0, 0.0, 8.615374796298428e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.95055730175447e-06, 8.615374796298425e-07, 0.0, 0.0, 6.323898076354738, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 87 + stamp: + secs: 1624875203 + nsecs: 799793005 + frame_id: "/world" +pose: + pose: + position: + x: -0.0309824971152 + y: 0.0342561548439 + z: 0.0 + orientation: + x: 0.0 + y: 0.000525987038703 + z: 0.0 + w: 0.999999861669 + covariance: [8.866954138062416, 2.9572405819855988e-09, 0.0, 0.0, -3.727007742265527e-06, 0.0, 2.957240581985595e-09, 8.866954223266472, 0.0, 0.0, 1.1790096818246053e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.727007742265527e-06, 1.1790096818246047e-06, 0.0, 0.0, 8.825477446385875, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 88 + stamp: + secs: 1624875203 + nsecs: 879812002 + frame_id: "/world" +pose: + pose: + position: + x: -0.0344277784667 + y: 0.0324848852501 + z: 0.0 + orientation: + x: 0.0 + y: 0.00173008697801 + z: 0.0 + w: 0.999998503398 + covariance: [5.825984817613667, 1.6098280014090348e-09, 0.0, 0.0, -2.1750407431437753e-05, 0.0, 1.6098280014090317e-09, 5.825984864197565, 0.0, 0.0, 1.4004888115707307e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1750407431437746e-05, 1.4004888115707307e-06, 0.0, 0.0, 5.802810211083719, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 89 + stamp: + secs: 1624875203 + nsecs: 959813118 + frame_id: "/world" +pose: + pose: + position: + x: -0.0339046833964 + y: 0.0324200086486 + z: 0.0 + orientation: + x: 0.0 + y: 0.000332632996013 + z: 0.0 + w: 0.999999944678 + covariance: [7.026391437656853, 8.422161757013851e-10, 0.0, 0.0, -1.3891188929663267e-05, 0.0, 8.422161757013834e-10, 7.026391462072635, 0.0, 0.0, 8.410228800457056e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3891188929663267e-05, 8.410228800457062e-07, 0.0, 0.0, 7.014174459658646, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 90 + stamp: + secs: 1624875204 + nsecs: 39814949 + frame_id: "/world" +pose: + pose: + position: + x: -0.0336694499778 + y: 0.0322203083101 + z: 0.0 + orientation: + x: 0.0 + y: 0.000176068595634 + z: 0.0 + w: 0.9999999845 + covariance: [6.87808014913502, 1.0619422557336054e-09, 0.0, 0.0, -2.0859047988894462e-05, 0.0, 1.0619422557336041e-09, 6.878080180358597, 0.0, 0.0, 1.1814973694538239e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.085904798889447e-05, 1.1814973694538234e-06, 0.0, 0.0, 6.861769548881901, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 91 + stamp: + secs: 1624875204 + nsecs: 119822979 + frame_id: "/world" +pose: + pose: + position: + x: -0.0331388001079 + y: 0.0320591442278 + z: 0.0 + orientation: + x: -0.0 + y: -0.000380136448881 + z: -0.0 + w: 0.999999927748 + covariance: [6.83999897315463, 1.70999389722201e-09, 0.0, 0.0, -2.226458264929575e-05, 0.0, 1.7099938972220078e-09, 6.839999024844985, 0.0, 0.0, 4.699388931989947e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.2264582649295753e-05, 4.699388931989949e-06, 0.0, 0.0, 6.811786733087152, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 92 + stamp: + secs: 1624875204 + nsecs: 199822903 + frame_id: "/world" +pose: + pose: + position: + x: -0.0330533062238 + y: 0.0322120337701 + z: 0.0 + orientation: + x: 0.0 + y: 1.37573412709e-05 + z: 0.0 + w: 0.999999999905 + covariance: [6.829071707050904, 1.9389714085807932e-09, 0.0, 0.0, -1.9747852705332995e-05, 0.0, 1.938971408580791e-09, 6.829071767346333, 0.0, 0.0, 5.662282439739642e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.974785270533299e-05, 5.662282439739644e-06, 0.0, 0.0, 6.795282992848959, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 93 + stamp: + secs: 1624875204 + nsecs: 279830933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0328404383099 + y: 0.0318653501373 + z: 0.0 + orientation: + x: 0.0 + y: 0.000299350995417 + z: 0.0 + w: 0.999999955194 + covariance: [5.434728805439111, 1.2578021596983645e-09, 0.0, 0.0, -1.0448880064291836e-05, 0.0, 1.2578021596983635e-09, 5.43472884534197, 0.0, 0.0, 2.9077871775893866e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0448880064291828e-05, 2.9077871775893853e-06, 0.0, 0.0, 5.411911148495045, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 94 + stamp: + secs: 1624875204 + nsecs: 359844923 + frame_id: "/world" +pose: + pose: + position: + x: -0.0335537017199 + y: 0.0314645405542 + z: 0.0 + orientation: + x: 0.0 + y: 0.00120113288654 + z: 0.0 + w: 0.99999927864 + covariance: [9.278534859387115, 3.4715907434055907e-09, 0.0, 0.0, -2.301446301365134e-05, 0.0, 3.4715907434055874e-09, 9.278534971923774, 0.0, 0.0, 7.438017746864878e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.3014463013651325e-05, 7.438017746864875e-06, 0.0, 0.0, 9.213334843220945, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 95 + stamp: + secs: 1624875204 + nsecs: 439868927 + frame_id: "/world" +pose: + pose: + position: + x: -0.033367072921 + y: 0.0316673289145 + z: 0.0 + orientation: + x: 0.0 + y: 0.00025451472398 + z: 0.0 + w: 0.999999967611 + covariance: [6.363887353467459, 1.4998048217274868e-09, 0.0, 0.0, -8.359749404400713e-06, 0.0, 1.4998048217274839e-09, 6.3638874025750125, 0.0, 0.0, 2.9289939249842745e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.35974940440071e-06, 2.9289939249842767e-06, 0.0, 0.0, 6.335020018787344, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 96 + stamp: + secs: 1624875204 + nsecs: 519855022 + frame_id: "/world" +pose: + pose: + position: + x: -0.0348338648711 + y: 0.0262302465414 + z: 0.0 + orientation: + x: -0.0 + y: -8.7332841064e-06 + z: -0.0 + w: 0.999999999962 + covariance: [6.162852344399239, 1.8041247970330366e-09, 0.0, 0.0, -6.443740038064464e-06, 0.0, 1.8041247970330351e-09, 6.162852404269027, 0.0, 0.0, 2.1338095757298696e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.4437400380644605e-06, 2.13380957572987e-06, 0.0, 0.0, 6.126690969693305, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 97 + stamp: + secs: 1624875204 + nsecs: 599853039 + frame_id: "/world" +pose: + pose: + position: + x: -0.0344394330311 + y: 0.0306871365431 + z: 0.0 + orientation: + x: -0.0 + y: -0.00015656970843 + z: -0.0 + w: 0.999999987743 + covariance: [6.066727496954406, 7.696880628126793e-11, 0.0, 0.0, -3.151326723928853e-07, 0.0, 7.696880628126779e-11, 6.066727499454091, 0.0, 0.0, 3.1317780592323037e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.151326723928846e-07, 3.1317780592323074e-07, 0.0, 0.0, 6.065212696692563, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 98 + stamp: + secs: 1624875204 + nsecs: 679869890 + frame_id: "/world" +pose: + pose: + position: + x: -0.0338299908124 + y: 0.0280517457894 + z: 0.0 + orientation: + x: 0.0 + y: 0.000265507918146 + z: 0.0 + w: 0.999999964753 + covariance: [6.056477543677572, 4.6285874399291374e-10, 0.0, 0.0, -1.1113497452578978e-06, 0.0, 4.628587439929135e-10, 6.056477559120053, 0.0, 0.0, 2.281488279929027e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1113497452578984e-06, 2.2814882799290287e-07, 0.0, 0.0, 6.046925064952447, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 99 + stamp: + secs: 1624875204 + nsecs: 759877920 + frame_id: "/world" +pose: + pose: + position: + x: -0.0329866515592 + y: 0.0278088847168 + z: 0.0 + orientation: + x: -0.0 + y: -0.000169404419646 + z: -0.0 + w: 0.999999985651 + covariance: [7.128632962916727, 5.875731598299246e-10, 0.0, 0.0, -8.703472016663721e-07, 0.0, 5.875731598299242e-10, 7.128632982592892, 0.0, 0.0, 1.7938865387042096e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.703472016663729e-07, 1.7938865387042101e-07, 0.0, 0.0, 7.1162835418361885, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 100 + stamp: + secs: 1624875204 + nsecs: 839879036 + frame_id: "/world" +pose: + pose: + position: + x: -0.0311154973658 + y: 0.027280179285 + z: 0.0 + orientation: + x: 0.0 + y: 0.000121586685539 + z: 0.0 + w: 0.999999992608 + covariance: [7.576464061595512, 1.4464416789095634e-09, 0.0, 0.0, -3.3697787239758352e-06, 0.0, 1.446441678909562e-09, 7.576464110183898, 0.0, 0.0, 2.2518517835426142e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.369778723975836e-06, 2.2518517835426136e-07, 0.0, 0.0, 7.54527150915445, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 101 + stamp: + secs: 1624875204 + nsecs: 919888020 + frame_id: "/world" +pose: + pose: + position: + x: -0.0308621440054 + y: 0.0268758312756 + z: 0.0 + orientation: + x: 0.0 + y: 0.000149921646249 + z: 0.0 + w: 0.999999988762 + covariance: [6.496061590876407, 1.475563981339107e-09, 0.0, 0.0, -3.479437316583001e-06, 0.0, 1.4755639813391061e-09, 6.496061640511535, 0.0, 0.0, 6.167050714684449e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.4794373165830004e-06, 6.167050714684446e-07, 0.0, 0.0, 6.463676017441984, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 102 + stamp: + secs: 1624875204 + nsecs: 999908924 + frame_id: "/world" +pose: + pose: + position: + x: -0.0307967662538 + y: 0.0270356381578 + z: 0.0 + orientation: + x: 0.0 + y: 0.000307910440141 + z: 0.0 + w: 0.999999952596 + covariance: [6.720865926229536, 1.8921470645116818e-09, 0.0, 0.0, -2.952371215782367e-06, 0.0, 1.8921470645116805e-09, 6.720865989957784, 0.0, 0.0, 8.940032764606197e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.9523712157823677e-06, 8.940032764606198e-07, 0.0, 0.0, 6.678675916608024, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 103 + stamp: + secs: 1624875205 + nsecs: 79900026 + frame_id: "/world" +pose: + pose: + position: + x: -0.0292694340565 + y: 0.0251408741667 + z: 0.0 + orientation: + x: 0.0 + y: 0.000418195119105 + z: 0.0 + w: 0.999999912556 + covariance: [8.191414216495252, 3.0740713481742043e-09, 0.0, 0.0, -2.96976797078951e-06, 0.0, 3.074071348174201e-09, 8.19141432010717, 0.0, 0.0, 1.1726953217447635e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.96976797078951e-06, 1.1726953217447633e-06, 0.0, 0.0, 8.121821190221294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 104 + stamp: + secs: 1624875205 + nsecs: 159907103 + frame_id: "/world" +pose: + pose: + position: + x: -0.0269060014989 + y: 0.026547691892 + z: 0.0 + orientation: + x: 0.0 + y: 0.000231854374674 + z: 0.0 + w: 0.999999973122 + covariance: [6.1535880854239755, 1.9336092367815195e-09, 0.0, 0.0, -3.220015025013334e-05, 0.0, 1.933609236781518e-09, 6.153588151035405, 0.0, 0.0, 1.9864591427352405e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.220015025013334e-05, 1.986459142735241e-06, 0.0, 0.0, 6.108501135787327, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 105 + stamp: + secs: 1624875205 + nsecs: 239924908 + frame_id: "/world" +pose: + pose: + position: + x: -0.0242349737454 + y: 0.0299399329082 + z: 0.0 + orientation: + x: 0.0 + y: 0.000238124672259 + z: 0.0 + w: 0.999999971648 + covariance: [7.203672141420394, 2.2880239048294966e-09, 0.0, 0.0, -0.0001009262665111744, 0.0, 2.288023904829495e-09, 7.203672225130319, 0.0, 0.0, 7.537435938692662e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00010092626651117442, 7.537435938692666e-06, 0.0, 0.0, 7.141758772228517, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 106 + stamp: + secs: 1624875205 + nsecs: 319930077 + frame_id: "/world" +pose: + pose: + position: + x: -0.0223290701719 + y: 0.0276953029368 + z: 0.0 + orientation: + x: -0.0 + y: -0.000471969629237 + z: -0.0 + w: 0.999999888622 + covariance: [10.806865863833153, 5.2640177746204485e-09, 0.0, 0.0, -0.00037112542953827207, 0.0, 5.26401777462044e-09, 10.80686616490761, 0.0, 0.0, 3.528434041076206e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003711254295382722, 3.528434041076207e-05, 0.0, 0.0, 10.54184294164946, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 107 + stamp: + secs: 1624875205 + nsecs: 399924994 + frame_id: "/world" +pose: + pose: + position: + x: -0.0216832806074 + y: 0.0271965744313 + z: 0.0 + orientation: + x: 0.0 + y: 0.000205124659965 + z: 0.0 + w: 0.999999978962 + covariance: [8.97139692562157, 3.0656500575536066e-09, 0.0, 0.0, -0.00022050763383345907, 0.0, 3.065650057553599e-09, 8.971397161569744, 0.0, 0.0, 2.2888386818543097e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00022050763383345916, 2.2888386818543107e-05, 0.0, 0.0, 8.745768335711709, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 108 + stamp: + secs: 1624875205 + nsecs: 479929924 + frame_id: "/world" +pose: + pose: + position: + x: -0.0210443530108 + y: 0.0277616442926 + z: 0.0 + orientation: + x: 0.0 + y: 0.000153249999882 + z: 0.0 + w: 0.999999988257 + covariance: [5.86173182967955, 7.861113392175589e-10, 0.0, 0.0, -5.512350526599892e-05, 0.0, 7.861113392175561e-10, 5.861731902653673, 0.0, 0.0, 7.169261987220312e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.512350526599894e-05, 7.1692619872203145e-06, 0.0, 0.0, 5.788777134408452, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 109 + stamp: + secs: 1624875205 + nsecs: 559950113 + frame_id: "/world" +pose: + pose: + position: + x: -0.0208444492588 + y: 0.0276181965 + z: 0.0 + orientation: + x: 0.0 + y: 0.000392762305429 + z: 0.0 + w: 0.999999922869 + covariance: [7.09019489749804, 5.179923228793742e-10, 0.0, 0.0, -3.9885929219927276e-05, 0.0, 5.179923228793714e-10, 7.090194975326228, 0.0, 0.0, 7.532119953578711e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.98859292199273e-05, 7.532119953578708e-06, 0.0, 0.0, 7.008358385653565, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 110 + stamp: + secs: 1624875205 + nsecs: 639954090 + frame_id: "/world" +pose: + pose: + position: + x: -0.0206806629598 + y: 0.0275006543784 + z: 0.0 + orientation: + x: 0.0 + y: 0.000455728624985 + z: 0.0 + w: 0.999999896156 + covariance: [10.556672854473353, 5.012310378477949e-10, 0.0, 0.0, -4.199546505392787e-05, 0.0, 5.01231037847791e-10, 10.55667296162493, 0.0, 0.0, 8.925405966031005e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.199546505392788e-05, 8.925405966031003e-06, 0.0, 0.0, 10.441121106658985, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 111 + stamp: + secs: 1624875205 + nsecs: 719960928 + frame_id: "/world" +pose: + pose: + position: + x: -0.0201304147827 + y: 0.0269101588137 + z: 0.0 + orientation: + x: 0.0 + y: 0.000280804740835 + z: 0.0 + w: 0.999999960574 + covariance: [9.85797649490676, 2.402902249834455e-10, 0.0, 0.0, -2.2618123392973962e-05, 0.0, 2.402902249834429e-10, 9.857976566732077, 0.0, 0.0, 5.864265210453712e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.2618123392973976e-05, 5.864265210453712e-06, 0.0, 0.0, 9.77888075198424, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 112 + stamp: + secs: 1624875205 + nsecs: 799964905 + frame_id: "/world" +pose: + pose: + position: + x: -0.0185306526293 + y: 0.0269073240406 + z: 0.0 + orientation: + x: 0.0 + y: 0.000812724337519 + z: 0.0 + w: 0.99999966974 + covariance: [7.738198538605972, 7.249260886670068e-11, 0.0, 0.0, -1.0474687892030071e-05, 0.0, 7.249260886669899e-11, 7.738198587390989, 0.0, 0.0, 4.128636377329034e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0474687892030074e-05, 4.128636377329034e-06, 0.0, 0.0, 7.682603119075294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 113 + stamp: + secs: 1624875205 + nsecs: 879976034 + frame_id: "/world" +pose: + pose: + position: + x: -0.0182633788442 + y: 0.0267188952873 + z: 0.0 + orientation: + x: 0.0 + y: 0.000863213571145 + z: 0.0 + w: 0.999999627431 + covariance: [11.070022413868518, 7.153691185359882e-12, 0.0, 0.0, -1.3921550056593933e-05, 0.0, 7.153691185356287e-12, 11.070022518909951, 0.0, 0.0, 7.983309001994027e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3921550056593933e-05, 7.983309001994027e-06, 0.0, 0.0, 10.947340005863346, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 114 + stamp: + secs: 1624875205 + nsecs: 959978104 + frame_id: "/world" +pose: + pose: + position: + x: -0.0179925526894 + y: 0.0264395674232 + z: 0.0 + orientation: + x: 0.0 + y: 0.000297724259556 + z: 0.0 + w: 0.99999995568 + covariance: [8.935835657880686, -3.351546096070136e-11, 0.0, 0.0, -1.3086072063318267e-05, 0.0, -3.351546096070319e-11, 8.935835711129798, 0.0, 0.0, 6.720498236479114e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3086072063318273e-05, 6.720498236479113e-06, 0.0, 0.0, 8.872679935561846, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 115 + stamp: + secs: 1624875206 + nsecs: 40004015 + frame_id: "/world" +pose: + pose: + position: + x: -0.0177912468211 + y: 0.0262907982793 + z: 0.0 + orientation: + x: 0.0 + y: 0.000482243739872 + z: 0.0 + w: 0.99999988372 + covariance: [9.202620087947007, -2.040298736356732e-10, 0.0, 0.0, -2.7929718638954978e-05, 0.0, -2.0402987363567531e-10, 9.202620151291894, 0.0, 0.0, 1.2985170437266609e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.792971863895498e-05, 1.2985170437266607e-05, 0.0, 0.0, 9.125579044959062, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 116 + stamp: + secs: 1624875206 + nsecs: 119993925 + frame_id: "/world" +pose: + pose: + position: + x: -0.0231749157567 + y: 0.0148295463433 + z: 0.0 + orientation: + x: 0.0 + y: 0.000210898587134 + z: 0.0 + w: 0.999999977761 + covariance: [8.328273322338097, -1.9411843869317915e-10, 0.0, 0.0, -1.8351649506314005e-05, 0.0, -1.9411843869318034e-10, 8.32827336247226, 0.0, 0.0, 9.157278128081366e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8351649506314005e-05, 9.157278128081368e-06, 0.0, 0.0, 8.278600801984739, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 117 + stamp: + secs: 1624875206 + nsecs: 199990988 + frame_id: "/world" +pose: + pose: + position: + x: -0.02299716388 + y: 0.0146507323071 + z: 0.0 + orientation: + x: 0.0 + y: 0.000137752994957 + z: 0.0 + w: 0.999999990512 + covariance: [11.479037152282265, -5.326957207623402e-10, 0.0, 0.0, -3.0612832973066205e-05, 0.0, -5.326957207623424e-10, 11.479037224144653, 0.0, 0.0, 1.6274931424681063e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.0612832973066205e-05, 1.6274931424681066e-05, 0.0, 0.0, 11.388309687778115, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 118 + stamp: + secs: 1624875206 + nsecs: 280004025 + frame_id: "/world" +pose: + pose: + position: + x: -0.022917166196 + y: 0.0143090039172 + z: 0.0 + orientation: + x: -0.0 + y: -0.000197716386214 + z: -0.0 + w: 0.999999980454 + covariance: [7.383230190583339, -2.0653715315980992e-10, 0.0, 0.0, -9.237221517089571e-06, 0.0, -2.0653715315981072e-10, 7.383230215031422, 0.0, 0.0, 5.080690483860106e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.237221517089575e-06, 5.080690483860107e-06, 0.0, 0.0, 7.351908948740117, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 119 + stamp: + secs: 1624875206 + nsecs: 360021114 + frame_id: "/world" +pose: + pose: + position: + x: -0.0235232108536 + y: 0.0158795092608 + z: 0.0 + orientation: + x: -0.0 + y: -0.000425189601446 + z: -0.0 + w: 0.999999909607 + covariance: [7.678720028429655, -3.4915910139598493e-10, 0.0, 0.0, -8.80679168635356e-06, 0.0, -3.491591013959859e-10, 7.678720060991857, 0.0, 0.0, 6.367947421803017e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.806791686353562e-06, 6.3679474218030165e-06, 0.0, 0.0, 7.635973878069887, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 120 + stamp: + secs: 1624875206 + nsecs: 440040112 + frame_id: "/world" +pose: + pose: + position: + x: -0.0238875755032 + y: 0.0163535814918 + z: 0.0 + orientation: + x: -0.0 + y: -0.000193245896964 + z: -0.0 + w: 0.999999981328 + covariance: [8.630624022829892, -5.181334676670465e-10, 0.0, 0.0, -9.732494808975448e-06, 0.0, -5.181334676670477e-10, 8.630624065599063, 0.0, 0.0, 7.1840100509190324e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.732494808975448e-06, 7.184010050919034e-06, 0.0, 0.0, 8.5734533583517, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 121 + stamp: + secs: 1624875206 + nsecs: 520046949 + frame_id: "/world" +pose: + pose: + position: + x: -0.0254625677107 + y: 0.0207340946087 + z: 0.0 + orientation: + x: -0.0 + y: -8.47632319135e-05 + z: -0.0 + w: 0.999999996408 + covariance: [8.14783907993573, -5.967051723548534e-10, 0.0, 0.0, -8.515532928792829e-06, 0.0, -5.967051723548549e-10, 8.147839125450133, 0.0, 0.0, 5.569756398519332e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.515532928792827e-06, 5.569756398519331e-06, 0.0, 0.0, 8.085831564385149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 122 + stamp: + secs: 1624875206 + nsecs: 600040913 + frame_id: "/world" +pose: + pose: + position: + x: -0.021514677121 + y: 0.0187254136152 + z: 0.0 + orientation: + x: 0.0 + y: 0.00225126106215 + z: 0.0 + w: 0.999997465909 + covariance: [7.975982974818024, -6.538310641181409e-10, 0.0, 0.0, -9.480824641322966e-06, 0.0, -6.538310641181426e-10, 7.975983022230691, 0.0, 0.0, 3.992503314234489e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.480824641322962e-06, 3.992503314234488e-06, 0.0, 0.0, 7.910270910791598, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 123 + stamp: + secs: 1624875206 + nsecs: 680032969 + frame_id: "/world" +pose: + pose: + position: + x: -0.0214332402648 + y: 0.0186503914779 + z: 0.0 + orientation: + x: 0.0 + y: 0.00109258343587 + z: 0.0 + w: 0.999999403131 + covariance: [9.820008198748663, -6.017148079178165e-10, 0.0, 0.0, -8.819377412104283e-06, 0.0, -6.01714807917818e-10, 9.82000824163459, 0.0, 0.0, 3.003885479144821e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.819377412104281e-06, 3.0038854791448207e-06, 0.0, 0.0, 9.760124273115483, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 124 + stamp: + secs: 1624875206 + nsecs: 760040998 + frame_id: "/world" +pose: + pose: + position: + x: -0.0213392366995 + y: 0.0185613358439 + z: 0.0 + orientation: + x: 0.0 + y: 0.000148826674158 + z: 0.0 + w: 0.999999988925 + covariance: [8.532483141096968, -4.0879358899993684e-10, 0.0, 0.0, -1.894427229134666e-05, 0.0, -4.0879358899993777e-10, 8.532483169269126, 0.0, 0.0, 1.5196607487185151e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8944272291346646e-05, 1.5196607487185151e-06, 0.0, 0.0, 8.49256512212595, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 125 + stamp: + secs: 1624875206 + nsecs: 840075016 + frame_id: "/world" +pose: + pose: + position: + x: -0.022211740611 + y: 0.0110155061012 + z: 0.0 + orientation: + x: 0.0 + y: 6.38691002156e-05 + z: 0.0 + w: 0.99999999796 + covariance: [6.73333915865292, -2.8941716487302587e-10, 0.0, 0.0, -2.2630467187315206e-05, 0.0, -2.894171648730264e-10, 6.7333391771564335, 0.0, 0.0, 1.2945879349312284e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.2630467187315203e-05, 1.2945879349312292e-06, 0.0, 0.0, 6.706249565606263, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 126 + stamp: + secs: 1624875206 + nsecs: 920078039 + frame_id: "/world" +pose: + pose: + position: + x: -0.0222409799199 + y: 0.011048094896 + z: 0.0 + orientation: + x: 0.0 + y: 9.28344478399e-05 + z: 0.0 + w: 0.999999995691 + covariance: [10.22751085925785, -1.6334099452560162e-10, 0.0, 0.0, -1.247852279036819e-05, 0.0, -1.6334099452560193e-10, 10.227510869979964, 0.0, 0.0, 7.350963471726725e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2478522790368189e-05, 7.350963471726732e-07, 0.0, 0.0, 10.211947692085849, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 127 + stamp: + secs: 1624875207 + nsecs: 104904 + frame_id: "/world" +pose: + pose: + position: + x: -0.0183395444905 + y: 0.0110053078331 + z: 0.0 + orientation: + x: -0.0 + y: -0.00358757292589 + z: -0.0 + w: 0.99999356464 + covariance: [12.81100767248707, -3.230994829911428e-10, 0.0, 0.0, -2.7258830938452172e-05, 0.0, -3.2309948299114347e-10, 12.81100769210501, 0.0, 0.0, 8.811132966162442e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.7258830938452172e-05, 8.81113296616245e-07, 0.0, 0.0, 12.781542415719633, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 128 + stamp: + secs: 1624875207 + nsecs: 80077887 + frame_id: "/world" +pose: + pose: + position: + x: -0.0201559870744 + y: 0.010116690955 + z: 0.0 + orientation: + x: 0.0 + y: 0.000552887390014 + z: 0.0 + w: 0.999999847158 + covariance: [7.643226268295187, -2.6787770368641524e-10, 0.0, 0.0, -1.8029266264096224e-05, 0.0, -2.6787770368641565e-10, 7.643226283168313, 0.0, 0.0, 7.387093667500837e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8029266264096224e-05, 7.38709366750084e-07, 0.0, 0.0, 7.619748712073523, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 129 + stamp: + secs: 1624875207 + nsecs: 160103083 + frame_id: "/world" +pose: + pose: + position: + x: -0.019890488839 + y: 0.00981281935897 + z: 0.0 + orientation: + x: 0.0 + y: 0.000456716680405 + z: 0.0 + w: 0.999999895705 + covariance: [10.993790329377488, -1.1168245493714973e-09, 0.0, 0.0, -6.56008768809389e-05, 0.0, -1.1168245493714992e-09, 10.993790385932353, 0.0, 0.0, 3.1642822402349156e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.56008768809389e-05, 3.1642822402349147e-06, 0.0, 0.0, 10.900266042348838, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 130 + stamp: + secs: 1624875207 + nsecs: 240103006 + frame_id: "/world" +pose: + pose: + position: + x: -0.0238166654646 + y: 0.00592690260835 + z: 0.0 + orientation: + x: 0.0 + y: 1.01483706241e-05 + z: 0.0 + w: 0.999999999949 + covariance: [8.905482690895404, -5.729012074319021e-10, 0.0, 0.0, -3.888408878470981e-05, 0.0, -5.729012074319029e-10, 8.905482719060785, 0.0, 0.0, 1.6182550412668407e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.888408878470981e-05, 1.6182550412668405e-06, 0.0, 0.0, 8.858027632986373, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 131 + stamp: + secs: 1624875207 + nsecs: 320096970 + frame_id: "/world" +pose: + pose: + position: + x: -0.0258947856358 + y: 0.00892641423116 + z: 0.0 + orientation: + x: -0.0 + y: -0.000100854807115 + z: -0.0 + w: 0.999999994914 + covariance: [6.288933456265454, -3.3948807458945774e-10, 0.0, 0.0, -2.2723695803208398e-05, 0.0, -3.394880745894584e-10, 6.288933470868127, 0.0, 0.0, 3.3120770133021176e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.2723695803208388e-05, 3.3120770133021154e-06, 0.0, 0.0, 6.263307048161116, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 132 + stamp: + secs: 1624875207 + nsecs: 400090933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0360834561166 + y: 0.0372382845405 + z: 0.0 + orientation: + x: -0.0 + y: -0.000666450150041 + z: -0.0 + w: 0.999999777922 + covariance: [5.705664648001188, -5.313545047623679e-10, 0.0, 0.0, -1.7958555214087125e-05, 0.0, -5.313545047623684e-10, 5.7056646658099766, 0.0, 0.0, 5.669117945246423e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7958555214087108e-05, 5.669117945246422e-06, 0.0, 0.0, 5.672717428431745, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 133 + stamp: + secs: 1624875207 + nsecs: 480118990 + frame_id: "/world" +pose: + pose: + position: + x: -0.0360490640703 + y: 0.0372176913577 + z: 0.0 + orientation: + x: -0.0 + y: -0.000281060902256 + z: -0.0 + w: 0.999999960502 + covariance: [5.957510824137518, -5.195197088393778e-10, 0.0, 0.0, -1.5001535609129928e-05, 0.0, -5.195197088393785e-10, 5.957510839726995, 0.0, 0.0, 3.875282449489996e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5001535609129927e-05, 3.875282449489996e-06, 0.0, 0.0, 5.927841350932035, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 134 + stamp: + secs: 1624875207 + nsecs: 560122967 + frame_id: "/world" +pose: + pose: + position: + x: -0.0366406302709 + y: 0.0351606397213 + z: 0.0 + orientation: + x: -0.0 + y: -0.000236692768377 + z: -0.0 + w: 0.999999971988 + covariance: [6.033058423264003, -5.170912782605844e-10, 0.0, 0.0, -1.3854620546779711e-05, 0.0, -5.170912782605851e-10, 6.033058437211719, 0.0, 0.0, 3.252686842327282e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3854620546779714e-05, 3.2526868423272822e-06, 0.0, 0.0, 6.005653877230422, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 135 + stamp: + secs: 1624875207 + nsecs: 640136957 + frame_id: "/world" +pose: + pose: + position: + x: -0.0384632552582 + y: 0.0345702256041 + z: 0.0 + orientation: + x: 0.0 + y: 0.000863074610267 + z: 0.0 + w: 0.999999627551 + covariance: [9.689200976815654, -2.660925842750344e-10, 0.0, 0.0, -7.550591718626467e-06, 0.0, -2.6609258427503487e-10, 9.689200984259601, 0.0, 0.0, 2.178103893207592e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.550591718626467e-06, 2.178103893207592e-06, 0.0, 0.0, 9.674701616492486, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 136 + stamp: + secs: 1624875207 + nsecs: 720158100 + frame_id: "/world" +pose: + pose: + position: + x: -0.0404778604266 + y: 0.0367839579424 + z: 0.0 + orientation: + x: 0.0 + y: 0.000254643735561 + z: 0.0 + w: 0.999999967578 + covariance: [7.001891423411357, -3.23176831610324e-10, 0.0, 0.0, -1.795920422672207e-05, 0.0, -3.231768316103242e-10, 7.00189143120808, 0.0, 0.0, 1.974130987031971e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.795920422672207e-05, 1.974130987031973e-06, 0.0, 0.0, 6.985950053697888, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 137 + stamp: + secs: 1624875207 + nsecs: 800143957 + frame_id: "/world" +pose: + pose: + position: + x: -0.0450964605258 + y: 0.040806684497 + z: 0.0 + orientation: + x: 0.0 + y: 0.00232913625657 + z: 0.0 + w: 0.999997287558 + covariance: [10.510877782204364, -2.076340233955924e-09, 0.0, 0.0, -8.00646540196225e-05, 0.0, -2.0763402339559254e-09, 10.510877821392738, 0.0, 0.0, 1.2210489596696603e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.00646540196225e-05, 1.2210489596696601e-05, 0.0, 0.0, 10.424165580689714, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 138 + stamp: + secs: 1624875207 + nsecs: 880158901 + frame_id: "/world" +pose: + pose: + position: + x: -0.0443288234939 + y: 0.0406363418229 + z: 0.0 + orientation: + x: 0.0 + y: 0.000153555078819 + z: 0.0 + w: 0.99999998821 + covariance: [7.184856518238638, -8.144800798626029e-10, 0.0, 0.0, -2.4880795707733304e-05, 0.0, -8.144800798626031e-10, 7.184856533130897, 0.0, 0.0, 4.464352201265126e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4880795707733304e-05, 4.464352201265126e-06, 0.0, 0.0, 7.151370626209529, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 139 + stamp: + secs: 1624875207 + nsecs: 960160017 + frame_id: "/world" +pose: + pose: + position: + x: -0.0526354817788 + y: 0.0474527919433 + z: 0.0 + orientation: + x: 0.0 + y: 0.000327659393797 + z: 0.0 + w: 0.99999994632 + covariance: [8.414681718629161, -1.7281776678117347e-09, 0.0, 0.0, -3.0223011044057723e-05, 0.0, -1.7281776678117362e-09, 8.414681747443408, 0.0, 0.0, 7.044490213201151e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.0223011044057726e-05, 7.044490213201149e-06, 0.0, 0.0, 8.347601133476493, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 140 + stamp: + secs: 1624875208 + nsecs: 40215015 + frame_id: "/world" +pose: + pose: + position: + x: -0.0553558911999 + y: 0.0502097829513 + z: 0.0 + orientation: + x: 0.0 + y: 0.00165480937865 + z: 0.0 + w: 0.999998630802 + covariance: [11.56664359102057, -3.3696835843063628e-09, 0.0, 0.0, -4.113028078024783e-05, 0.0, -3.369683584306365e-09, 11.566643644822836, 0.0, 0.0, 1.110562042255045e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.113028078024783e-05, 1.1105620422550447e-05, 0.0, 0.0, 11.439108764556975, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 141 + stamp: + secs: 1624875208 + nsecs: 120165110 + frame_id: "/world" +pose: + pose: + position: + x: -0.0551797716369 + y: 0.0501227728728 + z: 0.0 + orientation: + x: 0.0 + y: 0.000273577753018 + z: 0.0 + w: 0.999999962578 + covariance: [9.091310172058941, -1.8182472738716208e-09, 0.0, 0.0, -2.1650833548456706e-05, 0.0, -1.8182472738716216e-09, 9.091310200522797, 0.0, 0.0, 5.562749142179315e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1650833548456716e-05, 5.562749142179315e-06, 0.0, 0.0, 9.022889177870363, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 142 + stamp: + secs: 1624875208 + nsecs: 200181961 + frame_id: "/world" +pose: + pose: + position: + x: -0.0552709062456 + y: 0.0507339983546 + z: 0.0 + orientation: + x: 0.0 + y: 0.000575468756623 + z: 0.0 + w: 0.999999834418 + covariance: [9.276684570630454, -2.4033385069307367e-09, 0.0, 0.0, -3.335837582235645e-05, 0.0, -2.4033385069307375e-09, 9.276684605680192, 0.0, 0.0, 1.5054715593458989e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.335837582235646e-05, 1.5054715593458992e-05, 0.0, 0.0, 9.19032093760843, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 143 + stamp: + secs: 1624875208 + nsecs: 280190945 + frame_id: "/world" +pose: + pose: + position: + x: -0.0544202290469 + y: 0.0503397642511 + z: 0.0 + orientation: + x: 0.0 + y: 0.000252221257907 + z: 0.0 + w: 0.999999968192 + covariance: [9.360418777008881, -2.9545815324364646e-09, 0.0, 0.0, -4.250625397628083e-05, 0.0, -2.9545815324364666e-09, 9.360418815970595, 0.0, 0.0, 2.067052061121112e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.2506253976280845e-05, 2.0670520611211117e-05, 0.0, 0.0, 9.262036482546465, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 144 + stamp: + secs: 1624875208 + nsecs: 360193968 + frame_id: "/world" +pose: + pose: + position: + x: -0.0543521798515 + y: 0.0504648476661 + z: 0.0 + orientation: + x: 0.0 + y: 0.000306479606011 + z: 0.0 + w: 0.999999953035 + covariance: [6.956891337061026, -2.184692733035926e-09, 0.0, 0.0, -2.4828292566667605e-05, 0.0, -2.184692733035928e-09, 6.956891362423589, 0.0, 0.0, 2.4001264991781627e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4828292566667602e-05, 2.400126499178161e-05, 0.0, 0.0, 6.8911058066548945, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 145 + stamp: + secs: 1624875208 + nsecs: 440201998 + frame_id: "/world" +pose: + pose: + position: + x: -0.0544863146037 + y: 0.0505573716899 + z: 0.0 + orientation: + x: 0.0 + y: 4.89497561093e-05 + z: 0.0 + w: 0.999999998802 + covariance: [6.3379402900262285, -1.9243962892352826e-09, 0.0, 0.0, -1.3211349242841948e-05, 0.0, -1.9243962892352834e-09, 6.33794031003906, 0.0, 0.0, 2.1927071135828655e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3211349242841945e-05, 2.1927071135828638e-05, 0.0, 0.0, 6.2854992499142135, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 146 + stamp: + secs: 1624875208 + nsecs: 520207882 + frame_id: "/world" +pose: + pose: + position: + x: -0.0572166093362 + y: 0.0530239796646 + z: 0.0 + orientation: + x: 0.0 + y: 1.8103978634e-05 + z: 0.0 + w: 0.999999999836 + covariance: [7.270214796795777, -2.160880361900544e-09, 0.0, 0.0, -9.266504436621238e-06, 0.0, -2.1608803619005447e-09, 7.270214817945915, 0.0, 0.0, 1.9360993188032343e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.266504436621242e-06, 1.9360993188032336e-05, 0.0, 0.0, 7.214602775603673, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 147 + stamp: + secs: 1624875208 + nsecs: 600233078 + frame_id: "/world" +pose: + pose: + position: + x: -0.0651464908429 + y: 0.0508651812408 + z: 0.0 + orientation: + x: 0.0 + y: 0.00381077668692 + z: 0.0 + w: 0.999992738964 + covariance: [10.664326310339947, -2.7135641842194643e-09, 0.0, 0.0, -1.729462176451981e-05, 0.0, -2.7135641842194643e-09, 10.6643263359864, 0.0, 0.0, 2.1190106916090973e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.729462176451981e-05, 2.1190106916090966e-05, 0.0, 0.0, 10.596697903073082, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 148 + stamp: + secs: 1624875208 + nsecs: 680222988 + frame_id: "/world" +pose: + pose: + position: + x: -0.0654167497932 + y: 0.054391774801 + z: 0.0 + orientation: + x: 0.0 + y: 0.00164429440374 + z: 0.0 + w: 0.999998648147 + covariance: [11.31098166278718, -3.893899353379644e-09, 0.0, 0.0, -5.6203801083069885e-05, 0.0, -3.8938993533796434e-09, 11.31098169599069, 0.0, 0.0, 2.243541792665306e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.620380108306988e-05, 2.2435417926653053e-05, 0.0, 0.0, 11.221391980960899, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 149 + stamp: + secs: 1624875208 + nsecs: 760227919 + frame_id: "/world" +pose: + pose: + position: + x: -0.0651100630841 + y: 0.0554773485993 + z: 0.0 + orientation: + x: -0.0 + y: -0.000212752722516 + z: -0.0 + w: 0.999999977368 + covariance: [7.375336531115688, -2.6883671592726957e-09, 0.0, 0.0, -3.9750448029968936e-05, 0.0, -2.6883671592726957e-09, 7.375336551289715, 0.0, 0.0, 1.4480670800563622e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.975044802996893e-05, 1.4480670800563623e-05, 0.0, 0.0, 7.318176852081374, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 150 + stamp: + secs: 1624875208 + nsecs: 840251923 + frame_id: "/world" +pose: + pose: + position: + x: -0.0615147137741 + y: 0.0882993852084 + z: 0.0 + orientation: + x: -0.0 + y: -0.000115641229226 + z: -0.0 + w: 0.999999993314 + covariance: [6.444195421309092, -2.111913802922803e-09, 0.0, 0.0, -2.4380538396054102e-05, 0.0, -2.1119138029228034e-09, 6.444195435419457, 0.0, 0.0, 1.5206329567741403e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4380538396054102e-05, 1.5206329567741397e-05, 0.0, 0.0, 6.402979747310026, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 151 + stamp: + secs: 1624875208 + nsecs: 920262098 + frame_id: "/world" +pose: + pose: + position: + x: -0.0615041036046 + y: 0.0883452176358 + z: 0.0 + orientation: + x: 0.0 + y: 0.000310944405874 + z: 0.0 + w: 0.999999951657 + covariance: [10.057743802426893, -4.327438059930475e-09, 0.0, 0.0, -3.732313134892521e-05, 0.0, -4.327438059930475e-09, 10.057743828329142, 0.0, 0.0, 3.0997557089915934e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.7323131348925194e-05, 3.099755708991593e-05, 0.0, 0.0, 9.980547035736576, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 152 + stamp: + secs: 1624875209 + nsecs: 256062 + frame_id: "/world" +pose: + pose: + position: + x: -0.0610032104159 + y: 0.0875508175815 + z: 0.0 + orientation: + x: 0.0 + y: 0.000246998957053 + z: 0.0 + w: 0.999999969496 + covariance: [9.668568063690339, -4.5540118692694894e-09, 0.0, 0.0, -2.7412292922728392e-05, 0.0, -4.5540118692694894e-09, 9.668568088950678, 0.0, 0.0, 3.384598896537729e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.7412292922728375e-05, 3.384598896537727e-05, 0.0, 0.0, 9.592053431541236, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 153 + stamp: + secs: 1624875209 + nsecs: 80250978 + frame_id: "/world" +pose: + pose: + position: + x: -0.0607190040854 + y: 0.0877525656858 + z: 0.0 + orientation: + x: 0.0 + y: 0.000187608347056 + z: 0.0 + w: 0.999999982402 + covariance: [10.829891628162668, -8.723509355725396e-09, 0.0, 0.0, -2.9244149988576057e-05, 0.0, -8.723509355725396e-09, 10.8298916733383, 0.0, 0.0, 5.528366695424347e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.9244149988576043e-05, 5.528366695424345e-05, 0.0, 0.0, 10.69172281797864, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 154 + stamp: + secs: 1624875209 + nsecs: 160267115 + frame_id: "/world" +pose: + pose: + position: + x: -0.0594469015574 + y: 0.0886398935282 + z: 0.0 + orientation: + x: 0.0 + y: 0.000214720585167 + z: 0.0 + w: 0.999999976948 + covariance: [10.010611843861962, -8.468860250703496e-09, 0.0, 0.0, -1.8300827745647474e-05, 0.0, -8.468860250703494e-09, 10.01061188658705, 0.0, 0.0, 4.7364027458434726e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.830082774564747e-05, 4.7364027458434726e-05, 0.0, 0.0, 9.878805610649094, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 155 + stamp: + secs: 1624875209 + nsecs: 240287066 + frame_id: "/world" +pose: + pose: + position: + x: -0.0604745511625 + y: 0.0924090287805 + z: 0.0 + orientation: + x: 0.0 + y: 8.78225883622e-05 + z: 0.0 + w: 0.999999996144 + covariance: [12.80434032108651, -1.688850015847961e-08, 0.0, 0.0, -2.1904852286412305e-05, 0.0, -1.6888500158479602e-08, 12.804340404734388, 0.0, 0.0, 7.754159436377395e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.19048522864123e-05, 7.754159436377395e-05, 0.0, 0.0, 12.545740678017884, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 156 + stamp: + secs: 1624875209 + nsecs: 320278883 + frame_id: "/world" +pose: + pose: + position: + x: -0.0603786195445 + y: 0.0924717947534 + z: 0.0 + orientation: + x: 0.0 + y: 0.000426240048495 + z: 0.0 + w: 0.99999990916 + covariance: [10.802833164367774, -1.4614279978323301e-08, 0.0, 0.0, -4.5920883165877596e-05, 0.0, -1.46142799783233e-08, 10.802833234315777, 0.0, 0.0, 6.320762016939585e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.59208831658776e-05, 6.320762016939585e-05, 0.0, 0.0, 10.583016365207628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 157 + stamp: + secs: 1624875209 + nsecs: 400302887 + frame_id: "/world" +pose: + pose: + position: + x: -0.0603684543081 + y: 0.0927046492324 + z: 0.0 + orientation: + x: 0.0 + y: 0.000382750001533 + z: 0.0 + w: 0.999999926751 + covariance: [8.891945530766213, -9.10448914324255e-09, 0.0, 0.0, -4.045154341645455e-05, 0.0, -9.104489143242546e-09, 8.891945572249433, 0.0, 0.0, 3.814444648384035e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.045154341645456e-05, 3.814444648384033e-05, 0.0, 0.0, 8.758903866925792, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 158 + stamp: + secs: 1624875209 + nsecs: 480295897 + frame_id: "/world" +pose: + pose: + position: + x: -0.0604552656782 + y: 0.0930407149434 + z: 0.0 + orientation: + x: 0.0 + y: 0.000526804038043 + z: 0.0 + w: 0.999999861239 + covariance: [8.27481597652931, -8.846627106911211e-09, 0.0, 0.0, -3.5538308257135635e-05, 0.0, -8.846627106911208e-09, 8.274816014043816, 0.0, 0.0, 3.490905476503107e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.5538308257135635e-05, 3.490905476503105e-05, 0.0, 0.0, 8.151559137518946, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 159 + stamp: + secs: 1624875209 + nsecs: 560297012 + frame_id: "/world" +pose: + pose: + position: + x: -0.062989646739 + y: 0.0912434997297 + z: 0.0 + orientation: + x: 0.0 + y: 0.000235879799356 + z: 0.0 + w: 0.99999997218 + covariance: [7.302326756051475, -6.19145260638392e-09, 0.0, 0.0, -1.996946638609721e-05, 0.0, -6.191452606383917e-09, 7.3023267810786665, 0.0, 0.0, 2.160437960340071e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9969466386097207e-05, 2.16043796034007e-05, 0.0, 0.0, 7.218331216544132, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 160 + stamp: + secs: 1624875209 + nsecs: 640314102 + frame_id: "/world" +pose: + pose: + position: + x: -0.0627360525981 + y: 0.087607233021 + z: 0.0 + orientation: + x: 0.0 + y: 0.000173554798832 + z: 0.0 + w: 0.999999984939 + covariance: [9.489713802108358, -9.945644842733902e-09, 0.0, 0.0, -3.529895192066662e-05, 0.0, -9.945644842733899e-09, 9.489713840144862, 0.0, 0.0, 2.6941102784009624e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.52989519206666e-05, 2.6941102784009614e-05, 0.0, 0.0, 9.35942431815401, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 161 + stamp: + secs: 1624875209 + nsecs: 720318079 + frame_id: "/world" +pose: + pose: + position: + x: -0.0624946181861 + y: 0.0876490447431 + z: 0.0 + orientation: + x: 0.0 + y: 0.000118113702905 + z: 0.0 + w: 0.999999993025 + covariance: [8.469670997390306, -8.923686266727836e-09, 0.0, 0.0, -6.609165932169292e-05, 0.0, -8.923686266727841e-09, 8.4696710282805, 0.0, 0.0, 2.5624229299049516e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.609165932169295e-05, 2.5624229299049512e-05, 0.0, 0.0, 8.358388332576164, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 162 + stamp: + secs: 1624875209 + nsecs: 800335884 + frame_id: "/world" +pose: + pose: + position: + x: -0.065358309703 + y: 0.0905268229374 + z: 0.0 + orientation: + x: 0.0 + y: 0.000213824915872 + z: 0.0 + w: 0.999999977139 + covariance: [7.3735958497492495, -8.14568635085441e-09, 0.0, 0.0, -6.812098707268805e-05, 0.0, -8.14568635085441e-09, 7.373595872928433, 0.0, 0.0, 2.1479980188348905e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.812098707268806e-05, 2.1479980188348882e-05, 0.0, 0.0, 7.2802707248444385, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 163 + stamp: + secs: 1624875209 + nsecs: 880331039 + frame_id: "/world" +pose: + pose: + position: + x: -0.0653767133668 + y: 0.0905572157374 + z: 0.0 + orientation: + x: 0.0 + y: 0.000236269492658 + z: 0.0 + w: 0.999999972088 + covariance: [7.689630015032313, -7.4289025777378055e-09, 0.0, 0.0, -4.908285900278426e-05, 0.0, -7.428902577737806e-09, 7.689630033577643, 0.0, 0.0, 1.5843121828872007e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.9082859002784284e-05, 1.5843121828872e-05, 0.0, 0.0, 7.6085707989065785, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 164 + stamp: + secs: 1624875209 + nsecs: 960352898 + frame_id: "/world" +pose: + pose: + position: + x: -0.0670162056739 + y: 0.0874722199536 + z: 0.0 + orientation: + x: 0.0 + y: 0.000390085451194 + z: 0.0 + w: 0.999999923917 + covariance: [7.111465754217329, -5.677159263083617e-09, 0.0, 0.0, -2.8267402206741476e-05, 0.0, -5.677159263083617e-09, 7.111465766897703, 0.0, 0.0, 9.425595974755963e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.826740220674149e-05, 9.425595974755963e-06, 0.0, 0.0, 7.051897635863527, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 165 + stamp: + secs: 1624875210 + nsecs: 40358067 + frame_id: "/world" +pose: + pose: + position: + x: -0.0683245467124 + y: 0.089681841905 + z: 0.0 + orientation: + x: 0.0 + y: 0.000419909152 + z: 0.0 + w: 0.999999911838 + covariance: [6.925473396705636, -5.005882106299054e-09, 0.0, 0.0, -1.53238213264763e-05, 0.0, -5.005882106299055e-09, 6.925473406898262, 0.0, 0.0, 5.8766165250506775e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.532382132647631e-05, 5.876616525050679e-06, 0.0, 0.0, 6.87411547391299, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 166 + stamp: + secs: 1624875210 + nsecs: 120342016 + frame_id: "/world" +pose: + pose: + position: + x: -0.0684397127554 + y: 0.0902278537722 + z: 0.0 + orientation: + x: 0.0 + y: 0.000144791187036 + z: 0.0 + w: 0.999999989518 + covariance: [6.862953133410115, -4.63513766301716e-09, 0.0, 0.0, -7.241722078945175e-06, 0.0, -4.635137663017162e-09, 6.862953142270873, 0.0, 0.0, 4.77291941305279e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.241722078945181e-06, 4.772919413052791e-06, 0.0, 0.0, 6.815860796681202, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 167 + stamp: + secs: 1624875210 + nsecs: 200356007 + frame_id: "/world" +pose: + pose: + position: + x: -0.0677525044481 + y: 0.0889268876701 + z: 0.0 + orientation: + x: -0.0 + y: -1.14545539705e-05 + z: -0.0 + w: 0.999999999934 + covariance: [6.836365786305241, -3.919793638864386e-09, 0.0, 0.0, -3.952543710669084e-06, 0.0, -3.919793638864387e-09, 6.83636579351851, 0.0, 0.0, 3.5675286337656294e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.952543710669086e-06, 3.567528633765631e-06, 0.0, 0.0, 6.7966104291124765, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 168 + stamp: + secs: 1624875210 + nsecs: 280395031 + frame_id: "/world" +pose: + pose: + position: + x: -0.0714763939681 + y: 0.095146207254 + z: 0.0 + orientation: + x: 0.0 + y: 8.7584788216e-05 + z: 0.0 + w: 0.999999996164 + covariance: [7.485099594920979, -6.390798971192872e-09, 0.0, 0.0, -6.639135518791788e-06, 0.0, -6.3907989711928714e-09, 7.48509960627185, 0.0, 0.0, 3.7842497939865835e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.6391355187917894e-06, 3.784249793986585e-06, 0.0, 0.0, 7.420083096725052, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 169 + stamp: + secs: 1624875210 + nsecs: 360379934 + frame_id: "/world" +pose: + pose: + position: + x: -0.071602836204 + y: 0.0953587522889 + z: 0.0 + orientation: + x: 0.0 + y: 0.000274675491297 + z: 0.0 + w: 0.999999962277 + covariance: [8.55679124053225, -8.141745785440454e-09, 0.0, 0.0, -2.0959806192574718e-05, 0.0, -8.141745785440454e-09, 8.556791254658915, 0.0, 0.0, 4.154940994838682e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.0959806192574718e-05, 4.154940994838682e-06, 0.0, 0.0, 8.473613248795557, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 170 + stamp: + secs: 1624875210 + nsecs: 440391064 + frame_id: "/world" +pose: + pose: + position: + x: -0.0711354918431 + y: 0.0952215252298 + z: 0.0 + orientation: + x: 0.0 + y: 0.000383220672044 + z: 0.0 + w: 0.999999926571 + covariance: [9.05918491275364, -1.050486771455722e-08, 0.0, 0.0, -3.1632183983337616e-05, 0.0, -1.050486771455722e-08, 9.059184930353958, 0.0, 0.0, 4.385646597549421e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.1632183983337616e-05, 4.38564659754942e-06, 0.0, 0.0, 8.95109047363674, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 171 + stamp: + secs: 1624875210 + nsecs: 520392895 + frame_id: "/world" +pose: + pose: + position: + x: -0.0667549295503 + y: 0.0890447175755 + z: 0.0 + orientation: + x: 0.0 + y: 0.000434150283879 + z: 0.0 + w: 0.999999905757 + covariance: [8.303769751011767, -8.218010551480477e-09, 0.0, 0.0, -2.5779486358916677e-05, 0.0, -8.218010551480478e-09, 8.303769764444755, 0.0, 0.0, 2.743818685313314e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5779486358916684e-05, 2.743818685313314e-06, 0.0, 0.0, 8.21865392177844, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 172 + stamp: + secs: 1624875210 + nsecs: 600393057 + frame_id: "/world" +pose: + pose: + position: + x: -0.0674290962046 + y: 0.088755640247 + z: 0.0 + orientation: + x: 0.0 + y: 0.0011758505508 + z: 0.0 + w: 0.999999308688 + covariance: [10.076142307101978, -1.3508287019896064e-08, 0.0, 0.0, -4.7142227165322045e-05, 0.0, -1.3508287019896067e-08, 10.076142328195358, 0.0, 0.0, 1.0826392415117583e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.714222716532206e-05, 1.0826392415117583e-05, 0.0, 0.0, 9.935810645707686, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 173 + stamp: + secs: 1624875210 + nsecs: 680402040 + frame_id: "/world" +pose: + pose: + position: + x: -0.0674034307709 + y: 0.0890357717124 + z: 0.0 + orientation: + x: 0.0 + y: 0.000489899473388 + z: 0.0 + w: 0.999999879999 + covariance: [8.672944899474247, -1.1712703917852664e-08, 0.0, 0.0, -3.7493503307593155e-05, 0.0, -1.1712703917852672e-08, 8.672944916993467, 0.0, 0.0, 1.4679560750997515e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.749350330759315e-05, 1.4679560750997512e-05, 0.0, 0.0, 8.550548291018433, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 174 + stamp: + secs: 1624875210 + nsecs: 760426044 + frame_id: "/world" +pose: + pose: + position: + x: -0.0673770112846 + y: 0.0891953754435 + z: 0.0 + orientation: + x: 0.0 + y: 4.54551881465e-05 + z: 0.0 + w: 0.999999998967 + covariance: [9.113720900893439, -1.2388407213461635e-08, 0.0, 0.0, -3.908800295388416e-05, 0.0, -1.238840721346164e-08, 9.113720918659928, 0.0, 0.0, 2.483939448705318e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.908800295388416e-05, 2.4839394487053176e-05, 0.0, 0.0, 8.984777905137644, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 175 + stamp: + secs: 1624875210 + nsecs: 840425968 + frame_id: "/world" +pose: + pose: + position: + x: -0.0674566766479 + y: 0.0893492280149 + z: 0.0 + orientation: + x: -0.0 + y: -0.000235322323551 + z: -0.0 + w: 0.999999972312 + covariance: [9.300419255278255, -1.246551271484872e-08, 0.0, 0.0, -5.356387839918151e-05, 0.0, -1.2465512714848722e-08, 9.300419271982928, 0.0, 0.0, 3.297414300914958e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.356387839918151e-05, 3.297414300914957e-05, 0.0, 0.0, 9.173773395124538, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 176 + stamp: + secs: 1624875210 + nsecs: 920433044 + frame_id: "/world" +pose: + pose: + position: + x: -0.0638156349384 + y: 0.0818455869704 + z: 0.0 + orientation: + x: -0.0 + y: -0.000206646121422 + z: -0.0 + w: 0.999999978649 + covariance: [7.605881132950513, -9.31348367917051e-09, 0.0, 0.0, -6.804986645719923e-05, 0.0, -9.313483679170508e-09, 7.605881143219903, 0.0, 0.0, 2.2430080416189723e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.804986645719924e-05, 2.2430080416189712e-05, 0.0, 0.0, 7.515838436333252, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 177 + stamp: + secs: 1624875211 + nsecs: 436068 + frame_id: "/world" +pose: + pose: + position: + x: -0.064186282155 + y: 0.0822708672163 + z: 0.0 + orientation: + x: -0.0 + y: -0.000122115935874 + z: -0.0 + w: 0.999999992544 + covariance: [8.638644725224129, -1.3486303518595844e-08, 0.0, 0.0, -0.00012285533659181174, 0.0, -1.3486303518595847e-08, 8.638644733516214, 0.0, 0.0, 2.4591075403114134e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00012285533659181177, 2.4591075403114127e-05, 0.0, 0.0, 8.517966277357287, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 178 + stamp: + secs: 1624875211 + nsecs: 80427885 + frame_id: "/world" +pose: + pose: + position: + x: -0.0637543846903 + y: 0.0776712156116 + z: 0.0 + orientation: + x: 0.0 + y: 7.48996434248e-05 + z: 0.0 + w: 0.999999997195 + covariance: [7.418650957254186, -1.0702184035525193e-08, 0.0, 0.0, -8.510055884810425e-05, 0.0, -1.0702184035525195e-08, 7.4186509596888435, 0.0, 0.0, 1.4614374068271068e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.510055884810426e-05, 1.461437406827106e-05, 0.0, 0.0, 7.327320228172534, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 179 + stamp: + secs: 1624875211 + nsecs: 160442114 + frame_id: "/world" +pose: + pose: + position: + x: -0.0630875910835 + y: 0.0773653023406 + z: 0.0 + orientation: + x: 0.0 + y: 0.000347446088569 + z: 0.0 + w: 0.999999939641 + covariance: [7.019364780815247, -6.7875760100892094e-09, 0.0, 0.0, -4.539524417851057e-05, 0.0, -6.7875760100892094e-09, 7.019364780993988, 0.0, 0.0, 8.076754804054044e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.539524417851056e-05, 8.076754804054041e-06, 0.0, 0.0, 6.962794868444836, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 180 + stamp: + secs: 1624875211 + nsecs: 240469933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0642331875532 + y: 0.076568113063 + z: 0.0 + orientation: + x: 0.0 + y: 9.13823647978e-05 + z: 0.0 + w: 0.999999995825 + covariance: [6.357795103094717, -6.694679566469338e-09, 0.0, 0.0, -3.402567840340567e-05, 0.0, -6.694679566469336e-09, 6.357795101581306, 0.0, 0.0, 2.1800961834300426e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.4025678403405663e-05, 2.1800961834300433e-05, 0.0, 0.0, 6.305662526158487, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 181 + stamp: + secs: 1624875211 + nsecs: 320468903 + frame_id: "/world" +pose: + pose: + position: + x: -0.0645004623899 + y: 0.077265903976 + z: 0.0 + orientation: + x: -0.0 + y: -9.59026191496e-05 + z: -0.0 + w: 0.999999995401 + covariance: [5.702690780131673, -2.5318813949345575e-09, 0.0, 0.0, -1.2118174604145205e-05, 0.0, -2.5318813949345562e-09, 5.702690779467333, 0.0, 0.0, 9.700088651426859e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2118174604145204e-05, 9.70008865142686e-06, 0.0, 0.0, 5.683396900564999, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 182 + stamp: + secs: 1624875211 + nsecs: 400448084 + frame_id: "/world" +pose: + pose: + position: + x: -0.0645826760565 + y: 0.0771475139003 + z: 0.0 + orientation: + x: 0.0 + y: 0.000303085342513 + z: 0.0 + w: 0.99999995407 + covariance: [7.018584979011878, -8.212112739794991e-09, 0.0, 0.0, -3.5220012967455816e-05, 0.0, -8.212112739794991e-09, 7.018584976360864, 0.0, 0.0, 3.5110445353036324e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.5220012967455816e-05, 3.5110445353036324e-05, 0.0, 0.0, 6.963614993620737, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 183 + stamp: + secs: 1624875211 + nsecs: 480456114 + frame_id: "/world" +pose: + pose: + position: + x: -0.0643831748144 + y: 0.0768258878274 + z: 0.0 + orientation: + x: 0.0 + y: 4.89784353536e-05 + z: 0.0 + w: 0.999999998801 + covariance: [6.864417457991509, -2.8573479680107383e-09, 0.0, 0.0, -1.2300159802557137e-05, 0.0, -2.8573479680107383e-09, 6.864417457064917, 0.0, 0.0, 1.2280548069307739e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.230015980255714e-05, 1.2280548069307744e-05, 0.0, 0.0, 6.845246434296592, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 184 + stamp: + secs: 1624875211 + nsecs: 560573101 + frame_id: "/world" +pose: + pose: + position: + x: -0.0649794715692 + y: 0.0768045894808 + z: 0.0 + orientation: + x: 0.0 + y: 0.000212989428076 + z: 0.0 + w: 0.999999977318 + covariance: [7.4841116676868715, -7.339861321770579e-09, 0.0, 0.0, -1.9357700827015586e-05, 0.0, -7.339861321770579e-09, 7.484111665392173, 0.0, 0.0, 1.904769186943216e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9357700827015586e-05, 1.9047691869432164e-05, 0.0, 0.0, 7.439263816441796, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 185 + stamp: + secs: 1624875211 + nsecs: 640486956 + frame_id: "/world" +pose: + pose: + position: + x: -0.0648074791914 + y: 0.0766106779714 + z: 0.0 + orientation: + x: -0.0 + y: -0.000161030510187 + z: -0.0 + w: 0.999999987035 + covariance: [5.989265237225309, -5.52587946952387e-09, 0.0, 0.0, -9.08409999846855e-06, 0.0, -5.525879469523868e-09, 5.989265235526431, 0.0, 0.0, 8.608091294726054e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.084099998468556e-06, 8.608091294726053e-06, 0.0, 0.0, 5.956288848118261, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 186 + stamp: + secs: 1624875211 + nsecs: 720500946 + frame_id: "/world" +pose: + pose: + position: + x: -0.06432153393 + y: 0.0766283152631 + z: 0.0 + orientation: + x: -0.0 + y: -0.000255399250316 + z: -0.0 + w: 0.999999967386 + covariance: [5.627704734517555, -5.7457789778686906e-09, 0.0, 0.0, -5.22541915643028e-06, 0.0, -5.745778977868692e-09, 5.627704732773036, 0.0, 0.0, 4.739498755996313e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.225419156430284e-06, 4.739498755996313e-06, 0.0, 0.0, 5.593799080770885, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 187 + stamp: + secs: 1624875211 + nsecs: 800513029 + frame_id: "/world" +pose: + pose: + position: + x: -0.069799277725 + y: 0.0715132442794 + z: 0.0 + orientation: + x: -0.0 + y: -0.000254574243191 + z: -0.0 + w: 0.999999967596 + covariance: [7.629737818371217, -8.12008128216028e-09, 0.0, 0.0, -3.39688834672889e-06, 0.0, -8.120081282160282e-09, 7.629737815921798, 0.0, 0.0, 4.131786451610706e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.3968883467288934e-06, 4.131786451610706e-06, 0.0, 0.0, 7.581799449730552, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 188 + stamp: + secs: 1624875211 + nsecs: 880506992 + frame_id: "/world" +pose: + pose: + position: + x: -0.06987227977 + y: 0.0717055801752 + z: 0.0 + orientation: + x: 0.0 + y: 1.94774869033e-05 + z: 0.0 + w: 0.99999999981 + covariance: [6.018412320845307, -4.990293452156556e-09, 0.0, 0.0, -5.508165891128941e-07, 0.0, -4.990293452156553e-09, 6.01841231934603, 0.0, 0.0, 1.5435554707059462e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.508165891128954e-07, 1.543555470705947e-06, 0.0, 0.0, 5.988742694261827, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 189 + stamp: + secs: 1624875211 + nsecs: 960508108 + frame_id: "/world" +pose: + pose: + position: + x: -0.0669018728837 + y: 0.0791102968702 + z: 0.0 + orientation: + x: -0.0 + y: -0.00059346157969 + z: -0.0 + w: 0.999999823902 + covariance: [9.771800860085188, -1.8389608020280644e-08, 0.0, 0.0, -3.6674869413038455e-06, 0.0, -1.8389608020280634e-08, 9.771800854573405, 0.0, 0.0, 1.7259784561202466e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.667486941303848e-06, 1.7259784561202472e-06, 0.0, 0.0, 9.661639963851176, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 190 + stamp: + secs: 1624875212 + nsecs: 40527105 + frame_id: "/world" +pose: + pose: + position: + x: -0.0671447183967 + y: 0.079399946683 + z: 0.0 + orientation: + x: -0.0 + y: -3.90408158208e-05 + z: -0.0 + w: 0.999999999238 + covariance: [7.710339744536157, -9.835623115991636e-09, 0.0, 0.0, -3.24815815483313e-06, 0.0, -9.835623115991633e-09, 7.710339741587531, 0.0, 0.0, 1.6691145724359905e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.2481581548331324e-06, 1.669114572435992e-06, 0.0, 0.0, 7.65080483000845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 191 + stamp: + secs: 1624875212 + nsecs: 120568991 + frame_id: "/world" +pose: + pose: + position: + x: -0.0758594753221 + y: 0.0872578798723 + z: 0.0 + orientation: + x: -0.0 + y: -0.000149951582123 + z: -0.0 + w: 0.999999988757 + covariance: [7.847142885542752, -1.5925789664681933e-08, 0.0, 0.0, -5.544850122826242e-06, 0.0, -1.5925789664681926e-08, 7.847142880765877, 0.0, 0.0, 4.184621565051354e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.544850122826244e-06, 4.184621565051354e-06, 0.0, 0.0, 7.749210885877313, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 192 + stamp: + secs: 1624875212 + nsecs: 200536013 + frame_id: "/world" +pose: + pose: + position: + x: -0.0759416085309 + y: 0.0872348201874 + z: 0.0 + orientation: + x: -0.0 + y: -0.000292642815665 + z: -0.0 + w: 0.99999995718 + covariance: [7.878560736461114, -1.4856280130385023e-08, 0.0, 0.0, -4.244562309125132e-06, 0.0, -1.4856280130385023e-08, 7.87856073200425, 0.0, 0.0, 3.3108096362936802e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.244562309125135e-06, 3.31080963629368e-06, 0.0, 0.0, 7.786076746013208, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 193 + stamp: + secs: 1624875212 + nsecs: 280575037 + frame_id: "/world" +pose: + pose: + position: + x: -0.0775036085623 + y: 0.0869906630496 + z: 0.0 + orientation: + x: -0.0 + y: -0.000545294707222 + z: -0.0 + w: 0.999999851327 + covariance: [8.732594000411433, -1.4350898977398843e-08, 0.0, 0.0, -3.5345396629335378e-06, 0.0, -1.4350898977398838e-08, 8.73259399610498, 0.0, 0.0, 2.3678581949538095e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.5345396629335403e-06, 2.3678581949538095e-06, 0.0, 0.0, 8.642373290940599, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 194 + stamp: + secs: 1624875212 + nsecs: 360554934 + frame_id: "/world" +pose: + pose: + position: + x: -0.0778189843595 + y: 0.0863698777112 + z: 0.0 + orientation: + x: 0.0 + y: 0.000124553522561 + z: 0.0 + w: 0.999999992243 + covariance: [10.24555232525173, -1.1502041446210719e-08, 0.0, 0.0, -2.5648865468341656e-06, 0.0, -1.1502041446210714e-08, 10.245552321799526, 0.0, 0.0, 1.3813577441011839e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5648865468341677e-06, 1.3813577441011836e-06, 0.0, 0.0, 10.172859585276301, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 195 + stamp: + secs: 1624875212 + nsecs: 440562963 + frame_id: "/world" +pose: + pose: + position: + x: -0.0776955143081 + y: 0.0861583779382 + z: 0.0 + orientation: + x: -0.0 + y: -0.000168175241485 + z: -0.0 + w: 0.999999985859 + covariance: [8.70460367646707, -1.1975699814116953e-08, 0.0, 0.0, -1.0043856042590402e-05, 0.0, -1.1975699814116948e-08, 8.704603672856893, 0.0, 0.0, 4.367428621493413e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0043856042590404e-05, 4.367428621493414e-06, 0.0, 0.0, 8.62766703186998, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 196 + stamp: + secs: 1624875212 + nsecs: 520561934 + frame_id: "/world" +pose: + pose: + position: + x: -0.0808357936979 + y: 0.0862559911165 + z: 0.0 + orientation: + x: 0.0 + y: 2.19509910757e-05 + z: 0.0 + w: 0.999999999759 + covariance: [9.126050209809087, -1.6537893620885326e-08, 0.0, 0.0, -5.935532451307784e-05, 0.0, -1.6537893620885316e-08, 9.126050204105518, 0.0, 0.0, 8.087059506122517e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.9355324513077824e-05, 8.087059506122517e-06, 0.0, 0.0, 9.018702109496472, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 197 + stamp: + secs: 1624875212 + nsecs: 600589991 + frame_id: "/world" +pose: + pose: + position: + x: -0.0809388919923 + y: 0.0862151587872 + z: 0.0 + orientation: + x: 0.0 + y: 0.000427455809521 + z: 0.0 + w: 0.999999908641 + covariance: [9.29817844910503, -1.682952189869451e-08, 0.0, 0.0, -7.652153184415569e-05, 0.0, -1.68295218986945e-08, 9.298178441557086, 0.0, 0.0, 6.783944558095843e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.652153184415568e-05, 6.783944558095842e-06, 0.0, 0.0, 9.188536938469428, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 198 + stamp: + secs: 1624875212 + nsecs: 680576086 + frame_id: "/world" +pose: + pose: + position: + x: -0.0713131929553 + y: 0.116745653512 + z: 0.0 + orientation: + x: 0.0 + y: 0.000939986672819 + z: 0.0 + w: 0.999999558212 + covariance: [9.387291382714812, -1.9170396898759667e-08, 0.0, 0.0, -7.218758421624446e-05, 0.0, -1.917039689875965e-08, 9.38729137205671, 0.0, 0.0, 3.3376697624209957e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.218758421624448e-05, 3.337669762420995e-06, 0.0, 0.0, 9.260994940418831, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 199 + stamp: + secs: 1624875212 + nsecs: 760581970 + frame_id: "/world" +pose: + pose: + position: + x: -0.0579986693468 + y: 0.149519463176 + z: 0.0 + orientation: + x: -0.0 + y: -0.0002732363916 + z: -0.0 + w: 0.999999962671 + covariance: [7.6071584708632205, -1.0049798267121434e-08, 0.0, 0.0, -3.0744621536203854e-05, 0.0, -1.0049798267121424e-08, 7.607158464785454, 0.0, 0.0, 2.545238347039986e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.074462153620387e-05, 2.545238347039986e-06, 0.0, 0.0, 7.54034389335982, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 200 + stamp: + secs: 1624875212 + nsecs: 840596914 + frame_id: "/world" +pose: + pose: + position: + x: -0.0577952461299 + y: 0.149435779042 + z: 0.0 + orientation: + x: 0.0 + y: 0.000179467567357 + z: 0.0 + w: 0.999999983896 + covariance: [7.078118173935857, -7.146757430017939e-09, 0.0, 0.0, -1.5832717685819557e-05, 0.0, -7.1467574300179334e-09, 7.078118169256378, 0.0, 0.0, 4.198799868785044e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.583271768581956e-05, 4.198799868785042e-06, 0.0, 0.0, 7.030285934585913, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 201 + stamp: + secs: 1624875212 + nsecs: 920597076 + frame_id: "/world" +pose: + pose: + position: + x: -0.0578009970043 + y: 0.149609655869 + z: 0.0 + orientation: + x: 0.0 + y: 0.000262431496371 + z: 0.0 + w: 0.999999965565 + covariance: [8.348856566186615, -8.692600371925538e-09, 0.0, 0.0, -1.3016588632481835e-05, 0.0, -8.692600371925529e-09, 8.348856560153576, 0.0, 0.0, 6.073665122454936e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.301658863248184e-05, 6.073665122454934e-06, 0.0, 0.0, 8.290332987134356, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 202 + stamp: + secs: 1624875213 + nsecs: 623941 + frame_id: "/world" +pose: + pose: + position: + x: -0.0648869930524 + y: 0.160999763656 + z: 0.0 + orientation: + x: 0.0 + y: 0.000234148330999 + z: 0.0 + w: 0.999999972587 + covariance: [8.919674194181892, -7.362258567208585e-09, 0.0, 0.0, -8.462262243431985e-06, 0.0, -7.362258567208581e-09, 8.919674188935844, 0.0, 0.0, 4.636671727199689e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.462262243431985e-06, 4.636671727199688e-06, 0.0, 0.0, 8.86981569140546, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 203 + stamp: + secs: 1624875213 + nsecs: 80640078 + frame_id: "/world" +pose: + pose: + position: + x: -0.0647752764025 + y: 0.16098855974 + z: 0.0 + orientation: + x: 0.0 + y: 0.000488176127738 + z: 0.0 + w: 0.999999880842 + covariance: [8.234187322371552, -6.444380642916246e-09, 0.0, 0.0, -5.345311455713887e-06, 0.0, -6.444380642916245e-09, 8.234187317666569, 0.0, 0.0, 5.140830687999859e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.345311455713886e-06, 5.140830687999858e-06, 0.0, 0.0, 8.190513262141277, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 204 + stamp: + secs: 1624875213 + nsecs: 160621881 + frame_id: "/world" +pose: + pose: + position: + x: -0.0705581773746 + y: 0.161421436993 + z: 0.0 + orientation: + x: 0.0 + y: 0.00104183367585 + z: 0.0 + w: 0.999999457291 + covariance: [10.031348006822641, -1.6156466171781172e-08, 0.0, 0.0, -8.653257854433093e-06, 0.0, -1.615646617178117e-08, 10.031347994808012, 0.0, 0.0, 1.2333083724765819e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.653257854433094e-06, 1.2333083724765812e-05, 0.0, 0.0, 9.919402779650355, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 205 + stamp: + secs: 1624875213 + nsecs: 240650892 + frame_id: "/world" +pose: + pose: + position: + x: -0.0705621981038 + y: 0.161997072552 + z: 0.0 + orientation: + x: 0.0 + y: 0.000257737977977 + z: 0.0 + w: 0.999999966786 + covariance: [8.633364646300727, -1.2561903373294521e-08, 0.0, 0.0, -5.040840997634153e-06, 0.0, -1.2561903373294518e-08, 8.633364636904728, 0.0, 0.0, 7.280615555894683e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.040840997634155e-06, 7.280615555894682e-06, 0.0, 0.0, 8.54517457326381, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 206 + stamp: + secs: 1624875213 + nsecs: 320632935 + frame_id: "/world" +pose: + pose: + position: + x: -0.0705395638366 + y: 0.1621737086 + z: 0.0 + orientation: + x: 0.0 + y: 0.000284109382729 + z: 0.0 + w: 0.999999959641 + covariance: [7.402117573237779, -9.388767758297917e-09, 0.0, 0.0, -2.307859054577666e-05, 0.0, -9.388767758297914e-09, 7.4021175660526275, 0.0, 0.0, 3.367538906358908e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.307859054577666e-05, 3.367538906358907e-06, 0.0, 0.0, 7.335451702126676, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 207 + stamp: + secs: 1624875213 + nsecs: 400671005 + frame_id: "/world" +pose: + pose: + position: + x: -0.0711542463663 + y: 0.163794971352 + z: 0.0 + orientation: + x: 0.0 + y: 0.00034020950977 + z: 0.0 + w: 0.999999942129 + covariance: [7.0301245930688765, -9.166323482665889e-09, 0.0, 0.0, -3.4402365537248386e-05, 0.0, -9.166323482665884e-09, 7.03012458554465, 0.0, 0.0, 1.8499606629865858e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.440236553724838e-05, 1.849960662986586e-05, 0.0, 0.0, 6.965510207803547, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 208 + stamp: + secs: 1624875213 + nsecs: 480642080 + frame_id: "/world" +pose: + pose: + position: + x: -0.0716241204004 + y: 0.164955517122 + z: 0.0 + orientation: + x: 0.0 + y: 0.000353962823428 + z: 0.0 + w: 0.999999937355 + covariance: [7.576573663103091, -1.3140628778653531e-08, 0.0, 0.0, -3.087238690686374e-05, 0.0, -1.3140628778653525e-08, 7.576573652532563, 0.0, 0.0, 3.519497411489785e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.0872386906863724e-05, 3.519497411489785e-05, 0.0, 0.0, 7.486612417483455, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 209 + stamp: + secs: 1624875213 + nsecs: 560708046 + frame_id: "/world" +pose: + pose: + position: + x: -0.0723380269443 + y: 0.16484187283 + z: 0.0 + orientation: + x: 0.0 + y: 0.00023973300423 + z: 0.0 + w: 0.999999971264 + covariance: [7.097437063621975, -1.2364473481157014e-08, 0.0, 0.0, -1.9917081570284157e-05, 0.0, -1.2364473481157015e-08, 7.097437053879413, 0.0, 0.0, 2.4619189382050904e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.991708157028416e-05, 2.4619189382050907e-05, 0.0, 0.0, 7.013417502939897, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 210 + stamp: + secs: 1624875213 + nsecs: 640685081 + frame_id: "/world" +pose: + pose: + position: + x: -0.071282826782 + y: 0.166313499119 + z: 0.0 + orientation: + x: 0.0 + y: 0.000293504440394 + z: 0.0 + w: 0.999999956928 + covariance: [6.931548511338607, -1.0368231532850616e-08, 0.0, 0.0, -2.1644661942517233e-05, 0.0, -1.036823153285062e-08, 6.9315485032239375, 0.0, 0.0, 1.6292756017375845e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1644661942517233e-05, 1.6292756017375845e-05, 0.0, 0.0, 6.861697131767378, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 211 + stamp: + secs: 1624875213 + nsecs: 720674992 + frame_id: "/world" +pose: + pose: + position: + x: -0.0723260602155 + y: 0.167181440478 + z: 0.0 + orientation: + x: 0.0 + y: 0.00051335349927 + z: 0.0 + w: 0.999999868234 + covariance: [8.315660940669705, -1.5851307717467587e-08, 0.0, 0.0, -3.373104286803557e-05, 0.0, -1.5851307717467587e-08, 8.315660928135447, 0.0, 0.0, 1.7965777550723394e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.373104286803557e-05, 1.79657775507234e-05, 0.0, 0.0, 8.209987807966966, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 212 + stamp: + secs: 1624875213 + nsecs: 800682068 + frame_id: "/world" +pose: + pose: + position: + x: -0.0720948682338 + y: 0.167177811442 + z: 0.0 + orientation: + x: 0.0 + y: 0.000408927183225 + z: 0.0 + w: 0.999999916389 + covariance: [8.042541534872605, -1.3028974166532547e-08, 0.0, 0.0, -2.2143840030303365e-05, 0.0, -1.3028974166532549e-08, 8.042541524488833, 0.0, 0.0, 1.0812601021668432e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.214384003030336e-05, 1.0812601021668436e-05, 0.0, 0.0, 7.955717133152418, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 213 + stamp: + secs: 1624875213 + nsecs: 880716085 + frame_id: "/world" +pose: + pose: + position: + x: -0.0721589565579 + y: 0.167539762148 + z: 0.0 + orientation: + x: 0.0 + y: 0.000777605646838 + z: 0.0 + w: 0.999999697665 + covariance: [7.235041764609234, -1.1360508841562784e-08, 0.0, 0.0, -2.5941810592570596e-05, 0.0, -1.1360508841562786e-08, 7.235041755373409, 0.0, 0.0, 8.388891521316225e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5941810592570593e-05, 8.388891521316227e-06, 0.0, 0.0, 7.159882041222513, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 214 + stamp: + secs: 1624875213 + nsecs: 960705042 + frame_id: "/world" +pose: + pose: + position: + x: -0.0833136080689 + y: 0.169621916406 + z: 0.0 + orientation: + x: 0.0 + y: 0.000730085307521 + z: 0.0 + w: 0.999999733488 + covariance: [6.422854024090663, -9.47456809806743e-09, 0.0, 0.0, -2.7797808391550835e-05, 0.0, -9.474568098067428e-09, 6.422854016077826, 0.0, 0.0, 1.089654587259185e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.7797808391550835e-05, 1.0896545872591851e-05, 0.0, 0.0, 6.36000794116683, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 215 + stamp: + secs: 1624875214 + nsecs: 40746927 + frame_id: "/world" +pose: + pose: + position: + x: -0.0853692628428 + y: 0.165002383264 + z: 0.0 + orientation: + x: 0.0 + y: 7.95615894148e-05 + z: 0.0 + w: 0.999999996835 + covariance: [6.173798708885196, -6.043684493518283e-09, 0.0, 0.0, -1.627244899805488e-05, 0.0, -6.043684493518281e-09, 6.173798703708926, 0.0, 0.0, 1.0615924189579503e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.6272448998054878e-05, 1.0615924189579503e-05, 0.0, 0.0, 6.133939320081568, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 216 + stamp: + secs: 1624875214 + nsecs: 120723009 + frame_id: "/world" +pose: + pose: + position: + x: -0.0858497143164 + y: 0.168644290446 + z: 0.0 + orientation: + x: 0.0 + y: 0.000105303577777 + z: 0.0 + w: 0.999999994456 + covariance: [7.201397251355295, -7.60361395904355e-09, 0.0, 0.0, -2.6371231478352432e-05, 0.0, -7.603613959043549e-09, 7.201397244774411, 0.0, 0.0, 1.4847577926534025e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.6371231478352435e-05, 1.4847577926534027e-05, 0.0, 0.0, 7.152450338109883, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 217 + stamp: + secs: 1624875214 + nsecs: 200736046 + frame_id: "/world" +pose: + pose: + position: + x: -0.0873026961873 + y: 0.175522808034 + z: 0.0 + orientation: + x: 0.0 + y: 0.00036557771304 + z: 0.0 + w: 0.999999933176 + covariance: [6.954186404432193, -7.516672994898602e-09, 0.0, 0.0, -2.705774191496975e-05, 0.0, -7.516672994898602e-09, 6.954186397688143, 0.0, 0.0, 1.1156201207398514e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.7057741914969752e-05, 1.1156201207398519e-05, 0.0, 0.0, 6.906910004070561, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 218 + stamp: + secs: 1624875214 + nsecs: 280742884 + frame_id: "/world" +pose: + pose: + position: + x: -0.087849504203 + y: 0.17574086119 + z: 0.0 + orientation: + x: 0.0 + y: 0.00040789584873 + z: 0.0 + w: 0.99999991681 + covariance: [6.883217077200282, -9.069085994059954e-09, 0.0, 0.0, -2.9377994316860625e-05, 0.0, -9.069085994059956e-09, 6.883217068691036, 0.0, 0.0, 8.409153391552481e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.9377994316860632e-05, 8.409153391552483e-06, 0.0, 0.0, 6.826775430291029, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 219 + stamp: + secs: 1624875214 + nsecs: 360743999 + frame_id: "/world" +pose: + pose: + position: + x: -0.0849075036231 + y: 0.169626006906 + z: 0.0 + orientation: + x: 0.0 + y: 0.000379879219878 + z: 0.0 + w: 0.999999927846 + covariance: [6.327685835379596, -9.659520574996085e-09, 0.0, 0.0, -2.403627997404706e-05, 0.0, -9.659520574996083e-09, 6.327685825909227, 0.0, 0.0, 5.130116088891365e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.403627997404707e-05, 5.130116088891366e-06, 0.0, 0.0, 6.267785633032007, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 220 + stamp: + secs: 1624875214 + nsecs: 440733910 + frame_id: "/world" +pose: + pose: + position: + x: -0.093073931488 + y: 0.180145433713 + z: 0.0 + orientation: + x: 0.0 + y: 0.000829922225438 + z: 0.0 + w: 0.999999655614 + covariance: [6.684211507133398, -1.1660600464829524e-08, 0.0, 0.0, -3.8704605391856824e-05, 0.0, -1.166060046482952e-08, 6.684211495077529, 0.0, 0.0, 7.088137941801111e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.870460539185681e-05, 7.088137941801112e-06, 0.0, 0.0, 6.612586045996174, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 221 + stamp: + secs: 1624875214 + nsecs: 520785093 + frame_id: "/world" +pose: + pose: + position: + x: -0.0898115509783 + y: 0.181822797695 + z: 0.0 + orientation: + x: 0.0 + y: 0.000829707072535 + z: 0.0 + w: 0.999999655793 + covariance: [9.136042911479162, -2.2165644567657484e-08, 0.0, 0.0, -7.328082899920067e-05, 0.0, -2.2165644567657487e-08, 9.136042886661265, 0.0, 0.0, 1.280241099352802e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.328082899920066e-05, 1.2802410993528019e-05, 0.0, 0.0, 8.99939211557021, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 222 + stamp: + secs: 1624875214 + nsecs: 600769043 + frame_id: "/world" +pose: + pose: + position: + x: -0.103917106926 + y: 0.181960351119 + z: 0.0 + orientation: + x: -0.0 + y: -2.85271429829e-05 + z: -0.0 + w: 0.999999999593 + covariance: [10.552910178638335, -2.9735360297131915e-08, 0.0, 0.0, -8.29202674532419e-05, 0.0, -2.9735360297131922e-08, 10.552910143827223, 0.0, 0.0, 1.912897647529078e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.292026745324187e-05, 1.9128976475290773e-05, 0.0, 0.0, 10.369912452414017, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 223 + stamp: + secs: 1624875214 + nsecs: 680773020 + frame_id: "/world" +pose: + pose: + position: + x: -0.104719793881 + y: 0.18390407822 + z: 0.0 + orientation: + x: -0.0 + y: -0.000136087246792 + z: -0.0 + w: 0.99999999074 + covariance: [7.2259631628785215, -1.391144485402281e-08, 0.0, 0.0, -3.2988945820694154e-05, 0.0, -1.3911444854022804e-08, 7.225963146170574, 0.0, 0.0, 9.379850034910949e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.2988945820694134e-05, 9.379850034910949e-06, 0.0, 0.0, 7.139685980961851, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 224 + stamp: + secs: 1624875214 + nsecs: 760782957 + frame_id: "/world" +pose: + pose: + position: + x: -0.105323608951 + y: 0.184749930815 + z: 0.0 + orientation: + x: -0.0 + y: -8.66277929886e-05 + z: -0.0 + w: 0.999999996248 + covariance: [8.460527200753432, -1.9084367865443872e-08, 0.0, 0.0, -3.722438723849808e-05, 0.0, -1.9084367865443862e-08, 8.460527177149128, 0.0, 0.0, 1.0024231523641681e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.7224387238498044e-05, 1.002423152364168e-05, 0.0, 0.0, 8.342061808764793, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 225 + stamp: + secs: 1624875214 + nsecs: 840786934 + frame_id: "/world" +pose: + pose: + position: + x: -0.089179154332 + y: 0.180729840886 + z: 0.0 + orientation: + x: -0.0 + y: -5.86484887011e-05 + z: -0.0 + w: 0.99999999828 + covariance: [10.175795349446027, -2.7422100781661933e-08, 0.0, 0.0, -4.2925435548907616e-05, 0.0, -2.7422100781661933e-08, 10.175795314883526, 0.0, 0.0, 1.1623574824058533e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.292543554890759e-05, 1.1623574824058531e-05, 0.0, 0.0, 10.00490842184004, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 226 + stamp: + secs: 1624875214 + nsecs: 920783043 + frame_id: "/world" +pose: + pose: + position: + x: -0.0892034550565 + y: 0.185644424114 + z: 0.0 + orientation: + x: 0.0 + y: 6.89057287964e-05 + z: 0.0 + w: 0.999999997626 + covariance: [8.694645054429799, -1.9291802490223264e-08, 0.0, 0.0, -2.5207430520559193e-05, 0.0, -1.929180249022326e-08, 8.694645029863874, 0.0, 0.0, 7.0136754417558656e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.520743052055917e-05, 7.013675441755865e-06, 0.0, 0.0, 8.573040791503782, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 227 + stamp: + secs: 1624875215 + nsecs: 812054 + frame_id: "/world" +pose: + pose: + position: + x: -0.0692859455338 + y: 0.175968165307 + z: 0.0 + orientation: + x: 0.0 + y: 0.000289926973335 + z: 0.0 + w: 0.999999957971 + covariance: [9.122802880677016, -2.0127738741381074e-08, 0.0, 0.0, -2.1009483621896143e-05, 0.0, -2.0127738741381078e-08, 9.122802854860147, 0.0, 0.0, 1.0434202668741034e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1009483621896126e-05, 1.0434202668741038e-05, 0.0, 0.0, 8.994885705044343, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 228 + stamp: + secs: 1624875215 + nsecs: 80796003 + frame_id: "/world" +pose: + pose: + position: + x: -0.0693670350149 + y: 0.178630879479 + z: 0.0 + orientation: + x: -0.0 + y: -6.24720852563e-05 + z: -0.0 + w: 0.999999998049 + covariance: [6.921281090889064, -1.4396441097046827e-08, 0.0, 0.0, -1.0034800439044679e-05, 0.0, -1.4396441097046828e-08, 6.921281072363581, 0.0, 0.0, 8.570002956868368e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0034800439044676e-05, 8.570002956868372e-06, 0.0, 0.0, 6.828054173649712, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 229 + stamp: + secs: 1624875215 + nsecs: 160804033 + frame_id: "/world" +pose: + pose: + position: + x: -0.0680991217795 + y: 0.182955643138 + z: 0.0 + orientation: + x: -0.0 + y: -0.000238154606255 + z: -0.0 + w: 0.999999971641 + covariance: [7.532012779516534, -1.5179267476655746e-08, 0.0, 0.0, -1.010344533920927e-05, 0.0, -1.5179267476655746e-08, 7.5320127599523445, 0.0, 0.0, 7.248149568053789e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0103445339209269e-05, 7.248149568053793e-06, 0.0, 0.0, 7.432477337032703, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 230 + stamp: + secs: 1624875215 + nsecs: 240817070 + frame_id: "/world" +pose: + pose: + position: + x: -0.06768948149 + y: 0.181727257745 + z: 0.0 + orientation: + x: -0.0 + y: -8.31215717628e-05 + z: -0.0 + w: 0.999999996545 + covariance: [7.079308258404116, -1.2491824864445397e-08, 0.0, 0.0, -8.454311562052424e-06, 0.0, -1.2491824864445394e-08, 7.079308242279739, 0.0, 0.0, 4.436373262341629e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.454311562052422e-06, 4.43637326234163e-06, 0.0, 0.0, 6.996222819773897, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 231 + stamp: + secs: 1624875215 + nsecs: 320810080 + frame_id: "/world" +pose: + pose: + position: + x: -0.0678321027153 + y: 0.182100173058 + z: 0.0 + orientation: + x: -0.0 + y: -8.17249299571e-05 + z: -0.0 + w: 0.999999996661 + covariance: [7.001409948483838, -2.1334273635005022e-08, 0.0, 0.0, -2.420035685976731e-05, 0.0, -2.133427363500501e-08, 7.00140992075839, 0.0, 0.0, 4.0663728383639155e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.420035685976731e-05, 4.0663728383639155e-06, 0.0, 0.0, 6.855908692482383, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 232 + stamp: + secs: 1624875215 + nsecs: 400810003 + frame_id: "/world" +pose: + pose: + position: + x: -0.0702898923592 + y: 0.179636317373 + z: 0.0 + orientation: + x: 0.0 + y: 0.00026451883317 + z: 0.0 + w: 0.999999965015 + covariance: [6.918183614892453, -1.5680651424760227e-08, 0.0, 0.0, -2.3962171432877516e-05, 0.0, -1.5680651424760227e-08, 6.9181835943545975, 0.0, 0.0, 7.41120457741965e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.3962171432877516e-05, 7.411204577419648e-06, 0.0, 0.0, 6.809885553088628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 233 + stamp: + secs: 1624875215 + nsecs: 480870008 + frame_id: "/world" +pose: + pose: + position: + x: -0.072869049958 + y: 0.182944160456 + z: 0.0 + orientation: + x: 0.0 + y: 7.63720893022e-05 + z: 0.0 + w: 0.999999997084 + covariance: [6.324297376790609, -8.857872966108384e-09, 0.0, 0.0, -1.5109569696840433e-05, 0.0, -8.857872966108389e-09, 6.32429736513081, 0.0, 0.0, 6.091541416912843e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5109569696840437e-05, 6.091541416912842e-06, 0.0, 0.0, 6.262718931966723, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 234 + stamp: + secs: 1624875215 + nsecs: 560842037 + frame_id: "/world" +pose: + pose: + position: + x: -0.0801351259881 + y: 0.198435365887 + z: 0.0 + orientation: + x: -0.0 + y: -0.000526503977966 + z: -0.0 + w: 0.999999861397 + covariance: [8.922812897519085, -1.9311535858546602e-08, 0.0, 0.0, -2.0643857851260102e-05, 0.0, -1.9311535858546592e-08, 8.922812871923158, 0.0, 0.0, 7.624203649478449e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.0643857851260106e-05, 7.624203649478447e-06, 0.0, 0.0, 8.788686058638094, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 235 + stamp: + secs: 1624875215 + nsecs: 640876055 + frame_id: "/world" +pose: + pose: + position: + x: -0.0822161578556 + y: 0.204696964678 + z: 0.0 + orientation: + x: -0.0 + y: -0.000306685175375 + z: -0.0 + w: 0.999999952972 + covariance: [8.282462202687308, -1.714493950505576e-08, 0.0, 0.0, -1.039792959820423e-05, 0.0, -1.714493950505575e-08, 8.282462179915303, 0.0, 0.0, 5.6168048359505954e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0397929598204232e-05, 5.616804835950592e-06, 0.0, 0.0, 8.161598641643915, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 236 + stamp: + secs: 1624875215 + nsecs: 720865965 + frame_id: "/world" +pose: + pose: + position: + x: -0.0824719411358 + y: 0.205160378314 + z: 0.0 + orientation: + x: -0.0 + y: -6.53654353642e-05 + z: -0.0 + w: 0.999999997864 + covariance: [8.053357955855681, -1.6213014861423923e-08, 0.0, 0.0, -1.3216067415351139e-05, 0.0, -1.6213014861423913e-08, 8.05335793436216, 0.0, 0.0, 1.3953999474251822e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3216067415351139e-05, 1.3953999474251822e-05, 0.0, 0.0, 7.9379440300495965, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 237 + stamp: + secs: 1624875215 + nsecs: 800864935 + frame_id: "/world" +pose: + pose: + position: + x: -0.0817246502126 + y: 0.204838827232 + z: 0.0 + orientation: + x: -0.0 + y: -0.000123840630337 + z: -0.0 + w: 0.999999992332 + covariance: [7.967669027501841, -1.5917215340978075e-08, 0.0, 0.0, -4.816103588147254e-05, 0.0, -1.5917215340978058e-08, 7.967669006681341, 0.0, 0.0, 3.259431957985921e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.816103588147253e-05, 3.259431957985922e-05, 0.0, 0.0, 7.855939127837616, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 238 + stamp: + secs: 1624875215 + nsecs: 880872965 + frame_id: "/world" +pose: + pose: + position: + x: -0.0841595572119 + y: 0.204396081064 + z: 0.0 + orientation: + x: 0.0 + y: 0.000782956770013 + z: 0.0 + w: 0.999999693489 + covariance: [11.295244529755667, -3.353820734858239e-08, 0.0, 0.0, -0.00012877180555740823, 0.0, -3.3538207348582356e-08, 11.295244486342456, 0.0, 0.0, 7.582298744622546e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001287718055574082, 7.582298744622546e-05, 0.0, 0.0, 11.076067919676046, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 239 + stamp: + secs: 1624875215 + nsecs: 960884094 + frame_id: "/world" +pose: + pose: + position: + x: -0.0762371581739 + y: 0.203564343287 + z: 0.0 + orientation: + x: 0.0 + y: 0.000308785444784 + z: 0.0 + w: 0.999999952326 + covariance: [10.207248478064878, -2.81305590270521e-08, 0.0, 0.0, -9.28728562946896e-05, 0.0, -2.8130559027052072e-08, 10.207248441942596, 0.0, 0.0, 5.8174931612398725e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.287285629468959e-05, 5.817493161239873e-05, 0.0, 0.0, 10.029647963725582, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 240 + stamp: + secs: 1624875216 + nsecs: 40893078 + frame_id: "/world" +pose: + pose: + position: + x: -0.0765307572537 + y: 0.204309917706 + z: 0.0 + orientation: + x: 0.0 + y: 9.90109735276e-05 + z: 0.0 + w: 0.999999995098 + covariance: [9.77400360542105, -2.664108482344855e-08, 0.0, 0.0, -6.65281155365077e-05, 0.0, -2.664108482344852e-08, 9.774003572168384, 0.0, 0.0, 6.182507380086254e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.65281155365077e-05, 6.182507380086256e-05, 0.0, 0.0, 9.612158850073065, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 241 + stamp: + secs: 1624875216 + nsecs: 120889902 + frame_id: "/world" +pose: + pose: + position: + x: -0.0768735992097 + y: 0.204430380213 + z: 0.0 + orientation: + x: -0.0 + y: -1.90922775432e-05 + z: -0.0 + w: 0.999999999818 + covariance: [8.583784364056452, -2.8180185673649873e-08, 0.0, 0.0, -0.0003986035959806228, 0.0, -2.8180185673649853e-08, 8.58378430020021, 0.0, 0.0, 5.3765307839326686e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003986035959806228, 5.37653078393267e-05, 0.0, 0.0, 8.44338396474089, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 242 + stamp: + secs: 1624875216 + nsecs: 200895071 + frame_id: "/world" +pose: + pose: + position: + x: -0.0771014332471 + y: 0.205966462631 + z: 0.0 + orientation: + x: -0.0 + y: -7.38826374412e-05 + z: -0.0 + w: 0.999999997271 + covariance: [8.157353289267837, -2.978092838430008e-08, 0.0, 0.0, -0.0005099466735926385, 0.0, -2.9780928384300076e-08, 8.157353124138496, 0.0, 0.0, 3.577475013106243e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005099466735926386, 3.577475013106243e-05, 0.0, 0.0, 8.039496389566333, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 243 + stamp: + secs: 1624875216 + nsecs: 280922890 + frame_id: "/world" +pose: + pose: + position: + x: -0.0771120487011 + y: 0.206413023395 + z: 0.0 + orientation: + x: -0.0 + y: -0.000259371856646 + z: -0.0 + w: 0.999999966363 + covariance: [10.002130332056675, -4.9903375807177675e-08, 0.0, 0.0, -0.0006410122173492962, 0.0, -4.9903375807177656e-08, 10.002129920365604, 0.0, 0.0, 3.611470784482266e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006410122173492965, 3.6114707844822666e-05, 0.0, 0.0, 9.833901689096908, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 244 + stamp: + secs: 1624875216 + nsecs: 360913038 + frame_id: "/world" +pose: + pose: + position: + x: -0.0772224726454 + y: 0.206653320222 + z: 0.0 + orientation: + x: -0.0 + y: -0.000299326535766 + z: -0.0 + w: 0.999999955202 + covariance: [11.014674918960633, -6.199898823109156e-08, 0.0, 0.0, -0.0005682377841076578, 0.0, -6.199898823109153e-08, 11.01467431744622, 0.0, 0.0, 2.959795270263138e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000568237784107658, 2.9597952702631386e-05, 0.0, 0.0, 10.82100237977306, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 245 + stamp: + secs: 1624875216 + nsecs: 440912962 + frame_id: "/world" +pose: + pose: + position: + x: -0.0773691649227 + y: 0.206974469261 + z: 0.0 + orientation: + x: -0.0 + y: -0.000291476782334 + z: -0.0 + w: 0.999999957521 + covariance: [13.517252672322762, -1.0419011178155853e-07, 0.0, 0.0, -0.0006362957407247301, 0.0, -1.0419011178155847e-07, 13.51725155350965, 0.0, 0.0, 3.236071373516475e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006362957407247303, 3.2360713735164756e-05, 0.0, 0.0, 13.208832200211956, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 246 + stamp: + secs: 1624875216 + nsecs: 520924091 + frame_id: "/world" +pose: + pose: + position: + x: -0.0781167069823 + y: 0.207950819792 + z: 0.0 + orientation: + x: -0.0 + y: -0.000143154373108 + z: -0.0 + w: 0.999999989753 + covariance: [10.981321832541372, -5.470247676784251e-08, 0.0, 0.0, -0.0002775134245648622, 0.0, -5.470247676784248e-08, 10.981321227035048, 0.0, 0.0, 1.4174777027517648e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00027751342456486234, 1.4174777027517653e-05, 0.0, 0.0, 10.820405514566726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 247 + stamp: + secs: 1624875216 + nsecs: 600929976 + frame_id: "/world" +pose: + pose: + position: + x: -0.0778757894352 + y: 0.207673050582 + z: 0.0 + orientation: + x: -0.0 + y: -0.000269589423827 + z: -0.0 + w: 0.999999963661 + covariance: [10.071998475394977, -4.934524640145978e-08, 0.0, 0.0, -0.00016843772118466793, 0.0, -4.9345246401459724e-08, 10.071997902593427, 0.0, 0.0, 9.661341144285265e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00016843772118466801, 9.661341144285268e-06, 0.0, 0.0, 9.929646323857067, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 248 + stamp: + secs: 1624875216 + nsecs: 680928946 + frame_id: "/world" +pose: + pose: + position: + x: -0.0779916201598 + y: 0.207761631199 + z: 0.0 + orientation: + x: -0.0 + y: -0.000183126006852 + z: -0.0 + w: 0.999999983232 + covariance: [8.658442759065007, -3.8421403867474165e-08, 0.0, 0.0, -9.129444642909187e-05, 0.0, -3.8421403867474125e-08, 8.658442298862264, 0.0, 0.0, 6.966613448000476e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.12944464290919e-05, 6.9666134480004794e-06, 0.0, 0.0, 8.548433609782766, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 249 + stamp: + secs: 1624875216 + nsecs: 760956049 + frame_id: "/world" +pose: + pose: + position: + x: -0.0785439589966 + y: 0.207871054893 + z: 0.0 + orientation: + x: 0.0 + y: 0.000184197613972 + z: 0.0 + w: 0.999999983036 + covariance: [10.288600246792885, -5.898878481274031e-08, 0.0, 0.0, -9.94799189545387e-05, 0.0, -5.898878481274026e-08, 10.28859952439211, 0.0, 0.0, 9.483566173321246e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.947991895453871e-05, 9.48356617332125e-06, 0.0, 0.0, 10.12047153338736, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 250 + stamp: + secs: 1624875216 + nsecs: 840961933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0786430998767 + y: 0.208136136922 + z: 0.0 + orientation: + x: 0.0 + y: 0.000415623691727 + z: 0.0 + w: 0.999999913628 + covariance: [9.82541404356982, -6.138238887762508e-08, 0.0, 0.0, -7.418029401897698e-05, 0.0, -6.138238887762504e-08, 9.825413282388824, 0.0, 0.0, 7.721090943839061e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.4180294018977e-05, 7.721090943839066e-06, 0.0, 0.0, 9.649337251893343, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 251 + stamp: + secs: 1624875216 + nsecs: 920965910 + frame_id: "/world" +pose: + pose: + position: + x: -0.0710886181621 + y: 0.193346139946 + z: 0.0 + orientation: + x: 0.0 + y: 0.00031536525661 + z: 0.0 + w: 0.999999950272 + covariance: [8.580407269000688, -4.294360685880467e-08, 0.0, 0.0, -4.3878713075743766e-05, 0.0, -4.2943606858804645e-08, 8.580406732984887, 0.0, 0.0, 4.198434439531331e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.387871307574377e-05, 4.198434439531333e-06, 0.0, 0.0, 8.45584499574792, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 252 + stamp: + secs: 1624875217 + nsecs: 967979 + frame_id: "/world" +pose: + pose: + position: + x: -0.0711723845535 + y: 0.193519139037 + z: 0.0 + orientation: + x: 0.0 + y: 0.000583140763051 + z: 0.0 + w: 0.999999829973 + covariance: [9.107942063281394, -5.604046909911982e-08, 0.0, 0.0, -5.339444979252549e-05, 0.0, -5.6040469099119794e-08, 9.107941359531921, 0.0, 0.0, 4.224172520014586e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.3394449792525495e-05, 4.224172520014588e-06, 0.0, 0.0, 8.943696597380555, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 253 + stamp: + secs: 1624875217 + nsecs: 80965996 + frame_id: "/world" +pose: + pose: + position: + x: -0.0713557592873 + y: 0.194476320684 + z: 0.0 + orientation: + x: 0.0 + y: 0.000332028896375 + z: 0.0 + w: 0.999999944878 + covariance: [8.325292567118916, -3.680349576281345e-08, 0.0, 0.0, -3.1942036760394e-05, 0.0, -3.680349576281344e-08, 8.325292103425962, 0.0, 0.0, -2.095235482467815e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.1942036760394005e-05, -2.0952354824678134e-06, 0.0, 0.0, 8.215846932942707, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 254 + stamp: + secs: 1624875217 + nsecs: 160985947 + frame_id: "/world" +pose: + pose: + position: + x: -0.0705437733416 + y: 0.193901909063 + z: 0.0 + orientation: + x: 0.0 + y: 0.00044065986736 + z: 0.0 + w: 0.999999902909 + covariance: [8.070908514493489, -3.735243506577884e-08, 0.0, 0.0, -2.3765324240303986e-05, 0.0, -3.735243506577881e-08, 8.070908041568277, 0.0, 0.0, -7.325724102760076e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.376532424030398e-05, -7.325724102760076e-06, 0.0, 0.0, 7.958077855876616, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 255 + stamp: + secs: 1624875217 + nsecs: 240998983 + frame_id: "/world" +pose: + pose: + position: + x: -0.0711096054423 + y: 0.194113269291 + z: 0.0 + orientation: + x: 0.0 + y: 0.000462113919288 + z: 0.0 + w: 0.999999893225 + covariance: [7.250968341485635, -2.9541164792756137e-08, 0.0, 0.0, -3.21668550390345e-05, 0.0, -2.9541164792756127e-08, 7.2509679658158985, 0.0, 0.0, -4.715246348850721e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.21668550390345e-05, -4.715246348850721e-06, 0.0, 0.0, 7.160038936259018, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 256 + stamp: + secs: 1624875217 + nsecs: 320986986 + frame_id: "/world" +pose: + pose: + position: + x: -0.0740608059027 + y: 0.193076114188 + z: 0.0 + orientation: + x: 0.0 + y: 0.00255703927391 + z: 0.0 + w: 0.99999673077 + covariance: [10.813950000712696, -8.211102920691755e-08, 0.0, 0.0, -0.00010907693165059327, 0.0, -8.211102920691752e-08, 10.813948948289525, 0.0, 0.0, -7.707375989738151e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00010907693165059326, -7.707375989738153e-06, 0.0, 0.0, 10.555743890752712, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 257 + stamp: + secs: 1624875217 + nsecs: 400985956 + frame_id: "/world" +pose: + pose: + position: + x: -0.0733098963242 + y: 0.192683563383 + z: 0.0 + orientation: + x: 0.0 + y: 8.28152422876e-05 + z: 0.0 + w: 0.999999996571 + covariance: [7.996261853373878, -3.3978878272566894e-08, 0.0, 0.0, -5.1724216304315884e-05, 0.0, -3.3978878272566894e-08, 7.996261416828459, 0.0, 0.0, -2.5411523044369742e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.172421630431591e-05, -2.5411523044369755e-06, 0.0, 0.0, 7.887507946806881, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 258 + stamp: + secs: 1624875217 + nsecs: 481002092 + frame_id: "/world" +pose: + pose: + position: + x: -0.0735056622766 + y: 0.192910565253 + z: 0.0 + orientation: + x: 0.0 + y: 0.000456368430197 + z: 0.0 + w: 0.999999895864 + covariance: [8.823758891213725, -4.152704343844352e-08, 0.0, 0.0, -8.989248246013898e-05, 0.0, -4.152704343844352e-08, 8.823758354523276, 0.0, 0.0, 2.3793741897539935e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.9892482460139e-05, 2.3793741897539935e-06, 0.0, 0.0, 8.688933414844476, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 259 + stamp: + secs: 1624875217 + nsecs: 561059952 + frame_id: "/world" +pose: + pose: + position: + x: -0.0735628327053 + y: 0.192983282535 + z: 0.0 + orientation: + x: 0.0 + y: 0.000489181602761 + z: 0.0 + w: 0.999999880351 + covariance: [10.338104997014975, -4.2540338812940544e-08, 0.0, 0.0, -9.64300943761516e-05, 0.0, -4.2540338812940544e-08, 10.338104446226831, 0.0, 0.0, 5.437668859777262e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.64300943761516e-05, 5.437668859777264e-06, 0.0, 0.0, 10.198893415608241, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 260 + stamp: + secs: 1624875217 + nsecs: 641020060 + frame_id: "/world" +pose: + pose: + position: + x: -0.073501632657 + y: 0.193199024642 + z: 0.0 + orientation: + x: 0.0 + y: 5.46996537933e-06 + z: 0.0 + w: 0.999999999985 + covariance: [7.15587338856007, -1.6040999336633896e-08, 0.0, 0.0, -3.4085915681170736e-05, 0.0, -1.6040999336633893e-08, 7.155873180185478, 0.0, 0.0, -1.4234560138120365e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.408591568117076e-05, -1.423456013812036e-06, 0.0, 0.0, 7.102549302951419, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 261 + stamp: + secs: 1624875217 + nsecs: 721040964 + frame_id: "/world" +pose: + pose: + position: + x: -0.0735809764698 + y: 0.193304418351 + z: 0.0 + orientation: + x: 0.0 + y: 0.000589080555863 + z: 0.0 + w: 0.999999826492 + covariance: [9.395919765437254, -3.0840242435139395e-08, 0.0, 0.0, -4.805620213144637e-05, 0.0, -3.084024243513939e-08, 9.395919361050545, 0.0, 0.0, -9.412537405080078e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.805620213144638e-05, -9.412537405080074e-06, 0.0, 0.0, 9.292732976778227, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 262 + stamp: + secs: 1624875217 + nsecs: 801040888 + frame_id: "/world" +pose: + pose: + position: + x: -0.073941906964 + y: 0.193433295555 + z: 0.0 + orientation: + x: 0.0 + y: 0.00064389215744 + z: 0.0 + w: 0.999999792701 + covariance: [9.384755038713685, -2.3350302411623642e-08, 0.0, 0.0, -2.995817734421835e-05, 0.0, -2.335030241162364e-08, 9.384754731833834, 0.0, 0.0, -5.061409624911385e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.995817734421835e-05, -5.061409624911382e-06, 0.0, 0.0, 9.305386835907047, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 263 + stamp: + secs: 1624875217 + nsecs: 881045103 + frame_id: "/world" +pose: + pose: + position: + x: -0.0739314188873 + y: 0.193544804767 + z: 0.0 + orientation: + x: 0.0 + y: 0.000160694904816 + z: 0.0 + w: 0.999999987089 + covariance: [7.624593171211033, -2.0663525022636383e-08, 0.0, 0.0, -2.044212842754458e-05, 0.0, -2.066352502263637e-08, 7.624592899448356, 0.0, 0.0, 8.636084713587245e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.0442128427544578e-05, 8.636084713587245e-06, 0.0, 0.0, 7.55280758487379, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 264 + stamp: + secs: 1624875217 + nsecs: 961061954 + frame_id: "/world" +pose: + pose: + position: + x: -0.0740591336377 + y: 0.193782994226 + z: 0.0 + orientation: + x: 0.0 + y: 0.000108455971801 + z: 0.0 + w: 0.999999994119 + covariance: [8.627422411624515, -2.6230894241286296e-08, 0.0, 0.0, -1.750486033238176e-05, 0.0, -2.623089424128628e-08, 8.627422067688535, 0.0, 0.0, 1.82934148964345e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7504860332381752e-05, 1.82934148964345e-05, 0.0, 0.0, 8.535036864974364, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 265 + stamp: + secs: 1624875218 + nsecs: 41070938 + frame_id: "/world" +pose: + pose: + position: + x: -0.0753028980105 + y: 0.193404576171 + z: 0.0 + orientation: + x: -0.0 + y: -0.00061186885264 + z: -0.0 + w: 0.999999812808 + covariance: [9.094654635986014, -3.3240974919239453e-08, 0.0, 0.0, -0.00012461398222083297, 0.0, -3.324097491923945e-08, 9.094654205685858, 0.0, 0.0, 2.4789047394140237e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00012461398222083297, 2.478904739414023e-05, 0.0, 0.0, 8.978228705639838, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 266 + stamp: + secs: 1624875218 + nsecs: 121073961 + frame_id: "/world" +pose: + pose: + position: + x: -0.0754449458858 + y: 0.194833654317 + z: 0.0 + orientation: + x: 0.0 + y: 0.000197109958401 + z: 0.0 + w: 0.999999980574 + covariance: [8.330074557819467, -3.001476665892087e-08, 0.0, 0.0, -0.00016485918450811796, 0.0, -3.001476665892087e-08, 8.33007417551943, 0.0, 0.0, 2.3960274139643614e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000164859184508118, 2.396027413964361e-05, 0.0, 0.0, 8.227990768605043, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 267 + stamp: + secs: 1624875218 + nsecs: 201076984 + frame_id: "/world" +pose: + pose: + position: + x: -0.0759118745626 + y: 0.195745567144 + z: 0.0 + orientation: + x: -0.0 + y: -6.59592990123e-05 + z: -0.0 + w: 0.999999997825 + covariance: [7.327704901376255, -2.6084732823767373e-08, 0.0, 0.0, -0.00011741474359054761, 0.0, -2.608473282376737e-08, 7.327704574665999, 0.0, 0.0, 1.7785520035399776e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011741474359054768, 1.7785520035399776e-05, 0.0, 0.0, 7.241429703045467, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 268 + stamp: + secs: 1624875218 + nsecs: 281084061 + frame_id: "/world" +pose: + pose: + position: + x: -0.0738467308377 + y: 0.193359792155 + z: 0.0 + orientation: + x: 0.0 + y: 0.00034586754658 + z: 0.0 + w: 0.999999940188 + covariance: [7.018014500577828, -2.5451591883811218e-08, 0.0, 0.0, -8.919214049875191e-05, 0.0, -2.54515918838112e-08, 7.018014185854238, 0.0, 0.0, 1.3066386328457822e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.919214049875195e-05, 1.3066386328457824e-05, 0.0, 0.0, 6.935620431445128, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 269 + stamp: + secs: 1624875218 + nsecs: 361097097 + frame_id: "/world" +pose: + pose: + position: + x: -0.0740785627151 + y: 0.194017322215 + z: 0.0 + orientation: + x: 0.0 + y: 0.00029005961951 + z: 0.0 + w: 0.999999957933 + covariance: [8.361069188797261, -3.626403645072564e-08, 0.0, 0.0, -9.489769699789062e-05, 0.0, -3.6264036450725645e-08, 8.361068745808327, 0.0, 0.0, 1.7507706051600368e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.489769699789069e-05, 1.7507706051600368e-05, 0.0, 0.0, 8.245361834015096, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 270 + stamp: + secs: 1624875218 + nsecs: 441102982 + frame_id: "/world" +pose: + pose: + position: + x: -0.0728079456502 + y: 0.194969973359 + z: 0.0 + orientation: + x: 0.0 + y: 7.64712010315e-05 + z: 0.0 + w: 0.999999997076 + covariance: [8.072882392695224, -3.282223975353038e-08, 0.0, 0.0, -6.0914482785624365e-05, 0.0, -3.2822239753530384e-08, 8.07288199511429, 0.0, 0.0, 1.3575200328214039e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.0914482785624385e-05, 1.3575200328214035e-05, 0.0, 0.0, 7.968176159104928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 271 + stamp: + secs: 1624875218 + nsecs: 521126986 + frame_id: "/world" +pose: + pose: + position: + x: -0.0717671446558 + y: 0.196325472143 + z: 0.0 + orientation: + x: 0.0 + y: 0.000214319098157 + z: 0.0 + w: 0.999999977034 + covariance: [7.25583491421633, -2.902689737845941e-08, 0.0, 0.0, -3.437239861125081e-05, 0.0, -2.90268973784594e-08, 7.25583456474495, 0.0, 0.0, 7.982299237936582e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.437239861125082e-05, 7.982299237936582e-06, 0.0, 0.0, 7.163019346392249, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 272 + stamp: + secs: 1624875218 + nsecs: 601133108 + frame_id: "/world" +pose: + pose: + position: + x: -0.0720212572152 + y: 0.196897220124 + z: 0.0 + orientation: + x: 0.0 + y: 0.000304404034902 + z: 0.0 + w: 0.999999953669 + covariance: [6.987702176077731, -2.4047338689459946e-08, 0.0, 0.0, -3.040860966759905e-05, 0.0, -2.4047338689459933e-08, 6.9877018876057155, 0.0, 0.0, 4.6253771302696255e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.040860966759905e-05, 4.625377130269624e-06, 0.0, 0.0, 6.910132221979082, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 273 + stamp: + secs: 1624875218 + nsecs: 681112051 + frame_id: "/world" +pose: + pose: + position: + x: -0.0694311861681 + y: 0.199042852965 + z: 0.0 + orientation: + x: 0.0 + y: 0.000439360501519 + z: 0.0 + w: 0.999999903481 + covariance: [10.52845167223315, -4.988753176115606e-08, 0.0, 0.0, -6.414564722610465e-05, 0.0, -4.988753176115604e-08, 10.5284510751653, 0.0, 0.0, 7.032544147790344e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.414564722610464e-05, 7.032544147790342e-06, 0.0, 0.0, 10.367305238313572, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 274 + stamp: + secs: 1624875218 + nsecs: 761149883 + frame_id: "/world" +pose: + pose: + position: + x: -0.0695017287372 + y: 0.199124378304 + z: 0.0 + orientation: + x: 0.0 + y: 0.00111705049823 + z: 0.0 + w: 0.999999376099 + covariance: [13.151906513711381, -8.010994155709197e-08, 0.0, 0.0, -9.467886054862818e-05, 0.0, -8.010994155709193e-08, 13.151905556722282, 0.0, 0.0, 1.4520155925487143e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.467886054862818e-05, 1.4520155925487143e-05, 0.0, 0.0, 12.892813279390033, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 275 + stamp: + secs: 1624875218 + nsecs: 841130018 + frame_id: "/world" +pose: + pose: + position: + x: -0.0674099096352 + y: 0.203546158019 + z: 0.0 + orientation: + x: 0.0 + y: 0.00118979708159 + z: 0.0 + w: 0.999999292191 + covariance: [12.607157755943353, -7.45734646585869e-08, 0.0, 0.0, -9.341264596315865e-05, 0.0, -7.457346465858686e-08, 12.607156867977118, 0.0, 0.0, 2.4420744321264315e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.341264596315863e-05, 2.4420744321264318e-05, 0.0, 0.0, 12.36415856730339, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 276 + stamp: + secs: 1624875218 + nsecs: 921133995 + frame_id: "/world" +pose: + pose: + position: + x: -0.0669108475445 + y: 0.208514292271 + z: 0.0 + orientation: + x: 0.0 + y: 0.000596826066144 + z: 0.0 + w: 0.999999821899 + covariance: [12.355731507886965, -7.528370095599327e-08, 0.0, 0.0, -0.00010844492064665254, 0.0, -7.528370095599323e-08, 12.3557306192903, 0.0, 0.0, 4.784009077483298e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00010844492064665256, 4.7840090774832986e-05, 0.0, 0.0, 12.107320830736933, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 277 + stamp: + secs: 1624875219 + nsecs: 1161098 + frame_id: "/world" +pose: + pose: + position: + x: -0.0661537165748 + y: 0.198108247862 + z: 0.0 + orientation: + x: -0.0 + y: -0.000174348856785 + z: -0.0 + w: 0.999999984801 + covariance: [12.22479598487514, -7.309020100441114e-08, 0.0, 0.0, -8.739379553326301e-05, 0.0, -7.30902010044111e-08, 12.224795131192797, 0.0, 0.0, 5.742905848030394e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.7393795533263e-05, 5.7429058480303935e-05, 0.0, 0.0, 11.982368134693477, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 278 + stamp: + secs: 1624875219 + nsecs: 81146002 + frame_id: "/world" +pose: + pose: + position: + x: -0.0658554706011 + y: 0.198584234012 + z: 0.0 + orientation: + x: -0.0 + y: -0.000154829181964 + z: -0.0 + w: 0.999999988014 + covariance: [10.571167036304933, -5.8679331012110356e-08, 0.0, 0.0, -7.749369862664033e-05, 0.0, -5.867933101211031e-08, 10.57116635838467, 0.0, 0.0, 4.3288269085015984e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.749369862664033e-05, 4.328826908501598e-05, 0.0, 0.0, 10.375138584803809, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 279 + stamp: + secs: 1624875219 + nsecs: 161160946 + frame_id: "/world" +pose: + pose: + position: + x: -0.0643369663885 + y: 0.200017156198 + z: 0.0 + orientation: + x: 0.0 + y: 1.49401369366e-05 + z: 0.0 + w: 0.999999999888 + covariance: [9.921298481416102, -5.0382191481317835e-08, 0.0, 0.0, -7.748393667590503e-05, 0.0, -5.03821914813178e-08, 9.921297905746158, 0.0, 0.0, 3.0566145148218225e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.748393667590501e-05, 3.056614514821823e-05, 0.0, 0.0, 9.752280913178812, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 280 + stamp: + secs: 1624875219 + nsecs: 241172075 + frame_id: "/world" +pose: + pose: + position: + x: -0.0627982066071 + y: 0.203470437513 + z: 0.0 + orientation: + x: -0.0 + y: -6.89773984416e-06 + z: -0.0 + w: 0.999999999976 + covariance: [8.615649356317522, -3.713176874290918e-08, 0.0, 0.0, -4.827414490925237e-05, 0.0, -3.7131768742909156e-08, 8.615648935484392, 0.0, 0.0, 1.674690488917234e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.827414490925237e-05, 1.6746904889172343e-05, 0.0, 0.0, 8.489960703891967, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 281 + stamp: + secs: 1624875219 + nsecs: 321162939 + frame_id: "/world" +pose: + pose: + position: + x: -0.0620207075825 + y: 0.201427997997 + z: 0.0 + orientation: + x: -0.0 + y: -0.000385735626732 + z: -0.0 + w: 0.999999925604 + covariance: [9.093899309763037, -3.9747814137448744e-08, 0.0, 0.0, -3.714709362600195e-05, 0.0, -3.974781413744872e-08, 9.093898862236838, 0.0, 0.0, 1.232864177119996e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.714709362600196e-05, 1.232864177119996e-05, 0.0, 0.0, 8.958229319171652, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 282 + stamp: + secs: 1624875219 + nsecs: 401169062 + frame_id: "/world" +pose: + pose: + position: + x: -0.0627016398558 + y: 0.202507233488 + z: 0.0 + orientation: + x: -0.0 + y: -0.000178235283866 + z: -0.0 + w: 0.999999984116 + covariance: [9.273258024434625, -3.2226544360011053e-08, 0.0, 0.0, -2.31053974590957e-05, 0.0, -3.2226544360011034e-08, 9.273257662877443, 0.0, 0.0, 8.988899075860161e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.3105397459095702e-05, 8.98889907586016e-06, 0.0, 0.0, 9.162352990129731, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 283 + stamp: + secs: 1624875219 + nsecs: 481182098 + frame_id: "/world" +pose: + pose: + position: + x: -0.076788567603 + y: 0.215261627972 + z: 0.0 + orientation: + x: -0.0 + y: -0.000395999028047 + z: -0.0 + w: 0.999999921592 + covariance: [10.623031446769232, -4.734637020830244e-08, 0.0, 0.0, -6.257813702540697e-05, 0.0, -4.734637020830238e-08, 10.623030919895715, 0.0, 0.0, 2.5982940913045773e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.257813702540698e-05, 2.5982940913045777e-05, 0.0, 0.0, 10.459343808487144, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 284 + stamp: + secs: 1624875219 + nsecs: 561197996 + frame_id: "/world" +pose: + pose: + position: + x: -0.0770545901087 + y: 0.215248928592 + z: 0.0 + orientation: + x: -0.0 + y: -0.000385957212274 + z: -0.0 + w: 0.999999925519 + covariance: [11.347055784832865, -5.699059664907306e-08, 0.0, 0.0, -9.925739267572298e-05, 0.0, -5.6990596649072984e-08, 11.347055158503052, 0.0, 0.0, 3.796053238229741e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.9257392675723e-05, 3.796053238229742e-05, 0.0, 0.0, 11.150041878077687, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 285 + stamp: + secs: 1624875219 + nsecs: 641206980 + frame_id: "/world" +pose: + pose: + position: + x: -0.0768111316067 + y: 0.215257321056 + z: 0.0 + orientation: + x: -0.0 + y: -5.78035553547e-06 + z: -0.0 + w: 0.999999999983 + covariance: [11.74502667205212, -6.940397740555302e-08, 0.0, 0.0, -0.0001291903314135608, 0.0, -6.940397740555294e-08, 11.745025918660197, 0.0, 0.0, 4.042653245196555e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001291903314135608, 4.0426532451965557e-05, 0.0, 0.0, 11.504877487458026, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 286 + stamp: + secs: 1624875219 + nsecs: 721213102 + frame_id: "/world" +pose: + pose: + position: + x: -0.074646751398 + y: 0.216503072913 + z: 0.0 + orientation: + x: 0.0 + y: 0.000231611187284 + z: 0.0 + w: 0.999999973178 + covariance: [10.38527055916001, -5.463187063247553e-08, 0.0, 0.0, -9.66061428024148e-05, 0.0, -5.4631870632475466e-08, 10.385269971034074, 0.0, 0.0, 2.6943394580166456e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.660614280241478e-05, 2.6943394580166456e-05, 0.0, 0.0, 10.19495303337412, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 287 + stamp: + secs: 1624875219 + nsecs: 801218987 + frame_id: "/world" +pose: + pose: + position: + x: -0.0717184225034 + y: 0.217198491915 + z: 0.0 + orientation: + x: 0.0 + y: 0.000202147492672 + z: 0.0 + w: 0.999999979568 + covariance: [8.787168550401717, -4.341781650933562e-08, 0.0, 0.0, -0.00010156766251325926, 0.0, -4.341781650933558e-08, 8.787168086897607, 0.0, 0.0, 1.657342077423873e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001015676625132593, 1.657342077423873e-05, 0.0, 0.0, 8.634772342350946, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 288 + stamp: + secs: 1624875219 + nsecs: 881227016 + frame_id: "/world" +pose: + pose: + position: + x: -0.07143330459 + y: 0.217660622277 + z: 0.0 + orientation: + x: 0.0 + y: 0.000182283108325 + z: 0.0 + w: 0.999999983386 + covariance: [9.177177619798558, -4.398261145721746e-08, 0.0, 0.0, -0.00011487105366307066, 0.0, -4.3982611457217416e-08, 9.177177150969671, 0.0, 0.0, 8.949808836103109e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011487105366307063, 8.94980883610311e-06, 0.0, 0.0, 9.021889336017365, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 289 + stamp: + secs: 1624875219 + nsecs: 961224079 + frame_id: "/world" +pose: + pose: + position: + x: -0.0715475580445 + y: 0.218014033597 + z: 0.0 + orientation: + x: 0.0 + y: 0.000125916545563 + z: 0.0 + w: 0.999999992073 + covariance: [8.365152253812875, -3.417756215952177e-08, 0.0, 0.0, -7.750100890301545e-05, 0.0, -3.417756215952174e-08, 8.36515188859061, 0.0, 0.0, 2.3748631564285077e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.750100890301547e-05, 2.374863156428509e-06, 0.0, 0.0, 8.242895920507419, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 290 + stamp: + secs: 1624875220 + nsecs: 41249990 + frame_id: "/world" +pose: + pose: + position: + x: -0.0720047512954 + y: 0.218850738628 + z: 0.0 + orientation: + x: -0.0 + y: -4.92954542739e-05 + z: -0.0 + w: 0.999999998785 + covariance: [8.997507063183953, -4.102451533519235e-08, 0.0, 0.0, -6.880044134927916e-05, 0.0, -4.1024515335192304e-08, 8.997506623102202, 0.0, 0.0, -8.167304594680262e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.880044134927918e-05, -8.167304594680259e-07, 0.0, 0.0, 8.848597786547051, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 291 + stamp: + secs: 1624875220 + nsecs: 121259928 + frame_id: "/world" +pose: + pose: + position: + x: -0.0721686014235 + y: 0.219146517992 + z: 0.0 + orientation: + x: -0.0 + y: -0.000139155276807 + z: -0.0 + w: 0.999999990318 + covariance: [9.271139815657374, -4.2343872854059057e-08, 0.0, 0.0, -5.5188266583444915e-05, 0.0, -4.234387285405901e-08, 9.271139359875566, 0.0, 0.0, -2.6552945396054304e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.5188266583444936e-05, -2.65529453960543e-06, 0.0, 0.0, 9.114975886371479, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 292 + stamp: + secs: 1624875220 + nsecs: 201256037 + frame_id: "/world" +pose: + pose: + position: + x: -0.0718220592027 + y: 0.218488241328 + z: 0.0 + orientation: + x: 0.0 + y: 3.2995553866e-05 + z: 0.0 + w: 0.999999999456 + covariance: [7.602024617032422, -2.734789511692596e-08, 0.0, 0.0, -2.5550631347189332e-05, 0.0, -2.734789511692593e-08, 7.6020243220714585, 0.0, 0.0, -1.177968641877924e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5550631347189353e-05, -1.1779686418779243e-07, 0.0, 0.0, 7.49924596947639, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 293 + stamp: + secs: 1624875220 + nsecs: 281263113 + frame_id: "/world" +pose: + pose: + position: + x: -0.0712888725813 + y: 0.223814171085 + z: 0.0 + orientation: + x: 0.0 + y: 0.000130942751508 + z: 0.0 + w: 0.999999991427 + covariance: [9.681889735098974, -4.163573870452355e-08, 0.0, 0.0, -2.2908900962838973e-05, 0.0, -4.163573870452352e-08, 9.681889285517661, 0.0, 0.0, 3.951885896489254e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.290890096283899e-05, 3.9518858964892554e-06, 0.0, 0.0, 9.523400036501505, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 294 + stamp: + secs: 1624875220 + nsecs: 361269951 + frame_id: "/world" +pose: + pose: + position: + x: -0.0726052737164 + y: 0.234727297927 + z: 0.0 + orientation: + x: 0.0 + y: 0.000206472345828 + z: 0.0 + w: 0.999999978685 + covariance: [9.553055273398044, -3.893251606375478e-08, 0.0, 0.0, -1.4034929662285234e-05, 0.0, -3.8932516063754754e-08, 9.553054852757818, 0.0, 0.0, 5.61857685075771e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4034929662285237e-05, 5.61857685075771e-06, 0.0, 0.0, 9.402612654330817, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 295 + stamp: + secs: 1624875220 + nsecs: 441265106 + frame_id: "/world" +pose: + pose: + position: + x: -0.0726474043033 + y: 0.234996353904 + z: 0.0 + orientation: + x: 0.0 + y: 9.36454480508e-05 + z: 0.0 + w: 0.999999995615 + covariance: [8.50090983079158, -3.246955919734679e-08, 0.0, 0.0, -7.326284562873288e-06, 0.0, -3.246955919734677e-08, 8.500909479821486, 0.0, 0.0, 4.956381254904585e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.326284562873288e-06, 4.956381254904585e-06, 0.0, 0.0, 8.372949248044295, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 296 + stamp: + secs: 1624875220 + nsecs: 521287918 + frame_id: "/world" +pose: + pose: + position: + x: -0.0729943309088 + y: 0.23582706102 + z: 0.0 + orientation: + x: -0.0 + y: -1.30779801469e-05 + z: -0.0 + w: 0.999999999914 + covariance: [8.128276850280972, -2.844047862160623e-08, 0.0, 0.0, -7.5874848420642556e-06, 0.0, -2.844047862160622e-08, 8.12827654289553, 0.0, 0.0, 7.932965591298843e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.587484842064256e-06, 7.93296559129884e-06, 0.0, 0.0, 8.014250790747472, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 297 + stamp: + secs: 1624875220 + nsecs: 601290941 + frame_id: "/world" +pose: + pose: + position: + x: -0.0732659313619 + y: 0.23642002511 + z: 0.0 + orientation: + x: 0.0 + y: 3.75127242809e-05 + z: 0.0 + w: 0.999999999296 + covariance: [8.87917922892542, -3.2764135549598024e-08, 0.0, 0.0, -1.5137085226646413e-05, 0.0, -3.276413554959801e-08, 8.879178875351515, 0.0, 0.0, 1.308095526666226e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5137085226646408e-05, 1.3080955266662254e-05, 0.0, 0.0, 8.745936214569962, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 298 + stamp: + secs: 1624875220 + nsecs: 681297064 + frame_id: "/world" +pose: + pose: + position: + x: -0.075086980399 + y: 0.237000355091 + z: 0.0 + orientation: + x: -0.0 + y: -0.000751901882724 + z: -0.0 + w: 0.999999717322 + covariance: [9.211720105672967, -3.4263124733625136e-08, 0.0, 0.0, -1.755717071301511e-05, 0.0, -3.426312473362512e-08, 9.211719736513142, 0.0, 0.0, 9.50151371488263e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.75571707130151e-05, 9.501513714882625e-06, 0.0, 0.0, 9.070436688158658, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 299 + stamp: + secs: 1624875220 + nsecs: 761307001 + frame_id: "/world" +pose: + pose: + position: + x: -0.070929977494 + y: 0.255808966128 + z: 0.0 + orientation: + x: -0.0 + y: -0.000674604029729 + z: -0.0 + w: 0.999999772455 + covariance: [10.594095706625978, -4.4324270265251736e-08, 0.0, 0.0, -2.2576916200853522e-05, 0.0, -4.432427026525172e-08, 10.594095229632122, 0.0, 0.0, 9.04094679080549e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.257691620085351e-05, 9.040946790805483e-06, 0.0, 0.0, 10.408978138168878, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 300 + stamp: + secs: 1624875220 + nsecs: 841311932 + frame_id: "/world" +pose: + pose: + position: + x: -0.0727491934797 + y: 0.262049096337 + z: 0.0 + orientation: + x: -0.0 + y: -5.9910058681e-05 + z: -0.0 + w: 0.999999998205 + covariance: [8.813818601162096, -2.6048104533383155e-08, 0.0, 0.0, -1.2990675402021717e-05, 0.0, -2.6048104533383148e-08, 8.813818321091093, 0.0, 0.0, 5.31532630859073e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2990675402021706e-05, 5.315326308590725e-06, 0.0, 0.0, 8.70342074397333, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 301 + stamp: + secs: 1624875220 + nsecs: 921345949 + frame_id: "/world" +pose: + pose: + position: + x: -0.0711052889164 + y: 0.251609534713 + z: 0.0 + orientation: + x: 0.0 + y: 0.000173789865681 + z: 0.0 + w: 0.999999984899 + covariance: [9.193030022726505, -3.2756047592365766e-08, 0.0, 0.0, -1.36197935204652e-05, 0.0, -3.2756047592365766e-08, 9.193029671031834, 0.0, 0.0, 7.1591352079674625e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.361979352046519e-05, 7.159135207967457e-06, 0.0, 0.0, 9.051896069181568, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 302 + stamp: + secs: 1624875221 + nsecs: 1331091 + frame_id: "/world" +pose: + pose: + position: + x: -0.0592449768436 + y: 0.235018724583 + z: 0.0 + orientation: + x: -0.0 + y: -0.000266488875058 + z: -0.0 + w: 0.999999964492 + covariance: [10.589157523688257, -4.3825067054416714e-08, 0.0, 0.0, -0.00010115739732500836, 0.0, -4.3825067054416714e-08, 10.589157054727071, 0.0, 0.0, 1.631850162034697e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00010115739732500835, 1.6318501620346963e-05, 0.0, 0.0, 10.39923982102686, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 303 + stamp: + secs: 1624875221 + nsecs: 81346989 + frame_id: "/world" +pose: + pose: + position: + x: -0.0536614095382 + y: 0.235402038444 + z: 0.0 + orientation: + x: -0.0 + y: -0.00236744516077 + z: -0.0 + w: 0.999997197598 + covariance: [13.20599930894818, -6.783865873831547e-08, 0.0, 0.0, -0.0002384734454696985, 0.0, -6.783865873831544e-08, 13.205998585903346, 0.0, 0.0, 2.971943719324929e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00023847344546969846, 2.971943719324928e-05, 0.0, 0.0, 12.913457218447107, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 304 + stamp: + secs: 1624875221 + nsecs: 161340952 + frame_id: "/world" +pose: + pose: + position: + x: -0.0538962988469 + y: 0.236116010946 + z: 0.0 + orientation: + x: -0.0 + y: -0.00100530844421 + z: -0.0 + w: 0.999999494677 + covariance: [12.650461234989749, -6.411402021095188e-08, 0.0, 0.0, -0.00018535896888577152, 0.0, -6.411402021095186e-08, 12.650460553317677, 0.0, 0.0, 2.4340514178983595e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00018535896888577152, 2.434051417898359e-05, 0.0, 0.0, 12.372767223409843, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 305 + stamp: + secs: 1624875221 + nsecs: 241344929 + frame_id: "/world" +pose: + pose: + position: + x: -0.0536383330733 + y: 0.236931333487 + z: 0.0 + orientation: + x: -0.0 + y: -0.000701410157294 + z: -0.0 + w: 0.999999754012 + covariance: [12.377294950360772, -6.069947663492311e-08, 0.0, 0.0, -0.00012163074883410307, 0.0, -6.06994766349231e-08, 12.377294306162609, 0.0, 0.0, 1.79364450027553e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00012163074883410303, 1.7936445002755293e-05, 0.0, 0.0, 12.112533524784709, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 306 + stamp: + secs: 1624875221 + nsecs: 321346045 + frame_id: "/world" +pose: + pose: + position: + x: -0.0536554947827 + y: 0.239286932473 + z: 0.0 + orientation: + x: -0.0 + y: -0.000348627135337 + z: -0.0 + w: 0.99999993923 + covariance: [9.411509389404097, -4.2711330009659203e-08, 0.0, 0.0, -7.358250703066844e-05, 0.0, -4.27113300096592e-08, 9.411508937183084, 0.0, 0.0, 1.221903006584815e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.358250703066844e-05, 1.2219030065848146e-05, 0.0, 0.0, 9.222137811386139, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 307 + stamp: + secs: 1624875221 + nsecs: 401350975 + frame_id: "/world" +pose: + pose: + position: + x: -0.0533866924688 + y: 0.240158749231 + z: 0.0 + orientation: + x: -0.0 + y: -0.000272706715172 + z: -0.0 + w: 0.999999962816 + covariance: [10.739087741075585, -5.534297059715468e-08, 0.0, 0.0, -8.608015229910287e-05, 0.0, -5.534297059715467e-08, 10.739087156914952, 0.0, 0.0, 1.590892186313663e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.608015229910287e-05, 1.5908921863136626e-05, 0.0, 0.0, 10.491741905622405, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 308 + stamp: + secs: 1624875221 + nsecs: 481375933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0530613186788 + y: 0.239965662586 + z: 0.0 + orientation: + x: -0.0 + y: -5.84929934313e-05 + z: -0.0 + w: 0.999999998289 + covariance: [10.010615997144525, -4.667614202681969e-08, 0.0, 0.0, -6.400298860236924e-05, 0.0, -4.667614202681969e-08, 10.010615505443253, 0.0, 0.0, 1.142446762689816e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.400298860236923e-05, 1.142446762689816e-05, 0.0, 0.0, 9.799066153229566, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 309 + stamp: + secs: 1624875221 + nsecs: 561382055 + frame_id: "/world" +pose: + pose: + position: + x: -0.056245623567 + y: 0.240409892602 + z: 0.0 + orientation: + x: 0.0 + y: 0.000136528891498 + z: 0.0 + w: 0.99999999068 + covariance: [8.662293267654768, -3.4032732155981744e-08, 0.0, 0.0, -4.0456701609814416e-05, 0.0, -3.403273215598173e-08, 8.662292909687734, 0.0, 0.0, 6.387462571790146e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.04567016098144e-05, 6.387462571790147e-06, 0.0, 0.0, 8.505435215953325, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 310 + stamp: + secs: 1624875221 + nsecs: 641385078 + frame_id: "/world" +pose: + pose: + position: + x: -0.055026054056 + y: 0.239821517809 + z: 0.0 + orientation: + x: 0.0 + y: 0.0011154343428 + z: 0.0 + w: 0.999999377903 + covariance: [10.316525756160136, -4.7162077503369026e-08, 0.0, 0.0, -4.2237093001117274e-05, 0.0, -4.7162077503369006e-08, 10.316525260833734, 0.0, 0.0, 7.475397411887995e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.2237093001117253e-05, 7.4753974118879985e-06, 0.0, 0.0, 10.096902462494842, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 311 + stamp: + secs: 1624875221 + nsecs: 721393108 + frame_id: "/world" +pose: + pose: + position: + x: -0.0664853345228 + y: 0.253445552848 + z: 0.0 + orientation: + x: 0.0 + y: 0.00073651497299 + z: 0.0 + w: 0.999999728773 + covariance: [11.187840483848712, -4.824688525893254e-08, 0.0, 0.0, -3.332323161105107e-05, 0.0, -4.8246885258932514e-08, 11.187839977713123, 0.0, 0.0, 9.19003044157396e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.332323161105104e-05, 9.190030441573961e-06, 0.0, 0.0, 10.960235765545233, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 312 + stamp: + secs: 1624875221 + nsecs: 801403046 + frame_id: "/world" +pose: + pose: + position: + x: -0.0668622717009 + y: 0.25205467772 + z: 0.0 + orientation: + x: 0.0 + y: 0.000237664867538 + z: 0.0 + w: 0.999999971758 + covariance: [10.177532056051241, -4.022729371885413e-08, 0.0, 0.0, -3.2018324997053226e-05, 0.0, -4.0227293718854116e-08, 10.177531634607694, 0.0, 0.0, 8.504240279623335e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.2018324997053206e-05, 8.504240279623337e-06, 0.0, 0.0, 9.984561749360495, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 313 + stamp: + secs: 1624875221 + nsecs: 881417036 + frame_id: "/world" +pose: + pose: + position: + x: -0.0600659748247 + y: 0.246663544113 + z: 0.0 + orientation: + x: 0.0 + y: 0.000582431041317 + z: 0.0 + w: 0.999999830387 + covariance: [9.774800945853986, -3.711984697297885e-08, 0.0, 0.0, -3.595502409487876e-05, 0.0, -3.7119846972978847e-08, 9.774800557449955, 0.0, 0.0, 7.330526081496382e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.595502409487874e-05, 7.33052608149638e-06, 0.0, 0.0, 9.594688777466903, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 314 + stamp: + secs: 1624875221 + nsecs: 961416006 + frame_id: "/world" +pose: + pose: + position: + x: -0.0596399885306 + y: 0.24795227566 + z: 0.0 + orientation: + x: 0.0 + y: 0.00113154067508 + z: 0.0 + w: 0.999999359808 + covariance: [10.904800740104848, -4.2977867807664004e-08, 0.0, 0.0, -4.081380480631859e-05, 0.0, -4.297786780766399e-08, 10.904800291537686, 0.0, 0.0, 1.704507240998722e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.0813804806318563e-05, 1.7045072409987217e-05, 0.0, 0.0, 10.694594802513745, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 315 + stamp: + secs: 1624875222 + nsecs: 41435957 + frame_id: "/world" +pose: + pose: + position: + x: -0.0591758065669 + y: 0.246451996662 + z: 0.0 + orientation: + x: 0.0 + y: 0.00134868706419 + z: 0.0 + w: 0.999999090521 + covariance: [11.496171173540553, -5.8849942566826576e-08, 0.0, 0.0, -0.0005725543263537358, 0.0, -5.884994256682658e-08, 11.496170660445632, 0.0, 0.0, 0.0001654029510830258, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005725543263537357, 0.00016540295108302577, 0.0, 0.0, 11.274220378623415, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 316 + stamp: + secs: 1624875222 + nsecs: 121417046 + frame_id: "/world" +pose: + pose: + position: + x: -0.0591004761452 + y: 0.24654899964 + z: 0.0 + orientation: + x: 0.0 + y: 0.00193986465015 + z: 0.0 + w: 0.999998118461 + covariance: [13.824733287216592, -1.666415658197411e-07, 0.0, 0.0, -0.001385455952048602, 0.0, -1.6664156581974107e-07, 13.82473231613377, 0.0, 0.0, 0.0003984495864671929, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013854559520486017, 0.0003984495864671929, 0.0, 0.0, 13.526799061739172, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 317 + stamp: + secs: 1624875222 + nsecs: 201446056 + frame_id: "/world" +pose: + pose: + position: + x: -0.0591476830716 + y: 0.246629142032 + z: 0.0 + orientation: + x: 0.0 + y: 0.00207492094838 + z: 0.0 + w: 0.999997847349 + covariance: [15.437371282982902, -3.5403020691835286e-07, 0.0, 0.0, -0.0018575264665381867, 0.0, -3.540302069183529e-07, 15.437369587334238, 0.0, 0.0, 0.000546249143501606, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0018575264665381857, 0.0005462491435016058, 0.0, 0.0, 15.044858949644388, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 318 + stamp: + secs: 1624875222 + nsecs: 281445026 + frame_id: "/world" +pose: + pose: + position: + x: -0.0504233944545 + y: 0.250729831219 + z: 0.0 + orientation: + x: 0.0 + y: 0.00208477917832 + z: 0.0 + w: 0.999997826846 + covariance: [16.534322161770856, -6.043501605233961e-07, 0.0, 0.0, -0.0020915792990233843, 0.0, -6.043501605233961e-07, 16.534319515995215, 0.0, 0.0, 0.0006095480062201463, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0020915792990233843, 0.0006095480062201464, 0.0, 0.0, 16.02991449919313, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 319 + stamp: + secs: 1624875222 + nsecs: 361438990 + frame_id: "/world" +pose: + pose: + position: + x: -0.0609054952185 + y: 0.252065156756 + z: 0.0 + orientation: + x: 0.0 + y: 0.000547785612473 + z: 0.0 + w: 0.999999849965 + covariance: [12.020084629209812, -3.462388906653031e-07, 0.0, 0.0, -0.00093886135925317, 0.0, -3.4623889066530304e-07, 12.020083157606487, 0.0, 0.0, 0.00027080710646441435, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009388613592531698, 0.0002708071064644144, 0.0, 0.0, 11.758772170703857, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 320 + stamp: + secs: 1624875222 + nsecs: 441457987 + frame_id: "/world" +pose: + pose: + position: + x: -0.0607080397196 + y: 0.252552282636 + z: 0.0 + orientation: + x: 0.0 + y: 0.000528031086589 + z: 0.0 + w: 0.999999860592 + covariance: [10.4830671020409, -2.85456081483138e-07, 0.0, 0.0, -0.0005561659855871397, 0.0, -2.8545608148313795e-07, 10.4830659285497, 0.0, 0.0, 0.00016538441248811097, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005561659855871394, 0.00016538441248811092, 0.0, 0.0, 10.291805740225081, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 321 + stamp: + secs: 1624875222 + nsecs: 521461964 + frame_id: "/world" +pose: + pose: + position: + x: -0.0610870571733 + y: 0.253108929571 + z: 0.0 + orientation: + x: 0.0 + y: 0.000857994669415 + z: 0.0 + w: 0.999999631923 + covariance: [11.29946131128637, -3.9370440172523635e-07, 0.0, 0.0, -0.0005076594351132391, 0.0, -3.937044017252362e-07, 11.299459740256259, 0.0, 0.0, 0.00015937073491753586, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005076594351132388, 0.0001593707349175358, 0.0, 0.0, 11.064424747932069, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 322 + stamp: + secs: 1624875222 + nsecs: 601474047 + frame_id: "/world" +pose: + pose: + position: + x: -0.0606089013993 + y: 0.252236784796 + z: 0.0 + orientation: + x: 0.0 + y: 0.000897797158663 + z: 0.0 + w: 0.99999959698 + covariance: [11.724653639762375, -4.6685217929769756e-07, 0.0, 0.0, -0.00044656304487221497, 0.0, -4.6685217929769745e-07, 11.724651812590029, 0.0, 0.0, 0.00015948824538911197, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004465630448722147, 0.00015948824538911195, 0.0, 0.0, 11.461935086232751, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 323 + stamp: + secs: 1624875222 + nsecs: 681476116 + frame_id: "/world" +pose: + pose: + position: + x: -0.0601387769358 + y: 0.252443860586 + z: 0.0 + orientation: + x: 0.0 + y: 0.000509241831921 + z: 0.0 + w: 0.999999870336 + covariance: [10.385755804789264, -3.790915765193058e-07, 0.0, 0.0, -0.00028564095726039756, 0.0, -3.7909157651930594e-07, 10.385754340835263, 0.0, 0.0, 0.00011015463375678269, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00028564095726039756, 0.00011015463375678269, 0.0, 0.0, 10.179192691118548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 324 + stamp: + secs: 1624875222 + nsecs: 761483908 + frame_id: "/world" +pose: + pose: + position: + x: -0.0622200172223 + y: 0.251474850039 + z: 0.0 + orientation: + x: 0.0 + y: 0.000789638704392 + z: 0.0 + w: 0.999999688235 + covariance: [13.080361735067147, -6.051320192430684e-07, 0.0, 0.0, -0.00033579563710160135, 0.0, -6.051320192430685e-07, 13.080359421365893, 0.0, 0.0, 0.0001291052566652159, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00033579563710160135, 0.0001291052566652159, 0.0, 0.0, 12.759088390109579, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 325 + stamp: + secs: 1624875222 + nsecs: 841490030 + frame_id: "/world" +pose: + pose: + position: + x: -0.0618264327942 + y: 0.251893898201 + z: 0.0 + orientation: + x: 0.0 + y: 0.000536155519812 + z: 0.0 + w: 0.999999856269 + covariance: [12.622442022787533, -6.121197181912751e-07, 0.0, 0.0, -0.00028262046868592945, 0.0, -6.121197181912753e-07, 12.62243969623539, 0.0, 0.0, 9.711090625868903e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00028262046868592945, 9.711090625868906e-05, 0.0, 0.0, 12.298949632987824, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 326 + stamp: + secs: 1624875222 + nsecs: 921515942 + frame_id: "/world" +pose: + pose: + position: + x: -0.0628755340785 + y: 0.26062154256 + z: 0.0 + orientation: + x: 0.0 + y: 0.000171495676441 + z: 0.0 + w: 0.999999985295 + covariance: [9.447383291421087, -3.218982453511612e-07, 0.0, 0.0, -0.00014162101324229854, 0.0, -3.218982453511612e-07, 9.44738207172136, 0.0, 0.0, 4.100605533635475e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001416210132422985, 4.100605533635474e-05, 0.0, 0.0, 9.27608852370007, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 327 + stamp: + secs: 1624875223 + nsecs: 1523018 + frame_id: "/world" +pose: + pose: + position: + x: -0.0629538630759 + y: 0.260729326902 + z: 0.0 + orientation: + x: 0.0 + y: 0.000406282159971 + z: 0.0 + w: 0.999999917467 + covariance: [9.457066931986384, -2.9718296322205495e-07, 0.0, 0.0, -0.00011387180645084524, 0.0, -2.971829632220549e-07, 9.457065809084687, 0.0, 0.0, 2.9267677432943057e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011387180645084529, 2.926767743294306e-05, 0.0, 0.0, 9.298762089156346, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 328 + stamp: + secs: 1624875223 + nsecs: 81501961 + frame_id: "/world" +pose: + pose: + position: + x: -0.0658162474073 + y: 0.268168244138 + z: 0.0 + orientation: + x: 0.0 + y: 0.000790822111937 + z: 0.0 + w: 0.9999996873 + covariance: [12.383931199655388, -4.751437959604132e-07, 0.0, 0.0, -0.0001474677443072151, 0.0, -4.751437959604131e-07, 12.383929415412899, 0.0, 0.0, 0.00011706662155272503, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00014746774430721515, 0.00011706662155272501, 0.0, 0.0, 12.131842990062141, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 329 + stamp: + secs: 1624875223 + nsecs: 161525011 + frame_id: "/world" +pose: + pose: + position: + x: -0.0660812208708 + y: 0.268154185222 + z: 0.0 + orientation: + x: 0.0 + y: 0.000641663722076 + z: 0.0 + w: 0.999999794134 + covariance: [10.614012751091435, -3.4173234633695316e-07, 0.0, 0.0, -9.314679198754315e-05, 0.0, -3.417323463369532e-07, 10.614011478734016, 0.0, 0.0, 0.00012584301911690117, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.314679198754318e-05, 0.00012584301911690117, 0.0, 0.0, 10.431440901169568, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 330 + stamp: + secs: 1624875223 + nsecs: 241575956 + frame_id: "/world" +pose: + pose: + position: + x: -0.0650988149081 + y: 0.266440106956 + z: 0.0 + orientation: + x: 0.0 + y: 0.000144105217008 + z: 0.0 + w: 0.999999989617 + covariance: [8.85099847052954, -2.592844877046882e-07, 0.0, 0.0, -7.57653300144453e-05, 0.0, -2.5928448770468827e-07, 8.85099751651872, 0.0, 0.0, 0.00010434834314954772, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.57653300144453e-05, 0.00010434834314954772, 0.0, 0.0, 8.710279610456578, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 331 + stamp: + secs: 1624875223 + nsecs: 321557045 + frame_id: "/world" +pose: + pose: + position: + x: -0.0659773792453 + y: 0.268783664374 + z: 0.0 + orientation: + x: -0.0 + y: -1.66429757673e-05 + z: -0.0 + w: 0.999999999862 + covariance: [7.474562098339697, -1.6639571202392258e-07, 0.0, 0.0, -4.7981117370574916e-05, 0.0, -1.6639571202392258e-07, 7.474561492714461, 0.0, 0.0, 6.345162820711044e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.79811173705749e-05, 6.345162820711045e-05, 0.0, 0.0, 7.383557193412096, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 332 + stamp: + secs: 1624875223 + nsecs: 401560068 + frame_id: "/world" +pose: + pose: + position: + x: -0.0683041799822 + y: 0.271986292311 + z: 0.0 + orientation: + x: 0.0 + y: 0.000420421613039 + z: 0.0 + w: 0.999999911623 + covariance: [7.07396942701025, -1.6854970953086886e-07, 0.0, 0.0, -3.494689746222924e-05, 0.0, -1.6854970953086891e-07, 7.0739688212193075, 0.0, 0.0, 4.7737354170659394e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.494689746222924e-05, 4.773735417065941e-05, 0.0, 0.0, 6.981143309655695, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 333 + stamp: + secs: 1624875223 + nsecs: 481564999 + frame_id: "/world" +pose: + pose: + position: + x: -0.0708530048794 + y: 0.273362413903 + z: 0.0 + orientation: + x: 0.0 + y: 0.000539809258736 + z: 0.0 + w: 0.999999854303 + covariance: [8.389616415058956, -2.1994720688932727e-07, 0.0, 0.0, -3.095835351001098e-05, 0.0, -2.1994720688932732e-07, 8.389615630366235, 0.0, 0.0, 4.3849838378338154e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.0958353510010975e-05, 4.3849838378338154e-05, 0.0, 0.0, 8.267071024952523, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 334 + stamp: + secs: 1624875223 + nsecs: 561572075 + frame_id: "/world" +pose: + pose: + position: + x: -0.0789638008897 + y: 0.276809062711 + z: 0.0 + orientation: + x: 0.0 + y: 0.000405388425442 + z: 0.0 + w: 0.99999991783 + covariance: [8.98833036074085, -2.2836078790515871e-07, 0.0, 0.0, -2.2496140106223114e-05, 0.0, -2.2836078790515882e-07, 8.988329549442263, 0.0, 0.0, 3.30016905430963e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.2496140106223108e-05, 3.300169054309628e-05, 0.0, 0.0, 8.859667128400028, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 335 + stamp: + secs: 1624875223 + nsecs: 641552925 + frame_id: "/world" +pose: + pose: + position: + x: -0.0789727994369 + y: 0.277196007931 + z: 0.0 + orientation: + x: 0.0 + y: 0.000569758379728 + z: 0.0 + w: 0.999999837688 + covariance: [8.287749641444654, -1.7683869816003012e-07, 0.0, 0.0, -1.1163233229755226e-05, 0.0, -1.7683869816003018e-07, 8.287749014888576, 0.0, 0.0, 1.8297468066660258e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.116323322975522e-05, 1.8297468066660247e-05, 0.0, 0.0, 8.187483565696068, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 336 + stamp: + secs: 1624875223 + nsecs: 721590996 + frame_id: "/world" +pose: + pose: + position: + x: -0.0789995951559 + y: 0.277667994039 + z: 0.0 + orientation: + x: 0.0 + y: 0.000559018776837 + z: 0.0 + w: 0.999999843749 + covariance: [8.039848537243204, -1.598541092902315e-07, 0.0, 0.0, -9.391583902347966e-06, 0.0, -1.5985410929023152e-07, 8.039847972106827, 0.0, 0.0, 1.3529663932041463e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.391583902347961e-06, 1.352966393204146e-05, 0.0, 0.0, 7.94736133218905, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 337 + stamp: + secs: 1624875223 + nsecs: 801577091 + frame_id: "/world" +pose: + pose: + position: + x: -0.0795914350492 + y: 0.278457276129 + z: 0.0 + orientation: + x: -0.0 + y: -4.18618530647e-05 + z: -0.0 + w: 0.999999999124 + covariance: [7.230432952037622, -1.2559554452268912e-07, 0.0, 0.0, -2.3450374558133242e-05, 0.0, -1.2559554452268918e-07, 7.230432508721251, 0.0, 0.0, 8.860111553621698e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.3450374558133242e-05, 8.860111553621693e-06, 0.0, 0.0, 7.15623457607848, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 338 + stamp: + secs: 1624875223 + nsecs: 881587982 + frame_id: "/world" +pose: + pose: + position: + x: -0.076344896705 + y: 0.273440931165 + z: 0.0 + orientation: + x: -0.0 + y: -0.000120878518504 + z: -0.0 + w: 0.999999992694 + covariance: [6.976016765496476, -1.1352848485117645e-07, 0.0, 0.0, -3.0270970885673144e-05, 0.0, -1.1352848485117648e-07, 6.976016364934502, 0.0, 0.0, 6.041409156791846e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.0270970885673137e-05, 6.041409156791841e-06, 0.0, 0.0, 6.9079108281391175, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 339 + stamp: + secs: 1624875223 + nsecs: 961596966 + frame_id: "/world" +pose: + pose: + position: + x: -0.0809575537586 + y: 0.277520830363 + z: 0.0 + orientation: + x: -0.0 + y: -2.93591825883e-05 + z: -0.0 + w: 0.999999999569 + covariance: [7.542058548828703, -1.28291106959609e-07, 0.0, 0.0, -2.9144793887127767e-05, 0.0, -1.2829110695960903e-07, 7.542058096112143, 0.0, 0.0, 4.850865118189671e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.9144793887127774e-05, 4.850865118189668e-06, 0.0, 0.0, 7.4639089776321015, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 340 + stamp: + secs: 1624875224 + nsecs: 41613102 + frame_id: "/world" +pose: + pose: + position: + x: -0.0845112181695 + y: 0.278911001904 + z: 0.0 + orientation: + x: -0.0 + y: -0.000195859993587 + z: -0.0 + w: 0.999999980819 + covariance: [7.079962443797534, -1.1935680976334024e-07, 0.0, 0.0, -2.5682895905627326e-05, 0.0, -1.1935680976334019e-07, 7.079962023519487, 0.0, 0.0, 3.079422528545546e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.568289590562733e-05, 3.079422528545546e-05, 0.0, 0.0, 7.006204493763564, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 341 + stamp: + secs: 1624875224 + nsecs: 121651888 + frame_id: "/world" +pose: + pose: + position: + x: -0.0861482180483 + y: 0.279982870415 + z: 0.0 + orientation: + x: -0.0 + y: -0.000278540581508 + z: -0.0 + w: 0.999999961208 + covariance: [6.9574936173701705, -1.567860087988423e-07, 0.0, 0.0, -3.960186607098884e-05, 0.0, -1.5678600879884227e-07, 6.957493070956921, 0.0, 0.0, 5.706723208453386e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.960186607098883e-05, 5.706723208453385e-05, 0.0, 0.0, 6.859196196446501, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 342 + stamp: + secs: 1624875224 + nsecs: 201616049 + frame_id: "/world" +pose: + pose: + position: + x: -0.077556423474 + y: 0.266944843058 + z: 0.0 + orientation: + x: 0.0 + y: 2.21314590936e-05 + z: 0.0 + w: 0.999999999755 + covariance: [9.326236994992977, -2.833339545758425e-07, 0.0, 0.0, -6.113335317778019e-05, 0.0, -2.8333395457584246e-07, 9.326236015630434, 0.0, 0.0, 8.200671247209192e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.113335317778015e-05, 8.20067124720919e-05, 0.0, 0.0, 9.147254084555145, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 343 + stamp: + secs: 1624875224 + nsecs: 281644106 + frame_id: "/world" +pose: + pose: + position: + x: -0.0775953235325 + y: 0.26680551569 + z: 0.0 + orientation: + x: 0.0 + y: 0.000194035660082 + z: 0.0 + w: 0.999999981175 + covariance: [9.412888547140684, -2.6489978245649104e-07, 0.0, 0.0, -4.230982437243472e-05, 0.0, -2.6489978245649094e-07, 9.412887635274387, 0.0, 0.0, 6.1015311787004334e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.230982437243469e-05, 6.101531178700431e-05, 0.0, 0.0, 9.243428593176809, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 344 + stamp: + secs: 1624875224 + nsecs: 361641884 + frame_id: "/world" +pose: + pose: + position: + x: -0.0767888290382 + y: 0.263676304478 + z: 0.0 + orientation: + x: -0.0 + y: -0.000309140194416 + z: -0.0 + w: 0.999999952216 + covariance: [9.4447414653369, -2.4804753667989636e-07, 0.0, 0.0, -0.00010201279250681467, 0.0, -2.480475366798963e-07, 9.444740614765985, 0.0, 0.0, 4.742402089432809e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00010201279250681469, 4.742402089432809e-05, 0.0, 0.0, 9.28472208050006, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 345 + stamp: + secs: 1624875224 + nsecs: 441647053 + frame_id: "/world" +pose: + pose: + position: + x: -0.0765826620295 + y: 0.263537451233 + z: 0.0 + orientation: + x: -0.0 + y: -0.000571391003235 + z: -0.0 + w: 0.999999836756 + covariance: [9.476157168176934, -2.6707822644836313e-07, 0.0, 0.0, -0.000165206074526183, 0.0, -2.670782264483631e-07, 9.476156251790414, 0.0, 0.0, 4.056859774027124e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00016520607452618299, 4.056859774027124e-05, 0.0, 0.0, 9.301906205851333, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 346 + stamp: + secs: 1624875224 + nsecs: 521675110 + frame_id: "/world" +pose: + pose: + position: + x: -0.0758445284269 + y: 0.268027662074 + z: 0.0 + orientation: + x: -0.0 + y: -0.00027135703475 + z: -0.0 + w: 0.999999963183 + covariance: [8.48418980402142, -2.1952052300272794e-07, 0.0, 0.0, -0.00013914730382207045, 0.0, -2.1952052300272794e-07, 8.484189048406241, 0.0, 0.0, 2.6881626961270266e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00013914730382207048, 2.6881626961270266e-05, 0.0, 0.0, 8.339044754140371, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 347 + stamp: + secs: 1624875224 + nsecs: 601653099 + frame_id: "/world" +pose: + pose: + position: + x: -0.0765596575245 + y: 0.26971748426 + z: 0.0 + orientation: + x: -0.0 + y: -8.89738266997e-05 + z: -0.0 + w: 0.999999996042 + covariance: [8.137494150467276, -2.017407405599342e-07, 0.0, 0.0, -0.00011470395610172289, 0.0, -2.017407405599341e-07, 8.13749345306914, 0.0, 0.0, 1.9141138102215134e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011470395610172289, 1.9141138102215145e-05, 0.0, 0.0, 8.0019707755978, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 348 + stamp: + secs: 1624875224 + nsecs: 681679964 + frame_id: "/world" +pose: + pose: + position: + x: -0.0766817364409 + y: 0.269669047437 + z: 0.0 + orientation: + x: 0.0 + y: 0.000142445652347 + z: 0.0 + w: 0.999999989855 + covariance: [8.011967628619116, -1.94072604685331e-07, 0.0, 0.0, -8.325357979265529e-05, 0.0, -1.9407260468533088e-07, 8.01196695526083, 0.0, 0.0, 1.2128212650588888e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.325357979265528e-05, 1.2128212650588893e-05, 0.0, 0.0, 7.879509336318668, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 349 + stamp: + secs: 1624875224 + nsecs: 761667967 + frame_id: "/world" +pose: + pose: + position: + x: -0.0792062117799 + y: 0.271575186002 + z: 0.0 + orientation: + x: 0.0 + y: 0.000150884841275 + z: 0.0 + w: 0.999999988617 + covariance: [7.96341809737664, -1.8601162480945377e-07, 0.0, 0.0, -8.50051031386703e-05, 0.0, -1.8601162480945364e-07, 7.963417449488675, 0.0, 0.0, 8.590744768687535e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.50051031386703e-05, 8.59074476868754e-06, 0.0, 0.0, 7.834402514405279, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 350 + stamp: + secs: 1624875224 + nsecs: 841675043 + frame_id: "/world" +pose: + pose: + position: + x: -0.0797926180461 + y: 0.272955328307 + z: 0.0 + orientation: + x: 0.0 + y: 9.03086612735e-05 + z: 0.0 + w: 0.999999995922 + covariance: [6.622993047551593, -1.1810357158625077e-07, 0.0, 0.0, -5.460635402201216e-05, 0.0, -1.1810357158625067e-07, 6.62299263444393, 0.0, 0.0, 4.4726577342637616e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.460635402201214e-05, 4.472657734263764e-06, 0.0, 0.0, 6.539559020065255, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 351 + stamp: + secs: 1624875224 + nsecs: 921693087 + frame_id: "/world" +pose: + pose: + position: + x: -0.0801173625538 + y: 0.273184670813 + z: 0.0 + orientation: + x: 0.0 + y: 2.81467591238e-05 + z: 0.0 + w: 0.999999999604 + covariance: [6.254073117015302, -9.520358802266636e-08, 0.0, 0.0, -5.1919786067113475e-05, 0.0, -9.520358802266631e-08, 6.2540727834425, 0.0, 0.0, 1.810188884517827e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.1919786067113475e-05, 1.8101888845178268e-05, 0.0, 0.0, 6.185886648173521, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 352 + stamp: + secs: 1624875225 + nsecs: 1673937 + frame_id: "/world" +pose: + pose: + position: + x: -0.0802803552942 + y: 0.273236749469 + z: 0.0 + orientation: + x: 0.0 + y: 6.76048988962e-05 + z: 0.0 + w: 0.999999997715 + covariance: [8.848710365148527, -1.4971089159280565e-07, 0.0, 0.0, -8.555006109994648e-05, 0.0, -1.497108915928056e-07, 8.848709842868717, 0.0, 0.0, 4.085114519158449e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.555006109994649e-05, 4.085114519158449e-05, 0.0, 0.0, 8.74139507381806, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 353 + stamp: + secs: 1624875225 + nsecs: 81682920 + frame_id: "/world" +pose: + pose: + position: + x: -0.0804948149461 + y: 0.273300878929 + z: 0.0 + orientation: + x: 0.0 + y: 0.000172914703221 + z: 0.0 + w: 0.99999998505 + covariance: [6.842336724519776, -1.0381843960129253e-07, 0.0, 0.0, -5.57053641484502e-05, 0.0, -1.0381843960129252e-07, 6.8423363640379256, 0.0, 0.0, 2.3740500795327743e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.5705364148450214e-05, 2.3740500795327743e-05, 0.0, 0.0, 6.767250849649829, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 354 + stamp: + secs: 1624875225 + nsecs: 161689043 + frame_id: "/world" +pose: + pose: + position: + x: -0.080697452357 + y: 0.273172924826 + z: 0.0 + orientation: + x: 0.0 + y: 0.000475921310687 + z: 0.0 + w: 0.999999886749 + covariance: [6.875033344419229, -1.2914723096814106e-07, 0.0, 0.0, -6.340339293583947e-05, 0.0, -1.2914723096814103e-07, 6.8750328976581825, 0.0, 0.0, 1.8910865888437137e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.340339293583944e-05, 1.8910865888437137e-05, 0.0, 0.0, 6.780880384479232, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 355 + stamp: + secs: 1624875225 + nsecs: 241738081 + frame_id: "/world" +pose: + pose: + position: + x: -0.0811792404278 + y: 0.274038105969 + z: 0.0 + orientation: + x: 0.0 + y: 0.000406250681459 + z: 0.0 + w: 0.99999991748 + covariance: [6.878889327722448, -1.2669622887342905e-07, 0.0, 0.0, -4.8937157700628336e-05, 0.0, -1.2669622887342897e-07, 6.878888889965597, 0.0, 0.0, 1.166603261406046e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.89371577006283e-05, 1.1666032614060454e-05, 0.0, 0.0, 6.785228223370331, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 356 + stamp: + secs: 1624875225 + nsecs: 321708918 + frame_id: "/world" +pose: + pose: + position: + x: -0.081290157309 + y: 0.274129920264 + z: 0.0 + orientation: + x: 0.0 + y: 0.000175432914357 + z: 0.0 + w: 0.999999984612 + covariance: [6.872725412388043, -1.1479064907772075e-07, 0.0, 0.0, -3.089473794218805e-05, 0.0, -1.1479064907772063e-07, 6.872725015998508, 0.0, 0.0, 6.932822901736759e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.089473794218803e-05, 6.9328229017367525e-06, 0.0, 0.0, 6.786480666878184, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 357 + stamp: + secs: 1624875225 + nsecs: 401716948 + frame_id: "/world" +pose: + pose: + position: + x: -0.0819274671055 + y: 0.275088848837 + z: 0.0 + orientation: + x: 0.0 + y: 3.78640856774e-05 + z: 0.0 + w: 0.999999999283 + covariance: [6.868403867536371, -1.068095313394706e-07, 0.0, 0.0, -2.260686327234516e-05, 0.0, -1.068095313394705e-07, 6.868403498883822, 0.0, 0.0, 7.0568498404089995e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.260686327234515e-05, 7.056849840408999e-06, 0.0, 0.0, 6.786891177317468, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 358 + stamp: + secs: 1624875225 + nsecs: 481729984 + frame_id: "/world" +pose: + pose: + position: + x: -0.083971233837 + y: 0.276180505559 + z: 0.0 + orientation: + x: -0.0 + y: -0.000120043432073 + z: -0.0 + w: 0.999999992795 + covariance: [7.49638630007811, -1.0382691253786488e-07, 0.0, 0.0, -2.3590393921623978e-05, 0.0, -1.038269125378648e-07, 7.496385942027027, 0.0, 0.0, 1.3113625398517515e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.3590393921623978e-05, 1.3113625398517515e-05, 0.0, 0.0, 7.416190651549669, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 359 + stamp: + secs: 1624875225 + nsecs: 561794043 + frame_id: "/world" +pose: + pose: + position: + x: -0.0870949474083 + y: 0.279499687286 + z: 0.0 + orientation: + x: -0.0 + y: -0.00033572549703 + z: -0.0 + w: 0.999999943644 + covariance: [7.743542939720301, -1.0618535263907891e-07, 0.0, 0.0, -2.6263680468436355e-05, 0.0, -1.0618535263907892e-07, 7.743542574120819, 0.0, 0.0, 1.6012183226435375e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.6263680468436368e-05, 1.601218322643538e-05, 0.0, 0.0, 7.66051471679914, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 360 + stamp: + secs: 1624875225 + nsecs: 641766071 + frame_id: "/world" +pose: + pose: + position: + x: -0.0886857555693 + y: 0.278736807462 + z: 0.0 + orientation: + x: -0.0 + y: -0.000150325983202 + z: -0.0 + w: 0.999999988701 + covariance: [8.704594408969355, -1.5208053742057257e-07, 0.0, 0.0, -9.876621199402392e-05, 0.0, -1.5208053742057252e-07, 8.704593887865917, 0.0, 0.0, 4.783137197249906e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.876621199402391e-05, 4.783137197249905e-05, 0.0, 0.0, 8.584728607752771, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 0 + stamp: + secs: 1624875191 + nsecs: 558718920 + frame_id: "/world" +pose: + pose: + position: + x: 0.0923602762393 + y: 0.0102065644464 + z: 0.0 + orientation: + x: 0.0 + y: 0.0471156780545 + z: 0.0 + w: 0.998889439769 + covariance: [0.09798037559877427, -1.68358732288718e-18, 0.0, 0.0, 6.128441227512958e-14, 0.0, -1.6835873228864287e-18, 0.09798037559877444, 0.0, 0.0, -3.650189795357495e-12, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 6.128441227513547e-14, -3.650189795357921e-12, 0.0, 0.0, 0.09798030470902293, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 1 + stamp: + secs: 1624875191 + nsecs: 638731003 + frame_id: "/world" +pose: + pose: + position: + x: 0.106228830275 + y: 0.0151566925105 + z: 0.0 + orientation: + x: 0.0 + y: 0.0194111332989 + z: 0.0 + w: 0.999811586202 + covariance: [3.3783884747177413, -1.221265690512682e-12, 0.0, 0.0, -1.5340831415739486e-07, 0.0, -1.2212656905126821e-12, 3.3783884747199147, 0.0, 0.0, 3.4118344821480353e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.534083141573949e-07, 3.4118344821480353e-07, 0.0, 0.0, 3.3783362523957123, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 2 + stamp: + secs: 1624875192 + nsecs: 838804007 + frame_id: "/world" +pose: + pose: + position: + x: 0.100935010492 + y: 0.0126733741331 + z: 0.0 + orientation: + x: 0.0 + y: 0.179613772122 + z: 0.0 + w: 0.983737207218 + covariance: [9.761567366508634, -2.332133514151258e-06, 0.0, 0.0, -0.0026928580039068074, 0.0, -2.3321335141512508e-06, 9.76156342453144, 0.0, 0.0, 0.0012467757868695967, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.002692858003906807, 0.0012467757868695974, 0.0, 0.0, 5.015700300680833, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 3 + stamp: + secs: 1624875192 + nsecs: 918823004 + frame_id: "/world" +pose: + pose: + position: + x: 0.100805737952 + y: -0.0081697671005 + z: 0.0 + orientation: + x: -0.0 + y: -0.0304815183375 + z: -0.0 + w: 0.999535330561 + covariance: [4.921541774535543, -4.07231484642146e-07, 0.0, 0.0, -0.0004978060921384511, 0.0, -4.0723148464214474e-07, 4.921541082765353, 0.0, 0.0, 0.00022934761942997674, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004978060921384514, 0.00022934761942997695, 0.0, 0.0, 4.169424018901372, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 4 + stamp: + secs: 1624875192 + nsecs: 998827934 + frame_id: "/world" +pose: + pose: + position: + x: 0.103944920863 + y: -0.00805548280622 + z: 0.0 + orientation: + x: -0.0 + y: -0.00304883284805 + z: -0.0 + w: 0.999995352298 + covariance: [5.271889144134795, -1.7637610081217596e-07, 0.0, 0.0, -0.00018386063908794271, 0.0, -1.7637610081217572e-07, 5.271888843753759, 0.0, 0.0, 8.52631026464194e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00018386063908794293, 8.526310264641944e-05, 0.0, 0.0, 5.023671625077126, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 5 + stamp: + secs: 1624875193 + nsecs: 78836918 + frame_id: "/world" +pose: + pose: + position: + x: 0.103897258579 + y: -0.00823029979625 + z: 0.0 + orientation: + x: -0.0 + y: -0.000273336546512 + z: -0.0 + w: 0.999999962644 + covariance: [5.3513290480510705, -8.153367698449751e-08, 0.0, 0.0, -6.84088287689448e-05, 0.0, -8.153367698449742e-08, 5.351328909000762, 0.0, 0.0, 3.221944839149563e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.840882876894486e-05, 3.2219448391495636e-05, 0.0, 0.0, 5.269717394378887, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 6 + stamp: + secs: 1624875193 + nsecs: 158852100 + frame_id: "/world" +pose: + pose: + position: + x: 0.109411745971 + y: -0.00685425519602 + z: 0.0 + orientation: + x: 0.0 + y: 3.07364402165e-05 + z: 0.0 + w: 0.999999999528 + covariance: [5.999784545432195, -2.120025043194099e-08, 0.0, 0.0, -1.953346366418934e-05, 0.0, -2.1200250431940956e-08, 5.999784509300183, 0.0, 0.0, 9.265053252169039e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9533463664189353e-05, 9.265053252169042e-06, 0.0, 0.0, 5.974651556951078, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 7 + stamp: + secs: 1624875193 + nsecs: 238862991 + frame_id: "/world" +pose: + pose: + position: + x: 0.101107083214 + y: 0.00826885647459 + z: 0.0 + orientation: + x: -0.0 + y: -5.99540288784e-05 + z: -0.0 + w: 0.999999998203 + covariance: [6.214448445083825, -6.3418131396398505e-09, 0.0, 0.0, -5.9679674251992935e-06, 0.0, -6.34181313963984e-09, 6.214448434277419, 0.0, 0.0, 2.8448986712828544e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.9679674251992986e-06, 2.8448986712828565e-06, 0.0, 0.0, 6.206589940699875, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 8 + stamp: + secs: 1624875193 + nsecs: 318856001 + frame_id: "/world" +pose: + pose: + position: + x: 0.0926784332314 + y: 0.0275423287747 + z: 0.0 + orientation: + x: -0.0 + y: -9.06341683549e-06 + z: -0.0 + w: 0.999999999959 + covariance: [5.5820660642535, -3.757411128092938e-09, 0.0, 0.0, -2.6227490863092643e-06, 0.0, -3.757411128092934e-09, 5.582066057836703, 0.0, 0.0, 1.178963372560483e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.622749086309266e-06, 1.1789633725604836e-06, 0.0, 0.0, 5.579323898143024, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 9 + stamp: + secs: 1624875193 + nsecs: 398844004 + frame_id: "/world" +pose: + pose: + position: + x: 0.0926559298547 + y: 0.0274670273806 + z: 0.0 + orientation: + x: -0.0 + y: -0.000116353083093 + z: -0.0 + w: 0.999999993231 + covariance: [8.033322705860774, -6.021354819196237e-09, 0.0, 0.0, -2.7705522978739985e-06, 0.0, -6.021354819196235e-09, 8.033322695562301, 0.0, 0.0, 1.2836501094260473e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.7705522978740006e-06, 1.2836501094260479e-06, 0.0, 0.0, 8.0305848008468, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 10 + stamp: + secs: 1624875193 + nsecs: 478880882 + frame_id: "/world" +pose: + pose: + position: + x: 0.0926154340635 + y: 0.0273305404609 + z: 0.0 + orientation: + x: -0.0 + y: -0.000147346206854 + z: -0.0 + w: 0.999999989145 + covariance: [6.38240668427666, -8.782873068207728e-09, 0.0, 0.0, -7.565640638865887e-06, 0.0, -8.782873068207726e-09, 6.382406669222914, 0.0, 0.0, 1.3463373568663217e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.565640638865889e-06, 1.346337356866321e-06, 0.0, 0.0, 6.379890838924413, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 11 + stamp: + secs: 1624875193 + nsecs: 558876991 + frame_id: "/world" +pose: + pose: + position: + x: 0.0994538135161 + y: 0.0269118320679 + z: 0.0 + orientation: + x: -0.0 + y: -0.000246817175358 + z: -0.0 + w: 0.999999969541 + covariance: [5.622733027742423, -2.8557583546671916e-09, 0.0, 0.0, -2.7108959258121925e-06, 0.0, -2.855758354667191e-09, 5.622733022845247, 0.0, 0.0, 4.7139564391582756e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.710895925812192e-06, 4.713956439158275e-07, 0.0, 0.0, 5.621947685414704, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 12 + stamp: + secs: 1624875193 + nsecs: 638890028 + frame_id: "/world" +pose: + pose: + position: + x: 0.0785011235269 + y: 0.0705717263013 + z: 0.0 + orientation: + x: -0.0 + y: -8.70945188234e-06 + z: -0.0 + w: 0.999999999962 + covariance: [5.430779826872614, -1.0068993121418857e-09, 0.0, 0.0, -1.037791514702723e-06, 0.0, -1.0068993121418855e-09, 5.430779825144899, 0.0, 0.0, 1.8532259785351084e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0377915147027228e-06, 1.853225978535108e-07, 0.0, 0.0, 5.430512230033345, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 13 + stamp: + secs: 1624875193 + nsecs: 718884945 + frame_id: "/world" +pose: + pose: + position: + x: 0.0785048670066 + y: 0.0705838882405 + z: 0.0 + orientation: + x: -0.0 + y: -4.60666550946e-07 + z: -0.0 + w: 1.0 + covariance: [5.1053931692575185, -1.1060481354697719e-10, 0.0, 0.0, -4.616188987285344e-08, 0.0, -1.1060481354697714e-10, 5.105393169068048, 0.0, 0.0, 9.621007357360895e-09, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.616188987285342e-08, 9.621007357360897e-09, 0.0, 0.0, 5.105360142705162, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 14 + stamp: + secs: 1624875193 + nsecs: 798893929 + frame_id: "/world" +pose: + pose: + position: + x: 0.078504911107 + y: 0.0705840315188 + z: 0.0 + orientation: + x: 0.0 + y: 4.75983779315e-08 + z: 0.0 + w: 1.0 + covariance: [5.587932491517596, -3.3136259306765436e-11, 0.0, 0.0, -1.2806364405573206e-08, 0.0, -3.3136259306765404e-11, 5.587932491460832, 0.0, 0.0, 2.7212772508994753e-09, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2806364405573197e-08, 2.7212772508994753e-09, 0.0, 0.0, 5.587922553201984, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 15 + stamp: + secs: 1624875193 + nsecs: 878897905 + frame_id: "/world" +pose: + pose: + position: + x: 0.0538617571471 + y: 0.0671889231217 + z: 0.0 + orientation: + x: -0.0 + y: -1.8942193014e-05 + z: -0.0 + w: 0.999999999821 + covariance: [5.4216312089425465, -1.0303624768745532e-10, 0.0, 0.0, -8.50993809552369e-08, 0.0, -1.0303624768745528e-10, 5.421631208765199, 0.0, 0.0, 1.2327275937115075e-08, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.509938095523691e-08, 1.2327275937115072e-08, 0.0, 0.0, 5.421604783330392, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 16 + stamp: + secs: 1624875193 + nsecs: 958905935 + frame_id: "/world" +pose: + pose: + position: + x: 0.0538758894214 + y: 0.0672342117071 + z: 0.0 + orientation: + x: 0.0 + y: 4.25045697237e-05 + z: 0.0 + w: 0.999999999097 + covariance: [5.68333865483073, -1.7366002722022156e-10, 0.0, 0.0, -2.0948165892337386e-07, 0.0, -1.7366002722022148e-10, 5.683338654530382, 0.0, 0.0, 1.3140815808171763e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.094816589233738e-07, 1.314081580817176e-07, 0.0, 0.0, 5.683287345219091, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 17 + stamp: + secs: 1624875194 + nsecs: 38930893 + frame_id: "/world" +pose: + pose: + position: + x: 0.0595394034332 + y: 0.0570295160187 + z: 0.0 + orientation: + x: -0.0 + y: -7.34677248385e-05 + z: -0.0 + w: 0.999999997301 + covariance: [4.280835092259253, -3.0707018058059495e-10, 0.0, 0.0, 1.970729167793004e-07, 0.0, -3.0707018058059495e-10, 4.280835091729262, 0.0, 0.0, -1.0952617060021471e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 1.9707291677930037e-07, -1.0952617060021471e-07, 0.0, 0.0, 4.280746026906948, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 18 + stamp: + secs: 1624875194 + nsecs: 118920088 + frame_id: "/world" +pose: + pose: + position: + x: 0.0675043409015 + y: 0.0498450790251 + z: 0.0 + orientation: + x: 0.0 + y: 0.000111318370813 + z: 0.0 + w: 0.999999993804 + covariance: [5.327032038943727, -2.639789327478965e-09, 0.0, 0.0, -5.161797321980913e-07, 0.0, -2.6397893274789646e-09, 5.327032034385305, 0.0, 0.0, 5.205595664688122e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.161797321980913e-07, 5.205595664688122e-07, 0.0, 0.0, 5.326234122702448, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 19 + stamp: + secs: 1624875194 + nsecs: 198947906 + frame_id: "/world" +pose: + pose: + position: + x: 0.0674847777806 + y: 0.0497835592123 + z: 0.0 + orientation: + x: 0.0 + y: 7.17136789194e-07 + z: 0.0 + w: 1.0 + covariance: [8.558755355148655, -2.884998113982955e-10, 0.0, 0.0, -1.7821660783935503e-07, 0.0, -2.8849981139829534e-10, 8.55875535465037, 0.0, 0.0, 5.5952146772781216e-08, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.782166078393551e-07, 5.59521467727812e-08, 0.0, 0.0, 8.55865879479844, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 20 + stamp: + secs: 1624875194 + nsecs: 278934002 + frame_id: "/world" +pose: + pose: + position: + x: 0.0675316962731 + y: 0.0499314799019 + z: 0.0 + orientation: + x: 0.0 + y: 0.000169527658975 + z: 0.0 + w: 0.99999998563 + covariance: [11.94159815152312, -5.851750930727207e-09, 0.0, 0.0, -5.203939135255632e-07, 0.0, -5.851750930727206e-09, 11.941598141419338, 0.0, 0.0, 1.5487880808267688e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.203939135255633e-07, 1.5487880808267686e-06, 0.0, 0.0, 11.939785460265538, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 21 + stamp: + secs: 1624875194 + nsecs: 358956099 + frame_id: "/world" +pose: + pose: + position: + x: 0.0738006844331 + y: 0.0428194080969 + z: 0.0 + orientation: + x: 0.0 + y: 0.00025398323796 + z: 0.0 + w: 0.999999967746 + covariance: [8.404940348216137, -1.2126182579968446e-08, 0.0, 0.0, -9.8494106908807e-07, 0.0, -1.2126182579968449e-08, 8.40494032728229, 0.0, 0.0, 2.7923417810837023e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.849410690880697e-07, 2.792341781083703e-06, 0.0, 0.0, 8.401082983993494, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 22 + stamp: + secs: 1624875194 + nsecs: 438956976 + frame_id: "/world" +pose: + pose: + position: + x: 0.0857788322256 + y: 0.0344530994906 + z: 0.0 + orientation: + x: 0.0 + y: 0.00079361661975 + z: 0.0 + w: 0.999999685086 + covariance: [8.03516676316282, -3.276671147477185e-08, 0.0, 0.0, -4.0991748637689757e-07, 0.0, -3.2766711474771855e-08, 8.035166706604493, 0.0, 0.0, 4.270134767721572e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.0991748637689757e-07, 4.2701347677215726e-06, 0.0, 0.0, 8.024418421515472, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 23 + stamp: + secs: 1624875194 + nsecs: 518964052 + frame_id: "/world" +pose: + pose: + position: + x: 0.0858718776551 + y: 0.0346991921308 + z: 0.0 + orientation: + x: 0.0 + y: 0.000862017474509 + z: 0.0 + w: 0.999999628463 + covariance: [11.547410163055522, -7.119596866563642e-08, 0.0, 0.0, -2.1826942286276045e-06, 0.0, -7.119596866563645e-08, 11.547410040170385, 0.0, 0.0, 6.197743156203284e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.182694228627604e-06, 6.197743156203285e-06, 0.0, 0.0, 11.523544281498362, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 24 + stamp: + secs: 1624875194 + nsecs: 598967075 + frame_id: "/world" +pose: + pose: + position: + x: 0.0936511263592 + y: 0.0326972470274 + z: 0.0 + orientation: + x: -0.0 + y: -0.000140938366677 + z: -0.0 + w: 0.999999990068 + covariance: [12.435649151939524, -4.8506064157546624e-08, 0.0, 0.0, -2.5176564293010083e-06, 0.0, -4.850606415754664e-08, 12.43564906821802, 0.0, 0.0, 3.984861027034668e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5176564293010083e-06, 3.984861027034668e-06, 0.0, 0.0, 12.419328352581724, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 25 + stamp: + secs: 1624875194 + nsecs: 678981066 + frame_id: "/world" +pose: + pose: + position: + x: 0.0926630059323 + y: 0.0342065219345 + z: 0.0 + orientation: + x: -0.0 + y: -0.000602588046255 + z: -0.0 + w: 0.999999818444 + covariance: [10.288525559314532, -6.407655931856736e-08, 0.0, 0.0, -1.7004928987329004e-05, 0.0, -6.407655931856738e-08, 10.28852544868748, 0.0, 0.0, 3.5619107880050186e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7004928987328997e-05, 3.5619107880050186e-06, 0.0, 0.0, 10.266148686642602, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 26 + stamp: + secs: 1624875194 + nsecs: 758990049 + frame_id: "/world" +pose: + pose: + position: + x: 0.0958160523547 + y: 0.0375334779637 + z: 0.0 + orientation: + x: -0.0 + y: -0.000516380659031 + z: -0.0 + w: 0.999999866675 + covariance: [13.258872642643166, -4.1982354748534495e-08, 0.0, 0.0, -1.0945092164106599e-05, 0.0, -4.19823547485345e-08, 13.258872570167195, 0.0, 0.0, 2.4419252497304425e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0945092164106594e-05, 2.4419252497304425e-06, 0.0, 0.0, 13.244259878918678, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 27 + stamp: + secs: 1624875194 + nsecs: 838989973 + frame_id: "/world" +pose: + pose: + position: + x: 0.10024628264 + y: 0.0384475877581 + z: 0.0 + orientation: + x: 0.0 + y: 2.14260702054e-05 + z: 0.0 + w: 0.99999999977 + covariance: [11.791392581508845, -2.4987127073826576e-11, 0.0, 0.0, -1.1889959091327181e-05, 0.0, -2.498712707381298e-11, 11.791392581417597, 0.0, 0.0, -3.9161165813748645e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.188995909132719e-05, -3.9161165813748634e-07, 0.0, 0.0, 11.790830454602801, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 28 + stamp: + secs: 1624875194 + nsecs: 918983936 + frame_id: "/world" +pose: + pose: + position: + x: 0.10043076449 + y: 0.0389117980548 + z: 0.0 + orientation: + x: 0.0 + y: 0.000712056549991 + z: 0.0 + w: 0.999999746488 + covariance: [14.391105036010831, -3.841462381136573e-08, 0.0, 0.0, -3.928763713252007e-06, 0.0, -3.841462381136577e-08, 14.391104969656933, 0.0, 0.0, 7.093134515030945e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.928763713251996e-06, 7.093134515030945e-06, 0.0, 0.0, 14.37684844843973, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 29 + stamp: + secs: 1624875194 + nsecs: 999001026 + frame_id: "/world" +pose: + pose: + position: + x: 0.100463929418 + y: 0.0389948212032 + z: 0.0 + orientation: + x: 0.0 + y: 0.000616593692666 + z: 0.0 + w: 0.999999809906 + covariance: [16.246732901488745, -4.00499245089968e-08, 0.0, 0.0, -5.065990433110867e-06, 0.0, -4.004992450899684e-08, 16.246732832295766, 0.0, 0.0, 5.43142683544828e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.065990433110857e-06, 5.43142683544828e-06, 0.0, 0.0, 16.231681515682247, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 30 + stamp: + secs: 1624875195 + nsecs: 79009056 + frame_id: "/world" +pose: + pose: + position: + x: 0.117074898757 + y: 0.0273119354461 + z: 0.0 + orientation: + x: 0.0 + y: 0.000726209905823 + z: 0.0 + w: 0.99999973631 + covariance: [12.99652753846536, -6.617811358430674e-08, 0.0, 0.0, -6.583459508262642e-06, 0.0, -6.617811358430678e-08, 12.996527424317543, 0.0, 0.0, 4.231063476536652e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.58345950826264e-06, 4.2310634765366524e-05, 0.0, 0.0, 12.97026813870605, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 31 + stamp: + secs: 1624875195 + nsecs: 159003973 + frame_id: "/world" +pose: + pose: + position: + x: 0.123965068032 + y: 0.0219874593042 + z: 0.0 + orientation: + x: -0.0 + y: -6.70025875379e-05 + z: -0.0 + w: 0.999999997755 + covariance: [11.721553602035723, -1.1665902622807822e-07, 0.0, 0.0, -0.0005234001037202219, 0.0, -1.1665902622807827e-07, 11.721553375099017, 0.0, 0.0, 8.477867714905602e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005234001037202218, 8.477867714905605e-05, 0.0, 0.0, 11.675765946784095, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 32 + stamp: + secs: 1624875195 + nsecs: 239037991 + frame_id: "/world" +pose: + pose: + position: + x: 0.125837677132 + y: 0.0202839057683 + z: 0.0 + orientation: + x: 0.0 + y: 0.000205528803547 + z: 0.0 + w: 0.999999978879 + covariance: [11.163788964673563, -1.28097141237304e-07, 0.0, 0.0, -0.0007246089553224255, 0.0, -1.2809714123730406e-07, 11.163788631090362, 0.0, 0.0, 7.053211099724943e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007246089553224254, 7.053211099724943e-05, 0.0, 0.0, 11.115171224695358, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 33 + stamp: + secs: 1624875195 + nsecs: 319048882 + frame_id: "/world" +pose: + pose: + position: + x: 0.128681412985 + y: 0.0190470572541 + z: 0.0 + orientation: + x: 0.0 + y: 0.000142986278536 + z: 0.0 + w: 0.999999989777 + covariance: [12.234386353390223, -1.256210524485577e-07, 0.0, 0.0, -0.0006438389687046262, 0.0, -1.256210524485577e-07, 12.234385983408236, 0.0, 0.0, 5.6955245336934415e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000643838968704626, 5.69552453369344e-05, 0.0, 0.0, 12.187237448094653, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 34 + stamp: + secs: 1624875195 + nsecs: 399015903 + frame_id: "/world" +pose: + pose: + position: + x: 0.133516401742 + y: 0.01834091075 + z: 0.0 + orientation: + x: 0.0 + y: 0.000274624270913 + z: 0.0 + w: 0.999999962291 + covariance: [11.384942356749447, -1.2004475773224755e-07, 0.0, 0.0, -0.0004743544307640542, 0.0, -1.2004475773224752e-07, 11.384941955636222, 0.0, 0.0, 3.980462363767507e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00047435443076405406, 3.980462363767507e-05, 0.0, 0.0, 11.340113943861333, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 35 + stamp: + secs: 1624875195 + nsecs: 479039907 + frame_id: "/world" +pose: + pose: + position: + x: 0.133627009334 + y: 0.0184568747502 + z: 0.0 + orientation: + x: 0.0 + y: 0.000533345427639 + z: 0.0 + w: 0.999999857771 + covariance: [14.104941688125463, -1.6026802996780641e-07, 0.0, 0.0, -0.0005082364915181532, 0.0, -1.6026802996780641e-07, 14.104941112476386, 0.0, 0.0, 4.1636817166548484e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005082364915181528, 4.163681716654848e-05, 0.0, 0.0, 14.045249172976062, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 36 + stamp: + secs: 1624875195 + nsecs: 559047937 + frame_id: "/world" +pose: + pose: + position: + x: 0.133137311073 + y: 0.017543011601 + z: 0.0 + orientation: + x: 0.0 + y: 0.000863868411507 + z: 0.0 + w: 0.999999626866 + covariance: [13.861505992540131, -1.8532274661421006e-07, 0.0, 0.0, -0.0004299813962681654, 0.0, -1.8532274661421006e-07, 13.861505280527654, 0.0, 0.0, 3.4971087347398704e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004299813962681652, 3.497108734739871e-05, 0.0, 0.0, 13.79203483655907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 37 + stamp: + secs: 1624875195 + nsecs: 639061928 + frame_id: "/world" +pose: + pose: + position: + x: 0.141514468711 + y: 0.0172445122426 + z: 0.0 + orientation: + x: 0.0 + y: 0.000438169789138 + z: 0.0 + w: 0.999999904004 + covariance: [15.923212680117791, -2.741551551352535e-07, 0.0, 0.0, -0.00046239252707326817, 0.0, -2.741551551352535e-07, 15.92321158202501, 0.0, 0.0, 4.833088641004912e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00046239252707326795, 4.8330886410049134e-05, 0.0, 0.0, 15.819529721629205, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 38 + stamp: + secs: 1624875195 + nsecs: 719072104 + frame_id: "/world" +pose: + pose: + position: + x: 0.143341677066 + y: 0.0172740598609 + z: 0.0 + orientation: + x: 0.0 + y: 0.000224591267408 + z: 0.0 + w: 0.999999974779 + covariance: [12.860688262042643, -1.1933845222506693e-07, 0.0, 0.0, -0.00019114928503589614, 0.0, -1.1933845222506693e-07, 12.860687781892347, 0.0, 0.0, 2.1405434259072677e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00019114928503589609, 2.140543425907269e-05, 0.0, 0.0, 12.815326309844025, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 39 + stamp: + secs: 1624875195 + nsecs: 799081087 + frame_id: "/world" +pose: + pose: + position: + x: 0.14353207764 + y: 0.0174389928946 + z: 0.0 + orientation: + x: 0.0 + y: 0.00070330755904 + z: 0.0 + w: 0.999999752679 + covariance: [15.202066579054204, -2.0887267119126797e-07, 0.0, 0.0, -0.0004424151665574836, 0.0, -2.0887267119126802e-07, 15.20206570232755, 0.0, 0.0, 3.875581374294658e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004424151665574836, 3.875581374294659e-05, 0.0, 0.0, 15.121504109270616, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 40 + stamp: + secs: 1624875195 + nsecs: 879076004 + frame_id: "/world" +pose: + pose: + position: + x: 0.146670272927 + y: 0.0107045652454 + z: 0.0 + orientation: + x: 0.0 + y: 0.000380539869486 + z: 0.0 + w: 0.999999927595 + covariance: [14.431701006178075, -2.1497967307642454e-07, 0.0, 0.0, -0.0005316951105715222, 0.0, -2.1497967307642457e-07, 14.431700068961634, 0.0, 0.0, 3.662213962975546e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005316951105715222, 3.6622139629755474e-05, 0.0, 0.0, 14.347598525158562, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 41 + stamp: + secs: 1624875195 + nsecs: 959115028 + frame_id: "/world" +pose: + pose: + position: + x: 0.14920209322 + y: 0.0136058659801 + z: 0.0 + orientation: + x: -0.0 + y: -0.000428230986806 + z: -0.0 + w: 0.999999908309 + covariance: [14.038913481019597, -2.2454647634295275e-07, 0.0, 0.0, -0.0005572131352480672, 0.0, -2.2454647634295282e-07, 14.038912467664078, 0.0, 0.0, 3.18887320401775e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005572131352480672, 3.1888732040177516e-05, 0.0, 0.0, 13.949752630931266, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 42 + stamp: + secs: 1624875196 + nsecs: 39123058 + frame_id: "/world" +pose: + pose: + position: + x: 0.144082229624 + y: 0.0168413207326 + z: 0.0 + orientation: + x: 0.0 + y: 0.000717558851491 + z: 0.0 + w: 0.999999742555 + covariance: [16.058091546489273, -3.1606365622028067e-07, 0.0, 0.0, -0.0007235687289401172, 0.0, -3.160636562202809e-07, 16.0580900732218, 0.0, 0.0, 3.994852342311296e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007235687289401173, 3.9948523423112976e-05, 0.0, 0.0, 15.930966005076563, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 43 + stamp: + secs: 1624875196 + nsecs: 119092941 + frame_id: "/world" +pose: + pose: + position: + x: 0.139326615318 + y: 0.0198317446396 + z: 0.0 + orientation: + x: 0.0 + y: 0.00199561467528 + z: 0.0 + w: 0.999998008759 + covariance: [17.467884848420596, -3.952930781774462e-07, 0.0, 0.0, -0.0007633068010739801, 0.0, -3.952930781774464e-07, 17.467882985993025, 0.0, 0.0, 0.00010359489904426507, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007633068010739802, 0.00010359489904426506, 0.0, 0.0, 17.308724919883417, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 44 + stamp: + secs: 1624875196 + nsecs: 199114084 + frame_id: "/world" +pose: + pose: + position: + x: 0.13952550793 + y: 0.0198845923684 + z: 0.0 + orientation: + x: 0.0 + y: 0.00204794269602 + z: 0.0 + w: 0.999997902963 + covariance: [18.439726576033575, -4.986633553552704e-07, 0.0, 0.0, -0.0009147705309012214, 0.0, -4.986633553552708e-07, 18.439724223182616, 0.0, 0.0, 0.00020270710324363472, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009147705309012214, 0.00020270710324363477, 0.0, 0.0, 18.239838067424422, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 45 + stamp: + secs: 1624875196 + nsecs: 279119015 + frame_id: "/world" +pose: + pose: + position: + x: 0.139707603414 + y: 0.0200213585105 + z: 0.0 + orientation: + x: 0.0 + y: 0.00136595863608 + z: 0.0 + w: 0.999999067078 + covariance: [19.091298585670543, -5.876256001825093e-07, 0.0, 0.0, -0.0011410945491818767, 0.0, -5.876256001825097e-07, 19.091295801612027, 0.0, 0.0, 0.00025092394933717886, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011410945491818769, 0.0002509239493371789, 0.0, 0.0, 18.85736887489047, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 46 + stamp: + secs: 1624875196 + nsecs: 359162092 + frame_id: "/world" +pose: + pose: + position: + x: 0.139887987632 + y: 0.0201511016678 + z: 0.0 + orientation: + x: 0.0 + y: 0.000999115940855 + z: 0.0 + w: 0.999999500884 + covariance: [19.523517897021115, -6.605494005611074e-07, 0.0, 0.0, -0.0012489939951052802, 0.0, -6.605494005611077e-07, 19.523514755748078, 0.0, 0.0, 0.0002661802417557854, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0012489939951052806, 0.00026618024175578545, 0.0, 0.0, 19.262155712364446, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 47 + stamp: + secs: 1624875196 + nsecs: 439135075 + frame_id: "/world" +pose: + pose: + position: + x: 0.140037745192 + y: 0.0202586944643 + z: 0.0 + orientation: + x: 0.0 + y: 0.000661512925184 + z: 0.0 + w: 0.9999997812 + covariance: [16.533660365674166, -4.979519512436703e-07, 0.0, 0.0, -0.0008499581130913744, 0.0, -4.979519512436703e-07, 16.533657992123327, 0.0, 0.0, 0.0001803588036703954, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000849958113091374, 0.0001803588036703954, 0.0, 0.0, 16.33560569564781, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 48 + stamp: + secs: 1624875196 + nsecs: 519134998 + frame_id: "/world" +pose: + pose: + position: + x: 0.140226081868 + y: 0.0203575050588 + z: 0.0 + orientation: + x: 0.0 + y: 0.000922251193892 + z: 0.0 + w: 0.999999574726 + covariance: [17.826293724994162, -6.078119842687434e-07, 0.0, 0.0, -0.0008690414369380767, 0.0, -6.078119842687435e-07, 17.826290824146437, 0.0, 0.0, 0.00018754007921662361, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008690414369380764, 0.00018754007921662361, 0.0, 0.0, 17.584277635608522, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 49 + stamp: + secs: 1624875196 + nsecs: 599162102 + frame_id: "/world" +pose: + pose: + position: + x: 0.140407228226 + y: 0.0204837717124 + z: 0.0 + orientation: + x: 0.0 + y: 0.00125888264072 + z: 0.0 + w: 0.999999207607 + covariance: [18.700467673194723, -6.915965121453265e-07, 0.0, 0.0, -0.0008684985095493674, 0.0, -6.915965121453266e-07, 18.700464367954186, 0.0, 0.0, 0.0001807869998388871, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008684985095493673, 0.0001807869998388871, 0.0, 0.0, 18.423957994958453, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 50 + stamp: + secs: 1624875196 + nsecs: 679157019 + frame_id: "/world" +pose: + pose: + position: + x: 0.140583254706 + y: 0.0206027267884 + z: 0.0 + orientation: + x: 0.0 + y: 0.00151443092167 + z: 0.0 + w: 0.999998853249 + covariance: [19.279179205722286, -7.457009737905874e-07, 0.0, 0.0, -0.000841424757964681, 0.0, -7.457009737905877e-07, 19.27917563522086, 0.0, 0.0, 0.00016349958328449064, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008414247579646807, 0.00016349958328449061, 0.0, 0.0, 18.979042502063347, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 51 + stamp: + secs: 1624875196 + nsecs: 759172916 + frame_id: "/world" +pose: + pose: + position: + x: 0.140786776954 + y: 0.0207406176665 + z: 0.0 + orientation: + x: 0.0 + y: 0.000959624898986 + z: 0.0 + w: 0.99999953956 + covariance: [19.68298297510194, -8.3834072684779e-07, 0.0, 0.0, -0.0007964582157048356, 0.0, -8.383407268477903e-07, 19.682978955568043, 0.0, 0.0, 0.00015066792184781664, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007964582157048354, 0.00015066792184781661, 0.0, 0.0, 19.340727552084306, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 52 + stamp: + secs: 1624875196 + nsecs: 839164019 + frame_id: "/world" +pose: + pose: + position: + x: 0.140947994582 + y: 0.0208486786768 + z: 0.0 + orientation: + x: -0.0 + y: -0.000120712371078 + z: -0.0 + w: 0.999999992714 + covariance: [19.917912954718776, -8.291545340631593e-07, 0.0, 0.0, -0.0007066290086477547, 0.0, -8.291545340631598e-07, 19.917908979234966, 0.0, 0.0, 0.00014538395146126328, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007066290086477547, 0.0001453839514612633, 0.0, 0.0, 19.575672262973608, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 53 + stamp: + secs: 1624875196 + nsecs: 919202089 + frame_id: "/world" +pose: + pose: + position: + x: 0.141107047099 + y: 0.0209538851665 + z: 0.0 + orientation: + x: -0.0 + y: -0.000736401992221 + z: -0.0 + w: 0.999999728856 + covariance: [20.06858349721397, -8.176886577947344e-07, 0.0, 0.0, -0.0006357201047859182, 0.0, -8.176886577947349e-07, 20.06857957950005, 0.0, 0.0, 0.0001473125375187703, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006357201047859181, 0.00014731253751877033, 0.0, 0.0, 19.7275453021173, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 54 + stamp: + secs: 1624875196 + nsecs: 999176979 + frame_id: "/world" +pose: + pose: + position: + x: 0.141266142782 + y: 0.0210592860901 + z: 0.0 + orientation: + x: -0.0 + y: -0.000715708263153 + z: -0.0 + w: 0.999999743881 + covariance: [20.165408486877897, -8.053279113955774e-07, 0.0, 0.0, -0.0005471150894265668, 0.0, -8.053279113955776e-07, 20.165404629895736, 0.0, 0.0, 0.00013294675078253927, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005471150894265666, 0.00013294675078253927, 0.0, 0.0, 19.825245545039923, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 55 + stamp: + secs: 1624875197 + nsecs: 79178095 + frame_id: "/world" +pose: + pose: + position: + x: 0.14142428373 + y: 0.0211638210578 + z: 0.0 + orientation: + x: -0.0 + y: -0.000353548246362 + z: -0.0 + w: 0.999999937502 + covariance: [20.227672292280456, -7.932845574122855e-07, 0.0, 0.0, -0.0004728082189797432, 0.0, -7.932845574122861e-07, 20.227668495607926, 0.0, 0.0, 0.0001267920636793975, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004728082189797431, 0.00012679206367939748, 0.0, 0.0, 19.887989013538697, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 56 + stamp: + secs: 1624875197 + nsecs: 159200907 + frame_id: "/world" +pose: + pose: + position: + x: 0.141594741206 + y: 0.0212753506445 + z: 0.0 + orientation: + x: -0.0 + y: -6.76449389378e-05 + z: -0.0 + w: 0.999999997712 + covariance: [20.28128806878443, -8.130048304096402e-07, 0.0, 0.0, -0.0004521442336915954, 0.0, -8.130048304096411e-07, 20.281284186131984, 0.0, 0.0, 0.00015644666486459326, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004521442336915952, 0.0001564466648645932, 0.0, 0.0, 19.9282464029608, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 57 + stamp: + secs: 1624875197 + nsecs: 239206076 + frame_id: "/world" +pose: + pose: + position: + x: 0.141757922801 + y: 0.0213821728233 + z: 0.0 + orientation: + x: 0.0 + y: 0.000100234296303 + z: 0.0 + w: 0.999999994977 + covariance: [20.318488430962933, -8.305005835321762e-07, 0.0, 0.0, -0.00047323493888882536, 0.0, -8.305005835321772e-07, 20.318484490667295, 0.0, 0.0, 0.0002645001342582306, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00047323493888882514, 0.0002645001342582306, 0.0, 0.0, 19.954056956637363, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 58 + stamp: + secs: 1624875197 + nsecs: 319202900 + frame_id: "/world" +pose: + pose: + position: + x: 0.141885753279 + y: 0.0214638379438 + z: 0.0 + orientation: + x: -0.0 + y: -0.000105138157686 + z: -0.0 + w: 0.999999994473 + covariance: [20.31855932608583, -7.907370504615866e-07, 0.0, 0.0, -0.0005286214312372513, 0.0, -7.907370504615875e-07, 20.318555620812315, 0.0, 0.0, 0.0003846592589271845, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005286214312372512, 0.00038465925892718447, 0.0, 0.0, 19.97060307224003, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 59 + stamp: + secs: 1624875197 + nsecs: 399205923 + frame_id: "/world" +pose: + pose: + position: + x: 0.142049518958 + y: 0.0215638838068 + z: 0.0 + orientation: + x: -0.0 + y: -0.000629823219446 + z: -0.0 + w: 0.999999801661 + covariance: [20.358369335834745, -8.616529964809776e-07, 0.0, 0.0, -0.0006788210205087805, 0.0, -8.616529964809783e-07, 20.358365395167198, 0.0, 0.0, 0.0005369916770487256, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006788210205087806, 0.0005369916770487255, 0.0, 0.0, 19.98130103917718, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 60 + stamp: + secs: 1624875197 + nsecs: 479234934 + frame_id: "/world" +pose: + pose: + position: + x: 0.142190503903 + y: 0.0216459835056 + z: 0.0 + orientation: + x: -0.0 + y: -0.00107641820801 + z: -0.0 + w: 0.999999420662 + covariance: [20.367806244239233, -8.734268459692813e-07, 0.0, 0.0, -0.000753518235739007, 0.0, -8.734268459692821e-07, 20.367802340598757, 0.0, 0.0, 0.0005784198370693017, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000753518235739007, 0.0005784198370693016, 0.0, 0.0, 19.988461444487548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 61 + stamp: + secs: 1624875197 + nsecs: 559230089 + frame_id: "/world" +pose: + pose: + position: + x: 0.142322909546 + y: 0.0217199394621 + z: 0.0 + orientation: + x: -0.0 + y: -0.00131297481155 + z: -0.0 + w: 0.999999138048 + covariance: [20.36701957027534, -8.673118416178904e-07, 0.0, 0.0, -0.0007722214911405818, 0.0, -8.673118416178912e-07, 20.367015777216455, 0.0, 0.0, 0.0005611447942552138, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007722214911405816, 0.0005611447942552135, 0.0, 0.0, 19.992903013618772, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 62 + stamp: + secs: 1624875197 + nsecs: 639235020 + frame_id: "/world" +pose: + pose: + position: + x: 0.142451625064 + y: 0.0217917332905 + z: 0.0 + orientation: + x: -0.0 + y: -0.00105127595096 + z: -0.0 + w: 0.999999447409 + covariance: [20.36216942499042, -8.517444533814034e-07, 0.0, 0.0, -0.0007175647258071141, 0.0, -8.517444533814038e-07, 20.362165766160654, 0.0, 0.0, 0.0005026144805265393, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000717564725807114, 0.0005026144805265392, 0.0, 0.0, 19.995507103665037, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 63 + stamp: + secs: 1624875197 + nsecs: 719242096 + frame_id: "/world" +pose: + pose: + position: + x: 0.142571663678 + y: 0.0218588780235 + z: 0.0 + orientation: + x: -0.0 + y: -0.000645311738444 + z: -0.0 + w: 0.999999791786 + covariance: [20.34987289751099, -8.189060578965417e-07, 0.0, 0.0, -0.0006278500928641375, 0.0, -8.189060578965421e-07, 20.34986943316976, 0.0, 0.0, 0.0004377728798368377, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006278500928641374, 0.0004377728798368376, 0.0, 0.0, 19.997101054204084, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 64 + stamp: + secs: 1624875197 + nsecs: 799248934 + frame_id: "/world" +pose: + pose: + position: + x: 0.142688849732 + y: 0.0219248698359 + z: 0.0 + orientation: + x: -0.0 + y: -0.000280792392206 + z: -0.0 + w: 0.999999960578 + covariance: [20.341124545621714, -7.96310661401607e-07, 0.0, 0.0, -0.0005577252295113297, 0.0, -7.963106614016076e-07, 20.34112123351684, 0.0, 0.0, 0.00042234935121777793, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005577252295113294, 0.00042234935121777777, 0.0, 0.0, 19.998088273231176, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 65 + stamp: + secs: 1624875197 + nsecs: 879255056 + frame_id: "/world" +pose: + pose: + position: + x: 0.142793076844 + y: 0.0219887265856 + z: 0.0 + orientation: + x: -0.0 + y: -0.000224043332258 + z: -0.0 + w: 0.999999974902 + covariance: [20.33489782431552, -7.861004940141888e-07, 0.0, 0.0, -0.0005118636245879254, 0.0, -7.861004940141894e-07, 20.33489464523732, 0.0, 0.0, 0.0005830942323055184, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005118636245879253, 0.0005830942323055183, 0.0, 0.0, 19.998861023595147, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 66 + stamp: + secs: 1624875197 + nsecs: 959276915 + frame_id: "/world" +pose: + pose: + position: + x: 0.142900331804 + y: 0.0220587522923 + z: 0.0 + orientation: + x: -0.0 + y: -0.000740923061719 + z: -0.0 + w: 0.999999725516 + covariance: [20.350226117329473, -8.333193308432022e-07, 0.0, 0.0, -0.0005192153474078675, 0.0, -8.333193308432027e-07, 20.350222893297303, 0.0, 0.0, 0.0008200331606486834, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005192153474078673, 0.0008200331606486831, 0.0, 0.0, 19.999716574405923, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 67 + stamp: + secs: 1624875198 + nsecs: 39307117 + frame_id: "/world" +pose: + pose: + position: + x: 0.143006468766 + y: 0.022125868666 + z: 0.0 + orientation: + x: -0.0 + y: -0.000970210638807 + z: -0.0 + w: 0.999999529346 + covariance: [20.36291538043386, -8.725479623433077e-07, 0.0, 0.0, -0.0005188517449850574, 0.0, -8.725479623433083e-07, 20.362912138303546, 0.0, 0.0, 0.0008873823144354131, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005188517449850573, 0.0008873823144354127, 0.0, 0.0, 19.99991289590822, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 68 + stamp: + secs: 1624875198 + nsecs: 119277000 + frame_id: "/world" +pose: + pose: + position: + x: 0.143047754079 + y: 0.0221518498366 + z: 0.0 + orientation: + x: -0.0 + y: -0.000555098603107 + z: -0.0 + w: 0.999999845933 + covariance: [20.28292523308736, -6.79334735246807e-07, 0.0, 0.0, -0.00039173198278479173, 0.0, -6.793347352468075e-07, 20.282922738108446, 0.0, 0.0, 0.0006800408290099104, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00039173198278479157, 0.0006800408290099102, 0.0, 0.0, 19.999888820804404, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 69 + stamp: + secs: 1624875198 + nsecs: 199289083 + frame_id: "/world" +pose: + pose: + position: + x: 0.14314235281 + y: 0.0222112887021 + z: 0.0 + orientation: + x: 0.0 + y: 7.35061802635e-05 + z: 0.0 + w: 0.999999997298 + covariance: [20.2935137438148, -7.079472860429985e-07, 0.0, 0.0, -0.0003614262141310263, 0.0, -7.07947286042999e-07, 20.293511227717723, 0.0, 0.0, 0.0006425054350370249, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00036142621413102615, 0.0006425054350370246, 0.0, 0.0, 19.999800219541292, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 70 + stamp: + secs: 1624875198 + nsecs: 279292107 + frame_id: "/world" +pose: + pose: + position: + x: 0.143235230776 + y: 0.0222703422694 + z: 0.0 + orientation: + x: 0.0 + y: 0.000664175354051 + z: 0.0 + w: 0.999999779436 + covariance: [20.302983224378547, -7.315285352248396e-07, 0.0, 0.0, -0.00032523364683389067, 0.0, -7.315285352248401e-07, 20.302980699171652, 0.0, 0.0, 0.0006036385673005004, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003252336468338906, 0.0006036385673005002, 0.0, 0.0, 19.999924522135384, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 71 + stamp: + secs: 1624875198 + nsecs: 359307051 + frame_id: "/world" +pose: + pose: + position: + x: 0.143323933658 + y: 0.0223279709658 + z: 0.0 + orientation: + x: 0.0 + y: 0.000948688613795 + z: 0.0 + w: 0.999999549995 + covariance: [20.308833819192348, -7.444235801270228e-07, 0.0, 0.0, -0.00028376405270847305, 0.0, -7.444235801270234e-07, 20.308831314932092, 0.0, 0.0, 0.0005682152508496066, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000283764052708473, 0.0005682152508496064, 0.0, 0.0, 20.000073850339614, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 72 + stamp: + secs: 1624875198 + nsecs: 439341068 + frame_id: "/world" +pose: + pose: + position: + x: 0.143411465918 + y: 0.0223857061656 + z: 0.0 + orientation: + x: 0.0 + y: 0.000837314373215 + z: 0.0 + w: 0.999999649452 + covariance: [20.314229396100586, -7.539933640705781e-07, 0.0, 0.0, -0.00023982258255056613, 0.0, -7.539933640705786e-07, 20.31422691499952, 0.0, 0.0, 0.0005241687662868368, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00023982258255056613, 0.0005241687662868367, 0.0, 0.0, 20.00008596997165, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 73 + stamp: + secs: 1624875198 + nsecs: 519325018 + frame_id: "/world" +pose: + pose: + position: + x: 0.143496210896 + y: 0.0224434667567 + z: 0.0 + orientation: + x: 0.0 + y: 0.000664026573213 + z: 0.0 + w: 0.999999779534 + covariance: [20.319555693571086, -7.619935731798487e-07, 0.0, 0.0, -0.00020095955058760563, 0.0, -7.619935731798491e-07, 20.31955323644494, 0.0, 0.0, 0.0005089743705799907, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00020095955058760566, 0.0005089743705799906, 0.0, 0.0, 20.000126516201448, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 74 + stamp: + secs: 1624875198 + nsecs: 599320889 + frame_id: "/world" +pose: + pose: + position: + x: 0.143577493004 + y: 0.0225008440471 + z: 0.0 + orientation: + x: 0.0 + y: 0.000630998815394 + z: 0.0 + w: 0.99999980092 + covariance: [20.324101840368563, -7.669170633226726e-07, 0.0, 0.0, -0.0001686965467288735, 0.0, -7.669170633226732e-07, 20.32409941318292, 0.0, 0.0, 0.0005060442686293259, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00016869654672887354, 0.0005060442686293258, 0.0, 0.0, 20.000177737584465, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 75 + stamp: + secs: 1624875198 + nsecs: 679327011 + frame_id: "/world" +pose: + pose: + position: + x: 0.143657896801 + y: 0.0225576892355 + z: 0.0 + orientation: + x: 0.0 + y: 0.000590281761934 + z: 0.0 + w: 0.999999825784 + covariance: [20.32828028464122, -7.69615317552232e-07, 0.0, 0.0, -0.00014645793606303973, 0.0, -7.696153175522325e-07, 20.32827788743366, 0.0, 0.0, 0.000477053252916665, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00014645793606303973, 0.000477053252916665, 0.0, 0.0, 20.00017891990006, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 76 + stamp: + secs: 1624875198 + nsecs: 759337902 + frame_id: "/world" +pose: + pose: + position: + x: 0.143754612422 + y: 0.0226268839057 + z: 0.0 + orientation: + x: 0.0 + y: 0.000564916960703 + z: 0.0 + w: 0.999999840434 + covariance: [20.361066318191718, -8.356014061968462e-07, 0.0, 0.0, -0.0001176395451562261, 0.0, -8.356014061968467e-07, 20.36106375448946, 0.0, 0.0, 0.0004541630641877266, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00011763954515622609, 0.0004541630641877266, 0.0, 0.0, 20.000202812611093, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 77 + stamp: + secs: 1624875198 + nsecs: 839340925 + frame_id: "/world" +pose: + pose: + position: + x: 0.143834701164 + y: 0.0226849845262 + z: 0.0 + orientation: + x: 0.0 + y: 0.000533222734573 + z: 0.0 + w: 0.999999857837 + covariance: [20.3592225033623, -8.206716051496224e-07, 0.0, 0.0, -8.260524684840447e-05, 0.0, -8.206716051496228e-07, 20.359220009245007, 0.0, 0.0, 0.0003906988256370396, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.260524684840446e-05, 0.00039069882563703967, 0.0, 0.0, 20.000214836540547, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 78 + stamp: + secs: 1624875198 + nsecs: 919356108 + frame_id: "/world" +pose: + pose: + position: + x: 0.143926323399 + y: 0.0227512540892 + z: 0.0 + orientation: + x: 0.0 + y: 0.000553968229217 + z: 0.0 + w: 0.99999984656 + covariance: [20.37967933711851, -8.545160280897374e-07, 0.0, 0.0, -6.292732656093559e-05, 0.0, -8.545160280897377e-07, 20.379676763692263, 0.0, 0.0, 0.0003425974117212289, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.292732656093556e-05, 0.0003425974117212288, 0.0, 0.0, 20.00023766467564, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 79 + stamp: + secs: 1624875198 + nsecs: 999368906 + frame_id: "/world" +pose: + pose: + position: + x: 0.144017384225 + y: 0.0228173805027 + z: 0.0 + orientation: + x: 0.0 + y: 0.000623743366926 + z: 0.0 + w: 0.999999805472 + covariance: [20.39671755568844, -8.789709215831281e-07, 0.0, 0.0, -4.688774330701036e-05, 0.0, -8.789709215831286e-07, 20.39671492765556, 0.0, 0.0, 0.00029673148818289136, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.6887743307010344e-05, 0.00029673148818289136, 0.0, 0.0, 20.000320013731834, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 80 + stamp: + secs: 1624875199 + nsecs: 79366922 + frame_id: "/world" +pose: + pose: + position: + x: 0.144090699598 + y: 0.0228698908812 + z: 0.0 + orientation: + x: 0.0 + y: 0.000685648223919 + z: 0.0 + w: 0.999999764943 + covariance: [20.37866153408463, -8.276995283889596e-07, 0.0, 0.0, -5.335144749536147e-05, 0.0, -8.276995283889601e-07, 20.378659072374326, 0.0, 0.0, 0.00024923652980300747, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.335144749536144e-05, 0.00024923652980300747, 0.0, 0.0, 20.00038724806373, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 81 + stamp: + secs: 1624875199 + nsecs: 159377098 + frame_id: "/world" +pose: + pose: + position: + x: 0.144173239643 + y: 0.0229279310786 + z: 0.0 + orientation: + x: 0.0 + y: 0.000632426822125 + z: 0.0 + w: 0.999999800018 + covariance: [20.38348553249298, -8.257557065149534e-07, 0.0, 0.0, -7.338298447920312e-05, 0.0, -8.257557065149539e-07, 20.383483089967083, 0.0, 0.0, 0.00021924395496224398, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.338298447920311e-05, 0.00021924395496224395, 0.0, 0.0, 20.00027828356472, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 82 + stamp: + secs: 1624875199 + nsecs: 239401102 + frame_id: "/world" +pose: + pose: + position: + x: 0.14425336991 + y: 0.0229832314532 + z: 0.0 + orientation: + x: 0.0 + y: 0.000659002414231 + z: 0.0 + w: 0.999999782858 + covariance: [20.383477448338375, -8.133858008411231e-07, 0.0, 0.0, -9.392154114910258e-05, 0.0, -8.133858008411234e-07, 20.383475053046514, 0.0, 0.0, 0.00018647890533262756, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.392154114910258e-05, 0.0001864789053326275, 0.0, 0.0, 20.00045605378125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 83 + stamp: + secs: 1624875199 + nsecs: 319385052 + frame_id: "/world" +pose: + pose: + position: + x: 0.141909054139 + y: 0.0495358066692 + z: 0.0 + orientation: + x: 0.0 + y: 0.000555859648123 + z: 0.0 + w: 0.99999984551 + covariance: [16.95057869599822, -5.898166458347048e-07, 0.0, 0.0, -8.399647319616842e-05, 0.0, -5.898166458347049e-07, 16.95057696620987, 0.0, 0.0, 0.00011821696428369132, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.399647319616843e-05, 0.0001182169642836913, 0.0, 0.0, 16.666908443257825, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 84 + stamp: + secs: 1624875199 + nsecs: 399395943 + frame_id: "/world" +pose: + pose: + position: + x: 0.136716080555 + y: 0.0506369886303 + z: 0.0 + orientation: + x: 0.0 + y: 0.000722263912807 + z: 0.0 + w: 0.999999739167 + covariance: [18.137664388385783, -6.748234341930772e-07, 0.0, 0.0, -0.0002753889822473472, 0.0, -6.748234341930774e-07, 18.13766241754715, 0.0, 0.0, 0.00013386184047531303, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00027538898224734715, 0.000133861840475313, 0.0, 0.0, 17.809335818804918, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 85 + stamp: + secs: 1624875199 + nsecs: 479382038 + frame_id: "/world" +pose: + pose: + position: + x: 0.136778762808 + y: 0.0507476970571 + z: 0.0 + orientation: + x: 0.0 + y: 0.00135618767375 + z: 0.0 + w: 0.999999080377 + covariance: [18.935434551390905, -7.365456441090824e-07, 0.0, 0.0, -0.0005077408016643635, 0.0, -7.365456441090829e-07, 18.935432401570843, 0.0, 0.0, 0.0001610613648677671, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005077408016643635, 0.00016106136486776704, 0.0, 0.0, 18.57351218602324, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 86 + stamp: + secs: 1624875199 + nsecs: 559417963 + frame_id: "/world" +pose: + pose: + position: + x: 0.136822723178 + y: 0.0508833219849 + z: 0.0 + orientation: + x: 0.0 + y: 0.000938055702979 + z: 0.0 + w: 0.999999560026 + covariance: [19.450792719680763, -7.53727295154971e-07, 0.0, 0.0, -0.000577371670883137, 0.0, -7.537272951549714e-07, 19.450790518637092, 0.0, 0.0, 0.00017103977813274446, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000577371670883137, 0.00017103977813274446, 0.0, 0.0, 19.07625559751021, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 87 + stamp: + secs: 1624875199 + nsecs: 639408112 + frame_id: "/world" +pose: + pose: + position: + x: 0.136872936301 + y: 0.0510384230948 + z: 0.0 + orientation: + x: 0.0 + y: 0.000601856820511 + z: 0.0 + w: 0.999999818884 + covariance: [19.809919088780774, -8.067133398834359e-07, 0.0, 0.0, -0.0006001632559252081, 0.0, -8.067133398834366e-07, 19.809916730194875, 0.0, 0.0, 0.00017231537923247193, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006001632559252082, 0.00017231537923247193, 0.0, 0.0, 19.404691388899124, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 88 + stamp: + secs: 1624875199 + nsecs: 719436884 + frame_id: "/world" +pose: + pose: + position: + x: 0.132887213177 + y: 0.0470177234791 + z: 0.0 + orientation: + x: 0.0 + y: 0.000627512079701 + z: 0.0 + w: 0.999999803114 + covariance: [20.069610286791267, -8.885753582303269e-07, 0.0, 0.0, -0.0005851457632625704, 0.0, -8.885753582303276e-07, 20.069607685629272, 0.0, 0.0, 0.00016984415956720938, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005851457632625704, 0.00016984415956720935, 0.0, 0.0, 19.617310685326085, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 89 + stamp: + secs: 1624875199 + nsecs: 799429893 + frame_id: "/world" +pose: + pose: + position: + x: 0.132562062672 + y: 0.0520253851008 + z: 0.0 + orientation: + x: 0.0 + y: 0.00407400486071 + z: 0.0 + w: 0.999991701208 + covariance: [20.23380959857869, -9.294569341386509e-07, 0.0, 0.0, -0.0005452496681331392, 0.0, -9.294569341386513e-07, 20.233806875250462, 0.0, 0.0, 0.00016415063795676012, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005452496681331392, 0.0001641506379567601, 0.0, 0.0, 19.754427500391532, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 90 + stamp: + secs: 1624875199 + nsecs: 879475117 + frame_id: "/world" +pose: + pose: + position: + x: 0.121547632064 + y: 0.0509946755823 + z: 0.0 + orientation: + x: 0.0 + y: 0.00318364158447 + z: 0.0 + w: 0.9999949322 + covariance: [20.37631917098131, -1.0212608759918213e-06, 0.0, 0.0, -0.0005539397117804976, 0.0, -1.0212608759918217e-06, 20.376316179883293, 0.0, 0.0, 0.0002018382607891089, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005539397117804976, 0.00020183826078910887, 0.0, 0.0, 19.84267822117244, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 91 + stamp: + secs: 1624875199 + nsecs: 959450006 + frame_id: "/world" +pose: + pose: + position: + x: 0.12158075261 + y: 0.0509715981335 + z: 0.0 + orientation: + x: 0.0 + y: 0.00227346912016 + z: 0.0 + w: 0.999997415666 + covariance: [20.41799497305208, -9.82270426879905e-07, 0.0, 0.0, -0.0005228471120172287, 0.0, -9.822704268799054e-07, 20.417992099959818, 0.0, 0.0, 0.00021828156546889178, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005228471120172286, 0.00021828156546889178, 0.0, 0.0, 19.899557739403164, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 92 + stamp: + secs: 1624875200 + nsecs: 39455891 + frame_id: "/world" +pose: + pose: + position: + x: 0.121547976497 + y: 0.0511037800197 + z: 0.0 + orientation: + x: 0.0 + y: 0.00196052138408 + z: 0.0 + w: 0.999998078176 + covariance: [20.442306513511518, -9.493325045360411e-07, 0.0, 0.0, -0.0004925604820264288, 0.0, -9.493325045360413e-07, 20.442303740387263, 0.0, 0.0, 0.00021737921281768095, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004925604820264286, 0.00021737921281768092, 0.0, 0.0, 19.936237442945394, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 93 + stamp: + secs: 1624875200 + nsecs: 119455099 + frame_id: "/world" +pose: + pose: + position: + x: 0.121515012847 + y: 0.0512354170601 + z: 0.0 + orientation: + x: 0.0 + y: 0.00162574104812 + z: 0.0 + w: 0.999998678482 + covariance: [20.456379704349164, -9.214570249253112e-07, 0.0, 0.0, -0.00044642246865207226, 0.0, -9.214570249253114e-07, 20.456377016140028, 0.0, 0.0, 0.00020413876628912943, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004464224686520721, 0.0002041387662891294, 0.0, 0.0, 19.959382592198143, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 94 + stamp: + secs: 1624875200 + nsecs: 199474096 + frame_id: "/world" +pose: + pose: + position: + x: 0.121478211388 + y: 0.0513811820333 + z: 0.0 + orientation: + x: 0.0 + y: 0.00135395360797 + z: 0.0 + w: 0.999999083404 + covariance: [20.48651833413105, -9.372676546501918e-07, 0.0, 0.0, -0.0004116031073087455, 0.0, -9.372676546501919e-07, 20.486515603418432, 0.0, 0.0, 0.00019009258019696742, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004116031073087453, 0.00019009258019696745, 0.0, 0.0, 19.97444988044076, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 95 + stamp: + secs: 1624875200 + nsecs: 279485941 + frame_id: "/world" +pose: + pose: + position: + x: 0.121448317916 + y: 0.0514987865547 + z: 0.0 + orientation: + x: 0.0 + y: 0.00112345450848 + z: 0.0 + w: 0.999999368925 + covariance: [20.46789104583358, -8.749523420403631e-07, 0.0, 0.0, -0.000353534113093661, 0.0, -8.749523420403631e-07, 20.467888498870906, 0.0, 0.0, 0.00016055136695435488, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00035353411309366076, 0.0001605513669543549, 0.0, 0.0, 19.983843439932297, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 96 + stamp: + secs: 1624875200 + nsecs: 359488964 + frame_id: "/world" +pose: + pose: + position: + x: 0.121413436452 + y: 0.0516361311299 + z: 0.0 + orientation: + x: 0.0 + y: 0.000837012034883 + z: 0.0 + w: 0.999999649705 + covariance: [20.482199009551895, -8.77100922394175e-07, 0.0, 0.0, -0.00031418219768844887, 0.0, -8.771009223941751e-07, 20.48219645855932, 0.0, 0.0, 0.0001373184018254589, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00031418219768844865, 0.00013731840182545894, 0.0, 0.0, 19.98971298834571, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 97 + stamp: + secs: 1624875200 + nsecs: 439486027 + frame_id: "/world" +pose: + pose: + position: + x: 0.121378148004 + y: 0.0517697730301 + z: 0.0 + orientation: + x: 0.0 + y: 0.000888955512696 + z: 0.0 + w: 0.999999604879 + covariance: [20.493234367864176, -8.770178403814583e-07, 0.0, 0.0, -0.0003270221443344637, 0.0, -8.770178403814584e-07, 20.493231818637675, 0.0, 0.0, 0.00012299771878578416, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00032702214433446354, 0.00012299771878578416, 0.0, 0.0, 19.994018061104093, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 98 + stamp: + secs: 1624875200 + nsecs: 519515038 + frame_id: "/world" +pose: + pose: + position: + x: 0.121341750968 + y: 0.0518991242364 + z: 0.0 + orientation: + x: 0.0 + y: 0.00117934041324 + z: 0.0 + w: 0.999999304578 + covariance: [20.50215575021878, -8.757902551106705e-07, 0.0, 0.0, -0.0003656689730582504, 0.0, -8.757902551106706e-07, 20.50215320562888, 0.0, 0.0, 0.00012297359509308873, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003656689730582504, 0.00012297359509308873, 0.0, 0.0, 19.996767288196896, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 99 + stamp: + secs: 1624875200 + nsecs: 599533081 + frame_id: "/world" +pose: + pose: + position: + x: 0.121304589169 + y: 0.0520275664187 + z: 0.0 + orientation: + x: 0.0 + y: 0.00125222446583 + z: 0.0 + w: 0.999999215967 + covariance: [20.50938035416286, -8.728256964963638e-07, 0.0, 0.0, -0.0003673074331506511, 0.0, -8.728256964963637e-07, 20.50937781969439, 0.0, 0.0, 0.00012540453762082302, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003673074331506511, 0.00012540453762082307, 0.0, 0.0, 19.99848201169108, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 100 + stamp: + secs: 1624875200 + nsecs: 679512978 + frame_id: "/world" +pose: + pose: + position: + x: 0.121267179299 + y: 0.0521558643234 + z: 0.0 + orientation: + x: 0.0 + y: 0.00127903445653 + z: 0.0 + w: 0.999999182035 + covariance: [20.5154822566628, -8.683666415819488e-07, 0.0, 0.0, -0.0003410433886378491, 0.0, -8.683666415819487e-07, 20.515479736687713, 0.0, 0.0, 0.00012116962595663264, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003410433886378491, 0.0001211696259566327, 0.0, 0.0, 19.999667355471157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 101 + stamp: + secs: 1624875200 + nsecs: 759515047 + frame_id: "/world" +pose: + pose: + position: + x: 0.121229878821 + y: 0.0522837048447 + z: 0.0 + orientation: + x: 0.0 + y: 0.00135517214142 + z: 0.0 + w: 0.999999081754 + covariance: [20.52022177075076, -8.617317548946696e-07, 0.0, 0.0, -0.00030210520404500837, 0.0, -8.617317548946697e-07, 20.52021927126484, 0.0, 0.0, 0.00011039216688662572, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003021052040450083, 0.00011039216688662577, 0.0, 0.0, 20.000561265631394, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 102 + stamp: + secs: 1624875200 + nsecs: 839543104 + frame_id: "/world" +pose: + pose: + position: + x: 0.121192525614 + y: 0.0524075971347 + z: 0.0 + orientation: + x: 0.0 + y: 0.00132556341149 + z: 0.0 + w: 0.99999912144 + covariance: [20.524637751702436, -8.549595344128645e-07, 0.0, 0.0, -0.0003226634400215518, 0.0, -8.549595344128647e-07, 20.5246352716741, 0.0, 0.0, 9.784118176448694e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00032266344002155164, 9.7841181764487e-05, 0.0, 0.0, 20.000862754511942, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 103 + stamp: + secs: 1624875200 + nsecs: 919538975 + frame_id: "/world" +pose: + pose: + position: + x: 0.121154158033 + y: 0.0525273777005 + z: 0.0 + orientation: + x: 0.0 + y: 0.0011614302884 + z: 0.0 + w: 0.99999932554 + covariance: [20.529019839311136, -8.486999516294216e-07, 0.0, 0.0, -0.00036384307942375477, 0.0, -8.486999516294215e-07, 20.529017376443072, 0.0, 0.0, 0.00010017497766786806, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00036384307942375466, 0.0001001749776678681, 0.0, 0.0, 20.000950695779736, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 104 + stamp: + secs: 1624875200 + nsecs: 999536991 + frame_id: "/world" +pose: + pose: + position: + x: 0.121116162924 + y: 0.0526428186384 + z: 0.0 + orientation: + x: 0.0 + y: 0.00116659700703 + z: 0.0 + w: 0.999999319525 + covariance: [20.526100369796236, -8.312887463841209e-07, 0.0, 0.0, -0.0003595310074937897, 0.0, -8.312887463841209e-07, 20.52609795739026, 0.0, 0.0, 0.0001043279769048286, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003595310074937896, 0.00010432797690482864, 0.0, 0.0, 20.001367829448714, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 105 + stamp: + secs: 1624875201 + nsecs: 79540968 + frame_id: "/world" +pose: + pose: + position: + x: 0.121071522212 + y: 0.0527780162248 + z: 0.0 + orientation: + x: 0.0 + y: 0.00142266406348 + z: 0.0 + w: 0.999998988013 + covariance: [20.56159165332065, -8.72141936784241e-07, 0.0, 0.0, -0.0003507361703321775, 0.0, -8.721419367842411e-07, 20.561589122174148, 0.0, 0.0, 0.00010585026492241899, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003507361703321773, 0.00010585026492241902, 0.0, 0.0, 20.001846078902247, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 106 + stamp: + secs: 1624875201 + nsecs: 159560919 + frame_id: "/world" +pose: + pose: + position: + x: 0.121036520622 + y: 0.0528761730428 + z: 0.0 + orientation: + x: 0.0 + y: 0.00110768681814 + z: 0.0 + w: 0.999999386515 + covariance: [20.532667544819827, -8.158066033953628e-07, 0.0, 0.0, -0.00039463553761946696, 0.0, -8.158066033953629e-07, 20.532665175161615, 0.0, 0.0, 0.00010117938872685844, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003946355376194668, 0.00010117938872685846, 0.0, 0.0, 20.001124009982018, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 107 + stamp: + secs: 1624875201 + nsecs: 239557981 + frame_id: "/world" +pose: + pose: + position: + x: 0.120994784894 + y: 0.0529852884194 + z: 0.0 + orientation: + x: 0.0 + y: 0.000532206997831 + z: 0.0 + w: 0.999999858378 + covariance: [20.545011197950508, -8.225992075702254e-07, 0.0, 0.0, -0.0004935555376261311, 0.0, -8.225992075702255e-07, 20.54500880236531, 0.0, 0.0, 0.00010256070166428799, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000493555537626131, 0.00010256070166428797, 0.0, 0.0, 20.000526962703912, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 108 + stamp: + secs: 1624875201 + nsecs: 319547892 + frame_id: "/world" +pose: + pose: + position: + x: 0.120951002602 + y: 0.0530870411698 + z: 0.0 + orientation: + x: -0.0 + y: -4.81469695837e-05 + z: -0.0 + w: 0.999999998841 + covariance: [20.55127633872474, -8.219017851504633e-07, 0.0, 0.0, -0.0005900040451021643, 0.0, -8.219017851504636e-07, 20.551273940299104, 0.0, 0.0, 0.0001410217484815958, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005900040451021641, 0.00014102174848159578, 0.0, 0.0, 20.000063578010177, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 109 + stamp: + secs: 1624875201 + nsecs: 399564028 + frame_id: "/world" +pose: + pose: + position: + x: 0.120904794305 + y: 0.0531818526263 + z: 0.0 + orientation: + x: -0.0 + y: -0.000532272429985 + z: -0.0 + w: 0.999999858343 + covariance: [20.554467418053747, -8.192996639125734e-07, 0.0, 0.0, -0.0006672691520352934, 0.0, -8.192996639125735e-07, 20.554465025119296, 0.0, 0.0, 0.00018679941431243362, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006672691520352933, 0.00018679941431243353, 0.0, 0.0, 19.99997668749489, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 110 + stamp: + secs: 1624875201 + nsecs: 479578972 + frame_id: "/world" +pose: + pose: + position: + x: 0.120860502577 + y: 0.0532700962768 + z: 0.0 + orientation: + x: -0.0 + y: -0.000835642008155 + z: -0.0 + w: 0.999999650851 + covariance: [20.548265554592305, -8.029738340131802e-07, 0.0, 0.0, -0.000689576697186586, 0.0, -8.029738340131802e-07, 20.54826320607622, 0.0, 0.0, 0.00019310537298939336, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006895766971865859, 0.00019310537298939325, 0.0, 0.0, 20.000094943631595, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 111 + stamp: + secs: 1624875201 + nsecs: 559628963 + frame_id: "/world" +pose: + pose: + position: + x: 0.120800517119 + y: 0.0533552033551 + z: 0.0 + orientation: + x: -0.0 + y: -0.00101413566837 + z: -0.0 + w: 0.999999485764 + covariance: [20.612620275701786, -8.961558304354472e-07, 0.0, 0.0, -0.0011867193733151463, 0.0, -8.961558304354471e-07, 20.612617617867826, 0.0, 0.0, 0.00023352005572317502, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001186719373315146, 0.0002335200557231749, 0.0, 0.0, 20.00016910104026, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 112 + stamp: + secs: 1624875201 + nsecs: 639638901 + frame_id: "/world" +pose: + pose: + position: + x: 0.120757561627 + y: 0.0533947797635 + z: 0.0 + orientation: + x: -0.0 + y: -0.000759796971543 + z: -0.0 + w: 0.999999711354 + covariance: [20.570095136835604, -8.372757651716205e-07, 0.0, 0.0, -0.001393147436312483, 0.0, -8.372757651716205e-07, 20.570092601557036, 0.0, 0.0, 0.000238794668343114, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001393147436312483, 0.00023879466834311386, 0.0, 0.0, 20.000154618675545, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 113 + stamp: + secs: 1624875201 + nsecs: 719597101 + frame_id: "/world" +pose: + pose: + position: + x: 0.120705508316 + y: 0.0534406832492 + z: 0.0 + orientation: + x: -0.0 + y: -0.000710009446878 + z: -0.0 + w: 0.999999747943 + covariance: [20.57388705168037, -8.489514176894268e-07, 0.0, 0.0, -0.0015051303769686869, 0.0, -8.489514176894265e-07, 20.573884419359366, 0.0, 0.0, 0.00025311531138204986, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0015051303769686867, 0.0002531153113820498, 0.0, 0.0, 20.00027953883724, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 114 + stamp: + secs: 1624875201 + nsecs: 799607038 + frame_id: "/world" +pose: + pose: + position: + x: 0.120635087141 + y: 0.0534850348489 + z: 0.0 + orientation: + x: -0.0 + y: -0.000764748241207 + z: -0.0 + w: 0.99999970758 + covariance: [20.662326632897262, -9.92233106084788e-07, 0.0, 0.0, -0.001894475078499878, 0.0, -9.922331060847878e-07, 20.662323424312877, 0.0, 0.0, 0.00027477676142650834, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0018944750784998777, 0.00027477676142650823, 0.0, 0.0, 20.000270464551342, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 115 + stamp: + secs: 1624875201 + nsecs: 879617929 + frame_id: "/world" +pose: + pose: + position: + x: 0.120578093289 + y: 0.0535055433088 + z: 0.0 + orientation: + x: -0.0 + y: -0.000969806829934 + z: -0.0 + w: 0.999999529737 + covariance: [20.66345678102275, -1.0029550041486276e-06, 0.0, 0.0, -0.001982857736368122, 0.0, -1.002955004148627e-06, 20.663453418920106, 0.0, 0.0, 0.0002697869382511768, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0019828577363681216, 0.00026978693825117667, 0.0, 0.0, 20.000847005930414, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 116 + stamp: + secs: 1624875201 + nsecs: 959651947 + frame_id: "/world" +pose: + pose: + position: + x: 0.120521149387 + y: 0.0535226410165 + z: 0.0 + orientation: + x: -0.0 + y: -0.00116346614288 + z: -0.0 + w: 0.999999323173 + covariance: [20.655815530361167, -1.000040908414131e-06, 0.0, 0.0, -0.00189815955235924, 0.0, -1.0000409084141304e-06, 20.6558120863413, 0.0, 0.0, 0.00026972090240210686, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00189815955235924, 0.0002697209024021068, 0.0, 0.0, 20.000827847679272, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 117 + stamp: + secs: 1624875202 + nsecs: 39701939 + frame_id: "/world" +pose: + pose: + position: + x: 0.120467120907 + y: 0.0535370255846 + z: 0.0 + orientation: + x: -0.0 + y: -0.000634369720018 + z: -0.0 + w: 0.999999798788 + covariance: [20.629973256905284, -9.673155271427665e-07, 0.0, 0.0, -0.0016931945529843609, 0.0, -9.673155271427654e-07, 20.629969863861174, 0.0, 0.0, 0.0002678295574150905, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001693194552984361, 0.00026782955741509046, 0.0, 0.0, 20.00024568910632, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 118 + stamp: + secs: 1624875202 + nsecs: 119643927 + frame_id: "/world" +pose: + pose: + position: + x: 0.120420262058 + y: 0.0535488962732 + z: 0.0 + orientation: + x: -0.0 + y: -0.000304718665135 + z: -0.0 + w: 0.999999953573 + covariance: [20.575842392362897, -8.877112845723594e-07, 0.0, 0.0, -0.001410264117944784, 0.0, -8.877112845723584e-07, 20.57583924194194, 0.0, 0.0, 0.0002486997209908747, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0014102641179447838, 0.0002486997209908747, 0.0, 0.0, 20.00025743316449, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 119 + stamp: + secs: 1624875202 + nsecs: 199664116 + frame_id: "/world" +pose: + pose: + position: + x: 0.120358251967 + y: 0.0535641751311 + z: 0.0 + orientation: + x: -0.0 + y: -0.000164725746143 + z: -0.0 + w: 0.999999986433 + covariance: [20.59645063015971, -9.234691100653328e-07, 0.0, 0.0, -0.0012553348841527674, 0.0, -9.234691100653319e-07, 20.5964473059016, 0.0, 0.0, 0.00024106008693532458, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0012553348841527674, 0.0002410600869353246, 0.0, 0.0, 20.000057268500715, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 120 + stamp: + secs: 1624875202 + nsecs: 279659033 + frame_id: "/world" +pose: + pose: + position: + x: 0.120303103064 + y: 0.0535736141478 + z: 0.0 + orientation: + x: -0.0 + y: -0.000347417288993 + z: -0.0 + w: 0.999999939651 + covariance: [20.584824280308, -9.056859323519149e-07, 0.0, 0.0, -0.0011166370057923702, 0.0, -9.056859323519143e-07, 20.584820981152653, 0.0, 0.0, 0.00021370878227058659, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011166370057923702, 0.00021370878227058667, 0.0, 0.0, 20.00039097358133, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 121 + stamp: + secs: 1624875202 + nsecs: 359657049 + frame_id: "/world" +pose: + pose: + position: + x: 0.120244801916 + y: 0.053577821311 + z: 0.0 + orientation: + x: -0.0 + y: -0.000747479852809 + z: -0.0 + w: 0.999999720637 + covariance: [20.58886987432295, -9.109353647788195e-07, 0.0, 0.0, -0.0010570717197718562, 0.0, -9.109353647788187e-07, 20.588866514334445, 0.0, 0.0, 0.0001880268862971448, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010570717197718562, 0.00018802688629714485, 0.0, 0.0, 20.000434624225903, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 122 + stamp: + secs: 1624875202 + nsecs: 439666033 + frame_id: "/world" +pose: + pose: + position: + x: 0.120188457786 + y: 0.0535779080094 + z: 0.0 + orientation: + x: -0.0 + y: -0.000589567480518 + z: -0.0 + w: 0.999999826205 + covariance: [20.581027766948495, -8.964714651582974e-07, 0.0, 0.0, -0.000992498995512358, 0.0, -8.964714651582965e-07, 20.581024427016676, 0.0, 0.0, 0.00017314750136592053, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000992498995512358, 0.00017314750136592056, 0.0, 0.0, 20.000290117678734, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 123 + stamp: + secs: 1624875202 + nsecs: 519676924 + frame_id: "/world" +pose: + pose: + position: + x: 0.120127361069 + y: 0.0535756275741 + z: 0.0 + orientation: + x: -0.0 + y: -0.00043014103218 + z: -0.0 + w: 0.999999907489 + covariance: [20.59116045090737, -9.086547511750554e-07, 0.0, 0.0, -0.0009342597521032428, 0.0, -9.086547511750548e-07, 20.591157036917558, 0.0, 0.0, 0.00016753728350060046, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009342597521032426, 0.00016753728350060043, 0.0, 0.0, 20.000257254404904, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 124 + stamp: + secs: 1624875202 + nsecs: 599704027 + frame_id: "/world" +pose: + pose: + position: + x: 0.120072774816 + y: 0.0535724348513 + z: 0.0 + orientation: + x: -0.0 + y: -0.000288826326278 + z: -0.0 + w: 0.99999995829 + covariance: [20.57375494368962, -8.763593549838349e-07, 0.0, 0.0, -0.0008285072766980759, 0.0, -8.763593549838343e-07, 20.573751629709996, 0.0, 0.0, 0.0001473236608327186, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008285072766980757, 0.00014732366083271856, 0.0, 0.0, 20.0001391218508, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 125 + stamp: + secs: 1624875202 + nsecs: 679709911 + frame_id: "/world" +pose: + pose: + position: + x: 0.120006081259 + y: 0.0535659910546 + z: 0.0 + orientation: + x: -0.0 + y: -6.38289664575e-05 + z: -0.0 + w: 0.999999997963 + covariance: [20.609868508361224, -9.237333871587829e-07, 0.0, 0.0, -0.0007911786291885359, 0.0, -9.237333871587821e-07, 20.609864990019098, 0.0, 0.0, 0.00013338325477278264, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007911786291885357, 0.00013338325477278256, 0.0, 0.0, 20.0000451033738, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 126 + stamp: + secs: 1624875202 + nsecs: 759694099 + frame_id: "/world" +pose: + pose: + position: + x: 0.119948241072 + y: 0.0535547745393 + z: 0.0 + orientation: + x: 0.0 + y: 0.000322980040157 + z: 0.0 + w: 0.999999947842 + covariance: [20.601764537953493, -9.032261256374164e-07, 0.0, 0.0, -0.0007720115681266761, 0.0, -9.032261256374153e-07, 20.60176107615262, 0.0, 0.0, 0.00011756490869710488, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000772011568126676, 0.00011756490869710483, 0.0, 0.0, 20.00003568862044, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 127 + stamp: + secs: 1624875202 + nsecs: 839711905 + frame_id: "/world" +pose: + pose: + position: + x: 0.119888416864 + y: 0.0535402290457 + z: 0.0 + orientation: + x: 0.0 + y: 0.000667256552082 + z: 0.0 + w: 0.999999777384 + covariance: [20.60060420859299, -8.929462970143382e-07, 0.0, 0.0, -0.0007440133841670558, 0.0, -8.92946297014337e-07, 20.600600767269015, 0.0, 0.0, 0.0001143278054704367, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007440133841670557, 0.00011432780547043666, 0.0, 0.0, 20.000122494343433, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 128 + stamp: + secs: 1624875202 + nsecs: 919713974 + frame_id: "/world" +pose: + pose: + position: + x: 0.119821180666 + y: 0.0535262360576 + z: 0.0 + orientation: + x: 0.0 + y: 0.000265580197239 + z: 0.0 + w: 0.999999964734 + covariance: [20.625546618950946, -9.198822948175844e-07, 0.0, 0.0, -0.0006687339434056996, 0.0, -9.198822948175833e-07, 20.625543062177414, 0.0, 0.0, 0.00012624118106263873, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006687339434056997, 0.0001262411810626387, 0.0, 0.0, 20.000012156067, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 129 + stamp: + secs: 1624875202 + nsecs: 999722004 + frame_id: "/world" +pose: + pose: + position: + x: 0.119758699192 + y: 0.0535132387019 + z: 0.0 + orientation: + x: -0.0 + y: -0.000120173040001 + z: -0.0 + w: 0.999999992779 + covariance: [20.62436231769586, -9.074161458298366e-07, 0.0, 0.0, -0.0005711213457310076, 0.0, -9.074161458298355e-07, 20.62435880182465, 0.0, 0.0, 0.00012762642053383092, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005711213457310076, 0.00012762642053383092, 0.0, 0.0, 20.000004635681705, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 130 + stamp: + secs: 1624875203 + nsecs: 79710960 + frame_id: "/world" +pose: + pose: + position: + x: 0.119701632688 + y: 0.0535010690024 + z: 0.0 + orientation: + x: -0.0 + y: -2.50620756476e-05 + z: -0.0 + w: 0.999999999686 + covariance: [20.60241544660692, -8.648368595850821e-07, 0.0, 0.0, -0.00047312066165260987, 0.0, -8.64836859585081e-07, 20.60241208982821, 0.0, 0.0, 0.0001155613275185968, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004731206616526098, 0.00011556132751859681, 0.0, 0.0, 20.00000070920627, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 131 + stamp: + secs: 1624875203 + nsecs: 159800053 + frame_id: "/world" +pose: + pose: + position: + x: 0.119634468878 + y: 0.0534867363233 + z: 0.0 + orientation: + x: 0.0 + y: 0.00020254045739 + z: 0.0 + w: 0.999999979489 + covariance: [20.62635896677506, -8.863190107921235e-07, 0.0, 0.0, -0.00040387299563251046, 0.0, -8.863190107921222e-07, 20.626355520552924, 0.0, 0.0, 0.00010512693218647135, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004038729956325103, 0.00010512693218647136, 0.0, 0.0, 20.000042920414554, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 132 + stamp: + secs: 1624875203 + nsecs: 239774942 + frame_id: "/world" +pose: + pose: + position: + x: 0.119576509395 + y: 0.05347476297 + z: 0.0 + orientation: + x: 0.0 + y: 0.000621422137744 + z: 0.0 + w: 0.999999806917 + covariance: [20.60910762023457, -8.497799600179792e-07, 0.0, 0.0, -0.00032110522113189076, 0.0, -8.49779960017978e-07, 20.60910431203065, 0.0, 0.0, 8.831362647162233e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003211052211318906, 8.831362647162233e-05, 0.0, 0.0, 20.0003305890172, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 133 + stamp: + secs: 1624875203 + nsecs: 319755077 + frame_id: "/world" +pose: + pose: + position: + x: 0.119514762011 + y: 0.0534614608507 + z: 0.0 + orientation: + x: 0.0 + y: 0.00100864157374 + z: 0.0 + w: 0.999999491321 + covariance: [20.612362375983526, -8.412975210200575e-07, 0.0, 0.0, -0.0002681712312382927, 0.0, -8.412975210200563e-07, 20.612359096821713, 0.0, 0.0, 7.060613092973237e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002681712312382926, 7.060613092973236e-05, 0.0, 0.0, 20.000611037213105, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 134 + stamp: + secs: 1624875203 + nsecs: 399734974 + frame_id: "/world" +pose: + pose: + position: + x: 0.119462040519 + y: 0.0534492565604 + z: 0.0 + orientation: + x: 0.0 + y: 0.00103512702983 + z: 0.0 + w: 0.999999464256 + covariance: [20.58025613104007, -7.85767331817555e-07, 0.0, 0.0, -0.00022444875858946414, 0.0, -7.857673318175537e-07, 20.58025306526944, 0.0, 0.0, 5.200913499342807e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00022444875858946406, 5.200913499342807e-05, 0.0, 0.0, 20.000747361967, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 135 + stamp: + secs: 1624875203 + nsecs: 479762077 + frame_id: "/world" +pose: + pose: + position: + x: 0.119400915238 + y: 0.0534351163313 + z: 0.0 + orientation: + x: 0.0 + y: 0.000974330405041 + z: 0.0 + w: 0.99999952534 + covariance: [20.58893667025932, -7.846823294663177e-07, 0.0, 0.0, -0.00019256159145454731, 0.0, -7.846823294663166e-07, 20.58893360591373, 0.0, 0.0, 4.0617861733799485e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001925615914545472, 4.061786173379949e-05, 0.0, 0.0, 20.00070278559429, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 136 + stamp: + secs: 1624875203 + nsecs: 559773922 + frame_id: "/world" +pose: + pose: + position: + x: 0.119314768146 + y: 0.0534141016422 + z: 0.0 + orientation: + x: 0.0 + y: 0.000865187358501 + z: 0.0 + w: 0.999999625725 + covariance: [20.630725217821528, -8.296877488516365e-07, 0.0, 0.0, -0.0002465889074272225, 0.0, -8.296877488516353e-07, 20.630721996412028, 0.0, 0.0, 0.0003002832100439812, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00024658890742722245, 0.00030028321004398127, 0.0, 0.0, 20.000707763113102, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 137 + stamp: + secs: 1624875203 + nsecs: 639780045 + frame_id: "/world" +pose: + pose: + position: + x: 0.119231582793 + y: 0.0533921006783 + z: 0.0 + orientation: + x: 0.0 + y: 0.000857870217731 + z: 0.0 + w: 0.999999632029 + covariance: [20.609919511280246, -7.994896676135392e-07, 0.0, 0.0, -0.00030374116501066486, 0.0, -7.994896676135381e-07, 20.609916460889036, 0.0, 0.0, 0.0005420238203003826, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00030374116501066486, 0.0005420238203003826, 0.0, 0.0, 20.00089032112281, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 138 + stamp: + secs: 1624875203 + nsecs: 719793081 + frame_id: "/world" +pose: + pose: + position: + x: 0.119134364449 + y: 0.0533525666274 + z: 0.0 + orientation: + x: 0.0 + y: 0.000986836393148 + z: 0.0 + w: 0.999999513077 + covariance: [20.633219597898638, -8.379233749155235e-07, 0.0, 0.0, -0.0005474493292306959, 0.0, -8.379233749155223e-07, 20.633216499360152, 0.0, 0.0, 0.0006728863406027545, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005474493292306959, 0.0006728863406027545, 0.0, 0.0, 20.00101819803006, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 139 + stamp: + secs: 1624875203 + nsecs: 799793005 + frame_id: "/world" +pose: + pose: + position: + x: 0.119036599127 + y: 0.0532997660884 + z: 0.0 + orientation: + x: 0.0 + y: 0.000952879774964 + z: 0.0 + w: 0.99999954601 + covariance: [20.651496715330794, -8.797931215992057e-07, 0.0, 0.0, -0.0008041748914912668, 0.0, -8.797931215992047e-07, 20.651493574990738, 0.0, 0.0, 0.0007053323035125088, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000804174891491267, 0.0007053323035125089, 0.0, 0.0, 20.000982295403865, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 140 + stamp: + secs: 1624875203 + nsecs: 879812002 + frame_id: "/world" +pose: + pose: + position: + x: 0.118939111002 + y: 0.0532398796657 + z: 0.0 + orientation: + x: 0.0 + y: 0.000813758330451 + z: 0.0 + w: 0.999999668899 + covariance: [20.66306701397587, -9.151797695087174e-07, 0.0, 0.0, -0.0009924851468552205, 0.0, -9.151797695087165e-07, 20.66306384861479, 0.0, 0.0, 0.000680687747476981, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009924851468552207, 0.0006806877474769813, 0.0, 0.0, 20.00081940140776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 141 + stamp: + secs: 1624875203 + nsecs: 959813118 + frame_id: "/world" +pose: + pose: + position: + x: 0.118834347083 + y: 0.0531684048044 + z: 0.0 + orientation: + x: 0.0 + y: 0.00107885250267 + z: 0.0 + w: 0.999999418038 + covariance: [20.694190021910522, -9.791424426480006e-07, 0.0, 0.0, -0.001132884158314052, 0.0, -9.791424426479996e-07, 20.69418672403573, 0.0, 0.0, 0.0006317936126450344, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011328841583140522, 0.0006317936126450347, 0.0, 0.0, 20.001752447522527, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 142 + stamp: + secs: 1624875204 + nsecs: 39814949 + frame_id: "/world" +pose: + pose: + position: + x: 0.118729266831 + y: 0.053097612058 + z: 0.0 + orientation: + x: 0.0 + y: 0.0012838429018 + z: 0.0 + w: 0.999999175873 + covariance: [20.720066047382264, -1.0290243281374772e-06, 0.0, 0.0, -0.0011107149620169304, 0.0, -1.029024328137476e-06, 20.720062651191565, 0.0, 0.0, 0.0005663327970072738, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011107149620169306, 0.000566332797007274, 0.0, 0.0, 20.001527802866764, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 143 + stamp: + secs: 1624875204 + nsecs: 119822979 + frame_id: "/world" +pose: + pose: + position: + x: 0.118622499237 + y: 0.0530289196768 + z: 0.0 + orientation: + x: 0.0 + y: 0.000949906430178 + z: 0.0 + w: 0.999999548839 + covariance: [20.72184843716251, -1.0478210240190688e-06, 0.0, 0.0, -0.001035391993222134, 0.0, -1.0478210240190677e-06, 20.721845067572772, 0.0, 0.0, 0.0006142742780443283, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010353919932221342, 0.0006142742780443284, 0.0, 0.0, 20.00108714001132, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 144 + stamp: + secs: 1624875204 + nsecs: 199822903 + frame_id: "/world" +pose: + pose: + position: + x: 0.11851405824 + y: 0.0529574579231 + z: 0.0 + orientation: + x: 0.0 + y: 0.000907224463778 + z: 0.0 + w: 0.999999588472 + covariance: [20.704529661082635, -1.045204540711342e-06, 0.0, 0.0, -0.0010119489049159056, 0.0, -1.045204540711341e-06, 20.704526406416544, 0.0, 0.0, 0.0006957334339221963, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010119489049159056, 0.0006957334339221964, 0.0, 0.0, 20.001435601292208, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 145 + stamp: + secs: 1624875204 + nsecs: 279830933 + frame_id: "/world" +pose: + pose: + position: + x: 0.118406232481 + y: 0.0528819047605 + z: 0.0 + orientation: + x: 0.0 + y: 0.00119972851312 + z: 0.0 + w: 0.999999280325 + covariance: [20.686784586101055, -1.039793572976869e-06, 0.0, 0.0, -0.0009900013924151081, 0.0, -1.039793572976868e-06, 20.686781441208517, 0.0, 0.0, 0.0006981810943531755, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009900013924151083, 0.0006981810943531756, 0.0, 0.0, 20.001980916377494, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 146 + stamp: + secs: 1624875204 + nsecs: 359844923 + frame_id: "/world" +pose: + pose: + position: + x: 0.118307272005 + y: 0.0528108510642 + z: 0.0 + orientation: + x: 0.0 + y: 0.00150006118663 + z: 0.0 + w: 0.999998874908 + covariance: [20.65191261956748, -1.0009205280116267e-06, 0.0, 0.0, -0.0009090878395821619, 0.0, -1.000920528011626e-06, 20.651909660587968, 0.0, 0.0, 0.0006323531300180356, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009090878395821621, 0.0006323531300180356, 0.0, 0.0, 20.002815768798506, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 147 + stamp: + secs: 1624875204 + nsecs: 439868927 + frame_id: "/world" +pose: + pose: + position: + x: 0.11817361589 + y: 0.0527158031987 + z: 0.0 + orientation: + x: 0.0 + y: 0.00208024864087 + z: 0.0 + w: 0.99999783628 + covariance: [20.711125784906045, -1.107090254295217e-06, 0.0, 0.0, -0.0008530163504760206, 0.0, -1.1070902542952161e-06, 20.711122595486813, 0.0, 0.0, 0.0005962652132033027, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008530163504760204, 0.0005962652132033028, 0.0, 0.0, 20.00422274482919, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 148 + stamp: + secs: 1624875204 + nsecs: 519855022 + frame_id: "/world" +pose: + pose: + position: + x: 0.118068661611 + y: 0.052642960491 + z: 0.0 + orientation: + x: 0.0 + y: 0.0018546788338 + z: 0.0 + w: 0.999998280082 + covariance: [20.689306722969103, -1.0750915510267178e-06, 0.0, 0.0, -0.000687095039697058, 0.0, -1.0750915510267165e-06, 20.689303672521703, 0.0, 0.0, 0.0004936941317807485, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000687095039697058, 0.0004936941317807486, 0.0, 0.0, 20.003363194045548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 149 + stamp: + secs: 1624875204 + nsecs: 599853039 + frame_id: "/world" +pose: + pose: + position: + x: 0.117964147956 + y: 0.0525658170013 + z: 0.0 + orientation: + x: 0.0 + y: 0.00126324402825 + z: 0.0 + w: 0.999999202107 + covariance: [20.67171955569221, -1.0489512191604228e-06, 0.0, 0.0, -0.0006246062842293143, 0.0, -1.0489512191604215e-06, 20.671716618093786, 0.0, 0.0, 0.0004045771236633283, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006246062842293144, 0.0004045771236633284, 0.0, 0.0, 20.00214658998543, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 150 + stamp: + secs: 1624875204 + nsecs: 679869890 + frame_id: "/world" +pose: + pose: + position: + x: 0.12525722812 + y: 0.0297316668687 + z: 0.0 + orientation: + x: 0.0 + y: 0.000251956746045 + z: 0.0 + w: 0.999999968259 + covariance: [17.109395008159577, -6.864559557731499e-07, 0.0, 0.0, -0.00041799007702874056, 0.0, -6.864559557731492e-07, 17.109393103091882, 0.0, 0.0, 0.00022428163818598814, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004179900770287406, 0.00022428163818598822, 0.0, 0.0, 16.667617382474262, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 151 + stamp: + secs: 1624875204 + nsecs: 759877920 + frame_id: "/world" +pose: + pose: + position: + x: 0.125203169074 + y: 0.0294995405908 + z: 0.0 + orientation: + x: 0.0 + y: 0.00020912137763 + z: 0.0 + w: 0.999999978134 + covariance: [18.293409877541542, -7.542411722045438e-07, 0.0, 0.0, -0.0005406439519533432, 0.0, -7.542411722045431e-07, 18.29340780161646, 0.0, 0.0, 0.00019944681677007412, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005406439519533432, 0.00019944681677007414, 0.0, 0.0, 17.808962405701955, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 152 + stamp: + secs: 1624875204 + nsecs: 839879036 + frame_id: "/world" +pose: + pose: + position: + x: 0.125146999382 + y: 0.0292735523156 + z: 0.0 + orientation: + x: 0.0 + y: 0.000261259942522 + z: 0.0 + w: 0.999999965872 + covariance: [19.083930676475628, -7.952851318347315e-07, 0.0, 0.0, -0.0006581901190890199, 0.0, -7.952851318347306e-07, 19.083928492425564, 0.0, 0.0, 0.00017179254536029757, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00065819011908902, 0.00017179254536029757, 0.0, 0.0, 18.57287140893109, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 153 + stamp: + secs: 1624875204 + nsecs: 919888020 + frame_id: "/world" +pose: + pose: + position: + x: 0.125078722659 + y: 0.0290037837618 + z: 0.0 + orientation: + x: 0.0 + y: 0.000519766475609 + z: 0.0 + w: 0.999999864921 + covariance: [19.645563911536417, -8.837934208402938e-07, 0.0, 0.0, -0.0007500754100549147, 0.0, -8.837934208402929e-07, 19.64556148623445, 0.0, 0.0, 0.00017776485978549886, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007500754100549146, 0.00017776485978549883, 0.0, 0.0, 19.07662362889442, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 154 + stamp: + secs: 1624875204 + nsecs: 999908924 + frame_id: "/world" +pose: + pose: + position: + x: 0.125020436106 + y: 0.0287781773644 + z: 0.0 + orientation: + x: 0.0 + y: 0.000788978950389 + z: 0.0 + w: 0.999999688756 + covariance: [19.97376710775799, -8.796642987546075e-07, 0.0, 0.0, -0.00071441193907949, 0.0, -8.796642987546066e-07, 19.97376469578722, 0.0, 0.0, 0.00017725117593952596, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00071441193907949, 0.00017725117593952596, 0.0, 0.0, 19.40524637815989, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 155 + stamp: + secs: 1624875205 + nsecs: 79900026 + frame_id: "/world" +pose: + pose: + position: + x: 0.124949708331 + y: 0.0285093371148 + z: 0.0 + orientation: + x: 0.0 + y: 0.000883466523382 + z: 0.0 + w: 0.999999609743 + covariance: [20.22836428843851, -9.385885070213936e-07, 0.0, 0.0, -0.0006767903794114099, 0.0, -9.385885070213926e-07, 20.22836171841337, 0.0, 0.0, 0.00019304913205087516, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006767903794114101, 0.00019304913205087519, 0.0, 0.0, 19.61778332631817, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 156 + stamp: + secs: 1624875205 + nsecs: 159907103 + frame_id: "/world" +pose: + pose: + position: + x: 0.124882357475 + y: 0.0282461165277 + z: 0.0 + orientation: + x: 0.0 + y: 0.000935547787207 + z: 0.0 + w: 0.999999562375 + covariance: [20.378426212163667, -9.542015643040949e-07, 0.0, 0.0, -0.0008160750740504691, 0.0, -9.542015643040936e-07, 20.37842359264583, 0.0, 0.0, 0.000207126917604297, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008160750740504694, 0.00020712691760429704, 0.0, 0.0, 19.75541810733098, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 157 + stamp: + secs: 1624875205 + nsecs: 239924908 + frame_id: "/world" +pose: + pose: + position: + x: 0.124819996879 + y: 0.0279852060413 + z: 0.0 + orientation: + x: 0.0 + y: 0.000784446895262 + z: 0.0 + w: 0.999999692321 + covariance: [20.44993756813879, -9.300294919757571e-07, 0.0, 0.0, -0.0011448431942365058, 0.0, -9.300294919757558e-07, 20.449934979030242, 0.0, 0.0, 0.00022108842860630635, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011448431942365058, 0.0002210884286063063, 0.0, 0.0, 19.84302940258926, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 158 + stamp: + secs: 1624875205 + nsecs: 319930077 + frame_id: "/world" +pose: + pose: + position: + x: 0.124695117105 + y: 0.027452025269 + z: 0.0 + orientation: + x: 0.0 + y: 0.000438057885498 + z: 0.0 + w: 0.999999904053 + covariance: [20.731312531915638, -1.2929834000716946e-06, 0.0, 0.0, -0.0020140072509750276, 0.0, -1.2929834000716932e-06, 20.731308768747517, 0.0, 0.0, 0.00032313575818826017, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.002014007250975028, 0.0003231357581882601, 0.0, 0.0, 19.89955760862993, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 159 + stamp: + secs: 1624875205 + nsecs: 399924994 + frame_id: "/world" +pose: + pose: + position: + x: 0.134919439646 + y: 0.0239509063043 + z: 0.0 + orientation: + x: -0.0 + y: -0.00036700797512 + z: -0.0 + w: 0.999999932653 + covariance: [17.324789398944496, -1.0816249211378576e-06, 0.0, 0.0, -0.0015751630820863927, 0.0, -1.0816249211378568e-06, 17.324786164764774, 0.0, 0.0, 0.00024423656457015587, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001575163082086393, 0.00024423656457015587, 0.0, 0.0, 16.622383505714108, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 160 + stamp: + secs: 1624875205 + nsecs: 479929924 + frame_id: "/world" +pose: + pose: + position: + x: 0.134925470936 + y: 0.0236747444802 + z: 0.0 + orientation: + x: 0.0 + y: 0.000134028844377 + z: 0.0 + w: 0.999999991018 + covariance: [18.475765095449816, -1.0712091471646118e-06, 0.0, 0.0, -0.001416458405087703, 0.0, -1.0712091471646105e-06, 18.47576185049254, 0.0, 0.0, 0.0002265017347118429, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0014164584050877032, 0.0002265017347118429, 0.0, 0.0, 17.77876712846188, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 161 + stamp: + secs: 1624875205 + nsecs: 559950113 + frame_id: "/world" +pose: + pose: + position: + x: 0.134933989448 + y: 0.0233830738568 + z: 0.0 + orientation: + x: 0.0 + y: 0.000519348402044 + z: 0.0 + w: 0.999999865139 + covariance: [19.233147848667578, -1.0420160515995657e-06, 0.0, 0.0, -0.0012219742943312792, 0.0, -1.0420160515995645e-06, 19.233144659038864, 0.0, 0.0, 0.00020713401709714283, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0012219742943312794, 0.0002071340170971428, 0.0, 0.0, 18.553208897901772, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 162 + stamp: + secs: 1624875205 + nsecs: 639954090 + frame_id: "/world" +pose: + pose: + position: + x: 0.134941749006 + y: 0.0230926329819 + z: 0.0 + orientation: + x: 0.0 + y: 0.0007734101017 + z: 0.0 + w: 0.999999700918 + covariance: [19.722342151211546, -1.0055129415717305e-06, 0.0, 0.0, -0.0010311421444693962, 0.0, -1.0055129415717292e-06, 19.722339046699695, 0.0, 0.0, 0.0001921411311628344, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010311421444693962, 0.0001921411311628343, 0.0, 0.0, 19.063836116569117, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 163 + stamp: + secs: 1624875205 + nsecs: 719960928 + frame_id: "/world" +pose: + pose: + position: + x: 0.136222626122 + y: 0.0198701431852 + z: 0.0 + orientation: + x: -0.0 + y: -0.000470456726306 + z: -0.0 + w: 0.999999889335 + covariance: [16.689328444008282, -6.729849913876634e-07, 0.0, 0.0, -0.0009027205156245475, 0.0, -6.729849913876625e-07, 16.68932632416469, 0.0, 0.0, 0.00012558668184269462, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009027205156245475, 0.00012558668184269462, 0.0, 0.0, 16.246185302064987, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 164 + stamp: + secs: 1624875205 + nsecs: 799964905 + frame_id: "/world" +pose: + pose: + position: + x: 0.136186005541 + y: 0.0200197897116 + z: 0.0 + orientation: + x: 0.0 + y: 6.02457732111e-05 + z: 0.0 + w: 0.999999998185 + covariance: [18.00956883448021, -7.428921226909511e-07, 0.0, 0.0, -0.0013655768875985338, 0.0, -7.4289212269095e-07, 18.009566368051296, 0.0, 0.0, 0.0001273796181134263, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013655768875985334, 0.00012737961811342633, 0.0, 0.0, 17.523125886941074, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 165 + stamp: + secs: 1624875205 + nsecs: 879976034 + frame_id: "/world" +pose: + pose: + position: + x: 0.136199618767 + y: 0.0196632243829 + z: 0.0 + orientation: + x: 0.0 + y: 0.000296154540897 + z: 0.0 + w: 0.999999956146 + covariance: [18.89113403603491, -7.776370645146904e-07, 0.0, 0.0, -0.0014994978584117417, 0.0, -7.776370645146894e-07, 18.891131328372154, 0.0, 0.0, 0.00012051937579876621, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0014994978584117412, 0.00012051937579876623, 0.0, 0.0, 18.38345816163294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 166 + stamp: + secs: 1624875205 + nsecs: 959978104 + frame_id: "/world" +pose: + pose: + position: + x: 0.136212263076 + y: 0.0193088479528 + z: 0.0 + orientation: + x: 0.0 + y: 0.00092900063922 + z: 0.0 + w: 0.999999568479 + covariance: [19.47109371290106, -7.951032069129269e-07, 0.0, 0.0, -0.0014635635198650477, 0.0, -7.951032069129261e-07, 19.47109083359036, 0.0, 0.0, 0.00012077555055186969, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0014635635198650473, 0.00012077555055186965, 0.0, 0.0, 18.953373216098992, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 167 + stamp: + secs: 1624875206 + nsecs: 40004015 + frame_id: "/world" +pose: + pose: + position: + x: 0.144500854143 + y: 0.0303782297485 + z: 0.0 + orientation: + x: 0.0 + y: 0.000830909694516 + z: 0.0 + w: 0.999999654794 + covariance: [19.847553163637432, -8.015434394667041e-07, 0.0, 0.0, -0.0013434624173025251, 0.0, -8.015434394667035e-07, 19.847550167431905, 0.0, 0.0, 0.00012330897501902117, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013434624173025247, 0.00012330897501902115, 0.0, 0.0, 19.325430455041346, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 168 + stamp: + secs: 1624875206 + nsecs: 119993925 + frame_id: "/world" +pose: + pose: + position: + x: 0.144565830568 + y: 0.0300351563344 + z: 0.0 + orientation: + x: 0.0 + y: 0.000727308533362 + z: 0.0 + w: 0.999999735511 + covariance: [20.090347168710068, -8.016218414611106e-07, 0.0, 0.0, -0.001215446081938499, 0.0, -8.016218414611098e-07, 20.090344087798815, 0.0, 0.0, 0.00011863477398623279, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001215446081938499, 0.00011863477398623273, 0.0, 0.0, 19.565834815425337, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 169 + stamp: + secs: 1624875206 + nsecs: 199990988 + frame_id: "/world" +pose: + pose: + position: + x: 0.144626294674 + y: 0.0296965617277 + z: 0.0 + orientation: + x: 0.0 + y: 0.000451107921675 + z: 0.0 + w: 0.999999898251 + covariance: [20.274693459993696, -8.433961130145399e-07, 0.0, 0.0, -0.0011554063641818588, 0.0, -8.433961130145391e-07, 20.27469013480176, 0.0, 0.0, 0.0001393098927065603, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011554063641818588, 0.0001393098927065603, 0.0, 0.0, 19.7212850100616, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 170 + stamp: + secs: 1624875206 + nsecs: 280004025 + frame_id: "/world" +pose: + pose: + position: + x: 0.144672337952 + y: 0.0293565920105 + z: 0.0 + orientation: + x: 0.0 + y: 5.98916759118e-05 + z: 0.0 + w: 0.999999998206 + covariance: [20.397443232594508, -8.891848795742399e-07, 0.0, 0.0, -0.0010642705603043719, 0.0, -8.891848795742391e-07, 20.39743972524047, 0.0, 0.0, 0.0003602877297331169, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010642705603043719, 0.00036028772973311697, 0.0, 0.0, 19.820775862250958, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 171 + stamp: + secs: 1624875206 + nsecs: 360021114 + frame_id: "/world" +pose: + pose: + position: + x: 0.14469833284 + y: 0.0290869537981 + z: 0.0 + orientation: + x: -0.0 + y: -0.000203996184485 + z: -0.0 + w: 0.999999979193 + covariance: [20.428378590943066, -8.508163908570661e-07, 0.0, 0.0, -0.0008902449353146382, 0.0, -8.50816390857065e-07, 20.42837528369411, 0.0, 0.0, 0.000535827442129174, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008902449353146382, 0.0005358274421291742, 0.0, 0.0, 19.885096775708906, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 172 + stamp: + secs: 1624875206 + nsecs: 440040112 + frame_id: "/world" +pose: + pose: + position: + x: 0.144725051677 + y: 0.0287900986384 + z: 0.0 + orientation: + x: -0.0 + y: -0.000109974950398 + z: -0.0 + w: 0.999999993953 + covariance: [20.470818482180707, -8.63816026561991e-07, 0.0, 0.0, -0.0007747654547182105, 0.0, -8.638160265619897e-07, 20.470815175346466, 0.0, 0.0, 0.0006277941962265235, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007747654547182103, 0.0006277941962265236, 0.0, 0.0, 19.926438668155722, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 173 + stamp: + secs: 1624875206 + nsecs: 520046949 + frame_id: "/world" +pose: + pose: + position: + x: 0.144753704639 + y: 0.0284847121044 + z: 0.0 + orientation: + x: -0.0 + y: -7.02152665021e-05 + z: -0.0 + w: 0.999999997535 + covariance: [20.49544495009412, -8.673421774967779e-07, 0.0, 0.0, -0.000667462218510679, 0.0, -8.673421774967766e-07, 20.495441672772387, 0.0, 0.0, 0.000626550982493443, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006674622185106789, 0.000626550982493443, 0.0, 0.0, 19.952856643625324, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 174 + stamp: + secs: 1624875206 + nsecs: 600040913 + frame_id: "/world" +pose: + pose: + position: + x: 0.14478159089 + y: 0.0281858166113 + z: 0.0 + orientation: + x: -0.0 + y: -0.000266271755122 + z: -0.0 + w: 0.99999996455 + covariance: [20.506056120816638, -8.603030577629318e-07, 0.0, 0.0, -0.0005750961580421128, 0.0, -8.603030577629305e-07, 20.50605290681735, 0.0, 0.0, 0.0005763081576443862, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005750961580421127, 0.0005763081576443862, 0.0, 0.0, 19.96979496960457, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 175 + stamp: + secs: 1624875206 + nsecs: 680032969 + frame_id: "/world" +pose: + pose: + position: + x: 0.144807727063 + y: 0.0278921852075 + z: 0.0 + orientation: + x: -0.0 + y: -0.000341197707182 + z: -0.0 + w: 0.999999941792 + covariance: [20.508038920334883, -8.473289196707694e-07, 0.0, 0.0, -0.000494426443540488, 0.0, -8.473289196707681e-07, 20.508035790017438, 0.0, 0.0, 0.0005241991201846846, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000494426443540488, 0.0005241991201846845, 0.0, 0.0, 19.980666779382602, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 176 + stamp: + secs: 1624875206 + nsecs: 760040998 + frame_id: "/world" +pose: + pose: + position: + x: 0.150110569626 + y: 0.0319668922732 + z: 0.0 + orientation: + x: -0.0 + y: -6.34034686518e-05 + z: -0.0 + w: 0.99999999799 + covariance: [17.01797475693596, -5.741850705340525e-07, 0.0, 0.0, -0.0002877029806271601, 0.0, -5.741850705340516e-07, 17.017972653947805, 0.0, 0.0, 0.00032765586963984933, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00028770298062716, 0.0003276558696398492, 0.0, 0.0, 16.658171689204462, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 177 + stamp: + secs: 1624875206 + nsecs: 840075016 + frame_id: "/world" +pose: + pose: + position: + x: 0.155516802459 + y: 0.031492077295 + z: 0.0 + orientation: + x: -0.0 + y: -0.00154315843964 + z: -0.0 + w: 0.99999880933 + covariance: [18.24094082609352, -6.996706231519143e-07, 0.0, 0.0, -0.0002940960861338145, 0.0, -6.99670623151913e-07, 18.24093829820398, 0.0, 0.0, 0.0003412087662451708, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002940960861338143, 0.00034120876624517063, 0.0, 0.0, 17.802668838814803, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 178 + stamp: + secs: 1624875206 + nsecs: 920078039 + frame_id: "/world" +pose: + pose: + position: + x: 0.162158988007 + y: 0.0309247990533 + z: 0.0 + orientation: + x: -0.0 + y: -0.00211224330014 + z: -0.0 + w: 0.999997769212 + covariance: [19.059037277280446, -7.805924243658962e-07, 0.0, 0.0, -0.0003022962373931249, 0.0, -7.80592424365895e-07, 19.059034488817055, 0.0, 0.0, 0.000346861701139921, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003022962373931248, 0.00034686170113992077, 0.0, 0.0, 18.56876280319795, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 179 + stamp: + secs: 1624875207 + nsecs: 104904 + frame_id: "/world" +pose: + pose: + position: + x: 0.162257934467 + y: 0.0306714083051 + z: 0.0 + orientation: + x: -0.0 + y: -0.00144103122325 + z: -0.0 + w: 0.999998961714 + covariance: [19.55580384732583, -7.65016798788938e-07, 0.0, 0.0, -0.0003166944093142392, 0.0, -7.65016798788937e-07, 19.555801137765314, 0.0, 0.0, 0.0003194790953180591, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003166944093142391, 0.000319479095318059, 0.0, 0.0, 19.073412233083978, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 180 + stamp: + secs: 1624875207 + nsecs: 80077887 + frame_id: "/world" +pose: + pose: + position: + x: 0.150963417414 + y: 0.0391685007139 + z: 0.0 + orientation: + x: 0.0 + y: 0.000475885312731 + z: 0.0 + w: 0.999999886767 + covariance: [19.907380857737156, -7.970786045663572e-07, 0.0, 0.0, -0.00036217177906811276, 0.0, -7.970786045663563e-07, 19.907378059905817, 0.0, 0.0, 0.0002971557507124828, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00036217177906811254, 0.00029715575071248264, 0.0, 0.0, 19.402416165654852, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 181 + stamp: + secs: 1624875207 + nsecs: 160103083 + frame_id: "/world" +pose: + pose: + position: + x: 0.133635387309 + y: 0.0469573447314 + z: 0.0 + orientation: + x: 0.0 + y: 0.00538388799993 + z: 0.0 + w: 0.99998550677 + covariance: [20.1522654291959, -8.42297008272025e-07, 0.0, 0.0, -0.0004290494915031747, 0.0, -8.422970082720238e-07, 20.152262495626335, 0.0, 0.0, 0.00027204797870456095, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004290494915031746, 0.00027204797870456084, 0.0, 0.0, 19.61579485972072, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 182 + stamp: + secs: 1624875207 + nsecs: 240103006 + frame_id: "/world" +pose: + pose: + position: + x: 0.138032693415 + y: 0.047119753054 + z: 0.0 + orientation: + x: 0.0 + y: 0.000544818900905 + z: 0.0 + w: 0.999999851586 + covariance: [16.882245963849385, -6.022909014358274e-07, 0.0, 0.0, -0.00034487041989283615, 0.0, -6.022909014358268e-07, 16.882243885048602, 0.0, 0.0, 0.00022912715049944928, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003448704198928362, 0.00022912715049944922, 0.0, 0.0, 16.49522596381316, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 183 + stamp: + secs: 1624875207 + nsecs: 320096970 + frame_id: "/world" +pose: + pose: + position: + x: 0.141414231251 + y: 0.0467829901983 + z: 0.0 + orientation: + x: 0.0 + y: 7.96617397215e-05 + z: 0.0 + w: 0.999999996827 + covariance: [15.313287976333497, -4.3475311950171025e-07, 0.0, 0.0, -0.00025301764396367066, 0.0, -4.347531195017098e-07, 15.313286491555447, 0.0, 0.0, 0.00020850200977323065, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002530176439636706, 0.0002085020097732306, 0.0, 0.0, 15.032731342795298, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 184 + stamp: + secs: 1624875207 + nsecs: 400090933 + frame_id: "/world" +pose: + pose: + position: + x: 0.141583542517 + y: 0.043734564388 + z: 0.0 + orientation: + x: -0.0 + y: -0.00043732706155 + z: -0.0 + w: 0.999999904373 + covariance: [14.573801107531713, -4.193649536837453e-07, 0.0, 0.0, -0.00021952256588382736, 0.0, -4.193649536837447e-07, 14.573799699996295, 0.0, 0.0, 0.0002225054373070231, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00021952256588382728, 0.0002225054373070231, 0.0, 0.0, 14.302666564369643, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 185 + stamp: + secs: 1624875207 + nsecs: 480118990 + frame_id: "/world" +pose: + pose: + position: + x: 0.142476902866 + y: 0.0424621431629 + z: 0.0 + orientation: + x: -0.0 + y: -0.00083548566371 + z: -0.0 + w: 0.999999650982 + covariance: [16.50841420032839, -5.123647910931299e-07, 0.0, 0.0, -0.00042349159441433146, 0.0, -5.12364791093129e-07, 16.508412508141117, 0.0, 0.0, 0.0002637036658399103, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004234915944143312, 0.0002637036658399104, 0.0, 0.0, 16.179727688183178, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 186 + stamp: + secs: 1624875207 + nsecs: 560122967 + frame_id: "/world" +pose: + pose: + position: + x: 0.142473613519 + y: 0.0423778617224 + z: 0.0 + orientation: + x: -0.0 + y: -0.000583356819748 + z: -0.0 + w: 0.999999829847 + covariance: [17.747423764090193, -4.2112518149873565e-07, 0.0, 0.0, -0.0004299240961578801, 0.0, -4.211251814987349e-07, 17.74742237829128, 0.0, 0.0, 0.00021303299837377475, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004299240961578798, 0.00021303299837377484, 0.0, 0.0, 17.47795690147369, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 187 + stamp: + secs: 1624875207 + nsecs: 640136957 + frame_id: "/world" +pose: + pose: + position: + x: 0.142462351175 + y: 0.0420869757409 + z: 0.0 + orientation: + x: -0.0 + y: -0.000434446499099 + z: -0.0 + w: 0.999999905628 + covariance: [18.692762159910096, -5.409575300987148e-07, 0.0, 0.0, -0.000717628413961763, 0.0, -5.409575300987138e-07, 18.692760391331834, 0.0, 0.0, 0.00023672240457309231, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007176284139617625, 0.00023672240457309231, 0.0, 0.0, 18.3527062021872, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 188 + stamp: + secs: 1624875207 + nsecs: 720158100 + frame_id: "/world" +pose: + pose: + position: + x: 0.142449918138 + y: 0.041760134266 + z: 0.0 + orientation: + x: -0.0 + y: -4.84009222737e-05 + z: -0.0 + w: 0.999999998829 + covariance: [19.35310216822201, -6.783219467092668e-07, 0.0, 0.0, -0.000944735508180052, 0.0, -6.783219467092655e-07, 19.35309994437682, 0.0, 0.0, 0.0002399228080693974, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009447355081800518, 0.00023992280806939742, 0.0, 0.0, 18.93149486390693, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 189 + stamp: + secs: 1624875207 + nsecs: 800143957 + frame_id: "/world" +pose: + pose: + position: + x: 0.142437518753 + y: 0.0414405965818 + z: 0.0 + orientation: + x: 0.0 + y: 0.000268287894111 + z: 0.0 + w: 0.999999964011 + covariance: [19.791423938206112, -7.786164937725876e-07, 0.0, 0.0, -0.0010475641464883906, 0.0, -7.786164937725861e-07, 19.791421368927285, 0.0, 0.0, 0.00022828665333003885, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010475641464883906, 0.00022828665333003885, 0.0, 0.0, 19.310260900422517, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 190 + stamp: + secs: 1624875207 + nsecs: 880158901 + frame_id: "/world" +pose: + pose: + position: + x: 0.142422428277 + y: 0.0411012694767 + z: 0.0 + orientation: + x: 0.0 + y: 0.000264937000551 + z: 0.0 + w: 0.999999964904 + covariance: [20.083991688557617, -8.630288719803566e-07, 0.0, 0.0, -0.0013706935861623126, 0.0, -8.630288719803551e-07, 20.083988798475954, 0.0, 0.0, 0.00024696579761042007, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013706935861623123, 0.00024696579761041996, 0.0, 0.0, 19.55612838453532, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 191 + stamp: + secs: 1624875207 + nsecs: 960160017 + frame_id: "/world" +pose: + pose: + position: + x: 0.14240634703 + y: 0.0407704732381 + z: 0.0 + orientation: + x: 0.0 + y: 0.000337797867003 + z: 0.0 + w: 0.999999942946 + covariance: [20.25818674406134, -9.010680177773379e-07, 0.0, 0.0, -0.0016566327614700714, 0.0, -9.010680177773366e-07, 20.258183652260563, 0.0, 0.0, 0.00026118040805964707, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0016566327614700714, 0.000261180408059647, 0.0, 0.0, 19.714967233883627, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 192 + stamp: + secs: 1624875208 + nsecs: 40215015 + frame_id: "/world" +pose: + pose: + position: + x: 0.142389429741 + y: 0.0404398063698 + z: 0.0 + orientation: + x: 0.0 + y: 0.00043439845396 + z: 0.0 + w: 0.999999905649 + covariance: [20.37153683720421, -9.29866966082794e-07, 0.0, 0.0, -0.0016905183840150782, 0.0, -9.298669660827927e-07, 20.37153358054137, 0.0, 0.0, 0.00026260552362958003, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0016905183840150782, 0.00026260552362958003, 0.0, 0.0, 19.817245115540953, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 193 + stamp: + secs: 1624875208 + nsecs: 120165110 + frame_id: "/world" +pose: + pose: + position: + x: 0.142368458862 + y: 0.0400470786113 + z: 0.0 + orientation: + x: 0.0 + y: 0.000515841728213 + z: 0.0 + w: 0.999999866954 + covariance: [20.49128239534723, -1.030495394262505e-06, 0.0, 0.0, -0.0016649046040139504, 0.0, -1.0304953942625035e-06, 20.491278720459466, 0.0, 0.0, 0.00026926356503130446, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0016649046040139502, 0.0002692635650313045, 0.0, 0.0, 19.88299368483262, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 194 + stamp: + secs: 1624875208 + nsecs: 200181961 + frame_id: "/world" +pose: + pose: + position: + x: 0.1423496766 + y: 0.0397309792451 + z: 0.0 + orientation: + x: 0.0 + y: 0.000635076089843 + z: 0.0 + w: 0.999999798339 + covariance: [20.520550999209334, -1.0134533004936717e-06, 0.0, 0.0, -0.001451856158361279, 0.0, -1.0134533004936702e-06, 20.520547353954036, 0.0, 0.0, 0.00026803327069191033, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001451856158361279, 0.0002680332706919103, 0.0, 0.0, 19.92536882711999, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 195 + stamp: + secs: 1624875208 + nsecs: 280190945 + frame_id: "/world" +pose: + pose: + position: + x: 0.140560508904 + y: 0.0345101037347 + z: 0.0 + orientation: + x: 0.0 + y: 0.000797935742198 + z: 0.0 + w: 0.999999681649 + covariance: [17.069822206417484, -7.416681006146688e-07, 0.0, 0.0, -0.0009229103726266189, 0.0, -7.416681006146676e-07, 17.069819522640255, 0.0, 0.0, 0.00020446319425063952, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000922910372626619, 0.00020446319425063952, 0.0, 0.0, 16.63405670483017, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 196 + stamp: + secs: 1624875208 + nsecs: 360193968 + frame_id: "/world" +pose: + pose: + position: + x: 0.143062682233 + y: 0.0380298571903 + z: 0.0 + orientation: + x: 0.0 + y: 0.000303562297453 + z: 0.0 + w: 0.999999953925 + covariance: [18.304064213810708, -8.900881851052045e-07, 0.0, 0.0, -0.0009084884306007618, 0.0, -8.900881851052034e-07, 18.304060991753875, 0.0, 0.0, 0.0002942949159250886, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009084884306007619, 0.00029429491592508855, 0.0, 0.0, 17.78655013653313, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 197 + stamp: + secs: 1624875208 + nsecs: 440201998 + frame_id: "/world" +pose: + pose: + position: + x: 0.147859714268 + y: 0.0413242187074 + z: 0.0 + orientation: + x: -0.0 + y: -0.00129572502538 + z: -0.0 + w: 0.999999160548 + covariance: [19.04436444124868, -8.404040800969801e-07, 0.0, 0.0, -0.000748857432391046, 0.0, -8.40404080096979e-07, 19.044361414522026, 0.0, 0.0, 0.0003345063357748019, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007488574323910463, 0.00033450633577480183, 0.0, 0.0, 18.557934335634513, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 198 + stamp: + secs: 1624875208 + nsecs: 520207882 + frame_id: "/world" +pose: + pose: + position: + x: 0.147856018569 + y: 0.0409729173796 + z: 0.0 + orientation: + x: -0.0 + y: -0.000567162889524 + z: -0.0 + w: 0.999999839163 + covariance: [19.60780405715735, -9.424134574908398e-07, 0.0, 0.0, -0.0006795757624748822, 0.0, -9.424134574908385e-07, 19.60780069501504, 0.0, 0.0, 0.0004282552650167189, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006795757624748825, 0.00042825526501671886, 0.0, 0.0, 19.066705049697873, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 199 + stamp: + secs: 1624875208 + nsecs: 600233078 + frame_id: "/world" +pose: + pose: + position: + x: 0.144375333932 + y: 0.0426706811863 + z: 0.0 + orientation: + x: 0.0 + y: 0.00125564454595 + z: 0.0 + w: 0.999999211678 + covariance: [19.981063772426396, -1.0159637330053566e-06, 0.0, 0.0, -0.0005940268801615351, 0.0, -1.0159637330053549e-06, 19.9810601742661, 0.0, 0.0, 0.00045212981709114134, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005940268801615351, 0.00045212981709114134, 0.0, 0.0, 19.398597093876152, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 200 + stamp: + secs: 1624875208 + nsecs: 680222988 + frame_id: "/world" +pose: + pose: + position: + x: 0.138905891857 + y: 0.0419220004916 + z: 0.0 + orientation: + x: 0.0 + y: 0.00245519063178 + z: 0.0 + w: 0.999996986015 + covariance: [20.245982894247526, -1.1023534749048171e-06, 0.0, 0.0, -0.0005719329070006276, 0.0, -1.1023534749048152e-06, 20.245979020694673, 0.0, 0.0, 0.0004696229731888643, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005719329070006279, 0.00046962297318886434, 0.0, 0.0, 19.613903945079123, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 201 + stamp: + secs: 1624875208 + nsecs: 760227919 + frame_id: "/world" +pose: + pose: + position: + x: 0.13887442379 + y: 0.0414163769421 + z: 0.0 + orientation: + x: 0.0 + y: 0.00189510578148 + z: 0.0 + w: 0.999998204285 + covariance: [20.42360035200424, -1.1684627215715925e-06, 0.0, 0.0, -0.0005666300578947264, 0.0, -1.1684627215715904e-06, 20.42359628371323, 0.0, 0.0, 0.0004920062474365625, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005666300578947265, 0.0004920062474365625, 0.0, 0.0, 19.75259819336361, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 202 + stamp: + secs: 1624875208 + nsecs: 840251923 + frame_id: "/world" +pose: + pose: + position: + x: 0.138800305295 + y: 0.0410555848699 + z: 0.0 + orientation: + x: 0.0 + y: 0.00169437326739 + z: 0.0 + w: 0.999998564549 + covariance: [20.538392496578197, -1.2081295317323807e-06, 0.0, 0.0, -0.0005227829545212774, 0.0, -1.2081295317323786e-06, 20.538388327870518, 0.0, 0.0, 0.0005000847337855841, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005227829545212774, 0.000500084733785584, 0.0, 0.0, 19.842653763951592, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 203 + stamp: + secs: 1624875208 + nsecs: 920262098 + frame_id: "/world" +pose: + pose: + position: + x: 0.138724382208 + y: 0.0406907336721 + z: 0.0 + orientation: + x: 0.0 + y: 0.0014893058682 + z: 0.0 + w: 0.999998890983 + covariance: [20.615153582768453, -1.2368720018510262e-06, 0.0, 0.0, -0.0005423277940263922, 0.0, -1.2368720018510243e-06, 20.61514935473362, 0.0, 0.0, 0.0004959056065078365, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005423277940263922, 0.0004959056065078364, 0.0, 0.0, 19.899441380280997, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 204 + stamp: + secs: 1624875209 + nsecs: 256062 + frame_id: "/world" +pose: + pose: + position: + x: 0.138647412379 + y: 0.0403218044626 + z: 0.0 + orientation: + x: 0.0 + y: 0.00130658686254 + z: 0.0 + w: 0.999999146415 + covariance: [20.666829130770097, -1.2572009798744244e-06, 0.0, 0.0, -0.0005741019089943265, 0.0, -1.2572009798744225e-06, 20.66682487210388, 0.0, 0.0, 0.00047303913506572864, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005741019089943266, 0.00047303913506572875, 0.0, 0.0, 19.93677484211388, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 205 + stamp: + secs: 1624875209 + nsecs: 80250978 + frame_id: "/world" +pose: + pose: + position: + x: 0.138570324353 + y: 0.039953263934 + z: 0.0 + orientation: + x: 0.0 + y: 0.00114508589986 + z: 0.0 + w: 0.999999344389 + covariance: [20.70224838841741, -1.2686469278436214e-06, 0.0, 0.0, -0.0005462337225038096, 0.0, -1.2686469278436195e-06, 20.702244122807723, 0.0, 0.0, 0.00042861399531021093, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005462337225038098, 0.00042861399531021093, 0.0, 0.0, 19.95960735759614, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 206 + stamp: + secs: 1624875209 + nsecs: 160267115 + frame_id: "/world" +pose: + pose: + position: + x: 0.138874080141 + y: 0.0413653345064 + z: 0.0 + orientation: + x: 0.0 + y: 0.000589949352852 + z: 0.0 + w: 0.99999982598 + covariance: [17.145508872843248, -8.350178545958933e-07, 0.0, 0.0, -0.00032808869854119394, 0.0, -8.350178545958925e-07, 17.14550607979006, 0.0, 0.0, 0.0002669698019110615, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00032808869854119405, 0.0002669698019110615, 0.0, 0.0, 16.649108196503555, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 207 + stamp: + secs: 1624875209 + nsecs: 240287066 + frame_id: "/world" +pose: + pose: + position: + x: 0.13879136552 + y: 0.0409863951229 + z: 0.0 + orientation: + x: 0.0 + y: 0.000788519699119 + z: 0.0 + w: 0.999999689118 + covariance: [18.389091322749554, -9.88815640773958e-07, 0.0, 0.0, -0.0003243809586724937, 0.0, -9.88815640773957e-07, 18.389088043290556, 0.0, 0.0, 0.0002915311157111446, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00032438095867249375, 0.00029153111571114453, 0.0, 0.0, 17.796887034429552, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 208 + stamp: + secs: 1624875209 + nsecs: 320278883 + frame_id: "/world" +pose: + pose: + position: + x: 0.143344897788 + y: 0.0420706400096 + z: 0.0 + orientation: + x: 0.0 + y: 0.000246607652712 + z: 0.0 + w: 0.999999969592 + covariance: [19.272001691110155, -1.1695384689601978e-06, 0.0, 0.0, -0.0003956905864243096, 0.0, -1.169538468960196e-06, 19.27199784548348, 0.0, 0.0, 0.0003307581212088146, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00039569058642430964, 0.0003307581212088145, 0.0, 0.0, 18.56583714060859, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 209 + stamp: + secs: 1624875209 + nsecs: 400302887 + frame_id: "/world" +pose: + pose: + position: + x: 0.143884601821 + y: 0.0481189698821 + z: 0.0 + orientation: + x: 0.0 + y: 0.000164834211141 + z: 0.0 + w: 0.999999986415 + covariance: [16.49135495008524, -7.737722412203046e-07, 0.0, 0.0, -0.00028462949985883016, 0.0, -7.737722412203036e-07, 16.491352417974074, 0.0, 0.0, 0.00021982229108583135, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00028462949985883016, 0.00021982229108583127, 0.0, 0.0, 16.0175189677815, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 210 + stamp: + secs: 1624875209 + nsecs: 480295897 + frame_id: "/world" +pose: + pose: + position: + x: 0.140780270749 + y: 0.0500811189308 + z: 0.0 + orientation: + x: 0.0 + y: 0.000961539922621 + z: 0.0 + w: 0.99999953772 + covariance: [17.93446739384575, -9.18296198629834e-07, 0.0, 0.0, -0.0003290952741895451, 0.0, -9.182961986298327e-07, 17.93446441351104, 0.0, 0.0, 0.00026281302926821077, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003290952741895451, 0.00026281302926821066, 0.0, 0.0, 17.368464980704022, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 211 + stamp: + secs: 1624875209 + nsecs: 560297012 + frame_id: "/world" +pose: + pose: + position: + x: 0.138374342632 + y: 0.0514087023616 + z: 0.0 + orientation: + x: 0.0 + y: 0.00137145796054 + z: 0.0 + w: 0.999999059551 + covariance: [18.85064255408925, -9.178396940499558e-07, 0.0, 0.0, -0.00030783363454321304, 0.0, -9.178396940499544e-07, 18.850639591968864, 0.0, 0.0, 0.0002604546010937218, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003078336345432131, 0.0002604546010937217, 0.0, 0.0, 18.279727226664544, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 212 + stamp: + secs: 1624875209 + nsecs: 640314102 + frame_id: "/world" +pose: + pose: + position: + x: 0.138292013783 + y: 0.0511420379492 + z: 0.0 + orientation: + x: 0.0 + y: 0.000895138900629 + z: 0.0 + w: 0.999999599363 + covariance: [19.499934701659527, -9.801526909312594e-07, 0.0, 0.0, -0.00029852671563510377, 0.0, -9.801526909312584e-07, 19.49993155813948, 0.0, 0.0, 0.00026788973714469955, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002985267156351038, 0.0002678897371446995, 0.0, 0.0, 18.88365535606345, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 213 + stamp: + secs: 1624875209 + nsecs: 720318079 + frame_id: "/world" +pose: + pose: + position: + x: 0.147101841813 + y: 0.0560749490266 + z: 0.0 + orientation: + x: 0.0 + y: 0.000900469295823 + z: 0.0 + w: 0.999999594577 + covariance: [19.96762767330168, -1.0817621794639465e-06, 0.0, 0.0, -0.00031011505581638956, 0.0, -1.0817621794639454e-06, 19.967624225283032, 0.0, 0.0, 0.0002745467088205769, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003101150558163896, 0.0002745467088205768, 0.0, 0.0, 19.279273300304258, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 214 + stamp: + secs: 1624875209 + nsecs: 800335884 + frame_id: "/world" +pose: + pose: + position: + x: 0.147082336193 + y: 0.0558364914987 + z: 0.0 + orientation: + x: 0.0 + y: 0.000844995202109 + z: 0.0 + w: 0.999999642991 + covariance: [20.250157469090126, -1.107869457960124e-06, 0.0, 0.0, -0.000299869132492094, 0.0, -1.107869457960123e-06, 20.250153953607537, 0.0, 0.0, 0.00025284302359927395, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002998691324920941, 0.00025284302359927384, 0.0, 0.0, 19.53667393103118, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 215 + stamp: + secs: 1624875209 + nsecs: 880331039 + frame_id: "/world" +pose: + pose: + position: + x: 0.152959594596 + y: 0.0536601232637 + z: 0.0 + orientation: + x: 0.0 + y: 0.00050780744724 + z: 0.0 + w: 0.999999871066 + covariance: [14.506156160750482, -5.648690972424474e-07, 0.0, 0.0, -0.0001446679205998285, 0.0, -5.648690972424471e-07, 14.506154374859056, 0.0, 0.0, 0.00013066367766445948, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00014466792059982856, 0.0001306636776644594, 0.0, 0.0, 14.133659232141284, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 216 + stamp: + secs: 1624875209 + nsecs: 960352898 + frame_id: "/world" +pose: + pose: + position: + x: 0.152989998547 + y: 0.0533674851651 + z: 0.0 + orientation: + x: 0.0 + y: 0.00117496704699 + z: 0.0 + w: 0.999999309726 + covariance: [16.549437675306297, -7.322566810283447e-07, 0.0, 0.0, -0.00017368128217754028, 0.0, -7.322566810283444e-07, 16.549435374222103, 0.0, 0.0, 0.00017401059363862268, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00017368128217754033, 0.00017401059363862263, 0.0, 0.0, 16.062458691644157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 217 + stamp: + secs: 1624875210 + nsecs: 40358067 + frame_id: "/world" +pose: + pose: + position: + x: 0.156187088143 + y: 0.0531801485102 + z: 0.0 + orientation: + x: 0.0 + y: 0.000954490731887 + z: 0.0 + w: 0.999999544474 + covariance: [15.204413668600539, -5.682466611532847e-07, 0.0, 0.0, -0.0001216400539467323, 0.0, -5.682466611532844e-07, 15.204411889176392, 0.0, 0.0, 0.00012994322353394918, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00012164005394673238, 0.00012994322353394918, 0.0, 0.0, 14.820026346234135, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 218 + stamp: + secs: 1624875210 + nsecs: 120342016 + frame_id: "/world" +pose: + pose: + position: + x: 0.162011783802 + y: 0.0481856783237 + z: 0.0 + orientation: + x: 0.0 + y: 0.000932714554032 + z: 0.0 + w: 0.999999565022 + covariance: [17.07994953256771, -7.830405731720905e-07, 0.0, 0.0, -0.00013114090354453213, 0.0, -7.830405731720898e-07, 17.07994709239313, 0.0, 0.0, 0.00015959557636444026, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001311409035445322, 0.00015959557636444028, 0.0, 0.0, 16.54175776914888, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 219 + stamp: + secs: 1624875210 + nsecs: 200356007 + frame_id: "/world" +pose: + pose: + position: + x: 0.162061696321 + y: 0.0480184988457 + z: 0.0 + orientation: + x: 0.0 + y: 0.000609143594155 + z: 0.0 + w: 0.999999814472 + covariance: [18.221683645682734, -7.167736496024413e-07, 0.0, 0.0, -0.00010876904074787774, 0.0, -7.167736496024406e-07, 18.221681415770643, 0.0, 0.0, 0.00013617848026313241, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00010876904074787778, 0.00013617848026313244, 0.0, 0.0, 17.72366436681826, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 220 + stamp: + secs: 1624875210 + nsecs: 280395031 + frame_id: "/world" +pose: + pose: + position: + x: 0.162150619269 + y: 0.0476992718366 + z: 0.0 + orientation: + x: 0.0 + y: 0.000492739866296 + z: 0.0 + w: 0.999999878604 + covariance: [19.10285473404375, -8.335330349139783e-07, 0.0, 0.0, -0.00023556872860822886, 0.0, -8.335330349139777e-07, 19.102852152665832, 0.0, 0.0, 0.00018529571610345142, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00023556872860822884, 0.00018529571610345145, 0.0, 0.0, 18.516542689922623, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 221 + stamp: + secs: 1624875210 + nsecs: 360379934 + frame_id: "/world" +pose: + pose: + position: + x: 0.162221227273 + y: 0.0474225540458 + z: 0.0 + orientation: + x: 0.0 + y: 0.000736129933605 + z: 0.0 + w: 0.999999729056 + covariance: [19.647528091179208, -8.572786916059132e-07, 0.0, 0.0, -0.000373889757502315, 0.0, -8.572786916059124e-07, 19.647525450191317, 0.0, 0.0, 0.00023505963455554453, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00037388975750231497, 0.0002350596345555446, 0.0, 0.0, 19.040029348247423, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 222 + stamp: + secs: 1624875210 + nsecs: 440391064 + frame_id: "/world" +pose: + pose: + position: + x: 0.162278961997 + y: 0.047192465533 + z: 0.0 + orientation: + x: 0.0 + y: 0.000596045855659 + z: 0.0 + w: 0.999999822365 + covariance: [16.667668149803845, -6.021460624868289e-07, 0.0, 0.0, -0.0002987367576298679, 0.0, -6.021460624868284e-07, 16.667666303125475, 0.0, 0.0, 0.00017776426955914875, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002987367576298678, 0.00017776426955914883, 0.0, 0.0, 16.234733031463534, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 223 + stamp: + secs: 1624875210 + nsecs: 520392895 + frame_id: "/world" +pose: + pose: + position: + x: 0.162372864373 + y: 0.0468240207781 + z: 0.0 + orientation: + x: 0.0 + y: 0.00108960580451 + z: 0.0 + w: 0.999999406379 + covariance: [18.058127021315766, -7.479438002429899e-07, 0.0, 0.0, -0.0003540233190239082, 0.0, -7.479438002429893e-07, 18.058124741347577, 0.0, 0.0, 0.00020600422988593565, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00035402331902390817, 0.00020600422988593573, 0.0, 0.0, 17.51737254131063, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 224 + stamp: + secs: 1624875210 + nsecs: 600393057 + frame_id: "/world" +pose: + pose: + position: + x: 0.162441471099 + y: 0.0465440718868 + z: 0.0 + orientation: + x: 0.0 + y: 0.00145845586998 + z: 0.0 + w: 0.999998936453 + covariance: [18.959729257846348, -7.949559660621536e-07, 0.0, 0.0, -0.00035834515173682193, 0.0, -7.949559660621533e-07, 18.959726845665912, 0.0, 0.0, 0.0002138841262182181, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003583451517368219, 0.00021388412621821816, 0.0, 0.0, 18.38027400832202, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 225 + stamp: + secs: 1624875210 + nsecs: 680402040 + frame_id: "/world" +pose: + pose: + position: + x: 0.162517313156 + y: 0.0462235106813 + z: 0.0 + orientation: + x: 0.0 + y: 0.00136802216266 + z: 0.0 + w: 0.999999064257 + covariance: [19.592464692102325, -8.717059451717726e-07, 0.0, 0.0, -0.000373575414064317, 0.0, -8.717059451717722e-07, 19.592462061729666, 0.0, 0.0, 0.00023874935410166445, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000373575414064317, 0.00023874935410166456, 0.0, 0.0, 18.950307021265093, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 226 + stamp: + secs: 1624875210 + nsecs: 760426044 + frame_id: "/world" +pose: + pose: + position: + x: 0.162575486047 + y: 0.0459643264415 + z: 0.0 + orientation: + x: 0.0 + y: 0.000702089773082 + z: 0.0 + w: 0.999999753535 + covariance: [19.95343773642661, -8.481937736585343e-07, 0.0, 0.0, -0.0003619236605465665, 0.0, -8.481937736585343e-07, 19.95343519035328, 0.0, 0.0, 0.00025721600706647387, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003619236605465665, 0.000257216007066474, 0.0, 0.0, 19.32173483480294, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 227 + stamp: + secs: 1624875210 + nsecs: 840425968 + frame_id: "/world" +pose: + pose: + position: + x: 0.162636815497 + y: 0.0456501623727 + z: 0.0 + orientation: + x: 0.0 + y: 0.000166595125585 + z: 0.0 + w: 0.999999986123 + covariance: [20.220193744063224, -8.800365613479252e-07, 0.0, 0.0, -0.0005717222493846278, 0.0, -8.80036561347925e-07, 20.22019112811467, 0.0, 0.0, 0.0003427771292993325, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005717222493846278, 0.0003427771292993327, 0.0, 0.0, 19.56356591219736, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 228 + stamp: + secs: 1624875210 + nsecs: 920433044 + frame_id: "/world" +pose: + pose: + position: + x: 0.162691692558 + y: 0.0453320563465 + z: 0.0 + orientation: + x: -0.0 + y: -7.76810030644e-05 + z: -0.0 + w: 0.999999996983 + covariance: [20.37994617278429, -8.929774798661758e-07, 0.0, 0.0, -0.0009076894089653886, 0.0, -8.929774798661753e-07, 20.379943540872635, 0.0, 0.0, 0.00039368823399866566, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009076894089653884, 0.00039368823399866577, 0.0, 0.0, 19.719436055553537, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 229 + stamp: + secs: 1624875211 + nsecs: 436068 + frame_id: "/world" +pose: + pose: + position: + x: 0.16274551877 + y: 0.0450029937148 + z: 0.0 + orientation: + x: -0.0 + y: -9.97144780193e-05 + z: -0.0 + w: 0.999999995029 + covariance: [20.480496014063316, -9.058856041132462e-07, 0.0, 0.0, -0.0011939760802176312, 0.0, -9.058856041132457e-07, 20.480493346234184, 0.0, 0.0, 0.00039979228469573183, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011939760802176312, 0.00039979228469573183, 0.0, 0.0, 19.820183528789958, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 230 + stamp: + secs: 1624875211 + nsecs: 80427885 + frame_id: "/world" +pose: + pose: + position: + x: 0.162808157775 + y: 0.0446078609731 + z: 0.0 + orientation: + x: 0.0 + y: 4.53566512001e-05 + z: 0.0 + w: 0.999999998971 + covariance: [20.592884344556946, -9.888825884723961e-07, 0.0, 0.0, -0.0014391195307431087, 0.0, -9.88882588472396e-07, 20.592881415695054, 0.0, 0.0, 0.00040405748692359924, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001439119530743109, 0.00040405748692359924, 0.0, 0.0, 19.884697945677527, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 231 + stamp: + secs: 1624875211 + nsecs: 160442114 + frame_id: "/world" +pose: + pose: + position: + x: 0.162857241155 + y: 0.0442969750926 + z: 0.0 + orientation: + x: 0.0 + y: 0.000229375878088 + z: 0.0 + w: 0.999999973693 + covariance: [20.60306223189616, -9.521970073120834e-07, 0.0, 0.0, -0.001357289919336116, 0.0, -9.521970073120832e-07, 20.60305939491459, 0.0, 0.0, 0.0003505554009371014, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013572899193361164, 0.0003505554009371014, 0.0, 0.0, 19.92644363336895, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 232 + stamp: + secs: 1624875211 + nsecs: 240469933 + frame_id: "/world" +pose: + pose: + position: + x: 0.162892542112 + y: 0.0440365316284 + z: 0.0 + orientation: + x: -0.0 + y: -0.000181178553751 + z: -0.0 + w: 0.999999983587 + covariance: [17.085409456668145, -6.383851168703135e-07, 0.0, 0.0, -0.000866033845387825, 0.0, -6.383851168703135e-07, 17.085407561872355, 0.0, 0.0, 0.0002790661578185712, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008660338453878252, 0.0002790661578185712, 0.0, 0.0, 16.633866352862416, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 233 + stamp: + secs: 1624875211 + nsecs: 320468903 + frame_id: "/world" +pose: + pose: + position: + x: 0.160690376494 + y: 0.048643150079 + z: 0.0 + orientation: + x: 0.0 + y: 0.000423181181184 + z: 0.0 + w: 0.999999910459 + covariance: [18.316933566747178, -7.754447592541205e-07, 0.0, 0.0, -0.0009254473597586651, 0.0, -7.754447592541205e-07, 18.31693130847225, 0.0, 0.0, 0.00044442040020472304, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009254473597586655, 0.0004444204002047231, 0.0, 0.0, 17.78606147720979, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 234 + stamp: + secs: 1624875211 + nsecs: 400448084 + frame_id: "/world" +pose: + pose: + position: + x: 0.164019139316 + y: 0.0553009029739 + z: 0.0 + orientation: + x: 0.0 + y: 0.000143222258878 + z: 0.0 + w: 0.999999989744 + covariance: [13.842310625721803, -4.5550871937325395e-07, 0.0, 0.0, -0.0005047845330959829, 0.0, -4.5550871937325385e-07, 13.842309323195375, 0.0, 0.0, 0.00031065607197886604, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005047845330959832, 0.00031065607197886626, 0.0, 0.0, 13.534258568386209, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 235 + stamp: + secs: 1624875211 + nsecs: 480456114 + frame_id: "/world" +pose: + pose: + position: + x: 0.161538348852 + y: 0.0586548441264 + z: 0.0 + orientation: + x: 0.0 + y: 0.00116773426072 + z: 0.0 + w: 0.999999318198 + covariance: [13.822182974585413, -4.5919850382532313e-07, 0.0, 0.0, -0.0004903161024629613, 0.0, -4.5919850382532313e-07, 13.822181698535834, 0.0, 0.0, 0.00032942436033468324, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004903161024629615, 0.0003294243603346834, 0.0, 0.0, 13.52191104594252, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 236 + stamp: + secs: 1624875211 + nsecs: 560573101 + frame_id: "/world" +pose: + pose: + position: + x: 0.161553724235 + y: 0.0584032445552 + z: 0.0 + orientation: + x: 0.0 + y: 0.000757716635465 + z: 0.0 + w: 0.999999712933 + covariance: [16.0140726133697, -6.103580354188074e-07, 0.0, 0.0, -0.0005938518863159128, 0.0, -6.103580354188073e-07, 16.01407095895082, 0.0, 0.0, 0.00038954479525431105, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005938518863159131, 0.0003895447952543112, 0.0, 0.0, 15.627403280388316, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 237 + stamp: + secs: 1624875211 + nsecs: 640486956 + frame_id: "/world" +pose: + pose: + position: + x: 0.161583863767 + y: 0.0580979516583 + z: 0.0 + orientation: + x: 0.0 + y: 0.000200449722067 + z: 0.0 + w: 0.99999997991 + covariance: [17.558524052630588, -7.411129632413095e-07, 0.0, 0.0, -0.0007128657059650457, 0.0, -7.411129632413093e-07, 17.558522080010544, 0.0, 0.0, 0.00040878848846817996, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007128657059650459, 0.00040878848846818, 0.0, 0.0, 17.100196475726346, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 238 + stamp: + secs: 1624875211 + nsecs: 720500946 + frame_id: "/world" +pose: + pose: + position: + x: 0.161598290596 + y: 0.0578148007595 + z: 0.0 + orientation: + x: -0.0 + y: -0.000337928936087 + z: -0.0 + w: 0.999999942902 + covariance: [18.624289932822855, -8.641194543206052e-07, 0.0, 0.0, -0.0008241260771612317, 0.0, -8.641194543206049e-07, 18.624287662313826, 0.0, 0.0, 0.0004050833338288385, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008241260771612319, 0.0004050833338288387, 0.0, 0.0, 18.100434493014724, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 239 + stamp: + secs: 1624875211 + nsecs: 800513029 + frame_id: "/world" +pose: + pose: + position: + x: 0.161611113042 + y: 0.0575594163361 + z: 0.0 + orientation: + x: -0.0 + y: -0.000591622752475 + z: -0.0 + w: 0.999999824991 + covariance: [19.31428307852607, -9.131038258270765e-07, 0.0, 0.0, -0.0007991960772466283, 0.0, -9.131038258270762e-07, 19.31428069891496, 0.0, 0.0, 0.0003645158369812062, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007991960772466284, 0.00036451583698120634, 0.0, 0.0, 18.76577942763237, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 240 + stamp: + secs: 1624875211 + nsecs: 880506992 + frame_id: "/world" +pose: + pose: + position: + x: 0.161625212478 + y: 0.0572750710021 + z: 0.0 + orientation: + x: -0.0 + y: -0.000491902651009 + z: -0.0 + w: 0.999999879016 + covariance: [19.793353778010633, -9.88644018934245e-07, 0.0, 0.0, -0.0007535076556016807, 0.0, -9.886440189342447e-07, 19.79335121960438, 0.0, 0.0, 0.0003267662447286305, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007535076556016807, 0.0003267662447286307, 0.0, 0.0, 19.20218348179904, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 241 + stamp: + secs: 1624875211 + nsecs: 960508108 + frame_id: "/world" +pose: + pose: + position: + x: 0.161640424986 + y: 0.0569569387196 + z: 0.0 + orientation: + x: -0.0 + y: -0.000304465914277 + z: -0.0 + w: 0.99999995365 + covariance: [20.13207464478425, -1.0836036387409429e-06, 0.0, 0.0, -0.0008543898852829514, 0.0, -1.0836036387409427e-06, 20.132071847500356, 0.0, 0.0, 0.00028901070437233696, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008543898852829516, 0.00028901070437233707, 0.0, 0.0, 19.486157644269653, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 242 + stamp: + secs: 1624875212 + nsecs: 40527105 + frame_id: "/world" +pose: + pose: + position: + x: 0.161656207805 + y: 0.0566152537542 + z: 0.0 + orientation: + x: -0.0 + y: -0.000368056302965 + z: -0.0 + w: 0.999999932267 + covariance: [20.371604262729324, -1.177721129451926e-06, 0.0, 0.0, -0.0009930039182592775, 0.0, -1.1777211294519256e-06, 20.371601211306846, 0.0, 0.0, 0.00025049949680957113, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009930039182592773, 0.0002504994968095713, 0.0, 0.0, 19.67002703041774, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 243 + stamp: + secs: 1624875212 + nsecs: 120568991 + frame_id: "/world" +pose: + pose: + position: + x: 0.161672669525 + y: 0.0562580822593 + z: 0.0 + orientation: + x: -0.0 + y: -0.000577547255893 + z: -0.0 + w: 0.99999983322 + covariance: [20.55034506569027, -1.2729285915735258e-06, 0.0, 0.0, -0.0010066531667928399, 0.0, -1.2729285915735256e-06, 20.550341753522574, 0.0, 0.0, 0.0002146827639892466, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010066531667928397, 0.0002146827639892467, 0.0, 0.0, 19.78864395887087, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 244 + stamp: + secs: 1624875212 + nsecs: 200536013 + frame_id: "/world" +pose: + pose: + position: + x: 0.161683998572 + y: 0.0560100557244 + z: 0.0 + orientation: + x: -0.0 + y: -0.000688550266905 + z: -0.0 + w: 0.999999762949 + covariance: [20.567223776829714, -1.1649874368647393e-06, 0.0, 0.0, -0.0008495042642364259, 0.0, -1.1649874368647391e-06, 20.567220738177532, 0.0, 0.0, 0.00016828812373319226, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008495042642364255, 0.0001682881237331923, 0.0, 0.0, 19.86500579654188, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 245 + stamp: + secs: 1624875212 + nsecs: 280575037 + frame_id: "/world" +pose: + pose: + position: + x: 0.161697544325 + y: 0.0557108135882 + z: 0.0 + orientation: + x: -0.0 + y: -0.000704176431039 + z: -0.0 + w: 0.999999752068 + covariance: [20.61819131131803, -1.1581910539994494e-06, 0.0, 0.0, -0.0007457047517328126, 0.0, -1.1581910539994491e-06, 20.61818828116052, 0.0, 0.0, 0.00013877177236456707, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007457047517328123, 0.0001387717723645671, 0.0, 0.0, 19.913609800502538, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 246 + stamp: + secs: 1624875212 + nsecs: 360554934 + frame_id: "/world" +pose: + pose: + position: + x: 0.161710373733 + y: 0.0554211434994 + z: 0.0 + orientation: + x: -0.0 + y: -0.000691328776155 + z: -0.0 + w: 0.999999761032 + covariance: [20.641839568481497, -1.1339458170675572e-06, 0.0, 0.0, -0.0006358438073505402, 0.0, -1.1339458170675567e-06, 20.641836594131092, 0.0, 0.0, 0.00011675173504920058, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00063584380735054, 0.00011675173504920062, 0.0, 0.0, 19.94525610746541, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 247 + stamp: + secs: 1624875212 + nsecs: 440562963 + frame_id: "/world" +pose: + pose: + position: + x: 0.1617219679 + y: 0.0551296756693 + z: 0.0 + orientation: + x: -0.0 + y: -0.000786489360542 + z: -0.0 + w: 0.999999690717 + covariance: [20.65578180634075, -1.1120525735330814e-06, 0.0, 0.0, -0.0005657477066797772, 0.0, -1.112052573533081e-06, 20.655778882972516, 0.0, 0.0, 0.00011556712264428747, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000565747706679777, 0.00011556712264428748, 0.0, 0.0, 19.965349296437992, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 248 + stamp: + secs: 1624875212 + nsecs: 520561934 + frame_id: "/world" +pose: + pose: + position: + x: 0.161732485442 + y: 0.0548297019487 + z: 0.0 + orientation: + x: -0.0 + y: -0.000432195456419 + z: -0.0 + w: 0.999999906604 + covariance: [20.661960248859145, -1.0901376910477697e-06, 0.0, 0.0, -0.000653239762902536, 0.0, -1.090137691047769e-06, 20.66195736975083, 0.0, 0.0, 0.00011872062373598926, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006532397629025356, 0.00011872062373598926, 0.0, 0.0, 19.977437662887287, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 249 + stamp: + secs: 1624875212 + nsecs: 600589991 + frame_id: "/world" +pose: + pose: + position: + x: 0.161742532976 + y: 0.0545234269197 + z: 0.0 + orientation: + x: 0.0 + y: 0.000292720760676 + z: 0.0 + w: 0.999999957157 + covariance: [20.66484658424566, -1.0705195861397184e-06, 0.0, 0.0, -0.0007298042164265321, 0.0, -1.0705195861397177e-06, 20.664843737703492, 0.0, 0.0, 0.00011879600002094637, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007298042164265319, 0.00011879600002094637, 0.0, 0.0, 19.985390049009897, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 250 + stamp: + secs: 1624875212 + nsecs: 680576086 + frame_id: "/world" +pose: + pose: + position: + x: 0.161752372282 + y: 0.0542253944589 + z: 0.0 + orientation: + x: 0.0 + y: 0.000487520427273 + z: 0.0 + w: 0.999999881162 + covariance: [20.66073318518629, -1.0435616363973497e-06, 0.0, 0.0, -0.0006854672125088796, 0.0, -1.0435616363973493e-06, 20.66073039570676, 0.0, 0.0, 0.00010812457128015007, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006854672125088792, 0.0001081245712801501, 0.0, 0.0, 19.990637384664122, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 251 + stamp: + secs: 1624875212 + nsecs: 760581970 + frame_id: "/world" +pose: + pose: + position: + x: 0.161758824895 + y: 0.0539241688121 + z: 0.0 + orientation: + x: 0.0 + y: 0.000621267645801 + z: 0.0 + w: 0.999999807013 + covariance: [20.6569374550032, -1.0222595519441305e-06, 0.0, 0.0, -0.00066709761786493, 0.0, -1.02225955194413e-06, 20.656934713115255, 0.0, 0.0, 0.00015028876544516723, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006670976178649299, 0.0001502887654451673, 0.0, 0.0, 19.99438031508344, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 252 + stamp: + secs: 1624875212 + nsecs: 840596914 + frame_id: "/world" +pose: + pose: + position: + x: 0.161758852826 + y: 0.0536246703924 + z: 0.0 + orientation: + x: 0.0 + y: 0.00100870163523 + z: 0.0 + w: 0.99999949126 + covariance: [20.648448702420296, -1.0002699106859015e-06, 0.0, 0.0, -0.0006668209592742035, 0.0, -1.0002699106859011e-06, 20.64844602267259, 0.0, 0.0, 0.00024818442760564244, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006668209592742033, 0.00024818442760564244, 0.0, 0.0, 19.996965668880804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 253 + stamp: + secs: 1624875212 + nsecs: 920597076 + frame_id: "/world" +pose: + pose: + position: + x: 0.161755940648 + y: 0.0533227568686 + z: 0.0 + orientation: + x: 0.0 + y: 0.000953381316296 + z: 0.0 + w: 0.999999545532 + covariance: [20.642469655982424, -9.847425083080167e-07, 0.0, 0.0, -0.0006421708127048097, 0.0, -9.847425083080162e-07, 20.64246702869571, 0.0, 0.0, 0.00031895530683423114, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006421708127048094, 0.0003189553068342311, 0.0, 0.0, 19.998260907111515, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 254 + stamp: + secs: 1624875213 + nsecs: 623941 + frame_id: "/world" +pose: + pose: + position: + x: 0.161751777141 + y: 0.0530212290526 + z: 0.0 + orientation: + x: 0.0 + y: 0.000837590833752 + z: 0.0 + w: 0.999999649221 + covariance: [20.63647397129081, -9.697222822338338e-07, 0.0, 0.0, -0.0006029729959861455, 0.0, -9.697222822338333e-07, 20.63647139710939, 0.0, 0.0, 0.00034983574687772574, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006029729959861451, 0.00034983574687772574, 0.0, 0.0, 19.999347303770776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 255 + stamp: + secs: 1624875213 + nsecs: 80640078 + frame_id: "/world" +pose: + pose: + position: + x: 0.161747656232 + y: 0.0527763105905 + z: 0.0 + orientation: + x: 0.0 + y: 0.0011344306991 + z: 0.0 + w: 0.999999356533 + covariance: [20.586689747348874, -8.875588111125368e-07, 0.0, 0.0, -0.0004859529206797198, 0.0, -8.875588111125365e-07, 20.586687401808568, 0.0, 0.0, 0.0003276657620349954, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004859529206797196, 0.0003276657620349954, 0.0, 0.0, 20.00129262322976, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 256 + stamp: + secs: 1624875213 + nsecs: 160621881 + frame_id: "/world" +pose: + pose: + position: + x: 0.161742075909 + y: 0.0524473886552 + z: 0.0 + orientation: + x: 0.0 + y: 0.00130157855144 + z: 0.0 + w: 0.999999152946 + covariance: [20.619169933053872, -9.279591538286531e-07, 0.0, 0.0, -0.0003852686020293624, 0.0, -9.279591538286529e-07, 20.61916749453015, 0.0, 0.0, 0.0003218792028106905, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00038526860202936226, 0.00032187920281069056, 0.0, 0.0, 20.000701039706907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 257 + stamp: + secs: 1624875213 + nsecs: 240650892 + frame_id: "/world" +pose: + pose: + position: + x: 0.161736493403 + y: 0.0521324514021 + z: 0.0 + orientation: + x: 0.0 + y: 0.0010009563412 + z: 0.0 + w: 0.999999499043 + covariance: [20.63405542345888, -9.402424523801291e-07, 0.0, 0.0, -0.0003062650195429578, 0.0, -9.402424523801291e-07, 20.634052963579546, 0.0, 0.0, 0.00029509970017957713, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00030626501954295765, 0.00029509970017957724, 0.0, 0.0, 20.001332607790257, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 258 + stamp: + secs: 1624875213 + nsecs: 320632935 + frame_id: "/world" +pose: + pose: + position: + x: 0.161731942674 + y: 0.0518730881755 + z: 0.0 + orientation: + x: 0.0 + y: 0.00102681778025 + z: 0.0 + w: 0.999999472822 + covariance: [20.59397084198086, -8.733191335974788e-07, 0.0, 0.0, -0.0003396274077230073, 0.0, -8.733191335974788e-07, 20.593968564439862, 0.0, 0.0, 0.0002460919083574306, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00033962740772300716, 0.0002460919083574307, 0.0, 0.0, 20.001707130589228, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 259 + stamp: + secs: 1624875213 + nsecs: 400671005 + frame_id: "/world" +pose: + pose: + position: + x: 0.161715084092 + y: 0.0515299025851 + z: 0.0 + orientation: + x: 0.0 + y: 0.00106514939196 + z: 0.0 + w: 0.999999432728 + covariance: [20.62284388843462, -9.143154077650458e-07, 0.0, 0.0, -0.0005003031446944228, 0.0, -9.143154077650462e-07, 20.622841530563264, 0.0, 0.0, 0.00039331779072221743, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005003031446944227, 0.0003933177907222176, 0.0, 0.0, 20.001724877854983, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 260 + stamp: + secs: 1624875213 + nsecs: 480642080 + frame_id: "/world" +pose: + pose: + position: + x: 0.161683565969 + y: 0.0511598507831 + z: 0.0 + orientation: + x: 0.0 + y: 0.000909642051876 + z: 0.0 + w: 0.999999586276 + covariance: [20.682225832388646, -9.963271420497e-07, 0.0, 0.0, -0.00031753759118988964, 0.0, -9.963271420497002e-07, 20.682223316509344, 0.0, 0.0, 0.000623411542805777, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003175375911898894, 0.0006234115428057769, 0.0, 0.0, 20.001424650525646, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 261 + stamp: + secs: 1624875213 + nsecs: 560708046 + frame_id: "/world" +pose: + pose: + position: + x: 0.161653070458 + y: 0.0508190346948 + z: 0.0 + orientation: + x: 0.0 + y: 0.000722106449865 + z: 0.0 + w: 0.999999739281 + covariance: [20.720890322343386, -1.0292022160935584e-06, 0.0, 0.0, 1.592121187500839e-05, 0.0, -1.0292022160935588e-06, 20.720887732128823, 0.0, 0.0, 0.0006840876957238006, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 1.592121187500855e-05, 0.0006840876957238004, 0.0, 0.0, 20.001214497012647, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 262 + stamp: + secs: 1624875213 + nsecs: 640685081 + frame_id: "/world" +pose: + pose: + position: + x: 0.16162266205 + y: 0.050479441103 + z: 0.0 + orientation: + x: 0.0 + y: 0.000930296455535 + z: 0.0 + w: 0.999999567274 + covariance: [20.751654723820394, -1.0478683765368218e-06, 0.0, 0.0, 0.00018277197446218616, 0.0, -1.047868376536822e-06, 20.75165207998453, 0.0, 0.0, 0.000663359615461486, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.00018277197446218635, 0.0006633596154614859, 0.0, 0.0, 20.002334105147366, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 263 + stamp: + secs: 1624875213 + nsecs: 720674992 + frame_id: "/world" +pose: + pose: + position: + x: 0.161592852215 + y: 0.0501467900562 + z: 0.0 + orientation: + x: 0.0 + y: 0.00108422367378 + z: 0.0 + w: 0.999999412229 + covariance: [20.770153592142115, -1.0489642752413406e-06, 0.0, 0.0, 0.00025080793027525654, 0.0, -1.0489642752413406e-06, 20.77015093502726, 0.0, 0.0, 0.0005998944360574351, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0002508079302752567, 0.0005998944360574351, 0.0, 0.0, 20.002028002866073, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 264 + stamp: + secs: 1624875213 + nsecs: 800682068 + frame_id: "/world" +pose: + pose: + position: + x: 0.161562872315 + y: 0.0498197911699 + z: 0.0 + orientation: + x: 0.0 + y: 0.00114536243357 + z: 0.0 + w: 0.999999344072 + covariance: [20.77956417800249, -1.037995932575425e-06, 0.0, 0.0, 0.0002606509342371993, 0.0, -1.0379959325754252e-06, 20.779561538635075, 0.0, 0.0, 0.0005315668304889258, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.00026065093423719945, 0.0005315668304889258, 0.0, 0.0, 20.002967065374335, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 265 + stamp: + secs: 1624875213 + nsecs: 880716085 + frame_id: "/world" +pose: + pose: + position: + x: 0.16153214513 + y: 0.0494920429299 + z: 0.0 + orientation: + x: 0.0 + y: 0.00195760177349 + z: 0.0 + w: 0.999998083896 + covariance: [20.786749146473156, -1.0249488287919102e-06, 0.0, 0.0, 0.00022310562218394293, 0.0, -1.0249488287919104e-06, 20.786746533426943, 0.0, 0.0, 0.00046782865883747367, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.000223105622183943, 0.00046782865883747356, 0.0, 0.0, 20.007843995442958, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 266 + stamp: + secs: 1624875213 + nsecs: 960705042 + frame_id: "/world" +pose: + pose: + position: + x: 0.161500546724 + y: 0.0491624407426 + z: 0.0 + orientation: + x: 0.0 + y: 0.00224412577269 + z: 0.0 + w: 0.999997481947 + covariance: [20.793493786283165, -1.0119242689319505e-06, 0.0, 0.0, 0.00017114373365800234, 0.0, -1.011924268931951e-06, 20.793491201768695, 0.0, 0.0, 0.00041343799077500436, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.00017114373365800236, 0.0004134379907750042, 0.0, 0.0, 20.006257439376988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 267 + stamp: + secs: 1624875214 + nsecs: 40746927 + frame_id: "/world" +pose: + pose: + position: + x: 0.170558749759 + y: 0.0488838807287 + z: 0.0 + orientation: + x: 0.0 + y: 0.00151097075954 + z: 0.0 + w: 0.999998858483 + covariance: [20.740840102988617, -9.271734559476981e-07, 0.0, 0.0, 0.00012630146044822615, 0.0, -9.271734559476984e-07, 20.74083773194887, 0.0, 0.0, 0.00036270452853438346, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.00012630146044822615, 0.00036270452853438324, 0.0, 0.0, 20.00418922251163, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 268 + stamp: + secs: 1624875214 + nsecs: 120723009 + frame_id: "/world" +pose: + pose: + position: + x: 0.162768582574 + y: 0.0552152456575 + z: 0.0 + orientation: + x: 0.0 + y: 0.00232287605053 + z: 0.0 + w: 0.99999730212 + covariance: [20.737436091650157, -9.044045311653334e-07, 0.0, 0.0, 8.90451146030691e-05, 0.0, -9.044045311653337e-07, 20.737433776575756, 0.0, 0.0, 0.0003379795366924856, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 8.90451146030691e-05, 0.00033797953669248545, 0.0, 0.0, 20.00376096063892, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 269 + stamp: + secs: 1624875214 + nsecs: 200736046 + frame_id: "/world" +pose: + pose: + position: + x: 0.162800444322 + y: 0.0548295346662 + z: 0.0 + orientation: + x: 0.0 + y: 0.00191101854746 + z: 0.0 + w: 0.999998174002 + covariance: [20.698023634651317, -8.406444794470279e-07, 0.0, 0.0, 5.692005774215475e-05, 0.0, -8.406444794470283e-07, 20.698021481470928, 0.0, 0.0, 0.0002925977992148294, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 5.692005774215475e-05, 0.0002925977992148293, 0.0, 0.0, 20.004434571369686, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 270 + stamp: + secs: 1624875214 + nsecs: 280742884 + frame_id: "/world" +pose: + pose: + position: + x: 0.162775848308 + y: 0.0545524826579 + z: 0.0 + orientation: + x: 0.0 + y: 0.00173090475688 + z: 0.0 + w: 0.999998501983 + covariance: [20.711298872372147, -8.416718018767334e-07, 0.0, 0.0, -7.991142563289961e-05, 0.0, -8.41671801876734e-07, 20.711296720280913, 0.0, 0.0, 0.0002662364149982742, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.99114256328996e-05, 0.000266236414998274, 0.0, 0.0, 20.003840126338233, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 271 + stamp: + secs: 1624875214 + nsecs: 360743999 + frame_id: "/world" +pose: + pose: + position: + x: 0.162752347498 + y: 0.0542839216059 + z: 0.0 + orientation: + x: 0.0 + y: 0.00157063618485 + z: 0.0 + w: 0.99999876655 + covariance: [20.705737071388874, -8.225472084279941e-07, 0.0, 0.0, -0.00022869309170810162, 0.0, -8.225472084279946e-07, 20.7057349715286, 0.0, 0.0, 0.00023354223444010366, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00022869309170810162, 0.0002335422344401035, 0.0, 0.0, 20.004635311787222, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 272 + stamp: + secs: 1624875214 + nsecs: 440733910 + frame_id: "/world" +pose: + pose: + position: + x: 0.162728724549 + y: 0.0540213111932 + z: 0.0 + orientation: + x: 0.0 + y: 0.0019274199208 + z: 0.0 + w: 0.999998142524 + covariance: [20.687518847282984, -7.913050423702986e-07, 0.0, 0.0, -0.0004039840013347071, 0.0, -7.91305042370299e-07, 20.687516827659792, 0.0, 0.0, 0.00021871605049879545, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000403984001334707, 0.00021871605049879532, 0.0, 0.0, 20.007473285520295, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 273 + stamp: + secs: 1624875214 + nsecs: 520785093 + frame_id: "/world" +pose: + pose: + position: + x: 0.162704686541 + y: 0.0537602711117 + z: 0.0 + orientation: + x: 0.0 + y: 0.00154178187868 + z: 0.0 + w: 0.999998811454 + covariance: [20.66491007607508, -7.577694203742778e-07, 0.0, 0.0, -0.0005490171547236896, 0.0, -7.577694203742782e-07, 20.664908137725888, 0.0, 0.0, 0.00020904427680939992, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005490171547236894, 0.00020904427680939986, 0.0, 0.0, 20.003321126301664, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 274 + stamp: + secs: 1624875214 + nsecs: 600769043 + frame_id: "/world" +pose: + pose: + position: + x: 0.162679687954 + y: 0.0534980341522 + z: 0.0 + orientation: + x: 0.0 + y: 0.00046600185664 + z: 0.0 + w: 0.999999891421 + covariance: [20.647707116537024, -7.312971877712592e-07, 0.0, 0.0, -0.0006015375841126266, 0.0, -7.312971877712596e-07, 20.647705240192032, 0.0, 0.0, 0.00020436439829636628, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006015375841126264, 0.00020436439829636622, 0.0, 0.0, 20.001196108133147, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 275 + stamp: + secs: 1624875214 + nsecs: 680773020 + frame_id: "/world" +pose: + pose: + position: + x: 0.162653740416 + y: 0.05323508429 + z: 0.0 + orientation: + x: 0.0 + y: 4.54413180674e-05 + z: 0.0 + w: 0.999999998968 + covariance: [20.633933686151074, -7.0956090022862e-07, 0.0, 0.0, -0.0006037423883783023, 0.0, -7.095609002286201e-07, 20.633931860325248, 0.0, 0.0, 0.00019976939216298137, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006037423883783023, 0.00019976939216298135, 0.0, 0.0, 20.000751659457908, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 276 + stamp: + secs: 1624875214 + nsecs: 760782957 + frame_id: "/world" +pose: + pose: + position: + x: 0.16262772406 + y: 0.0529704696988 + z: 0.0 + orientation: + x: -0.0 + y: -1.11535060463e-05 + z: -0.0 + w: 0.999999999938 + covariance: [20.623724037120503, -6.917894069199149e-07, 0.0, 0.0, -0.000584307716895742, 0.0, -6.917894069199151e-07, 20.62372225084427, 0.0, 0.0, 0.00018357508041095047, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000584307716895742, 0.00018357508041095047, 0.0, 0.0, 20.000410657496108, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 277 + stamp: + secs: 1624875214 + nsecs: 840786934 + frame_id: "/world" +pose: + pose: + position: + x: 0.162601508849 + y: 0.0527052841034 + z: 0.0 + orientation: + x: -0.0 + y: -2.25210597149e-05 + z: -0.0 + w: 0.999999999746 + covariance: [20.615548534022757, -6.762402945985347e-07, 0.0, 0.0, -0.0005472522575175168, 0.0, -6.762402945985349e-07, 20.615546781855187, 0.0, 0.0, 0.0001657896527496541, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005472522575175169, 0.0001657896527496541, 0.0, 0.0, 20.00029193741773, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 278 + stamp: + secs: 1624875214 + nsecs: 920783043 + frame_id: "/world" +pose: + pose: + position: + x: 0.162576133978 + y: 0.0524507262866 + z: 0.0 + orientation: + x: 0.0 + y: 9.61466366046e-05 + z: 0.0 + w: 0.999999995378 + covariance: [20.599461886779764, -6.520194312784196e-07, 0.0, 0.0, -0.0004908327417855123, 0.0, -6.520194312784199e-07, 20.599460192470453, 0.0, 0.0, 0.00014646592893456417, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004908327417855126, 0.00014646592893456417, 0.0, 0.0, 20.0003362226886, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 279 + stamp: + secs: 1624875215 + nsecs: 812054 + frame_id: "/world" +pose: + pose: + position: + x: 0.162550582216 + y: 0.0522045884132 + z: 0.0 + orientation: + x: 0.0 + y: 0.000351035794111 + z: 0.0 + w: 0.999999938387 + covariance: [20.5793314737984, -6.240221326598273e-07, 0.0, 0.0, -0.0004287150676580984, 0.0, -6.240221326598276e-07, 20.579329849462052, 0.0, 0.0, 0.00014169052043131863, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00042871506765809856, 0.00014169052043131863, 0.0, 0.0, 20.00062436178246, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 280 + stamp: + secs: 1624875215 + nsecs: 80796003 + frame_id: "/world" +pose: + pose: + position: + x: 0.162513180984 + y: 0.0518581847377 + z: 0.0 + orientation: + x: 0.0 + y: 0.000147991373756 + z: 0.0 + w: 0.999999989049 + covariance: [20.655624784043354, -6.978142184183057e-07, 0.0, 0.0, -0.00040365880205901034, 0.0, -6.978142184183057e-07, 20.655622966017948, 0.0, 0.0, 0.00016305726861329606, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00040365880205901045, 0.000163057268613296, 0.0, 0.0, 20.000008362107646, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 281 + stamp: + secs: 1624875215 + nsecs: 160804033 + frame_id: "/world" +pose: + pose: + position: + x: 0.1624857888 + y: 0.0516043506176 + z: 0.0 + orientation: + x: -0.0 + y: -0.000191124759285 + z: -0.0 + w: 0.999999981736 + covariance: [20.630381194029106, -6.632394048144913e-07, 0.0, 0.0, -0.0003478979304880035, 0.0, -6.632394048144913e-07, 20.63037946473694, 0.0, 0.0, 0.00014746077366116747, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003478979304880036, 0.0001474607736611674, 0.0, 0.0, 20.000002915448064, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 282 + stamp: + secs: 1624875215 + nsecs: 240817070 + frame_id: "/world" +pose: + pose: + position: + x: 0.162452710047 + y: 0.0512971708706 + z: 0.0 + orientation: + x: -0.0 + y: -0.00020099560729 + z: -0.0 + w: 0.9999999798 + covariance: [20.659282152686703, -6.846602664046609e-07, 0.0, 0.0, -0.0003319449118813775, 0.0, -6.846602664046608e-07, 20.659280365805124, 0.0, 0.0, 0.00013718299564862162, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003319449118813776, 0.00013718299564862156, 0.0, 0.0, 20.000008738253356, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 283 + stamp: + secs: 1624875215 + nsecs: 320810080 + frame_id: "/world" +pose: + pose: + position: + x: 0.16239979279 + y: 0.0508003724103 + z: 0.0 + orientation: + x: -0.0 + y: -0.000208300109191 + z: -0.0 + w: 0.999999978306 + covariance: [20.8722155057111, -8.894922911066705e-07, 0.0, 0.0, -0.0004473297827182661, 0.0, -8.8949229110667e-07, 20.87221317923689, 0.0, 0.0, 0.000143531600829799, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00044732978271826634, 0.00014353160082979896, 0.0, 0.0, 20.000004723422208, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 284 + stamp: + secs: 1624875215 + nsecs: 400810003 + frame_id: "/world" +pose: + pose: + position: + x: 0.162371002879 + y: 0.0505432545842 + z: 0.0 + orientation: + x: 0.0 + y: 9.50800776774e-05 + z: 0.0 + w: 0.99999999548 + covariance: [20.792092011421158, -7.977816121172167e-07, 0.0, 0.0, -0.00044453227629551363, 0.0, -7.977816121172166e-07, 20.792089923220797, 0.0, 0.0, 0.00014406784163026995, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00044453227629551374, 0.00014406784163026993, 0.0, 0.0, 20.0000946405043, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 285 + stamp: + secs: 1624875215 + nsecs: 480870008 + frame_id: "/world" +pose: + pose: + position: + x: 0.162333972411 + y: 0.0502276930857 + z: 0.0 + orientation: + x: 0.0 + y: 0.000376395377119 + z: 0.0 + w: 0.999999929163 + covariance: [20.78263852954081, -7.80121643488602e-07, 0.0, 0.0, -0.0005341650736032816, 0.0, -7.801216434886016e-07, 20.782636486188736, 0.0, 0.0, 0.00017410089177941776, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005341650736032816, 0.00017410089177941778, 0.0, 0.0, 20.000114702344504, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 286 + stamp: + secs: 1624875215 + nsecs: 560842037 + frame_id: "/world" +pose: + pose: + position: + x: 0.16229926048 + y: 0.0499245335949 + z: 0.0 + orientation: + x: -0.0 + y: -0.000201333062044 + z: -0.0 + w: 0.999999979732 + covariance: [20.760572316875358, -7.501817804371899e-07, 0.0, 0.0, -0.0005647225844258641, 0.0, -7.501817804371896e-07, 20.760570347769306, 0.0, 0.0, 0.00016438312126154992, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005647225844258642, 0.00016438312126154997, 0.0, 0.0, 20.000266221317, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 287 + stamp: + secs: 1624875215 + nsecs: 640876055 + frame_id: "/world" +pose: + pose: + position: + x: 0.162264563691 + y: 0.0496225891964 + z: 0.0 + orientation: + x: -0.0 + y: -0.000422537504587 + z: -0.0 + w: 0.999999910731 + covariance: [20.74346059778606, -7.248706576023869e-07, 0.0, 0.0, -0.0005262227655620526, 0.0, -7.248706576023867e-07, 20.743458691970147, 0.0, 0.0, 0.00014954454785856813, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005262227655620526, 0.00014954454785856815, 0.0, 0.0, 20.00001468917229, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 288 + stamp: + secs: 1624875215 + nsecs: 720865965 + frame_id: "/world" +pose: + pose: + position: + x: 0.162227663496 + y: 0.0493254422883 + z: 0.0 + orientation: + x: -0.0 + y: -0.000255068823089 + z: -0.0 + w: 0.99999996747 + covariance: [20.723959026822413, -6.991669181966224e-07, 0.0, 0.0, -0.0004975397508841813, 0.0, -6.99166918196622e-07, 20.723957189679407, 0.0, 0.0, 0.00017575181672932046, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004975397508841812, 0.00017575181672932046, 0.0, 0.0, 20.000148639271465, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 289 + stamp: + secs: 1624875215 + nsecs: 800864935 + frame_id: "/world" +pose: + pose: + position: + x: 0.162185250681 + y: 0.0490246623393 + z: 0.0 + orientation: + x: -0.0 + y: -0.000297087705719 + z: -0.0 + w: 0.999999955869 + covariance: [20.70226500030047, -6.773216235269457e-07, 0.0, 0.0, -0.0006134545051771166, 0.0, -6.773216235269452e-07, 20.702263228411702, 0.0, 0.0, 0.0002701453432097663, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006134545051771164, 0.0002701453432097662, 0.0, 0.0, 20.000067559696028, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 290 + stamp: + secs: 1624875215 + nsecs: 880872965 + frame_id: "/world" +pose: + pose: + position: + x: 0.16213937813 + y: 0.0487195545205 + z: 0.0 + orientation: + x: -0.0 + y: -0.000211426890352 + z: -0.0 + w: 0.999999977649 + covariance: [20.68158973466781, -6.625242207778437e-07, 0.0, 0.0, -0.0007393502092005424, 0.0, -6.625242207778433e-07, 20.681588015964515, 0.0, 0.0, 0.00034889597252729177, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007393502092005421, 0.00034889597252729177, 0.0, 0.0, 20.00009607502927, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 291 + stamp: + secs: 1624875215 + nsecs: 960884094 + frame_id: "/world" +pose: + pose: + position: + x: 0.162092396441 + y: 0.0484138830175 + z: 0.0 + orientation: + x: 0.0 + y: 1.7755637071e-05 + z: 0.0 + w: 0.999999999842 + covariance: [20.66609459885883, -6.529462677754265e-07, 0.0, 0.0, -0.0007537188739933198, 0.0, -6.529462677754262e-07, 20.666092922459335, 0.0, 0.0, 0.00038046894739539365, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007537188739933196, 0.0003804689473953937, 0.0, 0.0, 20.00000926579327, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 292 + stamp: + secs: 1624875216 + nsecs: 40893078 + frame_id: "/world" +pose: + pose: + position: + x: 0.162041346744 + y: 0.0481082903742 + z: 0.0 + orientation: + x: 0.0 + y: 3.11490417932e-05 + z: 0.0 + w: 0.999999999515 + covariance: [20.654175868466083, -6.48318466614775e-07, 0.0, 0.0, -0.000707748557197155, 0.0, -6.483184666147745e-07, 20.654174231137212, 0.0, 0.0, 0.00043073265178365615, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007077485571971547, 0.0004307326517836562, 0.0, 0.0, 20.000054480089748, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 293 + stamp: + secs: 1624875216 + nsecs: 120889902 + frame_id: "/world" +pose: + pose: + position: + x: 0.161977161381 + y: 0.0476562131705 + z: 0.0 + orientation: + x: -0.0 + y: -0.000262217718639 + z: -0.0 + w: 0.999999965621 + covariance: [20.6934352844889, -7.435558852719146e-07, 0.0, 0.0, -0.002102208331530969, 0.0, -7.435558852719143e-07, 20.69343330479393, 0.0, 0.0, 0.0004991909971219595, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0021022083315309684, 0.0004991909971219595, 0.0, 0.0, 20.000080297019384, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 294 + stamp: + secs: 1624875216 + nsecs: 200895071 + frame_id: "/world" +pose: + pose: + position: + x: 0.161925177121 + y: 0.0472178149548 + z: 0.0 + orientation: + x: -0.0 + y: -0.000238012407611 + z: -0.0 + w: 0.999999971675 + covariance: [20.666066993906185, -7.874965017448961e-07, 0.0, 0.0, -0.0033349000268777206, 0.0, -7.874965017448959e-07, 20.66606438759467, 0.0, 0.0, 0.00046299027781704247, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0033349000268777197, 0.0004629902778170424, 0.0, 0.0, 20.000078787139667, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 295 + stamp: + secs: 1624875216 + nsecs: 280922890 + frame_id: "/world" +pose: + pose: + position: + x: 0.161873170743 + y: 0.0467792551784 + z: 0.0 + orientation: + x: -0.0 + y: -0.000337887815924 + z: -0.0 + w: 0.999999942916 + covariance: [20.64507051227236, -8.228421215798722e-07, 0.0, 0.0, -0.003720176479059717, 0.0, -8.228421215798717e-07, 20.645067204375298, 0.0, 0.0, 0.00041043437820396765, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0037201764790597155, 0.0004104343782039677, 0.0, 0.0, 20.000241921216286, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 296 + stamp: + secs: 1624875216 + nsecs: 360913038 + frame_id: "/world" +pose: + pose: + position: + x: 0.161823093775 + y: 0.0463582959346 + z: 0.0 + orientation: + x: -0.0 + y: -0.000400454526335 + z: -0.0 + w: 0.999999919818 + covariance: [20.620131805254047, -8.364727619926463e-07, 0.0, 0.0, -0.0035728698044949596, 0.0, -8.364727619926459e-07, 20.620127934260882, 0.0, 0.0, 0.00034947764450218643, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.003572869804494958, 0.00034947764450218654, 0.0, 0.0, 20.00021327421349, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 297 + stamp: + secs: 1624875216 + nsecs: 440912962 + frame_id: "/world" +pose: + pose: + position: + x: 0.161765041745 + y: 0.0458723005337 + z: 0.0 + orientation: + x: -0.0 + y: -0.000327457180896 + z: -0.0 + w: 0.999999946386 + covariance: [20.637981274357475, -9.058528939420069e-07, 0.0, 0.0, -0.003363758283619958, 0.0, -9.058528939420065e-07, 20.637976548019864, 0.0, 0.0, 0.0003041672665353959, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0033637582836199566, 0.00030416726653539596, 0.0, 0.0, 20.000188228015507, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 298 + stamp: + secs: 1624875216 + nsecs: 520924091 + frame_id: "/world" +pose: + pose: + position: + x: 0.161709907846 + y: 0.045420067695 + z: 0.0 + orientation: + x: -0.0 + y: -0.000378738599043 + z: -0.0 + w: 0.999999928279 + covariance: [20.63360499228382, -9.34583057204464e-07, 0.0, 0.0, -0.0029558905992569146, 0.0, -9.345830572044635e-07, 20.633599722156738, 0.0, 0.0, 0.00027250772382459554, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.002955890599256914, 0.00027250772382459554, 0.0, 0.0, 20.00034661057524, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 299 + stamp: + secs: 1624875216 + nsecs: 600929976 + frame_id: "/world" +pose: + pose: + position: + x: 0.161655703577 + y: 0.0449853287192 + z: 0.0 + orientation: + x: -0.0 + y: -0.000516233099285 + z: -0.0 + w: 0.999999866752 + covariance: [20.620579205158332, -9.438094389586085e-07, 0.0, 0.0, -0.0025119759251275584, 0.0, -9.438094389586082e-07, 20.620573586169243, 0.0, 0.0, 0.00025039803438461786, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0025119759251275575, 0.0002503980343846178, 0.0, 0.0, 20.000515084583263, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 300 + stamp: + secs: 1624875216 + nsecs: 680928946 + frame_id: "/world" +pose: + pose: + position: + x: 0.161589226998 + y: 0.0444567437742 + z: 0.0 + orientation: + x: -0.0 + y: -0.000500314847216 + z: -0.0 + w: 0.999999874843 + covariance: [20.661410675227515, -1.0369918610605247e-06, 0.0, 0.0, -0.002267233587483667, 0.0, -1.0369918610605243e-06, 20.661404185762716, 0.0, 0.0, 0.0002495313300150435, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0022672335874836655, 0.0002495313300150435, 0.0, 0.0, 20.000350348584234, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 301 + stamp: + secs: 1624875216 + nsecs: 760956049 + frame_id: "/world" +pose: + pose: + position: + x: 0.161518165693 + y: 0.0438972404468 + z: 0.0 + orientation: + x: -0.0 + y: -0.000122674273703 + z: -0.0 + w: 0.999999992476 + covariance: [20.710720801826188, -1.1401841317730176e-06, 0.0, 0.0, -0.002068194267513167, 0.0, -1.140184131773017e-06, 20.710713398288004, 0.0, 0.0, 0.0002527027299433043, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0020681942675131668, 0.00025270272994330425, 0.0, 0.0, 20.000026213405423, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 302 + stamp: + secs: 1624875216 + nsecs: 840961933 + frame_id: "/world" +pose: + pose: + position: + x: 0.161437967833 + y: 0.043265723339 + z: 0.0 + orientation: + x: 0.0 + y: 0.00039691636233 + z: 0.0 + w: 0.999999921229 + covariance: [20.793620475391354, -1.2930620102859225e-06, 0.0, 0.0, -0.001931225026227353, 0.0, -1.2930620102859221e-06, 20.793611828158905, 0.0, 0.0, 0.0002511965972886196, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0019312250262273523, 0.00025119659728861947, 0.0, 0.0, 20.000094105984928, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 303 + stamp: + secs: 1624875216 + nsecs: 920965910 + frame_id: "/world" +pose: + pose: + position: + x: 0.161372785408 + y: 0.0427491747583 + z: 0.0 + orientation: + x: 0.0 + y: 0.000551844271027 + z: 0.0 + w: 0.999999847734 + covariance: [20.786760524980693, -1.288560115057128e-06, 0.0, 0.0, -0.0017186086481936918, 0.0, -1.2885601150571278e-06, 20.786751748117744, 0.0, 0.0, 0.00022473908636468895, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0017186086481936907, 0.0002247390863646888, 0.0, 0.0, 20.000176253924103, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 304 + stamp: + secs: 1624875217 + nsecs: 967979 + frame_id: "/world" +pose: + pose: + position: + x: 0.161299969479 + y: 0.0421703256166 + z: 0.0 + orientation: + x: 0.0 + y: 0.000859000883043 + z: 0.0 + w: 0.999999631059 + covariance: [20.81587356909352, -1.3407616106388121e-06, 0.0, 0.0, -0.0016152316504781529, 0.0, -1.3407616106388117e-06, 20.815864287753975, 0.0, 0.0, 0.00020870192199873167, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001615231650478152, 0.0002087019219987315, 0.0, 0.0, 20.001048563978756, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 305 + stamp: + secs: 1624875217 + nsecs: 80965996 + frame_id: "/world" +pose: + pose: + position: + x: 0.161233757134 + y: 0.0416312213863 + z: 0.0 + orientation: + x: 0.0 + y: 0.0012177961037 + z: 0.0 + w: 0.999999258486 + covariance: [20.812647879248143, -1.3318993175990537e-06, 0.0, 0.0, -0.0014725188558029835, 0.0, -1.3318993175990533e-06, 20.81263853407752, 0.0, 0.0, 0.00016408005378911069, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0014725188558029827, 0.00016408005378911058, 0.0, 0.0, 20.00184225836238, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 306 + stamp: + secs: 1624875217 + nsecs: 160985947 + frame_id: "/world" +pose: + pose: + position: + x: 0.161171433254 + y: 0.0411132939917 + z: 0.0 + orientation: + x: 0.0 + y: 0.00144615439909 + z: 0.0 + w: 0.999998954318 + covariance: [20.796180899505075, -1.2965083363311475e-06, 0.0, 0.0, -0.0013066262791414994, 0.0, -1.2965083363311475e-06, 20.796171694562247, 0.0, 0.0, 0.00011652521216749084, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013066262791414983, 0.00011652521216749076, 0.0, 0.0, 20.00313164065976, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 307 + stamp: + secs: 1624875217 + nsecs: 240998983 + frame_id: "/world" +pose: + pose: + position: + x: 0.161102842217 + y: 0.0405445804932 + z: 0.0 + orientation: + x: 0.0 + y: 0.00163795534348 + z: 0.0 + w: 0.99999865855 + covariance: [20.814121860000874, -1.314475792890502e-06, 0.0, 0.0, -0.0011550389132877637, 0.0, -1.314475792890502e-06, 20.81411243261102, 0.0, 0.0, 8.703164490934267e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011550389132877628, 8.703164490934262e-05, 0.0, 0.0, 20.00382570758238, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 308 + stamp: + secs: 1624875217 + nsecs: 320986986 + frame_id: "/world" +pose: + pose: + position: + x: 0.161015218096 + y: 0.0398179500227 + z: 0.0 + orientation: + x: 0.0 + y: 0.00152125108186 + z: 0.0 + w: 0.999998842897 + covariance: [20.928738482579853, -1.4811213077917854e-06, 0.0, 0.0, -0.0010654064058135924, 0.0, -1.4811213077917859e-06, 20.928727756312142, 0.0, 0.0, 6.846741154178876e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010654064058135918, 6.84674115417887e-05, 0.0, 0.0, 20.00315778935062, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 309 + stamp: + secs: 1624875217 + nsecs: 400985956 + frame_id: "/world" +pose: + pose: + position: + x: 0.160952506582 + y: 0.0393025526889 + z: 0.0 + orientation: + x: 0.0 + y: 0.00134697179697 + z: 0.0 + w: 0.999999092833 + covariance: [20.878942735889567, -1.3863600351930417e-06, 0.0, 0.0, -0.001044172636771669, 0.0, -1.3863600351930421e-06, 20.87893264231307, 0.0, 0.0, 8.259748097017452e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010441726367716683, 8.259748097017445e-05, 0.0, 0.0, 20.004019419190875, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 310 + stamp: + secs: 1624875217 + nsecs: 481002092 + frame_id: "/world" +pose: + pose: + position: + x: 0.160889291288 + y: 0.0387905955488 + z: 0.0 + orientation: + x: 0.0 + y: 0.00143228165645 + z: 0.0 + w: 0.999998974284 + covariance: [20.829164327163323, -1.2977278149738822e-06, 0.0, 0.0, -0.0011597888142339298, 0.0, -1.2977278149738827e-06, 20.829154839433034, 0.0, 0.0, 0.00012230066891430838, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001159788814233929, 0.00012230066891430832, 0.0, 0.0, 20.004377955714432, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 311 + stamp: + secs: 1624875217 + nsecs: 561059952 + frame_id: "/world" +pose: + pose: + position: + x: 0.160826219118 + y: 0.0382825908911 + z: 0.0 + orientation: + x: 0.0 + y: 0.00126155970792 + z: 0.0 + w: 0.999999204233 + covariance: [20.786246231546325, -1.222328763312125e-06, 0.0, 0.0, -0.0011833492220971584, 0.0, -1.2223287633121261e-06, 20.786237269317127, 0.0, 0.0, 0.00014448251588197953, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011833492220971577, 0.00014448251588197947, 0.0, 0.0, 20.003500334665404, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 312 + stamp: + secs: 1624875217 + nsecs: 641020060 + frame_id: "/world" +pose: + pose: + position: + x: 0.160755045723 + y: 0.0377087345275 + z: 0.0 + orientation: + x: 0.0 + y: 0.000961312508988 + z: 0.0 + w: 0.999999537939 + covariance: [20.789560801586738, -1.2183241571085118e-06, 0.0, 0.0, -0.0011698884435242748, 0.0, -1.218324157108513e-06, 20.78955184683916, 0.0, 0.0, 0.00015288235856695167, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011698884435242744, 0.00015288235856695162, 0.0, 0.0, 20.002622095090707, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 313 + stamp: + secs: 1624875217 + nsecs: 721040964 + frame_id: "/world" +pose: + pose: + position: + x: 0.160698298375 + y: 0.037256135634 + z: 0.0 + orientation: + x: 0.0 + y: 0.00127854651875 + z: 0.0 + w: 0.999999182659 + covariance: [20.725026976007904, -1.1101260990733781e-06, 0.0, 0.0, -0.0010214820436043933, 0.0, -1.1101260990733794e-06, 20.72501880969629, 0.0, 0.0, 0.00014784471484805684, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010214820436043927, 0.00014784471484805678, 0.0, 0.0, 20.00569077829132, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 314 + stamp: + secs: 1624875217 + nsecs: 801040888 + frame_id: "/world" +pose: + pose: + position: + x: 0.160628446104 + y: 0.0367142899433 + z: 0.0 + orientation: + x: 0.0 + y: 0.00175280179163 + z: 0.0 + w: 0.999998463842 + covariance: [20.722888487070183, -1.0994511145891653e-06, 0.0, 0.0, -0.0009294177232807143, 0.0, -1.0994511145891662e-06, 20.72288040853553, 0.0, 0.0, 0.00017255174770127764, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009294177232807137, 0.0001725517477012776, 0.0, 0.0, 20.005160255881986, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 315 + stamp: + secs: 1624875217 + nsecs: 881045103 + frame_id: "/world" +pose: + pose: + position: + x: 0.16055476771 + y: 0.0361753532931 + z: 0.0 + orientation: + x: 0.0 + y: 0.00140503407086 + z: 0.0 + w: 0.999999012939 + covariance: [20.719250348195565, -1.0887785396343112e-06, 0.0, 0.0, -0.0008383745574200791, 0.0, -1.0887785396343123e-06, 20.719242386309645, 0.0, 0.0, 0.00023923119252675996, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008383745574200783, 0.00023923119252675985, 0.0, 0.0, 20.00422707191085, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 316 + stamp: + secs: 1624875217 + nsecs: 961061954 + frame_id: "/world" +pose: + pose: + position: + x: 0.160480684924 + y: 0.0356554774549 + z: 0.0 + orientation: + x: 0.0 + y: 0.00104844152137 + z: 0.0 + w: 0.999999450385 + covariance: [20.706138008902055, -1.064253746663794e-06, 0.0, 0.0, -0.0007369635858607742, 0.0, -1.0642537466637948e-06, 20.706130276801186, 0.0, 0.0, 0.0002921303672285344, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007369635858607736, 0.0002921303672285344, 0.0, 0.0, 20.003110090469296, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 317 + stamp: + secs: 1624875218 + nsecs: 41070938 + frame_id: "/world" +pose: + pose: + position: + x: 0.160408003766 + y: 0.0351304617076 + z: 0.0 + orientation: + x: 0.0 + y: 0.00086260705066 + z: 0.0 + w: 0.999999627954 + covariance: [20.686380157907305, -1.0364064310717715e-06, 0.0, 0.0, -0.0010095401347704198, 0.0, -1.0364064310717717e-06, 20.6863726902438, 0.0, 0.0, 0.00031425700244328345, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010095401347704196, 0.0003142570024432834, 0.0, 0.0, 20.00286613104907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 318 + stamp: + secs: 1624875218 + nsecs: 121073961 + frame_id: "/world" +pose: + pose: + position: + x: 0.160323333661 + y: 0.0345002281587 + z: 0.0 + orientation: + x: 0.0 + y: 0.00107251951093 + z: 0.0 + w: 0.999999424851 + covariance: [20.709612935362706, -1.0851443724768963e-06, 0.0, 0.0, -0.001515309733415238, 0.0, -1.085144372476897e-06, 20.709605186088748, 0.0, 0.0, 0.0003369727563395624, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0015153097334152379, 0.00033697275633956243, 0.0, 0.0, 20.00389857262301, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 319 + stamp: + secs: 1624875218 + nsecs: 201076984 + frame_id: "/world" +pose: + pose: + position: + x: 0.160233121887 + y: 0.0338274455151 + z: 0.0 + orientation: + x: 0.0 + y: 0.00122854427494 + z: 0.0 + w: 0.999999245339 + covariance: [20.74932202236467, -1.156809149690564e-06, 0.0, 0.0, -0.001726490298478896, 0.0, -1.156809149690565e-06, 20.749313806530374, 0.0, 0.0, 0.00033232839472280084, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0017264902984788957, 0.0003323283947228009, 0.0, 0.0, 20.003662970173433, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 320 + stamp: + secs: 1624875218 + nsecs: 281084061 + frame_id: "/world" +pose: + pose: + position: + x: 0.16015779676 + y: 0.0332643992136 + z: 0.0 + orientation: + x: 0.0 + y: 0.00121013824097 + z: 0.0 + w: 0.999999267782 + covariance: [20.724854539061365, -1.1236651724048098e-06, 0.0, 0.0, -0.001676407226939717, 0.0, -1.1236651724048104e-06, 20.72484658127838, 0.0, 0.0, 0.0002972081286882326, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0016764072269397172, 0.0002972081286882327, 0.0, 0.0, 20.00424515216363, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 321 + stamp: + secs: 1624875218 + nsecs: 361097097 + frame_id: "/world" +pose: + pose: + position: + x: 0.160070496157 + y: 0.032614570537 + z: 0.0 + orientation: + x: 0.0 + y: 0.00118782664209 + z: 0.0 + w: 0.999999294534 + covariance: [20.74602677039448, -1.1628204421565693e-06, 0.0, 0.0, -0.0016606882137924009, 0.0, -1.1628204421565697e-06, 20.746018561162302, 0.0, 0.0, 0.0002831862007554831, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0016606882137924009, 0.0002831862007554832, 0.0, 0.0, 20.00334848641612, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 322 + stamp: + secs: 1624875218 + nsecs: 441102982 + frame_id: "/world" +pose: + pose: + position: + x: 0.159985390084 + y: 0.0319862596812 + z: 0.0 + orientation: + x: 0.0 + y: 0.000694074789324 + z: 0.0 + w: 0.99999975913 + covariance: [20.75296201327784, -1.1754256694349716e-06, 0.0, 0.0, -0.0015132420769921678, 0.0, -1.1754256694349722e-06, 20.752953741035746, 0.0, 0.0, 0.00026191887775933167, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001513242076992168, 0.0002619188777593318, 0.0, 0.0, 20.00157930857842, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 323 + stamp: + secs: 1624875218 + nsecs: 521126986 + frame_id: "/world" +pose: + pose: + position: + x: 0.159903253868 + y: 0.0313806543171 + z: 0.0 + orientation: + x: 0.0 + y: 0.000692116963689 + z: 0.0 + w: 0.999999760487 + covariance: [20.747697272223963, -1.164848388212891e-06, 0.0, 0.0, -0.0013136531363351057, 0.0, -1.1648483882128916e-06, 20.747689093954993, 0.0, 0.0, 0.00023071110545953957, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001313653136335106, 0.00023071110545953968, 0.0, 0.0, 20.002814842554187, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 324 + stamp: + secs: 1624875218 + nsecs: 601133108 + frame_id: "/world" +pose: + pose: + position: + x: 0.159822568621 + y: 0.0307811165327 + z: 0.0 + orientation: + x: 0.0 + y: 0.00084407470487 + z: 0.0 + w: 0.999999643769 + covariance: [20.73883052633613, -1.1465929771651227e-06, 0.0, 0.0, -0.0011809587447069927, 0.0, -1.146592977165123e-06, 20.738822486511594, 0.0, 0.0, 0.0001966970300161578, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011809587447069929, 0.00019669703001615784, 0.0, 0.0, 20.002000277593957, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 325 + stamp: + secs: 1624875218 + nsecs: 681112051 + frame_id: "/world" +pose: + pose: + position: + x: 0.159729504564 + y: 0.030083818306 + z: 0.0 + orientation: + x: 0.0 + y: 0.00104192787977 + z: 0.0 + w: 0.999999457193 + covariance: [20.777851371440995, -1.2006527253794518e-06, 0.0, 0.0, -0.0011433726216507388, 0.0, -1.200652725379452e-06, 20.777842956220812, 0.0, 0.0, 0.00017113989880327836, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011433726216507386, 0.0001711398988032784, 0.0, 0.0, 20.003873520074052, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 326 + stamp: + secs: 1624875218 + nsecs: 761149883 + frame_id: "/world" +pose: + pose: + position: + x: 0.159642760115 + y: 0.029432128097 + z: 0.0 + orientation: + x: 0.0 + y: 0.00146039736415 + z: 0.0 + w: 0.999998933619 + covariance: [20.78683588222587, -1.204151443054739e-06, 0.0, 0.0, -0.00102504227980001, 0.0, -1.2041514430547397e-06, 20.78682744299188, 0.0, 0.0, 0.00014088033482266283, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010250422798000096, 0.00014088033482266291, 0.0, 0.0, 20.00496455729258, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 327 + stamp: + secs: 1624875218 + nsecs: 841130018 + frame_id: "/world" +pose: + pose: + position: + x: 0.159568576009 + y: 0.028880526286 + z: 0.0 + orientation: + x: 0.0 + y: 0.00159445018171 + z: 0.0 + w: 0.999998728864 + covariance: [20.74394501373731, -1.1284570298426436e-06, 0.0, 0.0, -0.0008795736629207193, 0.0, -1.1284570298426442e-06, 20.74393711040587, 0.0, 0.0, 0.00012779959821879555, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008795736629207192, 0.0001277995982187956, 0.0, 0.0, 20.00609191488779, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 328 + stamp: + secs: 1624875218 + nsecs: 921133995 + frame_id: "/world" +pose: + pose: + position: + x: 0.159486047397 + y: 0.0282879709869 + z: 0.0 + orientation: + x: 0.0 + y: 0.0011070091597 + z: 0.0 + w: 0.999999387265 + covariance: [20.72877798027312, -1.0976991615576195e-06, 0.0, 0.0, -0.0008128279126514634, 0.0, -1.09769916155762e-06, 20.72877031479769, 0.0, 0.0, 0.0001641843354055838, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008128279126514633, 0.00016418433540558387, 0.0, 0.0, 20.00225626089652, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 329 + stamp: + secs: 1624875219 + nsecs: 1161098 + frame_id: "/world" +pose: + pose: + position: + x: 0.159407480512 + y: 0.0277387301592 + z: 0.0 + orientation: + x: 0.0 + y: 0.000201645548053 + z: 0.0 + w: 0.99999997967 + covariance: [20.697013971063765, -1.0423259501065553e-06, 0.0, 0.0, -0.0006928016480857839, 0.0, -1.0423259501065558e-06, 20.697006720310092, 0.0, 0.0, 0.00019157545748115605, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006928016480857837, 0.00019157545748115607, 0.0, 0.0, 20.000714278853486, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 330 + stamp: + secs: 1624875219 + nsecs: 81146002 + frame_id: "/world" +pose: + pose: + position: + x: 0.15931751802 + y: 0.0271081921155 + z: 0.0 + orientation: + x: -0.0 + y: -3.19963751269e-05 + z: -0.0 + w: 0.999999999488 + covariance: [20.70912994276209, -1.0516850804438625e-06, 0.0, 0.0, -0.0006663974001348203, 0.0, -1.0516850804438627e-06, 20.709122655279046, 0.0, 0.0, 0.00020539324838565078, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00066639740013482, 0.0002053932483856508, 0.0, 0.0, 20.000674253949907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 331 + stamp: + secs: 1624875219 + nsecs: 161160946 + frame_id: "/world" +pose: + pose: + position: + x: 0.159238043091 + y: 0.0265468518856 + z: 0.0 + orientation: + x: 0.0 + y: 4.19835723275e-05 + z: 0.0 + w: 0.999999999119 + covariance: [20.684306085510467, -1.0062857211648324e-06, 0.0, 0.0, -0.0006534008204134142, 0.0, -1.0062857211648326e-06, 20.684299133686405, 0.0, 0.0, 0.00019137826332782208, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006534008204134141, 0.00019137826332782214, 0.0, 0.0, 20.000401618304906, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 332 + stamp: + secs: 1624875219 + nsecs: 241172075 + frame_id: "/world" +pose: + pose: + position: + x: 0.159158799218 + y: 0.0259870437568 + z: 0.0 + orientation: + x: -0.0 + y: -1.2688915543e-05 + z: -0.0 + w: 0.999999999919 + covariance: [20.664823548040584, -9.68114362951079e-07, 0.0, 0.0, -0.0005931138572846118, 0.0, -9.681143629510792e-07, 20.664816877178165, 0.0, 0.0, 0.000169276288089482, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005931138572846116, 0.0001692762880894821, 0.0, 0.0, 20.00021636370725, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 333 + stamp: + secs: 1624875219 + nsecs: 321162939 + frame_id: "/world" +pose: + pose: + position: + x: 0.159081850202 + y: 0.0254437814398 + z: 0.0 + orientation: + x: -0.0 + y: -3.41676105308e-05 + z: -0.0 + w: 0.999999999416 + covariance: [20.642767897781685, -9.259964080798568e-07, 0.0, 0.0, -0.0005106631486115327, 0.0, -9.259964080798567e-07, 20.642761531097815, 0.0, 0.0, 0.00014449891291986377, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005106631486115325, 0.00014449891291986385, 0.0, 0.0, 20.000134886318946, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 334 + stamp: + secs: 1624875219 + nsecs: 401169062 + frame_id: "/world" +pose: + pose: + position: + x: 0.158998408177 + y: 0.02485492262 + z: 0.0 + orientation: + x: -0.0 + y: -0.000140220022997 + z: -0.0 + w: 0.999999990169 + covariance: [20.64646094314798, -9.200886431600163e-07, 0.0, 0.0, -0.0004360912451261229, 0.0, -9.200886431600163e-07, 20.64645463023765, 0.0, 0.0, 0.0001236654566403315, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00043609124512612285, 0.00012366545664033155, 0.0, 0.0, 20.000010354793005, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 335 + stamp: + secs: 1624875219 + nsecs: 481182098 + frame_id: "/world" +pose: + pose: + position: + x: 0.158914037921 + y: 0.0242696028623 + z: 0.0 + orientation: + x: -0.0 + y: -0.000431802356032 + z: -0.0 + w: 0.999999906773 + covariance: [20.64557144850664, -9.087735112175001e-07, 0.0, 0.0, -0.000465759311318279, 0.0, -9.087735112175002e-07, 20.645565231523555, 0.0, 0.0, 0.00014053659256826718, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00046575931131827904, 0.00014053659256826724, 0.0, 0.0, 20.000116442231338, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 336 + stamp: + secs: 1624875219 + nsecs: 561197996 + frame_id: "/world" +pose: + pose: + position: + x: 0.158829077004 + y: 0.023688989642 + z: 0.0 + orientation: + x: -0.0 + y: -0.000492899518145 + z: -0.0 + w: 0.999999878525 + covariance: [20.640195865548186, -8.929546264666004e-07, 0.0, 0.0, -0.0005354138648876461, 0.0, -8.929546264666006e-07, 20.640189781516693, 0.0, 0.0, 0.00016683189389081086, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005354138648876464, 0.0001668318938908109, 0.0, 0.0, 20.00007964601121, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 337 + stamp: + secs: 1624875219 + nsecs: 641206980 + frame_id: "/world" +pose: + pose: + position: + x: 0.158730609156 + y: 0.0230136647507 + z: 0.0 + orientation: + x: -0.0 + y: -0.00011817234789 + z: -0.0 + w: 0.999999993018 + covariance: [20.677061074724083, -9.350102620462788e-07, 0.0, 0.0, -0.0006190010889725351, 0.0, -9.350102620462788e-07, 20.677054731978007, 0.0, 0.0, 0.00018072870218925174, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006190010889725354, 0.00018072870218925182, 0.0, 0.0, 20.000010709539012, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 338 + stamp: + secs: 1624875219 + nsecs: 721213102 + frame_id: "/world" +pose: + pose: + position: + x: 0.158642473572 + y: 0.0224088032312 + z: 0.0 + orientation: + x: 0.0 + y: 0.0002304152562 + z: 0.0 + w: 0.999999973454 + covariance: [20.674389784633966, -9.218828630758284e-07, 0.0, 0.0, -0.0006263674049085682, 0.0, -9.21882863075828e-07, 20.67438355255239, 0.0, 0.0, 0.00017288419011543259, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006263674049085685, 0.00017288419011543264, 0.0, 0.0, 20.000102331367543, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 339 + stamp: + secs: 1624875219 + nsecs: 801218987 + frame_id: "/world" +pose: + pose: + position: + x: 0.158540106021 + y: 0.0216979472807 + z: 0.0 + orientation: + x: 0.0 + y: 0.000392890325398 + z: 0.0 + w: 0.999999922819 + covariance: [20.716452877552996, -9.695754592957687e-07, 0.0, 0.0, -0.0007771007728684881, 0.0, -9.69575459295768e-07, 20.716446343791574, 0.0, 0.0, 0.00016746476728885431, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007771007728684886, 0.00016746476728885437, 0.0, 0.0, 20.000178817286134, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 340 + stamp: + secs: 1624875219 + nsecs: 881227016 + frame_id: "/world" +pose: + pose: + position: + x: 0.158457402751 + y: 0.0211106401788 + z: 0.0 + orientation: + x: 0.0 + y: 0.000371266465157 + z: 0.0 + w: 0.999999931081 + covariance: [20.690889105557766, -9.255276468604348e-07, 0.0, 0.0, -0.0008466977631648873, 0.0, -9.255276468604343e-07, 20.69088287020955, 0.0, 0.0, 0.00013298156817582508, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008466977631648876, 0.00013298156817582513, 0.0, 0.0, 20.000193085397452, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 341 + stamp: + secs: 1624875219 + nsecs: 961224079 + frame_id: "/world" +pose: + pose: + position: + x: 0.158377015199 + y: 0.0205344221653 + z: 0.0 + orientation: + x: 0.0 + y: 0.000354582113743 + z: 0.0 + w: 0.999999937136 + covariance: [20.666245349481443, -8.820944368038619e-07, 0.0, 0.0, -0.0008229220059457846, 0.0, -8.820944368038614e-07, 20.6662393999664, 0.0, 0.0, 9.68176936895264e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008229220059457849, 9.681769368952647e-05, 0.0, 0.0, 20.000233821687193, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 342 + stamp: + secs: 1624875220 + nsecs: 41249990 + frame_id: "/world" +pose: + pose: + position: + x: 0.158286563037 + y: 0.0198836489785 + z: 0.0 + orientation: + x: 0.0 + y: 9.34231867796e-05 + z: 0.0 + w: 0.999999995636 + covariance: [20.679590298468078, -8.876512830117536e-07, 0.0, 0.0, -0.0007872103670395861, 0.0, -8.876512830117529e-07, 20.679584300390953, 0.0, 0.0, 6.82818234724861e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007872103670395863, 6.828182347248616e-05, 0.0, 0.0, 20.000001517768425, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 343 + stamp: + secs: 1624875220 + nsecs: 121259928 + frame_id: "/world" +pose: + pose: + position: + x: 0.158201735523 + y: 0.0192698417793 + z: 0.0 + orientation: + x: -0.0 + y: -8.67815036117e-05 + z: -0.0 + w: 0.999999996234 + covariance: [20.674123096225347, -8.680226478955426e-07, 0.0, 0.0, -0.0007141991627531076, 0.0, -8.680226478955418e-07, 20.67411721809753, 0.0, 0.0, 4.3674189327397966e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0007141991627531078, 4.3674189327398007e-05, 0.0, 0.0, 20.000012345277252, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 344 + stamp: + secs: 1624875220 + nsecs: 201256037 + frame_id: "/world" +pose: + pose: + position: + x: 0.158118568123 + y: 0.0186712738534 + z: 0.0 + orientation: + x: 0.0 + y: 6.92966244807e-06 + z: 0.0 + w: 0.999999999976 + covariance: [20.66356270492448, -8.423439901455779e-07, 0.0, 0.0, -0.0006201714037730119, 0.0, -8.423439901455771e-07, 20.663556991705562, 0.0, 0.0, 3.56762868802865e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000620171403773012, 3.567628688028653e-05, 0.0, 0.0, 20.00001137548716, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 345 + stamp: + secs: 1624875220 + nsecs: 281263113 + frame_id: "/world" +pose: + pose: + position: + x: 0.158037940994 + y: 0.0180974096796 + z: 0.0 + orientation: + x: 0.0 + y: 0.000120282078338 + z: 0.0 + w: 0.999999992766 + covariance: [20.64537008431764, -8.079539051450016e-07, 0.0, 0.0, -0.0005122109993957025, 0.0, -8.079539051450008e-07, 20.6453646003625, 0.0, 0.0, 3.982857476695675e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005122109993957024, 3.9828574766956766e-05, 0.0, 0.0, 20.0000740828428, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 346 + stamp: + secs: 1624875220 + nsecs: 361269951 + frame_id: "/world" +pose: + pose: + position: + x: 0.157956875925 + y: 0.0175237187798 + z: 0.0 + orientation: + x: 0.0 + y: 0.000332305762711 + z: 0.0 + w: 0.999999944786 + covariance: [20.631492301500664, -7.794773770391211e-07, 0.0, 0.0, -0.0004198152170008819, 0.0, -7.794773770391204e-07, 20.63148700798186, 0.0, 0.0, 4.560322238032232e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004198152170008819, 4.560322238032233e-05, 0.0, 0.0, 20.00023976751301, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 347 + stamp: + secs: 1624875220 + nsecs: 441265106 + frame_id: "/world" +pose: + pose: + position: + x: 0.157864967584 + y: 0.016875128191 + z: 0.0 + orientation: + x: 0.0 + y: 0.000288295607662 + z: 0.0 + w: 0.999999958443 + covariance: [20.65327016064443, -7.937620558138228e-07, 0.0, 0.0, -0.00035155587946716476, 0.0, -7.937620558138223e-07, 20.65326476713428, 0.0, 0.0, 5.076951270163633e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00035155587946716465, 5.076951270163632e-05, 0.0, 0.0, 20.000058106548472, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 348 + stamp: + secs: 1624875220 + nsecs: 521287918 + frame_id: "/world" +pose: + pose: + position: + x: 0.157780752348 + y: 0.0162883899357 + z: 0.0 + orientation: + x: 0.0 + y: 0.000130664251933 + z: 0.0 + w: 0.999999991463 + covariance: [20.64400431197302, -7.71012002913126e-07, 0.0, 0.0, -0.00029931642497672795, 0.0, -7.710120029131257e-07, 20.643999072839097, 0.0, 0.0, 6.708122907235103e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00029931642497672795, 6.708122907235103e-05, 0.0, 0.0, 20.000064697848902, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 349 + stamp: + secs: 1624875220 + nsecs: 601290941 + frame_id: "/world" +pose: + pose: + position: + x: 0.157695472699 + y: 0.0157026727967 + z: 0.0 + orientation: + x: 0.0 + y: 0.000124284748211 + z: 0.0 + w: 0.999999992277 + covariance: [20.635832915480975, -7.503781095543408e-07, 0.0, 0.0, -0.0002812484944818067, 0.0, -7.503781095543405e-07, 20.63582781926224, 0.0, 0.0, 9.08308712418437e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002812484944818067, 9.083087124184368e-05, 0.0, 0.0, 20.000049870158083, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 350 + stamp: + secs: 1624875220 + nsecs: 681297064 + frame_id: "/world" +pose: + pose: + position: + x: 0.157610897575 + y: 0.0151183075518 + z: 0.0 + orientation: + x: -0.0 + y: -0.000103574171362 + z: -0.0 + w: 0.999999994636 + covariance: [20.62880361145428, -7.312416297365344e-07, 0.0, 0.0, -0.00026611504156141813, 0.0, -7.312416297365341e-07, 20.628798646999705, 0.0, 0.0, 8.94791483784892e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000266115041561418, 8.947914837848918e-05, 0.0, 0.0, 20.00002566680076, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 351 + stamp: + secs: 1624875220 + nsecs: 761307001 + frame_id: "/world" +pose: + pose: + position: + x: 0.157510952166 + y: 0.0144218091725 + z: 0.0 + orientation: + x: -0.0 + y: -0.000315629593933 + z: -0.0 + w: 0.999999950189 + covariance: [20.67234090758031, -7.685699078611064e-07, 0.0, 0.0, -0.00025511968045125545, 0.0, -7.685699078611063e-07, 20.672335690213384, 0.0, 0.0, 7.63556024276154e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002551196804512553, 7.63556024276154e-05, 0.0, 0.0, 20.000031242321462, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 352 + stamp: + secs: 1624875220 + nsecs: 841311932 + frame_id: "/world" +pose: + pose: + position: + x: 0.157412786419 + y: 0.0137497398706 + z: 0.0 + orientation: + x: -0.0 + y: -0.000366922107257 + z: -0.0 + w: 0.999999932684 + covariance: [20.697586348372432, -7.842454372681197e-07, 0.0, 0.0, -0.00022865384878145904, 0.0, -7.842454372681198e-07, 20.69758102830709, 0.0, 0.0, 9.117765038805897e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00022865384878145893, 9.117765038805896e-05, 0.0, 0.0, 20.000168375393216, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 353 + stamp: + secs: 1624875220 + nsecs: 921345949 + frame_id: "/world" +pose: + pose: + position: + x: 0.157312734259 + y: 0.0130794183741 + z: 0.0 + orientation: + x: -0.0 + y: -0.000222509740346 + z: -0.0 + w: 0.999999975245 + covariance: [20.717696574682265, -7.936712137673721e-07, 0.0, 0.0, -0.00020000306043691516, 0.0, -7.93671213767372e-07, 20.71769119735294, 0.0, 0.0, 0.00012082631834484578, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002000030604369151, 0.00012082631834484579, 0.0, 0.0, 20.000004275616025, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 354 + stamp: + secs: 1624875221 + nsecs: 1331091 + frame_id: "/world" +pose: + pose: + position: + x: 0.157220975465 + y: 0.0124608833195 + z: 0.0 + orientation: + x: -0.0 + y: -0.000514565632236 + z: -0.0 + w: 0.999999867611 + covariance: [20.70406906063207, -7.687399930678391e-07, 0.0, 0.0, -0.00039294076471866593, 0.0, -7.68739993067839e-07, 20.70406386537806, 0.0, 0.0, 0.0001455178844543886, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0003929407647186658, 0.0001455178844543886, 0.0, 0.0, 20.000943620837123, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 355 + stamp: + secs: 1624875221 + nsecs: 81346989 + frame_id: "/world" +pose: + pose: + position: + x: 0.157130524389 + y: 0.0118453082363 + z: 0.0 + orientation: + x: -0.0 + y: -0.000781661750156 + z: -0.0 + w: 0.999999694502 + covariance: [20.686444727464927, -7.431218438516786e-07, 0.0, 0.0, -0.0006312840377254331, 0.0, -7.431218438516784e-07, 20.68643972014311, 0.0, 0.0, 0.0001604217934042721, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000631284037725433, 0.0001604217934042721, 0.0, 0.0, 20.000525259080327, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 356 + stamp: + secs: 1624875221 + nsecs: 161340952 + frame_id: "/world" +pose: + pose: + position: + x: 0.157033686213 + y: 0.011189347781 + z: 0.0 + orientation: + x: -0.0 + y: -0.000587503199851 + z: -0.0 + w: 0.99999982742 + covariance: [20.69199330212741, -7.417664892758093e-07, 0.0, 0.0, -0.0006676475630537228, 0.0, -7.417664892758092e-07, 20.691988315483982, 0.0, 0.0, 0.00015822059699860993, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006676475630537227, 0.00015822059699860993, 0.0, 0.0, 20.00071915841384, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 357 + stamp: + secs: 1624875221 + nsecs: 241344929 + frame_id: "/world" +pose: + pose: + position: + x: 0.156941784066 + y: 0.0105691583828 + z: 0.0 + orientation: + x: -0.0 + y: -0.000702243842733 + z: -0.0 + w: 0.999999753427 + covariance: [20.6827691290608, -7.236245844501952e-07, 0.0, 0.0, -0.0005875357544164717, 0.0, -7.236245844501952e-07, 20.682764272904127, 0.0, 0.0, 0.00014154215511640118, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005875357544164717, 0.00014154215511640118, 0.0, 0.0, 20.001101270887286, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 358 + stamp: + secs: 1624875221 + nsecs: 321346045 + frame_id: "/world" +pose: + pose: + position: + x: 0.156812913657 + y: 0.00970012018088 + z: 0.0 + orientation: + x: -0.0 + y: -0.000870504836538 + z: -0.0 + w: 0.999999621111 + covariance: [20.785949593207626, -8.223856530849749e-07, 0.0, 0.0, -0.0006298286678019106, 0.0, -8.22385653084975e-07, 20.7859440875989, 0.0, 0.0, 0.00014833723622981017, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006298286678019104, 0.00014833723622981017, 0.0, 0.0, 20.00126823950756, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 359 + stamp: + secs: 1624875221 + nsecs: 401350975 + frame_id: "/world" +pose: + pose: + position: + x: 0.156708247943 + y: 0.00899615966393 + z: 0.0 + orientation: + x: -0.0 + y: -0.000639067240015 + z: -0.0 + w: 0.999999795797 + covariance: [20.79308304143612, -8.197435263718387e-07, 0.0, 0.0, -0.0006071034505387081, 0.0, -8.197435263718386e-07, 20.793077563577214, 0.0, 0.0, 0.00014164210732928563, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.000607103450538708, 0.0001416421073292856, 0.0, 0.0, 20.00077181167342, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 360 + stamp: + secs: 1624875221 + nsecs: 481375933 + frame_id: "/world" +pose: + pose: + position: + x: 0.156606852116 + y: 0.00831365695085 + z: 0.0 + orientation: + x: -0.0 + y: -0.000368392165123 + z: -0.0 + w: 0.999999932144 + covariance: [20.788648196892574, -8.047259991277277e-07, 0.0, 0.0, -0.0005628467487807399, 0.0, -8.047259991277278e-07, 20.78864282714855, 0.0, 0.0, 0.00012756676180324968, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005628467487807399, 0.00012756676180324965, 0.0, 0.0, 20.00048633719131, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 361 + stamp: + secs: 1624875221 + nsecs: 561382055 + frame_id: "/world" +pose: + pose: + position: + x: 0.156505631211 + y: 0.00763090237581 + z: 0.0 + orientation: + x: 0.0 + y: 3.76663577197e-07 + z: 0.0 + w: 1.0 + covariance: [20.785014845639214, -7.902449258913504e-07, 0.0, 0.0, -0.0005168679646392098, 0.0, -7.902449258913505e-07, 20.785009578384564, 0.0, 0.0, 0.00011090488301874536, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005168679646392099, 0.00011090488301874536, 0.0, 0.0, 20.000029109967233, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 362 + stamp: + secs: 1624875221 + nsecs: 641385078 + frame_id: "/world" +pose: + pose: + position: + x: 0.156404221332 + y: 0.00694810796535 + z: 0.0 + orientation: + x: 0.0 + y: 0.000567989151188 + z: 0.0 + w: 0.999999838694 + covariance: [20.782496876425242, -7.765920750304485e-07, 0.0, 0.0, -0.0004576699532627549, 0.0, -7.765920750304486e-07, 20.782491705646073, 0.0, 0.0, 9.78034417669808e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004576699532627548, 9.78034417669808e-05, 0.0, 0.0, 20.0002537684525, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 363 + stamp: + secs: 1624875221 + nsecs: 721393108 + frame_id: "/world" +pose: + pose: + position: + x: 0.156304272691 + y: 0.00627493628491 + z: 0.0 + orientation: + x: 0.0 + y: 0.00070712908035 + z: 0.0 + w: 0.999999749984 + covariance: [20.77541196180996, -7.585847053693611e-07, 0.0, 0.0, -0.0004300515632179827, 0.0, -7.585847053693612e-07, 20.775406915674132, 0.0, 0.0, 8.808388281717999e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00043005156321798254, 8.808388281717997e-05, 0.0, 0.0, 20.000197288925296, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 364 + stamp: + secs: 1624875221 + nsecs: 801403046 + frame_id: "/world" +pose: + pose: + position: + x: 0.156204693007 + y: 0.00560042917158 + z: 0.0 + orientation: + x: 0.0 + y: 0.000562982231156 + z: 0.0 + w: 0.999999841525 + covariance: [20.768760253936545, -7.412842191639886e-07, 0.0, 0.0, -0.00045002268087878847, 0.0, -7.412842191639886e-07, 20.768755325488893, 0.0, 0.0, 7.819898181687303e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00045002268087878836, 7.819898181687303e-05, 0.0, 0.0, 20.000318684065782, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 365 + stamp: + secs: 1624875221 + nsecs: 881417036 + frame_id: "/world" +pose: + pose: + position: + x: 0.156105209026 + y: 0.00492461612516 + z: 0.0 + orientation: + x: 0.0 + y: 0.00101973452154 + z: 0.0 + w: 0.999999480071 + covariance: [20.763317620897624, -7.252099907867666e-07, 0.0, 0.0, -0.0004634602304694881, 0.0, -7.252099907867667e-07, 20.76331280019966, 0.0, 0.0, 6.941029509982594e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00046346023046948796, 6.941029509982594e-05, 0.0, 0.0, 20.002181026498853, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 366 + stamp: + secs: 1624875221 + nsecs: 961416006 + frame_id: "/world" +pose: + pose: + position: + x: 0.155997996004 + y: 0.00420380853379 + z: 0.0 + orientation: + x: 0.0 + y: 0.00170453904585 + z: 0.0 + w: 0.999998547272 + covariance: [20.779136691253917, -7.292335680977055e-07, 0.0, 0.0, -0.0004722969962248904, 0.0, -7.292335680977056e-07, 20.779131847958865, 0.0, 0.0, 8.274038836261275e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00047229699622489016, 8.274038836261276e-05, 0.0, 0.0, 20.004280668222925, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 367 + stamp: + secs: 1624875222 + nsecs: 41435957 + frame_id: "/world" +pose: + pose: + position: + x: 0.155887572021 + y: 0.00352671991045 + z: 0.0 + orientation: + x: 0.0 + y: 0.0019597039688 + z: 0.0 + w: 0.999998079778 + covariance: [20.736983859227166, -7.239596510597972e-07, 0.0, 0.0, -0.0016707642807338512, 0.0, -7.239596510597971e-07, 20.73697918482915, 0.0, 0.0, 0.0004194086583789156, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0016707642807338517, 0.00041940865837891564, 0.0, 0.0, 20.00685488900616, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 368 + stamp: + secs: 1624875222 + nsecs: 121417046 + frame_id: "/world" +pose: + pose: + position: + x: 0.155763676333 + y: 0.00281863913944 + z: 0.0 + orientation: + x: 0.0 + y: 0.00218378517839 + z: 0.0 + w: 0.999997615538 + covariance: [20.688364639298523, -8.441800392786103e-07, 0.0, 0.0, -0.003034292232710272, 0.0, -8.441800392786103e-07, 20.68835972669695, 0.0, 0.0, 0.000813249797039473, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0030342922327102734, 0.0008132497970394732, 0.0, 0.0, 20.00914191313448, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 369 + stamp: + secs: 1624875222 + nsecs: 201446056 + frame_id: "/world" +pose: + pose: + position: + x: 0.155613734554 + y: 0.00197001207375 + z: 0.0 + orientation: + x: 0.0 + y: 0.00216156332752 + z: 0.0 + w: 0.999997663819 + covariance: [20.698377065120418, -1.1342650064572843e-06, 0.0, 0.0, -0.0038289259583123548, 0.0, -1.1342650064572845e-06, 20.698371202024788, 0.0, 0.0, 0.001064511673807411, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0038289259583123556, 0.001064511673807411, 0.0, 0.0, 20.008146861143434, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 370 + stamp: + secs: 1624875222 + nsecs: 281445026 + frame_id: "/world" +pose: + pose: + position: + x: 0.155440192759 + y: 0.000984488096916 + z: 0.0 + orientation: + x: 0.0 + y: 0.00174722317012 + z: 0.0 + w: 0.999998473604 + covariance: [20.753693628543743, -1.569775158850328e-06, 0.0, 0.0, -0.004252856668205558, 0.0, -1.5697751588503284e-06, 20.753686199116597, 0.0, 0.0, 0.0011868378194081766, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.004252856668205558, 0.0011868378194081763, 0.0, 0.0, 20.006757449419663, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 371 + stamp: + secs: 1624875222 + nsecs: 361438990 + frame_id: "/world" +pose: + pose: + position: + x: 0.155300276838 + y: 0.000188356934893 + z: 0.0 + orientation: + x: 0.0 + y: 0.00152779247057 + z: 0.0 + w: 0.999998832924 + covariance: [20.730724829164387, -1.7521223152363443e-06, 0.0, 0.0, -0.003905157600226667, 0.0, -1.7521223152363445e-06, 20.73071689425514, 0.0, 0.0, 0.0010866113633104283, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.003905157600226666, 0.001086611363310428, 0.0, 0.0, 20.007284529003837, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 372 + stamp: + secs: 1624875222 + nsecs: 441457987 + frame_id: "/world" +pose: + pose: + position: + x: 0.155163260014 + y: -0.000583192818771 + z: 0.0 + orientation: + x: 0.0 + y: 0.00144302168022 + z: 0.0 + w: 0.999998958844 + covariance: [20.703836373286276, -1.8846267363285303e-06, 0.0, 0.0, -0.0034478349842875467, 0.0, -1.8846267363285312e-06, 20.703828125208137, 0.0, 0.0, 0.0009763368589298458, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.003447834984287545, 0.0009763368589298456, 0.0, 0.0, 20.00635021967609, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 373 + stamp: + secs: 1624875222 + nsecs: 521461964 + frame_id: "/world" +pose: + pose: + position: + x: 0.155002969717 + y: -0.00147734267232 + z: 0.0 + orientation: + x: 0.0 + y: 0.00155320427646 + z: 0.0 + w: 0.999998793778 + covariance: [20.72416642890659, -2.1507640032388537e-06, 0.0, 0.0, -0.0031240336753270465, 0.0, -2.1507640032388546e-06, 20.724157308148136, 0.0, 0.0, 0.0009109686118442868, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0031240336753270456, 0.0009109686118442865, 0.0, 0.0, 20.008145600785948, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 374 + stamp: + secs: 1624875222 + nsecs: 601474047 + frame_id: "/world" +pose: + pose: + position: + x: 0.154839632657 + y: -0.00237193887772 + z: 0.0 + orientation: + x: 0.0 + y: 0.00152630679532 + z: 0.0 + w: 0.999998835193 + covariance: [20.739363559640463, -2.3794364126888178e-06, 0.0, 0.0, -0.0028101630481330033, 0.0, -2.379436412688818e-06, 20.739353729696745, 0.0, 0.0, 0.0008725466071699706, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.002810163048133003, 0.0008725466071699703, 0.0, 0.0, 20.006423962470638, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 375 + stamp: + secs: 1624875222 + nsecs: 681476116 + frame_id: "/world" +pose: + pose: + position: + x: 0.154679810868 + y: -0.0032367063325 + z: 0.0 + orientation: + x: 0.0 + y: 0.00130105721498 + z: 0.0 + w: 0.999999153625 + covariance: [20.739784275824327, -2.527244513442199e-06, 0.0, 0.0, -0.0024833526301344076, 0.0, -2.5272445134421988e-06, 20.73977404837287, 0.0, 0.0, 0.0008137714588820873, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.002483352630134407, 0.0008137714588820869, 0.0, 0.0, 20.00620600020181, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 376 + stamp: + secs: 1624875222 + nsecs: 761483908 + frame_id: "/world" +pose: + pose: + position: + x: 0.154524940906 + y: -0.00407902516349 + z: 0.0 + orientation: + x: 0.0 + y: 0.00119126099572 + z: 0.0 + w: 0.999999290448 + covariance: [20.73262163637809, -2.6080108171703307e-06, 0.0, 0.0, -0.0021269622541680014, 0.0, -2.6080108171703303e-06, 20.732611229331436, 0.0, 0.0, 0.0007096931401174388, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0021269622541680014, 0.0007096931401174385, 0.0, 0.0, 20.005258290308806, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 377 + stamp: + secs: 1624875222 + nsecs: 841490030 + frame_id: "/world" +pose: + pose: + position: + x: 0.154344350134 + y: -0.00506422615549 + z: 0.0 + orientation: + x: 0.0 + y: 0.000982632887378 + z: 0.0 + w: 0.999999517216 + covariance: [20.776012246754817, -2.862625961395717e-06, 0.0, 0.0, -0.001933146654430527, 0.0, -2.862625961395716e-06, 20.776000961631112, 0.0, 0.0, 0.0006336209915504408, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0019331466544305269, 0.0006336209915504406, 0.0, 0.0, 20.003902720961637, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 378 + stamp: + secs: 1624875222 + nsecs: 921515942 + frame_id: "/world" +pose: + pose: + position: + x: 0.154197798958 + y: -0.00586728860624 + z: 0.0 + orientation: + x: 0.0 + y: 0.00082216926806 + z: 0.0 + w: 0.999999662019 + covariance: [20.745032084354172, -2.800267378946476e-06, 0.0, 0.0, -0.0016821618961842637, 0.0, -2.800267378946475e-06, 20.745021122186433, 0.0, 0.0, 0.000526198331170989, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001682161896184264, 0.000526198331170989, 0.0, 0.0, 20.003583182145043, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 379 + stamp: + secs: 1624875223 + nsecs: 1523018 + frame_id: "/world" +pose: + pose: + position: + x: 0.154056804194 + y: -0.00663969488511 + z: 0.0 + orientation: + x: 0.0 + y: 0.000931445411726 + z: 0.0 + w: 0.999999566205 + covariance: [20.71011980233006, -2.7032655402496434e-06, 0.0, 0.0, -0.0014434900028164486, 0.0, -2.7032655402496426e-06, 20.71010927918576, 0.0, 0.0, 0.0004350204928219468, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0014434900028164489, 0.00043502049282194703, 0.0, 0.0, 20.004075744336216, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 380 + stamp: + secs: 1624875223 + nsecs: 81501961 + frame_id: "/world" +pose: + pose: + position: + x: 0.15385235361 + y: -0.00769546114219 + z: 0.0 + orientation: + x: 0.0 + y: 0.00142722346536 + z: 0.0 + w: 0.999998981516 + covariance: [20.779226356652085, -3.0209850771228206e-06, 0.0, 0.0, -0.0013887050877574845, 0.0, -3.0209850771228197e-06, 20.779214745881536, 0.0, 0.0, 0.0005847180282572756, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013887050877574845, 0.0005847180282572757, 0.0, 0.0, 20.00636992651554, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 381 + stamp: + secs: 1624875223 + nsecs: 161525011 + frame_id: "/world" +pose: + pose: + position: + x: 0.153661488455 + y: -0.00862267531756 + z: 0.0 + orientation: + x: 0.0 + y: 0.00158223382097 + z: 0.0 + w: 0.999998748267 + covariance: [20.7893730804891, -3.098140615712087e-06, 0.0, 0.0, -0.0012562824143973522, 0.0, -3.098140615712086e-06, 20.78936134971797, 0.0, 0.0, 0.0007450225593033366, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001256282414397352, 0.0007450225593033366, 0.0, 0.0, 20.006552935639156, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 382 + stamp: + secs: 1624875223 + nsecs: 241575956 + frame_id: "/world" +pose: + pose: + position: + x: 0.153466881244 + y: -0.00955159327139 + z: 0.0 + orientation: + x: 0.0 + y: 0.000994000493481 + z: 0.0 + w: 0.999999505981 + covariance: [20.796936575927223, -3.1537433129069546e-06, 0.0, 0.0, -0.001167353715093117, 0.0, -3.1537433129069533e-06, 20.796924804800828, 0.0, 0.0, 0.0008353408247890341, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011673537150931168, 0.0008353408247890344, 0.0, 0.0, 20.002531682198615, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 383 + stamp: + secs: 1624875223 + nsecs: 321557045 + frame_id: "/world" +pose: + pose: + position: + x: 0.153244554574 + y: -0.01060146539 + z: 0.0 + orientation: + x: 0.0 + y: 0.000429220452188 + z: 0.0 + w: 0.999999907885 + covariance: [20.84537263168969, -3.366378196426343e-06, 0.0, 0.0, -0.0011364202655829042, 0.0, -3.3663781964263415e-06, 20.84536025791343, 0.0, 0.0, 0.000898921245358838, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011364202655829037, 0.0008989212453588382, 0.0, 0.0, 20.002192251302752, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 384 + stamp: + secs: 1624875223 + nsecs: 401560068 + frame_id: "/world" +pose: + pose: + position: + x: 0.153045045955 + y: -0.0115426094386 + z: 0.0 + orientation: + x: 0.0 + y: 0.000759869279186 + z: 0.0 + w: 0.999999711299 + covariance: [20.84521757506134, -3.363445346340856e-06, 0.0, 0.0, -0.0010026632063493167, 0.0, -3.3634453463408548e-06, 20.845205346060286, 0.0, 0.0, 0.0008369379906091838, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001002663206349316, 0.0008369379906091839, 0.0, 0.0, 20.003707088859546, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 385 + stamp: + secs: 1624875223 + nsecs: 481564999 + frame_id: "/world" +pose: + pose: + position: + x: 0.152876800273 + y: -0.0123343444321 + z: 0.0 + orientation: + x: 0.0 + y: 0.000900926282092 + z: 0.0 + w: 0.999999594166 + covariance: [20.79174215704275, -3.1369674440547995e-06, 0.0, 0.0, -0.0008262440288601117, 0.0, -3.136967444054799e-06, 20.79173084015123, 0.0, 0.0, 0.0007162848117418477, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0008262440288601113, 0.0007162848117418475, 0.0, 0.0, 20.003023045993363, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 386 + stamp: + secs: 1624875223 + nsecs: 561572075 + frame_id: "/world" +pose: + pose: + position: + x: 0.152720839657 + y: -0.0130669061806 + z: 0.0 + orientation: + x: 0.0 + y: 0.000811088025145 + z: 0.0 + w: 0.999999671068 + covariance: [20.730617361616478, -2.8782910020400628e-06, 0.0, 0.0, -0.0006653619158400996, 0.0, -2.8782910020400628e-06, 20.730607046172135, 0.0, 0.0, 0.0005953047159363716, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006653619158400991, 0.0005953047159363716, 0.0, 0.0, 20.002918505131987, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 387 + stamp: + secs: 1624875223 + nsecs: 641552925 + frame_id: "/world" +pose: + pose: + position: + x: 0.152571091953 + y: -0.0137698559383 + z: 0.0 + orientation: + x: 0.0 + y: 0.00115723448701 + z: 0.0 + w: 0.999999330404 + covariance: [20.67458777799205, -2.639733464961201e-06, 0.0, 0.0, -0.000525845472248932, 0.0, -2.639733464961201e-06, 20.67457837194092, 0.0, 0.0, 0.0004860957533325603, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005258454722489316, 0.0004860957533325603, 0.0, 0.0, 20.005316805896605, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 388 + stamp: + secs: 1624875223 + nsecs: 721590996 + frame_id: "/world" +pose: + pose: + position: + x: 0.152414613991 + y: -0.014501958341 + z: 0.0 + orientation: + x: 0.0 + y: 0.00127662208794 + z: 0.0 + w: 0.999999185118 + covariance: [20.641129140740368, -2.4899960373282e-06, 0.0, 0.0, -0.00043291852539481865, 0.0, -2.4899960373281997e-06, 20.641120318623248, 0.0, 0.0, 0.00040934200254220645, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00043291852539481833, 0.0004093420025422063, 0.0, 0.0, 20.003793542131135, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 389 + stamp: + secs: 1624875223 + nsecs: 801577091 + frame_id: "/world" +pose: + pose: + position: + x: 0.152225849097 + y: -0.0153847281274 + z: 0.0 + orientation: + x: 0.0 + y: 0.000699966882943 + z: 0.0 + w: 0.999999755023 + covariance: [20.662884956685954, -2.551108387086257e-06, 0.0, 0.0, -0.00041026626387792635, 0.0, -2.5511083870862564e-06, 20.662875973936604, 0.0, 0.0, 0.0003643759347519196, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004102662638779263, 0.0003643759347519195, 0.0, 0.0, 20.001721949614655, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 390 + stamp: + secs: 1624875223 + nsecs: 881587982 + frame_id: "/world" +pose: + pose: + position: + x: 0.15203658321 + y: -0.0162700399151 + z: 0.0 + orientation: + x: 0.0 + y: 0.000264938754518 + z: 0.0 + w: 0.999999964904 + covariance: [20.680479218806838, -2.5915198863813355e-06, 0.0, 0.0, -0.00043726090761271564, 0.0, -2.591519886381335e-06, 20.680470142302234, 0.0, 0.0, 0.00032993565724223503, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00043726090761271553, 0.0003299356572422349, 0.0, 0.0, 20.001016455099546, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 391 + stamp: + secs: 1624875223 + nsecs: 961596966 + frame_id: "/world" +pose: + pose: + position: + x: 0.15184659155 + y: -0.017159801306 + z: 0.0 + orientation: + x: 0.0 + y: 7.73210094253e-05 + z: 0.0 + w: 0.999999997011 + covariance: [20.69461235762909, -2.6158292541651037e-06, 0.0, 0.0, -0.0005113672840142378, 0.0, -2.615829254165103e-06, 20.694603237996485, 0.0, 0.0, 0.00030264186531965423, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0005113672840142377, 0.0003026418653196541, 0.0, 0.0, 20.000485813399003, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 392 + stamp: + secs: 1624875224 + nsecs: 41613102 + frame_id: "/world" +pose: + pose: + position: + x: 0.14823540778 + y: -0.0176994536117 + z: 0.0 + orientation: + x: -0.0 + y: -0.000261178654598 + z: -0.0 + w: 0.999999965893 + covariance: [17.167748024353084, -1.8514036913747595e-06, 0.0, 0.0, -0.0004025987348446096, 0.0, -1.8514036913747595e-06, 17.16774159353181, 0.0, 0.0, 0.00019830512880603525, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004025987348446096, 0.00019830512880603517, 0.0, 0.0, 16.6666722730505, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 393 + stamp: + secs: 1624875224 + nsecs: 121651888 + frame_id: "/world" +pose: + pose: + position: + x: 0.143400551438 + y: -0.0104782241647 + z: 0.0 + orientation: + x: -0.0 + y: -0.000315195141974 + z: -0.0 + w: 0.999999950326 + covariance: [15.57613929794372, -1.6674450773762659e-06, 0.0, 0.0, -0.0003970093994048909, 0.0, -1.6674450773762656e-06, 15.576133529921588, 0.0, 0.0, 0.00016649769668547216, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00039700939940489087, 0.00016649769668547208, 0.0, 0.0, 15.116288862870006, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 394 + stamp: + secs: 1624875224 + nsecs: 201616049 + frame_id: "/world" +pose: + pose: + position: + x: 0.143291725506 + y: -0.0124227345379 + z: 0.0 + orientation: + x: -0.0 + y: -1.50600963187e-05 + z: -0.0 + w: 0.999999999887 + covariance: [17.313067539701194, -2.0271406971512193e-06, 0.0, 0.0, -0.00047974576413471775, 0.0, -2.0271406971512193e-06, 17.313060549500648, 0.0, 0.0, 0.00019335694842028206, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00047974576413471775, 0.00019335694842028195, 0.0, 0.0, 16.747483459950566, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 395 + stamp: + secs: 1624875224 + nsecs: 281644106 + frame_id: "/world" +pose: + pose: + position: + x: 0.143101007651 + y: -0.0130549844885 + z: 0.0 + orientation: + x: 0.0 + y: 0.000231997899013 + z: 0.0 + w: 0.999999973088 + covariance: [18.42288994407507, -1.986235650247959e-06, 0.0, 0.0, -0.0004386793062851585, 0.0, -1.9862356502479592e-06, 18.422883109086747, 0.0, 0.0, 0.00019300409558779295, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004386793062851585, 0.00019300409558779287, 0.0, 0.0, 17.862882703704756, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 396 + stamp: + secs: 1624875224 + nsecs: 361641884 + frame_id: "/world" +pose: + pose: + position: + x: 0.142867944663 + y: -0.0138366166287 + z: 0.0 + orientation: + x: -0.0 + y: -0.000274053113815 + z: -0.0 + w: 0.999999962447 + covariance: [19.198435900240614, -2.070782559585404e-06, 0.0, 0.0, -0.0006301138508029878, 0.0, -2.070782559585405e-06, 19.198428788104987, 0.0, 0.0, 0.0002148373887966314, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0006301138508029878, 0.00021483738879663134, 0.0, 0.0, 18.60866947420577, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 397 + stamp: + secs: 1624875224 + nsecs: 441647053 + frame_id: "/world" +pose: + pose: + position: + x: 0.142592135677 + y: -0.0147756541189 + z: 0.0 + orientation: + x: -0.0 + y: -0.000770800923003 + z: -0.0 + w: 0.999999702933 + covariance: [19.754470833565673, -2.2762168007767494e-06, 0.0, 0.0, -0.0009489810235539507, 0.0, -2.27621680077675e-06, 19.7544630135696, 0.0, 0.0, 0.00023775989410530706, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009489810235539503, 0.000237759894105307, 0.0, 0.0, 19.099527766791667, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 398 + stamp: + secs: 1624875224 + nsecs: 521675110 + frame_id: "/world" +pose: + pose: + position: + x: 0.142321202568 + y: -0.0157009596944 + z: 0.0 + orientation: + x: -0.0 + y: -0.000689882589474 + z: -0.0 + w: 0.999999762031 + covariance: [20.119135122637534, -2.4050819961705166e-06, 0.0, 0.0, -0.0011198810567986837, 0.0, -2.4050819961705174e-06, 20.119126845384898, 0.0, 0.0, 0.0002412817448613939, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011198810567986832, 0.00024128174486139387, 0.0, 0.0, 19.41999900893056, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 399 + stamp: + secs: 1624875224 + nsecs: 601653099 + frame_id: "/world" +pose: + pose: + position: + x: 0.142055607619 + y: -0.016611567258 + z: 0.0 + orientation: + x: -0.0 + y: -0.000466046410249 + z: -0.0 + w: 0.9999998914 + covariance: [20.353693583441622, -2.4707107654903346e-06, 0.0, 0.0, -0.001189483758681675, 0.0, -2.470710765490335e-06, 20.353685057692896, 0.0, 0.0, 0.00023164811596797482, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011894837586816749, 0.0002316481159679748, 0.0, 0.0, 19.626767466524903, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 400 + stamp: + secs: 1624875224 + nsecs: 681679964 + frame_id: "/world" +pose: + pose: + position: + x: 0.141791041485 + y: -0.017519993298 + z: 0.0 + orientation: + x: -0.0 + y: -6.83174185916e-05 + z: -0.0 + w: 0.999999997666 + covariance: [20.50703788154367, -2.5055256253580426e-06, 0.0, 0.0, -0.0011453338762353296, 0.0, -2.505525625358043e-06, 20.50702921210649, 0.0, 0.0, 0.00020648005860973565, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011453338762353292, 0.00020648005860973565, 0.0, 0.0, 19.760376976373024, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 401 + stamp: + secs: 1624875224 + nsecs: 761667967 + frame_id: "/world" +pose: + pose: + position: + x: 0.141533420598 + y: -0.0184121425351 + z: 0.0 + orientation: + x: 0.0 + y: 0.000136520231437 + z: 0.0 + w: 0.999999990681 + covariance: [20.59944590600934, -2.494751938406599e-06, 0.0, 0.0, -0.0011603654315307113, 0.0, -2.4947519384066e-06, 20.59943724092644, 0.0, 0.0, 0.00018119305694589002, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011603654315307111, 0.00018119305694589002, 0.0, 0.0, 19.846340424618052, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 402 + stamp: + secs: 1624875224 + nsecs: 841675043 + frame_id: "/world" +pose: + pose: + position: + x: 0.14125479126 + y: -0.0193844865333 + z: 0.0 + orientation: + x: 0.0 + y: 0.000261675800212 + z: 0.0 + w: 0.999999965763 + covariance: [20.68439898799884, -2.558083497317597e-06, 0.0, 0.0, -0.0012227693295450413, 0.0, -2.5580834973175983e-06, 20.68439005554895, 0.0, 0.0, 0.00016352026208963304, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001222769329545041, 0.00016352026208963304, 0.0, 0.0, 19.90155445386313, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 403 + stamp: + secs: 1624875224 + nsecs: 921693087 + frame_id: "/world" +pose: + pose: + position: + x: 0.140985159467 + y: -0.0203255092704 + z: 0.0 + orientation: + x: 0.0 + y: 0.000153637374031 + z: 0.0 + w: 0.999999988198 + covariance: [20.729039616344, -2.5563105852862905e-06, 0.0, 0.0, -0.0013129905782866737, 0.0, -2.5563105852862926e-06, 20.729030645119142, 0.0, 0.0, 0.00018812885352037558, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013129905782866737, 0.00018812885352037555, 0.0, 0.0, 19.93693160790719, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 404 + stamp: + secs: 1624875225 + nsecs: 1673937 + frame_id: "/world" +pose: + pose: + position: + x: 0.140759849607 + y: -0.0211116035137 + z: 0.0 + orientation: + x: 0.0 + y: 6.7737933964e-05 + z: 0.0 + w: 0.999999997706 + covariance: [20.70256177037326, -2.3740719335378905e-06, 0.0, 0.0, -0.001311833425661631, 0.0, -2.374071933537892e-06, 20.70255340503714, 0.0, 0.0, 0.00021186176878348095, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013118334256616306, 0.00021186176878348087, 0.0, 0.0, 19.959617382512672, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 405 + stamp: + secs: 1624875225 + nsecs: 81682920 + frame_id: "/world" +pose: + pose: + position: + x: 0.140494408842 + y: -0.0220405370409 + z: 0.0 + orientation: + x: 0.0 + y: 0.000295312327576 + z: 0.0 + w: 0.999999956395 + covariance: [20.725056234427438, -2.375117597162301e-06, 0.0, 0.0, -0.0013518641318834073, 0.0, -2.3751175971623027e-06, 20.725047824058, 0.0, 0.0, 0.00022849362725802126, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013518641318834067, 0.0002284936272580212, 0.0, 0.0, 19.974405829761373, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 406 + stamp: + secs: 1624875225 + nsecs: 161689043 + frame_id: "/world" +pose: + pose: + position: + x: 0.14019528269 + y: -0.0230945962837 + z: 0.0 + orientation: + x: 0.0 + y: 0.000803194793036 + z: 0.0 + w: 0.999999677439 + covariance: [20.78112227029476, -2.49471559696094e-06, 0.0, 0.0, -0.0014390338083664943, 0.0, -2.4947155969609418e-06, 20.781113380748874, 0.0, 0.0, 0.00023295765094764537, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0014390338083664935, 0.00023295765094764531, 0.0, 0.0, 19.98459902056286, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 407 + stamp: + secs: 1624875225 + nsecs: 241738081 + frame_id: "/world" +pose: + pose: + position: + x: 0.139936055444 + y: -0.0240116801523 + z: 0.0 + orientation: + x: 0.0 + y: 0.000948363256439 + z: 0.0 + w: 0.999999550303 + covariance: [20.777049956887538, -2.4339632568213365e-06, 0.0, 0.0, -0.0013597817036656455, 0.0, -2.4339632568213374e-06, 20.777041238522735, 0.0, 0.0, 0.00020857525438102648, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0013597817036656449, 0.0002085752543810264, 0.0, 0.0, 19.99076931683874, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 408 + stamp: + secs: 1624875225 + nsecs: 321708918 + frame_id: "/world" +pose: + pose: + position: + x: 0.139701235881 + y: -0.0248422969976 + z: 0.0 + orientation: + x: 0.0 + y: 0.000727577900055 + z: 0.0 + w: 0.999999735315 + covariance: [20.7442798437478, -2.2924664477838426e-06, 0.0, 0.0, -0.0011866214680192784, 0.0, -2.2924664477838447e-06, 20.74427159956747, 0.0, 0.0, 0.0001775157748534391, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011866214680192782, 0.00017751577485343906, 0.0, 0.0, 19.99413060162622, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 409 + stamp: + secs: 1624875225 + nsecs: 401716948 + frame_id: "/world" +pose: + pose: + position: + x: 0.139424020089 + y: -0.0258140374286 + z: 0.0 + orientation: + x: 0.0 + y: 0.000520154297943 + z: 0.0 + w: 0.99999986472 + covariance: [20.765139046354534, -2.319475512072365e-06, 0.0, 0.0, -0.0010714971909872675, 0.0, -2.319475512072367e-06, 20.765130681812753, 0.0, 0.0, 0.00019898742562932443, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.001071497190987267, 0.0001989874256293244, 0.0, 0.0, 19.996468029899514, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 410 + stamp: + secs: 1624875225 + nsecs: 481729984 + frame_id: "/world" +pose: + pose: + position: + x: 0.139190164083 + y: -0.0266254220142 + z: 0.0 + orientation: + x: 0.0 + y: 0.00019430977002 + z: 0.0 + w: 0.999999981122 + covariance: [20.726178313763892, -2.175512900234643e-06, 0.0, 0.0, -0.0009955114324961913, 0.0, -2.1755129002346446e-06, 20.726170462601516, 0.0, 0.0, 0.0002452786228243398, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0009955114324961911, 0.0002452786228243398, 0.0, 0.0, 19.99736978904107, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 411 + stamp: + secs: 1624875225 + nsecs: 561794043 + frame_id: "/world" +pose: + pose: + position: + x: 0.138927876682 + y: -0.0275386752265 + z: 0.0 + orientation: + x: -0.0 + y: -0.00020206902177 + z: -0.0 + w: 0.999999979584 + covariance: [20.7267582407134, -2.153077442402032e-06, 0.0, 0.0, -0.0010041984789175423, 0.0, -2.1530774424020335e-06, 20.726750463549273, 0.0, 0.0, 0.0002716133883308646, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0010041984789175421, 0.0002716133883308646, 0.0, 0.0, 19.998229744903114, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 412 + stamp: + secs: 1624875225 + nsecs: 641766071 + frame_id: "/world" +pose: + pose: + position: + x: 0.138660614292 + y: -0.0284652869326 + z: 0.0 + orientation: + x: -0.0 + y: -0.000181319775596 + z: -0.0 + w: 0.999999983562 + covariance: [20.726835054098615, -2.1390702255421217e-06, 0.0, 0.0, -0.0011849649586509407, 0.0, -2.1390702255421242e-06, 20.726827333295116, 0.0, 0.0, 0.0003593981253804352, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0011849649586509405, 0.0003593981253804352, 0.0, 0.0, 19.998893981982253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 0 + stamp: + secs: 1624875191 + nsecs: 558718920 + frame_id: "/world" +pose: + pose: + position: + x: 0.0572746301754 + y: 0.0203722993784 + z: 0.0 + orientation: + x: 0.0 + y: 0.0403072300115 + z: 0.0 + w: 0.999187333391 + covariance: [0.09798037477464908, -1.76815747288255e-18, 0.0, 0.0, 6.13465559113359e-14, 0.0, -1.768157472882468e-18, 0.09798037477464923, 0.0, 0.0, -3.650408832264524e-12, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 6.134655591133087e-14, -3.65040883226233e-12, 0.0, 0.0, 0.09798030471140112, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 1 + stamp: + secs: 1624875193 + nsecs: 318856001 + frame_id: "/world" +pose: + pose: + position: + x: -0.027583960469 + y: -0.0109764176242 + z: 0.0 + orientation: + x: 0.0 + y: 0.036213534968 + z: 0.0 + w: 0.999344074824 + covariance: [1.554217329643122, -4.566444801867897e-07, 0.0, 0.0, -0.000281048174497082, 0.0, -4.5664448018679055e-07, 1.5542167317263673, 0.0, 0.0, 0.00015192348150098203, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00028104817449708355, 0.0001519234815009988, 0.0, 0.0, 1.299112780009319, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 2 + stamp: + secs: 1624875196 + nsecs: 679157019 + frame_id: "/world" +pose: + pose: + position: + x: -0.0350439582251 + y: -0.0101363733353 + z: 0.0 + orientation: + x: -0.0 + y: -0.0227576230445 + z: -0.0 + w: 0.999741011759 + covariance: [1.722061717912726, -6.992448547714762e-06, 0.0, 0.0, -0.00023144360307907232, 0.0, -6.992448547714182e-06, 1.722053572694819, 0.0, 0.0, 0.0002266268869105261, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00023144360307907107, 0.00022662688691052536, 0.0, 0.0, 1.42831978995475, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 3 + stamp: + secs: 1624875196 + nsecs: 839164019 + frame_id: "/world" +pose: + pose: + position: + x: -0.0351885377998 + y: -0.0124582058831 + z: 0.0 + orientation: + x: 0.0 + y: 0.0148910534036 + z: 0.0 + w: 0.999889122117 + covariance: [1.3432536805914232, -5.052998560607446e-07, 0.0, 0.0, -1.9376407947275175e-05, 0.0, -5.052998560607228e-07, 1.3432531985575902, 0.0, 0.0, 1.8173610583605937e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9376407947275118e-05, 1.817361058360595e-05, 0.0, 0.0, 1.3239173697098163, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 4 + stamp: + secs: 1624875196 + nsecs: 999176979 + frame_id: "/world" +pose: + pose: + position: + x: -0.0687726925752 + y: 0.0159339240222 + z: 0.0 + orientation: + x: -0.0 + y: -0.00743833312454 + z: -0.0 + w: 0.999972335217 + covariance: [1.459788005551589, -1.5138467014668445e-07, 0.0, 0.0, -9.935670829771625e-06, 0.0, -1.5138467014668239e-07, 1.459787924821341, 0.0, 0.0, 7.19242763474458e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.93567082977164e-06, 7.1924276347445615e-06, 0.0, 0.0, 1.4533478938696847, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 5 + stamp: + secs: 1624875197 + nsecs: 239206076 + frame_id: "/world" +pose: + pose: + position: + x: -0.0794258114336 + y: 0.0124998106343 + z: 0.0 + orientation: + x: 0.0 + y: 0.00515393207601 + z: 0.0 + w: 0.999986718404 + covariance: [1.3664617598037045, -9.00688179183941e-08, 0.0, 0.0, -4.6822433635555305e-06, 0.0, -9.006881791839332e-08, 1.3664617352008077, 0.0, 0.0, 3.4124895544140678e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.682243363555532e-06, 3.4124895544140767e-06, 0.0, 0.0, 1.3607924744740298, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 6 + stamp: + secs: 1624875197 + nsecs: 399205923 + frame_id: "/world" +pose: + pose: + position: + x: -0.105267058789 + y: -0.0210065311936 + z: 0.0 + orientation: + x: -0.0 + y: -0.00205014890847 + z: -0.0 + w: 0.999997898443 + covariance: [1.343523072135344, -5.974507518064478e-08, 0.0, 0.0, -1.6303003996095524e-05, 0.0, -5.974507518064463e-08, 1.3435230568344847, 0.0, 0.0, 9.137910967919138e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.6303003996095568e-05, 9.137910967919101e-07, 0.0, 0.0, 1.3384011455814553, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 7 + stamp: + secs: 1624875197 + nsecs: 559230089 + frame_id: "/world" +pose: + pose: + position: + x: -0.123176392691 + y: -0.0901488591105 + z: 0.0 + orientation: + x: 0.0 + y: 0.00139627928502 + z: 0.0 + w: 0.999999025202 + covariance: [1.5759159354006635, -7.165159174616461e-08, 0.0, 0.0, -1.4836899276197031e-05, 0.0, -7.165159174616425e-08, 1.5759159003246415, 0.0, 0.0, 5.797075679901155e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4836899276197077e-05, 5.797075679901158e-07, 0.0, 0.0, 1.5679609766107694, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 8 + stamp: + secs: 1624875197 + nsecs: 719242096 + frame_id: "/world" +pose: + pose: + position: + x: -0.0938375235075 + y: -0.0281688531413 + z: 0.0 + orientation: + x: 0.0 + y: 0.000143521087332 + z: 0.0 + w: 0.999999989701 + covariance: [1.318610225144991, -4.9961067161111296e-08, 0.0, 0.0, -8.965443186230044e-06, 0.0, -4.996106716111135e-08, 1.3186101946252342, 0.0, 0.0, 1.51696291673374e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.965443186230073e-06, 1.5169629167337433e-06, 0.0, 0.0, 1.311898612995714, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 9 + stamp: + secs: 1624875197 + nsecs: 879255056 + frame_id: "/world" +pose: + pose: + position: + x: -0.104400119775 + y: -0.0767517060568 + z: 0.0 + orientation: + x: 0.0 + y: 0.0004786283699 + z: 0.0 + w: 0.999999885457 + covariance: [1.8041462923916858, -8.597628848894249e-08, 0.0, 0.0, -5.971868052093918e-05, 0.0, -8.597628848894208e-08, 1.8041462070145848, 0.0, 0.0, 2.888597443576239e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.9718680520939154e-05, 2.888597443576241e-06, 0.0, 0.0, 1.790831425360643, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 10 + stamp: + secs: 1624875198 + nsecs: 39307117 + frame_id: "/world" +pose: + pose: + position: + x: -0.101660674375 + y: -0.0895387989054 + z: 0.0 + orientation: + x: -0.0 + y: -0.000587201332259 + z: -0.0 + w: 0.999999827597 + covariance: [1.6076669373105446, -7.805846152768439e-08, 0.0, 0.0, -3.0220995309225865e-05, 0.0, -7.805846152768423e-08, 1.6076667812982182, 0.0, 0.0, 4.244376485208481e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.022099530922585e-05, 4.244376485208467e-06, 0.0, 0.0, 1.594421280653708, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 11 + stamp: + secs: 1624875198 + nsecs: 199289083 + frame_id: "/world" +pose: + pose: + position: + x: -0.104252589519 + y: -0.0977639275462 + z: 0.0 + orientation: + x: -0.0 + y: -0.000818003976646 + z: -0.0 + w: 0.999999665435 + covariance: [1.5682842721173635, -5.146944726517667e-08, 0.0, 0.0, -7.0439550568543135e-06, 0.0, -5.146944726517659e-08, 1.568284153081746, 0.0, 0.0, 2.332136666347177e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.043955056854302e-06, 2.332136666347172e-06, 0.0, 0.0, 1.5587449238388582, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 12 + stamp: + secs: 1624875198 + nsecs: 279292107 + frame_id: "/world" +pose: + pose: + position: + x: -0.106576209297 + y: -0.1072020102 + z: 0.0 + orientation: + x: -0.0 + y: -9.44184571137e-05 + z: -0.0 + w: 0.999999995543 + covariance: [1.4722214359795125, -3.253618874495884e-08, 0.0, 0.0, -1.2857914016508653e-06, 0.0, -3.25361887449588e-08, 1.4722213576724794, 0.0, 0.0, 9.452914954863612e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2857914016508655e-06, 9.452914954863592e-07, 0.0, 0.0, 1.4653424008324532, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 13 + stamp: + secs: 1624875198 + nsecs: 439341068 + frame_id: "/world" +pose: + pose: + position: + x: -0.107898699183 + y: -0.109235068271 + z: 0.0 + orientation: + x: -0.0 + y: -0.000929036659281 + z: -0.0 + w: 0.999999568445 + covariance: [2.3902266630971885, -1.428659820653964e-07, 0.0, 0.0, -5.5036115926805454e-05, 0.0, -1.4286598206539583e-07, 2.390226302146701, 0.0, 0.0, 1.2663447703806026e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.503611592680549e-05, 1.2663447703806022e-06, 0.0, 0.0, 2.354843063836702, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 14 + stamp: + secs: 1624875198 + nsecs: 599320889 + frame_id: "/world" +pose: + pose: + position: + x: -0.109688711654 + y: -0.112164679356 + z: 0.0 + orientation: + x: -0.0 + y: -0.00139212369844 + z: -0.0 + w: 0.999999030995 + covariance: [3.7240419555971487, -3.6524582650955037e-07, 0.0, 0.0, -0.00012971802247171676, 0.0, -3.652458265095487e-07, 3.7240409191770683, 0.0, 0.0, 2.2699925950166143e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00012971802247171667, 2.2699925950166148e-06, 0.0, 0.0, 3.6243087103717544, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 15 + stamp: + secs: 1624875198 + nsecs: 679327011 + frame_id: "/world" +pose: + pose: + position: + x: -0.109982796944 + y: -0.112646062937 + z: 0.0 + orientation: + x: 0.0 + y: 0.000583886842749 + z: 0.0 + w: 0.999999829538 + covariance: [1.6067021647461341, -3.1508383780291965e-08, 0.0, 0.0, -9.502866302532009e-06, 0.0, -3.150838378029184e-08, 1.6067020726180257, 0.0, 0.0, 2.8771228545940963e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.50286630253204e-06, 2.877122854594091e-06, 0.0, 0.0, 1.597602062429705, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 16 + stamp: + secs: 1624875198 + nsecs: 759337902 + frame_id: "/world" +pose: + pose: + position: + x: -0.11030939931 + y: -0.109867873443 + z: 0.0 + orientation: + x: -0.0 + y: -0.00056800326171 + z: -0.0 + w: 0.999999838686 + covariance: [1.470492692951918, -1.0414819489178212e-08, 0.0, 0.0, -2.1584098778848975e-06, 0.0, -1.0414819489178126e-08, 1.4704926618802079, 0.0, 0.0, 1.4565919806390564e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1584098778849e-06, 1.4565919806390526e-06, 0.0, 0.0, 1.4672171777229677, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 17 + stamp: + secs: 1624875198 + nsecs: 839340925 + frame_id: "/world" +pose: + pose: + position: + x: -0.107418013476 + y: -0.11281734616 + z: 0.0 + orientation: + x: -0.0 + y: -0.000105360068711 + z: -0.0 + w: 0.99999999445 + covariance: [1.4465265349526004, -1.9178952671966603e-08, 0.0, 0.0, -1.845720339978819e-06, 0.0, -1.9178952671966547e-08, 1.4465264786031014, 0.0, 0.0, 8.279643902947588e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8457203399788139e-06, 8.279643902947542e-06, 0.0, 0.0, 1.4396473475691502, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 18 + stamp: + secs: 1624875198 + nsecs: 999368906 + frame_id: "/world" +pose: + pose: + position: + x: -0.108163345181 + y: -0.11396041587 + z: 0.0 + orientation: + x: -0.0 + y: -0.000809614630396 + z: -0.0 + w: 0.999999672262 + covariance: [1.3208730540685167, -3.540696839242339e-08, 0.0, 0.0, -7.015670127024012e-07, 0.0, -3.5406968392423215e-08, 1.3208729567053457, 0.0, 0.0, 5.068376908860847e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.01567012702399e-07, 5.06837690886081e-06, 0.0, 0.0, 1.306906703716319, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 19 + stamp: + secs: 1624875199 + nsecs: 159377098 + frame_id: "/world" +pose: + pose: + position: + x: -0.105278889866 + y: -0.11968272569 + z: 0.0 + orientation: + x: -0.0 + y: -0.000432800093556 + z: -0.0 + w: 0.999999906342 + covariance: [1.567968676251421, -6.047791763077736e-08, 0.0, 0.0, -1.00318383466217e-05, 0.0, -6.047791763077704e-08, 1.567968523565198, 0.0, 0.0, 2.3064748136968444e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0031838346621688e-05, 2.306474813696848e-05, 0.0, 0.0, 1.5418977925759254, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 20 + stamp: + secs: 1624875199 + nsecs: 399395943 + frame_id: "/world" +pose: + pose: + position: + x: -0.0513979646357 + y: -0.156564701314 + z: 0.0 + orientation: + x: -0.0 + y: -0.00353550822883 + z: -0.0 + w: 0.999993750071 + covariance: [1.3932763992326205, -6.832814419209259e-08, 0.0, 0.0, -7.30086599652405e-06, 0.0, -6.832814419209255e-08, 1.3932762804451482, 0.0, 0.0, 3.220375251271922e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.300865996524021e-06, 3.2203752512719194e-05, 0.0, 0.0, 1.364776586862331, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 21 + stamp: + secs: 1624875199 + nsecs: 719436884 + frame_id: "/world" +pose: + pose: + position: + x: -0.0517245621772 + y: -0.160071365224 + z: 0.0 + orientation: + x: -0.0 + y: -6.93841430129e-05 + z: -0.0 + w: 0.999999997593 + covariance: [2.0190692161454273, -1.9761432989369794e-07, 0.0, 0.0, -4.0303283774099e-05, 0.0, -1.9761432989369752e-07, 2.019069005060484, 0.0, 0.0, 2.9765630653967722e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.030328377409904e-05, 2.976563065396772e-05, 0.0, 0.0, 1.9338876016401743, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 22 + stamp: + secs: 1624875199 + nsecs: 879475117 + frame_id: "/world" +pose: + pose: + position: + x: -0.0492116747622 + y: -0.138319436 + z: 0.0 + orientation: + x: -0.0 + y: -0.000523572397685 + z: -0.0 + w: 0.999999862936 + covariance: [1.438705368833236, -4.20167519040597e-08, 0.0, 0.0, -1.5593925962249142e-05, 0.0, -4.201675190405974e-08, 1.438705323480808, 0.0, 0.0, 4.724767179730621e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.559392596224915e-05, 4.724767179730615e-06, 0.0, 0.0, 1.4201483332844367, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 23 + stamp: + secs: 1624875199 + nsecs: 959450006 + frame_id: "/world" +pose: + pose: + position: + x: -0.0493194105363 + y: -0.139298472176 + z: 0.0 + orientation: + x: -0.0 + y: -0.000374752076434 + z: -0.0 + w: 0.99999992978 + covariance: [1.6633870417494834, -2.8444543774765755e-08, 0.0, 0.0, -1.3776611681980623e-05, 0.0, -2.844454377476574e-08, 1.6633870075852641, 0.0, 0.0, 9.013707553576074e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3776611681980608e-05, 9.01370755357607e-06, 0.0, 0.0, 1.6508751591751365, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 24 + stamp: + secs: 1624875200 + nsecs: 119455099 + frame_id: "/world" +pose: + pose: + position: + x: -0.0472362724043 + y: -0.137158179135 + z: 0.0 + orientation: + x: -0.0 + y: -0.000306998577178 + z: -0.0 + w: 0.999999952876 + covariance: [1.6085090924737866, -5.073547127661546e-08, 0.0, 0.0, -7.840658855426918e-06, 0.0, -5.0735471276615244e-08, 1.6085090333087346, 0.0, 0.0, 7.007291774981734e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.840658855426916e-06, 7.007291774981729e-06, 0.0, 0.0, 1.5864332822965217, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 25 + stamp: + secs: 1624875200 + nsecs: 279485941 + frame_id: "/world" +pose: + pose: + position: + x: -0.0472532280232 + y: -0.137749633261 + z: 0.0 + orientation: + x: -0.0 + y: -0.000501277324597 + z: -0.0 + w: 0.999999874361 + covariance: [1.4837381026437435, -3.6673719400244536e-08, 0.0, 0.0, -4.589911367116733e-06, 0.0, -3.6673719400244436e-08, 1.4837380604119785, 0.0, 0.0, 2.8513588735705137e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.589911367116728e-06, 2.8513588735705107e-06, 0.0, 0.0, 1.4668378673352518, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 26 + stamp: + secs: 1624875200 + nsecs: 359488964 + frame_id: "/world" +pose: + pose: + position: + x: -0.0468450474523 + y: -0.138380131322 + z: 0.0 + orientation: + x: -0.0 + y: -0.000706618657084 + z: -0.0 + w: 0.999999750345 + covariance: [1.6416401012456643, -2.9414096951515502e-08, 0.0, 0.0, -9.94178763979709e-06, 0.0, -2.9414096951515472e-08, 1.64164006675844, 0.0, 0.0, 2.3111302625391226e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.941787639797104e-06, 2.311130262539118e-06, 0.0, 0.0, 1.6271838514337313, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 27 + stamp: + secs: 1624875200 + nsecs: 519515038 + frame_id: "/world" +pose: + pose: + position: + x: -0.0468552189113 + y: -0.139319620841 + z: 0.0 + orientation: + x: -0.0 + y: -0.000493065474951 + z: -0.0 + w: 0.999999878443 + covariance: [1.6066841038172364, -3.957626643853144e-08, 0.0, 0.0, -5.988683230057577e-06, 0.0, -3.9576266438531445e-08, 1.606684054066615, 0.0, 0.0, 1.801261424182683e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.988683230057586e-06, 1.8012614241826826e-06, 0.0, 0.0, 1.585121771915552, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 28 + stamp: + secs: 1624875200 + nsecs: 679512978 + frame_id: "/world" +pose: + pose: + position: + x: -0.0468243322211 + y: -0.140227671283 + z: 0.0 + orientation: + x: -0.0 + y: -0.000344883747262 + z: -0.0 + w: 0.999999940528 + covariance: [1.5730833980219525, -2.5535706764035964e-08, 0.0, 0.0, -1.2022807876467717e-06, 0.0, -2.553570676403593e-08, 1.5730833653910565, 0.0, 0.0, 6.196402147088079e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2022807876467725e-06, 6.196402147088072e-07, 0.0, 0.0, 1.55812809226502, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 29 + stamp: + secs: 1624875200 + nsecs: 759515047 + frame_id: "/world" +pose: + pose: + position: + x: -0.0468923925038 + y: -0.140693920783 + z: 0.0 + orientation: + x: -0.0 + y: -0.000210898355484 + z: -0.0 + w: 0.999999977761 + covariance: [1.6434524132645036, -1.7747626309011437e-08, 0.0, 0.0, -1.3454574130668092e-05, 0.0, -1.7747626309011355e-08, 1.6434523905361105, 0.0, 0.0, 7.583728999230624e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3454574130668112e-05, 7.583728999230639e-06, 0.0, 0.0, 1.6327049300914147, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 30 + stamp: + secs: 1624875200 + nsecs: 919538975 + frame_id: "/world" +pose: + pose: + position: + x: -0.0468903383731 + y: -0.133899783958 + z: 0.0 + orientation: + x: -0.0 + y: -0.000310222432561 + z: -0.0 + w: 0.999999951881 + covariance: [1.5756743547064231, -2.80348296807963e-08, 0.0, 0.0, -9.83403731540205e-06, 0.0, -2.803482968079625e-08, 1.5756743190165419, 0.0, 0.0, 5.0612104549832426e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.834037315402061e-06, 5.061210454983251e-06, 0.0, 0.0, 1.5607276596484776, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 31 + stamp: + secs: 1624875200 + nsecs: 999536991 + frame_id: "/world" +pose: + pose: + position: + x: -0.0421047406635 + y: -0.120549912312 + z: 0.0 + orientation: + x: -0.0 + y: -0.000246916226538 + z: -0.0 + w: 0.999999969516 + covariance: [1.5428992137455255, -1.861659349823939e-08, 0.0, 0.0, -1.3892393849501633e-06, 0.0, -1.861659349823939e-08, 1.5428991900048434, 0.0, 0.0, 8.52312902308112e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.389239384950167e-06, 8.523129023081148e-07, 0.0, 0.0, 1.5327523331542856, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 32 + stamp: + secs: 1624875201 + nsecs: 159560919 + frame_id: "/world" +pose: + pose: + position: + x: -0.0383762313085 + y: -0.101973229468 + z: 0.0 + orientation: + x: 0.0 + y: 0.000613639855793 + z: 0.0 + w: 0.999999811723 + covariance: [1.7100211879947058, -4.007664156396667e-08, 0.0, 0.0, -2.214689745108399e-06, 0.0, -4.007664156396663e-08, 1.7100211368572462, 0.0, 0.0, 1.2413572021190935e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.2146897451083987e-06, 1.2413572021190942e-06, 0.0, 0.0, 1.6863085905594057, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 33 + stamp: + secs: 1624875201 + nsecs: 319547892 + frame_id: "/world" +pose: + pose: + position: + x: -0.0380724996761 + y: -0.097823313537 + z: 0.0 + orientation: + x: 0.0 + y: 0.000331691739789 + z: 0.0 + w: 0.99999994499 + covariance: [1.517891669470173, -3.684757008899174e-08, 0.0, 0.0, -1.1477478111215661e-06, 0.0, -3.684757008899154e-08, 1.5178916224991381, 0.0, 0.0, 1.7535664512162068e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1477478111215627e-06, 1.753566451216211e-06, 0.0, 0.0, 1.49354467297991, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 34 + stamp: + secs: 1624875201 + nsecs: 399564028 + frame_id: "/world" +pose: + pose: + position: + x: -0.0379899186705 + y: -0.0983111849511 + z: 0.0 + orientation: + x: 0.0 + y: 4.5981322794e-05 + z: 0.0 + w: 0.999999998943 + covariance: [1.5211293015764231, -2.2155946075013456e-08, 0.0, 0.0, -3.217381314585383e-05, 0.0, -2.2155946075013383e-08, 1.5211292642014083, 0.0, 0.0, 3.1093019179549904e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.217381314585377e-05, 3.109301917954992e-06, 0.0, 0.0, 1.506047962988126, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 35 + stamp: + secs: 1624875201 + nsecs: 559628963 + frame_id: "/world" +pose: + pose: + position: + x: -0.0377455884532 + y: -0.100097054232 + z: 0.0 + orientation: + x: 0.0 + y: 0.000276709580231 + z: 0.0 + w: 0.999999961716 + covariance: [1.631787347209926, -4.97804631382229e-08, 0.0, 0.0, -4.0635989330069155e-05, 0.0, -4.9780463138222885e-08, 1.63178718211217, 0.0, 0.0, 1.3508630087062141e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.063598933006912e-05, 1.3508630087062088e-05, 0.0, 0.0, 1.603334669100237, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 36 + stamp: + secs: 1624875201 + nsecs: 719597101 + frame_id: "/world" +pose: + pose: + position: + x: -0.0379183135091 + y: -0.101250645803 + z: 0.0 + orientation: + x: 0.0 + y: 0.000276810230556 + z: 0.0 + w: 0.999999961688 + covariance: [1.5819868748089125, -4.469491904099483e-08, 0.0, 0.0, -1.2146243082898805e-05, 0.0, -4.469491904099484e-08, 1.581986727469817, 0.0, 0.0, 5.6487880397793325e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.214624308289881e-05, 5.648788039779324e-06, 0.0, 0.0, 1.5590937646749092, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 37 + stamp: + secs: 1624875201 + nsecs: 799607038 + frame_id: "/world" +pose: + pose: + position: + x: -0.0378180036625 + y: -0.0973063325344 + z: 0.0 + orientation: + x: 0.0 + y: 0.000538997905486 + z: 0.0 + w: 0.999999854741 + covariance: [1.6493483195305634, -3.16524518346531e-08, 0.0, 0.0, -3.7270859876198807e-06, 0.0, -3.165245183465308e-08, 1.6493482161883941, 0.0, 0.0, 1.3501422126349808e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.7270859876198853e-06, 1.350142212634981e-06, 0.0, 0.0, 1.632898521101565, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 38 + stamp: + secs: 1624875201 + nsecs: 959651947 + frame_id: "/world" +pose: + pose: + position: + x: -0.0386223184876 + y: -0.094963530874 + z: 0.0 + orientation: + x: -0.0 + y: -5.29806272338e-05 + z: -0.0 + w: 0.999999998597 + covariance: [1.5594112760270131, -3.972684389783873e-08, 0.0, 0.0, -3.8987657587604996e-06, 0.0, -3.972684389783888e-08, 1.559411146968128, 0.0, 0.0, 2.473841810074445e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.898765758760506e-06, 2.473841810074444e-06, 0.0, 0.0, 1.536665146874787, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 39 + stamp: + secs: 1624875202 + nsecs: 119643927 + frame_id: "/world" +pose: + pose: + position: + x: -0.044346291302 + y: -0.0933186909233 + z: 0.0 + orientation: + x: -0.0 + y: -0.000373168258589 + z: -0.0 + w: 0.999999930373 + covariance: [1.59733330992441, -2.8434376709611482e-08, 0.0, 0.0, -2.2178845611380467e-06, 0.0, -2.8434376709611456e-08, 1.5973332179962834, 0.0, 0.0, 1.0193648744618593e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.217884561138047e-06, 1.019364874461857e-06, 0.0, 0.0, 1.5798532162847543, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 40 + stamp: + secs: 1624875202 + nsecs: 199664116 + frame_id: "/world" +pose: + pose: + position: + x: -0.0445028775416 + y: -0.0938304405913 + z: 0.0 + orientation: + x: 0.0 + y: 0.000104595164647 + z: 0.0 + w: 0.99999999453 + covariance: [1.6729228014340431, -1.7882971641900337e-08, 0.0, 0.0, -4.071934919431013e-06, 0.0, -1.7882971641900344e-08, 1.6729227435996568, 0.0, 0.0, 2.231797465248661e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.07193491943101e-06, 2.2317974652486568e-07, 0.0, 0.0, 1.6611852562898852, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 41 + stamp: + secs: 1624875202 + nsecs: 279659033 + frame_id: "/world" +pose: + pose: + position: + x: -0.0433307676976 + y: -0.0889342424361 + z: 0.0 + orientation: + x: -0.0 + y: -2.46155965115e-07 + z: -0.0 + w: 1.0 + covariance: [1.6826334386354467, -2.2775695845288156e-08, 0.0, 0.0, -2.6297079694963795e-06, 0.0, -2.2775695845288162e-08, 1.6826333643747082, 0.0, 0.0, 4.912657459554499e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.629707969496376e-06, 4.912657459554494e-07, 0.0, 0.0, 1.6663245843401226, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 42 + stamp: + secs: 1624875202 + nsecs: 439666033 + frame_id: "/world" +pose: + pose: + position: + x: -0.0417404557898 + y: -0.0893794431557 + z: 0.0 + orientation: + x: 0.0 + y: 0.000218185127129 + z: 0.0 + w: 0.999999976198 + covariance: [1.4892241765801857, -2.3651267510989245e-08, 0.0, 0.0, -4.245572901785336e-07, 0.0, -2.3651267510989206e-08, 1.4892240996654744, 0.0, 0.0, 5.502601014376109e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.245572901785317e-07, 5.50260101437611e-06, 0.0, 0.0, 1.4706130681818455, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 43 + stamp: + secs: 1624875202 + nsecs: 519676924 + frame_id: "/world" +pose: + pose: + position: + x: -0.0419304861079 + y: -0.0896571871044 + z: 0.0 + orientation: + x: 0.0 + y: 9.73196905106e-05 + z: 0.0 + w: 0.999999995264 + covariance: [1.4730829357344306, -1.4541577325793268e-08, 0.0, 0.0, -2.539495919868144e-07, 0.0, -1.4541577325793215e-08, 1.4730828973085255, 0.0, 0.0, 2.7096512855637874e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.539495919868148e-07, 2.709651285563784e-05, 0.0, 0.0, 1.4608277523223228, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 44 + stamp: + secs: 1624875202 + nsecs: 679709911 + frame_id: "/world" +pose: + pose: + position: + x: -0.0424010066117 + y: -0.0902143205601 + z: 0.0 + orientation: + x: -0.0 + y: -0.000141061703064 + z: -0.0 + w: 0.999999990051 + covariance: [1.6271246133635615, -2.9143833428754392e-08, 0.0, 0.0, -1.4073961326760227e-06, 0.0, -2.9143833428754382e-08, 1.6271246149955068, 0.0, 0.0, 2.377015182229369e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.407396132676022e-06, 2.3770151822293572e-05, 0.0, 0.0, 1.6005764355703802, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 45 + stamp: + secs: 1624875202 + nsecs: 839711905 + frame_id: "/world" +pose: + pose: + position: + x: -0.042694308045 + y: -0.0906429916197 + z: 0.0 + orientation: + x: 0.0 + y: 0.0003668598338 + z: 0.0 + w: 0.999999932707 + covariance: [1.6340766941865663, -2.579060047927871e-08, 0.0, 0.0, -8.117379910471021e-07, 0.0, -2.57906004792787e-08, 1.6340767256622244, 0.0, 0.0, 4.09291472884541e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.117379910471021e-07, 4.092914728845403e-05, 0.0, 0.0, 1.6091128075682755, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 46 + stamp: + secs: 1624875202 + nsecs: 919713974 + frame_id: "/world" +pose: + pose: + position: + x: -0.0429777559936 + y: -0.0908470232876 + z: 0.0 + orientation: + x: 0.0 + y: 0.0001306382147 + z: 0.0 + w: 0.999999991467 + covariance: [1.5261738481943805, -1.432679118813629e-08, 0.0, 0.0, -4.74085795850265e-06, 0.0, -1.4326791188136276e-08, 1.526173889675054, 0.0, 0.0, 1.3890508040215112e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.740857958502658e-06, 1.3890508040215102e-05, 0.0, 0.0, 1.5121643988355644, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 47 + stamp: + secs: 1624875203 + nsecs: 79710960 + frame_id: "/world" +pose: + pose: + position: + x: -0.0436169848191 + y: -0.0982436720432 + z: 0.0 + orientation: + x: -0.0 + y: -0.000290367961587 + z: -0.0 + w: 0.999999957843 + covariance: [1.6017885372987877, -2.3841341147627994e-08, 0.0, 0.0, -4.015575540279747e-06, 0.0, -2.3841341147628014e-08, 1.6017886189047628, 0.0, 0.0, 1.0103678273456817e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.0155755402797385e-06, 1.0103678273456828e-05, 0.0, 0.0, 1.5784293744844788, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 48 + stamp: + secs: 1624875203 + nsecs: 159800053 + frame_id: "/world" +pose: + pose: + position: + x: -0.0438559583061 + y: -0.0985644157248 + z: 0.0 + orientation: + x: -0.0 + y: -0.000392072414172 + z: -0.0 + w: 0.99999992314 + covariance: [1.4825796374770797, -1.5857829219250565e-08, 0.0, 0.0, -2.69687084061956e-06, 0.0, -1.585782921925057e-08, 1.4825796929604984, 0.0, 0.0, 2.4026375110076312e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.696870840619561e-06, 2.4026375110076257e-06, 0.0, 0.0, 1.4663614268241507, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 49 + stamp: + secs: 1624875203 + nsecs: 319755077 + frame_id: "/world" +pose: + pose: + position: + x: -0.0493230240099 + y: -0.10223199107 + z: 0.0 + orientation: + x: -0.0 + y: -0.000300343739556 + z: -0.0 + w: 0.999999954897 + covariance: [1.60653473250912, -2.7124891909091244e-08, 0.0, 0.0, -3.7550553716098153e-06, 0.0, -2.7124891909091337e-08, 1.6065348270938427, 0.0, 0.0, 4.29409686192339e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.7550553716098098e-06, 4.294096861923379e-06, 0.0, 0.0, 1.5756771965882284, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 50 + stamp: + secs: 1624875203 + nsecs: 479762077 + frame_id: "/world" +pose: + pose: + position: + x: -0.0505490783351 + y: -0.111605085793 + z: 0.0 + orientation: + x: -0.0 + y: -0.000241428121693 + z: -0.0 + w: 0.999999970856 + covariance: [1.84737049079415, -2.922627256976527e-08, 0.0, 0.0, -1.7025309494107868e-06, 0.0, -2.922627256976527e-08, 1.8473705918198282, 0.0, 0.0, 6.238056914969386e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7025309494107874e-06, 6.238056914969388e-06, 0.0, 0.0, 1.811477749686665, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 51 + stamp: + secs: 1624875203 + nsecs: 559773922 + frame_id: "/world" +pose: + pose: + position: + x: -0.051119566352 + y: -0.112466968817 + z: 0.0 + orientation: + x: -0.0 + y: -0.000455535058267 + z: -0.0 + w: 0.999999896244 + covariance: [1.7568837631224563, -1.7931930620798718e-08, 0.0, 0.0, -3.1785120140042935e-05, 0.0, -1.7931930620798695e-08, 1.7568838167031033, 0.0, 0.0, 2.094560887493035e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.178512014004293e-05, 2.0945608874930366e-06, 0.0, 0.0, 1.733772696177587, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 52 + stamp: + secs: 1624875203 + nsecs: 719793081 + frame_id: "/world" +pose: + pose: + position: + x: -0.0485611986579 + y: -0.10531277436 + z: 0.0 + orientation: + x: -0.0 + y: -0.000966981687428 + z: -0.0 + w: 0.999999532473 + covariance: [1.7584649746109604, -2.2260416656094905e-08, 0.0, 0.0, -2.5224541905817038e-05, 0.0, -2.2260416656094846e-08, 1.7584649933436465, 0.0, 0.0, 3.989353299752479e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5224541905817103e-05, 3.989353299752492e-06, 0.0, 0.0, 1.7291637430559073, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 53 + stamp: + secs: 1624875203 + nsecs: 799793005 + frame_id: "/world" +pose: + pose: + position: + x: -0.0519732983567 + y: -0.104805326161 + z: 0.0 + orientation: + x: -0.0 + y: -0.000632691528 + z: -0.0 + w: 0.999999799851 + covariance: [1.6899575875831965, -1.4315400442820027e-08, 0.0, 0.0, -6.062236427912193e-06, 0.0, -1.4315400442820041e-08, 1.689957590037377, 0.0, 0.0, 5.858032734096925e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.0622364279122005e-06, 5.858032734096915e-06, 0.0, 0.0, 1.6709784268601051, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 54 + stamp: + secs: 1624875203 + nsecs: 959813118 + frame_id: "/world" +pose: + pose: + position: + x: -0.0532496421776 + y: -0.104018366042 + z: 0.0 + orientation: + x: -0.0 + y: -0.000417159303538 + z: -0.0 + w: 0.999999912989 + covariance: [1.690189314550645, -1.6692355513810168e-08, 0.0, 0.0, -1.4308254529764918e-05, 0.0, -1.669235551381015e-08, 1.6901893128790795, 0.0, 0.0, 4.419280349902722e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4308254529764884e-05, 4.4192803499027135e-06, 0.0, 0.0, 1.6669537372843841, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 55 + stamp: + secs: 1624875204 + nsecs: 39814949 + frame_id: "/world" +pose: + pose: + position: + x: -0.0494467384867 + y: -0.0908628917065 + z: 0.0 + orientation: + x: 0.0 + y: 0.000142091509724 + z: 0.0 + w: 0.999999989905 + covariance: [1.7415896588455306, -1.2347610114612996e-08, 0.0, 0.0, -6.445133200591962e-06, 0.0, -1.2347610114613013e-08, 1.741589653970016, 0.0, 0.0, 1.3130970555017154e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.4451332005919656e-06, 1.3130970555017186e-06, 0.0, 0.0, 1.724154045334715, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 56 + stamp: + secs: 1624875204 + nsecs: 199822903 + frame_id: "/world" +pose: + pose: + position: + x: -0.0502074031025 + y: -0.0913759483059 + z: 0.0 + orientation: + x: -0.0 + y: -0.000524794202554 + z: -0.0 + w: 0.999999862296 + covariance: [1.721128162305667, -1.4969301643558706e-08, 0.0, 0.0, -2.912118240908404e-06, 0.0, -1.4969301643558722e-08, 1.7211281544922326, 0.0, 0.0, 3.8143878236581737e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.912118240908407e-06, 3.8143878236581745e-06, 0.0, 0.0, 1.6988297756645927, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 57 + stamp: + secs: 1624875204 + nsecs: 279830933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0458441319714 + y: -0.0914166477506 + z: 0.0 + orientation: + x: -0.0 + y: -0.0010054083722 + z: -0.0 + w: 0.999999494577 + covariance: [1.8753385782665344, -1.3390146805105362e-08, 0.0, 0.0, 1.954588384354656e-05, 0.0, -1.3390146805105324e-08, 1.8753385688903415, 0.0, 0.0, -1.609882161697127e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 1.9545883843546548e-05, -1.6098821616971285e-06, 0.0, 0.0, 1.8549799691652982, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 58 + stamp: + secs: 1624875204 + nsecs: 439868927 + frame_id: "/world" +pose: + pose: + position: + x: -0.0406754034563 + y: -0.103255378783 + z: 0.0 + orientation: + x: -0.0 + y: -0.00115889885933 + z: -0.0 + w: 0.999999328476 + covariance: [2.2356836525157413, -2.6356396038873715e-08, 0.0, 0.0, 2.1208240636445297e-05, 0.0, -2.6356396038873685e-08, 2.2356836138162635, 0.0, 0.0, 1.4524347245559193e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 2.1208240636445294e-05, 1.4524347245559191e-05, 0.0, 0.0, 2.193818127584565, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 59 + stamp: + secs: 1624875204 + nsecs: 519855022 + frame_id: "/world" +pose: + pose: + position: + x: -0.0401683794027 + y: -0.100363908088 + z: 0.0 + orientation: + x: 0.0 + y: 0.000246163536015 + z: 0.0 + w: 0.999999969702 + covariance: [1.9441370828689204, -1.003092440794691e-08, 0.0, 0.0, 1.6521734397098366e-06, 0.0, -1.003092440794688e-08, 1.9441370666945148, 0.0, 0.0, 5.161410872489511e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 1.6521734397098368e-06, 5.161410872489506e-06, 0.0, 0.0, 1.9267718728121748, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 60 + stamp: + secs: 1624875204 + nsecs: 599853039 + frame_id: "/world" +pose: + pose: + position: + x: -0.0320538877694 + y: -0.101508990045 + z: 0.0 + orientation: + x: -0.0 + y: -0.000486444474804 + z: -0.0 + w: 0.999999881686 + covariance: [2.224023441653499, -1.232025025036988e-08, 0.0, 0.0, -1.262694507292239e-06, 0.0, -1.2320250250369877e-08, 2.2240234212495165, 0.0, 0.0, 2.8562568752089127e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2626945072922387e-06, 2.856256875208906e-06, 0.0, 0.0, 2.200976882258232, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 61 + stamp: + secs: 1624875204 + nsecs: 679869890 + frame_id: "/world" +pose: + pose: + position: + x: -0.0316030396462 + y: -0.0983281188403 + z: 0.0 + orientation: + x: -0.0 + y: -0.000180620695683 + z: -0.0 + w: 0.999999983688 + covariance: [1.9130502209114313, -1.0900965218086603e-08, 0.0, 0.0, -5.649689118215256e-07, 0.0, -1.09009652180866e-08, 1.9130502027593808, 0.0, 0.0, 9.436160387824917e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.649689118215253e-07, 9.436160387824895e-07, 0.0, 0.0, 1.8908498236309916, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 62 + stamp: + secs: 1624875204 + nsecs: 839879036 + frame_id: "/world" +pose: + pose: + position: + x: -0.0200144671656 + y: -0.0400120765718 + z: 0.0 + orientation: + x: -0.0 + y: -0.000316972996109 + z: -0.0 + w: 0.999999949764 + covariance: [1.7028245532933362, -1.0082556174570601e-08, 0.0, 0.0, -1.9425534995711304e-07, 0.0, -1.0082556174570624e-08, 1.7028245364817804, 0.0, 0.0, 3.818537243014908e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9425534995711333e-07, 3.818537243014911e-07, 0.0, 0.0, 1.680368114463213, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 63 + stamp: + secs: 1624875204 + nsecs: 919888020 + frame_id: "/world" +pose: + pose: + position: + x: -0.0220065618636 + y: -0.0436619838995 + z: 0.0 + orientation: + x: -0.0 + y: -4.0558182804e-05 + z: -0.0 + w: 0.999999999178 + covariance: [1.7098937804014613, -5.9414100768566e-09, 0.0, 0.0, -8.284742576197036e-07, 0.0, -5.941410076856598e-09, 1.7098937704965722, 0.0, 0.0, 6.224309520825801e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.284742576197045e-07, 6.224309520825804e-07, 0.0, 0.0, 1.695813601176916, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 64 + stamp: + secs: 1624875205 + nsecs: 79900026 + frame_id: "/world" +pose: + pose: + position: + x: -0.0230240562091 + y: -0.03689692522 + z: 0.0 + orientation: + x: -0.0 + y: -0.000147503297175 + z: -0.0 + w: 0.999999989121 + covariance: [1.6626264391578567, -8.276977671200087e-09, 0.0, 0.0, 2.039765183880795e-06, 0.0, -8.276977671200054e-09, 1.662626425335902, 0.0, 0.0, 4.504318233839471e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 2.039765183880795e-06, 4.504318233839477e-07, 0.0, 0.0, 1.6411049130688857, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 65 + stamp: + secs: 1624875205 + nsecs: 159907103 + frame_id: "/world" +pose: + pose: + position: + x: -0.0266496882937 + y: -0.0465259059609 + z: 0.0 + orientation: + x: -0.0 + y: -0.000111931322106 + z: -0.0 + w: 0.999999993736 + covariance: [1.9737145997554886, -5.544216645388783e-09, 0.0, 0.0, -2.5363725571601462e-06, 0.0, -5.544216645388777e-09, 1.9737145903896072, 0.0, 0.0, 7.500137520407622e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5363725571601467e-06, 7.500137520407632e-07, 0.0, 0.0, 1.958590089675371, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 66 + stamp: + secs: 1624875205 + nsecs: 319930077 + frame_id: "/world" +pose: + pose: + position: + x: -0.0269142603989 + y: -0.0175280208285 + z: 0.0 + orientation: + x: -0.0 + y: -0.000500599664265 + z: -0.0 + w: 0.9999998747 + covariance: [1.7589721179624682, -5.4717752090678645e-09, 0.0, 0.0, -1.9249645974366213e-06, 0.0, -5.471775209067857e-09, 1.758972108458479, 0.0, 0.0, 4.4263254141069117e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9249645974366226e-06, 4.42632541410691e-07, 0.0, 0.0, 1.743096493958481, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 67 + stamp: + secs: 1624875205 + nsecs: 399924994 + frame_id: "/world" +pose: + pose: + position: + x: -0.00502593884927 + y: -0.0332294060332 + z: 0.0 + orientation: + x: -0.0 + y: -0.00172873658121 + z: -0.0 + w: 0.999998505734 + covariance: [2.36773689835362, -1.060180967951381e-08, 0.0, 0.0, -3.65062682618636e-06, 0.0, -1.0601809679513795e-08, 2.3677368797062437, 0.0, 0.0, 5.592820416019655e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.650626826186359e-06, 5.592820416019654e-07, 0.0, 0.0, 2.335083660380648, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 68 + stamp: + secs: 1624875205 + nsecs: 639954090 + frame_id: "/world" +pose: + pose: + position: + x: 0.000915048102236 + y: -0.0352859342117 + z: 0.0 + orientation: + x: -0.0 + y: -0.000558478734636 + z: -0.0 + w: 0.999999844051 + covariance: [1.814886534292705, -1.4620742680822371e-08, 0.0, 0.0, -5.528590868892705e-05, 0.0, -1.4620742680822368e-08, 1.814886492645989, 0.0, 0.0, 2.6639326119657106e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.5285908688926943e-05, 2.6639326119657063e-06, 0.0, 0.0, 1.7665315613990007, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 69 + stamp: + secs: 1624875205 + nsecs: 719960928 + frame_id: "/world" +pose: + pose: + position: + x: 0.000487930395772 + y: -0.0348964023964 + z: 0.0 + orientation: + x: -0.0 + y: -6.36711653451e-06 + z: -0.0 + w: 0.99999999998 + covariance: [1.8384861658215785, -4.115242282418451e-09, 0.0, 0.0, -1.3183649634973198e-05, 0.0, -4.115242282418457e-09, 1.8384861465237596, 0.0, 0.0, 6.289441550349059e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3183649634973224e-05, 6.289441550349059e-07, 0.0, 0.0, 1.8255404847461798, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 70 + stamp: + secs: 1624875205 + nsecs: 799964905 + frame_id: "/world" +pose: + pose: + position: + x: 0.000654237467015 + y: -0.0248910982783 + z: 0.0 + orientation: + x: -0.0 + y: -0.000487911584604 + z: -0.0 + w: 0.999999880971 + covariance: [2.076062220120913, -6.772168283757481e-09, 0.0, 0.0, -1.6836750649049097e-05, 0.0, -6.7721682837574865e-09, 2.0760621743196483, 0.0, 0.0, 3.2736171135276477e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.6836750649049097e-05, 3.2736171135276466e-07, 0.0, 0.0, 2.0557069752080324, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 71 + stamp: + secs: 1624875205 + nsecs: 879976034 + frame_id: "/world" +pose: + pose: + position: + x: 0.00358072680381 + y: -0.0204914290119 + z: 0.0 + orientation: + x: -0.0 + y: -0.000794501597799 + z: -0.0 + w: 0.999999684384 + covariance: [2.061209702114319, -8.701699160538504e-09, 0.0, 0.0, -9.99234822052326e-06, 0.0, -8.701699160538493e-09, 2.0612096357892655, 0.0, 0.0, 9.67013952701286e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.992348220523255e-06, 9.670139527012846e-07, 0.0, 0.0, 2.0339946047395476, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 72 + stamp: + secs: 1624875206 + nsecs: 40004015 + frame_id: "/world" +pose: + pose: + position: + x: 0.00374962264163 + y: -0.0201459596281 + z: 0.0 + orientation: + x: -0.0 + y: -3.67823224402e-05 + z: -0.0 + w: 0.999999999324 + covariance: [1.8374565777051153, -7.842096864430714e-09, 0.0, 0.0, -1.2023104232680047e-05, 0.0, -7.842096864430737e-09, 1.8374565159381022, 0.0, 0.0, 9.191710945817088e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.202310423268008e-05, 9.191710945817081e-07, 0.0, 0.0, 1.8110341062945683, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 73 + stamp: + secs: 1624875206 + nsecs: 119993925 + frame_id: "/world" +pose: + pose: + position: + x: 0.0104055911001 + y: -0.028960935542 + z: 0.0 + orientation: + x: 0.0 + y: 0.000171465079911 + z: 0.0 + w: 0.9999999853 + covariance: [2.2595335900073517, -6.35184944667205e-09, 0.0, 0.0, -6.172743038743401e-06, 0.0, -6.351849446672053e-09, 2.2595335405020833, 0.0, 0.0, 7.3546025999592865e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.172743038743407e-06, 7.354602599959281e-06, 0.0, 0.0, 2.238039543414941, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 74 + stamp: + secs: 1624875206 + nsecs: 199990988 + frame_id: "/world" +pose: + pose: + position: + x: 0.010431663715 + y: -0.0289205949462 + z: 0.0 + orientation: + x: 0.0 + y: 0.000229238872598 + z: 0.0 + w: 0.999999973725 + covariance: [1.9908053439204292, -7.168988118452248e-09, 0.0, 0.0, -6.6204886620212e-06, 0.0, -7.168988118452242e-09, 1.9908052963083813, 0.0, 0.0, 1.7811831647884757e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.620488662021201e-06, 1.7811831647884804e-05, 0.0, 0.0, 1.9679211687927058, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 75 + stamp: + secs: 1624875206 + nsecs: 360021114 + frame_id: "/world" +pose: + pose: + position: + x: 0.00785914318748 + y: -0.0350768428395 + z: 0.0 + orientation: + x: 0.0 + y: 0.000248634792076 + z: 0.0 + w: 0.99999996909 + covariance: [2.0703869372238475, -2.693776379122903e-08, 0.0, 0.0, -7.60039416416451e-05, 0.0, -2.693776379122903e-08, 2.070386838074582, 0.0, 0.0, 3.192255168623166e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.60039416416451e-05, 3.192255168623164e-05, 0.0, 0.0, 2.0262986303594546, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 76 + stamp: + secs: 1624875206 + nsecs: 440040112 + frame_id: "/world" +pose: + pose: + position: + x: 0.00729663358885 + y: -0.0299380414191 + z: 0.0 + orientation: + x: -0.0 + y: -0.000175934079993 + z: -0.0 + w: 0.999999984524 + covariance: [2.0185997122747614, -3.129135822852729e-08, 0.0, 0.0, -3.268252870199444e-05, 0.0, -3.1291358228527326e-08, 2.018599613155992, 0.0, 0.0, 1.2672590987433358e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.268252870199439e-05, 1.267259098743336e-05, 0.0, 0.0, 1.990758746164286, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 77 + stamp: + secs: 1624875206 + nsecs: 520046949 + frame_id: "/world" +pose: + pose: + position: + x: 0.00733621385628 + y: -0.0303820392214 + z: 0.0 + orientation: + x: 0.0 + y: 4.16339982765e-05 + z: 0.0 + w: 0.999999999133 + covariance: [2.058872321102207, -4.202269411675908e-08, 0.0, 0.0, -3.892845415776081e-05, 0.0, -4.2022694116759e-08, 2.058872188840962, 0.0, 0.0, 6.674223576324628e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.892845415776076e-05, 6.674223576324626e-06, 0.0, 0.0, 2.0282161283893023, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 78 + stamp: + secs: 1624875206 + nsecs: 680032969 + frame_id: "/world" +pose: + pose: + position: + x: -0.00326216756132 + y: -0.0382560828494 + z: 0.0 + orientation: + x: 0.0 + y: 0.000654857864109 + z: 0.0 + w: 0.999999785581 + covariance: [2.6833053800628184, -2.2453229870170714e-07, 0.0, 0.0, -0.00042736016868733217, 0.0, -2.2453229870170733e-07, 2.6833045599186542, 0.0, 0.0, 0.00010426928004800407, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00042736016868733255, 0.00010426928004800414, 0.0, 0.0, 2.616112683178166, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 79 + stamp: + secs: 1624875206 + nsecs: 760040998 + frame_id: "/world" +pose: + pose: + position: + x: -0.00339454594581 + y: -0.0395768513578 + z: 0.0 + orientation: + x: 0.0 + y: 3.83969782731e-05 + z: 0.0 + w: 0.999999999263 + covariance: [1.7985984875954946, -1.290144350572323e-07, 0.0, 0.0, -9.160050612739759e-05, 0.0, -1.2901443505723215e-07, 1.7985980113558706, 0.0, 0.0, 2.377432212042449e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.16005061273979e-05, 2.3774322120424525e-05, 0.0, 0.0, 1.7816697781723911, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 80 + stamp: + secs: 1624875206 + nsecs: 840075016 + frame_id: "/world" +pose: + pose: + position: + x: -0.00343968751584 + y: -0.0402519430325 + z: 0.0 + orientation: + x: 0.0 + y: 0.00044407023632 + z: 0.0 + w: 0.999999901401 + covariance: [1.7757537798636551, -1.4933294896593207e-07, 0.0, 0.0, -2.743492850514558e-05, 0.0, -1.4933294896593226e-07, 1.775753231050367, 0.0, 0.0, 7.451675207806738e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.743492850514565e-05, 7.451675207806744e-06, 0.0, 0.0, 1.7623314766118436, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 81 + stamp: + secs: 1624875206 + nsecs: 920078039 + frame_id: "/world" +pose: + pose: + position: + x: -0.00246173577697 + y: -0.0295442996873 + z: 0.0 + orientation: + x: 0.0 + y: 1.18165935754e-05 + z: 0.0 + w: 0.99999999993 + covariance: [1.6902744992829395, -2.0580428685988454e-07, 0.0, 0.0, -8.605845414963455e-06, 0.0, -2.058042868598842e-07, 1.6902737440121003, 0.0, 0.0, 2.422437042719097e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.60584541496347e-06, 2.4224370427190994e-06, 0.0, 0.0, 1.6725927172120376, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 82 + stamp: + secs: 1624875207 + nsecs: 80077887 + frame_id: "/world" +pose: + pose: + position: + x: -0.00821615852125 + y: -0.0317940629996 + z: 0.0 + orientation: + x: 0.0 + y: 0.000620694243467 + z: 0.0 + w: 0.999999807369 + covariance: [1.8636980566411203, -4.839730953360694e-07, 0.0, 0.0, -8.338566502042762e-06, 0.0, -4.839730953360695e-07, 1.8636962942470128, 0.0, 0.0, 3.226998618054302e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.338566502042764e-06, 3.226998618054303e-05, 0.0, 0.0, 1.8189392706097263, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 83 + stamp: + secs: 1624875207 + nsecs: 240103006 + frame_id: "/world" +pose: + pose: + position: + x: -0.00669040752248 + y: -0.0880337867714 + z: 0.0 + orientation: + x: -0.0 + y: -0.000789906092025 + z: -0.0 + w: 0.999999688024 + covariance: [1.8711996169300524, -4.135006044691124e-07, 0.0, 0.0, -4.356049060256984e-06, 0.0, -4.1350060446911306e-07, 1.8711981418115107, 0.0, 0.0, 1.6347039593020524e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.356049060256984e-06, 1.6347039593020544e-05, 0.0, 0.0, 1.8294016044511539, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 84 + stamp: + secs: 1624875207 + nsecs: 320096970 + frame_id: "/world" +pose: + pose: + position: + x: -0.00592696577547 + y: -0.0283491020271 + z: 0.0 + orientation: + x: -0.0 + y: -0.00400013906984 + z: -0.0 + w: 0.999991999412 + covariance: [1.8254277226526838, -2.5848726571057886e-07, 0.0, 0.0, -1.2038847706237911e-06, 0.0, -2.5848726571057897e-07, 1.8254268080557343, 0.0, 0.0, 4.040646512021606e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2038847706237905e-06, 4.040646512021594e-06, 0.0, 0.0, 1.7972944760545944, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 85 + stamp: + secs: 1624875207 + nsecs: 480118990 + frame_id: "/world" +pose: + pose: + position: + x: -0.00427694282486 + y: -0.0345147050858 + z: 0.0 + orientation: + x: 0.0 + y: 0.0023167359751 + z: 0.0 + w: 0.999997316364 + covariance: [1.6297797477971856, -2.8477501588407455e-07, 0.0, 0.0, 5.112830004550244e-07, 0.0, -2.8477501588407397e-07, 1.6297787436769104, 0.0, 0.0, 9.339361107790823e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 5.112830004550251e-07, 9.339361107790807e-07, 0.0, 0.0, 1.5945939262185393, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 86 + stamp: + secs: 1624875207 + nsecs: 640136957 + frame_id: "/world" +pose: + pose: + position: + x: -0.00757101970728 + y: -0.0320286322555 + z: 0.0 + orientation: + x: -0.0 + y: -0.00155990848621 + z: -0.0 + w: 0.999998783342 + covariance: [1.6614432577736096, -1.9714609870693578e-07, 0.0, 0.0, -2.649406162343664e-05, 0.0, -1.9714609870693555e-07, 1.6614425605895764, 0.0, 0.0, 4.118822135091302e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.6494061623436728e-05, 4.118822135091312e-06, 0.0, 0.0, 1.6350442185544718, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 87 + stamp: + secs: 1624875207 + nsecs: 720158100 + frame_id: "/world" +pose: + pose: + position: + x: -0.00329196440245 + y: -0.032853458787 + z: 0.0 + orientation: + x: 0.0 + y: 0.000326546679687 + z: 0.0 + w: 0.999999946684 + covariance: [1.6040678153099837, -1.3011900341901313e-07, 0.0, 0.0, -1.042096607231989e-05, 0.0, -1.3011900341901287e-07, 1.6040673478257008, 0.0, 0.0, 1.858924208829491e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0420966072319891e-05, 1.8589242088294905e-06, 0.0, 0.0, 1.5856007730756487, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 88 + stamp: + secs: 1624875207 + nsecs: 880158901 + frame_id: "/world" +pose: + pose: + position: + x: -0.00356324457845 + y: -0.0337990906803 + z: 0.0 + orientation: + x: -0.0 + y: -0.000634146938411 + z: -0.0 + w: 0.999999798929 + covariance: [1.7176335416929889, -1.7937846867736778e-07, 0.0, 0.0, -3.875965590353022e-06, 0.0, -1.7937846867736816e-07, 1.7176328924872304, 0.0, 0.0, 4.1852318415957595e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.875965590353015e-06, 4.1852318415957526e-07, 0.0, 0.0, 1.689673957413502, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 89 + stamp: + secs: 1624875207 + nsecs: 960160017 + frame_id: "/world" +pose: + pose: + position: + x: -0.00361146300675 + y: -0.0345568392217 + z: 0.0 + orientation: + x: 0.0 + y: 0.000132370079954 + z: 0.0 + w: 0.999999991239 + covariance: [1.6339774928720778, -1.1738435026580455e-07, 0.0, 0.0, -1.0584383440271161e-05, 0.0, -1.1738435026580415e-07, 1.6339770671879437, 0.0, 0.0, 2.3721108084883797e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0584383440271158e-05, 2.3721108084883797e-06, 0.0, 0.0, 1.6142633223224827, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 90 + stamp: + secs: 1624875208 + nsecs: 120165110 + frame_id: "/world" +pose: + pose: + position: + x: -0.00382407113079 + y: -0.0355370020367 + z: 0.0 + orientation: + x: -0.0 + y: -0.000296782066312 + z: -0.0 + w: 0.99999995596 + covariance: [1.7212915937665996, -1.6234818554945164e-07, 0.0, 0.0, -1.3964181568622037e-05, 0.0, -1.623481855494517e-07, 1.7212910069379699, 0.0, 0.0, 9.16140082263144e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.396418156862204e-05, 9.161400822631454e-06, 0.0, 0.0, 1.6915310290709678, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 91 + stamp: + secs: 1624875208 + nsecs: 200181961 + frame_id: "/world" +pose: + pose: + position: + x: -0.0050723855732 + y: -0.0440310058195 + z: 0.0 + orientation: + x: -0.0 + y: -0.000412507104631 + z: -0.0 + w: 0.999999914919 + covariance: [1.7478717226096319, -1.1574713769071338e-07, 0.0, 0.0, -1.926546373056468e-05, 0.0, -1.1574713769071309e-07, 1.7478713173790048, 0.0, 0.0, 1.8519057019452253e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.926546373056465e-05, 1.8519057019452287e-05, 0.0, 0.0, 1.7260674659991069, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 92 + stamp: + secs: 1624875208 + nsecs: 360193968 + frame_id: "/world" +pose: + pose: + position: + x: -0.00552432225663 + y: -0.0473789401518 + z: 0.0 + orientation: + x: -0.0 + y: -0.000407679556129 + z: -0.0 + w: 0.999999916899 + covariance: [1.7606384814445657, -1.6920718050462404e-07, 0.0, 0.0, -1.71207824203988e-05, 0.0, -1.692071805046245e-07, 1.7606379444433968, 0.0, 0.0, 2.251255923945774e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7120782420398767e-05, 2.2512559239457718e-05, 0.0, 0.0, 1.7280773139665202, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 93 + stamp: + secs: 1624875208 + nsecs: 440201998 + frame_id: "/world" +pose: + pose: + position: + x: -0.00573814580659 + y: -0.048284491919 + z: 0.0 + orientation: + x: -0.0 + y: -0.000145639975462 + z: -0.0 + w: 0.999999989394 + covariance: [1.7494457784046296, -1.0737174290387708e-07, 0.0, 0.0, -1.8221926922154206e-05, 0.0, -1.073717429038775e-07, 1.7494454526333596, 0.0, 0.0, 7.69432780200795e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.822192692215421e-05, 7.694327802007916e-06, 0.0, 0.0, 1.7283804743562345, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 94 + stamp: + secs: 1624875208 + nsecs: 600233078 + frame_id: "/world" +pose: + pose: + position: + x: -0.00441720612399 + y: -0.0143104799209 + z: 0.0 + orientation: + x: -0.0 + y: -0.000898818249404 + z: -0.0 + w: 0.999999596063 + covariance: [1.755540367965466, -1.3012863943496627e-07, 0.0, 0.0, -4.6314329238828526e-05, 0.0, -1.3012863943496592e-07, 1.755539964388035, 0.0, 0.0, 3.0504352014404467e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.6314329238828506e-05, 3.0504352014404425e-06, 0.0, 0.0, 1.728443756959659, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 95 + stamp: + secs: 1624875208 + nsecs: 760227919 + frame_id: "/world" +pose: + pose: + position: + x: -0.00875847401444 + y: -0.0154019784809 + z: 0.0 + orientation: + x: -0.0 + y: -0.000464915948349 + z: -0.0 + w: 0.999999891927 + covariance: [1.665502210506273, -1.0291300213564642e-07, 0.0, 0.0, -5.0621628960778616e-05, 0.0, -1.0291300213564628e-07, 1.6655018551936212, 0.0, 0.0, 7.78742200340651e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.06216289607787e-05, 7.787422003406519e-06, 0.0, 0.0, 1.6436355051644356, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 96 + stamp: + secs: 1624875208 + nsecs: 840251923 + frame_id: "/world" +pose: + pose: + position: + x: -0.0048650978665 + y: -0.0149031529164 + z: 0.0 + orientation: + x: -0.0 + y: -0.000675393829776 + z: -0.0 + w: 0.999999771922 + covariance: [1.7076282226493074, -6.661029969352896e-08, 0.0, 0.0, -1.9086760063287902e-05, 0.0, -6.661029969352887e-08, 1.7076279783538304, 0.0, 0.0, 3.2527120769580688e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.90867600632879e-05, 3.2527120769580713e-06, 0.0, 0.0, 1.6937754658007105, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 97 + stamp: + secs: 1624875209 + nsecs: 256062 + frame_id: "/world" +pose: + pose: + position: + x: -0.00836897567144 + y: -0.000198529961433 + z: 0.0 + orientation: + x: -0.0 + y: -0.000708145875186 + z: -0.0 + w: 0.999999749265 + covariance: [2.2639347615328345, -1.7410817352037372e-07, 0.0, 0.0, -2.2682286731668303e-05, 0.0, -1.7410817352037345e-07, 2.2639341084734594, 0.0, 0.0, 8.802747091435968e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.268228673166828e-05, 8.80274709143597e-06, 0.0, 0.0, 2.225319097221873, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 98 + stamp: + secs: 1624875209 + nsecs: 80250978 + frame_id: "/world" +pose: + pose: + position: + x: -0.0123811811887 + y: 0.00261610939291 + z: 0.0 + orientation: + x: 0.0 + y: 1.8918256449e-05 + z: 0.0 + w: 0.999999999821 + covariance: [1.950211143806021, -9.115537249034647e-08, 0.0, 0.0, -1.6457441496081313e-05, 0.0, -9.115537249034638e-08, 1.950210801844978, 0.0, 0.0, 3.7173008262198036e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.645744149608132e-05, 3.7173008262198074e-06, 0.0, 0.0, 1.9291039310692284, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 99 + stamp: + secs: 1624875209 + nsecs: 160267115 + frame_id: "/world" +pose: + pose: + position: + x: -0.015854664647 + y: -0.00411641411716 + z: 0.0 + orientation: + x: -0.0 + y: -0.000758654279928 + z: -0.0 + w: 0.999999712222 + covariance: [1.9302244361453849, -9.582727880531267e-08, 0.0, 0.0, -4.820024722222409e-05, 0.0, -9.582727880531233e-08, 1.930224076113128, 0.0, 0.0, 1.2809551950644853e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.820024722222406e-05, 1.2809551950644846e-05, 0.0, 0.0, 1.907600409513591, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 100 + stamp: + secs: 1624875209 + nsecs: 320278883 + frame_id: "/world" +pose: + pose: + position: + x: -0.0176537944286 + y: -0.0107489380159 + z: 0.0 + orientation: + x: -0.0 + y: -0.000815600163292 + z: -0.0 + w: 0.999999667398 + covariance: [1.8297123838285967, -1.1714023635125232e-07, 0.0, 0.0, -2.7823861107502735e-05, 0.0, -1.1714023635125227e-07, 1.8297119492162224, 0.0, 0.0, 8.19461831004986e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.7823861107502653e-05, 8.194618310049838e-06, 0.0, 0.0, 1.8032142978814398, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 101 + stamp: + secs: 1624875209 + nsecs: 400302887 + frame_id: "/world" +pose: + pose: + position: + x: -0.0188562982378 + y: 0.0191978026038 + z: 0.0 + orientation: + x: -0.0 + y: -0.00251721351973 + z: -0.0 + w: 0.999996831813 + covariance: [2.2634169073766186, -1.1079395375356554e-07, 0.0, 0.0, -9.7822021406345e-06, 0.0, -1.1079395375356541e-07, 2.2634164981982803, 0.0, 0.0, 3.0137814559272017e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.782202140634493e-06, 3.0137814559272e-06, 0.0, 0.0, 2.237273617176817, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 102 + stamp: + secs: 1624875209 + nsecs: 640314102 + frame_id: "/world" +pose: + pose: + position: + x: -0.0226500453243 + y: 0.00868031054124 + z: 0.0 + orientation: + x: -0.0 + y: -0.000558053224148 + z: -0.0 + w: 0.999999844288 + covariance: [2.7264445493091114, -5.445060667631012e-07, 0.0, 0.0, -3.757157897646139e-05, 0.0, -5.445060667631013e-07, 2.7264425406228905, 0.0, 0.0, 5.036235011324074e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.757157897646136e-05, 5.036235011324065e-06, 0.0, 0.0, 2.5772697954842028, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 103 + stamp: + secs: 1624875209 + nsecs: 800335884 + frame_id: "/world" +pose: + pose: + position: + x: -0.0230214917772 + y: 0.00816598389624 + z: 0.0 + orientation: + x: -0.0 + y: -0.000359351812885 + z: -0.0 + w: 0.999999935433 + covariance: [1.9192466769154861, -1.3194379498795747e-07, 0.0, 0.0, -1.0172049618106268e-05, 0.0, -1.3194379498795713e-07, 1.9192461906799372, 0.0, 0.0, 7.81342821394139e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0172049618106267e-05, 7.81342821394141e-06, 0.0, 0.0, 1.880160013081389, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 104 + stamp: + secs: 1624875209 + nsecs: 880331039 + frame_id: "/world" +pose: + pose: + position: + x: -0.0189030370624 + y: 0.0201314226004 + z: 0.0 + orientation: + x: -0.0 + y: -0.00068298572671 + z: -0.0 + w: 0.999999766765 + covariance: [1.9499457089296692, -3.0919708529097934e-08, 0.0, 0.0, -2.872388861410236e-06, 0.0, -3.0919708529097835e-08, 1.94994559566827, 0.0, 0.0, 2.2896289334546105e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.8723888614102303e-06, 2.289628933454613e-06, 0.0, 0.0, 1.9406232179513276, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 105 + stamp: + secs: 1624875209 + nsecs: 960352898 + frame_id: "/world" +pose: + pose: + position: + x: -0.0172645085389 + y: 0.0121864065367 + z: 0.0 + orientation: + x: -0.0 + y: -0.000248222073615 + z: -0.0 + w: 0.999999969193 + covariance: [1.9202764219969553, -3.6699361807453496e-08, 0.0, 0.0, -1.7644648159514204e-06, 0.0, -3.669936180745341e-08, 1.9202762891533507, 0.0, 0.0, 3.853491314920656e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7644648159514183e-06, 3.853491314920655e-06, 0.0, 0.0, 1.9081279979090322, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 106 + stamp: + secs: 1624875210 + nsecs: 40358067 + frame_id: "/world" +pose: + pose: + position: + x: -0.015800821562 + y: 0.0205928897181 + z: 0.0 + orientation: + x: -0.0 + y: -0.000715114604136 + z: -0.0 + w: 0.999999744306 + covariance: [1.7868420685733515, -4.520472855443249e-08, 0.0, 0.0, -6.413384191381361e-06, 0.0, -4.5204728554432324e-08, 1.7868419059365102, 0.0, 0.0, 1.835420625583562e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.413384191381355e-06, 1.8354206255835638e-06, 0.0, 0.0, 1.7711601903415117, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 107 + stamp: + secs: 1624875210 + nsecs: 200356007 + frame_id: "/world" +pose: + pose: + position: + x: -0.0215801325025 + y: 0.00944961005098 + z: 0.0 + orientation: + x: -0.0 + y: -0.00102349444487 + z: -0.0 + w: 0.999999476229 + covariance: [2.3786207934169528, -1.0497014591544331e-07, 0.0, 0.0, -1.2608155957759731e-05, 0.0, -1.0497014591544322e-07, 2.3786204144421035, 0.0, 0.0, 1.2625407141937574e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.260815595775972e-05, 1.2625407141937578e-06, 0.0, 0.0, 2.338427103592896, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 108 + stamp: + secs: 1624875210 + nsecs: 280395031 + frame_id: "/world" +pose: + pose: + position: + x: -0.0177650671655 + y: 0.014427704836 + z: 0.0 + orientation: + x: -0.0 + y: -0.000133968059037 + z: -0.0 + w: 0.999999991026 + covariance: [1.915970495894569, -3.899513611452234e-08, 0.0, 0.0, -3.020423791447676e-06, 0.0, -3.899513611452232e-08, 1.9159703548455238, 0.0, 0.0, 8.32435535259478e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.0204237914476806e-06, 8.324355352594779e-07, 0.0, 0.0, 1.9003392566737118, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 109 + stamp: + secs: 1624875210 + nsecs: 360379934 + frame_id: "/world" +pose: + pose: + position: + x: -0.0180528364044 + y: 0.0138177616402 + z: 0.0 + orientation: + x: -0.0 + y: -0.000740356107303 + z: -0.0 + w: 0.999999725936 + covariance: [1.8191632501593693, -3.936595825779304e-08, 0.0, 0.0, -1.4507111235675544e-05, 0.0, -3.9365958257793084e-08, 1.8191631073257044, 0.0, 0.0, 2.8908994490007875e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.4507111235675522e-05, 2.890899449000781e-06, 0.0, 0.0, 1.8024192315405911, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 110 + stamp: + secs: 1624875210 + nsecs: 520392895 + frame_id: "/world" +pose: + pose: + position: + x: -0.0156765062243 + y: 0.0197297137429 + z: 0.0 + orientation: + x: -0.0 + y: -0.000921353950671 + z: -0.0 + w: 0.999999575553 + covariance: [1.7558929986139256, -4.986990041967492e-08, 0.0, 0.0, -1.3692852084904276e-05, 0.0, -4.98699004196749e-08, 1.7558928170165167, 0.0, 0.0, 6.2560682738503005e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3692852084904309e-05, 6.256068273850301e-06, 0.0, 0.0, 1.7334926097557812, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 111 + stamp: + secs: 1624875210 + nsecs: 600393057 + frame_id: "/world" +pose: + pose: + position: + x: -0.0167348255494 + y: 0.022608323214 + z: 0.0 + orientation: + x: 0.0 + y: 0.000269944431353 + z: 0.0 + w: 0.999999963565 + covariance: [1.741809148582395, -2.8330819696685416e-08, 0.0, 0.0, -5.271531131532721e-06, 0.0, -2.833081969668545e-08, 1.7418090477861665, 0.0, 0.0, 8.105575283580987e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.271531131532728e-06, 8.10557528358099e-06, 0.0, 0.0, 1.7285462305191341, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 112 + stamp: + secs: 1624875210 + nsecs: 680402040 + frame_id: "/world" +pose: + pose: + position: + x: -0.0151815409614 + y: 0.0268601168938 + z: 0.0 + orientation: + x: 0.0 + y: 0.000181074163638 + z: 0.0 + w: 0.999999983606 + covariance: [1.7175549472333327, -3.813921933680286e-08, 0.0, 0.0, -2.002005146551767e-06, 0.0, -3.8139219336802933e-08, 1.71755481772857, 0.0, 0.0, 5.289110247841489e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.002005146551767e-06, 5.289110247841467e-06, 0.0, 0.0, 1.698919815966571, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 113 + stamp: + secs: 1624875210 + nsecs: 840425968 + frame_id: "/world" +pose: + pose: + position: + x: -0.0161310134795 + y: 0.0270475415063 + z: 0.0 + orientation: + x: 0.0 + y: 0.000102547760067 + z: 0.0 + w: 0.999999994742 + covariance: [1.9268786555899176, -7.170560326846011e-08, 0.0, 0.0, -1.959339302409181e-05, 0.0, -7.17056032684601e-08, 1.9268784183472327, 0.0, 0.0, 1.129281591489704e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.959339302409178e-05, 1.1292815914897023e-05, 0.0, 0.0, 1.8893645464156361, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 114 + stamp: + secs: 1624875210 + nsecs: 920433044 + frame_id: "/world" +pose: + pose: + position: + x: -0.0144401127726 + y: 0.0163655523434 + z: 0.0 + orientation: + x: -0.0 + y: -0.000413082990648 + z: -0.0 + w: 0.999999914681 + covariance: [1.8600431441394358, -4.832389505927113e-08, 0.0, 0.0, -1.279381318524166e-05, 0.0, -4.832389505927124e-08, 1.8600429890061072, 0.0, 0.0, 5.253915309008619e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.279381318524166e-05, 5.253915309008612e-06, 0.0, 0.0, 1.8343950181993693, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 115 + stamp: + secs: 1624875211 + nsecs: 80427885 + frame_id: "/world" +pose: + pose: + position: + x: -0.0198610711195 + y: 0.0256738120055 + z: 0.0 + orientation: + x: -0.0 + y: -0.00038599638508 + z: -0.0 + w: 0.999999925503 + covariance: [1.7964962856169158, -5.4336771093988836e-08, 0.0, 0.0, -5.660641251633593e-06, 0.0, -5.4336771093988915e-08, 1.7964961136084119, 0.0, 0.0, 2.0190906453571833e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.660641251633592e-06, 2.019090645357179e-06, 0.0, 0.0, 1.7658696462941879, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 116 + stamp: + secs: 1624875211 + nsecs: 160442114 + frame_id: "/world" +pose: + pose: + position: + x: -0.0153228042934 + y: 0.0270988993171 + z: 0.0 + orientation: + x: 0.0 + y: 0.0001606858847 + z: 0.0 + w: 0.99999998709 + covariance: [2.028278757410154, -3.3278841386987134e-08, 0.0, 0.0, -9.180811537239745e-05, 0.0, -3.327884138698714e-08, 2.0282786094966827, 0.0, 0.0, 8.669867631696277e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.180811537239748e-05, 8.669867631696276e-07, 0.0, 0.0, 2.008833895673048, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 117 + stamp: + secs: 1624875211 + nsecs: 240469933 + frame_id: "/world" +pose: + pose: + position: + x: -0.0278697410627 + y: 0.0441777289446 + z: 0.0 + orientation: + x: -0.0 + y: -0.000502936148865 + z: -0.0 + w: 0.999999873528 + covariance: [1.8281871309889548, -3.153766810008135e-08, 0.0, 0.0, -5.805639353296562e-05, 0.0, -3.153766810008143e-08, 1.82818677002589, 0.0, 0.0, 1.2864844505347815e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.8056393532965785e-05, 1.2864844505347819e-06, 0.0, 0.0, 1.8093899057609084, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 118 + stamp: + secs: 1624875211 + nsecs: 320468903 + frame_id: "/world" +pose: + pose: + position: + x: -0.0209562233462 + y: 0.0459004277255 + z: 0.0 + orientation: + x: -0.0 + y: -0.00199480456087 + z: -0.0 + w: 0.999998010375 + covariance: [1.7547167198499007, -3.500954541907041e-08, 0.0, 0.0, -3.7081918348769676e-05, 0.0, -3.500954541907046e-08, 1.7547162334232373, 0.0, 0.0, 4.793621031509397e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.7081918348769696e-05, 4.7936210315094e-06, 0.0, 0.0, 1.7336410041953976, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 119 + stamp: + secs: 1624875211 + nsecs: 480456114 + frame_id: "/world" +pose: + pose: + position: + x: -0.0347148789225 + y: 0.0319532120273 + z: 0.0 + orientation: + x: 0.0 + y: 0.000218589213485 + z: 0.0 + w: 0.999999976109 + covariance: [1.8304492449014345, -6.603087813110398e-08, 0.0, 0.0, -3.1749523646959775e-05, 0.0, -6.603087813110394e-08, 1.8304483358625017, 0.0, 0.0, 5.076344509695924e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.174952364695976e-05, 5.0763445096959235e-06, 0.0, 0.0, 1.7907237563209897, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 120 + stamp: + secs: 1624875211 + nsecs: 640486956 + frame_id: "/world" +pose: + pose: + position: + x: -0.0351585550581 + y: 0.0307477117648 + z: 0.0 + orientation: + x: 0.0 + y: 0.000249420675031 + z: 0.0 + w: 0.999999968895 + covariance: [1.7676537484061823, -5.5087761952654015e-08, 0.0, 0.0, -1.583371319393279e-05, 0.0, -5.508776195265402e-08, 1.7676529994813701, 0.0, 0.0, 2.1644922186936384e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.583371319393279e-05, 2.1644922186936363e-06, 0.0, 0.0, 1.7323073682258, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 121 + stamp: + secs: 1624875211 + nsecs: 720500946 + frame_id: "/world" +pose: + pose: + position: + x: -0.0355765290453 + y: 0.0301628610216 + z: 0.0 + orientation: + x: -0.0 + y: -9.06694762601e-05 + z: -0.0 + w: 0.99999999589 + covariance: [1.777231743902157, -2.7228484439367553e-08, 0.0, 0.0, -6.601429633196624e-06, 0.0, -2.7228484439367537e-08, 1.777231375392685, 0.0, 0.0, 5.284172979764981e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.60142963319664e-06, 5.284172979764985e-07, 0.0, 0.0, 1.758909384332062, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 122 + stamp: + secs: 1624875211 + nsecs: 800513029 + frame_id: "/world" +pose: + pose: + position: + x: -0.0300332962856 + y: 0.0242580191195 + z: 0.0 + orientation: + x: 0.0 + y: 0.000274336377285 + z: 0.0 + w: 0.99999996237 + covariance: [1.9958154267746533, -3.737769522343045e-08, 0.0, 0.0, -8.260644785140953e-06, 0.0, -3.737769522343051e-08, 1.9958149216239023, 0.0, 0.0, 5.16626571355384e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.260644785140964e-06, 5.166265713553839e-07, 0.0, 0.0, 1.9687116480162554, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 123 + stamp: + secs: 1624875211 + nsecs: 960508108 + frame_id: "/world" +pose: + pose: + position: + x: -0.0306737985319 + y: 0.0229282026058 + z: 0.0 + orientation: + x: 0.0 + y: 2.27042507861e-05 + z: 0.0 + w: 0.999999999742 + covariance: [2.1989459317633226, -5.27817951334415e-08, 0.0, 0.0, -9.065201075282274e-06, 0.0, -5.278179513344153e-08, 2.198945221630889, 0.0, 0.0, 6.23935876348776e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.065201075282268e-06, 6.239358763487763e-06, 0.0, 0.0, 2.1575027261563324, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 124 + stamp: + secs: 1624875212 + nsecs: 200536013 + frame_id: "/world" +pose: + pose: + position: + x: -0.0126580108318 + y: -0.0151249009866 + z: 0.0 + orientation: + x: -0.0 + y: -0.000666069468156 + z: -0.0 + w: 0.999999778176 + covariance: [1.8199122309059839, -7.14701003043723e-08, 0.0, 0.0, -4.4546002503291785e-06, 0.0, -7.147010030437258e-08, 1.8199113006807888, 0.0, 0.0, 3.6254735317293405e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.454600250329176e-06, 3.625473531729332e-05, 0.0, 0.0, 1.7553242812714172, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 125 + stamp: + secs: 1624875212 + nsecs: 280575037 + frame_id: "/world" +pose: + pose: + position: + x: -0.0125649076302 + y: -0.0165661076265 + z: 0.0 + orientation: + x: 0.0 + y: 0.000414913811558 + z: 0.0 + w: 0.999999913923 + covariance: [1.817834826313506, -2.7232208346303692e-08, 0.0, 0.0, -2.441821857697161e-06, 0.0, -2.723220834630375e-08, 1.817834485991075, 0.0, 0.0, 1.0961316579068044e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4418218576971594e-06, 1.0961316579068047e-05, 0.0, 0.0, 1.7920381133497134, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 126 + stamp: + secs: 1624875212 + nsecs: 440562963 + frame_id: "/world" +pose: + pose: + position: + x: -0.0127478132455 + y: -0.0181545302618 + z: 0.0 + orientation: + x: -0.0 + y: -0.000389798937385 + z: -0.0 + w: 0.999999924028 + covariance: [1.6440719564889155, -2.3974049976273022e-08, 0.0, 0.0, -2.969353714947975e-05, 0.0, -2.397404997627293e-08, 1.6440716692284039, 0.0, 0.0, 3.024493519713834e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.9693537149479706e-05, 3.0244935197138356e-06, 0.0, 0.0, 1.6203362794871619, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 127 + stamp: + secs: 1624875212 + nsecs: 520561934 + frame_id: "/world" +pose: + pose: + position: + x: -0.012777427079 + y: -0.0190119077224 + z: 0.0 + orientation: + x: -0.0 + y: -0.000351418861302 + z: -0.0 + w: 0.999999938252 + covariance: [1.7060298322335328, -1.3926411273134203e-08, 0.0, 0.0, -1.3996164461524566e-05, 0.0, -1.3926411273134228e-08, 1.7060296603095202, 0.0, 0.0, 1.5443891247214911e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3996164461524556e-05, 1.5443891247214899e-06, 0.0, 0.0, 1.6920592116878344, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 128 + stamp: + secs: 1624875212 + nsecs: 680576086 + frame_id: "/world" +pose: + pose: + position: + x: -0.012990063607 + y: -0.0207035111067 + z: 0.0 + orientation: + x: -0.0 + y: -0.000848261374327 + z: -0.0 + w: 0.999999640226 + covariance: [1.6893448886589562, -2.0313716703536002e-08, 0.0, 0.0, -6.315143989311915e-06, 0.0, -2.0313716703536035e-08, 1.68934464459119, 0.0, 0.0, 1.4454981630327028e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.315143989311915e-06, 1.4454981630327021e-05, 0.0, 0.0, 1.6689841198517645, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 129 + stamp: + secs: 1624875212 + nsecs: 760581970 + frame_id: "/world" +pose: + pose: + position: + x: -0.0163981854269 + y: -0.0107370428213 + z: 0.0 + orientation: + x: -0.0 + y: -0.000300191002887 + z: -0.0 + w: 0.999999954943 + covariance: [1.7087616492210447, -1.345410801219459e-08, 0.0, 0.0, -6.964730210419931e-06, 0.0, -1.3454108012194585e-08, 1.7087615008879269, 0.0, 0.0, 7.970168215677332e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.964730210419942e-06, 7.970168215677327e-06, 0.0, 0.0, 1.6952589287418098, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 130 + stamp: + secs: 1624875212 + nsecs: 920597076 + frame_id: "/world" +pose: + pose: + position: + x: -0.00394081515953 + y: -0.0105029290837 + z: 0.0 + orientation: + x: -0.0 + y: -0.00189355578176 + z: -0.0 + w: 0.999998207222 + covariance: [1.8123882068979635, -2.4227729432102258e-08, 0.0, 0.0, -5.984297053563993e-06, 0.0, -2.4227729432102215e-08, 1.8123879639457239, 0.0, 0.0, 4.274749227316811e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.9842970535639865e-06, 4.274749227316814e-06, 0.0, 0.0, 1.7879608462334327, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 131 + stamp: + secs: 1624875213 + nsecs: 160621881 + frame_id: "/world" +pose: + pose: + position: + x: -0.00419653377753 + y: -0.0126589751912 + z: 0.0 + orientation: + x: -0.0 + y: -0.000145064431591 + z: -0.0 + w: 0.999999989478 + covariance: [1.7577397912783934, -4.799700146928299e-08, 0.0, 0.0, -7.136252937790986e-06, 0.0, -4.799700146928312e-08, 1.7577393229809886, 0.0, 0.0, 3.292681180080038e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.136252937790955e-06, 3.292681180080037e-06, 0.0, 0.0, 1.703356177818743, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 132 + stamp: + secs: 1624875213 + nsecs: 240650892 + frame_id: "/world" +pose: + pose: + position: + x: -0.00443373726017 + y: -0.0136002813928 + z: 0.0 + orientation: + x: -0.0 + y: -0.000400502512205 + z: -0.0 + w: 0.999999919799 + covariance: [1.810941085345762, -1.8836335253451973e-08, 0.0, 0.0, -1.8991463162802732e-05, 0.0, -1.8836335253451933e-08, 1.8109409016127287, 0.0, 0.0, 1.038634429250637e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8991463162802712e-05, 1.0386344292506374e-06, 0.0, 0.0, 1.7884909351984446, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 133 + stamp: + secs: 1624875213 + nsecs: 400671005 + frame_id: "/world" +pose: + pose: + position: + x: -0.00690523722517 + y: -0.0115603637182 + z: 0.0 + orientation: + x: -0.0 + y: -0.000253709407933 + z: -0.0 + w: 0.999999967816 + covariance: [1.7269889510693466, -1.8966168513855578e-08, 0.0, 0.0, -1.370766082662116e-05, 0.0, -1.89661685138556e-08, 1.7269887567650364, 0.0, 0.0, 1.328800424836996e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3707660826621137e-05, 1.3288004248369962e-06, 0.0, 0.0, 1.702782391291518, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 134 + stamp: + secs: 1624875213 + nsecs: 480642080 + frame_id: "/world" +pose: + pose: + position: + x: -0.00699910200236 + y: -0.0122619658331 + z: 0.0 + orientation: + x: -0.0 + y: -9.48849666012e-05 + z: -0.0 + w: 0.999999995498 + covariance: [1.6814662160216771, -9.704480916695382e-09, 0.0, 0.0, -2.9097341401353432e-05, 0.0, -9.704480916695398e-09, 1.6814661125972725, 0.0, 0.0, 1.6012792379698798e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.9097341401353408e-05, 1.601279237969879e-06, 0.0, 0.0, 1.6689514953203453, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 135 + stamp: + secs: 1624875213 + nsecs: 560708046 + frame_id: "/world" +pose: + pose: + position: + x: -0.00704852338253 + y: -0.013286972516 + z: 0.0 + orientation: + x: -0.0 + y: -0.000268331167432 + z: -0.0 + w: 0.999999963999 + covariance: [1.6574732388107336, -1.500420885912657e-08, 0.0, 0.0, -2.066258949807088e-05, 0.0, -1.5004208859126616e-08, 1.6574730570341403, 0.0, 0.0, 1.047047609612736e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.06625894980709e-05, 1.0470476096127355e-06, 0.0, 0.0, 1.6395384005182905, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 136 + stamp: + secs: 1624875213 + nsecs: 720674992 + frame_id: "/world" +pose: + pose: + position: + x: -0.00708965380905 + y: -0.0151748239816 + z: 0.0 + orientation: + x: -0.0 + y: -0.00107304963146 + z: -0.0 + w: 0.999999424282 + covariance: [1.8544511249583058, -3.0318930441036966e-08, 0.0, 0.0, -1.2814365196650198e-05, 0.0, -3.03189304410369e-08, 1.8544507468929952, 0.0, 0.0, 2.0343933278549468e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2814365196650188e-05, 2.0343933278549497e-06, 0.0, 0.0, 1.8175831778265379, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 137 + stamp: + secs: 1624875213 + nsecs: 880716085 + frame_id: "/world" +pose: + pose: + position: + x: -0.0247137326465 + y: -0.00544502108451 + z: 0.0 + orientation: + x: -0.0 + y: -0.000632701845676 + z: -0.0 + w: 0.999999799844 + covariance: [1.73004047642552, -1.9621380452843024e-08, 0.0, 0.0, -1.0728602425091702e-05, 0.0, -1.9621380452843037e-08, 1.7300402391305918, 0.0, 0.0, 8.158622804101262e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.072860242509171e-05, 8.158622804101267e-06, 0.0, 0.0, 1.7048240198901057, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 138 + stamp: + secs: 1624875213 + nsecs: 960705042 + frame_id: "/world" +pose: + pose: + position: + x: -0.00589747873095 + y: -0.0511820441512 + z: 0.0 + orientation: + x: -0.0 + y: -0.0022870506106 + z: -0.0 + w: 0.999997384696 + covariance: [2.476728209911555, -2.7189894787959586e-08, 0.0, 0.0, -3.8943407014738214e-05, 0.0, -2.718989478795958e-08, 2.4767279186898965, 0.0, 0.0, 9.760559604343356e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.894340701473822e-05, 9.760559604343356e-06, 0.0, 0.0, 2.444166244980211, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 139 + stamp: + secs: 1624875214 + nsecs: 120723009 + frame_id: "/world" +pose: + pose: + position: + x: -0.0159555094821 + y: -0.0423671685151 + z: 0.0 + orientation: + x: -0.0 + y: -0.000263977577843 + z: -0.0 + w: 0.999999965158 + covariance: [1.8817610974819143, -4.0377701822125527e-08, 0.0, 0.0, -0.00010793625619293747, 0.0, -4.037770182212546e-08, 1.881760664164917, 0.0, 0.0, 4.442859218565017e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0001079362561929374, 4.442859218565011e-06, 0.0, 0.0, 1.8373166666647096, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 140 + stamp: + secs: 1624875214 + nsecs: 280742884 + frame_id: "/world" +pose: + pose: + position: + x: -0.0164479106857 + y: -0.0266694880648 + z: 0.0 + orientation: + x: -0.0 + y: -0.00126591214118 + z: -0.0 + w: 0.999999198733 + covariance: [1.9832325565756552, -4.191070345222918e-08, 0.0, 0.0, -5.983787315777082e-05, 0.0, -4.1910703452229195e-08, 1.9832319929473496, 0.0, 0.0, 1.866131034076362e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.9837873157770814e-05, 1.8661310340763602e-06, 0.0, 0.0, 1.9389327890311985, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 141 + stamp: + secs: 1624875214 + nsecs: 360743999 + frame_id: "/world" +pose: + pose: + position: + x: -0.0179661941506 + y: -0.0270122022306 + z: 0.0 + orientation: + x: -0.0 + y: -0.000254917516947 + z: -0.0 + w: 0.999999967509 + covariance: [1.674801097568249, -1.811492561463064e-08, 0.0, 0.0, -1.3189674742983305e-05, 0.0, -1.8114925614630605e-08, 1.6748008534438652, 0.0, 0.0, 1.172562778415646e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.3189674742983275e-05, 1.172562778415646e-05, 0.0, 0.0, 1.655730425923764, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 142 + stamp: + secs: 1624875214 + nsecs: 520785093 + frame_id: "/world" +pose: + pose: + position: + x: -0.0177621977282 + y: -0.027390538112 + z: 0.0 + orientation: + x: 0.0 + y: 7.02743391511e-05 + z: 0.0 + w: 0.999999997531 + covariance: [1.7160833032247964, -2.224161124586853e-08, 0.0, 0.0, -9.21931862777409e-06, 0.0, -2.2241611245868505e-08, 1.7160830477614726, 0.0, 0.0, 1.1484637366955054e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.219318627774097e-06, 1.1484637366955059e-05, 0.0, 0.0, 1.6942463374656325, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 143 + stamp: + secs: 1624875214 + nsecs: 600769043 + frame_id: "/world" +pose: + pose: + position: + x: -0.0181091753222 + y: -0.0285220466819 + z: 0.0 + orientation: + x: 0.0 + y: 0.000479977640177 + z: 0.0 + w: 0.999999884811 + covariance: [1.682529460783641, -1.5017497423673953e-08, 0.0, 0.0, -1.549448471382952e-05, 0.0, -1.5017497423673953e-08, 1.6825293042362472, 0.0, 0.0, 4.042389726519246e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5494484713829544e-05, 4.042389726519249e-06, 0.0, 0.0, 1.66850988968082, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 144 + stamp: + secs: 1624875214 + nsecs: 680773020 + frame_id: "/world" +pose: + pose: + position: + x: -0.0186190140113 + y: -0.0200777770547 + z: 0.0 + orientation: + x: 0.0 + y: 6.7314019886e-05 + z: 0.0 + w: 0.999999997734 + covariance: [1.775531613143067, -2.263906562386046e-08, 0.0, 0.0, -1.2499276318203065e-05, 0.0, -2.2639065623860494e-08, 1.7755313891341333, 0.0, 0.0, 2.565860386645869e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.249927631820307e-05, 2.565860386645864e-06, 0.0, 0.0, 1.754516691258627, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 145 + stamp: + secs: 1624875214 + nsecs: 840786934 + frame_id: "/world" +pose: + pose: + position: + x: -0.0191579941375 + y: -0.0215878702341 + z: 0.0 + orientation: + x: -0.0 + y: -0.000710052934631 + z: -0.0 + w: 0.999999747912 + covariance: [1.8967194325879266, -4.241625215166131e-08, 0.0, 0.0, -1.8896153278672175e-05, 0.0, -4.241625215166134e-08, 1.8967190654155976, 0.0, 0.0, 3.622038746655128e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.88961532786722e-05, 3.622038746655136e-05, 0.0, 0.0, 1.8592280960317893, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 146 + stamp: + secs: 1624875214 + nsecs: 920783043 + frame_id: "/world" +pose: + pose: + position: + x: -0.0277137290155 + y: -0.00293535405265 + z: 0.0 + orientation: + x: 0.0 + y: 3.40797880468e-05 + z: 0.0 + w: 0.999999999419 + covariance: [2.230430153299887, -4.756721458125785e-08, 0.0, 0.0, -1.064354874328306e-05, 0.0, -4.756721458125787e-08, 2.2304298427652665, 0.0, 0.0, 2.2353773209621798e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0643548743283073e-05, 2.235377320962179e-05, 0.0, 0.0, 2.1939577298984845, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 147 + stamp: + secs: 1624875215 + nsecs: 80796003 + frame_id: "/world" +pose: + pose: + position: + x: -0.0239585873436 + y: -0.0062342909353 + z: 0.0 + orientation: + x: 0.0 + y: 0.000712132191441 + z: 0.0 + w: 0.999999746434 + covariance: [1.786948240739618, -3.9358238609088995e-08, 0.0, 0.0, -2.5054394537498006e-05, 0.0, -3.935823860908905e-08, 1.7869480166930096, 0.0, 0.0, 6.033720516010694e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.5054394537498034e-05, 6.0337205160106885e-06, 0.0, 0.0, 1.7577777624864048, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 148 + stamp: + secs: 1624875215 + nsecs: 160804033 + frame_id: "/world" +pose: + pose: + position: + x: -0.0263929021945 + y: -0.00684020648068 + z: 0.0 + orientation: + x: -0.0 + y: -0.000330875261076 + z: -0.0 + w: 0.999999945261 + covariance: [1.8091440389710087, -2.2508537454904115e-08, 0.0, 0.0, -1.1184096364113381e-05, 0.0, -2.250853745490419e-08, 1.809143912659984, 0.0, 0.0, 2.3928832940313463e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.118409636411339e-05, 2.392883294031336e-06, 0.0, 0.0, 1.7921785540785415, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 149 + stamp: + secs: 1624875215 + nsecs: 320810080 + frame_id: "/world" +pose: + pose: + position: + x: -0.0262556310407 + y: -0.00257554184772 + z: 0.0 + orientation: + x: -0.0 + y: -0.000553320052148 + z: -0.0 + w: 0.999999846918 + covariance: [1.7257169983750016, -2.887215893959103e-08, 0.0, 0.0, -2.0839792791054042e-05, 0.0, -2.887215893959098e-08, 1.7257168365096953, 0.0, 0.0, 3.277273409671279e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.0839792791054032e-05, 3.277273409671277e-06, 0.0, 0.0, 1.7030458295424296, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 150 + stamp: + secs: 1624875215 + nsecs: 400810003 + frame_id: "/world" +pose: + pose: + position: + x: -0.0296610786575 + y: 0.00168027198319 + z: 0.0 + orientation: + x: -0.0 + y: -0.000133604754941 + z: -0.0 + w: 0.999999991075 + covariance: [1.7760199041739, -2.367491376008142e-08, 0.0, 0.0, -1.2049783621271146e-05, 0.0, -2.367491376008137e-08, 1.7760197700925517, 0.0, 0.0, 1.640503390238761e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.204978362127114e-05, 1.6405033902387638e-06, 0.0, 0.0, 1.7569022699144987, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 151 + stamp: + secs: 1624875215 + nsecs: 560842037 + frame_id: "/world" +pose: + pose: + position: + x: -0.030088594316 + y: 0.000695336183922 + z: 0.0 + orientation: + x: 0.0 + y: 0.000376638912957 + z: 0.0 + w: 0.999999929072 + covariance: [1.6709392937874474, -3.0554808814418046e-08, 0.0, 0.0, -7.51160805491788e-06, 0.0, -3.0554808814417966e-08, 1.6709391230205617, 0.0, 0.0, 9.406945221654571e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.511608054917877e-06, 9.406945221654561e-06, 0.0, 0.0, 1.6448962532836724, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 152 + stamp: + secs: 1624875215 + nsecs: 640876055 + frame_id: "/world" +pose: + pose: + position: + x: -0.0189968732394 + y: -0.00588618382175 + z: 0.0 + orientation: + x: -0.0 + y: -0.000153993311551 + z: -0.0 + w: 0.999999988143 + covariance: [1.9458403826887298, -2.815408347038933e-08, 0.0, 0.0, -7.99692423660816e-06, 0.0, -2.8154083470389363e-08, 1.9458402335642075, 0.0, 0.0, 8.750129212436589e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.996924236608163e-06, 8.750129212436604e-06, 0.0, 0.0, 1.9212561828607555, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 153 + stamp: + secs: 1624875215 + nsecs: 800864935 + frame_id: "/world" +pose: + pose: + position: + x: -0.00993021979217 + y: -0.0226336156956 + z: 0.0 + orientation: + x: -0.0 + y: -0.00248970957058 + z: -0.0 + w: 0.999996900668 + covariance: [1.9846308489516553, -4.465353311579839e-08, 0.0, 0.0, -2.1701735585398107e-06, 0.0, -4.465353311579835e-08, 1.9846306333925328, 0.0, 0.0, 3.8609679116356746e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1701735585398175e-06, 3.860967911635674e-05, 0.0, 0.0, 1.943700401610839, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 154 + stamp: + secs: 1624875215 + nsecs: 960884094 + frame_id: "/world" +pose: + pose: + position: + x: -0.0135344938785 + y: -0.0190627382726 + z: 0.0 + orientation: + x: 0.0 + y: 0.0012422125781 + z: 0.0 + w: 0.999999228454 + covariance: [1.890802308862325, -1.1294541302390839e-07, 0.0, 0.0, -0.0004989383884347277, 0.0, -1.1294541302390858e-07, 1.890800643038723, 0.0, 0.0, 2.1601230958583295e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0004989383884347279, 2.1601230958583264e-05, 0.0, 0.0, 1.8381975901145113, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 155 + stamp: + secs: 1624875216 + nsecs: 120889902 + frame_id: "/world" +pose: + pose: + position: + x: -0.0140338834248 + y: -0.0212345246735 + z: 0.0 + orientation: + x: -0.0 + y: -0.000598612726465 + z: -0.0 + w: 0.999999820831 + covariance: [1.9362057630151812, -1.1952045563597273e-07, 0.0, 0.0, -0.00025669139106513874, 0.0, -1.1952045563597273e-07, 1.9362014342811933, 0.0, 0.0, 5.352238995584263e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.0002566913910651389, 5.352238995584258e-06, 0.0, 0.0, 1.9002942268670815, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 156 + stamp: + secs: 1624875216 + nsecs: 200895071 + frame_id: "/world" +pose: + pose: + position: + x: -0.0141336973117 + y: -0.0229941989455 + z: 0.0 + orientation: + x: 0.0 + y: 0.000297532869607 + z: 0.0 + w: 0.999999955737 + covariance: [2.0379603362087533, -6.270301393790661e-08, 0.0, 0.0, -6.385941059764795e-05, 0.0, -6.270301393790661e-08, 2.0379576380679, 0.0, 0.0, 1.0658927689375592e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.385941059764787e-05, 1.065892768937558e-06, 0.0, 0.0, 2.020535902160479, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 157 + stamp: + secs: 1624875216 + nsecs: 280922890 + frame_id: "/world" +pose: + pose: + position: + x: -0.0181141481185 + y: -0.00714884038211 + z: 0.0 + orientation: + x: 0.0 + y: 0.000760002020438 + z: 0.0 + w: 0.999999711198 + covariance: [2.2336925604878783, -8.576990136636337e-08, 0.0, 0.0, -3.072687749286127e-05, 0.0, -8.57699013663634e-08, 2.233688666536996, 0.0, 0.0, 1.9708381412087154e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.072687749286122e-05, 1.9708381412087113e-05, 0.0, 0.0, 2.211075083457304, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 158 + stamp: + secs: 1624875216 + nsecs: 360913038 + frame_id: "/world" +pose: + pose: + position: + x: -0.00623181004681 + y: 0.00329876527136 + z: 0.0 + orientation: + x: -0.0 + y: -0.0010060813585 + z: -0.0 + w: 0.9999994939 + covariance: [1.7760505305802554, -6.372936151679336e-08, 0.0, 0.0, -8.125297298334594e-06, 0.0, -6.372936151679318e-08, 1.7760477176965102, 0.0, 0.0, 9.08370732928812e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.125297298334615e-06, 9.083707329288124e-06, 0.0, 0.0, 1.7587306568009633, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 159 + stamp: + secs: 1624875216 + nsecs: 600929976 + frame_id: "/world" +pose: + pose: + position: + x: -0.00863278428775 + y: -0.00662414472651 + z: 0.0 + orientation: + x: 0.0 + y: 0.000486766547536 + z: 0.0 + w: 0.999999881529 + covariance: [2.019899522224218, -2.8840132946824433e-07, 0.0, 0.0, -8.07223753890459e-05, 0.0, -2.884013294682437e-07, 2.019887471733767, 0.0, 0.0, 2.728816990831616e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.07223753890459e-05, 2.728816990831616e-05, 0.0, 0.0, 1.9311985011979682, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 160 + stamp: + secs: 1624875216 + nsecs: 760956049 + frame_id: "/world" +pose: + pose: + position: + x: -0.00891683724342 + y: -0.00869444442759 + z: 0.0 + orientation: + x: -0.0 + y: -0.00082515791413 + z: -0.0 + w: 0.999999659557 + covariance: [1.7444861875084943, -1.06789932933038e-07, 0.0, 0.0, -2.491525158341813e-05, 0.0, -1.0678993293303793e-07, 1.7444820708334643, 0.0, 0.0, 8.136925590560365e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.491525158341814e-05, 8.13692559056037e-06, 0.0, 0.0, 1.7117681942122305, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 161 + stamp: + secs: 1624875216 + nsecs: 840961933 + frame_id: "/world" +pose: + pose: + position: + x: -0.00904886237411 + y: -0.00992791982665 + z: 0.0 + orientation: + x: 0.0 + y: 2.66785031672e-06 + z: 0.0 + w: 0.999999999996 + covariance: [1.870180454005927, -4.7974480573056856e-08, 0.0, 0.0, -6.9923948651325484e-06, 0.0, -4.7974480573056703e-08, 1.8701786929083137, 0.0, 0.0, 2.441366611356094e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.992394865132542e-06, 2.441366611356092e-06, 0.0, 0.0, 1.8554399725853994, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 162 + stamp: + secs: 1624875216 + nsecs: 920965910 + frame_id: "/world" +pose: + pose: + position: + x: -0.0139583728875 + y: -0.00744317769063 + z: 0.0 + orientation: + x: -0.0 + y: -0.00095108253289 + z: -0.0 + w: 0.999999547721 + covariance: [1.9207163223599037, -5.8365637507756615e-08, 0.0, 0.0, -2.906136228531491e-06, 0.0, -5.8365637507756674e-08, 1.9207142440805265, 0.0, 0.0, 1.4624076512237565e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.90613622853148e-06, 1.4624076512237523e-06, 0.0, 0.0, 1.9025410782912338, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 163 + stamp: + secs: 1624875217 + nsecs: 80965996 + frame_id: "/world" +pose: + pose: + position: + x: -0.0144283166657 + y: -0.00938026722802 + z: 0.0 + orientation: + x: -0.0 + y: -0.000816974520533 + z: -0.0 + w: 0.999999666276 + covariance: [1.7612928010550937, -6.157133780834283e-08, 0.0, 0.0, -5.597707793377422e-06, 0.0, -6.157133780834285e-08, 1.7612906274225448, 0.0, 0.0, 5.191994051419185e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.59770779337741e-06, 5.191994051419173e-07, 0.0, 0.0, 1.7403514683951793, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 164 + stamp: + secs: 1624875217 + nsecs: 160985947 + frame_id: "/world" +pose: + pose: + position: + x: -0.011198531709 + y: -0.00805949230635 + z: 0.0 + orientation: + x: -0.0 + y: -0.000156333920919 + z: -0.0 + w: 0.99999998778 + covariance: [1.7706940674247764, -3.0283291064472704e-08, 0.0, 0.0, -1.9896639129704306e-06, 0.0, -3.02832910644727e-08, 1.77069300027923, 0.0, 0.0, 1.0529763509315963e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.989663912970425e-06, 1.0529763509315972e-07, 0.0, 0.0, 1.7596711200372572, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 165 + stamp: + secs: 1624875217 + nsecs: 240998983 + frame_id: "/world" +pose: + pose: + position: + x: -0.00750152131664 + y: -0.0036410270864 + z: 0.0 + orientation: + x: -0.0 + y: -0.000508811198224 + z: -0.0 + w: 0.999999870556 + covariance: [1.7761945565724073, -3.8265220311603956e-08, 0.0, 0.0, -6.357517432109237e-07, 0.0, -3.826522031160385e-08, 1.7761932092179338, 0.0, 0.0, 1.3208691765571122e-08, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.357517432109236e-07, 1.3208691765571104e-08, 0.0, 0.0, 1.7609733874802644, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 166 + stamp: + secs: 1624875217 + nsecs: 400985956 + frame_id: "/world" +pose: + pose: + position: + x: -0.00696761023803 + y: -0.0051198525222 + z: 0.0 + orientation: + x: -0.0 + y: -0.000742803581219 + z: -0.0 + w: 0.999999724121 + covariance: [1.8180570188735319, -5.818035153391153e-08, 0.0, 0.0, -4.878021979650565e-06, 0.0, -5.818035153391143e-08, 1.818054970498542, 0.0, 0.0, -2.3357274196385267e-08, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.878021979650561e-06, -2.3357274196385343e-08, 0.0, 0.0, 1.793211409937832, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 167 + stamp: + secs: 1624875217 + nsecs: 481002092 + frame_id: "/world" +pose: + pose: + position: + x: -0.00865423581956 + y: -0.00498649163186 + z: 0.0 + orientation: + x: -0.0 + y: -0.000402445730884 + z: -0.0 + w: 0.999999919019 + covariance: [2.001475569036382, -6.291976679635332e-08, 0.0, 0.0, -6.5518724848095285e-06, 0.0, -6.291976679635327e-08, 2.0014733533329814, 0.0, 0.0, 1.852736422359716e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.551872484809532e-06, 1.852736422359717e-07, 0.0, 0.0, 1.9716807102202987, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 168 + stamp: + secs: 1624875217 + nsecs: 641020060 + frame_id: "/world" +pose: + pose: + position: + x: -0.015520449065 + y: -0.000718194972907 + z: 0.0 + orientation: + x: -0.0 + y: -0.00135389919787 + z: -0.0 + w: 0.999999083478 + covariance: [2.420131841911906, -1.1196391133912191e-07, 0.0, 0.0, -5.7507321086209995e-06, 0.0, -1.1196391133912205e-07, 2.4201278992254576, 0.0, 0.0, 1.585479957450454e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.750732108621005e-06, 1.5854799574504537e-07, 0.0, 0.0, 2.3649747689187275, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 169 + stamp: + secs: 1624875217 + nsecs: 721040964 + frame_id: "/world" +pose: + pose: + position: + x: -0.0176545031441 + y: -0.00297295608791 + z: 0.0 + orientation: + x: 0.0 + y: 0.000170364589184 + z: 0.0 + w: 0.999999985488 + covariance: [1.7542934679971265, -3.1912306461547856e-08, 0.0, 0.0, -7.797428102711512e-07, 0.0, -3.191230646154794e-08, 1.754292348974104, 0.0, 0.0, 1.807645337043654e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.797428102711521e-07, 1.8076453370436575e-05, 0.0, 0.0, 1.7367822910071253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 170 + stamp: + secs: 1624875217 + nsecs: 801040888 + frame_id: "/world" +pose: + pose: + position: + x: -0.00410236126918 + y: 0.0140200276578 + z: 0.0 + orientation: + x: -0.0 + y: -0.00140206773077 + z: -0.0 + w: 0.999999017103 + covariance: [2.03459013078347, -4.696413724706143e-08, 0.0, 0.0, -2.2603874112814893e-07, 0.0, -4.696413724706141e-08, 2.0345885118129643, 0.0, 0.0, 1.9392348747922244e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.2603874112814885e-07, 1.9392348747922278e-05, 0.0, 0.0, 2.0067121233885685, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 171 + stamp: + secs: 1624875217 + nsecs: 961061954 + frame_id: "/world" +pose: + pose: + position: + x: -0.0090901628641 + y: -0.00333069958549 + z: 0.0 + orientation: + x: 0.0 + y: 0.000245697553199 + z: 0.0 + w: 0.999999969816 + covariance: [1.821482382362624, -6.494295307547523e-08, 0.0, 0.0, -1.6290825636853137e-08, 0.0, -6.494295307547538e-08, 1.8214801578734259, 0.0, 0.0, 6.7273992866800306e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.6290825636853147e-08, 6.7273992866800196e-06, 0.0, 0.0, 1.7777276549094412, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 172 + stamp: + secs: 1624875218 + nsecs: 121073961 + frame_id: "/world" +pose: + pose: + position: + x: -0.00220648142904 + y: 0.00699029183312 + z: 0.0 + orientation: + x: -0.0 + y: -0.00105551461204 + z: -0.0 + w: 0.999999442944 + covariance: [1.9892900722934472, -7.425040758016299e-08, 0.0, 0.0, -4.70103166156141e-06, 0.0, -7.425040758016304e-08, 1.9892875342845573, 0.0, 0.0, 2.1239272694446582e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.70103166156141e-06, 2.1239272694446582e-06, 0.0, 0.0, 1.9324829385278268, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 173 + stamp: + secs: 1624875218 + nsecs: 281084061 + frame_id: "/world" +pose: + pose: + position: + x: -0.0125016009645 + y: 0.00893361224124 + z: 0.0 + orientation: + x: -0.0 + y: -0.000176548453512 + z: -0.0 + w: 0.999999984415 + covariance: [1.842340861928419, -4.506086555483202e-08, 0.0, 0.0, -7.296077421818681e-06, 0.0, -4.506086555483205e-08, 1.8423393306847407, 0.0, 0.0, 5.200340890237755e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.296077421818674e-06, 5.200340890237751e-06, 0.0, 0.0, 1.8046114116260852, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 174 + stamp: + secs: 1624875218 + nsecs: 361097097 + frame_id: "/world" +pose: + pose: + position: + x: -0.00661349187337 + y: 0.0147183409108 + z: 0.0 + orientation: + x: -0.0 + y: -0.000892858321568 + z: -0.0 + w: 0.999999601402 + covariance: [2.17015377709267, -3.308452160788557e-08, 0.0, 0.0, -7.310813064323434e-05, 0.0, -3.308452160788556e-08, 2.1701526772356687, 0.0, 0.0, 2.902312144247622e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.310813064323437e-05, 2.9023121442476196e-06, 0.0, 0.0, 2.141558073570872, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 175 + stamp: + secs: 1624875218 + nsecs: 521126986 + frame_id: "/world" +pose: + pose: + position: + x: -0.00960792878894 + y: 0.00234989396802 + z: 0.0 + orientation: + x: -0.0 + y: -0.000227857449092 + z: -0.0 + w: 0.99999997404 + covariance: [1.9220771648511952, -3.91128655194514e-08, 0.0, 0.0, -5.301272603977029e-05, 0.0, -3.9112865519451386e-08, 1.9220757964788517, 0.0, 0.0, 1.0523728661211618e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.3012726039770276e-05, 1.0523728661211612e-06, 0.0, 0.0, 1.8872942206137542, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 176 + stamp: + secs: 1624875218 + nsecs: 601133108 + frame_id: "/world" +pose: + pose: + position: + x: -0.0114511372161 + y: 0.00473942656332 + z: 0.0 + orientation: + x: -0.0 + y: -0.000641578273327 + z: -0.0 + w: 0.999999794189 + covariance: [1.7539186696197737, -1.6260886819244515e-08, 0.0, 0.0, -9.444924618903406e-06, 0.0, -1.6260886819244505e-08, 1.7539180900066778, 0.0, 0.0, 2.5238383546960664e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.444924618903409e-06, 2.5238383546960595e-07, 0.0, 0.0, 1.7391612637708633, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 177 + stamp: + secs: 1624875218 + nsecs: 681112051 + frame_id: "/world" +pose: + pose: + position: + x: -0.00321234374268 + y: 0.00108809835907 + z: 0.0 + orientation: + x: -0.0 + y: -0.00120390429085 + z: -0.0 + w: 0.999999275307 + covariance: [1.8443245292567965, -2.0331084695336856e-08, 0.0, 0.0, -6.677308321683935e-06, 0.0, -2.0331084695336846e-08, 1.8443237983751994, 0.0, 0.0, 9.311744835961264e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.677308321683938e-06, 9.311744835961258e-07, 0.0, 0.0, 1.8252993298718596, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 178 + stamp: + secs: 1624875218 + nsecs: 841130018 + frame_id: "/world" +pose: + pose: + position: + x: -0.00360279417834 + y: -0.00101304208978 + z: 0.0 + orientation: + x: -0.0 + y: -0.000507844430792 + z: -0.0 + w: 0.999999871047 + covariance: [1.8072511137023821, -3.665424510130845e-08, 0.0, 0.0, -1.772689308839707e-05, 0.0, -3.665424510130855e-08, 1.807249798118531, 0.0, 0.0, 6.116834228113157e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.772689308839706e-05, 6.116834228113135e-07, 0.0, 0.0, 1.7650653305577524, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 179 + stamp: + secs: 1624875219 + nsecs: 1161098 + frame_id: "/world" +pose: + pose: + position: + x: -0.0247193267308 + y: 0.0241437234491 + z: 0.0 + orientation: + x: -0.0 + y: -0.000236151985194 + z: -0.0 + w: 0.999999972116 + covariance: [1.7591145070165783, -2.2796333745991692e-08, 0.0, 0.0, -6.62053613269735e-06, 0.0, -2.2796333745991675e-08, 1.7591136879805906, 0.0, 0.0, 3.4022954142557725e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.620536132697361e-06, 3.4022954142557836e-07, 0.0, 0.0, 1.73076432535645, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 180 + stamp: + secs: 1624875219 + nsecs: 81146002 + frame_id: "/world" +pose: + pose: + position: + x: -0.0249665430873 + y: 0.023178707076 + z: 0.0 + orientation: + x: -0.0 + y: -0.000180825473005 + z: -0.0 + w: 0.999999983651 + covariance: [1.7753536209401872, -1.2487073998883996e-08, 0.0, 0.0, -2.1177216676354725e-06, 0.0, -1.2487073998884011e-08, 1.775353174118469, 0.0, 0.0, 3.6508249105706666e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.117721667635472e-06, 3.6508249105706645e-06, 0.0, 0.0, 1.7588415053923856, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 181 + stamp: + secs: 1624875219 + nsecs: 161160946 + frame_id: "/world" +pose: + pose: + position: + x: 0.00627649167009 + y: 0.025831140694 + z: 0.0 + orientation: + x: -0.0 + y: -0.00423538501684 + z: -0.0 + w: 0.999991030717 + covariance: [1.915675738767697, -1.5136360053834664e-08, 0.0, 0.0, -9.57031186644239e-07, 0.0, -1.5136360053834677e-08, 1.915675203087062, 0.0, 0.0, -1.1181527613166993e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.570311866442411e-07, -1.1181527613166978e-06, 0.0, 0.0, 1.8941023635676388, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 182 + stamp: + secs: 1624875219 + nsecs: 401169062 + frame_id: "/world" +pose: + pose: + position: + x: -0.00241391806304 + y: 0.0232959518887 + z: 0.0 + orientation: + x: 0.0 + y: 0.0026198656672 + z: 0.0 + w: 0.999996568146 + covariance: [1.8979764580468057, -7.718719610028475e-08, 0.0, 0.0, -0.00017698301314779578, 0.0, -7.7187196100285e-08, 1.8979749369940044, 0.0, 0.0, 3.703840151375312e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -0.00017698301314779557, 3.703840151375313e-05, 0.0, 0.0, 1.834942985143629, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 183 + stamp: + secs: 1624875219 + nsecs: 481182098 + frame_id: "/world" +pose: + pose: + position: + x: 0.000488929172891 + y: 0.0202035533422 + z: 0.0 + orientation: + x: -0.0 + y: -0.0010575132483 + z: -0.0 + w: 0.999999440833 + covariance: [1.967268717640398, -8.124880105687398e-08, 0.0, 0.0, -6.410270234248261e-05, 0.0, -8.12488010568742e-08, 1.9672678328868163, 0.0, 0.0, 1.4811381274155901e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.410270234248262e-05, 1.4811381274155864e-05, 0.0, 0.0, 1.9368120245280191, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 184 + stamp: + secs: 1624875219 + nsecs: 641206980 + frame_id: "/world" +pose: + pose: + position: + x: 0.000150580897616 + y: 0.0191635069808 + z: 0.0 + orientation: + x: 0.0 + y: 0.000352402986802 + z: 0.0 + w: 0.999999937906 + covariance: [1.8330957624158029, -1.0011890317262454e-07, 0.0, 0.0, -1.781860068437479e-05, 0.0, -1.0011890317262446e-07, 1.8330948796389053, 0.0, 0.0, 4.840250627668411e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7818600684374797e-05, 4.840250627668415e-06, 0.0, 0.0, 1.8045402179955512, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 185 + stamp: + secs: 1624875219 + nsecs: 721213102 + frame_id: "/world" +pose: + pose: + position: + x: -0.0101143909028 + y: 0.013152693522 + z: 0.0 + orientation: + x: -0.0 + y: -0.000704737528125 + z: -0.0 + w: 0.999999751672 + covariance: [1.8780078749318798, -5.6125090318239745e-08, 0.0, 0.0, -1.2061174266450217e-05, 0.0, -5.612509031823968e-08, 1.8780074002053222, 0.0, 0.0, 1.0688581815074524e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2061174266450207e-05, 1.0688581815074518e-06, 0.0, 0.0, 1.862727273943907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 186 + stamp: + secs: 1624875219 + nsecs: 801218987 + frame_id: "/world" +pose: + pose: + position: + x: -0.00790245581082 + y: 0.0162568178309 + z: 0.0 + orientation: + x: -0.0 + y: -0.000330782149686 + z: -0.0 + w: 0.999999945292 + covariance: [1.6665279450948722, -5.3242424275311136e-08, 0.0, 0.0, -6.1380357561798565e-06, 0.0, -5.324242427531104e-08, 1.6665275007005185, 0.0, 0.0, 2.712203691428772e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.1380357561798616e-06, 2.712203691428774e-07, 0.0, 0.0, 1.65103863619447, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 187 + stamp: + secs: 1624875219 + nsecs: 961224079 + frame_id: "/world" +pose: + pose: + position: + x: -0.00836176023115 + y: 0.0147978469525 + z: 0.0 + orientation: + x: -0.0 + y: -0.00039331077613 + z: -0.0 + w: 0.999999922653 + covariance: [2.1617291370105503, -1.1313644736176536e-07, 0.0, 0.0, -4.610758893442236e-05, 0.0, -1.1313644736176536e-07, 2.161728189583937, 0.0, 0.0, 2.580959591891213e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.6107588934422433e-05, 2.580959591891216e-06, 0.0, 0.0, 2.126295270250253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 188 + stamp: + secs: 1624875220 + nsecs: 41249990 + frame_id: "/world" +pose: + pose: + position: + x: -0.00872158834957 + y: 0.0142043909338 + z: 0.0 + orientation: + x: 0.0 + y: 5.43625831497e-05 + z: 0.0 + w: 0.999999998522 + covariance: [1.940988648567923, -5.805310080438981e-08, 0.0, 0.0, -1.7179605348563708e-05, 0.0, -5.805310080438991e-08, 1.9409881553507258, 0.0, 0.0, 1.2320975491890255e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.7179605348563732e-05, 1.2320975491890272e-06, 0.0, 0.0, 1.9218628610396518, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 189 + stamp: + secs: 1624875220 + nsecs: 121259928 + frame_id: "/world" +pose: + pose: + position: + x: -0.0106671808718 + y: -0.0073106335756 + z: 0.0 + orientation: + x: -0.0 + y: -0.000130724310983 + z: -0.0 + w: 0.999999991456 + covariance: [1.7254283464709286, -4.1238502545744535e-08, 0.0, 0.0, -4.386917218653393e-06, 0.0, -4.1238502545744476e-08, 1.7254279932020467, 0.0, 0.0, 3.117885886104504e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.386917218653389e-06, 3.117885886104505e-07, 0.0, 0.0, 1.7109786957927335, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 190 + stamp: + secs: 1624875220 + nsecs: 281263113 + frame_id: "/world" +pose: + pose: + position: + x: -0.0111911309172 + y: -0.00903861026461 + z: 0.0 + orientation: + x: 0.0 + y: 0.000429046989817 + z: 0.0 + w: 0.999999907959 + covariance: [1.8257192119880727, -9.389381799297072e-08, 0.0, 0.0, -1.941417420174091e-06, 0.0, -9.389381799297076e-08, 1.825718405070981, 0.0, 0.0, 1.7814727168622604e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9414174201740914e-06, 1.7814727168622604e-07, 0.0, 0.0, 1.7889140335846472, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 191 + stamp: + secs: 1624875220 + nsecs: 441265106 + frame_id: "/world" +pose: + pose: + position: + x: -0.00930873845963 + y: -0.00218760148319 + z: 0.0 + orientation: + x: -0.0 + y: -0.000235260216926 + z: -0.0 + w: 0.999999972326 + covariance: [1.8929002561189059, -7.499047261805555e-08, 0.0, 0.0, -6.556241205160164e-06, 0.0, -7.499047261805557e-08, 1.8928996151479351, 0.0, 0.0, 1.0204168431368456e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.5562412051601454e-06, 1.0204168431368429e-05, 0.0, 0.0, 1.8611737937040271, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 192 + stamp: + secs: 1624875220 + nsecs: 521287918 + frame_id: "/world" +pose: + pose: + position: + x: -0.0134994622676 + y: -0.00434107942587 + z: 0.0 + orientation: + x: -0.0 + y: -6.21331316797e-05 + z: -0.0 + w: 0.99999999807 + covariance: [1.996011363979168, -4.2792338804747156e-08, 0.0, 0.0, -1.0961135507353738e-05, 0.0, -4.27923388047471e-08, 1.9960110068997, 0.0, 0.0, 4.923457624710882e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.096113550735375e-05, 4.923457624710877e-06, 0.0, 0.0, 1.977287367486983, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 193 + stamp: + secs: 1624875220 + nsecs: 601290941 + frame_id: "/world" +pose: + pose: + position: + x: -0.0138647064633 + y: -0.00506375187263 + z: 0.0 + orientation: + x: -0.0 + y: -4.59505859656e-06 + z: -0.0 + w: 0.999999999989 + covariance: [1.7023079580221285, -3.636340947934349e-08, 0.0, 0.0, -7.892323264565757e-06, 0.0, -3.636340947934346e-08, 1.7023076601375446, 0.0, 0.0, 1.3813970642136962e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.89232326456576e-06, 1.381397064213698e-06, 0.0, 0.0, 1.6854248089103239, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 194 + stamp: + secs: 1624875220 + nsecs: 761307001 + frame_id: "/world" +pose: + pose: + position: + x: -0.0169791044043 + y: -0.00596658554036 + z: 0.0 + orientation: + x: -0.0 + y: -6.60669137371e-05 + z: -0.0 + w: 0.999999997818 + covariance: [1.8464777452866636, -5.3437419888738654e-08, 0.0, 0.0, -4.3851281302913945e-06, 0.0, -5.3437419888738674e-08, 1.8464773095966396, 0.0, 0.0, 5.293491722186717e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.38512813029139e-06, 5.293491722186716e-07, 0.0, 0.0, 1.8196021614866136, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 195 + stamp: + secs: 1624875220 + nsecs: 841311932 + frame_id: "/world" +pose: + pose: + position: + x: -0.0152549844083 + y: -0.00507478461002 + z: 0.0 + orientation: + x: 0.0 + y: 0.000462758100158 + z: 0.0 + w: 0.999999892927 + covariance: [1.754665400136773, -3.968194428115132e-08, 0.0, 0.0, -2.3631176001098618e-05, 0.0, -3.968194428115139e-08, 1.754665088662969, 0.0, 0.0, 1.1152744605477394e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.3631176001098604e-05, 1.1152744605477372e-05, 0.0, 0.0, 1.7346522193876082, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 196 + stamp: + secs: 1624875221 + nsecs: 1331091 + frame_id: "/world" +pose: + pose: + position: + x: -0.0163864327726 + y: -0.00580270666773 + z: 0.0 + orientation: + x: 0.0 + y: 0.000368950052603 + z: 0.0 + w: 0.999999931938 + covariance: [1.8156315507935108, -5.420700712112123e-08, 0.0, 0.0, -1.5932321895309828e-05, 0.0, -5.420700712112121e-08, 1.8156311847692008, 0.0, 0.0, 7.631162140586666e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5932321895309828e-05, 7.631162140586658e-06, 0.0, 0.0, 1.790536648146295, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 197 + stamp: + secs: 1624875221 + nsecs: 81346989 + frame_id: "/world" +pose: + pose: + position: + x: -0.016614315665 + y: -0.00660014124438 + z: 0.0 + orientation: + x: 0.0 + y: 6.53206699113e-05 + z: 0.0 + w: 0.999999997867 + covariance: [1.98894600277261, -3.792099522913069e-08, 0.0, 0.0, -4.632526033931528e-06, 0.0, -3.792099522913071e-08, 1.9889457571871914, 0.0, 0.0, 1.9998074194998513e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.632526033931527e-06, 1.9998074194998467e-06, 0.0, 0.0, 1.971503208817878, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 198 + stamp: + secs: 1624875221 + nsecs: 161340952 + frame_id: "/world" +pose: + pose: + position: + x: -0.0169929262025 + y: -0.00758666330406 + z: 0.0 + orientation: + x: 0.0 + y: 0.000452424461374 + z: 0.0 + w: 0.999999897656 + covariance: [1.8237681173721898, -3.4880148618443987e-08, 0.0, 0.0, -1.2075300067625661e-05, 0.0, -3.4880148618444e-08, 1.823767895913601, 0.0, 0.0, 2.9719904122339188e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2075300067625653e-05, 2.971990412233914e-06, 0.0, 0.0, 1.8070095537634245, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 199 + stamp: + secs: 1624875221 + nsecs: 241344929 + frame_id: "/world" +pose: + pose: + position: + x: -0.0174719986672 + y: -0.00857649530523 + z: 0.0 + orientation: + x: 0.0 + y: 2.0126500014e-05 + z: 0.0 + w: 0.999999999797 + covariance: [1.922304026583644, -4.799602574853959e-08, 0.0, 0.0, -8.686688253487691e-06, 0.0, -4.79960257485396e-08, 1.9223037260336646, 0.0, 0.0, 2.7539170269504376e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -8.686688253487686e-06, 2.753917026950443e-06, 0.0, 0.0, 1.897858601183947, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 200 + stamp: + secs: 1624875221 + nsecs: 401350975 + frame_id: "/world" +pose: + pose: + position: + x: -0.0153108627627 + y: -0.00795743731862 + z: 0.0 + orientation: + x: -0.0 + y: -4.34551842683e-06 + z: -0.0 + w: 0.999999999991 + covariance: [1.8343686905516035, -5.863026761107662e-08, 0.0, 0.0, -7.204421859490565e-06, 0.0, -5.863026761107648e-08, 1.8343683252694316, 0.0, 0.0, 1.298408785070291e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.204421859490562e-06, 1.2984087850702912e-06, 0.0, 0.0, 1.8018970234149791, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 201 + stamp: + secs: 1624875221 + nsecs: 481375933 + frame_id: "/world" +pose: + pose: + position: + x: -0.00515460156512 + y: -0.00680932342745 + z: 0.0 + orientation: + x: 0.0 + y: 0.00110638357679 + z: 0.0 + w: 0.999999387958 + covariance: [1.8145095679097962, -3.356562613766591e-08, 0.0, 0.0, -4.592002155510226e-05, 0.0, -3.356562613766591e-08, 1.8145093507507661, 0.0, 0.0, 2.9238167286360603e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.592002155510225e-05, 2.923816728636054e-06, 0.0, 0.0, 1.7955429013986095, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 202 + stamp: + secs: 1624875221 + nsecs: 721393108 + frame_id: "/world" +pose: + pose: + position: + x: -0.00436507957377 + y: 0.00818059900262 + z: 0.0 + orientation: + x: -0.0 + y: -0.00313104988872 + z: -0.0 + w: 0.999995098251 + covariance: [1.949449007460753, -1.4742196765553655e-07, 0.0, 0.0, -7.458582724576659e-05, 0.0, -1.4742196765553653e-07, 1.949447852464053, 0.0, 0.0, 5.836810021374224e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -7.45858272457665e-05, 5.836810021374216e-06, 0.0, 0.0, 1.8656575695842958, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 203 + stamp: + secs: 1624875221 + nsecs: 881417036 + frame_id: "/world" +pose: + pose: + position: + x: -0.0105088435457 + y: 0.010500298877 + z: 0.0 + orientation: + x: 0.0 + y: 8.25726346131e-06 + z: 0.0 + w: 0.999999999966 + covariance: [2.0311497008761306, -8.428522190033619e-08, 0.0, 0.0, -1.987984771970762e-05, 0.0, -8.428522190033629e-08, 2.031149025808958, 0.0, 0.0, 1.6888094878777858e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.9879847719707623e-05, 1.6888094878777854e-06, 0.0, 0.0, 1.9788984248993076, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 204 + stamp: + secs: 1624875222 + nsecs: 41435957 + frame_id: "/world" +pose: + pose: + position: + x: -0.0116713220419 + y: 0.0134815823038 + z: 0.0 + orientation: + x: -0.0 + y: -0.00148512595015 + z: -0.0 + w: 0.9999988972 + covariance: [2.1538917461679805, -6.044865588774103e-08, 0.0, 0.0, -1.2580963906825414e-05, 0.0, -6.044865588774115e-08, 2.153891262797581, 0.0, 0.0, 1.1524313444299223e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2580963906825415e-05, 1.1524313444299233e-05, 0.0, 0.0, 2.1161446688745262, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 205 + stamp: + secs: 1624875222 + nsecs: 121417046 + frame_id: "/world" +pose: + pose: + position: + x: -0.0186365076339 + y: 0.010010012416 + z: 0.0 + orientation: + x: -0.0 + y: -0.000112193034115 + z: -0.0 + w: 0.999999993706 + covariance: [1.7342465915672414, -1.6971172271969652e-08, 0.0, 0.0, -2.6220239734469574e-06, 0.0, -1.697117227196967e-08, 1.734246459155423, 0.0, 0.0, 3.0971258855759275e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.6220239734469637e-06, 3.0971258855759262e-06, 0.0, 0.0, 1.7230253177048247, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 206 + stamp: + secs: 1624875222 + nsecs: 201446056 + frame_id: "/world" +pose: + pose: + position: + x: -0.0165699860315 + y: 0.0114662788232 + z: 0.0 + orientation: + x: -0.0 + y: -0.000464308939087 + z: -0.0 + w: 0.999999892209 + covariance: [1.8672224777122646, -1.511924796926902e-08, 0.0, 0.0, -1.6389942120255714e-06, 0.0, -1.511924796926908e-08, 1.8672223623865782, 0.0, 0.0, 1.0569111033105775e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.6389942120255705e-06, 1.056911103310577e-06, 0.0, 0.0, 1.8563750574955418, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 207 + stamp: + secs: 1624875222 + nsecs: 281445026 + frame_id: "/world" +pose: + pose: + position: + x: -0.0139670054382 + y: -0.00825586066529 + z: 0.0 + orientation: + x: -0.0 + y: -0.000488999001178 + z: -0.0 + w: 0.99999988044 + covariance: [1.9225436843602657, -2.634062034097246e-08, 0.0, 0.0, -2.4176541091827893e-06, 0.0, -2.6340620340972427e-08, 1.9225434852139456, 0.0, 0.0, 4.3295076262250424e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4176541091827893e-06, 4.329507626225045e-07, 0.0, 0.0, 1.9020987186543783, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 208 + stamp: + secs: 1624875222 + nsecs: 441457987 + frame_id: "/world" +pose: + pose: + position: + x: 0.00974671291554 + y: 0.0230666008456 + z: 0.0 + orientation: + x: -0.0 + y: -0.00371003514794 + z: -0.0 + w: 0.999993117796 + covariance: [2.150987509510738, -5.244741805963288e-08, 0.0, 0.0, -1.5237091272488477e-05, 0.0, -5.244741805963278e-08, 2.1509871164763754, 0.0, 0.0, 6.945301002405438e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.5237091272488474e-05, 6.94530100240543e-06, 0.0, 0.0, 2.106977482829993, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 209 + stamp: + secs: 1624875222 + nsecs: 681476116 + frame_id: "/world" +pose: + pose: + position: + x: -0.0265509633026 + y: 0.0385884009918 + z: 0.0 + orientation: + x: 0.0 + y: 0.00037670259011 + z: 0.0 + w: 0.999999929048 + covariance: [1.8136210558334427, -6.305301541286962e-08, 0.0, 0.0, -1.213868519329487e-05, 0.0, -6.305301541286962e-08, 1.8136205958157, 0.0, 0.0, 4.127674870520173e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.2138685193294867e-05, 4.127674870520166e-06, 0.0, 0.0, 1.7528465848919756, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 210 + stamp: + secs: 1624875222 + nsecs: 761483908 + frame_id: "/world" +pose: + pose: + position: + x: 0.00757589766217 + y: 0.0332913709641 + z: 0.0 + orientation: + x: -0.0 + y: -0.00128547261191 + z: -0.0 + w: 0.99999917378 + covariance: [2.3761564510930375, -3.9282660858314565e-08, 0.0, 0.0, -4.685335292613336e-06, 0.0, -3.9282660858314585e-08, 2.376156166857276, 0.0, 0.0, 4.872614235967291e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.685335292613333e-06, 4.872614235967289e-06, 0.0, 0.0, 2.3360818904329155, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 211 + stamp: + secs: 1624875222 + nsecs: 921515942 + frame_id: "/world" +pose: + pose: + position: + x: 0.00747665075005 + y: 0.0327088642318 + z: 0.0 + orientation: + x: -0.0 + y: -4.72317197007e-05 + z: -0.0 + w: 0.999999998885 + covariance: [1.7967348833668766, -2.7788558335206744e-08, 0.0, 0.0, -2.417462112255062e-05, 0.0, -2.778855833520681e-08, 1.7967346842745933, 0.0, 0.0, 3.597873963892489e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.4174621122550642e-05, 3.5978739638924805e-06, 0.0, 0.0, 1.7666730647305602, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 212 + stamp: + secs: 1624875223 + nsecs: 1523018 + frame_id: "/world" +pose: + pose: + position: + x: 0.000453744158822 + y: 0.0248119972448 + z: 0.0 + orientation: + x: -0.0 + y: -0.000651615984115 + z: -0.0 + w: 0.999999787698 + covariance: [1.7721615873599765, -9.709682202380962e-09, 0.0, 0.0, -1.0904918936634507e-05, 0.0, -9.70968220238099e-09, 1.7721615165755162, 0.0, 0.0, 7.866881969222498e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0904918936634504e-05, 7.866881969222484e-07, 0.0, 0.0, 1.7613833402343388, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 213 + stamp: + secs: 1624875223 + nsecs: 81501961 + frame_id: "/world" +pose: + pose: + position: + x: -0.00113691557289 + y: 0.0220271643003 + z: 0.0 + orientation: + x: 0.0 + y: 0.000513293633802 + z: 0.0 + w: 0.999999868265 + covariance: [1.6887865945444143, -1.4560993339927585e-08, 0.0, 0.0, -1.0868115129112175e-05, 0.0, -1.4560993339927608e-08, 1.6887864931903005, 0.0, 0.0, 1.302832193387308e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0868115129112192e-05, 1.3028321933873072e-05, 0.0, 0.0, 1.6727430821347509, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 214 + stamp: + secs: 1624875223 + nsecs: 241575956 + frame_id: "/world" +pose: + pose: + position: + x: -0.0011313536776 + y: 0.022825955926 + z: 0.0 + orientation: + x: 0.0 + y: 0.000244499132092 + z: 0.0 + w: 0.99999997011 + covariance: [1.812963321921567, -2.7370767258969255e-08, 0.0, 0.0, -2.608972380741921e-05, 0.0, -2.73707672589692e-08, 1.812963167727304, 0.0, 0.0, 9.503619317269996e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.6089723807419203e-05, 9.503619317269992e-06, 0.0, 0.0, 1.7861410690563264, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 215 + stamp: + secs: 1624875223 + nsecs: 321557045 + frame_id: "/world" +pose: + pose: + position: + x: -0.00138059031145 + y: 0.022359590705 + z: 0.0 + orientation: + x: -0.0 + y: -0.000382253911441 + z: -0.0 + w: 0.999999926941 + covariance: [1.6634599015799008, -1.8162209208659365e-08, 0.0, 0.0, -1.6242467951275973e-05, 0.0, -1.816220920865939e-08, 1.663459803077689, 0.0, 0.0, 4.087541869577971e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.6242467951275956e-05, 4.087541869577973e-06, 0.0, 0.0, 1.6465664768987758, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 216 + stamp: + secs: 1624875223 + nsecs: 481564999 + frame_id: "/world" +pose: + pose: + position: + x: -0.000611757965217 + y: 0.0201900833438 + z: 0.0 + orientation: + x: -0.0 + y: -0.00100394770678 + z: -0.0 + w: 0.999999496044 + covariance: [1.8115882288710639, -2.9200881163422354e-08, 0.0, 0.0, -1.5320422896194035e-05, 0.0, -2.920088116342238e-08, 1.811588073372357, 0.0, 0.0, 2.4413406474438e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.532042289619402e-05, 2.441340647443794e-06, 0.0, 0.0, 1.7856040010922698, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 217 + stamp: + secs: 1624875223 + nsecs: 561572075 + frame_id: "/world" +pose: + pose: + position: + x: -0.000953172742303 + y: 0.0199452386238 + z: 0.0 + orientation: + x: -0.0 + y: -0.000655506227161 + z: -0.0 + w: 0.999999785156 + covariance: [1.7514653156245148, -1.9970061930216264e-08, 0.0, 0.0, -5.742161172756162e-06, 0.0, -1.9970061930216267e-08, 1.7514652089789067, 0.0, 0.0, 1.0934690155708493e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.742161172756158e-06, 1.0934690155708514e-06, 0.0, 0.0, 1.7331392891022368, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 218 + stamp: + secs: 1624875223 + nsecs: 721590996 + frame_id: "/world" +pose: + pose: + position: + x: 0.00282834168011 + y: 0.00957745710809 + z: 0.0 + orientation: + x: 0.0 + y: 8.47434489077e-05 + z: 0.0 + w: 0.999999996409 + covariance: [1.8532923124992646, -3.014335850062694e-08, 0.0, 0.0, -1.0910866363502732e-05, 0.0, -3.014335850062699e-08, 1.8532921638441768, 0.0, 0.0, 2.4906123114842124e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.0910866363502742e-05, 2.4906123114842077e-05, 0.0, 0.0, 1.8232555878052323, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 219 + stamp: + secs: 1624875223 + nsecs: 801577091 + frame_id: "/world" +pose: + pose: + position: + x: 0.00192829840345 + y: -0.00221379494976 + z: 0.0 + orientation: + x: 0.0 + y: 0.00047571603585 + z: 0.0 + w: 0.999999886847 + covariance: [1.922019627817414, -2.482893666113636e-08, 0.0, 0.0, -5.63470002593294e-06, 0.0, -2.4828936661136313e-08, 1.9220195304661287, 0.0, 0.0, 1.2133412663807352e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.634700025932942e-06, 1.2133412663807358e-05, 0.0, 0.0, 1.8991720879523406, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 220 + stamp: + secs: 1624875223 + nsecs: 961596966 + frame_id: "/world" +pose: + pose: + position: + x: 0.00715419898661 + y: 0.00802851820143 + z: 0.0 + orientation: + x: -0.0 + y: -0.000106420012518 + z: -0.0 + w: 0.999999994337 + covariance: [1.763403015544808, -2.657478219487305e-08, 0.0, 0.0, -6.819861121088835e-06, 0.0, -2.6574782194872974e-08, 1.7634029279658727, 0.0, 0.0, 1.9044411423635882e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.819861121088809e-06, 1.9044411423635895e-05, 0.0, 0.0, 1.7395269723086135, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 221 + stamp: + secs: 1624875224 + nsecs: 41613102 + frame_id: "/world" +pose: + pose: + position: + x: -0.00965684466772 + y: 0.0051812522801 + z: 0.0 + orientation: + x: 0.0 + y: 0.000523985266483 + z: 0.0 + w: 0.99999986272 + covariance: [1.9501399713735685, -2.4838466021580715e-08, 0.0, 0.0, -1.803510953420811e-05, 0.0, -2.4838466021580725e-08, 1.9501399039344196, 0.0, 0.0, 1.0276630966633254e-05, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.8035109534208112e-05, 1.0276630966633245e-05, 0.0, 0.0, 1.9290822114705835, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 222 + stamp: + secs: 1624875224 + nsecs: 201616049 + frame_id: "/world" +pose: + pose: + position: + x: -0.0100933563779 + y: 0.00443334536622 + z: 0.0 + orientation: + x: -0.0 + y: -0.000474759929823 + z: -0.0 + w: 0.999999887301 + covariance: [1.8323483297791563, -3.465430872018018e-08, 0.0, 0.0, -1.8379907795263756e-05, 0.0, -3.465430872018019e-08, 1.8323482410250742, 0.0, 0.0, 9.168516578011825e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.837990779526374e-05, 9.168516578011828e-06, 0.0, 0.0, 1.8040680180079156, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 223 + stamp: + secs: 1624875224 + nsecs: 281644106 + frame_id: "/world" +pose: + pose: + position: + x: -0.00712449017371 + y: -0.00136042664287 + z: 0.0 + orientation: + x: 0.0 + y: 6.04221504641e-06 + z: 0.0 + w: 0.999999999982 + covariance: [1.812971504234954, -2.182059823662339e-08, 0.0, 0.0, -9.62349027952663e-06, 0.0, -2.182059823662338e-08, 1.8129714506894317, 0.0, 0.0, 7.69934019815006e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -9.623490279526627e-06, 7.69934019815006e-06, 0.0, 0.0, 1.795440513373712, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 224 + stamp: + secs: 1624875224 + nsecs: 441647053 + frame_id: "/world" +pose: + pose: + position: + x: -0.00715121372408 + y: -0.00655713985432 + z: 0.0 + orientation: + x: 0.0 + y: 0.000256779091594 + z: 0.0 + w: 0.999999967032 + covariance: [1.669726039542415, -2.783442498062321e-08, 0.0, 0.0, -4.568043839645863e-06, 0.0, -2.7834424980623158e-08, 1.6697259754458755, 0.0, 0.0, 4.006733276253261e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -4.568043839645857e-06, 4.00673327625326e-06, 0.0, 0.0, 1.6472110925798713, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 225 + stamp: + secs: 1624875224 + nsecs: 601653099 + frame_id: "/world" +pose: + pose: + position: + x: -0.00244139280261 + y: 0.0082851913033 + z: 0.0 + orientation: + x: -0.0 + y: -0.000294330998062 + z: -0.0 + w: 0.999999956685 + covariance: [1.6605719193664692, -2.5797544294792705e-08, 0.0, 0.0, -1.1304137126256088e-06, 0.0, -2.5797544294792675e-08, 1.660571861022126, 0.0, 0.0, 2.1536117528796487e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -1.1304137126256115e-06, 2.1536117528796465e-06, 0.0, 0.0, 1.6382216182937268, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 226 + stamp: + secs: 1624875224 + nsecs: 681679964 + frame_id: "/world" +pose: + pose: + position: + x: -0.00177194098159 + y: 0.00754145774385 + z: 0.0 + orientation: + x: -0.0 + y: -0.000211409942188 + z: -0.0 + w: 0.999999977653 + covariance: [1.8068506465452607, -2.486258712143874e-08, 0.0, 0.0, -5.381295440989572e-07, 0.0, -2.4862587121438723e-08, 1.8068505906573447, 0.0, 0.0, 9.863035534601412e-07, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.38129544098958e-07, 9.863035534601433e-07, 0.0, 0.0, 1.7837011561016793, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 227 + stamp: + secs: 1624875224 + nsecs: 841675043 + frame_id: "/world" +pose: + pose: + position: + x: 0.0128689538688 + y: 0.0237631333425 + z: 0.0 + orientation: + x: -0.0 + y: -0.0020266239252 + z: -0.0 + w: 0.999997946396 + covariance: [2.0585713408294177, -4.6637922075132873e-08, 0.0, 0.0, -5.584699428968881e-06, 0.0, -4.6637922075132966e-08, 2.0585712362850557, 0.0, 0.0, 3.015664016049707e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -5.58469942896888e-06, 3.015664016049701e-06, 0.0, 0.0, 2.010406153140263, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 228 + stamp: + secs: 1624875225 + nsecs: 81682920 + frame_id: "/world" +pose: + pose: + position: + x: 0.00989291394214 + y: 0.0223202190851 + z: 0.0 + orientation: + x: -0.0 + y: -0.00016398719774 + z: -0.0 + w: 0.999999986554 + covariance: [1.8919777259409702, -6.686286029120172e-08, 0.0, 0.0, -3.3772544202411305e-06, 0.0, -6.686286029120162e-08, 1.891977576742007, 0.0, 0.0, 5.470024994617234e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -3.377254420241132e-06, 5.470024994617241e-06, 0.0, 0.0, 1.8128432298468902, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 229 + stamp: + secs: 1624875225 + nsecs: 241738081 + frame_id: "/world" +pose: + pose: + position: + x: 0.0074147595362 + y: 0.0269235046738 + z: 0.0 + orientation: + x: -0.0 + y: -0.00012726063262 + z: -0.0 + w: 0.999999991902 + covariance: [1.7426276809575674, -2.8325007788772667e-08, 0.0, 0.0, -6.655033974176582e-07, 0.0, -2.832500778877274e-08, 1.742627617970086, 0.0, 0.0, 1.2689829736664133e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -6.655033974176592e-07, 1.2689829736664106e-06, 0.0, 0.0, 1.704041127676915, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 230 + stamp: + secs: 1624875225 + nsecs: 321708918 + frame_id: "/world" +pose: + pose: + position: + x: -0.0016721715533 + y: 0.019384089063 + z: 0.0 + orientation: + x: 0.0 + y: 0.000746943622505 + z: 0.0 + w: 0.999999721038 + covariance: [1.783335878995612, -1.892268542293102e-08, 0.0, 0.0, -2.19117473837793e-05, 0.0, -1.8922685422931007e-08, 1.78333583683227, 0.0, 0.0, 7.981046086627504e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1911747383779276e-05, 7.981046086627506e-06, 0.0, 0.0, 1.757185218810035, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 231 + stamp: + secs: 1624875225 + nsecs: 481729984 + frame_id: "/world" +pose: + pose: + position: + x: -0.00693751493239 + y: 0.0290699850166 + z: 0.0 + orientation: + x: -0.0 + y: -3.34338565574e-05 + z: -0.0 + w: 0.999999999441 + covariance: [1.9031595989972274, -3.8334893098726945e-08, 0.0, 0.0, -2.181579749486606e-05, 0.0, -3.833489309872697e-08, 1.9031595119379818, 0.0, 0.0, 8.342397597122603e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.181579749486612e-05, 8.342397597122608e-06, 0.0, 0.0, 1.8590198940253084, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- +header: + seq: 232 + stamp: + secs: 1624875225 + nsecs: 641766071 + frame_id: "/world" +pose: + pose: + position: + x: -0.0172194439491 + y: 0.0194378851393 + z: 0.0 + orientation: + x: 0.0 + y: 0.000568660222151 + z: 0.0 + w: 0.999999838313 + covariance: [1.8676158879487474, -3.691464656214016e-08, 0.0, 0.0, -2.1017640081323175e-05, 0.0, -3.691464656214016e-08, 1.867615804114841, 0.0, 0.0, 8.037180861960741e-06, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07, 0.0, 0.0, -2.1017640081323186e-05, 8.037180861960741e-06, 0.0, 0.0, 1.8250910876171649, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-07] +--- diff --git a/GPU_version/vio/package.xml b/GPU_version/vio/package.xml old mode 100644 new mode 100755 index 7f8fbc5..1d8d5a4 --- a/GPU_version/vio/package.xml +++ b/GPU_version/vio/package.xml @@ -1,43 +1,32 @@ - vio_gpu + vio 0.1.0 - Monocular Visual Odometry - ROS Nodes + Monocular Visual Odometry Majid Geravand - Majid Geravand + Gfuse GPLv3 catkin + cmake_modules roscpp - cmake_modules - nav_msgs - std_msgs - visualization_msgs + roslib sensor_msgs image_transport cv_bridge tf - gpu_svo - vikit_common - vikit_ros geometry_msgs - + roscpp - nav_msgs - std_msgs - visualization_msgs - sensor_msgs + roslib image_transport cv_bridge tf - vikit_common - vikit_ros geometry_msgs - gpu_svo \ No newline at end of file diff --git a/GPU_version/vio/param/px30.yaml b/GPU_version/vio/param/px30.yaml index 10fa932..4b69c4f 100644 --- a/GPU_version/vio/param/px30.yaml +++ b/GPU_version/vio/param/px30.yaml @@ -1,8 +1,9 @@ -cam_model: ATAN -cam_width: 640 -cam_height: 480 -cam_fx: 0.463632 -cam_fy: 0.823661 -cam_cx: 0.497465 -cam_cy: 0.498443 -cam_d0: 1.01687 \ No newline at end of file +vio: + cam_model: ATAN + cam_width: 640 + cam_height: 480 + cam_fx: 0.463632 + cam_fy: 0.823661 + cam_cx: 0.497465 + cam_cy: 0.498443 + cam_d0: 1.01687 diff --git a/GPU_version/vio/param/vo_fast.yaml b/GPU_version/vio/param/vo_fast.yaml index 0aa2c15..90df6be 100644 --- a/GPU_version/vio/param/vo_fast.yaml +++ b/GPU_version/vio/param/vo_fast.yaml @@ -5,18 +5,11 @@ svo: quality_min_fts: 10 #If the number of tracked features drops below this threshold. Tracking quality is bad. quality_max_drop_fts: 60 #If within one frame, this amount of features are dropped. Tracking quality is bad. init_min_tracked: 100 - init_min_disparity: 20 + init_min_disparity: 30 structureoptim_max_pts: 50 kfselect_mindist: 0.05 poseoptim_thresh: 4.0 - ACC_noise: 0.0001 #acc white noise in continuous - GYO_noise: 0.0001 #gyro white noise in continuous - IUC: 0.1 #integration uncertainty continuous - ABC: 0.1 #acc bias in continuous - GBC: 0.1 #gyro bias in continuous - EBP: 0.1 #error in the bias used for preintegration - NRP: 0.001 #noise used for projection in preintegration - gravity: -9.65 - Acceleration_offset_x: 0.0 - Acceleration_offset_y: 0.0 - Gyroscope_offset_z: 0.0 + ACC_noise: 0.1 #acc white noise in continuous in EKF + GYO_noise: 0.1 #gyro white noise in continuous in EKF + svo_ekf: 20 #Svo noise that will be devided by number of Reprojected points after opmization in EKF + Cmd_Cov: 0.05 #control vector noise in EKF diff --git a/GPU_version/vio/rqt.perspective b/GPU_version/vio/rqt.perspective deleted file mode 100644 index 66dd7ef..0000000 --- a/GPU_version/vio/rqt.perspective +++ /dev/null @@ -1,293 +0,0 @@ -{ - "keys": {}, - "groups": { - "pluginmanager": { - "keys": { - "running-plugins": { - "type": "repr", - "repr": "{u'rqt_rviz/RViz': [1], u'rqt_reconfigure/Param': [1], u'rqt_image_view/ImageView': [1], u'svo_rqt/Svo': [1]}" - } - }, - "groups": { - "plugin__rqt_rviz__RViz__1": { - "keys": {}, - "groups": { - "dock_widget__": { - "keys": { - "dockable": { - "type": "repr", - "repr": "True" - }, - "parent": { - "type": "repr", - "repr": "None" - } - }, - "groups": {} - } - } - }, - "plugin__rqt_robot_steering__RobotSteering__1": { - "keys": {}, - "groups": { - "dock_widget__RobotSteeringUi": { - "keys": { - "dockable": { - "type": "repr", - "repr": "u'true'" - }, - "parent": { - "type": "repr", - "repr": "None" - } - }, - "groups": {} - }, - "plugin": { - "keys": { - "topic": { - "type": "repr", - "repr": "u'/cmd_vel'" - }, - "vx_min": { - "type": "repr", - "repr": "u'-1'" - }, - "vw_min": { - "type": "repr", - "repr": "u'-3'" - }, - "vw_max": { - "type": "repr", - "repr": "u'3'" - }, - "vx_max": { - "type": "repr", - "repr": "u'1'" - } - }, - "groups": {} - } - } - }, - "plugin__rqt_reconfigure__Param__1": { - "keys": {}, - "groups": { - "dock_widget___plugincontainer_top_widget": { - "keys": { - "dockable": { - "type": "repr", - "repr": "True" - }, - "parent": { - "type": "repr", - "repr": "None" - } - }, - "groups": {} - }, - "plugin": { - "keys": { - "splitter": { - "type": "repr(QByteArray.hex)", - "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff0000000000000002000000c00000006401000000060100000001')", - "pretty-print": " d " - }, - "_splitter": { - "type": "repr(QByteArray.hex)", - "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff00000000000000020000013e0000006401000000090100000002')", - "pretty-print": " > d " - } - }, - "groups": {} - } - } - }, - "plugin__rqt_image_view__ImageView__1": { - "keys": {}, - "groups": { - "dock_widget__ImageViewWidget": { - "keys": { - "dockable": { - "type": "repr", - "repr": "True" - }, - "parent": { - "type": "repr", - "repr": "None" - } - }, - "groups": {} - }, - "plugin": { - "keys": { - "dynamic_range": { - "type": "repr", - "repr": "False" - }, - "max_range": { - "type": "repr", - "repr": "10.0" - }, - "topic": { - "type": "repr", - "repr": "u'/svo/image'" - }, - "zoom1": { - "type": "repr", - "repr": "False" - } - }, - "groups": {} - } - } - }, - "plugin__svo_rqt__Svo__1": { - "keys": {}, - "groups": { - "dock_widget__SvoWidget": { - "keys": { - "dockable": { - "type": "repr", - "repr": "True" - }, - "parent": { - "type": "repr", - "repr": "None" - } - }, - "groups": {} - }, - "dock_widget__SvoUi": { - "keys": { - "dockable": { - "type": "repr", - "repr": "u'true'" - }, - "parent": { - "type": "repr", - "repr": "None" - } - }, - "groups": {} - } - } - }, - "plugin__rqt_shell__Shell__1": { - "keys": {}, - "groups": { - "plugin": { - "keys": { - "shell_type": { - "type": "repr", - "repr": "u'0'" - } - }, - "groups": {} - } - } - }, - "plugin__rqt_console__Console__1": { - "keys": {}, - "groups": { - "plugin": { - "keys": { - "show_highlighted_only": { - "type": "repr", - "repr": "u'false'" - }, - "message_limit": { - "type": "repr", - "repr": "u'20000'" - }, - "exclude_filters": { - "type": "repr", - "repr": "u'severity'" - }, - "table_splitter": { - "type": "repr(QByteArray.hex)", - "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff00000000000000020000004e000000ed01000000090100000002')", - "pretty-print": " N " - }, - "highlight_filters": { - "type": "repr", - "repr": "u'message'" - }, - "paused": { - "type": "repr", - "repr": "u'false'" - }, - "settings_exist": { - "type": "repr", - "repr": "u'true'" - }, - "filter_splitter": { - "type": "repr(QByteArray.hex)", - "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff0000000000000002000000720000007201000000090100000002')", - "pretty-print": " r r " - } - }, - "groups": { - "exclude_filter_0": { - "keys": { - "enabled": { - "type": "repr", - "repr": "u'true'" - }, - "itemlist": { - "type": "repr", - "repr": "u''" - } - }, - "groups": {} - }, - "highlight_filter_0": { - "keys": { - "regex": { - "type": "repr", - "repr": "u'false'" - }, - "text": { - "type": "repr", - "repr": "u''" - }, - "enabled": { - "type": "repr", - "repr": "u'true'" - } - }, - "groups": {} - } - } - } - } - } - } - }, - "mainwindow": { - "keys": { - "geometry": { - "type": "repr(QByteArray.hex)", - "repr(QByteArray.hex)": "QtCore.QByteArray('01d9d0cb00010000000007a9fffffffc00001187000005a7000007b1000000180000117f0000059f000000000000')", - "pretty-print": " " - }, - "state": { - "type": "repr(QByteArray.hex)", - "repr(QByteArray.hex)": "QtCore.QByteArray('000000ff00000000fd0000000100000003000009cf00000559fc0100000005fb0000002c00730076006f005f007200710074005f005f00530076006f005f005f0031005f005f00530076006f005500690100000000000003890000000000000000fb0000006a007200710074005f0072006f0062006f0074005f007300740065006500720069006e0067005f005f0052006f0062006f0074005300740065006500720069006e0067005f005f0031005f005f0052006f0062006f0074005300740065006500720069006e00670055006901000000000000020b0000000000000000fc00000000000003530000022e00fffffffc0200000004fb0000003400730076006f005f007200710074005f005f00530076006f005f005f0031005f005f00530076006f0057006900640067006500740100000019000000a30000009900fffffffb0000004c007200710074005f0063006f006e0073006f006c0065005f005f0043006f006e0073006f006c0065005f005f0031005f005f0043006f006e0073006f006c006500570069006400670065007401000000c3000003b50000000000000000fb0000005a007200710074005f0069006d006100670065005f0076006900650077005f005f0049006d0061006700650056006900650077005f005f0031005f005f0049006d006100670065005600690065007700570069006400670065007401000000c2000002700000005100fffffffb0000006c007200710074005f007200650063006f006e006600690067007500720065005f005f0050006100720061006d005f005f0031005f005f005f0070006c007500670069006e0063006f006e007400610069006e00650072005f0074006f0070005f00770069006400670065007401000003380000023a0000010f00fffffffb00000026007200710074005f007200760069007a005f005f005200560069007a005f005f0031005f005f010000035900000676000000a700fffffffb00000040007200710074005f007300680065006c006c005f005f005300680065006c006c005f005f0031005f005f0058005400650072006d005700690064006700650074010000091c000000b30000000000000000000009cf0000000000000004000000040000000800000008fc00000001000000030000000100000036004d0069006e0069006d0069007a006500640044006f0063006b00570069006400670065007400730054006f006f006c0062006100720000000000ffffffff0000000000000000')", - "pretty-print": " ,svo_rqt__Svo__1__SvoUi jrqt_robot_steering__RobotSteering__1__RobotSteeringUi S . p Q 8 : Y v " - } - }, - "groups": { - "toolbar_areas": { - "keys": { - "MinimizedDockWidgetsToolbar": { - "type": "repr", - "repr": "8" - } - }, - "groups": {} - } - } - } - } -} \ No newline at end of file diff --git a/GPU_version/vio/rviz_config.rviz b/GPU_version/vio/rviz_config.rviz deleted file mode 100644 index 95d7c0e..0000000 --- a/GPU_version/vio/rviz_config.rviz +++ /dev/null @@ -1,153 +0,0 @@ -Panels: - - Class: rviz/Displays - Help Height: 108 - Name: Displays - Property Tree Widget: - Expanded: - - /Global Options1 - - /Status1 - - /TF1 - - /Marker1 - - /Marker2 - - /Marker2/Namespaces1 - - /Image1 - Splitter Ratio: 0.5 - Tree Height: 680 - - Class: rviz/Selection - Name: Selection - - Class: rviz/Tool Properties - Expanded: - - /2D Pose Estimate1 - - /2D Nav Goal1 - - /Publish Point1 - Name: Tool Properties - Splitter Ratio: 0.588679 - - Class: rviz/Views - Expanded: - - /Current View1 - Name: Views - Splitter Ratio: 0.5 - - Class: rviz/Time - Experimental: false - Name: Time - SyncMode: 0 - SyncSource: Image -Visualization Manager: - Class: "" - Displays: - - Alpha: 0.5 - Cell Size: 1 - Class: rviz/Grid - Color: 160; 160; 164 - Enabled: true - Line Style: - Line Width: 0.03 - Value: Lines - Name: Grid - Normal Cell Count: 0 - Offset: - X: 0 - Y: 0 - Z: 0 - Plane: XY - Plane Cell Count: 10 - Reference Frame: - Value: true - - Class: rviz/TF - Enabled: false - Frame Timeout: 15 - Frames: - All Enabled: true - Marker Scale: 1 - Name: TF - Show Arrows: true - Show Axes: true - Show Names: true - Tree: - {} - Update Interval: 0 - Value: false - - Class: rviz/Marker - Enabled: true - Marker Topic: /svo/keyframes - Name: Marker - Namespaces: - cams: true - kfs: true - Queue Size: 100 - Value: true - - Class: rviz/Marker - Enabled: true - Marker Topic: /svo/points - Name: Marker - Namespaces: - pts: true - trajectory: true - Queue Size: 100 - Value: true - - Class: rviz/Image - Enabled: true - Image Topic: /svo/image - Max Value: 1 - Median window: 5 - Min Value: 0 - Name: Image - Normalize Range: true - Queue Size: 2 - Transport Hint: raw - Value: true - Enabled: true - Global Options: - Background Color: 255; 255; 255 - Fixed Frame: /world - Name: root - Tools: - - Class: rviz/Interact - Hide Inactive Objects: true - - Class: rviz/MoveCamera - - Class: rviz/Select - - Class: rviz/FocusCamera - - Class: rviz/Measure - - Class: rviz/SetInitialPose - Topic: /initialpose - - Class: rviz/SetGoal - Topic: /move_base_simple/goal - - Class: rviz/PublishPoint - Single click: true - Topic: /clicked_point - Value: true - Views: - Current: - Class: rviz/Orbit - Distance: 5.48911 - Focal Point: - X: 0.777511 - Y: 0.689927 - Z: -0.445833 - Name: Current View - Near Clip Distance: 0.01 - Pitch: 0.125204 - Target Frame: - Value: Orbit (rviz) - Yaw: 4.45215 - Saved: ~ -Window Geometry: - Displays: - collapsed: false - Height: 1416 - Hide Left Dock: false - Hide Right Dock: true - Image: - collapsed: false - QMainWindow State: 000000ff00000000fd0000000400000000000002cc00000542fc0200000009fb0000001200530065006c0065006300740069006f006e00000000280000009b0000006400fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000002800000355000000dd00fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d0061006700650100000383000001e70000001600ffffff000000010000010f000003dafc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a005600690065007700730000000028000003da000000b000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000003ce0000003efc0100000002fb0000000800540069006d00650000000000000003ce000002f600fffffffb0000000800540069006d00650100000000000004500000000000000000000006fd0000054200000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 - Selection: - collapsed: false - Time: - collapsed: false - Tool Properties: - collapsed: false - Views: - collapsed: true - Width: 2511 - X: 1962 - Y: 24 diff --git a/GPU_version/svo/src/atan_camera.cpp b/GPU_version/vio/src/atan_camera.cpp similarity index 100% rename from GPU_version/svo/src/atan_camera.cpp rename to GPU_version/vio/src/atan_camera.cpp diff --git a/GPU_version/svo/src/cl_class.cpp b/GPU_version/vio/src/cl_class.cpp similarity index 100% rename from GPU_version/svo/src/cl_class.cpp rename to GPU_version/vio/src/cl_class.cpp diff --git a/GPU_version/svo/src/config.cpp b/GPU_version/vio/src/config.cpp similarity index 96% rename from GPU_version/svo/src/config.cpp rename to GPU_version/vio/src/config.cpp index 8801d19..5c3cab7 100644 --- a/GPU_version/svo/src/config.cpp +++ b/GPU_version/vio/src/config.cpp @@ -56,10 +56,11 @@ Config::Config() : gbc(vk::getParam("svo/GBC", 1e-1)), ebp(vk::getParam("svo/EBP", 1e-2)), nrp(vk::getParam("svo/NRP", 1e-5)), - gravity(vk::getParam("svo/gravity", 9.8)), + svo_ekf(vk::getParam("svo/svo_ekf", 30)), acc_x_off(vk::getParam("svo/Acceleration_offset_x", 0.0)), acc_y_off(vk::getParam("svo/Acceleration_offset_y", 0.0)), - gyr_z_off(vk::getParam("svo/Gyroscope_offset_z", 0.0)) + gyr_z_off(vk::getParam("svo/Gyroscope_offset_z", 0.0)), + cmd_cov(vk::getParam("svo/Cmd_Cov", 0.0)) {} Config& Config::getInstance() diff --git a/GPU_version/svo/src/depth_filter.cpp b/GPU_version/vio/src/depth_filter.cpp similarity index 90% rename from GPU_version/svo/src/depth_filter.cpp rename to GPU_version/vio/src/depth_filter.cpp index 4e04b5f..cbf0f33 100644 --- a/GPU_version/svo/src/depth_filter.cpp +++ b/GPU_version/vio/src/depth_filter.cpp @@ -91,8 +91,7 @@ void DepthFilter::addFrame(FramePtr frame) } seeds_updating_halt_ = false; frame_queue_cond_.notify_one(); - } - else{ + }else{ updateSeeds(frame); } @@ -102,19 +101,20 @@ void DepthFilter::addKeyframe(FramePtr frame, double depth_mean, double depth_mi { new_keyframe_min_depth_ = depth_min; new_keyframe_mean_depth_ = depth_mean; - ++seeds_cont_; + if(thread_ != NULL) { new_keyframe_ = frame; new_keyframe_set_ = true; seeds_updating_halt_ = true; frame_queue_cond_.notify_one(); - } - else - if(seeds_cont_>5){ + }else if(seeds_cont_>3){ initializeSeeds(frame); seeds_cont_=0; - } + }else if(seeds_cont_==0){ + initializeSeeds(frame); + } + ++seeds_cont_; } void DepthFilter::initializeSeeds(FramePtr frame) @@ -184,7 +184,7 @@ void DepthFilter::updateSeedsLoop() if(new_keyframe_set_) { new_keyframe_set_ = false; - if(seeds_cont_>5){ + if(seeds_cont_>3){ seeds_updating_halt_ = false; } clearFrameQueue(); @@ -198,7 +198,7 @@ void DepthFilter::updateSeedsLoop() } updateSeeds(frame); - if(frame->isKeyframe() && seeds_cont_>5){ + if((frame->isKeyframe() && seeds_cont_>3) ||(frame->isKeyframe() && seeds_cont_==0)){ initializeSeeds(frame); seeds_cont_=0; } @@ -217,7 +217,6 @@ void DepthFilter::updateSeeds(FramePtr frame) const double focal_length = frame->cam_->errorMultiplier2(); double px_noise = 1.0; double px_error_angle = atan(px_noise/(2.0*focal_length))*2.0; // law of chord (sehnensatz) - while( it!=seeds_.end()) { // set this value true when seeds updating should be interrupted @@ -229,11 +228,19 @@ void DepthFilter::updateSeeds(FramePtr frame) it = seeds_.erase(it); continue; } - + if(it->ftr->frame == NULL){ + it = seeds_.erase(it); + continue; + } // check if point is visible in the current image - SE3 T_ref_cur = *it->ftr->frame->T_f_w_.T * frame->T_f_w_.T->inverse(); + SE2 T(it->ftr->frame->T_f_w_.getSE2() * frame->T_f_w_.inverse()); + Eigen::Matrix R; + R<mu * it->ftr->f) ); - if(xyz_f.z() < 0.0) { + if(xyz_f.z() < 0.0 && xyz_f.y() < 0.08) { ++it; // behind the camera continue; } @@ -242,29 +249,28 @@ void DepthFilter::updateSeeds(FramePtr frame) continue; } - // we are using inverse depth coordinates - float z_inv_min = it->mu + sqrt(it->sigma2); - float z_inv_max = max(it->mu - sqrt(it->sigma2), 0.00000001f); - if(z_inv_min <0){ + float z_min = it->mu + sqrt(it->sigma2); + float z_max = max(it->mu - sqrt(it->sigma2), 0.00000001f); + + if(z_min < 0){ ++it; continue; } + double z; if(!matcher_.findEpipolarMatchDirect( - *it->ftr->frame, *frame, *it->ftr, 1.0/it->mu, 1.0/z_inv_min, 1.0/z_inv_max, z)) + *it->ftr->frame, *frame, *it->ftr, 1.0/it->mu, 1.0/z_min, 1.0/z_max, z)) { it->b++; // increase outlier probability when no match was found ++it; ++n_failed_matches; continue; } - - // compute tau double tau = computeTau(T_ref_cur, it->ftr->f, z, px_error_angle); double tau_inverse = 0.5 * (1.0/max(0.0000001, z-tau) - 1.0/(z+tau)); // update the estimate - updateSeed(1./z, tau_inverse*tau_inverse, &*it); + updateSeed(1.0/z, tau_inverse*tau_inverse, &*it); ++n_updates; if(frame->isKeyframe()) @@ -277,13 +283,13 @@ void DepthFilter::updateSeeds(FramePtr frame) if(sqrt(it->sigma2) < it->z_range/options_.seed_convergence_sigma2_thresh) { assert(it->ftr->point == NULL); // TODO this should not happen anymore - Vector3d xyz_world(it->ftr->frame->T_f_w_.T->inverse() * (it->ftr->f * (1.0/it->mu))); + Vector3d xyz_world(it->ftr->frame->getSE3Inv() * (it->ftr->f/it->mu)); Point* point = new Point(xyz_world, it->ftr); it->ftr->point = point; seed_converged_cb_(point, it->sigma2); // put in candidate list it = seeds_.erase(it); } - else if(isnan(z_inv_min)) + else if(isnan(z_min)) { SVO_WARN_STREAM("z_min is NaN"); it = seeds_.erase(it); diff --git a/GPU_version/svo/src/feature_alignment.cpp b/GPU_version/vio/src/feature_alignment.cpp similarity index 99% rename from GPU_version/svo/src/feature_alignment.cpp rename to GPU_version/vio/src/feature_alignment.cpp index 6232e00..0a3de63 100644 --- a/GPU_version/svo/src/feature_alignment.cpp +++ b/GPU_version/vio/src/feature_alignment.cpp @@ -69,7 +69,7 @@ bool align1D( float v = cur_px_estimate.y(); // termination condition - const float min_update_squared = 0.03*0.03; + const float min_update_squared = 0.5*0.5; const int cur_step = cur_img.step.p[0]; float chi2 = 0; Vector2f update; update.setZero(); @@ -203,7 +203,7 @@ bool align2D( bool sign=true;// + // termination condition - const float min_update_squared = 0.3; + const float min_update_squared = 0.1;//0.001 const int cur_step = cur_img.step.p[0]; // float chi2 = 0; Vector3f update; update.setZero(); diff --git a/GPU_version/svo/src/feature_detection.cpp b/GPU_version/vio/src/feature_detection.cpp similarity index 100% rename from GPU_version/svo/src/feature_detection.cpp rename to GPU_version/vio/src/feature_detection.cpp diff --git a/GPU_version/svo/src/frame.cpp b/GPU_version/vio/src/frame.cpp similarity index 95% rename from GPU_version/svo/src/frame.cpp rename to GPU_version/vio/src/frame.cpp index b425646..30f085f 100644 --- a/GPU_version/svo/src/frame.cpp +++ b/GPU_version/vio/src/frame.cpp @@ -138,9 +138,7 @@ void Frame::removeKeyPoint(Feature* ftr) bool Frame::isVisible(const Vector3d& xyz_w) const { - Vector3d xyz_f = Vector3d(xyz_w.x()*T_f_w_.cos_theta_+xyz_w.z()*T_f_w_.sin_theta_+T_f_w_.X_, - xyz_w.y(), - -xyz_w.x()*T_f_w_.sin_theta_+xyz_w.z()*T_f_w_.cos_theta_+T_f_w_.Z_); + Vector3d xyz_f = Vector3d(this->getSE3Inv()*xyz_w); if(xyz_f.z() < 0.0) return false; // point is behind the camera Vector2d px = f2c(xyz_f); diff --git a/GPU_version/svo/src/frame_handler_base.cpp b/GPU_version/vio/src/frame_handler_base.cpp similarity index 100% rename from GPU_version/svo/src/frame_handler_base.cpp rename to GPU_version/vio/src/frame_handler_base.cpp diff --git a/GPU_version/svo/src/frame_handler_mono.cpp b/GPU_version/vio/src/frame_handler_mono.cpp similarity index 81% rename from GPU_version/svo/src/frame_handler_mono.cpp rename to GPU_version/vio/src/frame_handler_mono.cpp index a96ad9e..74527d1 100644 --- a/GPU_version/svo/src/frame_handler_mono.cpp +++ b/GPU_version/vio/src/frame_handler_mono.cpp @@ -24,17 +24,16 @@ #include #include #include -#ifdef USE_BUNDLE_ADJUSTMENT -#include -#endif namespace svo { -FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam,Sophus::SE3& SE_init) : +FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam,Eigen::Matrix& init) : FrameHandlerBase(), cam_(cam), reprojector_(cam_, map_), - depth_filter_(NULL) + depth_filter_(NULL), + ukfPtr_(init), + time_(ros::Time::now()) { gpu_fast_= new opencl(); gpu_fast_->make_kernel("fast_gray"); @@ -46,8 +45,7 @@ FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam,Sophus::SE3& SE_init) gpu_fast_->write_buf(0,2,1,icorner); gpu_fast_->write_buf(0,3,(1 << 18)); klt_homography_init_=new initialization::KltHomographyInit(gpu_fast_); - initialize(); - imu_integPtr_=std::make_shared(SE_init); + initialize(); } void FrameHandlerMono::initialize() @@ -66,7 +64,7 @@ FrameHandlerMono::~FrameHandlerMono() delete depth_filter_; } -void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) +void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp,const ros::Time& time) { if(!startFrameProcessingCommon(timestamp)) return; @@ -77,7 +75,7 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp) // create new frame new_frame_.reset(new Frame(cam_, img.clone(), timestamp)); - + time_=time; // process frame UpdateResult res = RESULT_FAILURE; if(stage_ == STAGE_DEFAULT_FRAME) @@ -105,6 +103,7 @@ FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() new_frame_->setKeyframe(); map_.addKeyframe(new_frame_); stage_ = STAGE_SECOND_FRAME; + ukfPtr_.UpdateSvo(new_frame_->T_f_w_.getSE2().translation()(0),new_frame_->T_f_w_.getSE2().translation()(1),new_frame_->T_f_w_.pitch(),1000,time_); SVO_INFO_STREAM("Init: Selected first frame."); return RESULT_IS_KEYFRAME; } @@ -113,18 +112,16 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() { new_frame_->T_f_w_ = last_frame_->T_f_w_; initialization::InitResult res = klt_homography_init_->addSecondFrame(new_frame_); + auto result=ukfPtr_.UpdateSvo(new_frame_->T_f_w_.getSE2().translation()(0),new_frame_->T_f_w_.getSE2().translation()(1),new_frame_->T_f_w_.pitch(),1000,time_); + new_frame_->T_f_w_ = SE2_5(result.second); + new_frame_->Cov_ = result.first; if(res == initialization::NO_KEYFRAME) - return RESULT_NO_KEYFRAME; - + return RESULT_NO_KEYFRAME; new_frame_->setKeyframe(); double depth_mean, depth_min; frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min); - if(!imu_integPtr_->init(new_frame_)){ - return RESULT_FAILURE; - } - // add frame to map map_.addKeyframe(new_frame_); stage_ = STAGE_DEFAULT_FRAME; @@ -136,50 +133,36 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() { - bool IMU=false; - SE2_5 tem(0.0,0.0,0.0); - if(imu_integPtr_->preintegrate_predict(tem))if((last_frame_->T_f_w_.T->translation()-tem.T->translation()).norm()>0.5){ - new_frame_->T_f_w_ = tem; - IMU=true; - }else{ - imu_integPtr_->reset(); - new_frame_->T_f_w_ = last_frame_->T_f_w_; - } + + new_frame_->T_f_w_ = last_frame_->T_f_w_; // sparse image align SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), 30, SparseImgAlign::LevenbergMarquardt, false, false); img_align.run(last_frame_, new_frame_); - new_frame_->T_f_w_.set(); + // std::cout<<"img_align:\n"<T_f_w_.getSE2()<<"\n"; // map reprojection & feature alignment reprojector_.reprojectMap(new_frame_, overlap_kfs_); - new_frame_->T_f_w_.set(); - if(IMU)if(!imu_integPtr_->predict(new_frame_,last_frame_,reprojector_.n_matches_)){ - return RESULT_FAILURE; - } size_t sfba_n_edges_final=0; double sfba_thresh, sfba_error_init, sfba_error_final; - new_frame_->T_f_w_.set(); pose_optimizer::optimizeGaussNewton( Config::poseOptimThresh(), Config::poseOptimNumIter(), false, new_frame_, sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final); - - new_frame_->T_f_w_.set(); - - std::cout<<"Reprojection Map: "<<"\t nPoint:"<T_f_w_.T->translation()-new_frame_->T_f_w_.T->translation()).norm()>1.0){ - new_frame_->T_f_w_ = last_frame_->T_f_w_; - return RESULT_NO_KEYFRAME; + if((last_frame_->T_f_w_.getSE2().translation()-new_frame_->T_f_w_.getSE2().translation()).norm()>0.1){ + new_frame_->T_f_w_ = last_frame_->T_f_w_; } + auto result=ukfPtr_.UpdateSvo(new_frame_->T_f_w_.getSE2().translation()(0), + new_frame_->T_f_w_.getSE2().translation()(1),new_frame_->T_f_w_.pitch(),sfba_n_edges_final,time_); + new_frame_->T_f_w_ = SE2_5(result.second); + new_frame_->Cov_ = result.first; + std::cout<<"Reprojection Map nPoint: "<T_f_w_.getSE2().translation()-new_frame_->T_f_w_.getSE2().translation()).norm()<<'\n'; if(sfba_n_edges_final < Config::qualityMinFts() || reprojector_.n_matches_ < Config::qualityMinFts()){ return RESULT_NO_KEYFRAME; } optimizeStructure(new_frame_, Config::structureOptimMaxPts(), Config::structureOptimNumIter()); - - new_frame_->T_f_w_.set(); // select keyframe core_kfs_.insert(new_frame_); setTrackingQuality(sfba_n_edges_final); @@ -189,13 +172,11 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() } double depth_mean, depth_min; - new_frame_->T_f_w_.set(); frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); - if(depth_mean > 50 || depth_mean < 0.0) + if(depth_mean > 50 || depth_min < 0.0) { return RESULT_NO_KEYFRAME; } - if(!needNewKf(depth_mean) || tracking_quality_ == TRACKING_BAD)//edited { depth_filter_->addFrame(new_frame_); @@ -203,7 +184,6 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() } new_frame_->setKeyframe(); - new_frame_->T_f_w_.set(); // new keyframe selected for(auto&& it:new_frame_->fts_){ if(it->point != NULL)it->point->addFrameRef(it); @@ -212,7 +192,6 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() // init new depth-filters depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min); - // if limited number of keyframes, remove the one furthest apart if(Config::maxNKfs() > 2 && map_.size() >= Config::maxNKfs()) { @@ -221,7 +200,6 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() map_.safeDeleteFrame(furthest_frame); } - new_frame_->T_f_w_.set(); // add keyframe to map map_.addKeyframe(new_frame_); std::cout<<"Svo pipline was finished\n"; @@ -298,7 +276,7 @@ bool FrameHandlerMono::needNewKf(double scene_depth_mean) if(scene_depth_mean >10.0)return true; for(auto&& it:overlap_kfs_) { - Vector3d relpos = new_frame_->w2f(it.first->pos()); + Vector3d relpos = new_frame_->w2f(Vector3d(it.first->pos()(0),0.0,it.first->pos()(1))); if(fabs(relpos.norm())/scene_depth_mean < Config::kfSelectMinDist()){ return false; } @@ -315,5 +293,13 @@ void FrameHandlerMono::setCoreKfs(size_t n_closest) boost::bind(&pair::second, _2)); std::for_each(overlap_kfs_.begin(), overlap_kfs_.end(), [&](pair& i){ core_kfs_.insert(i.first); }); } +void FrameHandlerMono::UpdateIMU(double* value,const ros::Time& time){ + if(value== nullptr)return; + ukfPtr_.UpdateIMU(value[0],value[1],value[2],time); +} +void FrameHandlerMono::UpdateCmd(double* value,const ros::Time& time){ + if(value== nullptr)return; + ukfPtr_.UpdateCmd(value[0],value[1],value[2],time); +} } // namespace svo diff --git a/GPU_version/svo/src/homography.cpp b/GPU_version/vio/src/homography.cpp similarity index 100% rename from GPU_version/svo/src/homography.cpp rename to GPU_version/vio/src/homography.cpp diff --git a/GPU_version/svo/src/initialization.cpp b/GPU_version/vio/src/initialization.cpp similarity index 91% rename from GPU_version/svo/src/initialization.cpp rename to GPU_version/vio/src/initialization.cpp index 6d54a36..1ca4ced 100644 --- a/GPU_version/svo/src/initialization.cpp +++ b/GPU_version/vio/src/initialization.cpp @@ -69,15 +69,11 @@ InitResult KltHomographyInit::addSecondFrame(FramePtr frame_cur) depth_vec.push_back((xyz_in_cur_[i]).z()); double scene_depth_median = vk::getMedian(depth_vec); double scale = Config::mapScale()/scene_depth_median; - SE3 tem=T_cur_from_ref_ * (*frame_ref_->T_f_w_.T); - frame_cur->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),asin(2*(tem.unit_quaternion().w()*tem.unit_quaternion().y()- - tem.unit_quaternion().z()*tem.unit_quaternion().x()))); - tem.translation() = -frame_cur->T_f_w_.T->rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); - frame_cur->T_f_w_.X_ = tem.translation().x(); - frame_cur->T_f_w_.Z_ = tem.translation().z(); - + frame_cur->T_f_w_ = SE2_5(T_cur_from_ref_.getSE2() * frame_ref_->T_f_w_.getSE2()); + frame_cur->T_f_w_.T2_.translation() = -frame_cur->T_f_w_.getSE2().rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); + //frame_cur->T_f_w_.T2_.translation() = frame_cur->T_f_w_.getSE2().rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); // For each inlier create 3D point and add feature in both frames - SE3 T_world_cur = frame_cur->T_f_w_.T->inverse(); + SE3 T_world_cur = frame_cur->getSE3Inv(); for(vector::iterator it=inliers_.begin(); it!=inliers_.end(); ++it) { Vector2d px_cur(px_cur_[*it].x, px_cur_[*it].y); @@ -138,7 +134,7 @@ void trackKlt( vector& f_cur, vector& disparities) { - const double klt_win_size = 45.0;//30.0 + const double klt_win_size = 30.0;//30.0 const int klt_max_iter = 30;//30 const double klt_eps = 0.001; vector status; @@ -180,7 +176,7 @@ void computeHomography( double reprojection_threshold, vector& inliers, vector& xyz_in_cur, - SE3& T_cur_from_ref) + SE2_5& T_cur_from_ref) { vector uv_ref(f_ref.size()); vector uv_cur(f_cur.size()); @@ -196,7 +192,7 @@ void computeHomography( Homography.T_c2_from_c1.rotation_matrix(), Homography.T_c2_from_c1.translation(), reprojection_threshold, focal_length, xyz_in_cur, inliers, outliers); - T_cur_from_ref = Homography.T_c2_from_c1; + T_cur_from_ref=SE2_5(Homography.T_c2_from_c1); } diff --git a/GPU_version/svo/src/map.cpp b/GPU_version/vio/src/map.cpp similarity index 92% rename from GPU_version/svo/src/map.cpp rename to GPU_version/vio/src/map.cpp index 6b27b1c..877d617 100644 --- a/GPU_version/svo/src/map.cpp +++ b/GPU_version/vio/src/map.cpp @@ -59,7 +59,7 @@ bool Map::safeDeleteFrame(FramePtr frame) if(found) return true; - SVO_ERROR_STREAM("Tried to delete Keyframe in map which was not there."); + //SVO_ERROR_STREAM("Tried to delete Keyframe in map which was not there."); return false; } @@ -109,16 +109,17 @@ void Map::getCloseKeyframes( { for(auto kf : keyframes_) { + std::cout<<"key points:"<key_pts_.size())<<'\t'; // check if kf has overlaping field of view with frame, use therefore KeyPoints for(auto keypoint : kf->key_pts_) { if(keypoint == nullptr) - continue; + continue; if(frame->isVisible(keypoint->point->pos_)) { close_kfs.push_back( std::make_pair( - kf, (frame->T_f_w_.T->translation()-kf->T_f_w_.T->translation()).norm())); + kf, (frame->T_f_w_.getSE2().translation()-kf->T_f_w_.getSE2().translation()).norm())); break; // this keyframe has an overlapping field of view -> add to close_kfs } } @@ -145,7 +146,7 @@ FramePtr Map::getClosestKeyframe(const FramePtr& frame) const return close_kfs.front().first; } -FramePtr Map::getFurthestKeyframe(const Vector3d& pos) const +FramePtr Map::getFurthestKeyframe(const Vector2d& pos) const { FramePtr furthest_kf; double maxdist = 0.0; @@ -172,15 +173,16 @@ bool Map::getKeyframeById(const int id, FramePtr& frame) const return found; } -void Map::transform(const Matrix3d& R, const Vector3d& t, const double& s) +void Map::transform(const Matrix2d& R, const Vector2d& t, const double& s) { + Eigen::Matrix R3; + R3<pos() + t; - Matrix3d rot = R*(*it)->T_f_w_.T->rotation_matrix().inverse(); - SE3 inv=SE3(rot, pos).inverse(); - (*it)->T_f_w_ = SE2_5(inv.translation().x(),inv.translation().z(),asin(2*(inv.unit_quaternion().w()*inv.unit_quaternion().y()- - inv.unit_quaternion().z()*inv.unit_quaternion().x()))); + SE2_5 tem(SE2(R*(*it)->T_f_w_.inverse().rotation_matrix(),s*R*(*it)->pos() + t)); + (*it)->T_f_w_ = tem.inverse(); for(auto ftr=(*it)->fts_.begin(); ftr!=(*it)->fts_.end(); ++ftr) { if((*ftr)->point == NULL) @@ -188,7 +190,7 @@ void Map::transform(const Matrix3d& R, const Vector3d& t, const double& s) if((*ftr)->point->last_published_ts_ == -1000) continue; (*ftr)->point->last_published_ts_ = -1000; - (*ftr)->point->pos_ = s*R*(*ftr)->point->pos_ + t; + (*ftr)->point->pos_ = s*R3*(*ftr)->point->pos_ + Vector3d(t(0),0.0,t(1)); } } } diff --git a/GPU_version/svo/src/matcher.cpp b/GPU_version/vio/src/matcher.cpp similarity index 95% rename from GPU_version/svo/src/matcher.cpp rename to GPU_version/vio/src/matcher.cpp index b8b9d2d..3e6d47b 100644 --- a/GPU_version/svo/src/matcher.cpp +++ b/GPU_version/vio/src/matcher.cpp @@ -146,8 +146,8 @@ bool Matcher::findMatchDirect( // warp affine warp::getWarpMatrixAffine( *ref_ftr_->frame->cam_, *cur_frame.cam_, ref_ftr_->px, ref_ftr_->f, - (ref_ftr_->frame->pos() - pt.pos_).norm(), - (*cur_frame.T_f_w_.T) * ref_ftr_->frame->T_f_w_.T->inverse(), ref_ftr_->level, A_cur_ref_); + (Vector3d(ref_ftr_->frame->pos()(0),0.0,ref_ftr_->frame->pos()(1)) - pt.pos_).norm(), + cur_frame.se3() * ref_ftr_->frame->getSE3Inv(), ref_ftr_->level, A_cur_ref_); search_level_ = warp::getBestSearchLevel(A_cur_ref_, Config::nPyrLevels()-1); warp::warpAffine(A_cur_ref_, ref_ftr_->frame->img_pyr_[ref_ftr_->level], ref_ftr_->px, ref_ftr_->level, search_level_, halfpatch_size_+1, patch_with_border_); @@ -185,7 +185,12 @@ bool Matcher::findEpipolarMatchDirect( double& depth) { if(isnan(d_min) || isnan(d_max))return false; - SE3 T_cur_ref = (*cur_frame.T_f_w_.T) * ref_frame.T_f_w_.T->inverse(); + SE2 T(cur_frame.T_f_w_.getSE2() * ref_frame.T_f_w_.inverse()); + Eigen::Matrix R; + R< +#include #include -namespace vk { -namespace output_helper { void publishTfTransform(const Sophus::SE3& T, const ros::Time& stamp, @@ -404,7 +402,4 @@ void publishFrameMarker(ros::Publisher pub, pub.publish(marker); } -} // namespace output_helper -} // namespace vk - diff --git a/GPU_version/svo/src/point.cpp b/GPU_version/vio/src/point.cpp similarity index 84% rename from GPU_version/svo/src/point.cpp rename to GPU_version/vio/src/point.cpp index e7f1f21..aee4bd8 100644 --- a/GPU_version/svo/src/point.cpp +++ b/GPU_version/vio/src/point.cpp @@ -89,20 +89,21 @@ void Point::initNormal() assert(!obs_.empty()); const Feature* ftr = obs_.back(); assert(ftr->frame != NULL); - normal_ = ftr->frame->T_f_w_.T->rotation_matrix().transpose()*(-ftr->f); - normal_information_ = DiagonalMatrix(pow(20/(pos_-ftr->frame->pos()).norm(),2), 1.0, 1.0); + normal_ = ftr->frame->se3().rotation_matrix().transpose()*(-ftr->f); + double x=pow(20/(pos_-Vector3d(ftr->frame->pos()(0),0.0,ftr->frame->pos()(1))).norm(),2); + normal_information_ = DiagonalMatrix(x, 1.0, 1.0); normal_set_ = true; } -bool Point::getCloseViewObs(const Vector3d& framepos, Feature*& ftr) const +bool Point::getCloseViewObs(const Vector2d& framepos, Feature*& ftr) const { // TODO: get frame with same point of view AND same pyramid level! - Vector3d obs_dir(framepos - pos_); obs_dir.normalize(); + Vector3d obs_dir(Vector3d(framepos(0),0.0,framepos(1)) - pos_); obs_dir.normalize(); auto min_it=obs_.begin(); double min_cos_angle = 0; for(auto it=obs_.begin(), ite=obs_.end(); it!=ite; ++it) { - Vector3d dir((*it)->frame->pos() - pos_); dir.normalize(); + Vector3d dir(Vector3d((*it)->frame->pos()(0),0.0,(*it)->frame->pos()(1)) - pos_); dir.normalize(); double cos_angle = obs_dir.dot(dir); if(cos_angle > min_cos_angle) { @@ -133,10 +134,8 @@ void Point::optimize(const size_t n_iter) for(auto it=obs_.begin(); it!=obs_.end(); ++it) { Matrix23d J; - const Vector3d p_in_f(pos_.x()*(*it)->frame->T_f_w_.cos_theta_+pos_.z()*(*it)->frame->T_f_w_.sin_theta_+(*it)->frame->T_f_w_.X_, - pos_.y(), - -pos_.x()*(*it)->frame->T_f_w_.sin_theta_+pos_.z()*(*it)->frame->T_f_w_.cos_theta_+(*it)->frame->T_f_w_.Z_); - Point::jacobian_xyz2uv(p_in_f, (*it)->frame->T_f_w_.T->rotation_matrix(), J); + const Vector3d p_in_f((*it)->frame->se3()*pos_); + Point::jacobian_xyz2uv(p_in_f, (*it)->frame->se3().rotation_matrix(), J); const Vector2d e(vk::project2d((*it)->f) - vk::project2d(p_in_f)); new_chi2 += e.squaredNorm(); A.noalias() += J.transpose() * J; diff --git a/GPU_version/svo/src/pose_optimizer.cpp b/GPU_version/vio/src/pose_optimizer.cpp similarity index 74% rename from GPU_version/svo/src/pose_optimizer.cpp rename to GPU_version/vio/src/pose_optimizer.cpp index 5dcbee3..79e4686 100644 --- a/GPU_version/svo/src/pose_optimizer.cpp +++ b/GPU_version/vio/src/pose_optimizer.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace svo { namespace pose_optimizer { @@ -39,9 +40,9 @@ void optimizeGaussNewton( double chi2(0.0); vector chi2_vec_init, chi2_vec_final; vk::robust_cost::TukeyWeightFunction weight_function; - SE2_5 T_old(frame->T_f_w_.X_,frame->T_f_w_.Z_,frame->T_f_w_.tetha_); - Matrix6d A; - Vector6d b; + SE2_5 T_old(frame->T_f_w_); + Matrix3d A; + Vector3d b; // compute the scale of the error for robust estimation std::vector errors; errors.reserve(frame->fts_.size()); @@ -51,9 +52,7 @@ void optimizeGaussNewton( continue; //Reprojection error Vector2d e = vk::project2d((*it)->f) - - vk::project2d(Vector3d((*it)->point->pos_.x()*frame->T_f_w_.cos_theta_+(*it)->point->pos_.z()*frame->T_f_w_.sin_theta_+frame->T_f_w_.X_, - (*it)->point->pos_.y(), - -(*it)->point->pos_.x()*frame->T_f_w_.sin_theta_+(*it)->point->pos_.z()*frame->T_f_w_.cos_theta_+frame->T_f_w_.Z_)); + - vk::project2d(Vector3d(frame->se3()*(*it)->point->pos_)); e *= 1.0 / (1<<(*it)->level); errors.push_back(e.norm()); @@ -61,12 +60,14 @@ void optimizeGaussNewton( if(errors.empty()) return; vk::robust_cost::MADScaleEstimator scale_estimator; - estimated_scale = scale_estimator.compute(errors); + estimated_scale = 0.5*scale_estimator.compute(errors); num_obs = errors.size(); chi2_vec_init.reserve(num_obs); chi2_vec_final.reserve(num_obs); double scale = estimated_scale; + bool direction=true; + size_t n_direction=0; for(size_t iter=0; iterpoint == NULL) continue; - Matrix26d J; - Vector3d xyz_f(Vector3d((*it)->point->pos_.x()*frame->T_f_w_.cos_theta_+(*it)->point->pos_.z()*frame->T_f_w_.sin_theta_+frame->T_f_w_.X_, - (*it)->point->pos_.y(), - -(*it)->point->pos_.x()*frame->T_f_w_.sin_theta_+(*it)->point->pos_.z()*frame->T_f_w_.cos_theta_+frame->T_f_w_.Z_)); + Matrix23d J; + Vector3d xyz_f(Vector3d(frame->se3()*(*it)->point->pos_)); Frame::jacobian_xyz2uv(xyz_f, J); Vector2d e = vk::project2d((*it)->f) - vk::project2d(xyz_f); double sqrt_inv_cov = 1.0 / (1<<(*it)->level); @@ -99,22 +98,33 @@ void optimizeGaussNewton( new_chi2 += e.squaredNorm()*weight; } // solve linear system - const Vector6d dT(A.ldlt().solve(b)); + const Vector3d dT(A.ldlt().solve(b)); // check if error increased - if((iter > 0 && new_chi2 > chi2) || (bool) std::isnan((double)dT[0])) + if((iter > 0 && new_chi2 > chi2 && n_direction>3) || (bool) std::isnan((double)dT[0])) { if(verbose) std::cout << "it " << iter << "\t FAILURE \t new_chi2 = " << new_chi2 << std::endl; frame->T_f_w_ = T_old; // roll-back break; + }else if((iter > 0 && new_chi2 > chi2 && n_direction<3) ){ + ++n_direction; + scale *=0.5; + if(direction){ + direction=false; + }else{ + direction=true; + } } // update the model - SE3 T_new = SE3::exp(dT)*(*frame->T_f_w_.T); T_old = frame->T_f_w_; - frame->T_f_w_ = SE2_5(T_new.translation().x(),T_new.translation().z(),atan(T_new.rotation_matrix()(0,2)/T_new.rotation_matrix()(0,0))); + if(direction){ + frame->T_f_w_=SE2_5(SE2::exp(dT)*(T_old.getSE2())); + }else{ + frame->T_f_w_=SE2_5(SE2::exp(-1.0*dT)*(T_old.getSE2())); + } chi2 = new_chi2; if(verbose) std::cout << "it " << iter @@ -127,8 +137,8 @@ void optimizeGaussNewton( } // Set covariance as inverse information matrix. Optimistic estimator! - const double pixel_variance=1.0; - frame->Cov_ = pixel_variance*(A*std::pow(frame->cam_->errorMultiplier2(),2)).inverse(); + //const double pixel_variance=1.0; + //frame->Cov_ = pixel_variance*(A*std::pow(frame->cam_->errorMultiplier2(),2)).inverse(); // Remove Measurements with too large reprojection error double reproj_thresh_scaled = reproj_thresh / frame->cam_->errorMultiplier2(); @@ -137,9 +147,7 @@ void optimizeGaussNewton( { if((*it)->point == NULL) continue; - Vector2d e = vk::project2d((*it)->f) - vk::project2d(Vector3d((*it)->point->pos_.x()*frame->T_f_w_.cos_theta_+(*it)->point->pos_.z()*frame->T_f_w_.sin_theta_+frame->T_f_w_.X_, - (*it)->point->pos_.y(), - -(*it)->point->pos_.x()*frame->T_f_w_.sin_theta_+(*it)->point->pos_.z()*frame->T_f_w_.cos_theta_+frame->T_f_w_.Z_)); + Vector2d e = vk::project2d((*it)->f) - vk::project2d(Vector3d(frame->se3()*(*it)->point->pos_)); double sqrt_inv_cov = 1.0 / (1<<(*it)->level); e *= sqrt_inv_cov; chi2_vec_final.push_back(e.squaredNorm()); @@ -150,7 +158,6 @@ void optimizeGaussNewton( ++n_deleted_refs; } } - error_init=0.0; error_final=0.0; if(!chi2_vec_init.empty()) diff --git a/GPU_version/svo/src/reprojector.cpp b/GPU_version/vio/src/reprojector.cpp similarity index 98% rename from GPU_version/svo/src/reprojector.cpp rename to GPU_version/vio/src/reprojector.cpp index b7f9022..7a598b6 100644 --- a/GPU_version/svo/src/reprojector.cpp +++ b/GPU_version/vio/src/reprojector.cpp @@ -72,7 +72,7 @@ void Reprojector::reprojectMap( list< pair > close_kfs; map_.getCloseKeyframes(frame, close_kfs); - //std::cout<<"The number of closed frames: "<::second, _1) < boost::bind(&std::pair::second, _2)); @@ -128,7 +128,6 @@ void Reprojector::reprojectMap( } } // unlock the mutex when out of scope //SVO_STOP_TIMER("reproject_candidates"); - // Now we go through each grid cell and select one point to match. // At the end, we should have at maximum one reprojected point per cell. //SVO_START_TIMER("feature_align"); diff --git a/GPU_version/svo/src/robust_cost.cpp b/GPU_version/vio/src/robust_cost.cpp similarity index 100% rename from GPU_version/svo/src/robust_cost.cpp rename to GPU_version/vio/src/robust_cost.cpp diff --git a/GPU_version/svo/src/sparse_img_align.cpp b/GPU_version/vio/src/sparse_img_align.cpp similarity index 88% rename from GPU_version/svo/src/sparse_img_align.cpp rename to GPU_version/vio/src/sparse_img_align.cpp index fbd10d6..533c776 100644 --- a/GPU_version/svo/src/sparse_img_align.cpp +++ b/GPU_version/vio/src/sparse_img_align.cpp @@ -37,7 +37,7 @@ SparseImgAlign::SparseImgAlign( n_iter_init_ = n_iter_; method_ = method; verbose_ = verbose; - eps_ = 0.000001; + eps_ = 0.0001; } size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) @@ -54,28 +54,27 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) cur_frame_ = cur_frame; ref_patch_cache_ = cv::Mat(ref_frame_->fts_.size(), patch_area_, CV_32F); jacobian_cache_.resize(Eigen::NoChange, ref_patch_cache_.rows*patch_area_); - visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? - SE3 T_cur_from_ref(*cur_frame_->T_f_w_.T * ref_frame_->T_f_w_.T->inverse()); + //visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? + SE2 T_cur_from_ref(cur_frame_->T_f_w_.getSE2() * ref_frame_->T_f_w_.inverse()); for(level_=max_level_; level_>=min_level_; --level_) { - //visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? - mu_ = 0.1; + visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? + mu_ = 1.0; jacobian_cache_.setZero(); have_ref_patch_cache_ = false; if(verbose_) printf("\nPYRAMID LEVEL %i\n---------------\n", level_); optimize(T_cur_from_ref); } - SE3 tem=T_cur_from_ref * (*ref_frame_->T_f_w_.T); - cur_frame_->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),atan(tem.rotation_matrix()(0,2)/tem.rotation_matrix()(0,0))); + cur_frame_->T_f_w_ = SE2_5(T_cur_from_ref * ref_frame_->T_f_w_.getSE2()); return n_meas_/patch_area_; } -Matrix SparseImgAlign::getFisherInformation() +Matrix SparseImgAlign::getFisherInformation() { double sigma_i_sq = 5e-4*255*255; // image noise - Matrix I = H_/sigma_i_sq; + Matrix I = H_/sigma_i_sq; return I; } @@ -85,7 +84,7 @@ void SparseImgAlign::precomputeReferencePatches() const cv::Mat& ref_img = ref_frame_->img_pyr_.at(level_); const int stride = ref_img.cols; const float scale = 1.0f/(1<pos(); + const Vector3d ref_pos(ref_frame_->pos()(0),1e-19,ref_frame_->pos()(1)); const double focal_length = ref_frame_->cam_->errorMultiplier2(); size_t feature_counter = 0; std::vector::iterator visiblity_it = visible_fts_.begin(); @@ -106,9 +105,8 @@ void SparseImgAlign::precomputeReferencePatches() const Vector3d xyz_ref((*it)->f*depth); // evaluate projection jacobian - Matrix frame_jac; + Matrix frame_jac; Frame::jacobian_xyz2uv(xyz_ref, frame_jac); - // compute bilateral interpolation weights for reference image const float subpix_u_ref = u_ref-u_ref_i; const float subpix_v_ref = v_ref-v_ref_i; @@ -143,7 +141,7 @@ void SparseImgAlign::precomputeReferencePatches() } double SparseImgAlign::computeResiduals( - const SE3& T_cur_from_ref, + const SE2& T_cur_from_ref, bool linearize_system, bool compute_weight_scale) { @@ -163,7 +161,7 @@ double SparseImgAlign::computeResiduals( const int stride = cur_img.cols; const int border = patch_halfsize_+1; const float scale = 1.0f/(1<pos()); + const Vector3d ref_pos(ref_frame_->pos()(0),1e-19,ref_frame_->pos()(1)); float chi2 = 0.0; size_t feature_counter = 0; // is used to compute the index of the cached jacobian std::vector::iterator visiblity_it = visible_fts_.begin(); @@ -177,7 +175,9 @@ double SparseImgAlign::computeResiduals( // compute pixel location in cur img const double depth = ((*it)->point->pos_ - ref_pos).norm(); const Vector3d xyz_ref((*it)->f*depth); - const Vector3d xyz_cur(T_cur_from_ref * xyz_ref); + const Vector3d xyz_cur((T_cur_from_ref.rotation_matrix()(0,0)*xyz_ref.x())+(T_cur_from_ref.rotation_matrix()(0,1)*xyz_ref.z())+T_cur_from_ref.translation()(0), + xyz_ref.y(), + -1.0*(T_cur_from_ref.rotation_matrix()(1,0)*xyz_ref.x())+(T_cur_from_ref.rotation_matrix()(1,1)*xyz_ref.z())+T_cur_from_ref.translation()(1)); const Vector2f uv_cur_pyr(cur_frame_->cam_->world2cam(xyz_cur).cast() * scale); const float u_cur = uv_cur_pyr[0]; const float v_cur = uv_cur_pyr[1]; @@ -212,7 +212,7 @@ double SparseImgAlign::computeResiduals( errors.push_back(fabsf(res)); // robustification - float weight = 1.0; + float weight = 2.0; if(use_weights_) { weight = weight_function_->value(res/scale_); } @@ -223,7 +223,7 @@ double SparseImgAlign::computeResiduals( if(linearize_system) { // compute Jacobian, weighted Hessian and weighted "steepest descend images" (times error) - const Vector6d J(jacobian_cache_.col(feature_counter*patch_area_ + pixel_counter)); + const Vector3d J(jacobian_cache_.col(feature_counter*patch_area_ + pixel_counter)); H_.noalias() += J*J.transpose()*weight; Jres_.noalias() -= J*res*weight; if(display_) @@ -232,7 +232,6 @@ double SparseImgAlign::computeResiduals( } } } - // compute the weights on the first iteration if(compute_weight_scale && iter_ == 0) scale_ = scale_estimator_->compute(errors); @@ -252,7 +251,7 @@ void SparseImgAlign::update( const ModelType& T_curold_from_ref, ModelType& T_curnew_from_ref) { - T_curnew_from_ref = T_curold_from_ref * SE3::exp(-x_); + T_curnew_from_ref = T_curold_from_ref * SE2::exp(-1.0*x_); } void SparseImgAlign::startIteration() diff --git a/GPU_version/svo/src/vision.cpp b/GPU_version/vio/src/vision.cpp similarity index 99% rename from GPU_version/svo/src/vision.cpp rename to GPU_version/vio/src/vision.cpp index b6d5f58..e1be729 100644 --- a/GPU_version/svo/src/vision.cpp +++ b/GPU_version/vio/src/vision.cpp @@ -5,7 +5,7 @@ * Author: cforster */ -#include +#include #if __SSE2__ # include diff --git a/GPU_version/vio/src/visualizer.cpp b/GPU_version/vio/src/visualizer.cpp index b7f860f..43bc4b1 100644 --- a/GPU_version/vio/src/visualizer.cpp +++ b/GPU_version/vio/src/visualizer.cpp @@ -14,16 +14,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include +#include #include #include #include #include -#include #include #include #include -#include +#include #include namespace svo { @@ -53,31 +52,27 @@ void Visualizer::publishMinimal( header_msg.stamp = ros::Time(timestamp); if(pub_pose_with_cov_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) { - Matrix Cov; // publish cam in world frame (Estimated odometry in the worls frame) - SE3 T_world_from_cam(frame->T_f_w_.T->inverse());// do not confused with inverse. the T_f_w_ is the from camera to initial position with reference of camera - double yaw=asin(2*(frame->T_f_w_.T->unit_quaternion().w()*frame->T_f_w_.T->unit_quaternion().y()- - frame->T_f_w_.T->unit_quaternion().z()*frame->T_f_w_.T->unit_quaternion().x())); - Quaterniond q; - q = AngleAxisd(0.0, Vector3d::UnitX()) - * AngleAxisd(0.0, Vector3d::UnitY()) - * AngleAxisd(yaw-1.5708, Vector3d::UnitZ()); - Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj(); + Quaterniond q(AngleAxisd(frame->T_f_w_.pitch(), Vector3d::UnitY())); geometry_msgs::PoseWithCovarianceStampedPtr msg_pose_with_cov(new geometry_msgs::PoseWithCovarianceStamped); msg_pose_with_cov->header = header_msg; - msg_pose_with_cov->pose.pose.position.x = -1.0*T_world_from_cam.translation().x(); - msg_pose_with_cov->pose.pose.position.y = -1.0*T_world_from_cam.translation().z(); + msg_pose_with_cov->pose.pose.position.x = frame->se3().translation().x(); + msg_pose_with_cov->pose.pose.position.y = frame->se3().translation().z(); msg_pose_with_cov->pose.pose.position.z = 0.0; - msg_pose_with_cov->pose.pose.orientation.x = q.x()/q.norm(); - msg_pose_with_cov->pose.pose.orientation.y = q.y()/q.norm(); - msg_pose_with_cov->pose.pose.orientation.z = q.z()/q.norm(); - msg_pose_with_cov->pose.pose.orientation.w = q.w()/q.norm(); - for(size_t i=0; i<36; ++i) - msg_pose_with_cov->pose.covariance[i] = Cov(i%6, i/6); + msg_pose_with_cov->pose.pose.orientation.x = q.x(); + msg_pose_with_cov->pose.pose.orientation.y = q.y(); + msg_pose_with_cov->pose.pose.orientation.z = q.z(); + msg_pose_with_cov->pose.pose.orientation.w = q.w(); + msg_pose_with_cov->pose.covariance = {frame->Cov_(0,0),frame->Cov_(0,1),0.0,0.0,frame->Cov_(0,2),0.0, + frame->Cov_(1,0),frame->Cov_(1,1),0.0,0.0,frame->Cov_(1,2),0.0, + 0.0,0.0,0.0000001,0.0,0.0,0.0, + 0.0,0.0,0.0,0.0000001,0.0,0.0, + frame->Cov_(2,0),frame->Cov_(2,1),0.0,0.0,frame->Cov_(2,2),0.0, + 0.0,0.0,0.0,0.0,0.0,0.0000001}; pub_pose_with_cov_.publish(msg_pose_with_cov); if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0){ - vk::output_helper::publishPointMarker( - pub_points_, Eigen::Vector3d(-1.0*T_world_from_cam.translation().x(),-1.0*T_world_from_cam.translation().z(),0.0), "trajectory", + publishPointMarker( + pub_points_, Eigen::Vector3d(frame->se3().translation().x(),frame->se3().translation().z(),0.0), "trajectory", ros::Time::now(), trace_id_, 0, 0.01, Vector3d(0.,0.,0.5)); } } @@ -92,14 +87,14 @@ void Visualizer::visualizeMarkers( if(frame == NULL) return; - vk::output_helper::publishTfTransform( - *frame->T_f_w_.T*T_world_from_vision_.inverse(), + publishTfTransform( + frame->se3()*T_world_from_vision_.inverse(), ros::Time(frame->timestamp_), "cam_pos", "world", br_); if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) { - vk::output_helper::publishPointMarker( - pub_points_, T_world_from_vision_*frame->pos(), "trajectory", + publishPointMarker( + pub_points_, T_world_from_vision_*Vector3d(frame->pos()(0),0.0,frame->pos()(1)), "trajectory", ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5)); removeDeletedPts(map); } @@ -110,7 +105,7 @@ void Visualizer::removeDeletedPts(const Map& map) if(pub_points_.getNumSubscribers() > 0) { for(list::const_iterator it=map.trash_points_.begin(); it!=map.trash_points_.end(); ++it) - vk::output_helper::publishPointMarker(pub_points_, Vector3d(), "pts", ros::Time::now(), (*it)->id_, 2, 0.006, Vector3d()); + publishPointMarker(pub_points_, Vector3d(), "pts", ros::Time::now(), (*it)->id_, 2, 0.006, Vector3d()); } } diff --git a/GPU_version/vio/src/vo_node.cpp b/GPU_version/vio/src/vo_node.cpp index 0087b0c..20e874d 100644 --- a/GPU_version/vio/src/vo_node.cpp +++ b/GPU_version/vio/src/vo_node.cpp @@ -13,10 +13,12 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include +#define VIO_DEBUG false +#include #include +#include #include -#include +#include #include #include #include @@ -25,13 +27,9 @@ #include #include #include -#include +#include #include - -namespace svo { - -/// SVO Interface class VoNode { public: @@ -39,16 +37,22 @@ public: svo::Visualizer visualizer_; bool publish_markers_; //!< publish only the minimal amount of info (choice for embedded devices) vk::AbstractCamera* cam_; - FILE* logtime; bool quit_; boost::thread* imu_th; VoNode(); ~VoNode(); void imgCb(const sensor_msgs::ImageConstPtr& msg); void imuCb(const sensor_msgs::ImuPtr& imu); - void imu(); + void cmdCb(const geometry_msgs::TwistPtr &imu); + void imu(); private: double* imu_; +#if VIO_DEBUG + FILE* log_= nullptr; + double imu_t_[6]={0.0,0.0,0.0,0.0,0.0,0.0}; +#endif + double* cmd_; + ros::Time imu_time_; }; VoNode::VoNode() : @@ -58,32 +62,42 @@ VoNode::VoNode() : quit_(false) { // Create Camera - imu_=(double *)calloc(static_cast(6), sizeof(double)); + imu_=(double *)calloc(static_cast(3), sizeof(double)); + cmd_=(double *)calloc(static_cast(3), sizeof(double)); if(!vk::camera_loader::loadFromRosNs("vio", cam_)) throw std::runtime_error("Camera model not correctly specified."); // Get initial position and orientation visualizer_.T_world_from_vision_ = Sophus::SE3( - vk::rpy2dcm(Vector3d(vk::getParam("vio/init_rx", 0.0), + vk::rpy2dcm(Eigen::Vector3d(vk::getParam("vio/init_rx", 0.0), vk::getParam("vio/init_ry", 0.0), vk::getParam("vio/init_rz", 0.0))), Eigen::Vector3d(vk::getParam("vio/init_tx", 0.0), vk::getParam("vio/init_ty", 0.0), vk::getParam("vio/init_tz", 0.0))); - // Init VO and start - vo_ = new svo::FrameHandlerMono(cam_,visualizer_.T_world_from_vision_); - vo_->start(); + Eigen::Matrix init; + init<<1e-5,1e-5,1e-5,1e-5,1e-5,1e-5; + vo_ = new svo::FrameHandlerMono(cam_,init); + usleep(500); + +#if VIO_DEBUG +log_ = fopen((std::string(getenv("HOME"))+"/imu_integration.txt").c_str(), "w+"); +#endif + vo_->start(); imu_th=new boost::thread(&VoNode::imu,this); - logtime = fopen((std::string(getenv("HOME"))+"/time.txt").c_str(), "w+"); } VoNode::~VoNode() { quit_=true; - fclose(logtime); + + +#if VIO_DEBUG + fclose(log_); + delete log_; +#endif imu_th->join(); delete imu_th; - delete logtime; delete vo_; delete cam_; } @@ -93,32 +107,70 @@ void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) try { auto start=std::chrono::steady_clock::now(); cv::Mat img=cv_bridge::toCvShare(msg, "mono8")->image; - vo_->addImage(img, msg->header.stamp.toSec()); + vo_->addImage(img, msg->header.stamp.toSec(),msg->header.stamp); visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, msg->header.stamp.toSec()); - if(vo_->stage() == FrameHandlerMono::STAGE_PAUSED) + if(vo_->stage() == svo::FrameHandlerMono::STAGE_PAUSED) usleep(100000); - fprintf(logtime, "%s\n",std::to_string(std::chrono::duration(std::chrono::steady_clock::now()-start).count()).c_str()); +#if VIO_DEBUG + fprintf(log_, ",,,,,,,%s,%f,%f,%f\n",std::to_string(std::chrono::duration(std::chrono::steady_clock::now()-start).count()).c_str(),vo_->lastFrame()->T_f_w_.translation()(0), + vo_->lastFrame()->T_f_w_.translation()(1), + acos(vo_->lastFrame()->T_f_w_.getSE2().rotation_matrix()(0,0))); +#endif } catch (cv_bridge::Exception& e) { ROS_ERROR("cv_bridge exception: %s", e.what()); } } void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { - double imu_in[6]; - imu_in[0] = 0.4*imu_[0]+0.6*imu->linear_acceleration.x; - imu_in[1] = 0.4*imu_[1]+0.6*imu->linear_acceleration.y; - imu_in[2] = 0.4*imu_[2]+0.6*imu->linear_acceleration.z; - imu_in[3] = 0.4*imu_[3]+0.6*imu->angular_velocity.x; - imu_in[4] = 0.4*imu_[4]+0.6*imu->angular_velocity.y; - imu_in[5] = 0.4*imu_[5]+0.6*imu->angular_velocity.z; - memcpy(imu_, imu_in, static_cast(6*sizeof(double))); - vo_->imu_integPtr_->update(imu_in); + double imu_in[3]; + if(abs(imu->linear_acceleration.x)>5.0){ + return; + }else{ + imu_in[0]=imu->linear_acceleration.x; + }; + if(abs(imu->linear_acceleration.y)>5.0){ + return; + }else{ + imu_in[1]=imu->linear_acceleration.y; + }; + imu_in[0] = 0.5*imu_[0]+0.5*imu->linear_acceleration.x; + imu_in[1] = 0.5*imu_[1]+0.5*imu->linear_acceleration.y; + imu_in[2] = 0.5*imu_[2]+0.5*imu->angular_velocity.z; + memcpy(imu_, imu_in, static_cast(3*sizeof(double))); +#if VIO_DEBUG + if(imu_t_[5]!=0.0){ + double dt=1e-9*(imu->header.stamp.toNSec()-imu_t_[5]); + imu_t_[0]+=imu_in[0]*dt; + imu_t_[1]+=imu_t_[0]*dt; + imu_t_[2]+=imu_in[1]*dt; + imu_t_[3]+=imu_t_[2]*dt; + imu_t_[4]+=imu_in[2]*dt; + imu_t_[5]=imu->header.stamp.toNSec(); + fprintf(log_, "%f,%f,%f,%f\n",imu_t_[1],imu_t_[3],imu_t_[4],dt); + }else{ + imu_t_[0]=imu_in[0]; + imu_t_[1]=0.0; + imu_t_[2]=imu_in[1]; + imu_t_[3]=0.0; + imu_t_[4]=imu_in[2]; + imu_t_[5]=imu->header.stamp.toNSec(); + } +#endif + vo_->UpdateIMU(imu_in,imu->header.stamp); +} +void VoNode::cmdCb(const geometry_msgs::TwistPtr &cmd) { + double _cmd[3]={cmd->linear.x,cmd->linear.y,cmd->angular.z}; + memcpy(cmd_, _cmd, static_cast(3*sizeof(double))); +#if VIO_DEBUG + fprintf(log_, ",,,,%f,%f,%f\n",_cmd[0],_cmd[1],_cmd[2]); +#endif + vo_->UpdateCmd(_cmd,imu_time_); } void VoNode::imu(){ ros::NodeHandle nh; // subscribe to cam msgs image_transport::ImageTransport it(nh); - image_transport::Subscriber it_sub = it.subscribe(vk::getParam("vio/cam_topic", "camera/image_raw"), 1, &svo::VoNode::imgCb, this); + image_transport::Subscriber it_sub = it.subscribe(vk::getParam("vio/cam_topic", "camera/image_raw"), 1, &VoNode::imgCb, this); // start processing callbacks while(ros::ok() && !quit_) { @@ -126,20 +178,19 @@ void VoNode::imu(){ } } -} // namespace svo int main(int argc, char **argv) { ros::init(argc, argv, "vio"); - svo::VoNode vo_node; + VoNode vo_node; ros::NodeHandle nh; - ros::Subscriber imu_sub=nh.subscribe(vk::getParam("vio/imu_topic", "imu/raw"),1,&svo::VoNode::imuCb, &vo_node); + ros::Subscriber imu_sub=nh.subscribe(vk::getParam("vio/imu_topic", "imu/raw"),10,&VoNode::imuCb, &vo_node); + ros::Subscriber cmd_sub=nh.subscribe(vk::getParam("vio/cmd_topic", "cmd/raw"),10,&VoNode::cmdCb, &vo_node); // start processing callbacks while(ros::ok() && !vo_node.quit_) { ros::spinOnce(); usleep(1000); - // TODO check when last image was processed. when too long ago. publish warning that no msgs are received! } printf("SVO terminated.\n"); return 0; diff --git a/GPU_version/svo/test/README.md b/GPU_version/vio/test/README.md similarity index 100% rename from GPU_version/svo/test/README.md rename to GPU_version/vio/test/README.md diff --git a/GPU_version/svo/test/benchmark.csv b/GPU_version/vio/test/benchmark.csv similarity index 100% rename from GPU_version/svo/test/benchmark.csv rename to GPU_version/vio/test/benchmark.csv diff --git a/GPU_version/svo/test/data/.gitignore b/GPU_version/vio/test/data/.gitignore similarity index 100% rename from GPU_version/svo/test/data/.gitignore rename to GPU_version/vio/test/data/.gitignore diff --git a/GPU_version/svo/test/results/.gitignore b/GPU_version/vio/test/results/.gitignore similarity index 100% rename from GPU_version/svo/test/results/.gitignore rename to GPU_version/vio/test/results/.gitignore diff --git a/GPU_version/svo/test/test_depth_filter.cpp b/GPU_version/vio/test/test_depth_filter.cpp similarity index 100% rename from GPU_version/svo/test/test_depth_filter.cpp rename to GPU_version/vio/test/test_depth_filter.cpp diff --git a/GPU_version/svo/test/test_feature_alignment.cpp b/GPU_version/vio/test/test_feature_alignment.cpp similarity index 100% rename from GPU_version/svo/test/test_feature_alignment.cpp rename to GPU_version/vio/test/test_feature_alignment.cpp diff --git a/GPU_version/svo/test/test_feature_detection.cpp b/GPU_version/vio/test/test_feature_detection.cpp similarity index 100% rename from GPU_version/svo/test/test_feature_detection.cpp rename to GPU_version/vio/test/test_feature_detection.cpp diff --git a/GPU_version/svo/test/test_matcher.cpp b/GPU_version/vio/test/test_matcher.cpp similarity index 100% rename from GPU_version/svo/test/test_matcher.cpp rename to GPU_version/vio/test/test_matcher.cpp diff --git a/GPU_version/svo/test/test_pipeline.cpp b/GPU_version/vio/test/test_pipeline.cpp similarity index 100% rename from GPU_version/svo/test/test_pipeline.cpp rename to GPU_version/vio/test/test_pipeline.cpp diff --git a/GPU_version/svo/test/test_pose_optimizer.cpp b/GPU_version/vio/test/test_pose_optimizer.cpp similarity index 100% rename from GPU_version/svo/test/test_pose_optimizer.cpp rename to GPU_version/vio/test/test_pose_optimizer.cpp diff --git a/GPU_version/svo/test/test_sparse_img_align.cpp b/GPU_version/vio/test/test_sparse_img_align.cpp similarity index 100% rename from GPU_version/svo/test/test_sparse_img_align.cpp rename to GPU_version/vio/test/test_sparse_img_align.cpp diff --git a/GPU_version/svo/test/test_utils.h b/GPU_version/vio/test/test_utils.h similarity index 100% rename from GPU_version/svo/test/test_utils.h rename to GPU_version/vio/test/test_utils.h From 405e12160558fbfbebbc0da06c6a060eb1c8101e Mon Sep 17 00:00:00 2001 From: Majid Geravand <44868211+Gfuse@users.noreply.github.com> Date: Tue, 29 Jun 2021 07:54:57 +0200 Subject: [PATCH 207/215] delete build directory --- .../vio/cmake-build-debug/CATKIN_IGNORE | 0 .../vio/cmake-build-debug/CMakeCache.txt | 785 ------------------ .../CMakeFiles/3.17.5/CMakeCCompiler.cmake | 76 -- .../CMakeFiles/3.17.5/CMakeCXXCompiler.cmake | 88 -- .../3.17.5/CMakeDetermineCompilerABI_C.bin | Bin 8248 -> 0 bytes .../3.17.5/CMakeDetermineCompilerABI_CXX.bin | Bin 8264 -> 0 bytes .../CMakeFiles/3.17.5/CMakeSystem.cmake | 15 - .../3.17.5/CompilerIdC/CMakeCCompilerId.c | 671 --------------- .../CMakeFiles/3.17.5/CompilerIdC/a.out | Bin 8408 -> 0 bytes .../CompilerIdCXX/CMakeCXXCompilerId.cpp | 660 --------------- .../CMakeFiles/3.17.5/CompilerIdCXX/a.out | Bin 8416 -> 0 bytes .../CMakeFiles/CMakeError.log | 65 -- .../CMakeFiles/CMakeOutput.log | 522 ------------ .../CMakeFiles/clion-environment.txt | 3 - .../CMakeFiles/clion-log.txt | 70 -- .../CMakeFiles/cmake.check_cache | 1 - .../cmake-build-debug/CTestConfiguration.ini | 107 --- .../vio/cmake-build-debug/CTestCustom.cmake | 2 - .../atomic_configure/.rosinstall | 2 - .../atomic_configure/_setup_util.py | 304 ------- .../cmake-build-debug/atomic_configure/env.sh | 16 - .../atomic_configure/local_setup.bash | 8 - .../atomic_configure/local_setup.sh | 9 - .../atomic_configure/local_setup.zsh | 8 - .../atomic_configure/setup.bash | 8 - .../atomic_configure/setup.sh | 96 --- .../atomic_configure/setup.zsh | 8 - .../catkin_generated/version/package.cmake | 24 - .../catkin_generated/env_cached.sh | 16 - .../catkin_generated/generate_cached_setup.py | 30 - .../catkin_generated/installspace/.rosinstall | 2 - .../installspace/_setup_util.py | 304 ------- .../catkin_generated/installspace/env.sh | 16 - .../installspace/local_setup.bash | 8 - .../installspace/local_setup.sh | 9 - .../installspace/local_setup.zsh | 8 - .../catkin_generated/installspace/setup.bash | 8 - .../catkin_generated/installspace/setup.sh | 96 --- .../catkin_generated/installspace/setup.zsh | 8 - .../catkin_generated/setup_cached.sh | 13 - .../stamps/vio/_setup_util.py.stamp | 304 ------- .../vio/interrogate_setup_dot_py.py.stamp | 255 ------ .../stamps/vio/package.xml.stamp | 48 -- .../vio/cmake-build-debug/devel/.catkin | 1 - .../vio/cmake-build-debug/devel/.rosinstall | 2 - .../cmake-build-debug/devel/_setup_util.py | 304 ------- .../vio/cmake-build-debug/devel/cmake.lock | 0 .../vio/cmake-build-debug/devel/env.sh | 16 - .../cmake-build-debug/devel/local_setup.bash | 8 - .../cmake-build-debug/devel/local_setup.sh | 9 - .../cmake-build-debug/devel/local_setup.zsh | 8 - .../vio/cmake-build-debug/devel/setup.bash | 8 - .../vio/cmake-build-debug/devel/setup.sh | 96 --- .../vio/cmake-build-debug/devel/setup.zsh | 8 - 54 files changed, 5133 deletions(-) delete mode 100644 GPU_version/vio/cmake-build-debug/CATKIN_IGNORE delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeCache.txt delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCCompiler.cmake delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCXXCompiler.cmake delete mode 100755 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_C.bin delete mode 100755 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_CXX.bin delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeSystem.cmake delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdC/CMakeCCompilerId.c delete mode 100755 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdC/a.out delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/CMakeCXXCompilerId.cpp delete mode 100755 GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/a.out delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeError.log delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeOutput.log delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/clion-environment.txt delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/clion-log.txt delete mode 100644 GPU_version/vio/cmake-build-debug/CMakeFiles/cmake.check_cache delete mode 100644 GPU_version/vio/cmake-build-debug/CTestConfiguration.ini delete mode 100644 GPU_version/vio/cmake-build-debug/CTestCustom.cmake delete mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/.rosinstall delete mode 100755 GPU_version/vio/cmake-build-debug/atomic_configure/_setup_util.py delete mode 100755 GPU_version/vio/cmake-build-debug/atomic_configure/env.sh delete mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.bash delete mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.sh delete mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.zsh delete mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/setup.bash delete mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/setup.sh delete mode 100644 GPU_version/vio/cmake-build-debug/atomic_configure/setup.zsh delete mode 100644 GPU_version/vio/cmake-build-debug/catkin/catkin_generated/version/package.cmake delete mode 100755 GPU_version/vio/cmake-build-debug/catkin_generated/env_cached.sh delete mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/generate_cached_setup.py delete mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/.rosinstall delete mode 100755 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/_setup_util.py delete mode 100755 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/env.sh delete mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.bash delete mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.sh delete mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.zsh delete mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.bash delete mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.sh delete mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.zsh delete mode 100755 GPU_version/vio/cmake-build-debug/catkin_generated/setup_cached.sh delete mode 100755 GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/_setup_util.py.stamp delete mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/interrogate_setup_dot_py.py.stamp delete mode 100644 GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/package.xml.stamp delete mode 100644 GPU_version/vio/cmake-build-debug/devel/.catkin delete mode 100644 GPU_version/vio/cmake-build-debug/devel/.rosinstall delete mode 100755 GPU_version/vio/cmake-build-debug/devel/_setup_util.py delete mode 100644 GPU_version/vio/cmake-build-debug/devel/cmake.lock delete mode 100755 GPU_version/vio/cmake-build-debug/devel/env.sh delete mode 100644 GPU_version/vio/cmake-build-debug/devel/local_setup.bash delete mode 100644 GPU_version/vio/cmake-build-debug/devel/local_setup.sh delete mode 100644 GPU_version/vio/cmake-build-debug/devel/local_setup.zsh delete mode 100644 GPU_version/vio/cmake-build-debug/devel/setup.bash delete mode 100644 GPU_version/vio/cmake-build-debug/devel/setup.sh delete mode 100644 GPU_version/vio/cmake-build-debug/devel/setup.zsh diff --git a/GPU_version/vio/cmake-build-debug/CATKIN_IGNORE b/GPU_version/vio/cmake-build-debug/CATKIN_IGNORE deleted file mode 100644 index e69de29..0000000 diff --git a/GPU_version/vio/cmake-build-debug/CMakeCache.txt b/GPU_version/vio/cmake-build-debug/CMakeCache.txt deleted file mode 100644 index d820937..0000000 --- a/GPU_version/vio/cmake-build-debug/CMakeCache.txt +++ /dev/null @@ -1,785 +0,0 @@ -# This is the CMakeCache file. -# For build in directory: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug -# It was generated by CMake: /opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -# You can edit this file to change values found and used by cmake. -# If you do not want to change any of the values, simply exit the editor. -# If you do want to change a value, simply edit, save, and exit the editor. -# The syntax for the file is as follows: -# KEY:TYPE=VALUE -# KEY is the name of a variable in the cache. -# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!. -# VALUE is the current value for the KEY. - -######################## -# EXTERNAL cache entries -######################## - -//Builds the googlemock subproject -BUILD_GMOCK:BOOL=ON - -//Builds the googletest subproject -BUILD_GTEST:BOOL=OFF - -//Build shared libraries (DLLs). -BUILD_SHARED_LIBS:BOOL=ON - -//Boost atomic library (debug) -Boost_ATOMIC_LIBRARY_DEBUG:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_atomic.so - -//Boost atomic library (release) -Boost_ATOMIC_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_atomic.so - -//Boost chrono library (debug) -Boost_CHRONO_LIBRARY_DEBUG:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_chrono.so - -//Boost chrono library (release) -Boost_CHRONO_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_chrono.so - -//Boost date_time library (debug) -Boost_DATE_TIME_LIBRARY_DEBUG:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_date_time.so - -//Boost date_time library (release) -Boost_DATE_TIME_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_date_time.so - -//The directory containing a CMake configuration file for Boost. -Boost_DIR:PATH=Boost_DIR-NOTFOUND - -//Path to a file. -Boost_INCLUDE_DIR:PATH=/usr/include - -//Boost library directory DEBUG -Boost_LIBRARY_DIR_DEBUG:PATH=/usr/lib/x86_64-linux-gnu - -//Boost library directory RELEASE -Boost_LIBRARY_DIR_RELEASE:PATH=/usr/lib/x86_64-linux-gnu - -//Boost system library (debug) -Boost_SYSTEM_LIBRARY_DEBUG:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_system.so - -//Boost system library (release) -Boost_SYSTEM_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_system.so - -//Boost thread library (debug) -Boost_THREAD_LIBRARY_DEBUG:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_thread.so - -//Boost thread library (release) -Boost_THREAD_LIBRARY_RELEASE:FILEPATH=/usr/lib/x86_64-linux-gnu/libboost_thread.so - -//Catkin enable testing -CATKIN_ENABLE_TESTING:BOOL=ON - -//Prefix to apply to package generated via gendebian -CATKIN_PACKAGE_PREFIX:STRING= - -//Catkin skip testing -CATKIN_SKIP_TESTING:BOOL=OFF - -//Replace the CMake install command with a custom implementation -// using symlinks instead of copying resources -CATKIN_SYMLINK_INSTALL:BOOL=OFF - -//Path to a program. -CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line - -//Path to a program. -CMAKE_AR:FILEPATH=/usr/bin/ar - -//Choose the type of build, options are: None Debug Release RelWithDebInfo -// MinSizeRel ... -CMAKE_BUILD_TYPE:STRING=Debug - -//Id string of the compiler for the CodeBlocks IDE. Automatically -// detected when left empty -CMAKE_CODEBLOCKS_COMPILER_ID:STRING= - -//The CodeBlocks executable -CMAKE_CODEBLOCKS_EXECUTABLE:FILEPATH=/usr/bin/codeblocks - -//Additional command line arguments when CodeBlocks invokes make. -// Enter e.g. -j to get parallel builds -CMAKE_CODEBLOCKS_MAKE_ARGUMENTS:STRING=-j8 - -//Enable/Disable color output during build. -CMAKE_COLOR_MAKEFILE:BOOL=ON - -//CXX compiler -CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++ - -//A wrapper around 'ar' adding the appropriate '--plugin' option -// for the GCC compiler -CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-7 - -//A wrapper around 'ranlib' adding the appropriate '--plugin' option -// for the GCC compiler -CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-7 - -//Flags used by the CXX compiler during all build types. -CMAKE_CXX_FLAGS:STRING= - -//Flags used by the CXX compiler during DEBUG builds. -CMAKE_CXX_FLAGS_DEBUG:STRING=-g - -//Flags used by the CXX compiler during MINSIZEREL builds. -CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG - -//Flags used by the CXX compiler during RELEASE builds. -CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG - -//Flags used by the CXX compiler during RELWITHDEBINFO builds. -CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG - -//C compiler -CMAKE_C_COMPILER:FILEPATH=/usr/bin/cc - -//A wrapper around 'ar' adding the appropriate '--plugin' option -// for the GCC compiler -CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-7 - -//A wrapper around 'ranlib' adding the appropriate '--plugin' option -// for the GCC compiler -CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-7 - -//Flags used by the C compiler during all build types. -CMAKE_C_FLAGS:STRING= - -//Flags used by the C compiler during DEBUG builds. -CMAKE_C_FLAGS_DEBUG:STRING=-g - -//Flags used by the C compiler during MINSIZEREL builds. -CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG - -//Flags used by the C compiler during RELEASE builds. -CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG - -//Flags used by the C compiler during RELWITHDEBINFO builds. -CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG - -//Path to a program. -CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND - -//Flags used by the linker during all build types. -CMAKE_EXE_LINKER_FLAGS:STRING= - -//Flags used by the linker during DEBUG builds. -CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING= - -//Flags used by the linker during MINSIZEREL builds. -CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING= - -//Flags used by the linker during RELEASE builds. -CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING= - -//Flags used by the linker during RELWITHDEBINFO builds. -CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING= - -//Enable/Disable output of compile commands during generation. -CMAKE_EXPORT_COMPILE_COMMANDS:BOOL= - -//Install path prefix, prepended onto install directories. -CMAKE_INSTALL_PREFIX:PATH=/usr/local - -//Path to a program. -CMAKE_LINKER:FILEPATH=/usr/bin/ld - -//Path to a program. -CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make - -//Flags used by the linker during the creation of modules during -// all build types. -CMAKE_MODULE_LINKER_FLAGS:STRING= - -//Flags used by the linker during the creation of modules during -// DEBUG builds. -CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING= - -//Flags used by the linker during the creation of modules during -// MINSIZEREL builds. -CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING= - -//Flags used by the linker during the creation of modules during -// RELEASE builds. -CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING= - -//Flags used by the linker during the creation of modules during -// RELWITHDEBINFO builds. -CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING= - -//Path to a program. -CMAKE_NM:FILEPATH=/usr/bin/nm - -//Path to a program. -CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy - -//Path to a program. -CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump - -//Value Computed by CMake -CMAKE_PROJECT_DESCRIPTION:STATIC= - -//Value Computed by CMake -CMAKE_PROJECT_HOMEPAGE_URL:STATIC= - -//Value Computed by CMake -CMAKE_PROJECT_NAME:STATIC=vio - -//Path to a program. -CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib - -//Path to a program. -CMAKE_READELF:FILEPATH=/usr/bin/readelf - -//Flags used by the linker during the creation of shared libraries -// during all build types. -CMAKE_SHARED_LINKER_FLAGS:STRING= - -//Flags used by the linker during the creation of shared libraries -// during DEBUG builds. -CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING= - -//Flags used by the linker during the creation of shared libraries -// during MINSIZEREL builds. -CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING= - -//Flags used by the linker during the creation of shared libraries -// during RELEASE builds. -CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING= - -//Flags used by the linker during the creation of shared libraries -// during RELWITHDEBINFO builds. -CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING= - -//If set, runtime paths are not added when installing shared libraries, -// but are added when building. -CMAKE_SKIP_INSTALL_RPATH:BOOL=NO - -//If set, runtime paths are not added when using shared libraries. -CMAKE_SKIP_RPATH:BOOL=NO - -//Flags used by the linker during the creation of static libraries -// during all build types. -CMAKE_STATIC_LINKER_FLAGS:STRING= - -//Flags used by the linker during the creation of static libraries -// during DEBUG builds. -CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING= - -//Flags used by the linker during the creation of static libraries -// during MINSIZEREL builds. -CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING= - -//Flags used by the linker during the creation of static libraries -// during RELEASE builds. -CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING= - -//Flags used by the linker during the creation of static libraries -// during RELWITHDEBINFO builds. -CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING= - -//Path to a program. -CMAKE_STRIP:FILEPATH=/usr/bin/strip - -//If this value is on, makefiles will be generated without the -// .SILENT directive, and all commands will be echoed to the console -// during the make. This is useful for debugging only. With Visual -// Studio IDE projects all commands are done without /nologo. -CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE - -//Path to a program. -DOXYGEN_EXECUTABLE:FILEPATH=/usr/bin/doxygen - -//Doxygen found -DOXYGEN_FOUND:BOOL=TRUE - -//Path to a file. -EIGEN_INCLUDE_DIR:PATH=/usr/include/eigen3 - -//Path to a program. -EMPY_EXECUTABLE:FILEPATH=/usr/bin/empy - -//Empy script -EMPY_SCRIPT:STRING=/usr/bin/empy - -//The directory containing a CMake configuration file for GMock. -GMock_DIR:PATH=GMock_DIR-NOTFOUND - -//Path to a file. -GTEST_INCLUDE_DIR:PATH=/usr/include - -//Path to a library. -GTEST_LIBRARY:FILEPATH=GTEST_LIBRARY-NOTFOUND - -//Path to a library. -GTEST_LIBRARY_DEBUG:FILEPATH=GTEST_LIBRARY_DEBUG-NOTFOUND - -//Path to a library. -GTEST_MAIN_LIBRARY:FILEPATH=GTEST_MAIN_LIBRARY-NOTFOUND - -//Path to a library. -GTEST_MAIN_LIBRARY_DEBUG:FILEPATH=GTEST_MAIN_LIBRARY_DEBUG-NOTFOUND - -//lsb_release executable was found -LSB_FOUND:BOOL=TRUE - -//Path to a program. -LSB_RELEASE_EXECUTABLE:FILEPATH=/usr/bin/lsb_release - -//Path to a program. -NOSETESTS:FILEPATH=/usr/bin/nosetests-2.7 - -//Path to a file. -OpenCL_INCLUDE_DIR:PATH=/usr/include - -//Path to a library. -OpenCL_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libOpenCL.so - -//The directory containing a CMake configuration file for OpenCV. -OpenCV_DIR:PATH=/usr/share/OpenCV - -//pkg-config executable -PKG_CONFIG_EXECUTABLE:FILEPATH=/usr/bin/pkg-config - -//Path to a program. -PYTHON_EXECUTABLE:FILEPATH=/usr/bin/python2 - -//Specify specific Python version to use ('major.minor' or 'major') -PYTHON_VERSION:STRING=2 - -//Path to a program. -ProcessorCount_cmd_nproc:FILEPATH=/usr/bin/nproc - -//Path to a program. -ProcessorCount_cmd_sysctl:FILEPATH=/sbin/sysctl - -//Path to a library. -RT_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/librt.so - -//Enable debian style python package layout -SETUPTOOLS_DEB_LAYOUT:BOOL=ON - -//Name of the computer/site where compile is being run -SITE:STRING=gfuse - -//The directory containing a CMake configuration file for Sophus. -Sophus_DIR:PATH=/root/workstation/Sophus/build - -//LSB Distrib tag -UBUNTU:BOOL=TRUE - -//LSB Distrib - codename tag -UBUNTU_BIONIC:BOOL=TRUE - -//Path to a file. -_gmock_INCLUDES:FILEPATH=/usr/include/gmock/gmock.h - -//Path to a file. -_gmock_SOURCES:FILEPATH=/usr/src/gmock/src/gmock.cc - -//Path to a file. -_gtest_INCLUDES:FILEPATH=/usr/include/gtest/gtest.h - -//Path to a file. -_gtest_SOURCES:FILEPATH=/usr/src/gtest/src/gtest.cc - -//The directory containing a CMake configuration file for catkin. -catkin_DIR:PATH=/opt/ros/melodic/share/catkin/cmake - -//The directory containing a CMake configuration file for cmake_modules. -cmake_modules_DIR:PATH=/opt/ros/melodic/share/cmake_modules/cmake - -//The directory containing a CMake configuration file for cpp_common. -cpp_common_DIR:PATH=/opt/ros/melodic/share/cpp_common/cmake - -//Value Computed by CMake -gmock_BINARY_DIR:STATIC=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/gtest/googlemock - -//Dependencies for the target -gmock_LIB_DEPENDS:STATIC=general;-lpthread; - -//Value Computed by CMake -gmock_SOURCE_DIR:STATIC=/usr/src/googletest/googlemock - -//Build all of Google Mock's own tests. -gmock_build_tests:BOOL=OFF - -//Dependencies for the target -gmock_main_LIB_DEPENDS:STATIC=general;-lpthread; - -//Value Computed by CMake -googletest-distribution_BINARY_DIR:STATIC=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/gtest - -//Value Computed by CMake -googletest-distribution_SOURCE_DIR:STATIC=/usr/src/googletest - -//Value Computed by CMake -gtest_BINARY_DIR:STATIC=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/gtest/googlemock/gtest - -//Dependencies for the target -gtest_LIB_DEPENDS:STATIC=general;-lpthread; - -//Value Computed by CMake -gtest_SOURCE_DIR:STATIC=/usr/src/googletest/googletest - -//Build gtest's sample programs. -gtest_build_samples:BOOL=OFF - -//Build all of gtest's own tests. -gtest_build_tests:BOOL=OFF - -//Disable uses of pthreads in gtest. -gtest_disable_pthreads:BOOL=OFF - -//Use shared (DLL) run-time lib even when Google Test is built -// as static lib. -gtest_force_shared_crt:BOOL=OFF - -//Build gtest with internal symbols hidden in shared libraries. -gtest_hide_internal_symbols:BOOL=OFF - -//Dependencies for the target -gtest_main_LIB_DEPENDS:STATIC=general;-lpthread;general;gtest; - -//Path to a library. -lib:FILEPATH=/opt/ros/melodic/lib/librospack.so - -//The directory containing a CMake configuration file for message_runtime. -message_runtime_DIR:PATH=/opt/ros/melodic/share/message_runtime/cmake - -//The directory containing a CMake configuration file for robot_localization. -robot_localization_DIR:PATH=robot_localization_DIR-NOTFOUND - -//The directory containing a CMake configuration file for rosconsole. -rosconsole_DIR:PATH=/opt/ros/melodic/share/rosconsole/cmake - -//The directory containing a CMake configuration file for roscpp. -roscpp_DIR:PATH=/opt/ros/melodic/share/roscpp/cmake - -//The directory containing a CMake configuration file for roscpp_serialization. -roscpp_serialization_DIR:PATH=/opt/ros/melodic/share/roscpp_serialization/cmake - -//The directory containing a CMake configuration file for roscpp_traits. -roscpp_traits_DIR:PATH=/opt/ros/melodic/share/roscpp_traits/cmake - -//The directory containing a CMake configuration file for rosgraph_msgs. -rosgraph_msgs_DIR:PATH=/opt/ros/melodic/share/rosgraph_msgs/cmake - -//The directory containing a CMake configuration file for roslib. -roslib_DIR:PATH=/opt/ros/melodic/share/roslib/cmake - -//The directory containing a CMake configuration file for rospack. -rospack_DIR:PATH=/opt/ros/melodic/share/rospack/cmake - -//The directory containing a CMake configuration file for rostime. -rostime_DIR:PATH=/opt/ros/melodic/share/rostime/cmake - -//The directory containing a CMake configuration file for std_msgs. -std_msgs_DIR:PATH=/opt/ros/melodic/share/std_msgs/cmake - -//Value Computed by CMake -vio_BINARY_DIR:STATIC=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug - -//Value Computed by CMake -vio_SOURCE_DIR:STATIC=/root/Project/ROS/src/vio_svo/GPU_version/svo - -//The directory containing a CMake configuration file for xmlrpcpp. -xmlrpcpp_DIR:PATH=/opt/ros/melodic/share/xmlrpcpp/cmake - - -######################## -# INTERNAL cache entries -######################## - -//ADVANCED property for variable: Boost_ATOMIC_LIBRARY_DEBUG -Boost_ATOMIC_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_ATOMIC_LIBRARY_RELEASE -Boost_ATOMIC_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_CHRONO_LIBRARY_DEBUG -Boost_CHRONO_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_CHRONO_LIBRARY_RELEASE -Boost_CHRONO_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_DATE_TIME_LIBRARY_DEBUG -Boost_DATE_TIME_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_DATE_TIME_LIBRARY_RELEASE -Boost_DATE_TIME_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_DIR -Boost_DIR-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_INCLUDE_DIR -Boost_INCLUDE_DIR-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_LIBRARY_DIR_DEBUG -Boost_LIBRARY_DIR_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_LIBRARY_DIR_RELEASE -Boost_LIBRARY_DIR_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_SYSTEM_LIBRARY_DEBUG -Boost_SYSTEM_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_SYSTEM_LIBRARY_RELEASE -Boost_SYSTEM_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_THREAD_LIBRARY_DEBUG -Boost_THREAD_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: Boost_THREAD_LIBRARY_RELEASE -Boost_THREAD_LIBRARY_RELEASE-ADVANCED:INTERNAL=1 -//catkin environment -CATKIN_ENV:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/catkin_generated/env_cached.sh -CATKIN_TEST_RESULTS_DIR:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/test_results -//ADVANCED property for variable: CMAKE_ADDR2LINE -CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_AR -CMAKE_AR-ADVANCED:INTERNAL=1 -//This is the directory where this CMakeCache.txt was created -CMAKE_CACHEFILE_DIR:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug -//Major version of cmake used to create the current loaded cache -CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 -//Minor version of cmake used to create the current loaded cache -CMAKE_CACHE_MINOR_VERSION:INTERNAL=17 -//Patch version of cmake used to create the current loaded cache -CMAKE_CACHE_PATCH_VERSION:INTERNAL=5 -//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE -CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1 -//Path to CMake executable. -CMAKE_COMMAND:INTERNAL=/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -//Path to cpack program executable. -CMAKE_CPACK_COMMAND:INTERNAL=/opt/clion-2020.3.2/bin/cmake/linux/bin/cpack -//Path to ctest program executable. -CMAKE_CTEST_COMMAND:INTERNAL=/opt/clion-2020.3.2/bin/cmake/linux/bin/ctest -//ADVANCED property for variable: CMAKE_CXX_COMPILER -CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR -CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB -CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_CXX_FLAGS -CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG -CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL -CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE -CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO -CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_COMPILER -CMAKE_C_COMPILER-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_COMPILER_AR -CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB -CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_FLAGS -CMAKE_C_FLAGS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG -CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL -CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE -CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO -CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_DLLTOOL -CMAKE_DLLTOOL-ADVANCED:INTERNAL=1 -//Executable file format -CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF -//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS -CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG -CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL -CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE -CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO -CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS -CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1 -//Name of external makefile project generator. -CMAKE_EXTRA_GENERATOR:INTERNAL=CodeBlocks -//CXX compiler system defined macros -CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS:INTERNAL=__STDC__;1;__STDC_VERSION__;201112L;__STDC_UTF_16__;1;__STDC_UTF_32__;1;__STDC_HOSTED__;1;__GNUC__;7;__GNUC_MINOR__;5;__GNUC_PATCHLEVEL__;0;__VERSION__;"7.5.0";__ATOMIC_RELAXED;0;__ATOMIC_SEQ_CST;5;__ATOMIC_ACQUIRE;2;__ATOMIC_RELEASE;3;__ATOMIC_ACQ_REL;4;__ATOMIC_CONSUME;1;__pic__;2;__PIC__;2;__pie__;2;__PIE__;2;__FINITE_MATH_ONLY__;0;_LP64;1;__LP64__;1;__SIZEOF_INT__;4;__SIZEOF_LONG__;8;__SIZEOF_LONG_LONG__;8;__SIZEOF_SHORT__;2;__SIZEOF_FLOAT__;4;__SIZEOF_DOUBLE__;8;__SIZEOF_LONG_DOUBLE__;16;__SIZEOF_SIZE_T__;8;__CHAR_BIT__;8;__BIGGEST_ALIGNMENT__;16;__ORDER_LITTLE_ENDIAN__;1234;__ORDER_BIG_ENDIAN__;4321;__ORDER_PDP_ENDIAN__;3412;__BYTE_ORDER__;__ORDER_LITTLE_ENDIAN__;__FLOAT_WORD_ORDER__;__ORDER_LITTLE_ENDIAN__;__SIZEOF_POINTER__;8;__SIZE_TYPE__;long unsigned int;__PTRDIFF_TYPE__;long int;__WCHAR_TYPE__;int;__WINT_TYPE__;unsigned int;__INTMAX_TYPE__;long int;__UINTMAX_TYPE__;long unsigned int;__CHAR16_TYPE__;short unsigned int;__CHAR32_TYPE__;unsigned int;__SIG_ATOMIC_TYPE__;int;__INT8_TYPE__;signed char;__INT16_TYPE__;short int;__INT32_TYPE__;int;__INT64_TYPE__;long int;__UINT8_TYPE__;unsigned char;__UINT16_TYPE__;short unsigned int;__UINT32_TYPE__;unsigned int;__UINT64_TYPE__;long unsigned int;__INT_LEAST8_TYPE__;signed char;__INT_LEAST16_TYPE__;short int;__INT_LEAST32_TYPE__;int;__INT_LEAST64_TYPE__;long int;__UINT_LEAST8_TYPE__;unsigned char;__UINT_LEAST16_TYPE__;short unsigned int;__UINT_LEAST32_TYPE__;unsigned int;__UINT_LEAST64_TYPE__;long unsigned int;__INT_FAST8_TYPE__;signed char;__INT_FAST16_TYPE__;long int;__INT_FAST32_TYPE__;long int;__INT_FAST64_TYPE__;long int;__UINT_FAST8_TYPE__;unsigned char;__UINT_FAST16_TYPE__;long unsigned int;__UINT_FAST32_TYPE__;long unsigned int;__UINT_FAST64_TYPE__;long unsigned int;__INTPTR_TYPE__;long int;__UINTPTR_TYPE__;long unsigned int;__has_include(STR);__has_include__(STR);__has_include_next(STR);__has_include_next__(STR);__GXX_ABI_VERSION;1011;__SCHAR_MAX__;0x7f;__SHRT_MAX__;0x7fff;__INT_MAX__;0x7fffffff;__LONG_MAX__;0x7fffffffffffffffL;__LONG_LONG_MAX__;0x7fffffffffffffffLL;__WCHAR_MAX__;0x7fffffff;__WCHAR_MIN__;(-__WCHAR_MAX__ - 1);__WINT_MAX__;0xffffffffU;__WINT_MIN__;0U;__PTRDIFF_MAX__;0x7fffffffffffffffL;__SIZE_MAX__;0xffffffffffffffffUL;__SCHAR_WIDTH__;8;__SHRT_WIDTH__;16;__INT_WIDTH__;32;__LONG_WIDTH__;64;__LONG_LONG_WIDTH__;64;__WCHAR_WIDTH__;32;__WINT_WIDTH__;32;__PTRDIFF_WIDTH__;64;__SIZE_WIDTH__;64;__INTMAX_MAX__;0x7fffffffffffffffL;__INTMAX_C(c);c ## L;__UINTMAX_MAX__;0xffffffffffffffffUL;__UINTMAX_C(c);c ## UL;__INTMAX_WIDTH__;64;__SIG_ATOMIC_MAX__;0x7fffffff;__SIG_ATOMIC_MIN__;(-__SIG_ATOMIC_MAX__ - 1);__SIG_ATOMIC_WIDTH__;32;__INT8_MAX__;0x7f;__INT16_MAX__;0x7fff;__INT32_MAX__;0x7fffffff;__INT64_MAX__;0x7fffffffffffffffL;__UINT8_MAX__;0xff;__UINT16_MAX__;0xffff;__UINT32_MAX__;0xffffffffU;__UINT64_MAX__;0xffffffffffffffffUL;__INT_LEAST8_MAX__;0x7f;__INT8_C(c);c;__INT_LEAST8_WIDTH__;8;__INT_LEAST16_MAX__;0x7fff;__INT16_C(c);c;__INT_LEAST16_WIDTH__;16;__INT_LEAST32_MAX__;0x7fffffff;__INT32_C(c);c;__INT_LEAST32_WIDTH__;32;__INT_LEAST64_MAX__;0x7fffffffffffffffL;__INT64_C(c);c ## L;__INT_LEAST64_WIDTH__;64;__UINT_LEAST8_MAX__;0xff;__UINT8_C(c);c;__UINT_LEAST16_MAX__;0xffff;__UINT16_C(c);c;__UINT_LEAST32_MAX__;0xffffffffU;__UINT32_C(c);c ## U;__UINT_LEAST64_MAX__;0xffffffffffffffffUL;__UINT64_C(c);c ## UL;__INT_FAST8_MAX__;0x7f;__INT_FAST8_WIDTH__;8;__INT_FAST16_MAX__;0x7fffffffffffffffL;__INT_FAST16_WIDTH__;64;__INT_FAST32_MAX__;0x7fffffffffffffffL;__INT_FAST32_WIDTH__;64;__INT_FAST64_MAX__;0x7fffffffffffffffL;__INT_FAST64_WIDTH__;64;__UINT_FAST8_MAX__;0xff;__UINT_FAST16_MAX__;0xffffffffffffffffUL;__UINT_FAST32_MAX__;0xffffffffffffffffUL;__UINT_FAST64_MAX__;0xffffffffffffffffUL;__INTPTR_MAX__;0x7fffffffffffffffL;__INTPTR_WIDTH__;64;__UINTPTR_MAX__;0xffffffffffffffffUL;__GCC_IEC_559;2;__GCC_IEC_559_COMPLEX;2;__FLT_EVAL_METHOD__;0;__FLT_EVAL_METHOD_TS_18661_3__;0;__DEC_EVAL_METHOD__;2;__FLT_RADIX__;2;__FLT_MANT_DIG__;24;__FLT_DIG__;6;__FLT_MIN_EXP__;(-125);__FLT_MIN_10_EXP__;(-37);__FLT_MAX_EXP__;128;__FLT_MAX_10_EXP__;38;__FLT_DECIMAL_DIG__;9;__FLT_MAX__;3.40282346638528859811704183484516925e+38F;__FLT_MIN__;1.17549435082228750796873653722224568e-38F;__FLT_EPSILON__;1.19209289550781250000000000000000000e-7F;__FLT_DENORM_MIN__;1.40129846432481707092372958328991613e-45F;__FLT_HAS_DENORM__;1;__FLT_HAS_INFINITY__;1;__FLT_HAS_QUIET_NAN__;1;__DBL_MANT_DIG__;53;__DBL_DIG__;15;__DBL_MIN_EXP__;(-1021);__DBL_MIN_10_EXP__;(-307);__DBL_MAX_EXP__;1024;__DBL_MAX_10_EXP__;308;__DBL_DECIMAL_DIG__;17;__DBL_MAX__;((double)1.79769313486231570814527423731704357e+308L);__DBL_MIN__;((double)2.22507385850720138309023271733240406e-308L);__DBL_EPSILON__;((double)2.22044604925031308084726333618164062e-16L);__DBL_DENORM_MIN__;((double)4.94065645841246544176568792868221372e-324L);__DBL_HAS_DENORM__;1;__DBL_HAS_INFINITY__;1;__DBL_HAS_QUIET_NAN__;1;__LDBL_MANT_DIG__;64;__LDBL_DIG__;18;__LDBL_MIN_EXP__;(-16381);__LDBL_MIN_10_EXP__;(-4931);__LDBL_MAX_EXP__;16384;__LDBL_MAX_10_EXP__;4932;__DECIMAL_DIG__;21;__LDBL_DECIMAL_DIG__;21;__LDBL_MAX__;1.18973149535723176502126385303097021e+4932L;__LDBL_MIN__;3.36210314311209350626267781732175260e-4932L;__LDBL_EPSILON__;1.08420217248550443400745280086994171e-19L;__LDBL_DENORM_MIN__;3.64519953188247460252840593361941982e-4951L;__LDBL_HAS_DENORM__;1;__LDBL_HAS_INFINITY__;1;__LDBL_HAS_QUIET_NAN__;1;__FLT32_MANT_DIG__;24;__FLT32_DIG__;6;__FLT32_MIN_EXP__;(-125);__FLT32_MIN_10_EXP__;(-37);__FLT32_MAX_EXP__;128;__FLT32_MAX_10_EXP__;38;__FLT32_DECIMAL_DIG__;9;__FLT32_MAX__;3.40282346638528859811704183484516925e+38F32;__FLT32_MIN__;1.17549435082228750796873653722224568e-38F32;__FLT32_EPSILON__;1.19209289550781250000000000000000000e-7F32;__FLT32_DENORM_MIN__;1.40129846432481707092372958328991613e-45F32;__FLT32_HAS_DENORM__;1;__FLT32_HAS_INFINITY__;1;__FLT32_HAS_QUIET_NAN__;1;__FLT64_MANT_DIG__;53;__FLT64_DIG__;15;__FLT64_MIN_EXP__;(-1021);__FLT64_MIN_10_EXP__;(-307);__FLT64_MAX_EXP__;1024;__FLT64_MAX_10_EXP__;308;__FLT64_DECIMAL_DIG__;17;__FLT64_MAX__;1.79769313486231570814527423731704357e+308F64;__FLT64_MIN__;2.22507385850720138309023271733240406e-308F64;__FLT64_EPSILON__;2.22044604925031308084726333618164062e-16F64;__FLT64_DENORM_MIN__;4.94065645841246544176568792868221372e-324F64;__FLT64_HAS_DENORM__;1;__FLT64_HAS_INFINITY__;1;__FLT64_HAS_QUIET_NAN__;1;__FLT128_MANT_DIG__;113;__FLT128_DIG__;33;__FLT128_MIN_EXP__;(-16381);__FLT128_MIN_10_EXP__;(-4931);__FLT128_MAX_EXP__;16384;__FLT128_MAX_10_EXP__;4932;__FLT128_DECIMAL_DIG__;36;__FLT128_MAX__;1.18973149535723176508575932662800702e+4932F128;__FLT128_MIN__;3.36210314311209350626267781732175260e-4932F128;__FLT128_EPSILON__;1.92592994438723585305597794258492732e-34F128;__FLT128_DENORM_MIN__;6.47517511943802511092443895822764655e-4966F128;__FLT128_HAS_DENORM__;1;__FLT128_HAS_INFINITY__;1;__FLT128_HAS_QUIET_NAN__;1;__FLT32X_MANT_DIG__;53;__FLT32X_DIG__;15;__FLT32X_MIN_EXP__;(-1021);__FLT32X_MIN_10_EXP__;(-307);__FLT32X_MAX_EXP__;1024;__FLT32X_MAX_10_EXP__;308;__FLT32X_DECIMAL_DIG__;17;__FLT32X_MAX__;1.79769313486231570814527423731704357e+308F32x;__FLT32X_MIN__;2.22507385850720138309023271733240406e-308F32x;__FLT32X_EPSILON__;2.22044604925031308084726333618164062e-16F32x;__FLT32X_DENORM_MIN__;4.94065645841246544176568792868221372e-324F32x;__FLT32X_HAS_DENORM__;1;__FLT32X_HAS_INFINITY__;1;__FLT32X_HAS_QUIET_NAN__;1;__FLT64X_MANT_DIG__;64;__FLT64X_DIG__;18;__FLT64X_MIN_EXP__;(-16381);__FLT64X_MIN_10_EXP__;(-4931);__FLT64X_MAX_EXP__;16384;__FLT64X_MAX_10_EXP__;4932;__FLT64X_DECIMAL_DIG__;21;__FLT64X_MAX__;1.18973149535723176502126385303097021e+4932F64x;__FLT64X_MIN__;3.36210314311209350626267781732175260e-4932F64x;__FLT64X_EPSILON__;1.08420217248550443400745280086994171e-19F64x;__FLT64X_DENORM_MIN__;3.64519953188247460252840593361941982e-4951F64x;__FLT64X_HAS_DENORM__;1;__FLT64X_HAS_INFINITY__;1;__FLT64X_HAS_QUIET_NAN__;1;__DEC32_MANT_DIG__;7;__DEC32_MIN_EXP__;(-94);__DEC32_MAX_EXP__;97;__DEC32_MIN__;1E-95DF;__DEC32_MAX__;9.999999E96DF;__DEC32_EPSILON__;1E-6DF;__DEC32_SUBNORMAL_MIN__;0.000001E-95DF;__DEC64_MANT_DIG__;16;__DEC64_MIN_EXP__;(-382);__DEC64_MAX_EXP__;385;__DEC64_MIN__;1E-383DD;__DEC64_MAX__;9.999999999999999E384DD;__DEC64_EPSILON__;1E-15DD;__DEC64_SUBNORMAL_MIN__;0.000000000000001E-383DD;__DEC128_MANT_DIG__;34;__DEC128_MIN_EXP__;(-6142);__DEC128_MAX_EXP__;6145;__DEC128_MIN__;1E-6143DL;__DEC128_MAX__;9.999999999999999999999999999999999E6144DL;__DEC128_EPSILON__;1E-33DL;__DEC128_SUBNORMAL_MIN__;0.000000000000000000000000000000001E-6143DL;__REGISTER_PREFIX__; ;__USER_LABEL_PREFIX__; ;__GNUC_STDC_INLINE__;1;__NO_INLINE__;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8;1;__GCC_ATOMIC_BOOL_LOCK_FREE;2;__GCC_ATOMIC_CHAR_LOCK_FREE;2;__GCC_ATOMIC_CHAR16_T_LOCK_FREE;2;__GCC_ATOMIC_CHAR32_T_LOCK_FREE;2;__GCC_ATOMIC_WCHAR_T_LOCK_FREE;2;__GCC_ATOMIC_SHORT_LOCK_FREE;2;__GCC_ATOMIC_INT_LOCK_FREE;2;__GCC_ATOMIC_LONG_LOCK_FREE;2;__GCC_ATOMIC_LLONG_LOCK_FREE;2;__GCC_ATOMIC_TEST_AND_SET_TRUEVAL;1;__GCC_ATOMIC_POINTER_LOCK_FREE;2;__GCC_HAVE_DWARF2_CFI_ASM;1;__PRAGMA_REDEFINE_EXTNAME;1;__SSP_STRONG__;3;__SIZEOF_INT128__;16;__SIZEOF_WCHAR_T__;4;__SIZEOF_WINT_T__;4;__SIZEOF_PTRDIFF_T__;8;__amd64;1;__amd64__;1;__x86_64;1;__x86_64__;1;__SIZEOF_FLOAT80__;16;__SIZEOF_FLOAT128__;16;__ATOMIC_HLE_ACQUIRE;65536;__ATOMIC_HLE_RELEASE;131072;__GCC_ASM_FLAG_OUTPUTS__;1;__k8;1;__k8__;1;__code_model_small__;1;__MMX__;1;__SSE__;1;__SSE2__;1;__FXSR__;1;__SSE_MATH__;1;__SSE2_MATH__;1;__SEG_FS;1;__SEG_GS;1;__gnu_linux__;1;__linux;1;__linux__;1;linux;1;__unix;1;__unix__;1;unix;1;__ELF__;1;__DECIMAL_BID_FORMAT__;1;_STDC_PREDEF_H;1;__STDC_IEC_559__;1;__STDC_IEC_559_COMPLEX__;1;__STDC_ISO_10646__;201706L;__STDC_NO_THREADS__;1;__STDC__;1;__cplusplus;201402L;__STDC_UTF_16__;1;__STDC_UTF_32__;1;__STDC_HOSTED__;1;__GNUC__;7;__GNUC_MINOR__;5;__GNUC_PATCHLEVEL__;0;__VERSION__;"7.5.0";__ATOMIC_RELAXED;0;__ATOMIC_SEQ_CST;5;__ATOMIC_ACQUIRE;2;__ATOMIC_RELEASE;3;__ATOMIC_ACQ_REL;4;__ATOMIC_CONSUME;1;__pic__;2;__PIC__;2;__pie__;2;__PIE__;2;__FINITE_MATH_ONLY__;0;_LP64;1;__LP64__;1;__SIZEOF_INT__;4;__SIZEOF_LONG__;8;__SIZEOF_LONG_LONG__;8;__SIZEOF_SHORT__;2;__SIZEOF_FLOAT__;4;__SIZEOF_DOUBLE__;8;__SIZEOF_LONG_DOUBLE__;16;__SIZEOF_SIZE_T__;8;__CHAR_BIT__;8;__BIGGEST_ALIGNMENT__;16;__ORDER_LITTLE_ENDIAN__;1234;__ORDER_BIG_ENDIAN__;4321;__ORDER_PDP_ENDIAN__;3412;__BYTE_ORDER__;__ORDER_LITTLE_ENDIAN__;__FLOAT_WORD_ORDER__;__ORDER_LITTLE_ENDIAN__;__SIZEOF_POINTER__;8;__GNUG__;7;__SIZE_TYPE__;long unsigned int;__PTRDIFF_TYPE__;long int;__WCHAR_TYPE__;int;__WINT_TYPE__;unsigned int;__INTMAX_TYPE__;long int;__UINTMAX_TYPE__;long unsigned int;__CHAR16_TYPE__;short unsigned int;__CHAR32_TYPE__;unsigned int;__SIG_ATOMIC_TYPE__;int;__INT8_TYPE__;signed char;__INT16_TYPE__;short int;__INT32_TYPE__;int;__INT64_TYPE__;long int;__UINT8_TYPE__;unsigned char;__UINT16_TYPE__;short unsigned int;__UINT32_TYPE__;unsigned int;__UINT64_TYPE__;long unsigned int;__INT_LEAST8_TYPE__;signed char;__INT_LEAST16_TYPE__;short int;__INT_LEAST32_TYPE__;int;__INT_LEAST64_TYPE__;long int;__UINT_LEAST8_TYPE__;unsigned char;__UINT_LEAST16_TYPE__;short unsigned int;__UINT_LEAST32_TYPE__;unsigned int;__UINT_LEAST64_TYPE__;long unsigned int;__INT_FAST8_TYPE__;signed char;__INT_FAST16_TYPE__;long int;__INT_FAST32_TYPE__;long int;__INT_FAST64_TYPE__;long int;__UINT_FAST8_TYPE__;unsigned char;__UINT_FAST16_TYPE__;long unsigned int;__UINT_FAST32_TYPE__;long unsigned int;__UINT_FAST64_TYPE__;long unsigned int;__INTPTR_TYPE__;long int;__UINTPTR_TYPE__;long unsigned int;__has_include(STR);__has_include__(STR);__has_include_next(STR);__has_include_next__(STR);__GXX_WEAK__;1;__DEPRECATED;1;__GXX_RTTI;1;__cpp_rtti;199711;__GXX_EXPERIMENTAL_CXX0X__;1;__cpp_binary_literals;201304;__cpp_hex_float;201603;__cpp_runtime_arrays;198712;__cpp_unicode_characters;200704;__cpp_raw_strings;200710;__cpp_unicode_literals;200710;__cpp_user_defined_literals;200809;__cpp_lambdas;200907;__cpp_range_based_for;200907;__cpp_static_assert;200410;__cpp_decltype;200707;__cpp_attributes;200809;__cpp_rvalue_reference;200610;__cpp_rvalue_references;200610;__cpp_variadic_templates;200704;__cpp_initializer_lists;200806;__cpp_delegating_constructors;200604;__cpp_nsdmi;200809;__cpp_inheriting_constructors;201511;__cpp_ref_qualifiers;200710;__cpp_alias_templates;200704;__cpp_return_type_deduction;201304;__cpp_init_captures;201304;__cpp_generic_lambdas;201304;__cpp_constexpr;201304;__cpp_decltype_auto;201304;__cpp_aggregate_nsdmi;201304;__cpp_variable_templates;201304;__cpp_digit_separators;201309;__cpp_sized_deallocation;201309;__cpp_threadsafe_static_init;200806;__EXCEPTIONS;1;__cpp_exceptions;199711;__GXX_ABI_VERSION;1011;__SCHAR_MAX__;0x7f;__SHRT_MAX__;0x7fff;__INT_MAX__;0x7fffffff;__LONG_MAX__;0x7fffffffffffffffL;__LONG_LONG_MAX__;0x7fffffffffffffffLL;__WCHAR_MAX__;0x7fffffff;__WCHAR_MIN__;(-__WCHAR_MAX__ - 1);__WINT_MAX__;0xffffffffU;__WINT_MIN__;0U;__PTRDIFF_MAX__;0x7fffffffffffffffL;__SIZE_MAX__;0xffffffffffffffffUL;__SCHAR_WIDTH__;8;__SHRT_WIDTH__;16;__INT_WIDTH__;32;__LONG_WIDTH__;64;__LONG_LONG_WIDTH__;64;__WCHAR_WIDTH__;32;__WINT_WIDTH__;32;__PTRDIFF_WIDTH__;64;__SIZE_WIDTH__;64;__GLIBCXX_TYPE_INT_N_0;__int128;__GLIBCXX_BITSIZE_INT_N_0;128;__INTMAX_MAX__;0x7fffffffffffffffL;__INTMAX_C(c);c ## L;__UINTMAX_MAX__;0xffffffffffffffffUL;__UINTMAX_C(c);c ## UL;__INTMAX_WIDTH__;64;__SIG_ATOMIC_MAX__;0x7fffffff;__SIG_ATOMIC_MIN__;(-__SIG_ATOMIC_MAX__ - 1);__SIG_ATOMIC_WIDTH__;32;__INT8_MAX__;0x7f;__INT16_MAX__;0x7fff;__INT32_MAX__;0x7fffffff;__INT64_MAX__;0x7fffffffffffffffL;__UINT8_MAX__;0xff;__UINT16_MAX__;0xffff;__UINT32_MAX__;0xffffffffU;__UINT64_MAX__;0xffffffffffffffffUL;__INT_LEAST8_MAX__;0x7f;__INT8_C(c);c;__INT_LEAST8_WIDTH__;8;__INT_LEAST16_MAX__;0x7fff;__INT16_C(c);c;__INT_LEAST16_WIDTH__;16;__INT_LEAST32_MAX__;0x7fffffff;__INT32_C(c);c;__INT_LEAST32_WIDTH__;32;__INT_LEAST64_MAX__;0x7fffffffffffffffL;__INT64_C(c);c ## L;__INT_LEAST64_WIDTH__;64;__UINT_LEAST8_MAX__;0xff;__UINT8_C(c);c;__UINT_LEAST16_MAX__;0xffff;__UINT16_C(c);c;__UINT_LEAST32_MAX__;0xffffffffU;__UINT32_C(c);c ## U;__UINT_LEAST64_MAX__;0xffffffffffffffffUL;__UINT64_C(c);c ## UL;__INT_FAST8_MAX__;0x7f;__INT_FAST8_WIDTH__;8;__INT_FAST16_MAX__;0x7fffffffffffffffL;__INT_FAST16_WIDTH__;64;__INT_FAST32_MAX__;0x7fffffffffffffffL;__INT_FAST32_WIDTH__;64;__INT_FAST64_MAX__;0x7fffffffffffffffL;__INT_FAST64_WIDTH__;64;__UINT_FAST8_MAX__;0xff;__UINT_FAST16_MAX__;0xffffffffffffffffUL;__UINT_FAST32_MAX__;0xffffffffffffffffUL;__UINT_FAST64_MAX__;0xffffffffffffffffUL;__INTPTR_MAX__;0x7fffffffffffffffL;__INTPTR_WIDTH__;64;__UINTPTR_MAX__;0xffffffffffffffffUL;__GCC_IEC_559;2;__GCC_IEC_559_COMPLEX;2;__FLT_EVAL_METHOD__;0;__FLT_EVAL_METHOD_TS_18661_3__;0;__DEC_EVAL_METHOD__;2;__FLT_RADIX__;2;__FLT_MANT_DIG__;24;__FLT_DIG__;6;__FLT_MIN_EXP__;(-125);__FLT_MIN_10_EXP__;(-37);__FLT_MAX_EXP__;128;__FLT_MAX_10_EXP__;38;__FLT_DECIMAL_DIG__;9;__FLT_MAX__;3.40282346638528859811704183484516925e+38F;__FLT_MIN__;1.17549435082228750796873653722224568e-38F;__FLT_EPSILON__;1.19209289550781250000000000000000000e-7F;__FLT_DENORM_MIN__;1.40129846432481707092372958328991613e-45F;__FLT_HAS_DENORM__;1;__FLT_HAS_INFINITY__;1;__FLT_HAS_QUIET_NAN__;1;__DBL_MANT_DIG__;53;__DBL_DIG__;15;__DBL_MIN_EXP__;(-1021);__DBL_MIN_10_EXP__;(-307);__DBL_MAX_EXP__;1024;__DBL_MAX_10_EXP__;308;__DBL_DECIMAL_DIG__;17;__DBL_MAX__;double(1.79769313486231570814527423731704357e+308L);__DBL_MIN__;double(2.22507385850720138309023271733240406e-308L);__DBL_EPSILON__;double(2.22044604925031308084726333618164062e-16L);__DBL_DENORM_MIN__;double(4.94065645841246544176568792868221372e-324L);__DBL_HAS_DENORM__;1;__DBL_HAS_INFINITY__;1;__DBL_HAS_QUIET_NAN__;1;__LDBL_MANT_DIG__;64;__LDBL_DIG__;18;__LDBL_MIN_EXP__;(-16381);__LDBL_MIN_10_EXP__;(-4931);__LDBL_MAX_EXP__;16384;__LDBL_MAX_10_EXP__;4932;__DECIMAL_DIG__;21;__LDBL_DECIMAL_DIG__;21;__LDBL_MAX__;1.18973149535723176502126385303097021e+4932L;__LDBL_MIN__;3.36210314311209350626267781732175260e-4932L;__LDBL_EPSILON__;1.08420217248550443400745280086994171e-19L;__LDBL_DENORM_MIN__;3.64519953188247460252840593361941982e-4951L;__LDBL_HAS_DENORM__;1;__LDBL_HAS_INFINITY__;1;__LDBL_HAS_QUIET_NAN__;1;__FLT32_MANT_DIG__;24;__FLT32_DIG__;6;__FLT32_MIN_EXP__;(-125);__FLT32_MIN_10_EXP__;(-37);__FLT32_MAX_EXP__;128;__FLT32_MAX_10_EXP__;38;__FLT32_DECIMAL_DIG__;9;__FLT32_MAX__;3.40282346638528859811704183484516925e+38F32;__FLT32_MIN__;1.17549435082228750796873653722224568e-38F32;__FLT32_EPSILON__;1.19209289550781250000000000000000000e-7F32;__FLT32_DENORM_MIN__;1.40129846432481707092372958328991613e-45F32;__FLT32_HAS_DENORM__;1;__FLT32_HAS_INFINITY__;1;__FLT32_HAS_QUIET_NAN__;1;__FLT64_MANT_DIG__;53;__FLT64_DIG__;15;__FLT64_MIN_EXP__;(-1021);__FLT64_MIN_10_EXP__;(-307);__FLT64_MAX_EXP__;1024;__FLT64_MAX_10_EXP__;308;__FLT64_DECIMAL_DIG__;17;__FLT64_MAX__;1.79769313486231570814527423731704357e+308F64;__FLT64_MIN__;2.22507385850720138309023271733240406e-308F64;__FLT64_EPSILON__;2.22044604925031308084726333618164062e-16F64;__FLT64_DENORM_MIN__;4.94065645841246544176568792868221372e-324F64;__FLT64_HAS_DENORM__;1;__FLT64_HAS_INFINITY__;1;__FLT64_HAS_QUIET_NAN__;1;__FLT128_MANT_DIG__;113;__FLT128_DIG__;33;__FLT128_MIN_EXP__;(-16381);__FLT128_MIN_10_EXP__;(-4931);__FLT128_MAX_EXP__;16384;__FLT128_MAX_10_EXP__;4932;__FLT128_DECIMAL_DIG__;36;__FLT128_MAX__;1.18973149535723176508575932662800702e+4932F128;__FLT128_MIN__;3.36210314311209350626267781732175260e-4932F128;__FLT128_EPSILON__;1.92592994438723585305597794258492732e-34F128;__FLT128_DENORM_MIN__;6.47517511943802511092443895822764655e-4966F128;__FLT128_HAS_DENORM__;1;__FLT128_HAS_INFINITY__;1;__FLT128_HAS_QUIET_NAN__;1;__FLT32X_MANT_DIG__;53;__FLT32X_DIG__;15;__FLT32X_MIN_EXP__;(-1021);__FLT32X_MIN_10_EXP__;(-307);__FLT32X_MAX_EXP__;1024;__FLT32X_MAX_10_EXP__;308;__FLT32X_DECIMAL_DIG__;17;__FLT32X_MAX__;1.79769313486231570814527423731704357e+308F32x;__FLT32X_MIN__;2.22507385850720138309023271733240406e-308F32x;__FLT32X_EPSILON__;2.22044604925031308084726333618164062e-16F32x;__FLT32X_DENORM_MIN__;4.94065645841246544176568792868221372e-324F32x;__FLT32X_HAS_DENORM__;1;__FLT32X_HAS_INFINITY__;1;__FLT32X_HAS_QUIET_NAN__;1;__FLT64X_MANT_DIG__;64;__FLT64X_DIG__;18;__FLT64X_MIN_EXP__;(-16381);__FLT64X_MIN_10_EXP__;(-4931);__FLT64X_MAX_EXP__;16384;__FLT64X_MAX_10_EXP__;4932;__FLT64X_DECIMAL_DIG__;21;__FLT64X_MAX__;1.18973149535723176502126385303097021e+4932F64x;__FLT64X_MIN__;3.36210314311209350626267781732175260e-4932F64x;__FLT64X_EPSILON__;1.08420217248550443400745280086994171e-19F64x;__FLT64X_DENORM_MIN__;3.64519953188247460252840593361941982e-4951F64x;__FLT64X_HAS_DENORM__;1;__FLT64X_HAS_INFINITY__;1;__FLT64X_HAS_QUIET_NAN__;1;__DEC32_MANT_DIG__;7;__DEC32_MIN_EXP__;(-94);__DEC32_MAX_EXP__;97;__DEC32_MIN__;1E-95DF;__DEC32_MAX__;9.999999E96DF;__DEC32_EPSILON__;1E-6DF;__DEC32_SUBNORMAL_MIN__;0.000001E-95DF;__DEC64_MANT_DIG__;16;__DEC64_MIN_EXP__;(-382);__DEC64_MAX_EXP__;385;__DEC64_MIN__;1E-383DD;__DEC64_MAX__;9.999999999999999E384DD;__DEC64_EPSILON__;1E-15DD;__DEC64_SUBNORMAL_MIN__;0.000000000000001E-383DD;__DEC128_MANT_DIG__;34;__DEC128_MIN_EXP__;(-6142);__DEC128_MAX_EXP__;6145;__DEC128_MIN__;1E-6143DL;__DEC128_MAX__;9.999999999999999999999999999999999E6144DL;__DEC128_EPSILON__;1E-33DL;__DEC128_SUBNORMAL_MIN__;0.000000000000000000000000000000001E-6143DL;__REGISTER_PREFIX__; ;__USER_LABEL_PREFIX__; ;__GNUC_STDC_INLINE__;1;__NO_INLINE__;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8;1;__GCC_ATOMIC_BOOL_LOCK_FREE;2;__GCC_ATOMIC_CHAR_LOCK_FREE;2;__GCC_ATOMIC_CHAR16_T_LOCK_FREE;2;__GCC_ATOMIC_CHAR32_T_LOCK_FREE;2;__GCC_ATOMIC_WCHAR_T_LOCK_FREE;2;__GCC_ATOMIC_SHORT_LOCK_FREE;2;__GCC_ATOMIC_INT_LOCK_FREE;2;__GCC_ATOMIC_LONG_LOCK_FREE;2;__GCC_ATOMIC_LLONG_LOCK_FREE;2;__GCC_ATOMIC_TEST_AND_SET_TRUEVAL;1;__GCC_ATOMIC_POINTER_LOCK_FREE;2;__GCC_HAVE_DWARF2_CFI_ASM;1;__PRAGMA_REDEFINE_EXTNAME;1;__SSP_STRONG__;3;__SIZEOF_INT128__;16;__SIZEOF_WCHAR_T__;4;__SIZEOF_WINT_T__;4;__SIZEOF_PTRDIFF_T__;8;__amd64;1;__amd64__;1;__x86_64;1;__x86_64__;1;__SIZEOF_FLOAT80__;16;__SIZEOF_FLOAT128__;16;__ATOMIC_HLE_ACQUIRE;65536;__ATOMIC_HLE_RELEASE;131072;__GCC_ASM_FLAG_OUTPUTS__;1;__k8;1;__k8__;1;__code_model_small__;1;__MMX__;1;__SSE__;1;__SSE2__;1;__FXSR__;1;__SSE_MATH__;1;__SSE2_MATH__;1;__SEG_FS;1;__SEG_GS;1;__gnu_linux__;1;__linux;1;__linux__;1;linux;1;__unix;1;__unix__;1;unix;1;__ELF__;1;__DECIMAL_BID_FORMAT__;1;_GNU_SOURCE;1;_STDC_PREDEF_H;1;__STDC_IEC_559__;1;__STDC_IEC_559_COMPLEX__;1;__STDC_ISO_10646__;201706L;__STDC_NO_THREADS__;1 -//CXX compiler system include directories -CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS:INTERNAL=/usr/include/c++/7;/usr/include/x86_64-linux-gnu/c++/7;/usr/include/c++/7/backward;/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include -//C compiler system defined macros -CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS:INTERNAL=__STDC__;1;__STDC_VERSION__;201112L;__STDC_UTF_16__;1;__STDC_UTF_32__;1;__STDC_HOSTED__;1;__GNUC__;7;__GNUC_MINOR__;5;__GNUC_PATCHLEVEL__;0;__VERSION__;"7.5.0";__ATOMIC_RELAXED;0;__ATOMIC_SEQ_CST;5;__ATOMIC_ACQUIRE;2;__ATOMIC_RELEASE;3;__ATOMIC_ACQ_REL;4;__ATOMIC_CONSUME;1;__pic__;2;__PIC__;2;__pie__;2;__PIE__;2;__FINITE_MATH_ONLY__;0;_LP64;1;__LP64__;1;__SIZEOF_INT__;4;__SIZEOF_LONG__;8;__SIZEOF_LONG_LONG__;8;__SIZEOF_SHORT__;2;__SIZEOF_FLOAT__;4;__SIZEOF_DOUBLE__;8;__SIZEOF_LONG_DOUBLE__;16;__SIZEOF_SIZE_T__;8;__CHAR_BIT__;8;__BIGGEST_ALIGNMENT__;16;__ORDER_LITTLE_ENDIAN__;1234;__ORDER_BIG_ENDIAN__;4321;__ORDER_PDP_ENDIAN__;3412;__BYTE_ORDER__;__ORDER_LITTLE_ENDIAN__;__FLOAT_WORD_ORDER__;__ORDER_LITTLE_ENDIAN__;__SIZEOF_POINTER__;8;__SIZE_TYPE__;long unsigned int;__PTRDIFF_TYPE__;long int;__WCHAR_TYPE__;int;__WINT_TYPE__;unsigned int;__INTMAX_TYPE__;long int;__UINTMAX_TYPE__;long unsigned int;__CHAR16_TYPE__;short unsigned int;__CHAR32_TYPE__;unsigned int;__SIG_ATOMIC_TYPE__;int;__INT8_TYPE__;signed char;__INT16_TYPE__;short int;__INT32_TYPE__;int;__INT64_TYPE__;long int;__UINT8_TYPE__;unsigned char;__UINT16_TYPE__;short unsigned int;__UINT32_TYPE__;unsigned int;__UINT64_TYPE__;long unsigned int;__INT_LEAST8_TYPE__;signed char;__INT_LEAST16_TYPE__;short int;__INT_LEAST32_TYPE__;int;__INT_LEAST64_TYPE__;long int;__UINT_LEAST8_TYPE__;unsigned char;__UINT_LEAST16_TYPE__;short unsigned int;__UINT_LEAST32_TYPE__;unsigned int;__UINT_LEAST64_TYPE__;long unsigned int;__INT_FAST8_TYPE__;signed char;__INT_FAST16_TYPE__;long int;__INT_FAST32_TYPE__;long int;__INT_FAST64_TYPE__;long int;__UINT_FAST8_TYPE__;unsigned char;__UINT_FAST16_TYPE__;long unsigned int;__UINT_FAST32_TYPE__;long unsigned int;__UINT_FAST64_TYPE__;long unsigned int;__INTPTR_TYPE__;long int;__UINTPTR_TYPE__;long unsigned int;__has_include(STR);__has_include__(STR);__has_include_next(STR);__has_include_next__(STR);__GXX_ABI_VERSION;1011;__SCHAR_MAX__;0x7f;__SHRT_MAX__;0x7fff;__INT_MAX__;0x7fffffff;__LONG_MAX__;0x7fffffffffffffffL;__LONG_LONG_MAX__;0x7fffffffffffffffLL;__WCHAR_MAX__;0x7fffffff;__WCHAR_MIN__;(-__WCHAR_MAX__ - 1);__WINT_MAX__;0xffffffffU;__WINT_MIN__;0U;__PTRDIFF_MAX__;0x7fffffffffffffffL;__SIZE_MAX__;0xffffffffffffffffUL;__SCHAR_WIDTH__;8;__SHRT_WIDTH__;16;__INT_WIDTH__;32;__LONG_WIDTH__;64;__LONG_LONG_WIDTH__;64;__WCHAR_WIDTH__;32;__WINT_WIDTH__;32;__PTRDIFF_WIDTH__;64;__SIZE_WIDTH__;64;__INTMAX_MAX__;0x7fffffffffffffffL;__INTMAX_C(c);c ## L;__UINTMAX_MAX__;0xffffffffffffffffUL;__UINTMAX_C(c);c ## UL;__INTMAX_WIDTH__;64;__SIG_ATOMIC_MAX__;0x7fffffff;__SIG_ATOMIC_MIN__;(-__SIG_ATOMIC_MAX__ - 1);__SIG_ATOMIC_WIDTH__;32;__INT8_MAX__;0x7f;__INT16_MAX__;0x7fff;__INT32_MAX__;0x7fffffff;__INT64_MAX__;0x7fffffffffffffffL;__UINT8_MAX__;0xff;__UINT16_MAX__;0xffff;__UINT32_MAX__;0xffffffffU;__UINT64_MAX__;0xffffffffffffffffUL;__INT_LEAST8_MAX__;0x7f;__INT8_C(c);c;__INT_LEAST8_WIDTH__;8;__INT_LEAST16_MAX__;0x7fff;__INT16_C(c);c;__INT_LEAST16_WIDTH__;16;__INT_LEAST32_MAX__;0x7fffffff;__INT32_C(c);c;__INT_LEAST32_WIDTH__;32;__INT_LEAST64_MAX__;0x7fffffffffffffffL;__INT64_C(c);c ## L;__INT_LEAST64_WIDTH__;64;__UINT_LEAST8_MAX__;0xff;__UINT8_C(c);c;__UINT_LEAST16_MAX__;0xffff;__UINT16_C(c);c;__UINT_LEAST32_MAX__;0xffffffffU;__UINT32_C(c);c ## U;__UINT_LEAST64_MAX__;0xffffffffffffffffUL;__UINT64_C(c);c ## UL;__INT_FAST8_MAX__;0x7f;__INT_FAST8_WIDTH__;8;__INT_FAST16_MAX__;0x7fffffffffffffffL;__INT_FAST16_WIDTH__;64;__INT_FAST32_MAX__;0x7fffffffffffffffL;__INT_FAST32_WIDTH__;64;__INT_FAST64_MAX__;0x7fffffffffffffffL;__INT_FAST64_WIDTH__;64;__UINT_FAST8_MAX__;0xff;__UINT_FAST16_MAX__;0xffffffffffffffffUL;__UINT_FAST32_MAX__;0xffffffffffffffffUL;__UINT_FAST64_MAX__;0xffffffffffffffffUL;__INTPTR_MAX__;0x7fffffffffffffffL;__INTPTR_WIDTH__;64;__UINTPTR_MAX__;0xffffffffffffffffUL;__GCC_IEC_559;2;__GCC_IEC_559_COMPLEX;2;__FLT_EVAL_METHOD__;0;__FLT_EVAL_METHOD_TS_18661_3__;0;__DEC_EVAL_METHOD__;2;__FLT_RADIX__;2;__FLT_MANT_DIG__;24;__FLT_DIG__;6;__FLT_MIN_EXP__;(-125);__FLT_MIN_10_EXP__;(-37);__FLT_MAX_EXP__;128;__FLT_MAX_10_EXP__;38;__FLT_DECIMAL_DIG__;9;__FLT_MAX__;3.40282346638528859811704183484516925e+38F;__FLT_MIN__;1.17549435082228750796873653722224568e-38F;__FLT_EPSILON__;1.19209289550781250000000000000000000e-7F;__FLT_DENORM_MIN__;1.40129846432481707092372958328991613e-45F;__FLT_HAS_DENORM__;1;__FLT_HAS_INFINITY__;1;__FLT_HAS_QUIET_NAN__;1;__DBL_MANT_DIG__;53;__DBL_DIG__;15;__DBL_MIN_EXP__;(-1021);__DBL_MIN_10_EXP__;(-307);__DBL_MAX_EXP__;1024;__DBL_MAX_10_EXP__;308;__DBL_DECIMAL_DIG__;17;__DBL_MAX__;((double)1.79769313486231570814527423731704357e+308L);__DBL_MIN__;((double)2.22507385850720138309023271733240406e-308L);__DBL_EPSILON__;((double)2.22044604925031308084726333618164062e-16L);__DBL_DENORM_MIN__;((double)4.94065645841246544176568792868221372e-324L);__DBL_HAS_DENORM__;1;__DBL_HAS_INFINITY__;1;__DBL_HAS_QUIET_NAN__;1;__LDBL_MANT_DIG__;64;__LDBL_DIG__;18;__LDBL_MIN_EXP__;(-16381);__LDBL_MIN_10_EXP__;(-4931);__LDBL_MAX_EXP__;16384;__LDBL_MAX_10_EXP__;4932;__DECIMAL_DIG__;21;__LDBL_DECIMAL_DIG__;21;__LDBL_MAX__;1.18973149535723176502126385303097021e+4932L;__LDBL_MIN__;3.36210314311209350626267781732175260e-4932L;__LDBL_EPSILON__;1.08420217248550443400745280086994171e-19L;__LDBL_DENORM_MIN__;3.64519953188247460252840593361941982e-4951L;__LDBL_HAS_DENORM__;1;__LDBL_HAS_INFINITY__;1;__LDBL_HAS_QUIET_NAN__;1;__FLT32_MANT_DIG__;24;__FLT32_DIG__;6;__FLT32_MIN_EXP__;(-125);__FLT32_MIN_10_EXP__;(-37);__FLT32_MAX_EXP__;128;__FLT32_MAX_10_EXP__;38;__FLT32_DECIMAL_DIG__;9;__FLT32_MAX__;3.40282346638528859811704183484516925e+38F32;__FLT32_MIN__;1.17549435082228750796873653722224568e-38F32;__FLT32_EPSILON__;1.19209289550781250000000000000000000e-7F32;__FLT32_DENORM_MIN__;1.40129846432481707092372958328991613e-45F32;__FLT32_HAS_DENORM__;1;__FLT32_HAS_INFINITY__;1;__FLT32_HAS_QUIET_NAN__;1;__FLT64_MANT_DIG__;53;__FLT64_DIG__;15;__FLT64_MIN_EXP__;(-1021);__FLT64_MIN_10_EXP__;(-307);__FLT64_MAX_EXP__;1024;__FLT64_MAX_10_EXP__;308;__FLT64_DECIMAL_DIG__;17;__FLT64_MAX__;1.79769313486231570814527423731704357e+308F64;__FLT64_MIN__;2.22507385850720138309023271733240406e-308F64;__FLT64_EPSILON__;2.22044604925031308084726333618164062e-16F64;__FLT64_DENORM_MIN__;4.94065645841246544176568792868221372e-324F64;__FLT64_HAS_DENORM__;1;__FLT64_HAS_INFINITY__;1;__FLT64_HAS_QUIET_NAN__;1;__FLT128_MANT_DIG__;113;__FLT128_DIG__;33;__FLT128_MIN_EXP__;(-16381);__FLT128_MIN_10_EXP__;(-4931);__FLT128_MAX_EXP__;16384;__FLT128_MAX_10_EXP__;4932;__FLT128_DECIMAL_DIG__;36;__FLT128_MAX__;1.18973149535723176508575932662800702e+4932F128;__FLT128_MIN__;3.36210314311209350626267781732175260e-4932F128;__FLT128_EPSILON__;1.92592994438723585305597794258492732e-34F128;__FLT128_DENORM_MIN__;6.47517511943802511092443895822764655e-4966F128;__FLT128_HAS_DENORM__;1;__FLT128_HAS_INFINITY__;1;__FLT128_HAS_QUIET_NAN__;1;__FLT32X_MANT_DIG__;53;__FLT32X_DIG__;15;__FLT32X_MIN_EXP__;(-1021);__FLT32X_MIN_10_EXP__;(-307);__FLT32X_MAX_EXP__;1024;__FLT32X_MAX_10_EXP__;308;__FLT32X_DECIMAL_DIG__;17;__FLT32X_MAX__;1.79769313486231570814527423731704357e+308F32x;__FLT32X_MIN__;2.22507385850720138309023271733240406e-308F32x;__FLT32X_EPSILON__;2.22044604925031308084726333618164062e-16F32x;__FLT32X_DENORM_MIN__;4.94065645841246544176568792868221372e-324F32x;__FLT32X_HAS_DENORM__;1;__FLT32X_HAS_INFINITY__;1;__FLT32X_HAS_QUIET_NAN__;1;__FLT64X_MANT_DIG__;64;__FLT64X_DIG__;18;__FLT64X_MIN_EXP__;(-16381);__FLT64X_MIN_10_EXP__;(-4931);__FLT64X_MAX_EXP__;16384;__FLT64X_MAX_10_EXP__;4932;__FLT64X_DECIMAL_DIG__;21;__FLT64X_MAX__;1.18973149535723176502126385303097021e+4932F64x;__FLT64X_MIN__;3.36210314311209350626267781732175260e-4932F64x;__FLT64X_EPSILON__;1.08420217248550443400745280086994171e-19F64x;__FLT64X_DENORM_MIN__;3.64519953188247460252840593361941982e-4951F64x;__FLT64X_HAS_DENORM__;1;__FLT64X_HAS_INFINITY__;1;__FLT64X_HAS_QUIET_NAN__;1;__DEC32_MANT_DIG__;7;__DEC32_MIN_EXP__;(-94);__DEC32_MAX_EXP__;97;__DEC32_MIN__;1E-95DF;__DEC32_MAX__;9.999999E96DF;__DEC32_EPSILON__;1E-6DF;__DEC32_SUBNORMAL_MIN__;0.000001E-95DF;__DEC64_MANT_DIG__;16;__DEC64_MIN_EXP__;(-382);__DEC64_MAX_EXP__;385;__DEC64_MIN__;1E-383DD;__DEC64_MAX__;9.999999999999999E384DD;__DEC64_EPSILON__;1E-15DD;__DEC64_SUBNORMAL_MIN__;0.000000000000001E-383DD;__DEC128_MANT_DIG__;34;__DEC128_MIN_EXP__;(-6142);__DEC128_MAX_EXP__;6145;__DEC128_MIN__;1E-6143DL;__DEC128_MAX__;9.999999999999999999999999999999999E6144DL;__DEC128_EPSILON__;1E-33DL;__DEC128_SUBNORMAL_MIN__;0.000000000000000000000000000000001E-6143DL;__REGISTER_PREFIX__; ;__USER_LABEL_PREFIX__; ;__GNUC_STDC_INLINE__;1;__NO_INLINE__;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4;1;__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8;1;__GCC_ATOMIC_BOOL_LOCK_FREE;2;__GCC_ATOMIC_CHAR_LOCK_FREE;2;__GCC_ATOMIC_CHAR16_T_LOCK_FREE;2;__GCC_ATOMIC_CHAR32_T_LOCK_FREE;2;__GCC_ATOMIC_WCHAR_T_LOCK_FREE;2;__GCC_ATOMIC_SHORT_LOCK_FREE;2;__GCC_ATOMIC_INT_LOCK_FREE;2;__GCC_ATOMIC_LONG_LOCK_FREE;2;__GCC_ATOMIC_LLONG_LOCK_FREE;2;__GCC_ATOMIC_TEST_AND_SET_TRUEVAL;1;__GCC_ATOMIC_POINTER_LOCK_FREE;2;__GCC_HAVE_DWARF2_CFI_ASM;1;__PRAGMA_REDEFINE_EXTNAME;1;__SSP_STRONG__;3;__SIZEOF_INT128__;16;__SIZEOF_WCHAR_T__;4;__SIZEOF_WINT_T__;4;__SIZEOF_PTRDIFF_T__;8;__amd64;1;__amd64__;1;__x86_64;1;__x86_64__;1;__SIZEOF_FLOAT80__;16;__SIZEOF_FLOAT128__;16;__ATOMIC_HLE_ACQUIRE;65536;__ATOMIC_HLE_RELEASE;131072;__GCC_ASM_FLAG_OUTPUTS__;1;__k8;1;__k8__;1;__code_model_small__;1;__MMX__;1;__SSE__;1;__SSE2__;1;__FXSR__;1;__SSE_MATH__;1;__SSE2_MATH__;1;__SEG_FS;1;__SEG_GS;1;__gnu_linux__;1;__linux;1;__linux__;1;linux;1;__unix;1;__unix__;1;unix;1;__ELF__;1;__DECIMAL_BID_FORMAT__;1;_STDC_PREDEF_H;1;__STDC_IEC_559__;1;__STDC_IEC_559_COMPLEX__;1;__STDC_ISO_10646__;201706L;__STDC_NO_THREADS__;1 -//C compiler system include directories -CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS:INTERNAL=/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include -//Name of generator. -CMAKE_GENERATOR:INTERNAL=Unix Makefiles -//Generator instance identifier. -CMAKE_GENERATOR_INSTANCE:INTERNAL= -//Name of generator platform. -CMAKE_GENERATOR_PLATFORM:INTERNAL= -//Name of generator toolset. -CMAKE_GENERATOR_TOOLSET:INTERNAL= -//Test CMAKE_HAVE_LIBC_PTHREAD -CMAKE_HAVE_LIBC_PTHREAD:INTERNAL= -//Have library pthreads -CMAKE_HAVE_PTHREADS_CREATE:INTERNAL= -//Have library pthread -CMAKE_HAVE_PTHREAD_CREATE:INTERNAL=1 -//Have include pthread.h -CMAKE_HAVE_PTHREAD_H:INTERNAL=1 -//Source directory with the top level CMakeLists.txt file for this -// project -CMAKE_HOME_DIRECTORY:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo -//Install .so files without execute permission. -CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1 -//ADVANCED property for variable: CMAKE_LINKER -CMAKE_LINKER-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MAKE_PROGRAM -CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS -CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG -CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL -CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE -CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO -CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_NM -CMAKE_NM-ADVANCED:INTERNAL=1 -//number of local generators -CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=4 -//ADVANCED property for variable: CMAKE_OBJCOPY -CMAKE_OBJCOPY-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_OBJDUMP -CMAKE_OBJDUMP-ADVANCED:INTERNAL=1 -//Platform information initialized -CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_RANLIB -CMAKE_RANLIB-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_READELF -CMAKE_READELF-ADVANCED:INTERNAL=1 -//Path to CMake installation. -CMAKE_ROOT:INTERNAL=/opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17 -//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS -CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG -CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL -CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE -CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO -CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH -CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SKIP_RPATH -CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS -CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG -CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL -CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE -CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO -CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_STRIP -CMAKE_STRIP-ADVANCED:INTERNAL=1 -//uname command -CMAKE_UNAME:INTERNAL=/bin/uname -//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE -CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: EIGEN_INCLUDE_DIR -EIGEN_INCLUDE_DIR-ADVANCED:INTERNAL=1 -//Details about finding Boost -FIND_PACKAGE_MESSAGE_DETAILS_Boost:INTERNAL=[/usr/include][cfound components: thread system chrono date_time atomic ][v1.65.1()] -//Details about finding Eigen -FIND_PACKAGE_MESSAGE_DETAILS_Eigen:INTERNAL=[/usr/include/eigen3][v()] -//Details about finding OpenCL -FIND_PACKAGE_MESSAGE_DETAILS_OpenCL:INTERNAL=[/usr/lib/x86_64-linux-gnu/libOpenCL.so][/usr/include][v2.2()] -//Details about finding OpenCV -FIND_PACKAGE_MESSAGE_DETAILS_OpenCV:INTERNAL=[/usr][v3.2.0(3)] -//Details about finding PkgConfig -FIND_PACKAGE_MESSAGE_DETAILS_PkgConfig:INTERNAL=[/usr/bin/pkg-config][v0.29.1()] -//Details about finding PythonInterp -FIND_PACKAGE_MESSAGE_DETAILS_PythonInterp:INTERNAL=[/usr/bin/python2][v2.7.17()] -//Details about finding Threads -FIND_PACKAGE_MESSAGE_DETAILS_Threads:INTERNAL=[TRUE][v()] -GMOCK_FROM_SOURCE_FOUND:INTERNAL=TRUE -GMOCK_FROM_SOURCE_INCLUDE_DIRS:INTERNAL=/usr/include -GMOCK_FROM_SOURCE_LIBRARIES:INTERNAL=gmock -GMOCK_FROM_SOURCE_LIBRARY_DIRS:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/gmock -GMOCK_FROM_SOURCE_MAIN_LIBRARIES:INTERNAL=gmock_main -GTEST_FROM_SOURCE_FOUND:INTERNAL=TRUE -GTEST_FROM_SOURCE_INCLUDE_DIRS:INTERNAL=/usr/include -GTEST_FROM_SOURCE_LIBRARIES:INTERNAL=gtest -GTEST_FROM_SOURCE_LIBRARY_DIRS:INTERNAL=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/gtest -GTEST_FROM_SOURCE_MAIN_LIBRARIES:INTERNAL=gtest_main -//ADVANCED property for variable: GTEST_INCLUDE_DIR -GTEST_INCLUDE_DIR-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: GTEST_LIBRARY -GTEST_LIBRARY-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: GTEST_LIBRARY_DEBUG -GTEST_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: GTEST_MAIN_LIBRARY -GTEST_MAIN_LIBRARY-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: GTEST_MAIN_LIBRARY_DEBUG -GTEST_MAIN_LIBRARY_DEBUG-ADVANCED:INTERNAL=1 -//Have symbol CL_VERSION_2_2 -OPENCL_VERSION_2_2:INTERNAL=1 -//ADVANCED property for variable: OpenCL_INCLUDE_DIR -OpenCL_INCLUDE_DIR-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: OpenCL_LIBRARY -OpenCL_LIBRARY-ADVANCED:INTERNAL=1 -PC_EIGEN_CFLAGS:INTERNAL=-I/usr/include/eigen3 -PC_EIGEN_CFLAGS_I:INTERNAL= -PC_EIGEN_CFLAGS_OTHER:INTERNAL= -PC_EIGEN_FOUND:INTERNAL=1 -PC_EIGEN_INCLUDEDIR:INTERNAL= -PC_EIGEN_INCLUDE_DIRS:INTERNAL=/usr/include/eigen3 -PC_EIGEN_LDFLAGS:INTERNAL= -PC_EIGEN_LDFLAGS_OTHER:INTERNAL= -PC_EIGEN_LIBDIR:INTERNAL= -PC_EIGEN_LIBRARIES:INTERNAL= -PC_EIGEN_LIBRARY_DIRS:INTERNAL= -PC_EIGEN_LIBS:INTERNAL= -PC_EIGEN_LIBS_L:INTERNAL= -PC_EIGEN_LIBS_OTHER:INTERNAL= -PC_EIGEN_LIBS_PATHS:INTERNAL= -PC_EIGEN_MODULE_NAME:INTERNAL=eigen3 -PC_EIGEN_PREFIX:INTERNAL=/usr -PC_EIGEN_STATIC_CFLAGS:INTERNAL=-I/usr/include/eigen3 -PC_EIGEN_STATIC_CFLAGS_I:INTERNAL= -PC_EIGEN_STATIC_CFLAGS_OTHER:INTERNAL= -PC_EIGEN_STATIC_INCLUDE_DIRS:INTERNAL=/usr/include/eigen3 -PC_EIGEN_STATIC_LDFLAGS:INTERNAL= -PC_EIGEN_STATIC_LDFLAGS_OTHER:INTERNAL= -PC_EIGEN_STATIC_LIBDIR:INTERNAL= -PC_EIGEN_STATIC_LIBRARIES:INTERNAL= -PC_EIGEN_STATIC_LIBRARY_DIRS:INTERNAL= -PC_EIGEN_STATIC_LIBS:INTERNAL= -PC_EIGEN_STATIC_LIBS_L:INTERNAL= -PC_EIGEN_STATIC_LIBS_OTHER:INTERNAL= -PC_EIGEN_STATIC_LIBS_PATHS:INTERNAL= -PC_EIGEN_VERSION:INTERNAL=3.3.4 -PC_EIGEN_eigen3_INCLUDEDIR:INTERNAL= -PC_EIGEN_eigen3_LIBDIR:INTERNAL= -PC_EIGEN_eigen3_PREFIX:INTERNAL= -PC_EIGEN_eigen3_VERSION:INTERNAL= -//ADVANCED property for variable: PKG_CONFIG_EXECUTABLE -PKG_CONFIG_EXECUTABLE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: PYTHON_EXECUTABLE -PYTHON_EXECUTABLE-ADVANCED:INTERNAL=1 -//This needs to be in PYTHONPATH when 'setup.py install' is called. -// And it needs to match. But setuptools won't tell us where -// it will install things. -PYTHON_INSTALL_DIR:INTERNAL=lib/python2.7/dist-packages -//ADVANCED property for variable: ProcessorCount_cmd_nproc -ProcessorCount_cmd_nproc-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: ProcessorCount_cmd_sysctl -ProcessorCount_cmd_sysctl-ADVANCED:INTERNAL=1 -//Components requested for this build tree. -_Boost_COMPONENTS_SEARCHED:INTERNAL=atomic;chrono;date_time;system;thread -//Last used Boost_INCLUDE_DIR value. -_Boost_INCLUDE_DIR_LAST:INTERNAL=/usr/include -//Last used Boost_LIBRARY_DIR_DEBUG value. -_Boost_LIBRARY_DIR_DEBUG_LAST:INTERNAL=/usr/lib/x86_64-linux-gnu -//Last used Boost_LIBRARY_DIR_RELEASE value. -_Boost_LIBRARY_DIR_RELEASE_LAST:INTERNAL=/usr/lib/x86_64-linux-gnu -//Last used Boost_NAMESPACE value. -_Boost_NAMESPACE_LAST:INTERNAL=boost -//Last used Boost_USE_MULTITHREADED value. -_Boost_USE_MULTITHREADED_LAST:INTERNAL=TRUE -__pkg_config_arguments_PC_EIGEN:INTERNAL=eigen3 -__pkg_config_checked_PC_EIGEN:INTERNAL=1 -prefix_result:INTERNAL= - diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCCompiler.cmake b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCCompiler.cmake deleted file mode 100644 index 5e07ef4..0000000 --- a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCCompiler.cmake +++ /dev/null @@ -1,76 +0,0 @@ -set(CMAKE_C_COMPILER "/usr/bin/cc") -set(CMAKE_C_COMPILER_ARG1 "") -set(CMAKE_C_COMPILER_ID "GNU") -set(CMAKE_C_COMPILER_VERSION "7.5.0") -set(CMAKE_C_COMPILER_VERSION_INTERNAL "") -set(CMAKE_C_COMPILER_WRAPPER "") -set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "11") -set(CMAKE_C_COMPILE_FEATURES "c_std_90;c_function_prototypes;c_std_99;c_restrict;c_variadic_macros;c_std_11;c_static_assert") -set(CMAKE_C90_COMPILE_FEATURES "c_std_90;c_function_prototypes") -set(CMAKE_C99_COMPILE_FEATURES "c_std_99;c_restrict;c_variadic_macros") -set(CMAKE_C11_COMPILE_FEATURES "c_std_11;c_static_assert") - -set(CMAKE_C_PLATFORM_ID "Linux") -set(CMAKE_C_SIMULATE_ID "") -set(CMAKE_C_COMPILER_FRONTEND_VARIANT "") -set(CMAKE_C_SIMULATE_VERSION "") - - - -set(CMAKE_AR "/usr/bin/ar") -set(CMAKE_C_COMPILER_AR "/usr/bin/gcc-ar-7") -set(CMAKE_RANLIB "/usr/bin/ranlib") -set(CMAKE_C_COMPILER_RANLIB "/usr/bin/gcc-ranlib-7") -set(CMAKE_LINKER "/usr/bin/ld") -set(CMAKE_MT "") -set(CMAKE_COMPILER_IS_GNUCC 1) -set(CMAKE_C_COMPILER_LOADED 1) -set(CMAKE_C_COMPILER_WORKS TRUE) -set(CMAKE_C_ABI_COMPILED TRUE) -set(CMAKE_COMPILER_IS_MINGW ) -set(CMAKE_COMPILER_IS_CYGWIN ) -if(CMAKE_COMPILER_IS_CYGWIN) - set(CYGWIN 1) - set(UNIX 1) -endif() - -set(CMAKE_C_COMPILER_ENV_VAR "CC") - -if(CMAKE_COMPILER_IS_MINGW) - set(MINGW 1) -endif() -set(CMAKE_C_COMPILER_ID_RUN 1) -set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m) -set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) -set(CMAKE_C_LINKER_PREFERENCE 10) - -# Save compiler ABI information. -set(CMAKE_C_SIZEOF_DATA_PTR "8") -set(CMAKE_C_COMPILER_ABI "ELF") -set(CMAKE_C_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") - -if(CMAKE_C_SIZEOF_DATA_PTR) - set(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}") -endif() - -if(CMAKE_C_COMPILER_ABI) - set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}") -endif() - -if(CMAKE_C_LIBRARY_ARCHITECTURE) - set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") -endif() - -set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "") -if(CMAKE_C_CL_SHOWINCLUDES_PREFIX) - set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}") -endif() - - - - - -set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include") -set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "gcc;gcc_s;c;gcc;gcc_s") -set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/7;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") -set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCXXCompiler.cmake b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCXXCompiler.cmake deleted file mode 100644 index 1ff034b..0000000 --- a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeCXXCompiler.cmake +++ /dev/null @@ -1,88 +0,0 @@ -set(CMAKE_CXX_COMPILER "/usr/bin/c++") -set(CMAKE_CXX_COMPILER_ARG1 "") -set(CMAKE_CXX_COMPILER_ID "GNU") -set(CMAKE_CXX_COMPILER_VERSION "7.5.0") -set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "") -set(CMAKE_CXX_COMPILER_WRAPPER "") -set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "14") -set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17") -set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters") -set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates") -set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates") -set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17") -set(CMAKE_CXX20_COMPILE_FEATURES "") - -set(CMAKE_CXX_PLATFORM_ID "Linux") -set(CMAKE_CXX_SIMULATE_ID "") -set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "") -set(CMAKE_CXX_SIMULATE_VERSION "") - - - -set(CMAKE_AR "/usr/bin/ar") -set(CMAKE_CXX_COMPILER_AR "/usr/bin/gcc-ar-7") -set(CMAKE_RANLIB "/usr/bin/ranlib") -set(CMAKE_CXX_COMPILER_RANLIB "/usr/bin/gcc-ranlib-7") -set(CMAKE_LINKER "/usr/bin/ld") -set(CMAKE_MT "") -set(CMAKE_COMPILER_IS_GNUCXX 1) -set(CMAKE_CXX_COMPILER_LOADED 1) -set(CMAKE_CXX_COMPILER_WORKS TRUE) -set(CMAKE_CXX_ABI_COMPILED TRUE) -set(CMAKE_COMPILER_IS_MINGW ) -set(CMAKE_COMPILER_IS_CYGWIN ) -if(CMAKE_COMPILER_IS_CYGWIN) - set(CYGWIN 1) - set(UNIX 1) -endif() - -set(CMAKE_CXX_COMPILER_ENV_VAR "CXX") - -if(CMAKE_COMPILER_IS_MINGW) - set(MINGW 1) -endif() -set(CMAKE_CXX_COMPILER_ID_RUN 1) -set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;CPP) -set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC) - -foreach (lang C OBJC OBJCXX) - if (CMAKE_${lang}_COMPILER_ID_RUN) - foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS) - list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension}) - endforeach() - endif() -endforeach() - -set(CMAKE_CXX_LINKER_PREFERENCE 30) -set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1) - -# Save compiler ABI information. -set(CMAKE_CXX_SIZEOF_DATA_PTR "8") -set(CMAKE_CXX_COMPILER_ABI "ELF") -set(CMAKE_CXX_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") - -if(CMAKE_CXX_SIZEOF_DATA_PTR) - set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}") -endif() - -if(CMAKE_CXX_COMPILER_ABI) - set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}") -endif() - -if(CMAKE_CXX_LIBRARY_ARCHITECTURE) - set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") -endif() - -set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "") -if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX) - set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}") -endif() - - - - - -set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include/c++/7;/usr/include/x86_64-linux-gnu/c++/7;/usr/include/c++/7/backward;/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include") -set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;gcc_s;gcc;c;gcc_s;gcc") -set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/7;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") -set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_C.bin b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_C.bin deleted file mode 100755 index b1860a3dd40b90b19fab68ce7a4bf1a8fee6135d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8248 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 diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_CXX.bin b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CMakeDetermineCompilerABI_CXX.bin deleted file mode 100755 index 19a9ccae8956d20ea78fcbaa929a195ae4089300..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8264 zcmeHMeQZ#_ndP--+kvEKOPLVIUNqc$t4~TSjx{am}aU_mr@3xSu}|%_+25E z3lyu6oKfFw0Mr_3noKjgiFW~_UX#-xthj>Y7`catl~iX3-n$HzQ3#(TP!Ib$RU?al zKABbEUaHj`RA}6ZgKj=){g{ti$o3&RqD8 zdq>>jo`qHJii(=2Dnv8ZRlyhA2?T$4^*~k2?_a$9?4jzdKbZHz7cS@j`0C|j>wDg~ zcJV8FR~&f!xkEo6yY8u8`1Y~)UVEQc5;V&b&a1DS7R!KJV8h3O^V#q}o`s(W{3;vy zy})_J-NNhjmDFm)3k(08AHt-8Xjqnm5g)$~Y z!C-V%eOZm3)nWRh5bNMx*3C;xO?> zE&RfM>&5NWC^W5iD6I9xlHqvlU=)g2rDgPRTGtZcSdy9EOcteLLTm5r&?3=vv_F>7 zqv_6$mUt=|?F{$CK|2}=>tRqqFpNN^ux`@C?!@6k`U&+FN>gZLsdZegb=Rc6Wxx zDt`psSI25LNZ9rc2o@IIaQnpHYge{n&9~&p1@XT%Ao%T6dc?1TYxTg?QPIk&)jyYxheI`K9ijQhXjf2ck8 zy1&a0b9vuyD&2(7&$*X+zK*W~uwg@XFTHQm?n29Gb4`)4S3qc!)w zzp(I4b#%g^Zh0&F7hKbQ-Tp`Y-TwW4ZDM?8K0kn^miB1X9mTf*e?h{r+;u;m-MD`*-YOKH0-OXq1vm|e=c^ND>19Bi&q=`3 zfc3Q5@qL8Jad3}t40#>PtLM7M9do_NuYm7Su)${_%Gt{cv6|#nkjHnE@OaxiOFmya z?`!T6v3=S7pWd)q9{;Eh%O~nV&W&=Eu&qboyB?-io}qq^_ep0<%^YVl^vKXT1oeBN zK8iX4kN0V3z_aALuAs*^RuS;5`A((ksef{g>S-FC+u>7dcS8)z~ciskPmp= z^1XQ$)JMRM`ME}ucha31xHAL)pEJPz0s8~|u4k;KVY9zR*QKIA#@9f;H!UZ5KEu#Y z#>D;yo@bc2{vWpsDJ&nQLx+8V=PQt<8{>Y1!&q)76tr>RI1rWs_20w;?M_4c}~NQtCIZHQ4{AITv`6e6KglyWkzq z_u*3BC3KsYkqd5=ykAP?D~tQ2l%FGbKb7)x1+Pmf?-snCrF>O!-<0y@_Zh5r!R|bc z4u~bWM720&%g@}e%qlKnbN>MWm+AgiD(@}E3rhL> z`~-Mkxwv=CM|F8=Z^$y?(ue+AyIpKds3 zSK0Lcb!o@ueCti?89m$Ar}T=MP>QA}v|bFRWH5q~()#16o^V`?=&5u@3ulK!Zz?eu zkLuBgvbk|flf94((rDpyIy?-q6g@pG`qJSF;Q7DHW43C!ipRsRdOsr?&0^3W7{*ct>bgz#r0fwY5DM?9@8_flv^e zlToXW7NfERx|*BK0i}-|r&511tMp`J5K4|kgo34kaArU#k>MoRGf+<(HD8UUGqF^%q@Y1vIvNk7 zf>2~kP8p2r0)LeL6lC=15d6wmpps6>fS(c_pp7*U0evnR`o<13G&m2&!--fgbO+;w z3WWQF0=qi_JJ#kg`p6Xe(eUUMqaW-yF|r@chEdj>?u7!r`q+J9|BBIP7KS{z+eNkk za%O$@!x&c=C5?<#zZK{k;Olbx?5{CmOal}9`|MvEtPndPgT6iMPg92R6b%@UL(H;1 zdkzl)hdwszv;W7)_XiM>$vS`gfkj`Q_1RBk?IRcph|XP5OL) zpQZo+%YleYTxNU|SX?r0zvwrTBb%rG^ZsN#p2zQjE{d=|-z)OiDM-!ocjkxn8LvQ< zS->24 & 0x00FF) -# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) -# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF) - -#elif defined(__BORLANDC__) -# define COMPILER_ID "Borland" - /* __BORLANDC__ = 0xVRR */ -# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) -# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) - -#elif defined(__WATCOMC__) && __WATCOMC__ < 1200 -# define COMPILER_ID "Watcom" - /* __WATCOMC__ = VVRR */ -# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) -# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) -# if (__WATCOMC__ % 10) > 0 -# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) -# endif - -#elif defined(__WATCOMC__) -# define COMPILER_ID "OpenWatcom" - /* __WATCOMC__ = VVRP + 1100 */ -# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100) -# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) -# if (__WATCOMC__ % 10) > 0 -# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) -# endif - -#elif defined(__SUNPRO_C) -# define COMPILER_ID "SunPro" -# if __SUNPRO_C >= 0x5100 - /* __SUNPRO_C = 0xVRRP */ -# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12) -# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF) -# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) -# else - /* __SUNPRO_CC = 0xVRP */ -# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8) -# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF) -# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) -# endif - -#elif defined(__HP_cc) -# define COMPILER_ID "HP" - /* __HP_cc = VVRRPP */ -# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000) -# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100) -# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100) - -#elif defined(__DECC) -# define COMPILER_ID "Compaq" - /* __DECC_VER = VVRRTPPPP */ -# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000) -# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100) -# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000) - -#elif defined(__IBMC__) && defined(__COMPILER_VER__) -# define COMPILER_ID "zOS" - /* __IBMC__ = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) -# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) -# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) - -#elif defined(__ibmxl__) && defined(__clang__) -# define COMPILER_ID "XLClang" -# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__) -# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__) -# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__) -# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__) - - -#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800 -# define COMPILER_ID "XL" - /* __IBMC__ = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) -# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) -# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) - -#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800 -# define COMPILER_ID "VisualAge" - /* __IBMC__ = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) -# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) -# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) - -#elif defined(__PGI) -# define COMPILER_ID "PGI" -# define COMPILER_VERSION_MAJOR DEC(__PGIC__) -# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) -# if defined(__PGIC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) -# endif - -#elif defined(_CRAYC) -# define COMPILER_ID "Cray" -# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR) -# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) - -#elif defined(__TI_COMPILER_VERSION__) -# define COMPILER_ID "TI" - /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ -# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) -# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) -# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) - -#elif defined(__FUJITSU) || defined(__FCC_VERSION) || defined(__fcc_version) -# define COMPILER_ID "Fujitsu" - -#elif defined(__ghs__) -# define COMPILER_ID "GHS" -/* __GHS_VERSION_NUMBER = VVVVRP */ -# ifdef __GHS_VERSION_NUMBER -# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100) -# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10) -# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10) -# endif - -#elif defined(__TINYC__) -# define COMPILER_ID "TinyCC" - -#elif defined(__BCC__) -# define COMPILER_ID "Bruce" - -#elif defined(__SCO_VERSION__) -# define COMPILER_ID "SCO" - -#elif defined(__ARMCC_VERSION) && !defined(__clang__) -# define COMPILER_ID "ARMCC" -#if __ARMCC_VERSION >= 1000000 - /* __ARMCC_VERSION = VRRPPPP */ - # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000) - # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100) - # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) -#else - /* __ARMCC_VERSION = VRPPPP */ - # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000) - # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10) - # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) -#endif - - -#elif defined(__clang__) && defined(__apple_build_version__) -# define COMPILER_ID "AppleClang" -# if defined(_MSC_VER) -# define SIMULATE_ID "MSVC" -# endif -# define COMPILER_VERSION_MAJOR DEC(__clang_major__) -# define COMPILER_VERSION_MINOR DEC(__clang_minor__) -# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) -# if defined(_MSC_VER) - /* _MSC_VER = VVRR */ -# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) -# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) -# endif -# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__) - -#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION) -# define COMPILER_ID "ARMClang" - # define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000) - # define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100) - # define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000) -# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION) - -#elif defined(__clang__) -# define COMPILER_ID "Clang" -# if defined(_MSC_VER) -# define SIMULATE_ID "MSVC" -# endif -# define COMPILER_VERSION_MAJOR DEC(__clang_major__) -# define COMPILER_VERSION_MINOR DEC(__clang_minor__) -# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) -# if defined(_MSC_VER) - /* _MSC_VER = VVRR */ -# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) -# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) -# endif - -#elif defined(__GNUC__) -# define COMPILER_ID "GNU" -# define COMPILER_VERSION_MAJOR DEC(__GNUC__) -# if defined(__GNUC_MINOR__) -# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) -# endif -# if defined(__GNUC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) -# endif - -#elif defined(_MSC_VER) -# define COMPILER_ID "MSVC" - /* _MSC_VER = VVRR */ -# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) -# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) -# if defined(_MSC_FULL_VER) -# if _MSC_VER >= 1400 - /* _MSC_FULL_VER = VVRRPPPPP */ -# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) -# else - /* _MSC_FULL_VER = VVRRPPPP */ -# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) -# endif -# endif -# if defined(_MSC_BUILD) -# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) -# endif - -#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) -# define COMPILER_ID "ADSP" -#if defined(__VISUALDSPVERSION__) - /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ -# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24) -# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF) -# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF) -#endif - -#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) -# define COMPILER_ID "IAR" -# if defined(__VER__) && defined(__ICCARM__) -# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000) -# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000) -# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000) -# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) -# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__)) -# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100) -# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100)) -# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__) -# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) -# endif - -#elif defined(__SDCC_VERSION_MAJOR) || defined(SDCC) -# define COMPILER_ID "SDCC" -# if defined(__SDCC_VERSION_MAJOR) -# define COMPILER_VERSION_MAJOR DEC(__SDCC_VERSION_MAJOR) -# define COMPILER_VERSION_MINOR DEC(__SDCC_VERSION_MINOR) -# define COMPILER_VERSION_PATCH DEC(__SDCC_VERSION_PATCH) -# else - /* SDCC = VRP */ -# define COMPILER_VERSION_MAJOR DEC(SDCC/100) -# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10) -# define COMPILER_VERSION_PATCH DEC(SDCC % 10) -# endif - - -/* These compilers are either not known or too old to define an - identification macro. Try to identify the platform and guess that - it is the native compiler. */ -#elif defined(__hpux) || defined(__hpua) -# define COMPILER_ID "HP" - -#else /* unknown compiler */ -# define COMPILER_ID "" -#endif - -/* Construct the string literal in pieces to prevent the source from - getting matched. Store it in a pointer rather than an array - because some compilers will just produce instructions to fill the - array rather than assigning a pointer to a static array. */ -char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; -#ifdef SIMULATE_ID -char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; -#endif - -#ifdef __QNXNTO__ -char const* qnxnto = "INFO" ":" "qnxnto[]"; -#endif - -#if defined(__CRAYXE) || defined(__CRAYXC) -char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]"; -#endif - -#define STRINGIFY_HELPER(X) #X -#define STRINGIFY(X) STRINGIFY_HELPER(X) - -/* Identify known platforms by name. */ -#if defined(__linux) || defined(__linux__) || defined(linux) -# define PLATFORM_ID "Linux" - -#elif defined(__CYGWIN__) -# define PLATFORM_ID "Cygwin" - -#elif defined(__MINGW32__) -# define PLATFORM_ID "MinGW" - -#elif defined(__APPLE__) -# define PLATFORM_ID "Darwin" - -#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) -# define PLATFORM_ID "Windows" - -#elif defined(__FreeBSD__) || defined(__FreeBSD) -# define PLATFORM_ID "FreeBSD" - -#elif defined(__NetBSD__) || defined(__NetBSD) -# define PLATFORM_ID "NetBSD" - -#elif defined(__OpenBSD__) || defined(__OPENBSD) -# define PLATFORM_ID "OpenBSD" - -#elif defined(__sun) || defined(sun) -# define PLATFORM_ID "SunOS" - -#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) -# define PLATFORM_ID "AIX" - -#elif defined(__hpux) || defined(__hpux__) -# define PLATFORM_ID "HP-UX" - -#elif defined(__HAIKU__) -# define PLATFORM_ID "Haiku" - -#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) -# define PLATFORM_ID "BeOS" - -#elif defined(__QNX__) || defined(__QNXNTO__) -# define PLATFORM_ID "QNX" - -#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) -# define PLATFORM_ID "Tru64" - -#elif defined(__riscos) || defined(__riscos__) -# define PLATFORM_ID "RISCos" - -#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) -# define PLATFORM_ID "SINIX" - -#elif defined(__UNIX_SV__) -# define PLATFORM_ID "UNIX_SV" - -#elif defined(__bsdos__) -# define PLATFORM_ID "BSDOS" - -#elif defined(_MPRAS) || defined(MPRAS) -# define PLATFORM_ID "MP-RAS" - -#elif defined(__osf) || defined(__osf__) -# define PLATFORM_ID "OSF1" - -#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) -# define PLATFORM_ID "SCO_SV" - -#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) -# define PLATFORM_ID "ULTRIX" - -#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) -# define PLATFORM_ID "Xenix" - -#elif defined(__WATCOMC__) -# if defined(__LINUX__) -# define PLATFORM_ID "Linux" - -# elif defined(__DOS__) -# define PLATFORM_ID "DOS" - -# elif defined(__OS2__) -# define PLATFORM_ID "OS2" - -# elif defined(__WINDOWS__) -# define PLATFORM_ID "Windows3x" - -# else /* unknown platform */ -# define PLATFORM_ID -# endif - -#elif defined(__INTEGRITY) -# if defined(INT_178B) -# define PLATFORM_ID "Integrity178" - -# else /* regular Integrity */ -# define PLATFORM_ID "Integrity" -# endif - -#else /* unknown platform */ -# define PLATFORM_ID - -#endif - -/* For windows compilers MSVC and Intel we can determine - the architecture of the compiler being used. This is because - the compilers do not have flags that can change the architecture, - but rather depend on which compiler is being used -*/ -#if defined(_WIN32) && defined(_MSC_VER) -# if defined(_M_IA64) -# define ARCHITECTURE_ID "IA64" - -# elif defined(_M_X64) || defined(_M_AMD64) -# define ARCHITECTURE_ID "x64" - -# elif defined(_M_IX86) -# define ARCHITECTURE_ID "X86" - -# elif defined(_M_ARM64) -# define ARCHITECTURE_ID "ARM64" - -# elif defined(_M_ARM) -# if _M_ARM == 4 -# define ARCHITECTURE_ID "ARMV4I" -# elif _M_ARM == 5 -# define ARCHITECTURE_ID "ARMV5I" -# else -# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM) -# endif - -# elif defined(_M_MIPS) -# define ARCHITECTURE_ID "MIPS" - -# elif defined(_M_SH) -# define ARCHITECTURE_ID "SHx" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif - -#elif defined(__WATCOMC__) -# if defined(_M_I86) -# define ARCHITECTURE_ID "I86" - -# elif defined(_M_IX86) -# define ARCHITECTURE_ID "X86" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif - -#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) -# if defined(__ICCARM__) -# define ARCHITECTURE_ID "ARM" - -# elif defined(__ICCRX__) -# define ARCHITECTURE_ID "RX" - -# elif defined(__ICCRH850__) -# define ARCHITECTURE_ID "RH850" - -# elif defined(__ICCRL78__) -# define ARCHITECTURE_ID "RL78" - -# elif defined(__ICCRISCV__) -# define ARCHITECTURE_ID "RISCV" - -# elif defined(__ICCAVR__) -# define ARCHITECTURE_ID "AVR" - -# elif defined(__ICC430__) -# define ARCHITECTURE_ID "MSP430" - -# elif defined(__ICCV850__) -# define ARCHITECTURE_ID "V850" - -# elif defined(__ICC8051__) -# define ARCHITECTURE_ID "8051" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif - -#elif defined(__ghs__) -# if defined(__PPC64__) -# define ARCHITECTURE_ID "PPC64" - -# elif defined(__ppc__) -# define ARCHITECTURE_ID "PPC" - -# elif defined(__ARM__) -# define ARCHITECTURE_ID "ARM" - -# elif defined(__x86_64__) -# define ARCHITECTURE_ID "x64" - -# elif defined(__i386__) -# define ARCHITECTURE_ID "X86" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif -#else -# define ARCHITECTURE_ID -#endif - -/* Convert integer to decimal digit literals. */ -#define DEC(n) \ - ('0' + (((n) / 10000000)%10)), \ - ('0' + (((n) / 1000000)%10)), \ - ('0' + (((n) / 100000)%10)), \ - ('0' + (((n) / 10000)%10)), \ - ('0' + (((n) / 1000)%10)), \ - ('0' + (((n) / 100)%10)), \ - ('0' + (((n) / 10)%10)), \ - ('0' + ((n) % 10)) - -/* Convert integer to hex digit literals. */ -#define HEX(n) \ - ('0' + ((n)>>28 & 0xF)), \ - ('0' + ((n)>>24 & 0xF)), \ - ('0' + ((n)>>20 & 0xF)), \ - ('0' + ((n)>>16 & 0xF)), \ - ('0' + ((n)>>12 & 0xF)), \ - ('0' + ((n)>>8 & 0xF)), \ - ('0' + ((n)>>4 & 0xF)), \ - ('0' + ((n) & 0xF)) - -/* Construct a string literal encoding the version number components. */ -#ifdef COMPILER_VERSION_MAJOR -char const info_version[] = { - 'I', 'N', 'F', 'O', ':', - 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', - COMPILER_VERSION_MAJOR, -# ifdef COMPILER_VERSION_MINOR - '.', COMPILER_VERSION_MINOR, -# ifdef COMPILER_VERSION_PATCH - '.', COMPILER_VERSION_PATCH, -# ifdef COMPILER_VERSION_TWEAK - '.', COMPILER_VERSION_TWEAK, -# endif -# endif -# endif - ']','\0'}; -#endif - -/* Construct a string literal encoding the internal version number. */ -#ifdef COMPILER_VERSION_INTERNAL -char const info_version_internal[] = { - 'I', 'N', 'F', 'O', ':', - 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_', - 'i','n','t','e','r','n','a','l','[', - COMPILER_VERSION_INTERNAL,']','\0'}; -#endif - -/* Construct a string literal encoding the version number components. */ -#ifdef SIMULATE_VERSION_MAJOR -char const info_simulate_version[] = { - 'I', 'N', 'F', 'O', ':', - 's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[', - SIMULATE_VERSION_MAJOR, -# ifdef SIMULATE_VERSION_MINOR - '.', SIMULATE_VERSION_MINOR, -# ifdef SIMULATE_VERSION_PATCH - '.', SIMULATE_VERSION_PATCH, -# ifdef SIMULATE_VERSION_TWEAK - '.', SIMULATE_VERSION_TWEAK, -# endif -# endif -# endif - ']','\0'}; -#endif - -/* Construct the string literal in pieces to prevent the source from - getting matched. Store it in a pointer rather than an array - because some compilers will just produce instructions to fill the - array rather than assigning a pointer to a static array. */ -char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; -char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; - - - - -#if !defined(__STDC__) -# if (defined(_MSC_VER) && !defined(__clang__)) \ - || (defined(__ibmxl__) || defined(__IBMC__)) -# define C_DIALECT "90" -# else -# define C_DIALECT -# endif -#elif __STDC_VERSION__ >= 201000L -# define C_DIALECT "11" -#elif __STDC_VERSION__ >= 199901L -# define C_DIALECT "99" -#else -# define C_DIALECT "90" -#endif -const char* info_language_dialect_default = - "INFO" ":" "dialect_default[" C_DIALECT "]"; - -/*--------------------------------------------------------------------------*/ - -#ifdef ID_VOID_MAIN -void main() {} -#else -# if defined(__CLASSIC_C__) -int main(argc, argv) int argc; char *argv[]; -# else -int main(int argc, char* argv[]) -# endif -{ - int require = 0; - require += info_compiler[argc]; - require += info_platform[argc]; - require += info_arch[argc]; -#ifdef COMPILER_VERSION_MAJOR - require += info_version[argc]; -#endif -#ifdef COMPILER_VERSION_INTERNAL - require += info_version_internal[argc]; -#endif -#ifdef SIMULATE_ID - require += info_simulate[argc]; -#endif -#ifdef SIMULATE_VERSION_MAJOR - require += info_simulate_version[argc]; -#endif -#if defined(__CRAYXE) || defined(__CRAYXC) - require += info_cray[argc]; -#endif - require += info_language_dialect_default[argc]; - (void)argv; - return require; -} -#endif diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdC/a.out b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdC/a.out deleted file mode 100755 index 11b7df452ad29dfd7bf1d9b188856c9e33182403..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8408 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 D$)0nc diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/CMakeCXXCompilerId.cpp b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/CMakeCXXCompilerId.cpp deleted file mode 100644 index 69cfdba..0000000 --- a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/CMakeCXXCompilerId.cpp +++ /dev/null @@ -1,660 +0,0 @@ -/* This source file must have a .cpp extension so that all C++ compilers - recognize the extension without flags. Borland does not know .cxx for - example. */ -#ifndef __cplusplus -# error "A C compiler has been selected for C++." -#endif - - -/* Version number components: V=Version, R=Revision, P=Patch - Version date components: YYYY=Year, MM=Month, DD=Day */ - -#if defined(__COMO__) -# define COMPILER_ID "Comeau" - /* __COMO_VERSION__ = VRR */ -# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100) -# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100) - -#elif defined(__INTEL_COMPILER) || defined(__ICC) -# define COMPILER_ID "Intel" -# if defined(_MSC_VER) -# define SIMULATE_ID "MSVC" -# endif -# if defined(__GNUC__) -# define SIMULATE_ID "GNU" -# endif - /* __INTEL_COMPILER = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) -# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) -# if defined(__INTEL_COMPILER_UPDATE) -# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE) -# else -# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) -# endif -# if defined(__INTEL_COMPILER_BUILD_DATE) - /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */ -# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) -# endif -# if defined(_MSC_VER) - /* _MSC_VER = VVRR */ -# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) -# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) -# endif -# if defined(__GNUC__) -# define SIMULATE_VERSION_MAJOR DEC(__GNUC__) -# elif defined(__GNUG__) -# define SIMULATE_VERSION_MAJOR DEC(__GNUG__) -# endif -# if defined(__GNUC_MINOR__) -# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__) -# endif -# if defined(__GNUC_PATCHLEVEL__) -# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) -# endif - -#elif defined(__PATHCC__) -# define COMPILER_ID "PathScale" -# define COMPILER_VERSION_MAJOR DEC(__PATHCC__) -# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) -# if defined(__PATHCC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) -# endif - -#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) -# define COMPILER_ID "Embarcadero" -# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) -# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) -# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF) - -#elif defined(__BORLANDC__) -# define COMPILER_ID "Borland" - /* __BORLANDC__ = 0xVRR */ -# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) -# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) - -#elif defined(__WATCOMC__) && __WATCOMC__ < 1200 -# define COMPILER_ID "Watcom" - /* __WATCOMC__ = VVRR */ -# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) -# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) -# if (__WATCOMC__ % 10) > 0 -# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) -# endif - -#elif defined(__WATCOMC__) -# define COMPILER_ID "OpenWatcom" - /* __WATCOMC__ = VVRP + 1100 */ -# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100) -# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) -# if (__WATCOMC__ % 10) > 0 -# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) -# endif - -#elif defined(__SUNPRO_CC) -# define COMPILER_ID "SunPro" -# if __SUNPRO_CC >= 0x5100 - /* __SUNPRO_CC = 0xVRRP */ -# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12) -# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF) -# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) -# else - /* __SUNPRO_CC = 0xVRP */ -# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8) -# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF) -# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) -# endif - -#elif defined(__HP_aCC) -# define COMPILER_ID "HP" - /* __HP_aCC = VVRRPP */ -# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000) -# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100) -# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100) - -#elif defined(__DECCXX) -# define COMPILER_ID "Compaq" - /* __DECCXX_VER = VVRRTPPPP */ -# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000) -# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100) -# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000) - -#elif defined(__IBMCPP__) && defined(__COMPILER_VER__) -# define COMPILER_ID "zOS" - /* __IBMCPP__ = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) -# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) -# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) - -#elif defined(__ibmxl__) && defined(__clang__) -# define COMPILER_ID "XLClang" -# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__) -# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__) -# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__) -# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__) - - -#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800 -# define COMPILER_ID "XL" - /* __IBMCPP__ = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) -# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) -# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) - -#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800 -# define COMPILER_ID "VisualAge" - /* __IBMCPP__ = VRP */ -# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) -# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) -# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) - -#elif defined(__PGI) -# define COMPILER_ID "PGI" -# define COMPILER_VERSION_MAJOR DEC(__PGIC__) -# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) -# if defined(__PGIC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) -# endif - -#elif defined(_CRAYC) -# define COMPILER_ID "Cray" -# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR) -# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) - -#elif defined(__TI_COMPILER_VERSION__) -# define COMPILER_ID "TI" - /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ -# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) -# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) -# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) - -#elif defined(__FUJITSU) || defined(__FCC_VERSION) || defined(__fcc_version) -# define COMPILER_ID "Fujitsu" - -#elif defined(__ghs__) -# define COMPILER_ID "GHS" -/* __GHS_VERSION_NUMBER = VVVVRP */ -# ifdef __GHS_VERSION_NUMBER -# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100) -# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10) -# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10) -# endif - -#elif defined(__SCO_VERSION__) -# define COMPILER_ID "SCO" - -#elif defined(__ARMCC_VERSION) && !defined(__clang__) -# define COMPILER_ID "ARMCC" -#if __ARMCC_VERSION >= 1000000 - /* __ARMCC_VERSION = VRRPPPP */ - # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000) - # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100) - # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) -#else - /* __ARMCC_VERSION = VRPPPP */ - # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000) - # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10) - # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) -#endif - - -#elif defined(__clang__) && defined(__apple_build_version__) -# define COMPILER_ID "AppleClang" -# if defined(_MSC_VER) -# define SIMULATE_ID "MSVC" -# endif -# define COMPILER_VERSION_MAJOR DEC(__clang_major__) -# define COMPILER_VERSION_MINOR DEC(__clang_minor__) -# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) -# if defined(_MSC_VER) - /* _MSC_VER = VVRR */ -# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) -# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) -# endif -# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__) - -#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION) -# define COMPILER_ID "ARMClang" - # define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000) - # define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100) - # define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000) -# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION) - -#elif defined(__clang__) -# define COMPILER_ID "Clang" -# if defined(_MSC_VER) -# define SIMULATE_ID "MSVC" -# endif -# define COMPILER_VERSION_MAJOR DEC(__clang_major__) -# define COMPILER_VERSION_MINOR DEC(__clang_minor__) -# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) -# if defined(_MSC_VER) - /* _MSC_VER = VVRR */ -# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) -# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) -# endif - -#elif defined(__GNUC__) || defined(__GNUG__) -# define COMPILER_ID "GNU" -# if defined(__GNUC__) -# define COMPILER_VERSION_MAJOR DEC(__GNUC__) -# else -# define COMPILER_VERSION_MAJOR DEC(__GNUG__) -# endif -# if defined(__GNUC_MINOR__) -# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) -# endif -# if defined(__GNUC_PATCHLEVEL__) -# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) -# endif - -#elif defined(_MSC_VER) -# define COMPILER_ID "MSVC" - /* _MSC_VER = VVRR */ -# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) -# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) -# if defined(_MSC_FULL_VER) -# if _MSC_VER >= 1400 - /* _MSC_FULL_VER = VVRRPPPPP */ -# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) -# else - /* _MSC_FULL_VER = VVRRPPPP */ -# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) -# endif -# endif -# if defined(_MSC_BUILD) -# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) -# endif - -#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) -# define COMPILER_ID "ADSP" -#if defined(__VISUALDSPVERSION__) - /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ -# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24) -# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF) -# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF) -#endif - -#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) -# define COMPILER_ID "IAR" -# if defined(__VER__) && defined(__ICCARM__) -# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000) -# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000) -# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000) -# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) -# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__)) -# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100) -# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100)) -# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__) -# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) -# endif - - -/* These compilers are either not known or too old to define an - identification macro. Try to identify the platform and guess that - it is the native compiler. */ -#elif defined(__hpux) || defined(__hpua) -# define COMPILER_ID "HP" - -#else /* unknown compiler */ -# define COMPILER_ID "" -#endif - -/* Construct the string literal in pieces to prevent the source from - getting matched. Store it in a pointer rather than an array - because some compilers will just produce instructions to fill the - array rather than assigning a pointer to a static array. */ -char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; -#ifdef SIMULATE_ID -char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; -#endif - -#ifdef __QNXNTO__ -char const* qnxnto = "INFO" ":" "qnxnto[]"; -#endif - -#if defined(__CRAYXE) || defined(__CRAYXC) -char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]"; -#endif - -#define STRINGIFY_HELPER(X) #X -#define STRINGIFY(X) STRINGIFY_HELPER(X) - -/* Identify known platforms by name. */ -#if defined(__linux) || defined(__linux__) || defined(linux) -# define PLATFORM_ID "Linux" - -#elif defined(__CYGWIN__) -# define PLATFORM_ID "Cygwin" - -#elif defined(__MINGW32__) -# define PLATFORM_ID "MinGW" - -#elif defined(__APPLE__) -# define PLATFORM_ID "Darwin" - -#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) -# define PLATFORM_ID "Windows" - -#elif defined(__FreeBSD__) || defined(__FreeBSD) -# define PLATFORM_ID "FreeBSD" - -#elif defined(__NetBSD__) || defined(__NetBSD) -# define PLATFORM_ID "NetBSD" - -#elif defined(__OpenBSD__) || defined(__OPENBSD) -# define PLATFORM_ID "OpenBSD" - -#elif defined(__sun) || defined(sun) -# define PLATFORM_ID "SunOS" - -#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) -# define PLATFORM_ID "AIX" - -#elif defined(__hpux) || defined(__hpux__) -# define PLATFORM_ID "HP-UX" - -#elif defined(__HAIKU__) -# define PLATFORM_ID "Haiku" - -#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) -# define PLATFORM_ID "BeOS" - -#elif defined(__QNX__) || defined(__QNXNTO__) -# define PLATFORM_ID "QNX" - -#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) -# define PLATFORM_ID "Tru64" - -#elif defined(__riscos) || defined(__riscos__) -# define PLATFORM_ID "RISCos" - -#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) -# define PLATFORM_ID "SINIX" - -#elif defined(__UNIX_SV__) -# define PLATFORM_ID "UNIX_SV" - -#elif defined(__bsdos__) -# define PLATFORM_ID "BSDOS" - -#elif defined(_MPRAS) || defined(MPRAS) -# define PLATFORM_ID "MP-RAS" - -#elif defined(__osf) || defined(__osf__) -# define PLATFORM_ID "OSF1" - -#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) -# define PLATFORM_ID "SCO_SV" - -#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) -# define PLATFORM_ID "ULTRIX" - -#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) -# define PLATFORM_ID "Xenix" - -#elif defined(__WATCOMC__) -# if defined(__LINUX__) -# define PLATFORM_ID "Linux" - -# elif defined(__DOS__) -# define PLATFORM_ID "DOS" - -# elif defined(__OS2__) -# define PLATFORM_ID "OS2" - -# elif defined(__WINDOWS__) -# define PLATFORM_ID "Windows3x" - -# else /* unknown platform */ -# define PLATFORM_ID -# endif - -#elif defined(__INTEGRITY) -# if defined(INT_178B) -# define PLATFORM_ID "Integrity178" - -# else /* regular Integrity */ -# define PLATFORM_ID "Integrity" -# endif - -#else /* unknown platform */ -# define PLATFORM_ID - -#endif - -/* For windows compilers MSVC and Intel we can determine - the architecture of the compiler being used. This is because - the compilers do not have flags that can change the architecture, - but rather depend on which compiler is being used -*/ -#if defined(_WIN32) && defined(_MSC_VER) -# if defined(_M_IA64) -# define ARCHITECTURE_ID "IA64" - -# elif defined(_M_X64) || defined(_M_AMD64) -# define ARCHITECTURE_ID "x64" - -# elif defined(_M_IX86) -# define ARCHITECTURE_ID "X86" - -# elif defined(_M_ARM64) -# define ARCHITECTURE_ID "ARM64" - -# elif defined(_M_ARM) -# if _M_ARM == 4 -# define ARCHITECTURE_ID "ARMV4I" -# elif _M_ARM == 5 -# define ARCHITECTURE_ID "ARMV5I" -# else -# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM) -# endif - -# elif defined(_M_MIPS) -# define ARCHITECTURE_ID "MIPS" - -# elif defined(_M_SH) -# define ARCHITECTURE_ID "SHx" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif - -#elif defined(__WATCOMC__) -# if defined(_M_I86) -# define ARCHITECTURE_ID "I86" - -# elif defined(_M_IX86) -# define ARCHITECTURE_ID "X86" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif - -#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) -# if defined(__ICCARM__) -# define ARCHITECTURE_ID "ARM" - -# elif defined(__ICCRX__) -# define ARCHITECTURE_ID "RX" - -# elif defined(__ICCRH850__) -# define ARCHITECTURE_ID "RH850" - -# elif defined(__ICCRL78__) -# define ARCHITECTURE_ID "RL78" - -# elif defined(__ICCRISCV__) -# define ARCHITECTURE_ID "RISCV" - -# elif defined(__ICCAVR__) -# define ARCHITECTURE_ID "AVR" - -# elif defined(__ICC430__) -# define ARCHITECTURE_ID "MSP430" - -# elif defined(__ICCV850__) -# define ARCHITECTURE_ID "V850" - -# elif defined(__ICC8051__) -# define ARCHITECTURE_ID "8051" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif - -#elif defined(__ghs__) -# if defined(__PPC64__) -# define ARCHITECTURE_ID "PPC64" - -# elif defined(__ppc__) -# define ARCHITECTURE_ID "PPC" - -# elif defined(__ARM__) -# define ARCHITECTURE_ID "ARM" - -# elif defined(__x86_64__) -# define ARCHITECTURE_ID "x64" - -# elif defined(__i386__) -# define ARCHITECTURE_ID "X86" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif -#else -# define ARCHITECTURE_ID -#endif - -/* Convert integer to decimal digit literals. */ -#define DEC(n) \ - ('0' + (((n) / 10000000)%10)), \ - ('0' + (((n) / 1000000)%10)), \ - ('0' + (((n) / 100000)%10)), \ - ('0' + (((n) / 10000)%10)), \ - ('0' + (((n) / 1000)%10)), \ - ('0' + (((n) / 100)%10)), \ - ('0' + (((n) / 10)%10)), \ - ('0' + ((n) % 10)) - -/* Convert integer to hex digit literals. */ -#define HEX(n) \ - ('0' + ((n)>>28 & 0xF)), \ - ('0' + ((n)>>24 & 0xF)), \ - ('0' + ((n)>>20 & 0xF)), \ - ('0' + ((n)>>16 & 0xF)), \ - ('0' + ((n)>>12 & 0xF)), \ - ('0' + ((n)>>8 & 0xF)), \ - ('0' + ((n)>>4 & 0xF)), \ - ('0' + ((n) & 0xF)) - -/* Construct a string literal encoding the version number components. */ -#ifdef COMPILER_VERSION_MAJOR -char const info_version[] = { - 'I', 'N', 'F', 'O', ':', - 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', - COMPILER_VERSION_MAJOR, -# ifdef COMPILER_VERSION_MINOR - '.', COMPILER_VERSION_MINOR, -# ifdef COMPILER_VERSION_PATCH - '.', COMPILER_VERSION_PATCH, -# ifdef COMPILER_VERSION_TWEAK - '.', COMPILER_VERSION_TWEAK, -# endif -# endif -# endif - ']','\0'}; -#endif - -/* Construct a string literal encoding the internal version number. */ -#ifdef COMPILER_VERSION_INTERNAL -char const info_version_internal[] = { - 'I', 'N', 'F', 'O', ':', - 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_', - 'i','n','t','e','r','n','a','l','[', - COMPILER_VERSION_INTERNAL,']','\0'}; -#endif - -/* Construct a string literal encoding the version number components. */ -#ifdef SIMULATE_VERSION_MAJOR -char const info_simulate_version[] = { - 'I', 'N', 'F', 'O', ':', - 's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[', - SIMULATE_VERSION_MAJOR, -# ifdef SIMULATE_VERSION_MINOR - '.', SIMULATE_VERSION_MINOR, -# ifdef SIMULATE_VERSION_PATCH - '.', SIMULATE_VERSION_PATCH, -# ifdef SIMULATE_VERSION_TWEAK - '.', SIMULATE_VERSION_TWEAK, -# endif -# endif -# endif - ']','\0'}; -#endif - -/* Construct the string literal in pieces to prevent the source from - getting matched. Store it in a pointer rather than an array - because some compilers will just produce instructions to fill the - array rather than assigning a pointer to a static array. */ -char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; -char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; - - - - -#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG) && _MSVC_LANG < 201403L -# if defined(__INTEL_CXX11_MODE__) -# if defined(__cpp_aggregate_nsdmi) -# define CXX_STD 201402L -# else -# define CXX_STD 201103L -# endif -# else -# define CXX_STD 199711L -# endif -#elif defined(_MSC_VER) && defined(_MSVC_LANG) -# define CXX_STD _MSVC_LANG -#else -# define CXX_STD __cplusplus -#endif - -const char* info_language_dialect_default = "INFO" ":" "dialect_default[" -#if CXX_STD > 201703L - "20" -#elif CXX_STD >= 201703L - "17" -#elif CXX_STD >= 201402L - "14" -#elif CXX_STD >= 201103L - "11" -#else - "98" -#endif -"]"; - -/*--------------------------------------------------------------------------*/ - -int main(int argc, char* argv[]) -{ - int require = 0; - require += info_compiler[argc]; - require += info_platform[argc]; -#ifdef COMPILER_VERSION_MAJOR - require += info_version[argc]; -#endif -#ifdef COMPILER_VERSION_INTERNAL - require += info_version_internal[argc]; -#endif -#ifdef SIMULATE_ID - require += info_simulate[argc]; -#endif -#ifdef SIMULATE_VERSION_MAJOR - require += info_simulate_version[argc]; -#endif -#if defined(__CRAYXE) || defined(__CRAYXC) - require += info_cray[argc]; -#endif - require += info_language_dialect_default[argc]; - (void)argv; - return require; -} diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/a.out b/GPU_version/vio/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/a.out deleted file mode 100755 index 71c2ceda86a2fae89d661d131b89af3990e37838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8416 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 L;1d=k>el}!^A2#R diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeError.log b/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeError.log deleted file mode 100644 index 3f8570b..0000000 --- a/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeError.log +++ /dev/null @@ -1,65 +0,0 @@ -Performing C SOURCE FILE Test CMAKE_HAVE_LIBC_PTHREAD failed with the following output: -Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp - -Run Build Command(s):/usr/bin/make cmTC_6ff0d/fast && /usr/bin/make -f CMakeFiles/cmTC_6ff0d.dir/build.make CMakeFiles/cmTC_6ff0d.dir/build -make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Building C object CMakeFiles/cmTC_6ff0d.dir/src.c.o -/usr/bin/cc -DCMAKE_HAVE_LIBC_PTHREAD -o CMakeFiles/cmTC_6ff0d.dir/src.c.o -c /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/src.c -Linking C executable cmTC_6ff0d -/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_6ff0d.dir/link.txt --verbose=1 -/usr/bin/cc -DCMAKE_HAVE_LIBC_PTHREAD -rdynamic CMakeFiles/cmTC_6ff0d.dir/src.c.o -o cmTC_6ff0d -CMakeFiles/cmTC_6ff0d.dir/src.c.o: In function `main': -src.c:(.text+0x3e): undefined reference to `pthread_create' -src.c:(.text+0x4a): undefined reference to `pthread_detach' -src.c:(.text+0x56): undefined reference to `pthread_cancel' -src.c:(.text+0x67): undefined reference to `pthread_join' -src.c:(.text+0x7b): undefined reference to `pthread_atfork' -collect2: error: ld returned 1 exit status -CMakeFiles/cmTC_6ff0d.dir/build.make:106: recipe for target 'cmTC_6ff0d' failed -make[1]: *** [cmTC_6ff0d] Error 1 -make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Makefile:141: recipe for target 'cmTC_6ff0d/fast' failed -make: *** [cmTC_6ff0d/fast] Error 2 - - -Source file was: -#include - -void* test_func(void* data) -{ - return data; -} - -int main(void) -{ - pthread_t thread; - pthread_create(&thread, NULL, test_func, NULL); - pthread_detach(thread); - pthread_cancel(thread); - pthread_join(thread, NULL); - pthread_atfork(NULL, NULL, NULL); - pthread_exit(NULL); - - return 0; -} - -Determining if the function pthread_create exists in the pthreads failed with the following output: -Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp - -Run Build Command(s):/usr/bin/make cmTC_ce6d0/fast && /usr/bin/make -f CMakeFiles/cmTC_ce6d0.dir/build.make CMakeFiles/cmTC_ce6d0.dir/build -make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Building C object CMakeFiles/cmTC_ce6d0.dir/CheckFunctionExists.c.o -/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -o CMakeFiles/cmTC_ce6d0.dir/CheckFunctionExists.c.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CheckFunctionExists.c -Linking C executable cmTC_ce6d0 -/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_ce6d0.dir/link.txt --verbose=1 -/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -rdynamic CMakeFiles/cmTC_ce6d0.dir/CheckFunctionExists.c.o -o cmTC_ce6d0 -lpthreads -/usr/bin/ld: cannot find -lpthreads -collect2: error: ld returned 1 exit status -CMakeFiles/cmTC_ce6d0.dir/build.make:106: recipe for target 'cmTC_ce6d0' failed -make[1]: *** [cmTC_ce6d0] Error 1 -make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Makefile:141: recipe for target 'cmTC_ce6d0/fast' failed -make: *** [cmTC_ce6d0/fast] Error 2 - - - diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeOutput.log b/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeOutput.log deleted file mode 100644 index 73cebf5..0000000 --- a/GPU_version/vio/cmake-build-debug/CMakeFiles/CMakeOutput.log +++ /dev/null @@ -1,522 +0,0 @@ -The system is: Linux - 5.8.0-48-generic - x86_64 -Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded. -Compiler: /usr/bin/cc -Build flags: -Id flags: - -The output was: -0 - - -Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "a.out" - -The C compiler identification is GNU, found in "/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdC/a.out" - -Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded. -Compiler: /usr/bin/c++ -Build flags: -Id flags: - -The output was: -0 - - -Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out" - -The CXX compiler identification is GNU, found in "/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/3.17.5/CompilerIdCXX/a.out" - -Determining if the C compiler works passed with the following output: -Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp - -Run Build Command(s):/usr/bin/make cmTC_06aef/fast && /usr/bin/make -f CMakeFiles/cmTC_06aef.dir/build.make CMakeFiles/cmTC_06aef.dir/build -make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Building C object CMakeFiles/cmTC_06aef.dir/testCCompiler.c.o -/usr/bin/cc -o CMakeFiles/cmTC_06aef.dir/testCCompiler.c.o -c /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/testCCompiler.c -Linking C executable cmTC_06aef -/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_06aef.dir/link.txt --verbose=1 -/usr/bin/cc -rdynamic CMakeFiles/cmTC_06aef.dir/testCCompiler.c.o -o cmTC_06aef -make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' - - - -Detecting C compiler ABI info compiled with the following output: -Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp - -Run Build Command(s):/usr/bin/make cmTC_4d3e9/fast && /usr/bin/make -f CMakeFiles/cmTC_4d3e9.dir/build.make CMakeFiles/cmTC_4d3e9.dir/build -make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Building C object CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -/usr/bin/cc -v -o CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCCompilerABI.c -Using built-in specs. -COLLECT_GCC=/usr/bin/cc -OFFLOAD_TARGET_NAMES=nvptx-none -OFFLOAD_TARGET_DEFAULT=1 -Target: x86_64-linux-gnu -Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu -Thread model: posix -gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) -COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' - /usr/lib/gcc/x86_64-linux-gnu/7/cc1 -quiet -v -imultiarch x86_64-linux-gnu /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCCompilerABI.c -quiet -dumpbase CMakeCCompilerABI.c -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccW0mWjy.s -GNU C11 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu) - compiled by GNU C version 7.5.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP - -GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 -ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" -ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/7/../../../../x86_64-linux-gnu/include" -#include "..." search starts here: -#include <...> search starts here: - /usr/lib/gcc/x86_64-linux-gnu/7/include - /usr/local/include - /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed - /usr/include/x86_64-linux-gnu - /usr/include -End of search list. -GNU C11 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu) - compiled by GNU C version 7.5.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP - -GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 -Compiler executable checksum: b62ed4a2880cd4159476ea8293b72fa8 -COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' - as -v --64 -o CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o /tmp/ccW0mWjy.s -GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.30 -COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/ -LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/ -COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' -Linking C executable cmTC_4d3e9 -/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_4d3e9.dir/link.txt --verbose=1 -/usr/bin/cc -v -rdynamic CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -o cmTC_4d3e9 -Using built-in specs. -COLLECT_GCC=/usr/bin/cc -COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -OFFLOAD_TARGET_NAMES=nvptx-none -OFFLOAD_TARGET_DEFAULT=1 -Target: x86_64-linux-gnu -Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu -Thread model: posix -gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) -COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/ -LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/ -COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_4d3e9' '-mtune=generic' '-march=x86-64' - /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/cckCIR5B.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_4d3e9 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o -COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_4d3e9' '-mtune=generic' '-march=x86-64' -make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' - - - -Parsed C implicit include dir info from above output: rv=done - found start of include info - found start of implicit include info - add: [/usr/lib/gcc/x86_64-linux-gnu/7/include] - add: [/usr/local/include] - add: [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] - add: [/usr/include/x86_64-linux-gnu] - add: [/usr/include] - end of search list found - collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/7/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/7/include] - collapse include dir [/usr/local/include] ==> [/usr/local/include] - collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] ==> [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] - collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu] - collapse include dir [/usr/include] ==> [/usr/include] - implicit include dirs: [/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include] - - -Parsed C implicit link information from above output: - link line regex: [^( *|.*[/\])(ld|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)] - ignore line: [Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp] - ignore line: [] - ignore line: [Run Build Command(s):/usr/bin/make cmTC_4d3e9/fast && /usr/bin/make -f CMakeFiles/cmTC_4d3e9.dir/build.make CMakeFiles/cmTC_4d3e9.dir/build] - ignore line: [make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp'] - ignore line: [Building C object CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o] - ignore line: [/usr/bin/cc -v -o CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCCompilerABI.c] - ignore line: [Using built-in specs.] - ignore line: [COLLECT_GCC=/usr/bin/cc] - ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none] - ignore line: [OFFLOAD_TARGET_DEFAULT=1] - ignore line: [Target: x86_64-linux-gnu] - ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] - ignore line: [Thread model: posix] - ignore line: [gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) ] - ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'] - ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/cc1 -quiet -v -imultiarch x86_64-linux-gnu /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCCompilerABI.c -quiet -dumpbase CMakeCCompilerABI.c -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccW0mWjy.s] - ignore line: [GNU C11 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu)] - ignore line: [ compiled by GNU C version 7.5.0 GMP version 6.1.2 MPFR version 4.0.1 MPC version 1.1.0 isl version isl-0.19-GMP] - ignore line: [] - ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072] - ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"] - ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/7/../../../../x86_64-linux-gnu/include"] - ignore line: [#include "..." search starts here:] - ignore line: [#include <...> search starts here:] - ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/include] - ignore line: [ /usr/local/include] - ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] - ignore line: [ /usr/include/x86_64-linux-gnu] - ignore line: [ /usr/include] - ignore line: [End of search list.] - ignore line: [GNU C11 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu)] - ignore line: [ compiled by GNU C version 7.5.0 GMP version 6.1.2 MPFR version 4.0.1 MPC version 1.1.0 isl version isl-0.19-GMP] - ignore line: [] - ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072] - ignore line: [Compiler executable checksum: b62ed4a2880cd4159476ea8293b72fa8] - ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'] - ignore line: [ as -v --64 -o CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o /tmp/ccW0mWjy.s] - ignore line: [GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.30] - ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/] - ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/] - ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'] - ignore line: [Linking C executable cmTC_4d3e9] - ignore line: [/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_4d3e9.dir/link.txt --verbose=1] - ignore line: [/usr/bin/cc -v -rdynamic CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -o cmTC_4d3e9 ] - ignore line: [Using built-in specs.] - ignore line: [COLLECT_GCC=/usr/bin/cc] - ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper] - ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none] - ignore line: [OFFLOAD_TARGET_DEFAULT=1] - ignore line: [Target: x86_64-linux-gnu] - ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] - ignore line: [Thread model: posix] - ignore line: [gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) ] - ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/] - ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/] - ignore line: [COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_4d3e9' '-mtune=generic' '-march=x86-64'] - link line: [ /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/cckCIR5B.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_4d3e9 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o] - arg [/usr/lib/gcc/x86_64-linux-gnu/7/collect2] ==> ignore - arg [-plugin] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so] ==> ignore - arg [-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper] ==> ignore - arg [-plugin-opt=-fresolution=/tmp/cckCIR5B.res] ==> ignore - arg [-plugin-opt=-pass-through=-lgcc] ==> ignore - arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore - arg [-plugin-opt=-pass-through=-lc] ==> ignore - arg [-plugin-opt=-pass-through=-lgcc] ==> ignore - arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore - arg [--build-id] ==> ignore - arg [--eh-frame-hdr] ==> ignore - arg [-m] ==> ignore - arg [elf_x86_64] ==> ignore - arg [--hash-style=gnu] ==> ignore - arg [--as-needed] ==> ignore - arg [-export-dynamic] ==> ignore - arg [-dynamic-linker] ==> ignore - arg [/lib64/ld-linux-x86-64.so.2] ==> ignore - arg [-pie] ==> ignore - arg [-znow] ==> ignore - arg [-zrelro] ==> ignore - arg [-o] ==> ignore - arg [cmTC_4d3e9] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o] ==> ignore - arg [-L/usr/lib/gcc/x86_64-linux-gnu/7] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7] - arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] - arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] - arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu] - arg [-L/lib/../lib] ==> dir [/lib/../lib] - arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu] - arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] - arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../..] - arg [CMakeFiles/cmTC_4d3e9.dir/CMakeCCompilerABI.c.o] ==> ignore - arg [-lgcc] ==> lib [gcc] - arg [--push-state] ==> ignore - arg [--as-needed] ==> ignore - arg [-lgcc_s] ==> lib [gcc_s] - arg [--pop-state] ==> ignore - arg [-lc] ==> lib [c] - arg [-lgcc] ==> lib [gcc] - arg [--push-state] ==> ignore - arg [--as-needed] ==> ignore - arg [-lgcc_s] ==> lib [gcc_s] - arg [--pop-state] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o] ==> ignore - collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7] ==> [/usr/lib/gcc/x86_64-linux-gnu/7] - collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] - collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] ==> [/usr/lib] - collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu] - collapse library dir [/lib/../lib] ==> [/lib] - collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] - collapse library dir [/usr/lib/../lib] ==> [/usr/lib] - collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../..] ==> [/usr/lib] - implicit libs: [gcc;gcc_s;c;gcc;gcc_s] - implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/7;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib] - implicit fwks: [] - - -Determining if the CXX compiler works passed with the following output: -Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp - -Run Build Command(s):/usr/bin/make cmTC_36240/fast && /usr/bin/make -f CMakeFiles/cmTC_36240.dir/build.make CMakeFiles/cmTC_36240.dir/build -make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Building CXX object CMakeFiles/cmTC_36240.dir/testCXXCompiler.cxx.o -/usr/bin/c++ -o CMakeFiles/cmTC_36240.dir/testCXXCompiler.cxx.o -c /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/testCXXCompiler.cxx -Linking CXX executable cmTC_36240 -/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_36240.dir/link.txt --verbose=1 -/usr/bin/c++ -rdynamic CMakeFiles/cmTC_36240.dir/testCXXCompiler.cxx.o -o cmTC_36240 -make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' - - - -Detecting CXX compiler ABI info compiled with the following output: -Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp - -Run Build Command(s):/usr/bin/make cmTC_bddc5/fast && /usr/bin/make -f CMakeFiles/cmTC_bddc5.dir/build.make CMakeFiles/cmTC_bddc5.dir/build -make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Building CXX object CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -/usr/bin/c++ -v -o CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCXXCompilerABI.cpp -Using built-in specs. -COLLECT_GCC=/usr/bin/c++ -OFFLOAD_TARGET_NAMES=nvptx-none -OFFLOAD_TARGET_DEFAULT=1 -Target: x86_64-linux-gnu -Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu -Thread model: posix -gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) -COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' - /usr/lib/gcc/x86_64-linux-gnu/7/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpbase CMakeCXXCompilerABI.cpp -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccEVgspL.s -GNU C++14 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu) - compiled by GNU C version 7.5.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP - -GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 -ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/7" -ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" -ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/7/../../../../x86_64-linux-gnu/include" -#include "..." search starts here: -#include <...> search starts here: - /usr/include/c++/7 - /usr/include/x86_64-linux-gnu/c++/7 - /usr/include/c++/7/backward - /usr/lib/gcc/x86_64-linux-gnu/7/include - /usr/local/include - /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed - /usr/include/x86_64-linux-gnu - /usr/include -End of search list. -GNU C++14 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu) - compiled by GNU C version 7.5.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP - -GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 -Compiler executable checksum: 3eb3dc290cd5714c3e1c3ae751116f07 -COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' - as -v --64 -o CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccEVgspL.s -GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.30 -COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/ -LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/ -COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' -Linking CXX executable cmTC_bddc5 -/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_bddc5.dir/link.txt --verbose=1 -/usr/bin/c++ -v -rdynamic CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_bddc5 -Using built-in specs. -COLLECT_GCC=/usr/bin/c++ -COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -OFFLOAD_TARGET_NAMES=nvptx-none -OFFLOAD_TARGET_DEFAULT=1 -Target: x86_64-linux-gnu -Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu -Thread model: posix -gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) -COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/ -LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/ -COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_bddc5' '-shared-libgcc' '-mtune=generic' '-march=x86-64' - /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/cckr006M.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_bddc5 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o -COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_bddc5' '-shared-libgcc' '-mtune=generic' '-march=x86-64' -make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' - - - -Parsed CXX implicit include dir info from above output: rv=done - found start of include info - found start of implicit include info - add: [/usr/include/c++/7] - add: [/usr/include/x86_64-linux-gnu/c++/7] - add: [/usr/include/c++/7/backward] - add: [/usr/lib/gcc/x86_64-linux-gnu/7/include] - add: [/usr/local/include] - add: [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] - add: [/usr/include/x86_64-linux-gnu] - add: [/usr/include] - end of search list found - collapse include dir [/usr/include/c++/7] ==> [/usr/include/c++/7] - collapse include dir [/usr/include/x86_64-linux-gnu/c++/7] ==> [/usr/include/x86_64-linux-gnu/c++/7] - collapse include dir [/usr/include/c++/7/backward] ==> [/usr/include/c++/7/backward] - collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/7/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/7/include] - collapse include dir [/usr/local/include] ==> [/usr/local/include] - collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] ==> [/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] - collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu] - collapse include dir [/usr/include] ==> [/usr/include] - implicit include dirs: [/usr/include/c++/7;/usr/include/x86_64-linux-gnu/c++/7;/usr/include/c++/7/backward;/usr/lib/gcc/x86_64-linux-gnu/7/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed;/usr/include/x86_64-linux-gnu;/usr/include] - - -Parsed CXX implicit link information from above output: - link line regex: [^( *|.*[/\])(ld|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)] - ignore line: [Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp] - ignore line: [] - ignore line: [Run Build Command(s):/usr/bin/make cmTC_bddc5/fast && /usr/bin/make -f CMakeFiles/cmTC_bddc5.dir/build.make CMakeFiles/cmTC_bddc5.dir/build] - ignore line: [make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp'] - ignore line: [Building CXX object CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o] - ignore line: [/usr/bin/c++ -v -o CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCXXCompilerABI.cpp] - ignore line: [Using built-in specs.] - ignore line: [COLLECT_GCC=/usr/bin/c++] - ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none] - ignore line: [OFFLOAD_TARGET_DEFAULT=1] - ignore line: [Target: x86_64-linux-gnu] - ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] - ignore line: [Thread model: posix] - ignore line: [gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) ] - ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'] - ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpbase CMakeCXXCompilerABI.cpp -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccEVgspL.s] - ignore line: [GNU C++14 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu)] - ignore line: [ compiled by GNU C version 7.5.0 GMP version 6.1.2 MPFR version 4.0.1 MPC version 1.1.0 isl version isl-0.19-GMP] - ignore line: [] - ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072] - ignore line: [ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/7"] - ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"] - ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/7/../../../../x86_64-linux-gnu/include"] - ignore line: [#include "..." search starts here:] - ignore line: [#include <...> search starts here:] - ignore line: [ /usr/include/c++/7] - ignore line: [ /usr/include/x86_64-linux-gnu/c++/7] - ignore line: [ /usr/include/c++/7/backward] - ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/include] - ignore line: [ /usr/local/include] - ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed] - ignore line: [ /usr/include/x86_64-linux-gnu] - ignore line: [ /usr/include] - ignore line: [End of search list.] - ignore line: [GNU C++14 (Ubuntu 7.5.0-3ubuntu1~18.04) version 7.5.0 (x86_64-linux-gnu)] - ignore line: [ compiled by GNU C version 7.5.0 GMP version 6.1.2 MPFR version 4.0.1 MPC version 1.1.0 isl version isl-0.19-GMP] - ignore line: [] - ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072] - ignore line: [Compiler executable checksum: 3eb3dc290cd5714c3e1c3ae751116f07] - ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'] - ignore line: [ as -v --64 -o CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccEVgspL.s] - ignore line: [GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.30] - ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/] - ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/] - ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'] - ignore line: [Linking CXX executable cmTC_bddc5] - ignore line: [/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_bddc5.dir/link.txt --verbose=1] - ignore line: [/usr/bin/c++ -v -rdynamic CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_bddc5 ] - ignore line: [Using built-in specs.] - ignore line: [COLLECT_GCC=/usr/bin/c++] - ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper] - ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none] - ignore line: [OFFLOAD_TARGET_DEFAULT=1] - ignore line: [Target: x86_64-linux-gnu] - ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] - ignore line: [Thread model: posix] - ignore line: [gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) ] - ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/] - ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/7/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/7/../../../:/lib/:/usr/lib/] - ignore line: [COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_bddc5' '-shared-libgcc' '-mtune=generic' '-march=x86-64'] - link line: [ /usr/lib/gcc/x86_64-linux-gnu/7/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper -plugin-opt=-fresolution=/tmp/cckr006M.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_bddc5 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/7 -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o] - arg [/usr/lib/gcc/x86_64-linux-gnu/7/collect2] ==> ignore - arg [-plugin] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so] ==> ignore - arg [-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper] ==> ignore - arg [-plugin-opt=-fresolution=/tmp/cckr006M.res] ==> ignore - arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore - arg [-plugin-opt=-pass-through=-lgcc] ==> ignore - arg [-plugin-opt=-pass-through=-lc] ==> ignore - arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore - arg [-plugin-opt=-pass-through=-lgcc] ==> ignore - arg [--build-id] ==> ignore - arg [--eh-frame-hdr] ==> ignore - arg [-m] ==> ignore - arg [elf_x86_64] ==> ignore - arg [--hash-style=gnu] ==> ignore - arg [--as-needed] ==> ignore - arg [-export-dynamic] ==> ignore - arg [-dynamic-linker] ==> ignore - arg [/lib64/ld-linux-x86-64.so.2] ==> ignore - arg [-pie] ==> ignore - arg [-znow] ==> ignore - arg [-zrelro] ==> ignore - arg [-o] ==> ignore - arg [cmTC_bddc5] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o] ==> ignore - arg [-L/usr/lib/gcc/x86_64-linux-gnu/7] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7] - arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] - arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] - arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu] - arg [-L/lib/../lib] ==> dir [/lib/../lib] - arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu] - arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] - arg [-L/usr/lib/gcc/x86_64-linux-gnu/7/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../..] - arg [CMakeFiles/cmTC_bddc5.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore - arg [-lstdc++] ==> lib [stdc++] - arg [-lm] ==> lib [m] - arg [-lgcc_s] ==> lib [gcc_s] - arg [-lgcc] ==> lib [gcc] - arg [-lc] ==> lib [c] - arg [-lgcc_s] ==> lib [gcc_s] - arg [-lgcc] ==> lib [gcc] - arg [/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o] ==> ignore - arg [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o] ==> ignore - collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7] ==> [/usr/lib/gcc/x86_64-linux-gnu/7] - collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] - collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib] ==> [/usr/lib] - collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu] - collapse library dir [/lib/../lib] ==> [/lib] - collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] - collapse library dir [/usr/lib/../lib] ==> [/usr/lib] - collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/7/../../..] ==> [/usr/lib] - implicit libs: [stdc++;m;gcc_s;gcc;c;gcc_s;gcc] - implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/7;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib] - implicit fwks: [] - - -Determining if the include file pthread.h exists passed with the following output: -Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp - -Run Build Command(s):/usr/bin/make cmTC_7a980/fast && /usr/bin/make -f CMakeFiles/cmTC_7a980.dir/build.make CMakeFiles/cmTC_7a980.dir/build -make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Building C object CMakeFiles/cmTC_7a980.dir/CheckIncludeFile.c.o -/usr/bin/cc -o CMakeFiles/cmTC_7a980.dir/CheckIncludeFile.c.o -c /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/CheckIncludeFile.c -Linking C executable cmTC_7a980 -/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_7a980.dir/link.txt --verbose=1 -/usr/bin/cc -rdynamic CMakeFiles/cmTC_7a980.dir/CheckIncludeFile.c.o -o cmTC_7a980 -make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' - - - -Determining if the function pthread_create exists in the pthread passed with the following output: -Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp - -Run Build Command(s):/usr/bin/make cmTC_1a96d/fast && /usr/bin/make -f CMakeFiles/cmTC_1a96d.dir/build.make CMakeFiles/cmTC_1a96d.dir/build -make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Building C object CMakeFiles/cmTC_1a96d.dir/CheckFunctionExists.c.o -/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -o CMakeFiles/cmTC_1a96d.dir/CheckFunctionExists.c.o -c /opt/clion-2020.3.2/bin/cmake/linux/share/cmake-3.17/Modules/CheckFunctionExists.c -Linking C executable cmTC_1a96d -/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_1a96d.dir/link.txt --verbose=1 -/usr/bin/cc -DCHECK_FUNCTION_EXISTS=pthread_create -rdynamic CMakeFiles/cmTC_1a96d.dir/CheckFunctionExists.c.o -o cmTC_1a96d -lpthread -make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' - - - -Determining if the CL_VERSION_2_2 exist passed with the following output: -Change Dir: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp - -Run Build Command(s):/usr/bin/make cmTC_fdf34/fast && /usr/bin/make -f CMakeFiles/cmTC_fdf34.dir/build.make CMakeFiles/cmTC_fdf34.dir/build -make[1]: Entering directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' -Building C object CMakeFiles/cmTC_fdf34.dir/CheckSymbolExists.c.o -/usr/bin/cc -o CMakeFiles/cmTC_fdf34.dir/CheckSymbolExists.c.o -c /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTC_fdf34 -/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -E cmake_link_script CMakeFiles/cmTC_fdf34.dir/link.txt --verbose=1 -/usr/bin/cc -rdynamic CMakeFiles/cmTC_fdf34.dir/CheckSymbolExists.c.o -o cmTC_fdf34 -make[1]: Leaving directory '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp' - - -File /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -int main(int argc, char** argv) -{ - (void)argv; -#ifndef CL_VERSION_2_2 - return ((int*)(&CL_VERSION_2_2))[argc]; -#else - (void)argc; - return 0; -#endif -} diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-environment.txt b/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-environment.txt deleted file mode 100644 index 270d93c..0000000 --- a/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-environment.txt +++ /dev/null @@ -1,3 +0,0 @@ -ToolSet: 1.0 (local)Options: - -Options: \ No newline at end of file diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-log.txt b/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-log.txt deleted file mode 100644 index 1363506..0000000 --- a/GPU_version/vio/cmake-build-debug/CMakeFiles/clion-log.txt +++ /dev/null @@ -1,70 +0,0 @@ -/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - Unix Makefiles" /root/Project/ROS/src/vio_svo/GPU_version/svo --- The C compiler identification is GNU 7.5.0 --- The CXX compiler identification is GNU 7.5.0 --- Check for working C compiler: /usr/bin/cc --- Check for working C compiler: /usr/bin/cc - works --- Detecting C compiler ABI info --- Detecting C compiler ABI info - done --- Detecting C compile features --- Detecting C compile features - done --- Check for working CXX compiler: /usr/bin/c++ --- Check for working CXX compiler: /usr/bin/c++ - works --- Detecting CXX compiler ABI info --- Detecting CXX compiler ABI info - done --- Detecting CXX compile features --- Detecting CXX compile features - done --- Found OpenCV: /usr (found suitable version "3.2.0", minimum required is "3") --- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1") --- Checking for module 'eigen3' --- Found eigen3, version 3.3.4 --- Found Eigen: /usr/include/eigen3 --- Eigen found (include: /usr/include/eigen3) --- Looking for pthread.h --- Looking for pthread.h - found --- Performing Test CMAKE_HAVE_LIBC_PTHREAD --- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed --- Looking for pthread_create in pthreads --- Looking for pthread_create in pthreads - not found --- Looking for pthread_create in pthread --- Looking for pthread_create in pthread - found --- Found Threads: TRUE --- Found Boost: /usr/include (found version "1.65.1") found components: thread system chrono date_time atomic --- Looking for CL_VERSION_2_2 --- Looking for CL_VERSION_2_2 - found --- Found OpenCL: /usr/lib/x86_64-linux-gnu/libOpenCL.so (found version "2.2") --- Using CATKIN_DEVEL_PREFIX: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel --- Using CMAKE_PREFIX_PATH: /opt/ros/melodic --- This workspace overlays: /opt/ros/melodic --- Found PythonInterp: /usr/bin/python2 (found suitable version "2.7.17", minimum required is "2") --- Using PYTHON_EXECUTABLE: /usr/bin/python2 --- Using Debian Python package layout --- Using empy: /usr/bin/empy --- Using CATKIN_ENABLE_TESTING: ON --- Call enable_testing() --- Using CATKIN_TEST_RESULTS_DIR: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/test_results --- Found gtest sources under '/usr/src/googletest': gtests will be built --- Found gmock sources under '/usr/src/googletest': gmock will be built --- Found PythonInterp: /usr/bin/python2 (found version "2.7.17") --- Using Python nosetests: /usr/bin/nosetests-2.7 --- catkin 0.7.28 --- BUILD_SHARED_LIBS is on --- Could NOT find robot_localization (missing: robot_localization_DIR) --- Could not find the required component 'robot_localization'. The following CMake error indicates that you either need to install the package with the same name or change your environment so that it can be found. -CMake Error at /opt/ros/melodic/share/catkin/cmake/catkinConfig.cmake:83 (find_package): - Could not find a package configuration file provided by - "robot_localization" with any of the following names: - - robot_localizationConfig.cmake - robot_localization-config.cmake - - Add the installation prefix of "robot_localization" to CMAKE_PREFIX_PATH or - set "robot_localization_DIR" to a directory containing one of the above - files. If "robot_localization" provides a separate development package or - SDK, be sure it has been installed. -Call Stack (most recent call first): - CMakeLists.txt:34 (FIND_PACKAGE) - - --- Configuring incomplete, errors occurred! -See also "/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeOutput.log". -See also "/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/CMakeFiles/CMakeError.log". diff --git a/GPU_version/vio/cmake-build-debug/CMakeFiles/cmake.check_cache b/GPU_version/vio/cmake-build-debug/CMakeFiles/cmake.check_cache deleted file mode 100644 index 3dccd73..0000000 --- a/GPU_version/vio/cmake-build-debug/CMakeFiles/cmake.check_cache +++ /dev/null @@ -1 +0,0 @@ -# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/GPU_version/vio/cmake-build-debug/CTestConfiguration.ini b/GPU_version/vio/cmake-build-debug/CTestConfiguration.ini deleted file mode 100644 index 38e6ab1..0000000 --- a/GPU_version/vio/cmake-build-debug/CTestConfiguration.ini +++ /dev/null @@ -1,107 +0,0 @@ -# This file is configured by CMake automatically as DartConfiguration.tcl -# If you choose not to use CMake, this file may be hand configured, by -# filling in the required variables. - - -# Configuration directories and files -SourceDirectory: /root/Project/ROS/src/vio_svo/GPU_version/svo -BuildDirectory: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug - -# Where to place the cost data store -CostDataFile: - -# Site is something like machine.domain, i.e. pragmatic.crd -Site: gfuse - -# Build name is osname-revision-compiler, i.e. Linux-2.4.2-2smp-c++ -BuildName: - -# Subprojects -LabelsForSubprojects: - -# Submission information -SubmitURL: - -# Dashboard start time -NightlyStartTime: - -# Commands for the build/test/submit cycle -ConfigureCommand: "/opt/clion-2020.3.2/bin/cmake/linux/bin/cmake" "/root/Project/ROS/src/vio_svo/GPU_version/svo" -MakeCommand: -DefaultCTestConfigurationType: - -# version control -UpdateVersionOnly: - -# CVS options -# Default is "-d -P -A" -CVSCommand: -CVSUpdateOptions: - -# Subversion options -SVNCommand: -SVNOptions: -SVNUpdateOptions: - -# Git options -GITCommand: -GITInitSubmodules: -GITUpdateOptions: -GITUpdateCustom: - -# Perforce options -P4Command: -P4Client: -P4Options: -P4UpdateOptions: -P4UpdateCustom: - -# Generic update command -UpdateCommand: -UpdateOptions: -UpdateType: - -# Compiler info -Compiler: /usr/bin/c++ -CompilerVersion: 7.5.0 - -# Dynamic analysis (MemCheck) -PurifyCommand: -ValgrindCommand: -ValgrindCommandOptions: -DrMemoryCommand: -DrMemoryCommandOptions: -MemoryCheckType: -MemoryCheckSanitizerOptions: -MemoryCheckCommand: -MemoryCheckCommandOptions: -MemoryCheckSuppressionFile: - -# Coverage -CoverageCommand: -CoverageExtraFlags: - -# Cluster commands -SlurmBatchCommand: -SlurmRunCommand: - -# Testing options -# TimeOut is the amount of time in seconds to wait for processes -# to complete during testing. After TimeOut seconds, the -# process will be summarily terminated. -# Currently set to 25 minutes -TimeOut: - -# During parallel testing CTest will not start a new test if doing -# so would cause the system load to exceed this value. -TestLoad: - -UseLaunchers: -CurlOptions: -# warning, if you add new options here that have to do with submit, -# you have to update cmCTestSubmitCommand.cxx - -# For CTest submissions that timeout, these options -# specify behavior for retrying the submission -CTestSubmitRetryDelay: -CTestSubmitRetryCount: diff --git a/GPU_version/vio/cmake-build-debug/CTestCustom.cmake b/GPU_version/vio/cmake-build-debug/CTestCustom.cmake deleted file mode 100644 index 14956f3..0000000 --- a/GPU_version/vio/cmake-build-debug/CTestCustom.cmake +++ /dev/null @@ -1,2 +0,0 @@ -set(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 0) -set(CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE 0) diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/.rosinstall b/GPU_version/vio/cmake-build-debug/atomic_configure/.rosinstall deleted file mode 100644 index b61ff9e..0000000 --- a/GPU_version/vio/cmake-build-debug/atomic_configure/.rosinstall +++ /dev/null @@ -1,2 +0,0 @@ -- setup-file: - local-name: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel/setup.sh diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/_setup_util.py b/GPU_version/vio/cmake-build-debug/atomic_configure/_setup_util.py deleted file mode 100755 index 760f26f..0000000 --- a/GPU_version/vio/cmake-build-debug/atomic_configure/_setup_util.py +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/python2 -# -*- coding: utf-8 -*- - -# Software License Agreement (BSD License) -# -# Copyright (c) 2012, Willow Garage, Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Willow Garage, Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -"""This file generates shell code for the setup.SHELL scripts to set environment variables.""" - -from __future__ import print_function - -import argparse -import copy -import errno -import os -import platform -import sys - -CATKIN_MARKER_FILE = '.catkin' - -system = platform.system() -IS_DARWIN = (system == 'Darwin') -IS_WINDOWS = (system == 'Windows') - -PATH_TO_ADD_SUFFIX = ['bin'] -if IS_WINDOWS: - # while catkin recommends putting dll's into bin, 3rd party packages often put dll's into lib - # since Windows finds dll's via the PATH variable, prepend it with path to lib - PATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'x86_64-linux-gnu')]]) - -# subfolder of workspace prepended to CMAKE_PREFIX_PATH -ENV_VAR_SUBFOLDERS = { - 'CMAKE_PREFIX_PATH': '', - 'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'x86_64-linux-gnu')], - 'PATH': PATH_TO_ADD_SUFFIX, - 'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'x86_64-linux-gnu', 'pkgconfig')], - 'PYTHONPATH': 'lib/python2.7/dist-packages', -} - - -def rollback_env_variables(environ, env_var_subfolders): - """ - Generate shell code to reset environment variables. - - by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH. - This does not cover modifications performed by environment hooks. - """ - lines = [] - unmodified_environ = copy.copy(environ) - for key in sorted(env_var_subfolders.keys()): - subfolders = env_var_subfolders[key] - if not isinstance(subfolders, list): - subfolders = [subfolders] - value = _rollback_env_variable(unmodified_environ, key, subfolders) - if value is not None: - environ[key] = value - lines.append(assignment(key, value)) - if lines: - lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH')) - return lines - - -def _rollback_env_variable(environ, name, subfolders): - """ - For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder. - - :param subfolders: list of str '' or subfoldername that may start with '/' - :returns: the updated value of the environment variable. - """ - value = environ[name] if name in environ else '' - env_paths = [path for path in value.split(os.pathsep) if path] - value_modified = False - for subfolder in subfolders: - if subfolder: - if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)): - subfolder = subfolder[1:] - if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)): - subfolder = subfolder[:-1] - for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True): - path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path - path_to_remove = None - for env_path in env_paths: - env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path - if env_path_clean == path_to_find: - path_to_remove = env_path - break - if path_to_remove: - env_paths.remove(path_to_remove) - value_modified = True - new_value = os.pathsep.join(env_paths) - return new_value if value_modified else None - - -def _get_workspaces(environ, include_fuerte=False, include_non_existing=False): - """ - Based on CMAKE_PREFIX_PATH return all catkin workspaces. - - :param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool`` - """ - # get all cmake prefix paths - env_name = 'CMAKE_PREFIX_PATH' - value = environ[env_name] if env_name in environ else '' - paths = [path for path in value.split(os.pathsep) if path] - # remove non-workspace paths - workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))] - return workspaces - - -def prepend_env_variables(environ, env_var_subfolders, workspaces): - """Generate shell code to prepend environment variables for the all workspaces.""" - lines = [] - lines.append(comment('prepend folders of workspaces to environment variables')) - - paths = [path for path in workspaces.split(os.pathsep) if path] - - prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '') - lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix)) - - for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'): - subfolder = env_var_subfolders[key] - prefix = _prefix_env_variable(environ, key, paths, subfolder) - lines.append(prepend(environ, key, prefix)) - return lines - - -def _prefix_env_variable(environ, name, paths, subfolders): - """ - Return the prefix to prepend to the environment variable NAME. - - Adding any path in NEW_PATHS_STR without creating duplicate or empty items. - """ - value = environ[name] if name in environ else '' - environ_paths = [path for path in value.split(os.pathsep) if path] - checked_paths = [] - for path in paths: - if not isinstance(subfolders, list): - subfolders = [subfolders] - for subfolder in subfolders: - path_tmp = path - if subfolder: - path_tmp = os.path.join(path_tmp, subfolder) - # skip nonexistent paths - if not os.path.exists(path_tmp): - continue - # exclude any path already in env and any path we already added - if path_tmp not in environ_paths and path_tmp not in checked_paths: - checked_paths.append(path_tmp) - prefix_str = os.pathsep.join(checked_paths) - if prefix_str != '' and environ_paths: - prefix_str += os.pathsep - return prefix_str - - -def assignment(key, value): - if not IS_WINDOWS: - return 'export %s="%s"' % (key, value) - else: - return 'set %s=%s' % (key, value) - - -def comment(msg): - if not IS_WINDOWS: - return '# %s' % msg - else: - return 'REM %s' % msg - - -def prepend(environ, key, prefix): - if key not in environ or not environ[key]: - return assignment(key, prefix) - if not IS_WINDOWS: - return 'export %s="%s$%s"' % (key, prefix, key) - else: - return 'set %s=%s%%%s%%' % (key, prefix, key) - - -def find_env_hooks(environ, cmake_prefix_path): - """Generate shell code with found environment hooks for the all workspaces.""" - lines = [] - lines.append(comment('found environment hooks in workspaces')) - - generic_env_hooks = [] - generic_env_hooks_workspace = [] - specific_env_hooks = [] - specific_env_hooks_workspace = [] - generic_env_hooks_by_filename = {} - specific_env_hooks_by_filename = {} - generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh' - specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None - # remove non-workspace paths - workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))] - for workspace in reversed(workspaces): - env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d') - if os.path.isdir(env_hook_dir): - for filename in sorted(os.listdir(env_hook_dir)): - if filename.endswith('.%s' % generic_env_hook_ext): - # remove previous env hook with same name if present - if filename in generic_env_hooks_by_filename: - i = generic_env_hooks.index(generic_env_hooks_by_filename[filename]) - generic_env_hooks.pop(i) - generic_env_hooks_workspace.pop(i) - # append env hook - generic_env_hooks.append(os.path.join(env_hook_dir, filename)) - generic_env_hooks_workspace.append(workspace) - generic_env_hooks_by_filename[filename] = generic_env_hooks[-1] - elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext): - # remove previous env hook with same name if present - if filename in specific_env_hooks_by_filename: - i = specific_env_hooks.index(specific_env_hooks_by_filename[filename]) - specific_env_hooks.pop(i) - specific_env_hooks_workspace.pop(i) - # append env hook - specific_env_hooks.append(os.path.join(env_hook_dir, filename)) - specific_env_hooks_workspace.append(workspace) - specific_env_hooks_by_filename[filename] = specific_env_hooks[-1] - env_hooks = generic_env_hooks + specific_env_hooks - env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace - count = len(env_hooks) - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count)) - for i in range(count): - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i])) - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i])) - return lines - - -def _parse_arguments(args=None): - parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.') - parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context') - parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment') - return parser.parse_known_args(args=args)[0] - - -if __name__ == '__main__': - try: - try: - args = _parse_arguments() - except Exception as e: - print(e, file=sys.stderr) - sys.exit(1) - - if not args.local: - # environment at generation time - CMAKE_PREFIX_PATH = '/opt/ros/melodic'.split(';') - else: - # don't consider any other prefix path than this one - CMAKE_PREFIX_PATH = [] - # prepend current workspace if not already part of CPP - base_path = os.path.dirname(__file__) - # CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent - # base_path on Windows contains backward slashes, need to be converted to forward slashes before comparison - if os.path.sep != '/': - base_path = base_path.replace(os.path.sep, '/') - - if base_path not in CMAKE_PREFIX_PATH: - CMAKE_PREFIX_PATH.insert(0, base_path) - CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH) - - environ = dict(os.environ) - lines = [] - if not args.extend: - lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS) - lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH) - lines += find_env_hooks(environ, CMAKE_PREFIX_PATH) - print('\n'.join(lines)) - - # need to explicitly flush the output - sys.stdout.flush() - except IOError as e: - # and catch potential "broken pipe" if stdout is not writable - # which can happen when piping the output to a file but the disk is full - if e.errno == errno.EPIPE: - print(e, file=sys.stderr) - sys.exit(2) - raise - - sys.exit(0) diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/env.sh b/GPU_version/vio/cmake-build-debug/atomic_configure/env.sh deleted file mode 100755 index 8aa9d24..0000000 --- a/GPU_version/vio/cmake-build-debug/atomic_configure/env.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/cmake/templates/env.sh.in - -if [ $# -eq 0 ] ; then - /bin/echo "Usage: env.sh COMMANDS" - /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." - exit 1 -fi - -# ensure to not use different shell type which was set before -CATKIN_SHELL=sh - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) -. "$_CATKIN_SETUP_DIR/setup.sh" -exec "$@" diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.bash b/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.bash deleted file mode 100644 index 7da0d97..0000000 --- a/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.bash +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -# generated from catkin/cmake/templates/local_setup.bash.in - -CATKIN_SHELL=bash - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) -. "$_CATKIN_SETUP_DIR/setup.sh" --extend --local diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.sh b/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.sh deleted file mode 100644 index d29ab41..0000000 --- a/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/cmake/template/local_setup.sh.in - -# since this file is sourced either use the provided _CATKIN_SETUP_DIR -# or fall back to the destination set at configure time -: ${_CATKIN_SETUP_DIR:=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel} -CATKIN_SETUP_UTIL_ARGS="--extend --local" -. "$_CATKIN_SETUP_DIR/setup.sh" -unset CATKIN_SETUP_UTIL_ARGS diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.zsh b/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.zsh deleted file mode 100644 index e692acc..0000000 --- a/GPU_version/vio/cmake-build-debug/atomic_configure/local_setup.zsh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env zsh -# generated from catkin/cmake/templates/local_setup.zsh.in - -CATKIN_SHELL=zsh - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) -emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh" --extend --local' diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/setup.bash b/GPU_version/vio/cmake-build-debug/atomic_configure/setup.bash deleted file mode 100644 index ff47af8..0000000 --- a/GPU_version/vio/cmake-build-debug/atomic_configure/setup.bash +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -# generated from catkin/cmake/templates/setup.bash.in - -CATKIN_SHELL=bash - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) -. "$_CATKIN_SETUP_DIR/setup.sh" diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/setup.sh b/GPU_version/vio/cmake-build-debug/atomic_configure/setup.sh deleted file mode 100644 index 1764d84..0000000 --- a/GPU_version/vio/cmake-build-debug/atomic_configure/setup.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/cmake/template/setup.sh.in - -# Sets various environment variables and sources additional environment hooks. -# It tries it's best to undo changes from a previously sourced setup file before. -# Supported command line options: -# --extend: skips the undoing of changes from a previously sourced setup file -# --local: only considers this workspace but not the chained ones -# In plain sh shell which doesn't support arguments for sourced scripts you can -# set the environment variable `CATKIN_SETUP_UTIL_ARGS=--extend/--local` instead. - -# since this file is sourced either use the provided _CATKIN_SETUP_DIR -# or fall back to the destination set at configure time -: ${_CATKIN_SETUP_DIR:=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel} -_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py" -unset _CATKIN_SETUP_DIR - -if [ ! -f "$_SETUP_UTIL" ]; then - echo "Missing Python script: $_SETUP_UTIL" - return 22 -fi - -# detect if running on Darwin platform -_UNAME=`uname -s` -_IS_DARWIN=0 -if [ "$_UNAME" = "Darwin" ]; then - _IS_DARWIN=1 -fi -unset _UNAME - -# make sure to export all environment variables -export CMAKE_PREFIX_PATH -if [ $_IS_DARWIN -eq 0 ]; then - export LD_LIBRARY_PATH -else - export DYLD_LIBRARY_PATH -fi -unset _IS_DARWIN -export PATH -export PKG_CONFIG_PATH -export PYTHONPATH - -# remember type of shell if not already set -if [ -z "$CATKIN_SHELL" ]; then - CATKIN_SHELL=sh -fi - -# invoke Python script to generate necessary exports of environment variables -# use TMPDIR if it exists, otherwise fall back to /tmp -if [ -d "${TMPDIR:-}" ]; then - _TMPDIR="${TMPDIR}" -else - _TMPDIR=/tmp -fi -_SETUP_TMP=`mktemp "${_TMPDIR}/setup.sh.XXXXXXXXXX"` -unset _TMPDIR -if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; then - echo "Could not create temporary file: $_SETUP_TMP" - return 1 -fi -CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ ${CATKIN_SETUP_UTIL_ARGS:-} >> "$_SETUP_TMP" -_RC=$? -if [ $_RC -ne 0 ]; then - if [ $_RC -eq 2 ]; then - echo "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?" - else - echo "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC" - fi - unset _RC - unset _SETUP_UTIL - rm -f "$_SETUP_TMP" - unset _SETUP_TMP - return 1 -fi -unset _RC -unset _SETUP_UTIL -. "$_SETUP_TMP" -rm -f "$_SETUP_TMP" -unset _SETUP_TMP - -# source all environment hooks -_i=0 -while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; do - eval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_i - unset _CATKIN_ENVIRONMENT_HOOKS_$_i - eval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE - unset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE - # set workspace for environment hook - CATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace - . "$_envfile" - unset CATKIN_ENV_HOOK_WORKSPACE - _i=$((_i + 1)) -done -unset _i - -unset _CATKIN_ENVIRONMENT_HOOKS_COUNT diff --git a/GPU_version/vio/cmake-build-debug/atomic_configure/setup.zsh b/GPU_version/vio/cmake-build-debug/atomic_configure/setup.zsh deleted file mode 100644 index 9f780b7..0000000 --- a/GPU_version/vio/cmake-build-debug/atomic_configure/setup.zsh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env zsh -# generated from catkin/cmake/templates/setup.zsh.in - -CATKIN_SHELL=zsh - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) -emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh"' diff --git a/GPU_version/vio/cmake-build-debug/catkin/catkin_generated/version/package.cmake b/GPU_version/vio/cmake-build-debug/catkin/catkin_generated/version/package.cmake deleted file mode 100644 index b3278c8..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin/catkin_generated/version/package.cmake +++ /dev/null @@ -1,24 +0,0 @@ -set(_CATKIN_CURRENT_PACKAGE "catkin") -set(catkin_VERSION "0.7.28") -set(catkin_MAINTAINER "Dirk Thomas ") -set(catkin_PACKAGE_FORMAT "3") -set(catkin_BUILD_DEPENDS "python-argparse" "python-catkin-pkg" "python3-catkin-pkg" "python-empy" "python3-empy") -set(catkin_BUILD_DEPENDS_python-catkin-pkg_VERSION_GT "0.4.3") -set(catkin_BUILD_DEPENDS_python3-catkin-pkg_VERSION_GT "0.4.3") -set(catkin_BUILD_EXPORT_DEPENDS "google-mock" "gtest" "python-nose" "python3-nose" "python-argparse" "python-catkin-pkg" "python3-catkin-pkg" "python-empy" "python3-empy") -set(catkin_BUILD_EXPORT_DEPENDS_python-catkin-pkg_VERSION_GT "0.4.3") -set(catkin_BUILD_EXPORT_DEPENDS_python3-catkin-pkg_VERSION_GT "0.4.3") -set(catkin_BUILDTOOL_DEPENDS "cmake" "python-setuptools" "python3-setuptools") -set(catkin_BUILDTOOL_EXPORT_DEPENDS "cmake" "python3-setuptools") -set(catkin_EXEC_DEPENDS "python-argparse" "python-catkin-pkg" "python3-catkin-pkg" "python-empy" "python3-empy") -set(catkin_EXEC_DEPENDS_python-catkin-pkg_VERSION_GT "0.4.3") -set(catkin_EXEC_DEPENDS_python3-catkin-pkg_VERSION_GT "0.4.3") -set(catkin_RUN_DEPENDS "python-argparse" "python-catkin-pkg" "python3-catkin-pkg" "python-empy" "python3-empy" "google-mock" "gtest" "python-nose" "python3-nose") -set(catkin_RUN_DEPENDS_python-catkin-pkg_VERSION_GT "0.4.3") -set(catkin_RUN_DEPENDS_python3-catkin-pkg_VERSION_GT "0.4.3") -set(catkin_TEST_DEPENDS "python-mock" "python3-mock" "python-nose" "python3-nose") -set(catkin_DOC_DEPENDS ) -set(catkin_URL_WEBSITE "http://wiki.ros.org/catkin") -set(catkin_URL_BUGTRACKER "https://github.com/ros/catkin/issues") -set(catkin_URL_REPOSITORY "https://github.com/ros/catkin") -set(catkin_DEPRECATED "") \ No newline at end of file diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/env_cached.sh b/GPU_version/vio/cmake-build-debug/catkin_generated/env_cached.sh deleted file mode 100755 index d6be91d..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/env_cached.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/cmake/templates/env.sh.in - -if [ $# -eq 0 ] ; then - /bin/echo "Usage: env.sh COMMANDS" - /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." - exit 1 -fi - -# ensure to not use different shell type which was set before -CATKIN_SHELL=sh - -# source setup_cached.sh from same directory as this file -_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) -. "$_CATKIN_SETUP_DIR/setup_cached.sh" -exec "$@" diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/generate_cached_setup.py b/GPU_version/vio/cmake-build-debug/catkin_generated/generate_cached_setup.py deleted file mode 100644 index b1f2d17..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/generate_cached_setup.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import print_function - -import os -import stat -import sys - -# find the import for catkin's python package - either from source space or from an installed underlay -if os.path.exists(os.path.join('/opt/ros/melodic/share/catkin/cmake', 'catkinConfig.cmake.in')): - sys.path.insert(0, os.path.join('/opt/ros/melodic/share/catkin/cmake', '..', 'python')) -try: - from catkin.environment_cache import generate_environment_script -except ImportError: - # search for catkin package in all workspaces and prepend to path - for workspace in '/opt/ros/melodic'.split(';'): - python_path = os.path.join(workspace, 'lib/python2.7/dist-packages') - if os.path.isdir(os.path.join(python_path, 'catkin')): - sys.path.insert(0, python_path) - break - from catkin.environment_cache import generate_environment_script - -code = generate_environment_script('/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel/env.sh') - -output_filename = '/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/catkin_generated/setup_cached.sh' -with open(output_filename, 'w') as f: - # print('Generate script for cached setup "%s"' % output_filename) - f.write('\n'.join(code)) - -mode = os.stat(output_filename).st_mode -os.chmod(output_filename, mode | stat.S_IXUSR) diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/.rosinstall b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/.rosinstall deleted file mode 100644 index 6fb13af..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/.rosinstall +++ /dev/null @@ -1,2 +0,0 @@ -- setup-file: - local-name: /usr/local/setup.sh diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/_setup_util.py b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/_setup_util.py deleted file mode 100755 index 760f26f..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/_setup_util.py +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/python2 -# -*- coding: utf-8 -*- - -# Software License Agreement (BSD License) -# -# Copyright (c) 2012, Willow Garage, Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Willow Garage, Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -"""This file generates shell code for the setup.SHELL scripts to set environment variables.""" - -from __future__ import print_function - -import argparse -import copy -import errno -import os -import platform -import sys - -CATKIN_MARKER_FILE = '.catkin' - -system = platform.system() -IS_DARWIN = (system == 'Darwin') -IS_WINDOWS = (system == 'Windows') - -PATH_TO_ADD_SUFFIX = ['bin'] -if IS_WINDOWS: - # while catkin recommends putting dll's into bin, 3rd party packages often put dll's into lib - # since Windows finds dll's via the PATH variable, prepend it with path to lib - PATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'x86_64-linux-gnu')]]) - -# subfolder of workspace prepended to CMAKE_PREFIX_PATH -ENV_VAR_SUBFOLDERS = { - 'CMAKE_PREFIX_PATH': '', - 'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'x86_64-linux-gnu')], - 'PATH': PATH_TO_ADD_SUFFIX, - 'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'x86_64-linux-gnu', 'pkgconfig')], - 'PYTHONPATH': 'lib/python2.7/dist-packages', -} - - -def rollback_env_variables(environ, env_var_subfolders): - """ - Generate shell code to reset environment variables. - - by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH. - This does not cover modifications performed by environment hooks. - """ - lines = [] - unmodified_environ = copy.copy(environ) - for key in sorted(env_var_subfolders.keys()): - subfolders = env_var_subfolders[key] - if not isinstance(subfolders, list): - subfolders = [subfolders] - value = _rollback_env_variable(unmodified_environ, key, subfolders) - if value is not None: - environ[key] = value - lines.append(assignment(key, value)) - if lines: - lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH')) - return lines - - -def _rollback_env_variable(environ, name, subfolders): - """ - For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder. - - :param subfolders: list of str '' or subfoldername that may start with '/' - :returns: the updated value of the environment variable. - """ - value = environ[name] if name in environ else '' - env_paths = [path for path in value.split(os.pathsep) if path] - value_modified = False - for subfolder in subfolders: - if subfolder: - if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)): - subfolder = subfolder[1:] - if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)): - subfolder = subfolder[:-1] - for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True): - path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path - path_to_remove = None - for env_path in env_paths: - env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path - if env_path_clean == path_to_find: - path_to_remove = env_path - break - if path_to_remove: - env_paths.remove(path_to_remove) - value_modified = True - new_value = os.pathsep.join(env_paths) - return new_value if value_modified else None - - -def _get_workspaces(environ, include_fuerte=False, include_non_existing=False): - """ - Based on CMAKE_PREFIX_PATH return all catkin workspaces. - - :param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool`` - """ - # get all cmake prefix paths - env_name = 'CMAKE_PREFIX_PATH' - value = environ[env_name] if env_name in environ else '' - paths = [path for path in value.split(os.pathsep) if path] - # remove non-workspace paths - workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))] - return workspaces - - -def prepend_env_variables(environ, env_var_subfolders, workspaces): - """Generate shell code to prepend environment variables for the all workspaces.""" - lines = [] - lines.append(comment('prepend folders of workspaces to environment variables')) - - paths = [path for path in workspaces.split(os.pathsep) if path] - - prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '') - lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix)) - - for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'): - subfolder = env_var_subfolders[key] - prefix = _prefix_env_variable(environ, key, paths, subfolder) - lines.append(prepend(environ, key, prefix)) - return lines - - -def _prefix_env_variable(environ, name, paths, subfolders): - """ - Return the prefix to prepend to the environment variable NAME. - - Adding any path in NEW_PATHS_STR without creating duplicate or empty items. - """ - value = environ[name] if name in environ else '' - environ_paths = [path for path in value.split(os.pathsep) if path] - checked_paths = [] - for path in paths: - if not isinstance(subfolders, list): - subfolders = [subfolders] - for subfolder in subfolders: - path_tmp = path - if subfolder: - path_tmp = os.path.join(path_tmp, subfolder) - # skip nonexistent paths - if not os.path.exists(path_tmp): - continue - # exclude any path already in env and any path we already added - if path_tmp not in environ_paths and path_tmp not in checked_paths: - checked_paths.append(path_tmp) - prefix_str = os.pathsep.join(checked_paths) - if prefix_str != '' and environ_paths: - prefix_str += os.pathsep - return prefix_str - - -def assignment(key, value): - if not IS_WINDOWS: - return 'export %s="%s"' % (key, value) - else: - return 'set %s=%s' % (key, value) - - -def comment(msg): - if not IS_WINDOWS: - return '# %s' % msg - else: - return 'REM %s' % msg - - -def prepend(environ, key, prefix): - if key not in environ or not environ[key]: - return assignment(key, prefix) - if not IS_WINDOWS: - return 'export %s="%s$%s"' % (key, prefix, key) - else: - return 'set %s=%s%%%s%%' % (key, prefix, key) - - -def find_env_hooks(environ, cmake_prefix_path): - """Generate shell code with found environment hooks for the all workspaces.""" - lines = [] - lines.append(comment('found environment hooks in workspaces')) - - generic_env_hooks = [] - generic_env_hooks_workspace = [] - specific_env_hooks = [] - specific_env_hooks_workspace = [] - generic_env_hooks_by_filename = {} - specific_env_hooks_by_filename = {} - generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh' - specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None - # remove non-workspace paths - workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))] - for workspace in reversed(workspaces): - env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d') - if os.path.isdir(env_hook_dir): - for filename in sorted(os.listdir(env_hook_dir)): - if filename.endswith('.%s' % generic_env_hook_ext): - # remove previous env hook with same name if present - if filename in generic_env_hooks_by_filename: - i = generic_env_hooks.index(generic_env_hooks_by_filename[filename]) - generic_env_hooks.pop(i) - generic_env_hooks_workspace.pop(i) - # append env hook - generic_env_hooks.append(os.path.join(env_hook_dir, filename)) - generic_env_hooks_workspace.append(workspace) - generic_env_hooks_by_filename[filename] = generic_env_hooks[-1] - elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext): - # remove previous env hook with same name if present - if filename in specific_env_hooks_by_filename: - i = specific_env_hooks.index(specific_env_hooks_by_filename[filename]) - specific_env_hooks.pop(i) - specific_env_hooks_workspace.pop(i) - # append env hook - specific_env_hooks.append(os.path.join(env_hook_dir, filename)) - specific_env_hooks_workspace.append(workspace) - specific_env_hooks_by_filename[filename] = specific_env_hooks[-1] - env_hooks = generic_env_hooks + specific_env_hooks - env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace - count = len(env_hooks) - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count)) - for i in range(count): - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i])) - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i])) - return lines - - -def _parse_arguments(args=None): - parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.') - parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context') - parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment') - return parser.parse_known_args(args=args)[0] - - -if __name__ == '__main__': - try: - try: - args = _parse_arguments() - except Exception as e: - print(e, file=sys.stderr) - sys.exit(1) - - if not args.local: - # environment at generation time - CMAKE_PREFIX_PATH = '/opt/ros/melodic'.split(';') - else: - # don't consider any other prefix path than this one - CMAKE_PREFIX_PATH = [] - # prepend current workspace if not already part of CPP - base_path = os.path.dirname(__file__) - # CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent - # base_path on Windows contains backward slashes, need to be converted to forward slashes before comparison - if os.path.sep != '/': - base_path = base_path.replace(os.path.sep, '/') - - if base_path not in CMAKE_PREFIX_PATH: - CMAKE_PREFIX_PATH.insert(0, base_path) - CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH) - - environ = dict(os.environ) - lines = [] - if not args.extend: - lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS) - lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH) - lines += find_env_hooks(environ, CMAKE_PREFIX_PATH) - print('\n'.join(lines)) - - # need to explicitly flush the output - sys.stdout.flush() - except IOError as e: - # and catch potential "broken pipe" if stdout is not writable - # which can happen when piping the output to a file but the disk is full - if e.errno == errno.EPIPE: - print(e, file=sys.stderr) - sys.exit(2) - raise - - sys.exit(0) diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/env.sh b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/env.sh deleted file mode 100755 index 8aa9d24..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/env.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/cmake/templates/env.sh.in - -if [ $# -eq 0 ] ; then - /bin/echo "Usage: env.sh COMMANDS" - /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." - exit 1 -fi - -# ensure to not use different shell type which was set before -CATKIN_SHELL=sh - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) -. "$_CATKIN_SETUP_DIR/setup.sh" -exec "$@" diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.bash b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.bash deleted file mode 100644 index 7da0d97..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.bash +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -# generated from catkin/cmake/templates/local_setup.bash.in - -CATKIN_SHELL=bash - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) -. "$_CATKIN_SETUP_DIR/setup.sh" --extend --local diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.sh b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.sh deleted file mode 100644 index f021098..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/cmake/template/local_setup.sh.in - -# since this file is sourced either use the provided _CATKIN_SETUP_DIR -# or fall back to the destination set at configure time -: ${_CATKIN_SETUP_DIR:=/usr/local} -CATKIN_SETUP_UTIL_ARGS="--extend --local" -. "$_CATKIN_SETUP_DIR/setup.sh" -unset CATKIN_SETUP_UTIL_ARGS diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.zsh b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.zsh deleted file mode 100644 index e692acc..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/local_setup.zsh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env zsh -# generated from catkin/cmake/templates/local_setup.zsh.in - -CATKIN_SHELL=zsh - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) -emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh" --extend --local' diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.bash b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.bash deleted file mode 100644 index ff47af8..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.bash +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -# generated from catkin/cmake/templates/setup.bash.in - -CATKIN_SHELL=bash - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) -. "$_CATKIN_SETUP_DIR/setup.sh" diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.sh b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.sh deleted file mode 100644 index b5a330e..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/cmake/template/setup.sh.in - -# Sets various environment variables and sources additional environment hooks. -# It tries it's best to undo changes from a previously sourced setup file before. -# Supported command line options: -# --extend: skips the undoing of changes from a previously sourced setup file -# --local: only considers this workspace but not the chained ones -# In plain sh shell which doesn't support arguments for sourced scripts you can -# set the environment variable `CATKIN_SETUP_UTIL_ARGS=--extend/--local` instead. - -# since this file is sourced either use the provided _CATKIN_SETUP_DIR -# or fall back to the destination set at configure time -: ${_CATKIN_SETUP_DIR:=/usr/local} -_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py" -unset _CATKIN_SETUP_DIR - -if [ ! -f "$_SETUP_UTIL" ]; then - echo "Missing Python script: $_SETUP_UTIL" - return 22 -fi - -# detect if running on Darwin platform -_UNAME=`uname -s` -_IS_DARWIN=0 -if [ "$_UNAME" = "Darwin" ]; then - _IS_DARWIN=1 -fi -unset _UNAME - -# make sure to export all environment variables -export CMAKE_PREFIX_PATH -if [ $_IS_DARWIN -eq 0 ]; then - export LD_LIBRARY_PATH -else - export DYLD_LIBRARY_PATH -fi -unset _IS_DARWIN -export PATH -export PKG_CONFIG_PATH -export PYTHONPATH - -# remember type of shell if not already set -if [ -z "$CATKIN_SHELL" ]; then - CATKIN_SHELL=sh -fi - -# invoke Python script to generate necessary exports of environment variables -# use TMPDIR if it exists, otherwise fall back to /tmp -if [ -d "${TMPDIR:-}" ]; then - _TMPDIR="${TMPDIR}" -else - _TMPDIR=/tmp -fi -_SETUP_TMP=`mktemp "${_TMPDIR}/setup.sh.XXXXXXXXXX"` -unset _TMPDIR -if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; then - echo "Could not create temporary file: $_SETUP_TMP" - return 1 -fi -CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ ${CATKIN_SETUP_UTIL_ARGS:-} >> "$_SETUP_TMP" -_RC=$? -if [ $_RC -ne 0 ]; then - if [ $_RC -eq 2 ]; then - echo "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?" - else - echo "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC" - fi - unset _RC - unset _SETUP_UTIL - rm -f "$_SETUP_TMP" - unset _SETUP_TMP - return 1 -fi -unset _RC -unset _SETUP_UTIL -. "$_SETUP_TMP" -rm -f "$_SETUP_TMP" -unset _SETUP_TMP - -# source all environment hooks -_i=0 -while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; do - eval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_i - unset _CATKIN_ENVIRONMENT_HOOKS_$_i - eval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE - unset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE - # set workspace for environment hook - CATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace - . "$_envfile" - unset CATKIN_ENV_HOOK_WORKSPACE - _i=$((_i + 1)) -done -unset _i - -unset _CATKIN_ENVIRONMENT_HOOKS_COUNT diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.zsh b/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.zsh deleted file mode 100644 index 9f780b7..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/installspace/setup.zsh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env zsh -# generated from catkin/cmake/templates/setup.zsh.in - -CATKIN_SHELL=zsh - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) -emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh"' diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/setup_cached.sh b/GPU_version/vio/cmake-build-debug/catkin_generated/setup_cached.sh deleted file mode 100755 index 619a325..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/setup_cached.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/python/catkin/environment_cache.py - -# based on a snapshot of the environment before and after calling the setup script -# it emulates the modifications of the setup script without recurring computations - -# new environment variables - -# modified environment variables -export CMAKE_PREFIX_PATH="/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel:$CMAKE_PREFIX_PATH" -export PATH='/opt/ros/melodic/bin:/opt/cmake-3.20.0-rc4-linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' -export ROSLISP_PACKAGE_DIRECTORIES='/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel/share/common-lisp' -export ROS_PACKAGE_PATH="/root/Project/ROS/src/vio_svo/GPU_version/svo:$ROS_PACKAGE_PATH" \ No newline at end of file diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/_setup_util.py.stamp b/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/_setup_util.py.stamp deleted file mode 100755 index 760f26f..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/_setup_util.py.stamp +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/python2 -# -*- coding: utf-8 -*- - -# Software License Agreement (BSD License) -# -# Copyright (c) 2012, Willow Garage, Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Willow Garage, Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -"""This file generates shell code for the setup.SHELL scripts to set environment variables.""" - -from __future__ import print_function - -import argparse -import copy -import errno -import os -import platform -import sys - -CATKIN_MARKER_FILE = '.catkin' - -system = platform.system() -IS_DARWIN = (system == 'Darwin') -IS_WINDOWS = (system == 'Windows') - -PATH_TO_ADD_SUFFIX = ['bin'] -if IS_WINDOWS: - # while catkin recommends putting dll's into bin, 3rd party packages often put dll's into lib - # since Windows finds dll's via the PATH variable, prepend it with path to lib - PATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'x86_64-linux-gnu')]]) - -# subfolder of workspace prepended to CMAKE_PREFIX_PATH -ENV_VAR_SUBFOLDERS = { - 'CMAKE_PREFIX_PATH': '', - 'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'x86_64-linux-gnu')], - 'PATH': PATH_TO_ADD_SUFFIX, - 'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'x86_64-linux-gnu', 'pkgconfig')], - 'PYTHONPATH': 'lib/python2.7/dist-packages', -} - - -def rollback_env_variables(environ, env_var_subfolders): - """ - Generate shell code to reset environment variables. - - by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH. - This does not cover modifications performed by environment hooks. - """ - lines = [] - unmodified_environ = copy.copy(environ) - for key in sorted(env_var_subfolders.keys()): - subfolders = env_var_subfolders[key] - if not isinstance(subfolders, list): - subfolders = [subfolders] - value = _rollback_env_variable(unmodified_environ, key, subfolders) - if value is not None: - environ[key] = value - lines.append(assignment(key, value)) - if lines: - lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH')) - return lines - - -def _rollback_env_variable(environ, name, subfolders): - """ - For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder. - - :param subfolders: list of str '' or subfoldername that may start with '/' - :returns: the updated value of the environment variable. - """ - value = environ[name] if name in environ else '' - env_paths = [path for path in value.split(os.pathsep) if path] - value_modified = False - for subfolder in subfolders: - if subfolder: - if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)): - subfolder = subfolder[1:] - if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)): - subfolder = subfolder[:-1] - for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True): - path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path - path_to_remove = None - for env_path in env_paths: - env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path - if env_path_clean == path_to_find: - path_to_remove = env_path - break - if path_to_remove: - env_paths.remove(path_to_remove) - value_modified = True - new_value = os.pathsep.join(env_paths) - return new_value if value_modified else None - - -def _get_workspaces(environ, include_fuerte=False, include_non_existing=False): - """ - Based on CMAKE_PREFIX_PATH return all catkin workspaces. - - :param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool`` - """ - # get all cmake prefix paths - env_name = 'CMAKE_PREFIX_PATH' - value = environ[env_name] if env_name in environ else '' - paths = [path for path in value.split(os.pathsep) if path] - # remove non-workspace paths - workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))] - return workspaces - - -def prepend_env_variables(environ, env_var_subfolders, workspaces): - """Generate shell code to prepend environment variables for the all workspaces.""" - lines = [] - lines.append(comment('prepend folders of workspaces to environment variables')) - - paths = [path for path in workspaces.split(os.pathsep) if path] - - prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '') - lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix)) - - for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'): - subfolder = env_var_subfolders[key] - prefix = _prefix_env_variable(environ, key, paths, subfolder) - lines.append(prepend(environ, key, prefix)) - return lines - - -def _prefix_env_variable(environ, name, paths, subfolders): - """ - Return the prefix to prepend to the environment variable NAME. - - Adding any path in NEW_PATHS_STR without creating duplicate or empty items. - """ - value = environ[name] if name in environ else '' - environ_paths = [path for path in value.split(os.pathsep) if path] - checked_paths = [] - for path in paths: - if not isinstance(subfolders, list): - subfolders = [subfolders] - for subfolder in subfolders: - path_tmp = path - if subfolder: - path_tmp = os.path.join(path_tmp, subfolder) - # skip nonexistent paths - if not os.path.exists(path_tmp): - continue - # exclude any path already in env and any path we already added - if path_tmp not in environ_paths and path_tmp not in checked_paths: - checked_paths.append(path_tmp) - prefix_str = os.pathsep.join(checked_paths) - if prefix_str != '' and environ_paths: - prefix_str += os.pathsep - return prefix_str - - -def assignment(key, value): - if not IS_WINDOWS: - return 'export %s="%s"' % (key, value) - else: - return 'set %s=%s' % (key, value) - - -def comment(msg): - if not IS_WINDOWS: - return '# %s' % msg - else: - return 'REM %s' % msg - - -def prepend(environ, key, prefix): - if key not in environ or not environ[key]: - return assignment(key, prefix) - if not IS_WINDOWS: - return 'export %s="%s$%s"' % (key, prefix, key) - else: - return 'set %s=%s%%%s%%' % (key, prefix, key) - - -def find_env_hooks(environ, cmake_prefix_path): - """Generate shell code with found environment hooks for the all workspaces.""" - lines = [] - lines.append(comment('found environment hooks in workspaces')) - - generic_env_hooks = [] - generic_env_hooks_workspace = [] - specific_env_hooks = [] - specific_env_hooks_workspace = [] - generic_env_hooks_by_filename = {} - specific_env_hooks_by_filename = {} - generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh' - specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None - # remove non-workspace paths - workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))] - for workspace in reversed(workspaces): - env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d') - if os.path.isdir(env_hook_dir): - for filename in sorted(os.listdir(env_hook_dir)): - if filename.endswith('.%s' % generic_env_hook_ext): - # remove previous env hook with same name if present - if filename in generic_env_hooks_by_filename: - i = generic_env_hooks.index(generic_env_hooks_by_filename[filename]) - generic_env_hooks.pop(i) - generic_env_hooks_workspace.pop(i) - # append env hook - generic_env_hooks.append(os.path.join(env_hook_dir, filename)) - generic_env_hooks_workspace.append(workspace) - generic_env_hooks_by_filename[filename] = generic_env_hooks[-1] - elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext): - # remove previous env hook with same name if present - if filename in specific_env_hooks_by_filename: - i = specific_env_hooks.index(specific_env_hooks_by_filename[filename]) - specific_env_hooks.pop(i) - specific_env_hooks_workspace.pop(i) - # append env hook - specific_env_hooks.append(os.path.join(env_hook_dir, filename)) - specific_env_hooks_workspace.append(workspace) - specific_env_hooks_by_filename[filename] = specific_env_hooks[-1] - env_hooks = generic_env_hooks + specific_env_hooks - env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace - count = len(env_hooks) - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count)) - for i in range(count): - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i])) - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i])) - return lines - - -def _parse_arguments(args=None): - parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.') - parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context') - parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment') - return parser.parse_known_args(args=args)[0] - - -if __name__ == '__main__': - try: - try: - args = _parse_arguments() - except Exception as e: - print(e, file=sys.stderr) - sys.exit(1) - - if not args.local: - # environment at generation time - CMAKE_PREFIX_PATH = '/opt/ros/melodic'.split(';') - else: - # don't consider any other prefix path than this one - CMAKE_PREFIX_PATH = [] - # prepend current workspace if not already part of CPP - base_path = os.path.dirname(__file__) - # CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent - # base_path on Windows contains backward slashes, need to be converted to forward slashes before comparison - if os.path.sep != '/': - base_path = base_path.replace(os.path.sep, '/') - - if base_path not in CMAKE_PREFIX_PATH: - CMAKE_PREFIX_PATH.insert(0, base_path) - CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH) - - environ = dict(os.environ) - lines = [] - if not args.extend: - lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS) - lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH) - lines += find_env_hooks(environ, CMAKE_PREFIX_PATH) - print('\n'.join(lines)) - - # need to explicitly flush the output - sys.stdout.flush() - except IOError as e: - # and catch potential "broken pipe" if stdout is not writable - # which can happen when piping the output to a file but the disk is full - if e.errno == errno.EPIPE: - print(e, file=sys.stderr) - sys.exit(2) - raise - - sys.exit(0) diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/interrogate_setup_dot_py.py.stamp b/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/interrogate_setup_dot_py.py.stamp deleted file mode 100644 index 5e25fbf..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/interrogate_setup_dot_py.py.stamp +++ /dev/null @@ -1,255 +0,0 @@ -# Software License Agreement (BSD License) -# -# Copyright (c) 2012, Willow Garage, Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Willow Garage, Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -from __future__ import print_function - -import os -import runpy -import sys -from argparse import ArgumentParser - -setup_modules = [] - -try: - import distutils.core - setup_modules.append(distutils.core) -except ImportError: - pass - -try: - import setuptools - setup_modules.append(setuptools) -except ImportError: - pass - -assert setup_modules, 'Must have distutils or setuptools installed' - - -def _get_locations(pkgs, package_dir): - """ - Based on setuptools logic and the package_dir dict, builds a dict of location roots for each pkg in pkgs. - - See http://docs.python.org/distutils/setupscript.html - - :returns: a dict {pkgname: root} for each pkgname in pkgs (and each of their parents) - """ - # package_dir contains a dict {package_name: relativepath} - # Example {'': 'src', 'foo': 'lib', 'bar': 'lib2'} - # - # '' means where to look for any package unless a parent package - # is listed so package bar.pot is expected at lib2/bar/pot, - # whereas package sup.dee is expected at src/sup/dee - # - # if package_dir does not state anything about a package, - # setuptool expects the package folder to be in the root of the - # project - locations = {} - allprefix = package_dir.get('', '') - for pkg in pkgs: - parent_location = None - splits = pkg.split('.') - # we iterate over compound name from parent to child - # so once we found parent, children just append to their parent - for key_len in range(len(splits)): - key = '.'.join(splits[:key_len + 1]) - if key not in locations: - if key in package_dir: - locations[key] = package_dir[key] - elif parent_location is not None: - locations[key] = os.path.join(parent_location, splits[key_len]) - else: - locations[key] = os.path.join(allprefix, key) - parent_location = locations[key] - return locations - - -def generate_cmake_file(package_name, version, scripts, package_dir, pkgs, modules, setup_module=None): - """ - Generate lines to add to a cmake file which will set variables. - - :param version: str, format 'int.int.int' - :param scripts: [list of str]: relative paths to scripts - :param package_dir: {modulename: path} - :param pkgs: [list of str] python_packages declared in catkin package - :param modules: [list of str] python modules - :param setup_module: str, setuptools or distutils - """ - prefix = '%s_SETUP_PY' % package_name - result = [] - if setup_module: - result.append(r'set(%s_SETUP_MODULE "%s")' % (prefix, setup_module)) - result.append(r'set(%s_VERSION "%s")' % (prefix, version)) - result.append(r'set(%s_SCRIPTS "%s")' % (prefix, ';'.join(scripts))) - - # Remove packages with '.' separators. - # - # setuptools allows specifying submodules in other folders than - # their parent - # - # The symlink approach of catkin does not work with such submodules. - # In the common case, this does not matter as the submodule is - # within the containing module. We verify this assumption, and if - # it passes, we remove submodule packages. - locations = _get_locations(pkgs, package_dir) - for pkgname, location in locations.items(): - if '.' not in pkgname: - continue - splits = pkgname.split('.') - # hack: ignore write-combining setup.py files for msg and srv files - if splits[1] in ['msg', 'srv']: - continue - # check every child has the same root folder as its parent - root_name = splits[0] - root_location = location - for _ in range(len(splits) - 1): - root_location = os.path.dirname(root_location) - if root_location != locations[root_name]: - raise RuntimeError( - 'catkin_export_python does not support setup.py files that combine across multiple directories: %s in %s, %s in %s' % (pkgname, location, root_name, locations[root_name])) - - # If checks pass, remove all submodules - pkgs = [p for p in pkgs if '.' not in p] - - resolved_pkgs = [] - for pkg in pkgs: - resolved_pkgs += [locations[pkg]] - - result.append(r'set(%s_PACKAGES "%s")' % (prefix, ';'.join(pkgs))) - result.append(r'set(%s_PACKAGE_DIRS "%s")' % (prefix, ';'.join(resolved_pkgs).replace('\\', '/'))) - - # skip modules which collide with package names - filtered_modules = [] - for modname in modules: - splits = modname.split('.') - # check all parents too - equals_package = [('.'.join(splits[:-i]) in locations) for i in range(len(splits))] - if any(equals_package): - continue - filtered_modules.append(modname) - module_locations = _get_locations(filtered_modules, package_dir) - - result.append(r'set(%s_MODULES "%s")' % (prefix, ';'.join(['%s.py' % m.replace('.', '/') for m in filtered_modules]))) - result.append(r'set(%s_MODULE_DIRS "%s")' % (prefix, ';'.join([module_locations[m] for m in filtered_modules]).replace('\\', '/'))) - - return result - - -def _create_mock_setup_function(setup_module, package_name, outfile): - """ - Create a function to call instead of distutils.core.setup or setuptools.setup. - - It just captures some args and writes them into a file that can be used from cmake. - - :param package_name: name of the package - :param outfile: filename that cmake will use afterwards - :returns: a function to replace disutils.core.setup and setuptools.setup - """ - - def setup(*args, **kwargs): - """Check kwargs and write a scriptfile.""" - if 'version' not in kwargs: - sys.stderr.write("\n*** Unable to find 'version' in setup.py of %s\n" % package_name) - raise RuntimeError('version not found in setup.py') - version = kwargs['version'] - package_dir = kwargs.get('package_dir', {}) - - pkgs = kwargs.get('packages', []) - scripts = kwargs.get('scripts', []) - modules = kwargs.get('py_modules', []) - - unsupported_args = [ - 'entry_points', - 'exclude_package_data', - 'ext_modules ', - 'ext_package', - 'include_package_data', - 'namespace_packages', - 'setup_requires', - 'use_2to3', - 'zip_safe'] - used_unsupported_args = [arg for arg in unsupported_args if arg in kwargs] - if used_unsupported_args: - sys.stderr.write('*** Arguments %s to setup() not supported in catkin devel space in setup.py of %s\n' % (used_unsupported_args, package_name)) - - result = generate_cmake_file(package_name=package_name, - version=version, - scripts=scripts, - package_dir=package_dir, - pkgs=pkgs, - modules=modules, - setup_module=setup_module) - with open(outfile, 'w') as out: - out.write('\n'.join(result)) - - return setup - - -def main(): - """Script main, parses arguments and invokes Dummy.setup indirectly.""" - parser = ArgumentParser(description='Utility to read setup.py values from cmake macros. Creates a file with CMake set commands setting variables.') - parser.add_argument('package_name', help='Name of catkin package') - parser.add_argument('setupfile_path', help='Full path to setup.py') - parser.add_argument('outfile', help='Where to write result to') - - args = parser.parse_args() - - # print("%s" % sys.argv) - # PACKAGE_NAME = sys.argv[1] - # OUTFILE = sys.argv[3] - # print("Interrogating setup.py for package %s into %s " % (PACKAGE_NAME, OUTFILE), - # file=sys.stderr) - - # print("executing %s" % args.setupfile_path) - - # be sure you're in the directory containing - # setup.py so the sys.path manipulation works, - # so the import of __version__ works - os.chdir(os.path.dirname(os.path.abspath(args.setupfile_path))) - - # patch setup() function of distutils and setuptools for the - # context of evaluating setup.py - backup_modules = {} - try: - - for module in setup_modules: - backup_modules[id(module)] = module.setup - module.setup = _create_mock_setup_function( - setup_module=module.__name__, package_name=args.package_name, outfile=args.outfile) - - runpy.run_path(args.setupfile_path) - finally: - for module in setup_modules: - module.setup = backup_modules[id(module)] - - -if __name__ == '__main__': - main() diff --git a/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/package.xml.stamp b/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/package.xml.stamp deleted file mode 100644 index bfd7934..0000000 --- a/GPU_version/vio/cmake-build-debug/catkin_generated/stamps/vio/package.xml.stamp +++ /dev/null @@ -1,48 +0,0 @@ - - - - catkin - 0.7.28 - Low-level build system macros and infrastructure for ROS. - Dirk Thomas - BSD - - http://wiki.ros.org/catkin - https://github.com/ros/catkin/issues - https://github.com/ros/catkin - - Troy Straszheim - Morten Kjaergaard - Brian Gerkey - Dirk Thomas - - python-argparse - python-catkin-pkg - python3-catkin-pkg - python-empy - python3-empy - - cmake - python-setuptools - python3-setuptools - - cmake - python3-setuptools - - google-mock - gtest - python-nose - python3-nose - - python-mock - python3-mock - python-nose - python3-nose - - - - - - diff --git a/GPU_version/vio/cmake-build-debug/devel/.catkin b/GPU_version/vio/cmake-build-debug/devel/.catkin deleted file mode 100644 index 749f40c..0000000 --- a/GPU_version/vio/cmake-build-debug/devel/.catkin +++ /dev/null @@ -1 +0,0 @@ -/root/Project/ROS/src/vio_svo/GPU_version/svo \ No newline at end of file diff --git a/GPU_version/vio/cmake-build-debug/devel/.rosinstall b/GPU_version/vio/cmake-build-debug/devel/.rosinstall deleted file mode 100644 index b61ff9e..0000000 --- a/GPU_version/vio/cmake-build-debug/devel/.rosinstall +++ /dev/null @@ -1,2 +0,0 @@ -- setup-file: - local-name: /root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel/setup.sh diff --git a/GPU_version/vio/cmake-build-debug/devel/_setup_util.py b/GPU_version/vio/cmake-build-debug/devel/_setup_util.py deleted file mode 100755 index 760f26f..0000000 --- a/GPU_version/vio/cmake-build-debug/devel/_setup_util.py +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/python2 -# -*- coding: utf-8 -*- - -# Software License Agreement (BSD License) -# -# Copyright (c) 2012, Willow Garage, Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Willow Garage, Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -"""This file generates shell code for the setup.SHELL scripts to set environment variables.""" - -from __future__ import print_function - -import argparse -import copy -import errno -import os -import platform -import sys - -CATKIN_MARKER_FILE = '.catkin' - -system = platform.system() -IS_DARWIN = (system == 'Darwin') -IS_WINDOWS = (system == 'Windows') - -PATH_TO_ADD_SUFFIX = ['bin'] -if IS_WINDOWS: - # while catkin recommends putting dll's into bin, 3rd party packages often put dll's into lib - # since Windows finds dll's via the PATH variable, prepend it with path to lib - PATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'x86_64-linux-gnu')]]) - -# subfolder of workspace prepended to CMAKE_PREFIX_PATH -ENV_VAR_SUBFOLDERS = { - 'CMAKE_PREFIX_PATH': '', - 'LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'x86_64-linux-gnu')], - 'PATH': PATH_TO_ADD_SUFFIX, - 'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'x86_64-linux-gnu', 'pkgconfig')], - 'PYTHONPATH': 'lib/python2.7/dist-packages', -} - - -def rollback_env_variables(environ, env_var_subfolders): - """ - Generate shell code to reset environment variables. - - by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH. - This does not cover modifications performed by environment hooks. - """ - lines = [] - unmodified_environ = copy.copy(environ) - for key in sorted(env_var_subfolders.keys()): - subfolders = env_var_subfolders[key] - if not isinstance(subfolders, list): - subfolders = [subfolders] - value = _rollback_env_variable(unmodified_environ, key, subfolders) - if value is not None: - environ[key] = value - lines.append(assignment(key, value)) - if lines: - lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH')) - return lines - - -def _rollback_env_variable(environ, name, subfolders): - """ - For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder. - - :param subfolders: list of str '' or subfoldername that may start with '/' - :returns: the updated value of the environment variable. - """ - value = environ[name] if name in environ else '' - env_paths = [path for path in value.split(os.pathsep) if path] - value_modified = False - for subfolder in subfolders: - if subfolder: - if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)): - subfolder = subfolder[1:] - if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)): - subfolder = subfolder[:-1] - for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True): - path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_path - path_to_remove = None - for env_path in env_paths: - env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_path - if env_path_clean == path_to_find: - path_to_remove = env_path - break - if path_to_remove: - env_paths.remove(path_to_remove) - value_modified = True - new_value = os.pathsep.join(env_paths) - return new_value if value_modified else None - - -def _get_workspaces(environ, include_fuerte=False, include_non_existing=False): - """ - Based on CMAKE_PREFIX_PATH return all catkin workspaces. - - :param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool`` - """ - # get all cmake prefix paths - env_name = 'CMAKE_PREFIX_PATH' - value = environ[env_name] if env_name in environ else '' - paths = [path for path in value.split(os.pathsep) if path] - # remove non-workspace paths - workspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))] - return workspaces - - -def prepend_env_variables(environ, env_var_subfolders, workspaces): - """Generate shell code to prepend environment variables for the all workspaces.""" - lines = [] - lines.append(comment('prepend folders of workspaces to environment variables')) - - paths = [path for path in workspaces.split(os.pathsep) if path] - - prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '') - lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix)) - - for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'): - subfolder = env_var_subfolders[key] - prefix = _prefix_env_variable(environ, key, paths, subfolder) - lines.append(prepend(environ, key, prefix)) - return lines - - -def _prefix_env_variable(environ, name, paths, subfolders): - """ - Return the prefix to prepend to the environment variable NAME. - - Adding any path in NEW_PATHS_STR without creating duplicate or empty items. - """ - value = environ[name] if name in environ else '' - environ_paths = [path for path in value.split(os.pathsep) if path] - checked_paths = [] - for path in paths: - if not isinstance(subfolders, list): - subfolders = [subfolders] - for subfolder in subfolders: - path_tmp = path - if subfolder: - path_tmp = os.path.join(path_tmp, subfolder) - # skip nonexistent paths - if not os.path.exists(path_tmp): - continue - # exclude any path already in env and any path we already added - if path_tmp not in environ_paths and path_tmp not in checked_paths: - checked_paths.append(path_tmp) - prefix_str = os.pathsep.join(checked_paths) - if prefix_str != '' and environ_paths: - prefix_str += os.pathsep - return prefix_str - - -def assignment(key, value): - if not IS_WINDOWS: - return 'export %s="%s"' % (key, value) - else: - return 'set %s=%s' % (key, value) - - -def comment(msg): - if not IS_WINDOWS: - return '# %s' % msg - else: - return 'REM %s' % msg - - -def prepend(environ, key, prefix): - if key not in environ or not environ[key]: - return assignment(key, prefix) - if not IS_WINDOWS: - return 'export %s="%s$%s"' % (key, prefix, key) - else: - return 'set %s=%s%%%s%%' % (key, prefix, key) - - -def find_env_hooks(environ, cmake_prefix_path): - """Generate shell code with found environment hooks for the all workspaces.""" - lines = [] - lines.append(comment('found environment hooks in workspaces')) - - generic_env_hooks = [] - generic_env_hooks_workspace = [] - specific_env_hooks = [] - specific_env_hooks_workspace = [] - generic_env_hooks_by_filename = {} - specific_env_hooks_by_filename = {} - generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh' - specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None - # remove non-workspace paths - workspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))] - for workspace in reversed(workspaces): - env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d') - if os.path.isdir(env_hook_dir): - for filename in sorted(os.listdir(env_hook_dir)): - if filename.endswith('.%s' % generic_env_hook_ext): - # remove previous env hook with same name if present - if filename in generic_env_hooks_by_filename: - i = generic_env_hooks.index(generic_env_hooks_by_filename[filename]) - generic_env_hooks.pop(i) - generic_env_hooks_workspace.pop(i) - # append env hook - generic_env_hooks.append(os.path.join(env_hook_dir, filename)) - generic_env_hooks_workspace.append(workspace) - generic_env_hooks_by_filename[filename] = generic_env_hooks[-1] - elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext): - # remove previous env hook with same name if present - if filename in specific_env_hooks_by_filename: - i = specific_env_hooks.index(specific_env_hooks_by_filename[filename]) - specific_env_hooks.pop(i) - specific_env_hooks_workspace.pop(i) - # append env hook - specific_env_hooks.append(os.path.join(env_hook_dir, filename)) - specific_env_hooks_workspace.append(workspace) - specific_env_hooks_by_filename[filename] = specific_env_hooks[-1] - env_hooks = generic_env_hooks + specific_env_hooks - env_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspace - count = len(env_hooks) - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count)) - for i in range(count): - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i])) - lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i])) - return lines - - -def _parse_arguments(args=None): - parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.') - parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context') - parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment') - return parser.parse_known_args(args=args)[0] - - -if __name__ == '__main__': - try: - try: - args = _parse_arguments() - except Exception as e: - print(e, file=sys.stderr) - sys.exit(1) - - if not args.local: - # environment at generation time - CMAKE_PREFIX_PATH = '/opt/ros/melodic'.split(';') - else: - # don't consider any other prefix path than this one - CMAKE_PREFIX_PATH = [] - # prepend current workspace if not already part of CPP - base_path = os.path.dirname(__file__) - # CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent - # base_path on Windows contains backward slashes, need to be converted to forward slashes before comparison - if os.path.sep != '/': - base_path = base_path.replace(os.path.sep, '/') - - if base_path not in CMAKE_PREFIX_PATH: - CMAKE_PREFIX_PATH.insert(0, base_path) - CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH) - - environ = dict(os.environ) - lines = [] - if not args.extend: - lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS) - lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH) - lines += find_env_hooks(environ, CMAKE_PREFIX_PATH) - print('\n'.join(lines)) - - # need to explicitly flush the output - sys.stdout.flush() - except IOError as e: - # and catch potential "broken pipe" if stdout is not writable - # which can happen when piping the output to a file but the disk is full - if e.errno == errno.EPIPE: - print(e, file=sys.stderr) - sys.exit(2) - raise - - sys.exit(0) diff --git a/GPU_version/vio/cmake-build-debug/devel/cmake.lock b/GPU_version/vio/cmake-build-debug/devel/cmake.lock deleted file mode 100644 index e69de29..0000000 diff --git a/GPU_version/vio/cmake-build-debug/devel/env.sh b/GPU_version/vio/cmake-build-debug/devel/env.sh deleted file mode 100755 index 8aa9d24..0000000 --- a/GPU_version/vio/cmake-build-debug/devel/env.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/cmake/templates/env.sh.in - -if [ $# -eq 0 ] ; then - /bin/echo "Usage: env.sh COMMANDS" - /bin/echo "Calling env.sh without arguments is not supported anymore. Instead spawn a subshell and source a setup file manually." - exit 1 -fi - -# ensure to not use different shell type which was set before -CATKIN_SHELL=sh - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(cd "`dirname "$0"`" > /dev/null && pwd) -. "$_CATKIN_SETUP_DIR/setup.sh" -exec "$@" diff --git a/GPU_version/vio/cmake-build-debug/devel/local_setup.bash b/GPU_version/vio/cmake-build-debug/devel/local_setup.bash deleted file mode 100644 index 7da0d97..0000000 --- a/GPU_version/vio/cmake-build-debug/devel/local_setup.bash +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -# generated from catkin/cmake/templates/local_setup.bash.in - -CATKIN_SHELL=bash - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) -. "$_CATKIN_SETUP_DIR/setup.sh" --extend --local diff --git a/GPU_version/vio/cmake-build-debug/devel/local_setup.sh b/GPU_version/vio/cmake-build-debug/devel/local_setup.sh deleted file mode 100644 index d29ab41..0000000 --- a/GPU_version/vio/cmake-build-debug/devel/local_setup.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/cmake/template/local_setup.sh.in - -# since this file is sourced either use the provided _CATKIN_SETUP_DIR -# or fall back to the destination set at configure time -: ${_CATKIN_SETUP_DIR:=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel} -CATKIN_SETUP_UTIL_ARGS="--extend --local" -. "$_CATKIN_SETUP_DIR/setup.sh" -unset CATKIN_SETUP_UTIL_ARGS diff --git a/GPU_version/vio/cmake-build-debug/devel/local_setup.zsh b/GPU_version/vio/cmake-build-debug/devel/local_setup.zsh deleted file mode 100644 index e692acc..0000000 --- a/GPU_version/vio/cmake-build-debug/devel/local_setup.zsh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env zsh -# generated from catkin/cmake/templates/local_setup.zsh.in - -CATKIN_SHELL=zsh - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) -emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh" --extend --local' diff --git a/GPU_version/vio/cmake-build-debug/devel/setup.bash b/GPU_version/vio/cmake-build-debug/devel/setup.bash deleted file mode 100644 index ff47af8..0000000 --- a/GPU_version/vio/cmake-build-debug/devel/setup.bash +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -# generated from catkin/cmake/templates/setup.bash.in - -CATKIN_SHELL=bash - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd) -. "$_CATKIN_SETUP_DIR/setup.sh" diff --git a/GPU_version/vio/cmake-build-debug/devel/setup.sh b/GPU_version/vio/cmake-build-debug/devel/setup.sh deleted file mode 100644 index 1764d84..0000000 --- a/GPU_version/vio/cmake-build-debug/devel/setup.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env sh -# generated from catkin/cmake/template/setup.sh.in - -# Sets various environment variables and sources additional environment hooks. -# It tries it's best to undo changes from a previously sourced setup file before. -# Supported command line options: -# --extend: skips the undoing of changes from a previously sourced setup file -# --local: only considers this workspace but not the chained ones -# In plain sh shell which doesn't support arguments for sourced scripts you can -# set the environment variable `CATKIN_SETUP_UTIL_ARGS=--extend/--local` instead. - -# since this file is sourced either use the provided _CATKIN_SETUP_DIR -# or fall back to the destination set at configure time -: ${_CATKIN_SETUP_DIR:=/root/Project/ROS/src/vio_svo/GPU_version/svo/cmake-build-debug/devel} -_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py" -unset _CATKIN_SETUP_DIR - -if [ ! -f "$_SETUP_UTIL" ]; then - echo "Missing Python script: $_SETUP_UTIL" - return 22 -fi - -# detect if running on Darwin platform -_UNAME=`uname -s` -_IS_DARWIN=0 -if [ "$_UNAME" = "Darwin" ]; then - _IS_DARWIN=1 -fi -unset _UNAME - -# make sure to export all environment variables -export CMAKE_PREFIX_PATH -if [ $_IS_DARWIN -eq 0 ]; then - export LD_LIBRARY_PATH -else - export DYLD_LIBRARY_PATH -fi -unset _IS_DARWIN -export PATH -export PKG_CONFIG_PATH -export PYTHONPATH - -# remember type of shell if not already set -if [ -z "$CATKIN_SHELL" ]; then - CATKIN_SHELL=sh -fi - -# invoke Python script to generate necessary exports of environment variables -# use TMPDIR if it exists, otherwise fall back to /tmp -if [ -d "${TMPDIR:-}" ]; then - _TMPDIR="${TMPDIR}" -else - _TMPDIR=/tmp -fi -_SETUP_TMP=`mktemp "${_TMPDIR}/setup.sh.XXXXXXXXXX"` -unset _TMPDIR -if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; then - echo "Could not create temporary file: $_SETUP_TMP" - return 1 -fi -CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ ${CATKIN_SETUP_UTIL_ARGS:-} >> "$_SETUP_TMP" -_RC=$? -if [ $_RC -ne 0 ]; then - if [ $_RC -eq 2 ]; then - echo "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?" - else - echo "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC" - fi - unset _RC - unset _SETUP_UTIL - rm -f "$_SETUP_TMP" - unset _SETUP_TMP - return 1 -fi -unset _RC -unset _SETUP_UTIL -. "$_SETUP_TMP" -rm -f "$_SETUP_TMP" -unset _SETUP_TMP - -# source all environment hooks -_i=0 -while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; do - eval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_i - unset _CATKIN_ENVIRONMENT_HOOKS_$_i - eval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE - unset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE - # set workspace for environment hook - CATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace - . "$_envfile" - unset CATKIN_ENV_HOOK_WORKSPACE - _i=$((_i + 1)) -done -unset _i - -unset _CATKIN_ENVIRONMENT_HOOKS_COUNT diff --git a/GPU_version/vio/cmake-build-debug/devel/setup.zsh b/GPU_version/vio/cmake-build-debug/devel/setup.zsh deleted file mode 100644 index 9f780b7..0000000 --- a/GPU_version/vio/cmake-build-debug/devel/setup.zsh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env zsh -# generated from catkin/cmake/templates/setup.zsh.in - -CATKIN_SHELL=zsh - -# source setup.sh from same directory as this file -_CATKIN_SETUP_DIR=$(builtin cd -q "`dirname "$0"`" > /dev/null && pwd) -emulate -R zsh -c 'source "$_CATKIN_SETUP_DIR/setup.sh"' From 43edfce29e863a7306efcf8a1a14283279514949 Mon Sep 17 00:00:00 2001 From: gfuse Date: Tue, 29 Jun 2021 10:23:52 +0200 Subject: [PATCH 208/215] correct visualization --- CPU_version/svo/CMakeLists.txt | 2 +- CPU_version/vio_svo/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CPU_version/svo/CMakeLists.txt b/CPU_version/svo/CMakeLists.txt index 5ecd775..c3ace90 100644 --- a/CPU_version/svo/CMakeLists.txt +++ b/CPU_version/svo/CMakeLists.txt @@ -47,7 +47,7 @@ ENDIF() SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -fsee -fomit-frame-pointer -fno-signed-zeros -fno-math-errno -funroll-loops") # Add plain cmake packages -FIND_PACKAGE(OpenCV REQUIRED) +FIND_PACKAGE(OpenCV 3 REQUIRED) FIND_PACKAGE(Eigen REQUIRED) FIND_PACKAGE(Sophus REQUIRED) FIND_PACKAGE(fast REQUIRED) diff --git a/CPU_version/vio_svo/CMakeLists.txt b/CPU_version/vio_svo/CMakeLists.txt index 70101db..7fdf637 100644 --- a/CPU_version/vio_svo/CMakeLists.txt +++ b/CPU_version/vio_svo/CMakeLists.txt @@ -37,7 +37,7 @@ FIND_PACKAGE(catkin REQUIRED COMPONENTS ) # Add plain cmake packages -FIND_PACKAGE(OpenCV REQUIRED) +FIND_PACKAGE(OpenCV 3 REQUIRED) FIND_PACKAGE(Eigen REQUIRED) FIND_PACKAGE(Sophus REQUIRED) FIND_PACKAGE(Boost REQUIRED COMPONENTS thread) From 46322cf74c55a9723954013eb0d40bf21fa0def7 Mon Sep 17 00:00:00 2001 From: gfuse Date: Tue, 29 Jun 2021 10:27:59 +0200 Subject: [PATCH 209/215] correct visualization --- GPU_version/vio/param/vo_fast.yaml | 2 +- GPU_version/vio/src/visualizer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU_version/vio/param/vo_fast.yaml b/GPU_version/vio/param/vo_fast.yaml index 90df6be..99da116 100644 --- a/GPU_version/vio/param/vo_fast.yaml +++ b/GPU_version/vio/param/vo_fast.yaml @@ -11,5 +11,5 @@ svo: poseoptim_thresh: 4.0 ACC_noise: 0.1 #acc white noise in continuous in EKF GYO_noise: 0.1 #gyro white noise in continuous in EKF - svo_ekf: 20 #Svo noise that will be devided by number of Reprojected points after opmization in EKF + svo_ekf: 5 #Svo noise that will be devided by number of Reprojected points after opmization in EKF Cmd_Cov: 0.05 #control vector noise in EKF diff --git a/GPU_version/vio/src/visualizer.cpp b/GPU_version/vio/src/visualizer.cpp index 43bc4b1..95b3353 100644 --- a/GPU_version/vio/src/visualizer.cpp +++ b/GPU_version/vio/src/visualizer.cpp @@ -53,7 +53,7 @@ void Visualizer::publishMinimal( if(pub_pose_with_cov_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) { // publish cam in world frame (Estimated odometry in the worls frame) - Quaterniond q(AngleAxisd(frame->T_f_w_.pitch(), Vector3d::UnitY())); + Quaterniond q(AngleAxisd(frame->T_f_w_.pitch(), Vector3d::UnitZ())); geometry_msgs::PoseWithCovarianceStampedPtr msg_pose_with_cov(new geometry_msgs::PoseWithCovarianceStamped); msg_pose_with_cov->header = header_msg; msg_pose_with_cov->pose.pose.position.x = frame->se3().translation().x(); From 9ca9e263ba6161e73b0f7c8e6f94937b1dbaf571 Mon Sep 17 00:00:00 2001 From: gfuse Date: Wed, 30 Jun 2021 10:22:49 +0200 Subject: [PATCH 210/215] edit EKF formula --- .../vio/include/gpu_svo/frame_handler_mono.h | 2 +- GPU_version/vio/include/gpu_svo/ukf.h | 108 ++++++++---------- GPU_version/vio/param/vo_fast.yaml | 2 +- GPU_version/vio/src/feature_alignment.cpp | 6 +- GPU_version/vio/src/frame_handler_mono.cpp | 3 +- GPU_version/vio/src/vo_node.cpp | 5 +- 6 files changed, 57 insertions(+), 69 deletions(-) diff --git a/GPU_version/vio/include/gpu_svo/frame_handler_mono.h b/GPU_version/vio/include/gpu_svo/frame_handler_mono.h index 3faa24f..ea323be 100644 --- a/GPU_version/vio/include/gpu_svo/frame_handler_mono.h +++ b/GPU_version/vio/include/gpu_svo/frame_handler_mono.h @@ -33,7 +33,7 @@ class FrameHandlerMono : public FrameHandlerBase public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW - FrameHandlerMono(vk::AbstractCamera* cam,Eigen::Matrix& init); + FrameHandlerMono(vk::AbstractCamera* cam,Eigen::Matrix& init); virtual ~FrameHandlerMono(); /// Provide an image. diff --git a/GPU_version/vio/include/gpu_svo/ukf.h b/GPU_version/vio/include/gpu_svo/ukf.h index 7919c32..0f1d787 100644 --- a/GPU_version/vio/include/gpu_svo/ukf.h +++ b/GPU_version/vio/include/gpu_svo/ukf.h @@ -10,93 +10,87 @@ #include class Base{ public: - Base(const Eigen::Matrix &init) { + Base(const Eigen::Matrix &init) { state_=init; cov_.setIdentity(); cov_*=0.0001; }; virtual ~Base(){ }; - void predict(double ddx,double ddz,double dpitch,double time){ + void predict(double dx,double dz,double dpitch,double time){ if(t_==0.0){ t_=time; return; } - double t=time-t_; + double dt=time-t_; t_=time; - state_h_< G; - G<<1.0,0,t,0,-0.5*pow(t,2)*(ddz*cos(state_(4))+ddx*sin(state_(4))),0, - 0,1.0,0,t,0.5*pow(t,2)*(ddx*cos(state_(4))-ddz*sin(state_(4))),0, - 0,0,1.0,0,-t*(ddz*cos(state_(4))+ddx*sin(state_(4))),0, - 0,0,0,1.0,t*(ddx*cos(state_(4))-ddz*sin(state_(4))),0, - 0,0,0,0,1.0,t*dpitch, - 0,0,0,0,0,1.0; - Eigen::Matrix R; - R<<10.0*svo::Config::ACC_Noise(),0,0,0,0,0, - 0,10.0*svo::Config::ACC_Noise(),0,0,0,0, - 0,0,svo::Config::ACC_Noise(),0,0,0, - 0,0,0,svo::Config::ACC_Noise(),0,0, - 0,0,0,0,10.0*svo::Config::GYO_Noise(),0, - 0,0,0,0,0,svo::Config::GYO_Noise(); + state_h_(2)=state_(2)+dt*dpitch; + state_h_(1)=state_(1)+dz*cos(state_(2))-dx*sin(state_(2)); + state_h_(0)=state_(0)+dx*cos(state_(2))+dz*sin(state_(2)); + Eigen::Matrix R; + R< G; + G<<1.0,0,-dx*sin(state_(2))+dz*cos(state_(2)), + 0,1.0,-dz*sin(state_(2))-dx*cos(state_(2)), + 0,0,1.0; cov_h_=G*cov_*G.transpose()+R; predict_up=true; } - void correct(double x, double z, double pitch, double time){ - Eigen::Matrix H; + void correct(double ddx, double ddz, double dpitch, double time){ + Eigen::Matrix H; Eigen::Matrix Q; Eigen::Matrix E; - Eigen::Matrix k; + Eigen::Matrix k; + double dt=time-t_; t_=time; - H<<0,0,1.0,0,0,0, - 0,0,0,1.0,0,0, - 0,0,0,0,0,1.0; - Q< H; + Eigen::Matrix H; Eigen::Matrix Q; Eigen::Matrix E; - Eigen::Matrix k; + Eigen::Matrix k; t_=time; ++match; - H<<1.0,0,0,0,0,0, - 0,1.0,0,0,0,0, - 0,0,0,0,1.0,0; + H<<1.0,0,0, + 0,1.0,0, + 0,0,1.0; Q< cov_; - Eigen::Matrix state_; + Eigen::Matrix cov_; + Eigen::Matrix state_; bool predict_up=false; private: double t_=0.0; - Eigen::Matrix cov_h_; - Eigen::Matrix state_h_;//state{x,z,dx,dv,pitch} + Eigen::Matrix cov_h_; + Eigen::Matrix state_h_;//state{x,z,pitch} }; class UKF { public: - UKF(const Eigen::Matrix& init) : filter_(new Base(init)) { + UKF(const Eigen::Matrix& init) : filter_(new Base(init)) { }; virtual ~UKF() { delete filter_; @@ -104,30 +98,24 @@ public: void UpdateIMU(double x,double z,double pitch,const ros::Time& time) { while(lock)usleep(5); lock=true; - //if(abs(x)<1.0)x=pow(x,3);//picked up from your code - //if(abs(z)<1.0)z=pow(z,3);//picked up from your code - if(!filter_->predict_up)filter_->predict(x,z,pitch,1e-9*time.toNSec()); + if(abs(x)<1.0)x=pow(x,3);//picked up from your code + if(abs(z)<1.0)z=pow(z,3);//picked up from your code + if(filter_->predict_up)filter_->correct(x,z,pitch,1e-9*time.toNSec()); lock=false; }; void UpdateCmd(double x,double z,double pitch,const ros::Time& time) { while(lock)usleep(5); lock=true; - filter_->correct(x,z,pitch,1e-9*time.toNSec()); + filter_->predict(x,z,pitch,1e-9*time.toNSec()); lock=false; }; std::pair,svo::SE2> UpdateSvo(double x,double z,double pitch,size_t match,ros::Time& time) { while(lock)usleep(5); lock=true; - filter_->correct(-1.0*x,-1.0*z,pitch,match,1e-9*time.toNSec()); + if(filter_->predict_up)filter_->correct(x,z,pitch,match,1e-9*time.toNSec()); lock=false; - //std::cout<<"filter cov\n"<cov_<<'\n'; - //std::cout<<"filter state\n"<state_<<'\n'; - Eigen::Matrix cov; - cov<cov_(0,0),filter_->cov_(0,1),filter_->cov_(0,4), - filter_->cov_(1,0),filter_->cov_(1,1),filter_->cov_(1,4), - filter_->cov_(4,0),filter_->cov_(4,1),filter_->cov_(4,4); - svo::SE2 out(filter_->state_(4),Eigen::Vector2d(-1.0*filter_->state_(0),-1.0*filter_->state_(1))); - return std::pair,svo::SE2>(cov,out); + svo::SE2 out(filter_->state_(2),Eigen::Vector2d(filter_->state_(0),filter_->state_(1))); + return std::pair,svo::SE2>(filter_->cov_,out); }; private: Base* filter_= nullptr; diff --git a/GPU_version/vio/param/vo_fast.yaml b/GPU_version/vio/param/vo_fast.yaml index 99da116..11b2b18 100644 --- a/GPU_version/vio/param/vo_fast.yaml +++ b/GPU_version/vio/param/vo_fast.yaml @@ -12,4 +12,4 @@ svo: ACC_noise: 0.1 #acc white noise in continuous in EKF GYO_noise: 0.1 #gyro white noise in continuous in EKF svo_ekf: 5 #Svo noise that will be devided by number of Reprojected points after opmization in EKF - Cmd_Cov: 0.05 #control vector noise in EKF + Cmd_Cov: 0.5 #control vector noise in EKF diff --git a/GPU_version/vio/src/feature_alignment.cpp b/GPU_version/vio/src/feature_alignment.cpp index 0a3de63..9e42e47 100644 --- a/GPU_version/vio/src/feature_alignment.cpp +++ b/GPU_version/vio/src/feature_alignment.cpp @@ -203,7 +203,7 @@ bool align2D( bool sign=true;// + // termination condition - const float min_update_squared = 0.1;//0.001 + const float min_update_squared = 0.5;//0.001 const int cur_step = cur_img.step.p[0]; // float chi2 = 0; Vector3f update; update.setZero(); @@ -337,7 +337,7 @@ bool align2D_SSE2( float v = cur_px_estimate.y(); // termination condition - const float min_update_squared = 0.03*0.03; + const float min_update_squared = 0.1*0.1; const int cur_step = cur_img.step.p[0]; const float Dinv = 1.0f/(A11*A22 - A12*A12); // we are missing an extra factor 16 float chi2 = 0; @@ -502,7 +502,7 @@ bool align2D_NEON ( float v = cur_px_estimate.y(); // termination condition - const float min_update_squared = 0.03*0.03; + const float min_update_squared = 0.1*0.1; const int cur_step = cur_img.step.p[0]; Vector3f update; Vector3f Jres; diff --git a/GPU_version/vio/src/frame_handler_mono.cpp b/GPU_version/vio/src/frame_handler_mono.cpp index 74527d1..f9782a5 100644 --- a/GPU_version/vio/src/frame_handler_mono.cpp +++ b/GPU_version/vio/src/frame_handler_mono.cpp @@ -27,7 +27,7 @@ namespace svo { -FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam,Eigen::Matrix& init) : +FrameHandlerMono::FrameHandlerMono(vk::AbstractCamera* cam,Eigen::Matrix& init) : FrameHandlerBase(), cam_(cam), reprojector_(cam_, map_), @@ -133,7 +133,6 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() { - new_frame_->T_f_w_ = last_frame_->T_f_w_; // sparse image align SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), diff --git a/GPU_version/vio/src/vo_node.cpp b/GPU_version/vio/src/vo_node.cpp index 20e874d..8fe3f84 100644 --- a/GPU_version/vio/src/vo_node.cpp +++ b/GPU_version/vio/src/vo_node.cpp @@ -74,8 +74,8 @@ VoNode::VoNode() : Eigen::Vector3d(vk::getParam("vio/init_tx", 0.0), vk::getParam("vio/init_ty", 0.0), vk::getParam("vio/init_tz", 0.0))); - Eigen::Matrix init; - init<<1e-5,1e-5,1e-5,1e-5,1e-5,1e-5; + Eigen::Matrix init; + init<<1e-19,1e-19,1e-19; vo_ = new svo::FrameHandlerMono(cam_,init); usleep(500); @@ -157,6 +157,7 @@ void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { } #endif vo_->UpdateIMU(imu_in,imu->header.stamp); + imu_time_=imu->header.stamp; } void VoNode::cmdCb(const geometry_msgs::TwistPtr &cmd) { double _cmd[3]={cmd->linear.x,cmd->linear.y,cmd->angular.z}; From 3b110b299b92a0eacc4b35c8bdb0950230b7e038 Mon Sep 17 00:00:00 2001 From: gfuse Date: Tue, 6 Jul 2021 18:43:09 +0200 Subject: [PATCH 211/215] edit EKF formula for odometry estimation problem --- GPU_version/vio/include/gpu_svo/ukf.h | 34 +++++++++++++++++----- GPU_version/vio/param/vo_fast.yaml | 10 +++---- GPU_version/vio/src/frame_handler_mono.cpp | 21 +++++-------- GPU_version/vio/src/map.cpp | 1 - 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/GPU_version/vio/include/gpu_svo/ukf.h b/GPU_version/vio/include/gpu_svo/ukf.h index 0f1d787..b3a5cd2 100644 --- a/GPU_version/vio/include/gpu_svo/ukf.h +++ b/GPU_version/vio/include/gpu_svo/ukf.h @@ -56,8 +56,23 @@ public: E(2)=state_(2)+dt*dpitch-state_h_(2); k=cov_h_*H.transpose()*(H*cov_h_*H.transpose()+Q).inverse(); state_=state_h_+k*E; + if(fabs(state_(2)-yaw_t_1_)>M_PI_4)state_(2)-=M_PI; + if(fabs(state_(2))>2*M_PI)state_(2)-=2.0*int(0.5*state_(2)/M_PI)*M_PI; cov_=(Eigen::MatrixXd::Identity(3,3)-k*H)*cov_h_; - predict_up=false; + state_h_(2)=state_(2)+dt*dpitch; + state_h_(1)=state_(1)+0.5*pow(dt,2)*(ddz*cos(state_(2))-ddx*sin(state_(2))); + state_h_(0)=state_(0)+0.5*pow(dt,2)*(ddx*cos(state_(2))+ddz*sin(state_(2))); + Eigen::Matrix R; + R< G; + G<<1.0,0,0.5*pow(dt,2)*(ddz*cos(state_(2))-ddx*sin(state_(2))), + 0,1.0,-0.5*pow(dt,2)*(ddx*cos(state_(2))+ddz*sin(state_(2))), + 0,0,1.0; + cov_h_=G*cov_*G.transpose()+R; + yaw_t_1_=state_(2); + } void correct(double x, double z,double pitch,size_t match,double time){ Eigen::Matrix H; @@ -69,13 +84,16 @@ public: H<<1.0,0,0, 0,1.0,0, 0,0,1.0; - Q<M_PI_4)state_(2)-=M_PI; + if(fabs(state_(2))>2*M_PI)state_(2)-=2.0*int(0.5*state_(2)/M_PI)*M_PI; cov_=(Eigen::MatrixXd::Identity(3,3)-k*H)*cov_h_; + yaw_t_1_=state_(2); predict_up=false; } Eigen::Matrix cov_; @@ -85,6 +103,7 @@ private: double t_=0.0; Eigen::Matrix cov_h_; Eigen::Matrix state_h_;//state{x,z,pitch} + double yaw_t_1_=0.0; }; @@ -109,13 +128,12 @@ public: filter_->predict(x,z,pitch,1e-9*time.toNSec()); lock=false; }; - std::pair,svo::SE2> UpdateSvo(double x,double z,double pitch,size_t match,ros::Time& time) { + std::pair,svo::SE2_5> UpdateSvo(double x,double z,double pitch,size_t match,ros::Time& time) { while(lock)usleep(5); lock=true; if(filter_->predict_up)filter_->correct(x,z,pitch,match,1e-9*time.toNSec()); lock=false; - svo::SE2 out(filter_->state_(2),Eigen::Vector2d(filter_->state_(0),filter_->state_(1))); - return std::pair,svo::SE2>(filter_->cov_,out); + return std::pair,svo::SE2_5>(filter_->cov_,svo::SE2_5(filter_->state_(0),filter_->state_(1),filter_->state_(2))); }; private: Base* filter_= nullptr; diff --git a/GPU_version/vio/param/vo_fast.yaml b/GPU_version/vio/param/vo_fast.yaml index 11b2b18..f0c5dd7 100644 --- a/GPU_version/vio/param/vo_fast.yaml +++ b/GPU_version/vio/param/vo_fast.yaml @@ -7,9 +7,9 @@ svo: init_min_tracked: 100 init_min_disparity: 30 structureoptim_max_pts: 50 - kfselect_mindist: 0.05 + kfselect_mindist: 0.001 poseoptim_thresh: 4.0 - ACC_noise: 0.1 #acc white noise in continuous in EKF - GYO_noise: 0.1 #gyro white noise in continuous in EKF - svo_ekf: 5 #Svo noise that will be devided by number of Reprojected points after opmization in EKF - Cmd_Cov: 0.5 #control vector noise in EKF + ACC_noise: 0.001 #acc white noise in continuous in EKF + GYO_noise: 0.001 #gyro white noise in continuous in EKF + svo_ekf: 100 #Svo noise that will be devided by number of Reprojected points after opmization in EKF + Cmd_Cov: 0.001 #control vector noise in EKF diff --git a/GPU_version/vio/src/frame_handler_mono.cpp b/GPU_version/vio/src/frame_handler_mono.cpp index f9782a5..5f172ab 100644 --- a/GPU_version/vio/src/frame_handler_mono.cpp +++ b/GPU_version/vio/src/frame_handler_mono.cpp @@ -113,7 +113,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() new_frame_->T_f_w_ = last_frame_->T_f_w_; initialization::InitResult res = klt_homography_init_->addSecondFrame(new_frame_); auto result=ukfPtr_.UpdateSvo(new_frame_->T_f_w_.getSE2().translation()(0),new_frame_->T_f_w_.getSE2().translation()(1),new_frame_->T_f_w_.pitch(),1000,time_); - new_frame_->T_f_w_ = SE2_5(result.second); + new_frame_->T_f_w_ = result.second; new_frame_->Cov_ = result.first; if(res == initialization::NO_KEYFRAME) return RESULT_NO_KEYFRAME; @@ -138,8 +138,6 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), 30, SparseImgAlign::LevenbergMarquardt, false, false); img_align.run(last_frame_, new_frame_); - // std::cout<<"img_align:\n"<T_f_w_.getSE2()<<"\n"; - // map reprojection & feature alignment reprojector_.reprojectMap(new_frame_, overlap_kfs_); size_t sfba_n_edges_final=0; double sfba_thresh, sfba_error_init, sfba_error_final; @@ -151,7 +149,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() } auto result=ukfPtr_.UpdateSvo(new_frame_->T_f_w_.getSE2().translation()(0), new_frame_->T_f_w_.getSE2().translation()(1),new_frame_->T_f_w_.pitch(),sfba_n_edges_final,time_); - new_frame_->T_f_w_ = SE2_5(result.second); + new_frame_->T_f_w_ =result.second; new_frame_->Cov_ = result.first; std::cout<<"Reprojection Map nPoint: "< 50 || depth_min < 0.0) - { - return RESULT_NO_KEYFRAME; - } if(!needNewKf(depth_mean) || tracking_quality_ == TRACKING_BAD)//edited { depth_filter_->addFrame(new_frame_); @@ -191,6 +185,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() // init new depth-filters depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min); + // if limited number of keyframes, remove the one furthest apart if(Config::maxNKfs() > 2 && map_.size() >= Config::maxNKfs()) { @@ -275,13 +270,11 @@ bool FrameHandlerMono::needNewKf(double scene_depth_mean) if(scene_depth_mean >10.0)return true; for(auto&& it:overlap_kfs_) { - Vector3d relpos = new_frame_->w2f(Vector3d(it.first->pos()(0),0.0,it.first->pos()(1))); - if(fabs(relpos.norm())/scene_depth_mean < Config::kfSelectMinDist()){ - return false; - } - + if(fabs(it.first->T_f_w_.pitch()-new_frame_->T_f_w_.pitch())>0.0523599)return true; + if(fabs((it.first->T_f_w_.translation()-new_frame_->T_f_w_.translation()).norm()) > Config::kfSelectMinDist()) + return true; } - return true; + return false; } void FrameHandlerMono::setCoreKfs(size_t n_closest) diff --git a/GPU_version/vio/src/map.cpp b/GPU_version/vio/src/map.cpp index 877d617..c6eb05b 100644 --- a/GPU_version/vio/src/map.cpp +++ b/GPU_version/vio/src/map.cpp @@ -109,7 +109,6 @@ void Map::getCloseKeyframes( { for(auto kf : keyframes_) { - std::cout<<"key points:"<key_pts_.size())<<'\t'; // check if kf has overlaping field of view with frame, use therefore KeyPoints for(auto keypoint : kf->key_pts_) { From 99fa000ad55f5178d9f6d45956de41aadb4876a9 Mon Sep 17 00:00:00 2001 From: gfuse Date: Sat, 10 Jul 2021 13:35:58 +0200 Subject: [PATCH 212/215] Edit EKF and VO pipline to publish the odometry as soon as algorithm initialized. And VO will not save those frames that do not have features. --- GPU_version/vio/include/gpu_svo/frame.h | 27 ++----- .../vio/include/gpu_svo/frame_handler_mono.h | 2 +- GPU_version/vio/include/gpu_svo/global.h | 19 ++++- GPU_version/vio/include/gpu_svo/matcher.h | 2 +- GPU_version/vio/include/gpu_svo/ukf.h | 25 ++++-- GPU_version/vio/include/gpu_svo/vision.h | 5 +- GPU_version/vio/include/gpu_svo/visualizer.h | 12 +-- GPU_version/vio/param/vo_fast.yaml | 8 +- GPU_version/vio/src/depth_filter.cpp | 2 +- GPU_version/vio/src/feature_alignment.cpp | 1 - GPU_version/vio/src/frame_handler_mono.cpp | 29 ++++--- GPU_version/vio/src/initialization.cpp | 6 +- GPU_version/vio/src/map.cpp | 2 +- GPU_version/vio/src/matcher.cpp | 76 +++++++++---------- GPU_version/vio/src/point.cpp | 14 ++-- GPU_version/vio/src/pose_optimizer.cpp | 4 +- GPU_version/vio/src/reprojector.cpp | 1 - GPU_version/vio/src/sparse_img_align.cpp | 8 +- GPU_version/vio/src/visualizer.cpp | 53 +++---------- GPU_version/vio/src/vo_node.cpp | 4 +- 20 files changed, 134 insertions(+), 166 deletions(-) diff --git a/GPU_version/vio/include/gpu_svo/frame.h b/GPU_version/vio/include/gpu_svo/frame.h index e02f1c6..3d1fd72 100644 --- a/GPU_version/vio/include/gpu_svo/frame.h +++ b/GPU_version/vio/include/gpu_svo/frame.h @@ -93,11 +93,7 @@ public: /// Transforms point coordinates in world-frame (w) to camera pixel coordinates (c). inline Vector2d w2c(const Vector3d& xyz_w) const { - Eigen::Matrix R; - R<world2cam( SE3(R,Vector3d(T_f_w_.T2_.translation()(0),1e-19,T_f_w_.T2_.translation()(1)))*xyz_w); + return cam_->world2cam( T_f_w_.se3()*xyz_w); } /// Transforms point coordinates in world-frame (w) to camera pixel coordinates (c). inline Vector2d w2px(const Vector3d& xyz_w) const { return cam_->world2cam( xyz_w ); } @@ -110,35 +106,22 @@ public: /// Transforms point coordinates in world-frame (w) to camera-frams (f). inline Vector3d w2f(const Vector3d& xyz_w) const { - Eigen::Matrix R; - R< R; - R<world2cam( f ); } /// Return the pose of the frame in the (w)orld coordinate frame. - inline Vector2d pos() const { return T_f_w_.T2_.translation(); } + inline Vector2d pos() const { return T_f_w_.se2().translation(); } inline SE3 se3() const{ - Eigen::Matrix R; - R< imu_integPtr_; //Integration of IMU void UpdateIMU(double* value,const ros::Time& time); void UpdateCmd(double* value,const ros::Time& time); + UKF ukfPtr_; protected: vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit). @@ -76,7 +77,6 @@ protected: DepthFilter* depth_filter_; //!< Depth estimation algorithm runs in a parallel thread and is used to initialize new 3D points. opencl* gpu_fast_; ros::Time time_; - UKF ukfPtr_; /// Initialize the visual odometry algorithm. virtual void initialize(); diff --git a/GPU_version/vio/include/gpu_svo/global.h b/GPU_version/vio/include/gpu_svo/global.h index e522a69..60d0f55 100644 --- a/GPU_version/vio/include/gpu_svo/global.h +++ b/GPU_version/vio/include/gpu_svo/global.h @@ -52,7 +52,6 @@ namespace svo const double PI = 3.14159265; class SE2_5: public SE2{ public: - SE2 T2_; SE2_5(SE2&& se2):T2_(se2){ } SE2_5(SE2& se2):T2_(se2){ @@ -87,17 +86,31 @@ namespace svo -sin(pitch),cos(pitch); T2_=SE2(R,Vector2d(x,z)); }; - SE2 getSE2() const{ + SE2 se2() const{ return T2_; } SE2 inverse() const{ double yaw=atan(T2_.rotation_matrix()(0,1)/T2_.rotation_matrix()(0,0)); - return SE2(yaw+PI,T2_.translation()); + if(yaw<0.0) + yaw=M_PI-yaw; + else + yaw=yaw-M_PI; + return SE2(yaw,-1.0*T2_.translation()); } double pitch()const{ return atan(T2_.rotation_matrix()(0,1)/T2_.rotation_matrix()(0,0)); } + SE3 se3() const{ + Eigen::Matrix R; + R<M_PI_4)state_(2)-=M_PI; - if(fabs(state_(2))>2*M_PI)state_(2)-=2.0*int(0.5*state_(2)/M_PI)*M_PI; cov_=(Eigen::MatrixXd::Identity(3,3)-k*H)*cov_h_; state_h_(2)=state_(2)+dt*dpitch; state_h_(1)=state_(1)+0.5*pow(dt,2)*(ddz*cos(state_(2))-ddx*sin(state_(2))); @@ -90,8 +88,6 @@ public: E<M_PI_4)state_(2)-=M_PI; - if(fabs(state_(2))>2*M_PI)state_(2)-=2.0*int(0.5*state_(2)/M_PI)*M_PI; cov_=(Eigen::MatrixXd::Identity(3,3)-k*H)*cov_h_; yaw_t_1_=state_(2); predict_up=false; @@ -131,10 +127,27 @@ public: std::pair,svo::SE2_5> UpdateSvo(double x,double z,double pitch,size_t match,ros::Time& time) { while(lock)usleep(5); lock=true; - if(filter_->predict_up)filter_->correct(x,z,pitch,match,1e-9*time.toNSec()); + if(pitch<0.0) + pitch=M_PI-pitch; + else + pitch=pitch-M_PI; + if(filter_->predict_up)filter_->correct(-x,-z,pitch,match,1e-9*time.toNSec()); lock=false; - return std::pair,svo::SE2_5>(filter_->cov_,svo::SE2_5(filter_->state_(0),filter_->state_(1),filter_->state_(2))); + double pitch_f; + if(filter_->state_(0)<0.0) + pitch_f=M_PI-filter_->state_(2); + else + pitch_f=filter_->state_(2)-M_PI; + return std::pair,svo::SE2_5>(filter_->cov_,svo::SE2_5(-filter_->state_(0),-filter_->state_(1),pitch_f)); }; + std::pair,svo::SE2_5> get_location(){ + double pitch_f; + if(filter_->state_(0)<0.0) + pitch_f=M_PI-filter_->state_(2); + else + pitch_f=filter_->state_(2)-M_PI; + return std::pair,svo::SE2_5>(filter_->cov_,svo::SE2_5(-filter_->state_(0),-filter_->state_(1),pitch_f)); + } private: Base* filter_= nullptr; bool lock=false; diff --git a/GPU_version/vio/include/gpu_svo/vision.h b/GPU_version/vio/include/gpu_svo/vision.h index 1533775..3b95183 100644 --- a/GPU_version/vio/include/gpu_svo/vision.h +++ b/GPU_version/vio/include/gpu_svo/vision.h @@ -42,7 +42,8 @@ interpolateMat_32f(const cv::Mat& mat, float u, float v) inline float interpolateMat_8u(const cv::Mat& mat, float u, float v) { - assert(mat.type()==CV_8U); + if(mat.empty())return 0.0; + if(mat.type()!=CV_8U)return 0.0; int x = floor(u); int y = floor(v); float subpix_x = u-x; @@ -55,6 +56,8 @@ interpolateMat_8u(const cv::Mat& mat, float u, float v) const int stride = mat.step.p[0]; unsigned char* ptr = mat.data + y*stride + x; + if(isnan(w00) || isnan(w01 )||isnan( w10) || isnan(w11) || isinf(w00) || isinf(w01)|| isinf(w10)|| isinf(w11))return 0.0; + if(ptr[0] == NULL || ptr[1]== NULL || ptr[stride]==NULL ||ptr[stride+1]==NULL)return 0.0; return w00*ptr[0] + w01*ptr[stride] + w10*ptr[1] + w11*ptr[stride+1]; } diff --git a/GPU_version/vio/include/gpu_svo/visualizer.h b/GPU_version/vio/include/gpu_svo/visualizer.h index 7c09cd1..819885d 100644 --- a/GPU_version/vio/include/gpu_svo/visualizer.h +++ b/GPU_version/vio/include/gpu_svo/visualizer.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace svo { @@ -54,18 +55,9 @@ public: ~Visualizer() {}; void publishMinimal( - const cv::Mat& img, - const FramePtr& frame, - const FrameHandlerMono& slam, + UKF& ukf, const double timestamp); - void visualizeMarkers( - const FramePtr& frame, - const set& core_kfs, - const Map& map); - - void removeDeletedPts(const Map& map); - }; } // end namespace svo diff --git a/GPU_version/vio/param/vo_fast.yaml b/GPU_version/vio/param/vo_fast.yaml index f0c5dd7..1ecb630 100644 --- a/GPU_version/vio/param/vo_fast.yaml +++ b/GPU_version/vio/param/vo_fast.yaml @@ -7,9 +7,9 @@ svo: init_min_tracked: 100 init_min_disparity: 30 structureoptim_max_pts: 50 - kfselect_mindist: 0.001 + kfselect_mindist: 0.01 poseoptim_thresh: 4.0 - ACC_noise: 0.001 #acc white noise in continuous in EKF + ACC_noise: 0.5 #acc white noise in continuous in EKF GYO_noise: 0.001 #gyro white noise in continuous in EKF - svo_ekf: 100 #Svo noise that will be devided by number of Reprojected points after opmization in EKF - Cmd_Cov: 0.001 #control vector noise in EKF + svo_ekf: 1.5 #Svo noise that will be devided by number of Reprojected points after opmization in EKF + Cmd_Cov: 1.0 #control vector noise in EKF diff --git a/GPU_version/vio/src/depth_filter.cpp b/GPU_version/vio/src/depth_filter.cpp index cbf0f33..ba653f2 100644 --- a/GPU_version/vio/src/depth_filter.cpp +++ b/GPU_version/vio/src/depth_filter.cpp @@ -233,7 +233,7 @@ void DepthFilter::updateSeeds(FramePtr frame) continue; } // check if point is visible in the current image - SE2 T(it->ftr->frame->T_f_w_.getSE2() * frame->T_f_w_.inverse()); + SE2 T(it->ftr->frame->T_f_w_.se2() * frame->T_f_w_.inverse()); Eigen::Matrix R; R<= cur_img.cols-halfpatch_size_ || v_r >= cur_img.rows-halfpatch_size_){ - std::cout<<"not in bach size\n"; break; } diff --git a/GPU_version/vio/src/frame_handler_mono.cpp b/GPU_version/vio/src/frame_handler_mono.cpp index 5f172ab..cc92553 100644 --- a/GPU_version/vio/src/frame_handler_mono.cpp +++ b/GPU_version/vio/src/frame_handler_mono.cpp @@ -89,7 +89,7 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp,const map_.getClosestKeyframe(last_frame_)); // set last frame - last_frame_ = new_frame_; + if(!new_frame_->fts_.empty() || stage_ != STAGE_DEFAULT_FRAME)last_frame_ = new_frame_; new_frame_.reset(); // finish processing finishFrameProcessingCommon(last_frame_->id_, res, last_frame_->nObs()); @@ -103,16 +103,18 @@ FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() new_frame_->setKeyframe(); map_.addKeyframe(new_frame_); stage_ = STAGE_SECOND_FRAME; - ukfPtr_.UpdateSvo(new_frame_->T_f_w_.getSE2().translation()(0),new_frame_->T_f_w_.getSE2().translation()(1),new_frame_->T_f_w_.pitch(),1000,time_); + ukfPtr_.UpdateSvo(new_frame_->T_f_w_.se2().translation()(0),new_frame_->T_f_w_.se2().translation()(1),new_frame_->T_f_w_.pitch(),1000,time_); SVO_INFO_STREAM("Init: Selected first frame."); return RESULT_IS_KEYFRAME; } FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() { - new_frame_->T_f_w_ = last_frame_->T_f_w_; + auto init_f= ukfPtr_.get_location(); + new_frame_->T_f_w_=init_f.second; + new_frame_->Cov_ = init_f.first; initialization::InitResult res = klt_homography_init_->addSecondFrame(new_frame_); - auto result=ukfPtr_.UpdateSvo(new_frame_->T_f_w_.getSE2().translation()(0),new_frame_->T_f_w_.getSE2().translation()(1),new_frame_->T_f_w_.pitch(),1000,time_); + auto result=ukfPtr_.UpdateSvo(new_frame_->T_f_w_.se2().translation()(0),new_frame_->T_f_w_.se2().translation()(1),new_frame_->T_f_w_.pitch(),1000,time_); new_frame_->T_f_w_ = result.second; new_frame_->Cov_ = result.first; if(res == initialization::NO_KEYFRAME) @@ -133,28 +135,31 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame() FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() { - new_frame_->T_f_w_ = last_frame_->T_f_w_; + auto init_f= ukfPtr_.get_location(); + new_frame_->T_f_w_=init_f.second; + new_frame_->Cov_ = init_f.first; // sparse image align SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(), 30, SparseImgAlign::LevenbergMarquardt, false, false); - img_align.run(last_frame_, new_frame_); + if(img_align.run(last_frame_, new_frame_)==0)return RESULT_FAILURE; reprojector_.reprojectMap(new_frame_, overlap_kfs_); size_t sfba_n_edges_final=0; double sfba_thresh, sfba_error_init, sfba_error_final; pose_optimizer::optimizeGaussNewton( Config::poseOptimThresh(), Config::poseOptimNumIter(), false, new_frame_, sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final); - if((last_frame_->T_f_w_.getSE2().translation()-new_frame_->T_f_w_.getSE2().translation()).norm()>0.1){ - new_frame_->T_f_w_ = last_frame_->T_f_w_; + if((last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()>2.0 || fabs(last_frame_->T_f_w_.pitch()-new_frame_->T_f_w_.pitch())>M_PI){ + new_frame_=last_frame_; + return RESULT_NO_KEYFRAME; } - auto result=ukfPtr_.UpdateSvo(new_frame_->T_f_w_.getSE2().translation()(0), - new_frame_->T_f_w_.getSE2().translation()(1),new_frame_->T_f_w_.pitch(),sfba_n_edges_final,time_); + auto result=ukfPtr_.UpdateSvo(new_frame_->T_f_w_.se2().translation()(0), + new_frame_->T_f_w_.se2().translation()(1),new_frame_->T_f_w_.pitch(),sfba_n_edges_final,time_); new_frame_->T_f_w_ =result.second; new_frame_->Cov_ = result.first; std::cout<<"Reprojection Map nPoint: "<T_f_w_.getSE2().translation()-new_frame_->T_f_w_.getSE2().translation()).norm()<<'\n'; + (last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()<<'\n'; if(sfba_n_edges_final < Config::qualityMinFts() || reprojector_.n_matches_ < Config::qualityMinFts()){ return RESULT_NO_KEYFRAME; } @@ -165,7 +170,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() setTrackingQuality(sfba_n_edges_final); if(tracking_quality_ == TRACKING_INSUFFICIENT) { - return RESULT_FAILURE; + return RESULT_FAILURE; } double depth_mean, depth_min; diff --git a/GPU_version/vio/src/initialization.cpp b/GPU_version/vio/src/initialization.cpp index 1ca4ced..379163f 100644 --- a/GPU_version/vio/src/initialization.cpp +++ b/GPU_version/vio/src/initialization.cpp @@ -69,9 +69,9 @@ InitResult KltHomographyInit::addSecondFrame(FramePtr frame_cur) depth_vec.push_back((xyz_in_cur_[i]).z()); double scene_depth_median = vk::getMedian(depth_vec); double scale = Config::mapScale()/scene_depth_median; - frame_cur->T_f_w_ = SE2_5(T_cur_from_ref_.getSE2() * frame_ref_->T_f_w_.getSE2()); - frame_cur->T_f_w_.T2_.translation() = -frame_cur->T_f_w_.getSE2().rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); - //frame_cur->T_f_w_.T2_.translation() = frame_cur->T_f_w_.getSE2().rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())); + frame_cur->T_f_w_ = SE2_5(T_cur_from_ref_.se2() * frame_ref_->T_f_w_.se2()); + frame_cur->T_f_w_ = SE2_5(SE2(frame_cur->T_f_w_.se2().rotation_matrix(), + -frame_cur->T_f_w_.se2().rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos())))); // For each inlier create 3D point and add feature in both frames SE3 T_world_cur = frame_cur->getSE3Inv(); for(vector::iterator it=inliers_.begin(); it!=inliers_.end(); ++it) diff --git a/GPU_version/vio/src/map.cpp b/GPU_version/vio/src/map.cpp index c6eb05b..3d0cace 100644 --- a/GPU_version/vio/src/map.cpp +++ b/GPU_version/vio/src/map.cpp @@ -118,7 +118,7 @@ void Map::getCloseKeyframes( { close_kfs.push_back( std::make_pair( - kf, (frame->T_f_w_.getSE2().translation()-kf->T_f_w_.getSE2().translation()).norm())); + kf, (frame->T_f_w_.se2().translation()-kf->T_f_w_.se2().translation()).norm())); break; // this keyframe has an overlapping field of view -> add to close_kfs } } diff --git a/GPU_version/vio/src/matcher.cpp b/GPU_version/vio/src/matcher.cpp index 3e6d47b..767d542 100644 --- a/GPU_version/vio/src/matcher.cpp +++ b/GPU_version/vio/src/matcher.cpp @@ -69,7 +69,7 @@ int getBestSearchLevel( return search_level; } -void warpAffine( +bool warpAffine( const Matrix2d& A_cur_ref, const cv::Mat& img_ref, const Vector2d& px_ref, @@ -78,14 +78,14 @@ void warpAffine( const int halfpatch_size, uint8_t* patch) { + if(patch==NULL || img_ref.empty())return false; const int patch_size = halfpatch_size*2 ; const Matrix2f A_ref_cur = A_cur_ref.inverse().cast(); if(isnan(A_ref_cur(0,0))) { printf("Affine warp is NaN, probably camera has no translation\n"); // TODO - return; + return false; } - // Perform the warp on a larger patch. uint8_t* patch_ptr = patch; const Vector2f px_ref_pyr = px_ref.cast() / (1<=img_ref.cols-1 || px[1]>=img_ref.rows-1) - *patch_ptr = 0; - else - *patch_ptr = (uint8_t) vk::interpolateMat_8u(img_ref, px[0], px[1]); + if(patch_ptr == nullptr)continue; + if (px[0]<1 || px[1]<1 || px[0]>=img_ref.cols-1 || px[1]>=img_ref.rows-1){ + *patch_ptr = 0; + }else{ + *patch_ptr = (uint8_t) vk::interpolateMat_8u(img_ref, px[0], px[1]); + } } } + return true; } } // namespace warp @@ -117,7 +120,7 @@ bool depthFromTriangulation( if(AtA.determinant() < 0.000001) return false; const Vector2d depth2 = - AtA.inverse()*A.transpose()*T_search_ref.translation(); - depth = fabs(depth2[0]); + depth = fabs(depth2[0]/depth2[1]); return true; } @@ -142,35 +145,36 @@ bool Matcher::findMatchDirect( if(!ref_ftr_->frame->cam_->isInFrame( ref_ftr_->px.cast()/(1<level), halfpatch_size_+2, ref_ftr_->level)) return false; - + if(ref_ftr_->frame->img_pyr_.empty())return false; + if(ref_ftr_->frame->img_pyr_[ref_ftr_->level].empty())return false; // warp affine warp::getWarpMatrixAffine( *ref_ftr_->frame->cam_, *cur_frame.cam_, ref_ftr_->px, ref_ftr_->f, (Vector3d(ref_ftr_->frame->pos()(0),0.0,ref_ftr_->frame->pos()(1)) - pt.pos_).norm(), cur_frame.se3() * ref_ftr_->frame->getSE3Inv(), ref_ftr_->level, A_cur_ref_); search_level_ = warp::getBestSearchLevel(A_cur_ref_, Config::nPyrLevels()-1); - warp::warpAffine(A_cur_ref_, ref_ftr_->frame->img_pyr_[ref_ftr_->level], ref_ftr_->px, - ref_ftr_->level, search_level_, halfpatch_size_+1, patch_with_border_); + if(!warp::warpAffine(A_cur_ref_, ref_ftr_->frame->img_pyr_[ref_ftr_->level], ref_ftr_->px, + ref_ftr_->level, search_level_, halfpatch_size_+1, patch_with_border_))return false; createPatchFromPatchWithBorder(); // px_cur should be set Vector2d px_scaled(px_cur/(1<type == Feature::EDGELET) - { - Vector2d dir_cur(A_cur_ref_*ref_ftr_->grad); - dir_cur.normalize(); - success = feature_alignment::align1D( - cur_frame.img_pyr_[search_level_], dir_cur.cast(), - patch_with_border_, patch_, options_.align_max_iter, px_scaled, h_inv_); - } - else - { + // if(ref_ftr_->type == Feature::EDGELET) + //{ + // Vector2d dir_cur(A_cur_ref_*ref_ftr_->grad); + // dir_cur.normalize(); + // success = feature_alignment::align1D( + // cur_frame.img_pyr_[search_level_], dir_cur.cast(), + // patch_with_border_, patch_, options_.align_max_iter, px_scaled, h_inv_); + //} + //else + //{ success = feature_alignment::align2D( cur_frame.img_pyr_[search_level_], patch_with_border_, patch_, options_.align_max_iter, px_scaled); - } + // } px_cur = px_scaled * (1< R; - R<cam2world(px_cur_), depth)) + if(depthFromTriangulation(T_cur_ref.se3(), ref_ftr.f, cur_frame.cam_->cam2world(px_cur_), depth)) return true; } return false; @@ -314,13 +312,13 @@ bool Matcher::findEpipolarMatchDirect( if(res) { px_cur_ = px_scaled*(1<cam2world(px_cur_), depth)) + if(depthFromTriangulation(T_cur_ref.se3(), ref_ftr.f, cur_frame.cam_->cam2world(px_cur_), depth)) return true; } return false; } px_cur_ = cur_frame.cam_->world2cam(uv_best); - if(depthFromTriangulation(T_cur_ref, ref_ftr.f, vk::unproject2d(uv_best).normalized(), depth)) + if(depthFromTriangulation(T_cur_ref.se3(), ref_ftr.f, vk::unproject2d(uv_best).normalized(), depth)) return true; } return false; diff --git a/GPU_version/vio/src/point.cpp b/GPU_version/vio/src/point.cpp index aee4bd8..cf12a1e 100644 --- a/GPU_version/vio/src/point.cpp +++ b/GPU_version/vio/src/point.cpp @@ -99,21 +99,19 @@ bool Point::getCloseViewObs(const Vector2d& framepos, Feature*& ftr) const { // TODO: get frame with same point of view AND same pyramid level! Vector3d obs_dir(Vector3d(framepos(0),0.0,framepos(1)) - pos_); obs_dir.normalize(); - auto min_it=obs_.begin(); - double min_cos_angle = 0; + auto max_it=obs_.begin(); + double max_cos_angle = 1; for(auto it=obs_.begin(), ite=obs_.end(); it!=ite; ++it) { Vector3d dir(Vector3d((*it)->frame->pos()(0),0.0,(*it)->frame->pos()(1)) - pos_); dir.normalize(); double cos_angle = obs_dir.dot(dir); - if(cos_angle > min_cos_angle) + if(cos_angle < max_cos_angle) { - min_cos_angle = cos_angle; - min_it = it; + max_cos_angle = cos_angle; + max_it = it; } } - ftr = *min_it; - if(min_cos_angle < 0.5) // assume that observations larger than 60° are useless - return false; + ftr = *max_it; return true; } diff --git a/GPU_version/vio/src/pose_optimizer.cpp b/GPU_version/vio/src/pose_optimizer.cpp index 79e4686..3d45ab5 100644 --- a/GPU_version/vio/src/pose_optimizer.cpp +++ b/GPU_version/vio/src/pose_optimizer.cpp @@ -121,9 +121,9 @@ void optimizeGaussNewton( // update the model T_old = frame->T_f_w_; if(direction){ - frame->T_f_w_=SE2_5(SE2::exp(dT)*(T_old.getSE2())); + frame->T_f_w_=SE2_5(SE2::exp(dT)*(T_old.se2())); }else{ - frame->T_f_w_=SE2_5(SE2::exp(-1.0*dT)*(T_old.getSE2())); + frame->T_f_w_=SE2_5(SE2::exp(-1.0*dT)*(T_old.se2())); } chi2 = new_chi2; if(verbose) diff --git a/GPU_version/vio/src/reprojector.cpp b/GPU_version/vio/src/reprojector.cpp index 7a598b6..897ce59 100644 --- a/GPU_version/vio/src/reprojector.cpp +++ b/GPU_version/vio/src/reprojector.cpp @@ -72,7 +72,6 @@ void Reprojector::reprojectMap( list< pair > close_kfs; map_.getCloseKeyframes(frame, close_kfs); - std::cout<<"The number of closed frames: "<::second, _1) < boost::bind(&std::pair::second, _2)); diff --git a/GPU_version/vio/src/sparse_img_align.cpp b/GPU_version/vio/src/sparse_img_align.cpp index 533c776..59c754c 100644 --- a/GPU_version/vio/src/sparse_img_align.cpp +++ b/GPU_version/vio/src/sparse_img_align.cpp @@ -46,7 +46,6 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) if(ref_frame->fts_.empty()) { - SVO_WARN_STREAM("SparseImgAlign: no features to track!"); return 0; } @@ -54,8 +53,7 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) cur_frame_ = cur_frame; ref_patch_cache_ = cv::Mat(ref_frame_->fts_.size(), patch_area_, CV_32F); jacobian_cache_.resize(Eigen::NoChange, ref_patch_cache_.rows*patch_area_); - //visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? - SE2 T_cur_from_ref(cur_frame_->T_f_w_.getSE2() * ref_frame_->T_f_w_.inverse()); + SE2 T_cur_from_ref(cur_frame_->T_f_w_.se2() * ref_frame_->T_f_w_.inverse()); for(level_=max_level_; level_>=min_level_; --level_) { visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level? @@ -66,7 +64,7 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame) printf("\nPYRAMID LEVEL %i\n---------------\n", level_); optimize(T_cur_from_ref); } - cur_frame_->T_f_w_ = SE2_5(T_cur_from_ref * ref_frame_->T_f_w_.getSE2()); + cur_frame_->T_f_w_ = SE2_5(T_cur_from_ref * ref_frame_->T_f_w_.se2()); return n_meas_/patch_area_; } @@ -251,7 +249,7 @@ void SparseImgAlign::update( const ModelType& T_curold_from_ref, ModelType& T_curnew_from_ref) { - T_curnew_from_ref = T_curold_from_ref * SE2::exp(-1.0*x_); + T_curnew_from_ref = T_curold_from_ref * SE2::exp(-0.25*x_); } void SparseImgAlign::startIteration() diff --git a/GPU_version/vio/src/visualizer.cpp b/GPU_version/vio/src/visualizer.cpp index 95b3353..9e8808d 100644 --- a/GPU_version/vio/src/visualizer.cpp +++ b/GPU_version/vio/src/visualizer.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace svo { @@ -40,9 +41,7 @@ Visualizer() : } void Visualizer::publishMinimal( - const cv::Mat& img, - const FramePtr& frame, - const FrameHandlerMono& slam, + UKF& ukf, const double timestamp) { ++trace_id_; @@ -50,63 +49,33 @@ void Visualizer::publishMinimal( header_msg.frame_id = "/world"; header_msg.seq = trace_id_; header_msg.stamp = ros::Time(timestamp); - if(pub_pose_with_cov_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME) + if(pub_pose_with_cov_.getNumSubscribers() > 0) { // publish cam in world frame (Estimated odometry in the worls frame) - Quaterniond q(AngleAxisd(frame->T_f_w_.pitch(), Vector3d::UnitZ())); + auto odom=ukf.get_location(); + Quaterniond q(AngleAxisd(odom.second.pitch()+M_PI_2, Vector3d::UnitZ())); geometry_msgs::PoseWithCovarianceStampedPtr msg_pose_with_cov(new geometry_msgs::PoseWithCovarianceStamped); msg_pose_with_cov->header = header_msg; - msg_pose_with_cov->pose.pose.position.x = frame->se3().translation().x(); - msg_pose_with_cov->pose.pose.position.y = frame->se3().translation().z(); + msg_pose_with_cov->pose.pose.position.x = -odom.second.se2().translation()(0); + msg_pose_with_cov->pose.pose.position.y = -odom.second.se2().translation()(1); msg_pose_with_cov->pose.pose.position.z = 0.0; msg_pose_with_cov->pose.pose.orientation.x = q.x(); msg_pose_with_cov->pose.pose.orientation.y = q.y(); msg_pose_with_cov->pose.pose.orientation.z = q.z(); msg_pose_with_cov->pose.pose.orientation.w = q.w(); - msg_pose_with_cov->pose.covariance = {frame->Cov_(0,0),frame->Cov_(0,1),0.0,0.0,frame->Cov_(0,2),0.0, - frame->Cov_(1,0),frame->Cov_(1,1),0.0,0.0,frame->Cov_(1,2),0.0, + msg_pose_with_cov->pose.covariance = {odom.first(0,0),odom.first(0,1),0.0,0.0,odom.first(0,2),0.0, + odom.first(1,0),odom.first(1,1),0.0,0.0,odom.first(1,2),0.0, 0.0,0.0,0.0000001,0.0,0.0,0.0, 0.0,0.0,0.0,0.0000001,0.0,0.0, - frame->Cov_(2,0),frame->Cov_(2,1),0.0,0.0,frame->Cov_(2,2),0.0, + odom.first(2,0),odom.first(2,1),0.0,0.0,odom.first(2,2),0.0, 0.0,0.0,0.0,0.0,0.0,0.0000001}; pub_pose_with_cov_.publish(msg_pose_with_cov); if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0){ publishPointMarker( - pub_points_, Eigen::Vector3d(frame->se3().translation().x(),frame->se3().translation().z(),0.0), "trajectory", + pub_points_, Eigen::Vector3d(-odom.second.se2().translation()(0),-odom.second.se2().translation()(1),0.0), "trajectory", ros::Time::now(), trace_id_, 0, 0.01, Vector3d(0.,0.,0.5)); } } } - -void Visualizer::visualizeMarkers( - const FramePtr& frame, - const set& core_kfs, - const Map& map) -{ - if(frame == NULL) - return; - - publishTfTransform( - frame->se3()*T_world_from_vision_.inverse(), - ros::Time(frame->timestamp_), "cam_pos", "world", br_); - - if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0) - { - publishPointMarker( - pub_points_, T_world_from_vision_*Vector3d(frame->pos()(0),0.0,frame->pos()(1)), "trajectory", - ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5)); - removeDeletedPts(map); - } -} - -void Visualizer::removeDeletedPts(const Map& map) -{ - if(pub_points_.getNumSubscribers() > 0) - { - for(list::const_iterator it=map.trash_points_.begin(); it!=map.trash_points_.end(); ++it) - publishPointMarker(pub_points_, Vector3d(), "pts", ros::Time::now(), (*it)->id_, 2, 0.006, Vector3d()); - } -} - } // end namespace gpu_svo diff --git a/GPU_version/vio/src/vo_node.cpp b/GPU_version/vio/src/vo_node.cpp index 8fe3f84..dfae0ab 100644 --- a/GPU_version/vio/src/vo_node.cpp +++ b/GPU_version/vio/src/vo_node.cpp @@ -108,9 +108,6 @@ void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) auto start=std::chrono::steady_clock::now(); cv::Mat img=cv_bridge::toCvShare(msg, "mono8")->image; vo_->addImage(img, msg->header.stamp.toSec(),msg->header.stamp); - visualizer_.publishMinimal(img, vo_->lastFrame(), *vo_, msg->header.stamp.toSec()); - if(vo_->stage() == svo::FrameHandlerMono::STAGE_PAUSED) - usleep(100000); #if VIO_DEBUG fprintf(log_, ",,,,,,,%s,%f,%f,%f\n",std::to_string(std::chrono::duration(std::chrono::steady_clock::now()-start).count()).c_str(),vo_->lastFrame()->T_f_w_.translation()(0), vo_->lastFrame()->T_f_w_.translation()(1), @@ -158,6 +155,7 @@ void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { #endif vo_->UpdateIMU(imu_in,imu->header.stamp); imu_time_=imu->header.stamp; + visualizer_.publishMinimal(vo_->ukfPtr_, imu->header.stamp.toSec()); } void VoNode::cmdCb(const geometry_msgs::TwistPtr &cmd) { double _cmd[3]={cmd->linear.x,cmd->linear.y,cmd->angular.z}; From 4cb5cbff09204a532c37368f1203422cb5f8f383 Mon Sep 17 00:00:00 2001 From: gfuse Date: Tue, 13 Jul 2021 12:05:55 +0200 Subject: [PATCH 213/215] solve the crash issue for feature delete --- GPU_version/vio/include/gpu_svo/map.h | 3 ++- GPU_version/vio/launch/Px30.launch | 2 +- GPU_version/vio/src/feature_alignment.cpp | 16 ++++++++-------- GPU_version/vio/src/frame_handler_mono.cpp | 7 +++---- GPU_version/vio/src/map.cpp | 9 +++++++++ GPU_version/vio/src/matcher.cpp | 22 +++++++++++----------- 6 files changed, 34 insertions(+), 25 deletions(-) diff --git a/GPU_version/vio/include/gpu_svo/map.h b/GPU_version/vio/include/gpu_svo/map.h index e554088..d4a02e0 100644 --- a/GPU_version/vio/include/gpu_svo/map.h +++ b/GPU_version/vio/include/gpu_svo/map.h @@ -66,7 +66,7 @@ public: void emptyTrash(); }; - +static bool syn_=false; /// Map object which saves all keyframes which are in a map. class Map : boost::noncopyable { @@ -75,6 +75,7 @@ public: list< Point* > trash_points_; //!< A deleted point is moved to the trash bin. Now and then this is cleaned. One reason is that the visualizer must remove the points also. MapPointCandidates point_candidates_; + Map(); ~Map(); diff --git a/GPU_version/vio/launch/Px30.launch b/GPU_version/vio/launch/Px30.launch index 581e4b1..efaecc2 100644 --- a/GPU_version/vio/launch/Px30.launch +++ b/GPU_version/vio/launch/Px30.launch @@ -1,6 +1,6 @@ - + diff --git a/GPU_version/vio/src/feature_alignment.cpp b/GPU_version/vio/src/feature_alignment.cpp index 00367df..918ab25 100644 --- a/GPU_version/vio/src/feature_alignment.cpp +++ b/GPU_version/vio/src/feature_alignment.cpp @@ -36,9 +36,9 @@ bool align1D( Vector2d& cur_px_estimate, double& h_inv) { - const int halfpatch_size_ = 4; - const int patch_size = 8; - const int patch_area = 64; + const int halfpatch_size_ = 1; + const int patch_size = 2; + const int patch_area = 4; bool converged=false; // compute derivative of template and prepare inverse compositional @@ -69,7 +69,7 @@ bool align1D( float v = cur_px_estimate.y(); // termination condition - const float min_update_squared = 0.5*0.5; + const float min_update_squared = 0.05; const int cur_step = cur_img.step.p[0]; float chi2 = 0; Vector2f update; update.setZero(); @@ -163,9 +163,9 @@ bool align2D( return align2D_NEON(cur_img, ref_patch_with_border, ref_patch, n_iter, cur_px_estimate); #endif - const int halfpatch_size_ = 4; - const int patch_size_ = 8; - const int patch_area_ = 64; + const int halfpatch_size_ = 1; + const int patch_size_ = 2; + const int patch_area_ = 4; bool converged=false; // compute derivative of template and prepare inverse compositional @@ -202,7 +202,7 @@ bool align2D( bool sign=true;// + // termination condition - const float min_update_squared = 0.5;//0.001 + const float min_update_squared = 0.05;//0.001 const int cur_step = cur_img.step.p[0]; // float chi2 = 0; Vector3f update; update.setZero(); diff --git a/GPU_version/vio/src/frame_handler_mono.cpp b/GPU_version/vio/src/frame_handler_mono.cpp index cc92553..caea65b 100644 --- a/GPU_version/vio/src/frame_handler_mono.cpp +++ b/GPU_version/vio/src/frame_handler_mono.cpp @@ -148,7 +148,9 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() pose_optimizer::optimizeGaussNewton( Config::poseOptimThresh(), Config::poseOptimNumIter(), false, new_frame_, sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final); - if((last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()>2.0 || fabs(last_frame_->T_f_w_.pitch()-new_frame_->T_f_w_.pitch())>M_PI){ + if((last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()>2.0 || + fabs(last_frame_->T_f_w_.pitch()-new_frame_->T_f_w_.pitch())>M_PI || + sfba_n_edges_final < Config::qualityMinFts() || reprojector_.n_matches_ < Config::qualityMinFts()){ new_frame_=last_frame_; return RESULT_NO_KEYFRAME; } @@ -160,9 +162,6 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame() <<"\tnCell: "<T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()<<'\n'; - if(sfba_n_edges_final < Config::qualityMinFts() || reprojector_.n_matches_ < Config::qualityMinFts()){ - return RESULT_NO_KEYFRAME; - } optimizeStructure(new_frame_, Config::structureOptimMaxPts(), Config::structureOptimNumIter()); // select keyframe diff --git a/GPU_version/vio/src/map.cpp b/GPU_version/vio/src/map.cpp index 3d0cace..9e4196e 100644 --- a/GPU_version/vio/src/map.cpp +++ b/GPU_version/vio/src/map.cpp @@ -40,6 +40,7 @@ void Map::reset() bool Map::safeDeleteFrame(FramePtr frame) { + if(syn_==true)return false; bool found = false; for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) { @@ -107,6 +108,7 @@ void Map::getCloseKeyframes( const FramePtr& frame, std::list< std::pair >& close_kfs) const { + syn_=true; for(auto kf : keyframes_) { // check if kf has overlaping field of view with frame, use therefore KeyPoints @@ -123,6 +125,7 @@ void Map::getCloseKeyframes( } } } + syn_=false; } FramePtr Map::getClosestKeyframe(const FramePtr& frame) const @@ -149,6 +152,7 @@ FramePtr Map::getFurthestKeyframe(const Vector2d& pos) const { FramePtr furthest_kf; double maxdist = 0.0; + syn_=true; for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) { double dist = ((*it)->pos()-pos).norm(); @@ -157,18 +161,21 @@ FramePtr Map::getFurthestKeyframe(const Vector2d& pos) const furthest_kf = *it; } } + syn_=false; return furthest_kf; } bool Map::getKeyframeById(const int id, FramePtr& frame) const { bool found = false; + syn_=true; for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it) if((*it)->id_ == id) { found = true; frame = *it; break; } + syn_=false; return found; } @@ -178,6 +185,7 @@ void Map::transform(const Matrix2d& R, const Vector2d& t, const double& s) R3<T_f_w_.inverse().rotation_matrix(),s*R*(*it)->pos() + t)); @@ -192,6 +200,7 @@ void Map::transform(const Matrix2d& R, const Vector2d& t, const double& s) (*ftr)->point->pos_ = s*R3*(*ftr)->point->pos_ + Vector3d(t(0),0.0,t(1)); } } + syn_=false; } void Map::emptyTrash() diff --git a/GPU_version/vio/src/matcher.cpp b/GPU_version/vio/src/matcher.cpp index 767d542..1b025c9 100644 --- a/GPU_version/vio/src/matcher.cpp +++ b/GPU_version/vio/src/matcher.cpp @@ -161,20 +161,20 @@ bool Matcher::findMatchDirect( Vector2d px_scaled(px_cur/(1<type == Feature::EDGELET) - //{ - // Vector2d dir_cur(A_cur_ref_*ref_ftr_->grad); - // dir_cur.normalize(); - // success = feature_alignment::align1D( - // cur_frame.img_pyr_[search_level_], dir_cur.cast(), - // patch_with_border_, patch_, options_.align_max_iter, px_scaled, h_inv_); - //} - //else - //{ + if(ref_ftr_->type == Feature::EDGELET) + { + Vector2d dir_cur(A_cur_ref_*ref_ftr_->grad); + dir_cur.normalize(); + success = feature_alignment::align1D( + cur_frame.img_pyr_[search_level_], dir_cur.cast(), + patch_with_border_, patch_, options_.align_max_iter, px_scaled, h_inv_); + } + else + { success = feature_alignment::align2D( cur_frame.img_pyr_[search_level_], patch_with_border_, patch_, options_.align_max_iter, px_scaled); - // } + } px_cur = px_scaled * (1< Date: Wed, 14 Jul 2021 18:18:45 +0200 Subject: [PATCH 214/215] turn to ros service --- GPU_version/vio/CMakeLists.txt | 17 +- .../vio/include/gpu_svo/frame_handler_base.h | 5 - GPU_version/vio/include/gpu_svo/visualizer.h | 3 - GPU_version/vio/launch/Px30.launch | 3 + GPU_version/vio/package.xml | 2 + GPU_version/vio/src/frame_handler_base.cpp | 10 - GPU_version/vio/src/frame_handler_mono.cpp | 5 +- GPU_version/vio/src/visualizer.cpp | 3 +- GPU_version/vio/src/vo_node.cpp | 185 +++++++++--------- GPU_version/vio/srv/getOdom.srv | 9 + GPU_version/vio/srv/start.srv | 5 + GPU_version/vio/srv/stop.srv | 5 + 12 files changed, 134 insertions(+), 118 deletions(-) create mode 100644 GPU_version/vio/srv/getOdom.srv create mode 100644 GPU_version/vio/srv/start.srv create mode 100644 GPU_version/vio/srv/stop.srv diff --git a/GPU_version/vio/CMakeLists.txt b/GPU_version/vio/CMakeLists.txt index 938c850..4644e2b 100755 --- a/GPU_version/vio/CMakeLists.txt +++ b/GPU_version/vio/CMakeLists.txt @@ -31,14 +31,19 @@ FIND_PACKAGE(Boost REQUIRED COMPONENTS thread system) FIND_PACKAGE(OpenCL REQUIRED) set(GTSAM_INCLUDE_DIRS "${GTSAM_INCLUDE_DIR}") -FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules image_transport cv_bridge tf geometry_msgs) +FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules image_transport cv_bridge tf geometry_msgs message_generation) + +add_service_files(FILES + getOdom.srv + stop.srv + start.srv) + +generate_messages(DEPENDENCIES std_msgs) catkin_package( - DEPENDS Eigen OpenCV Sophus Boost - CATKIN_DEPENDS roscpp roslib image_transport cv_bridge tf geometry_msgs - INCLUDE_DIRS include + DEPENDS Eigen OpenCV Sophus Boost + CATKIN_DEPENDS roscpp roslib image_transport cv_bridge tf geometry_msgs message_runtime + INCLUDE_DIRS include ) - - # Include dirs INCLUDE_DIRECTORIES( include diff --git a/GPU_version/vio/include/gpu_svo/frame_handler_base.h b/GPU_version/vio/include/gpu_svo/frame_handler_base.h index c8d84e5..99b4195 100644 --- a/GPU_version/vio/include/gpu_svo/frame_handler_base.h +++ b/GPU_version/vio/include/gpu_svo/frame_handler_base.h @@ -18,8 +18,6 @@ #define SVO_FRAME_HANDLER_BASE_H_ #include -//#include -//#include #include #include #include @@ -90,9 +88,6 @@ protected: bool set_reset_; //!< Flag that the user can set. Will reset the system before the next iteration. bool set_start_; //!< Flag the user can set to start the system when the next image is received. Map map_; //!< Map of keyframes created by the slam system. - //vk::Timer timer_; //!< Stopwatch to measure time to process frame. - //vk::RingBuffer acc_frame_timings_; //!< Total processing time of the last 10 frames, used to give some user feedback on the performance. - //vk::RingBuffer acc_num_obs_; //!< Number of observed features of the last 10 frames, used to give some user feedback on the tracking performance. size_t num_obs_last_; //!< Number of observations in the previous frame. TrackingQuality tracking_quality_; //!< An estimate of the tracking quality based on the number of tracked features. diff --git a/GPU_version/vio/include/gpu_svo/visualizer.h b/GPU_version/vio/include/gpu_svo/visualizer.h index 819885d..307c27e 100644 --- a/GPU_version/vio/include/gpu_svo/visualizer.h +++ b/GPU_version/vio/include/gpu_svo/visualizer.h @@ -46,9 +46,6 @@ public: ros::Publisher pub_frames_; ros::Publisher pub_points_; ros::Publisher pub_pose_with_cov_; - ros::Publisher pub_info_; - tf::TransformBroadcaster br_; - SE3 T_world_from_vision_; Visualizer(); diff --git a/GPU_version/vio/launch/Px30.launch b/GPU_version/vio/launch/Px30.launch index efaecc2..b5371c6 100644 --- a/GPU_version/vio/launch/Px30.launch +++ b/GPU_version/vio/launch/Px30.launch @@ -6,6 +6,9 @@ + + + diff --git a/GPU_version/vio/package.xml b/GPU_version/vio/package.xml index 1d8d5a4..262fff1 100755 --- a/GPU_version/vio/package.xml +++ b/GPU_version/vio/package.xml @@ -21,6 +21,7 @@ cv_bridge tf geometry_msgs + message_generation roscpp @@ -29,4 +30,5 @@ cv_bridge tf geometry_msgs + message_runtime \ No newline at end of file diff --git a/GPU_version/vio/src/frame_handler_base.cpp b/GPU_version/vio/src/frame_handler_base.cpp index 3c77fca..a232ce3 100644 --- a/GPU_version/vio/src/frame_handler_base.cpp +++ b/GPU_version/vio/src/frame_handler_base.cpp @@ -70,15 +70,9 @@ int FrameHandlerBase::finishFrameProcessingCommon( const UpdateResult dropout, const size_t num_observations) { -// SVO_DEBUG_STREAM("Frame: "<("keyframes", 10); diff --git a/GPU_version/vio/src/vo_node.cpp b/GPU_version/vio/src/vo_node.cpp index dfae0ab..a7df993 100644 --- a/GPU_version/vio/src/vo_node.cpp +++ b/GPU_version/vio/src/vo_node.cpp @@ -18,10 +18,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -29,96 +29,101 @@ #include #include #include +#include +#include +#include +#if VIO_DEBUG +#include +#endif -class VoNode +class VioNode { public: svo::FrameHandlerMono* vo_; - svo::Visualizer visualizer_; - bool publish_markers_; //!< publish only the minimal amount of info (choice for embedded devices) vk::AbstractCamera* cam_; - bool quit_; - boost::thread* imu_th; - VoNode(); - ~VoNode(); + VioNode(); + ~VioNode(); void imgCb(const sensor_msgs::ImageConstPtr& msg); void imuCb(const sensor_msgs::ImuPtr& imu); void cmdCb(const geometry_msgs::TwistPtr &imu); - void imu(); + void imu_th(); + bool getOdom(vio::getOdom::Request& req, vio::getOdom::Response& res); + uint trace_id_= 0; + bool start_=false; + bool start(vio::start::Request& req, vio::start::Response& res){ + if(req.on==1){ + start_=true; + if(vo_->stage()!=svo::FrameHandlerBase::STAGE_DEFAULT_FRAME) + vo_->start(); + else + vo_->reset(); + imu_the_=new boost::thread(&VioNode::imu_th,this); + ++trace_id_; + res.ret=0; + }else{ + res.ret=100; + } + return true; + }; + + bool stop(vio::stop::Request& req, vio::stop::Response& res){ + if(req.off==1){ + start_=false; + usleep(5000); + imu_the_->join(); + res.ret=0; + }else{ + res.ret=100; + } + return true; + }; private: double* imu_; -#if VIO_DEBUG - FILE* log_= nullptr; - double imu_t_[6]={0.0,0.0,0.0,0.0,0.0,0.0}; -#endif double* cmd_; ros::Time imu_time_; + boost::thread* imu_the_= nullptr; +#if VIO_DEBUG + svo::Visualizer visualizer_; +#endif }; -VoNode::VoNode() : +VioNode::VioNode() : vo_(NULL), - publish_markers_(vk::getParam("vio/publish_markers", true)), - cam_(NULL), - quit_(false) + cam_(NULL) { - // Create Camera - imu_=(double *)calloc(static_cast(3), sizeof(double)); - cmd_=(double *)calloc(static_cast(3), sizeof(double)); - if(!vk::camera_loader::loadFromRosNs("vio", cam_)) + imu_=(double *)calloc(static_cast(3), sizeof(double)); + cmd_=(double *)calloc(static_cast(3), sizeof(double)); + if(!vk::camera_loader::loadFromRosNs("vio", cam_)) throw std::runtime_error("Camera model not correctly specified."); - // Get initial position and orientation - visualizer_.T_world_from_vision_ = Sophus::SE3( - vk::rpy2dcm(Eigen::Vector3d(vk::getParam("vio/init_rx", 0.0), - vk::getParam("vio/init_ry", 0.0), - vk::getParam("vio/init_rz", 0.0))), - Eigen::Vector3d(vk::getParam("vio/init_tx", 0.0), - vk::getParam("vio/init_ty", 0.0), - vk::getParam("vio/init_tz", 0.0))); Eigen::Matrix init; init<<1e-19,1e-19,1e-19; vo_ = new svo::FrameHandlerMono(cam_,init); usleep(500); - -#if VIO_DEBUG -log_ = fopen((std::string(getenv("HOME"))+"/imu_integration.txt").c_str(), "w+"); -#endif - vo_->start(); - imu_th=new boost::thread(&VoNode::imu,this); - } -VoNode::~VoNode() +VioNode::~VioNode() { - quit_=true; - - -#if VIO_DEBUG - fclose(log_); - delete log_; -#endif - imu_th->join(); - delete imu_th; + start_=false; + usleep(5000); + imu_the_->join(); + delete imu_the_; delete vo_; delete cam_; } -void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg) +void VioNode::imgCb(const sensor_msgs::ImageConstPtr& msg) { + if(!start_)return; try { auto start=std::chrono::steady_clock::now(); cv::Mat img=cv_bridge::toCvShare(msg, "mono8")->image; vo_->addImage(img, msg->header.stamp.toSec(),msg->header.stamp); -#if VIO_DEBUG - fprintf(log_, ",,,,,,,%s,%f,%f,%f\n",std::to_string(std::chrono::duration(std::chrono::steady_clock::now()-start).count()).c_str(),vo_->lastFrame()->T_f_w_.translation()(0), - vo_->lastFrame()->T_f_w_.translation()(1), - acos(vo_->lastFrame()->T_f_w_.getSE2().rotation_matrix()(0,0))); -#endif - } catch (cv_bridge::Exception& e) { ROS_ERROR("cv_bridge exception: %s", e.what()); } } -void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { +void VioNode::imuCb(const sensor_msgs::ImuPtr &imu) { + if(!start_)return; double imu_in[3]; if(abs(imu->linear_acceleration.x)>5.0){ return; @@ -134,62 +139,62 @@ void VoNode::imuCb(const sensor_msgs::ImuPtr &imu) { imu_in[1] = 0.5*imu_[1]+0.5*imu->linear_acceleration.y; imu_in[2] = 0.5*imu_[2]+0.5*imu->angular_velocity.z; memcpy(imu_, imu_in, static_cast(3*sizeof(double))); -#if VIO_DEBUG - if(imu_t_[5]!=0.0){ - double dt=1e-9*(imu->header.stamp.toNSec()-imu_t_[5]); - imu_t_[0]+=imu_in[0]*dt; - imu_t_[1]+=imu_t_[0]*dt; - imu_t_[2]+=imu_in[1]*dt; - imu_t_[3]+=imu_t_[2]*dt; - imu_t_[4]+=imu_in[2]*dt; - imu_t_[5]=imu->header.stamp.toNSec(); - fprintf(log_, "%f,%f,%f,%f\n",imu_t_[1],imu_t_[3],imu_t_[4],dt); - }else{ - imu_t_[0]=imu_in[0]; - imu_t_[1]=0.0; - imu_t_[2]=imu_in[1]; - imu_t_[3]=0.0; - imu_t_[4]=imu_in[2]; - imu_t_[5]=imu->header.stamp.toNSec(); - } -#endif vo_->UpdateIMU(imu_in,imu->header.stamp); imu_time_=imu->header.stamp; - visualizer_.publishMinimal(vo_->ukfPtr_, imu->header.stamp.toSec()); -} -void VoNode::cmdCb(const geometry_msgs::TwistPtr &cmd) { - double _cmd[3]={cmd->linear.x,cmd->linear.y,cmd->angular.z}; - memcpy(cmd_, _cmd, static_cast(3*sizeof(double))); #if VIO_DEBUG - fprintf(log_, ",,,,%f,%f,%f\n",_cmd[0],_cmd[1],_cmd[2]); + visualizer_.publishMinimal(vo_->ukfPtr_, imu->header.stamp.toSec()); #endif +} +void VioNode::cmdCb(const geometry_msgs::TwistPtr &cmd) { + if(!start_)return; + double _cmd[3]={cmd->linear.x,cmd->linear.y,cmd->angular.z}; + memcpy(cmd_, _cmd, static_cast(3*sizeof(double))); vo_->UpdateCmd(_cmd,imu_time_); } -void VoNode::imu(){ +void VioNode::imu_th(){ ros::NodeHandle nh; - // subscribe to cam msgs - image_transport::ImageTransport it(nh); - image_transport::Subscriber it_sub = it.subscribe(vk::getParam("vio/cam_topic", "camera/image_raw"), 1, &VoNode::imgCb, this); - // start processing callbacks - while(ros::ok() && !quit_) + ros::Subscriber imu_sub=nh.subscribe(vk::getParam("vio/imu_topic", "imu/raw"),10,&VioNode::imuCb, this); + ros::Subscriber cmd_sub=nh.subscribe(vk::getParam("vio/cmd_topic", "cmd/raw"),10,&VioNode::cmdCb, this); + while(start_) { ros::spinOnce(); + usleep(1000); } } +bool VioNode::getOdom(vio::getOdom::Request &req, vio::getOdom::Response &res) { + if(req.get==1){ + res.header.stamp = ros::Time(); + res.header.frame_id = "/world"; + res.header.seq = trace_id_; + auto odom=vo_->ukfPtr_.get_location(); + res.x=odom.second.translation()(0); + res.y=odom.second.translation()(1); + res.yaw=odom.second.pitch(); + res.cov={odom.first(0,0),odom.first(0,1),odom.first(0,2), + odom.first(1,0),odom.first(1,1),odom.first(1,2), + odom.first(2,0),odom.first(2,1),odom.first(2,2)}; + } + return true; +} int main(int argc, char **argv) { ros::init(argc, argv, "vio"); - VoNode vo_node; ros::NodeHandle nh; - ros::Subscriber imu_sub=nh.subscribe(vk::getParam("vio/imu_topic", "imu/raw"),10,&VoNode::imuCb, &vo_node); - ros::Subscriber cmd_sub=nh.subscribe(vk::getParam("vio/cmd_topic", "cmd/raw"),10,&VoNode::cmdCb, &vo_node); + VioNode vio; + ros::ServiceServer start = nh.advertiseService(vk::getParam("vio/start", "start"), + &VioNode::start, &vio); + ros::ServiceServer stop = nh.advertiseService(vk::getParam("vio/stop", "stop"), + &VioNode::stop, &vio); + ros::ServiceServer getOdom = nh.advertiseService(vk::getParam("vio/odom", "get_odom"), + &VioNode::getOdom, &vio); + image_transport::ImageTransport it(nh); + image_transport::Subscriber it_sub = it.subscribe(vk::getParam("vio/cam_topic", "camera/image_raw"), 1, &VioNode::imgCb, &vio); // start processing callbacks - while(ros::ok() && !vo_node.quit_) + while(ros::ok()) { ros::spinOnce(); - usleep(1000); } printf("SVO terminated.\n"); return 0; diff --git a/GPU_version/vio/srv/getOdom.srv b/GPU_version/vio/srv/getOdom.srv new file mode 100644 index 0000000..9f60ae7 --- /dev/null +++ b/GPU_version/vio/srv/getOdom.srv @@ -0,0 +1,9 @@ +# Odometry information will be return if get is 1 +uint8 get +--- +# Odometry information +Header header +float64 x +float64 y +float64 yaw +float64[9] cov \ No newline at end of file diff --git a/GPU_version/vio/srv/start.srv b/GPU_version/vio/srv/start.srv new file mode 100644 index 0000000..a1c27cc --- /dev/null +++ b/GPU_version/vio/srv/start.srv @@ -0,0 +1,5 @@ +# Turn ON VIO if on is 1 +uint8 on +--- +# Return 0 if VIO is ON +uint8 ret \ No newline at end of file diff --git a/GPU_version/vio/srv/stop.srv b/GPU_version/vio/srv/stop.srv new file mode 100644 index 0000000..7fa22db --- /dev/null +++ b/GPU_version/vio/srv/stop.srv @@ -0,0 +1,5 @@ +# Turn off VIO if off is 1 +uint8 off +--- +# Return 0 if VIO is off +uint8 ret \ No newline at end of file From 7a355486b31d4d90342dadf5b2af822c91c96881 Mon Sep 17 00:00:00 2001 From: gfuse Date: Thu, 15 Jul 2021 16:02:11 +0200 Subject: [PATCH 215/215] solve the bug in the stop API --- .../vio/include/gpu_svo/frame_handler_mono.h | 2 +- GPU_version/vio/launch/Px30.launch | 4 ++-- GPU_version/vio/src/depth_filter.cpp | 1 + GPU_version/vio/src/vo_node.cpp | 19 ++++++++++++++----- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/GPU_version/vio/include/gpu_svo/frame_handler_mono.h b/GPU_version/vio/include/gpu_svo/frame_handler_mono.h index c1967c3..2e3b6ed 100644 --- a/GPU_version/vio/include/gpu_svo/frame_handler_mono.h +++ b/GPU_version/vio/include/gpu_svo/frame_handler_mono.h @@ -53,7 +53,7 @@ public: const vector& initFeatureTrackCurPx() const { return klt_homography_init_->px_cur_; } /// Access the depth filter. - DepthFilter* depthFilter() const { return depth_filter_; } + DepthFilter* depthFilter() const{ return depth_filter_; } /// An external place recognition module may know where to relocalize. bool relocalizeFrameAtPose( diff --git a/GPU_version/vio/launch/Px30.launch b/GPU_version/vio/launch/Px30.launch index b5371c6..36114e8 100644 --- a/GPU_version/vio/launch/Px30.launch +++ b/GPU_version/vio/launch/Px30.launch @@ -1,6 +1,6 @@ - + @@ -8,7 +8,7 @@ - + diff --git a/GPU_version/vio/src/depth_filter.cpp b/GPU_version/vio/src/depth_filter.cpp index ba653f2..c7ebf2c 100644 --- a/GPU_version/vio/src/depth_filter.cpp +++ b/GPU_version/vio/src/depth_filter.cpp @@ -74,6 +74,7 @@ void DepthFilter::stopThread() SVO_INFO_STREAM("DepthFilter interrupt and join thread... "); seeds_updating_halt_ = true; thread_->interrupt(); + usleep(5000); thread_->join(); thread_ = NULL; } diff --git a/GPU_version/vio/src/vo_node.cpp b/GPU_version/vio/src/vo_node.cpp index a7df993..a182007 100644 --- a/GPU_version/vio/src/vo_node.cpp +++ b/GPU_version/vio/src/vo_node.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #if VIO_DEBUG #include #endif @@ -55,8 +56,11 @@ public: start_=true; if(vo_->stage()!=svo::FrameHandlerBase::STAGE_DEFAULT_FRAME) vo_->start(); - else + else{ + vo_->depthFilter()->startThread(); vo_->reset(); + } + imu_the_=new boost::thread(&VioNode::imu_th,this); ++trace_id_; res.ret=0; @@ -67,10 +71,15 @@ public: }; bool stop(vio::stop::Request& req, vio::stop::Response& res){ - if(req.off==1){ + if(req.off==1 && imu_the_!=NULL){ start_=false; - usleep(5000); - imu_the_->join(); + vo_->depthFilter()->stopThread(); + imu_the_->interrupt(); + if(imu_the_->get_id()==boost::this_thread::get_id()) + imu_the_->detach(); + else + imu_the_->join(); + imu_the_=NULL; res.ret=0; }else{ res.ret=100; @@ -155,7 +164,7 @@ void VioNode::imu_th(){ ros::NodeHandle nh; ros::Subscriber imu_sub=nh.subscribe(vk::getParam("vio/imu_topic", "imu/raw"),10,&VioNode::imuCb, this); ros::Subscriber cmd_sub=nh.subscribe(vk::getParam("vio/cmd_topic", "cmd/raw"),10,&VioNode::cmdCb, this); - while(start_) + while(start_ && !boost::this_thread::interruption_requested()) { ros::spinOnce(); usleep(1000);

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�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