├── .github
└── workflows
│ └── dockerimage.yml
├── LICENSE
├── README.md
├── docker
├── Dockerfile.kinetic
└── Dockerfile.melodic
├── gazebo_upgrade.md
├── img
└── rviz.png
├── robosense_description
├── CHANGELOG.rst
├── CMakeLists.txt
├── launch
│ └── example.launch
├── meshes
│ └── robosense_16.dae
├── package.xml
├── rviz
│ └── example.rviz
├── urdf
│ ├── RS-16.urdf.xacro
│ └── example.urdf.xacro
└── world
│ └── example.world
├── robosense_gazebo_plugins
├── CHANGELOG.rst
├── CMakeLists.txt
├── include
│ └── robosense_gazebo_plugins
│ │ └── GazeboRosRoboSenseLaser.h
├── package.xml
└── src
│ └── GazeboRosRoboSenseLaser.cpp
└── robosense_simulator
└── robosense_simulator
├── CHANGELOG.rst
├── CMakeLists.txt
└── package.xml
/.github/workflows/dockerimage.yml:
--------------------------------------------------------------------------------
1 | name: Docker Image CI kinetic/melodic
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 |
11 | kinetic:
12 |
13 | runs-on: ubuntu-16.04
14 |
15 | steps:
16 | - uses: actions/checkout@v2
17 | - name: Build the Docker image kinetic
18 | run: docker build . --file docker/Dockerfile.kinetic --tag my-image-name:$(date +%s)
19 |
20 | melodic:
21 |
22 | runs-on: ubuntu-18.04
23 |
24 | steps:
25 | - uses: actions/checkout@v2
26 | - name: Build the Docker image melodic
27 | run: docker build . --file docker/Dockerfile.melodic --tag my-image-name:$(date +%s)
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Software License Agreement (BSD License)
2 |
3 | Copyright (c) 2020, ENSTA PARIS.
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without modification,
7 | are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice,
10 | this list of conditions and the following disclaimer.
11 | * Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 | * Neither the name of Dataspeed Inc. nor the names of its
15 | contributors may be used to endorse or promote products derived from this
16 | software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Robosense Simulator
2 | URDF description and Gazebo plugins to simulate Robosense laser scanners. Cloned and adapted from [velodyne_simulator](https://bitbucket.org/DataspeedInc/velodyne_simulator)
3 |
4 | 
5 |
6 | 
7 |
8 | # Features
9 | * URDF with colored meshes
10 | * Gazebo plugin based on [gazebo_plugins/gazebo_ros_block_laser](https://github.com/ros-simulation/gazebo_ros_pkgs/blob/kinetic-devel/gazebo_plugins/src/gazebo_ros_block_laser.cpp)
11 | * Publishes PointCloud2 with same structure (x, y, z, intensity, ring)
12 | * Simulated Gaussian noise
13 | * GPU acceleration ([with a modern Gazebo build](gazebo_upgrade.md))
14 | * Supported models:
15 | * [RS-LiDAR-16](robosense_description/urdf/RS-16.urdf.xacro)
16 | * Pull requests for other models are welcome
17 | * Experimental support for clipping low-intensity returns
18 |
19 | # Parameters
20 | * ```*origin``` URDF transform from parent link.
21 | * ```parent``` URDF parent link name. Default ```base_link```
22 | * ```name``` URDF model name. Also used as tf frame_id for PointCloud2 output. Default ```robosense```
23 | * ```topic``` PointCloud2 output topic name. Default ```/rs_points```
24 | * ```hz``` Update rate in hz. Default ```20```
25 | * ```lasers``` Number of vertical spinning lasers. Default ```RS-16: 16```
26 | * ```samples``` Number of horizontal rotating samples. Default ```RS-16: 900```
27 | * ```min_range``` Minimum range value in meters. Default ```0.9```
28 | * ```max_range``` Maximum range value in meters. Default ```130.0```
29 | * ```noise``` Gausian noise value in meters. Default ```0.008```
30 | * ```min_angle``` Minimum horizontal angle in radians. Default ```-3.14```
31 | * ```max_angle``` Maximum horizontal angle in radians. Default ```3.14```
32 | * ```gpu``` Use gpu_ray sensor instead of the standard ray sensor. Default ```false```
33 | * ```min_intensity``` The minimum intensity beneath which returns will be clipped. Can be used to remove low-intensity objects.
34 |
35 | # Known Issues
36 |
37 | # Example Gazebo Robot
38 | ```roslaunch robosense_description example.launch```
39 |
40 | # Example Gazebo Robot (with GPU)
41 | ```roslaunch robosense_description example.launch gpu:=true```
42 |
--------------------------------------------------------------------------------
/docker/Dockerfile.kinetic:
--------------------------------------------------------------------------------
1 | FROM ros:kinetic-perception
2 |
3 | #Workspace to use
4 | RUN mkdir -p root/catkin_ws/src/
5 | RUN /bin/bash -c 'cd /root/catkin_ws'
6 |
7 | #Copy code
8 | COPY . root/catkin_ws/src/robosense_simulator
9 |
10 | RUN apt-get update && apt-get upgrade -y && apt-get install -y ros-kinetic-gazebo-ros
11 |
12 | #Launch the compile
13 | RUN /bin/bash -c ' source /opt/ros/kinetic/setup.bash \
14 | && cd root/catkin_ws\
15 | && catkin_make -DCMAKE_INSTALL_PREFIX=/opt/ros/kinetic install'
16 |
--------------------------------------------------------------------------------
/docker/Dockerfile.melodic:
--------------------------------------------------------------------------------
1 | FROM ros:melodic-perception
2 |
3 | #Workspace to use
4 | RUN mkdir -p root/catkin_ws/src/
5 | RUN /bin/bash -c 'cd /root/catkin_ws'
6 |
7 | #Copy code
8 | COPY . root/catkin_ws/src/robosense_simulator
9 |
10 | RUN apt-get update && apt-get upgrade -y && apt-get install -y ros-melodic-gazebo-ros
11 |
12 | #Launch the compile
13 | RUN /bin/bash -c ' source /opt/ros/melodic/setup.bash \
14 | && cd root/catkin_ws\
15 | && catkin_make'
16 |
--------------------------------------------------------------------------------
/gazebo_upgrade.md:
--------------------------------------------------------------------------------
1 | # GPU issues
2 | The GPU problems reported in this [issue](https://bitbucket.org/osrf/gazebo/issues/946/) have been solved with this [pull request](https://bitbucket.org/osrf/gazebo/pull-requests/2955/) for the ```gazebo7``` branch. The Gazebo versions from the ROS apt repository (7.0.0 for Kinetic, 9.0.0 for Melodic) do not have this fix. One solution is to pull up-to-date packages from the OSRF Gazebo apt repository. Another solution is to compile from source: http://gazebosim.org/tutorials?tut=install_from_source
3 |
4 | * The GPU fix was added to ```gazebo7``` in version 7.14.0
5 | * The GPU fix was added to ```gazebo9``` in version 9.4.0
6 |
7 | # Use up-to-date packages from the OSRF Gazebo apt repository
8 | ```
9 | sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/gazebo-stable.list'
10 | sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys D2486D2DD83DB69272AFE98867170598AF249743
11 | sudo apt update
12 | sudo apt upgrade
13 | ```
14 |
15 |
--------------------------------------------------------------------------------
/img/rviz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomlogan501/robosense_simulator/a443e50a7cf2764faf8b3966326cb812f2169cf7/img/rviz.png
--------------------------------------------------------------------------------
/robosense_description/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | Changelog for package robosense_description
3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 |
5 |
--------------------------------------------------------------------------------
/robosense_description/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(robosense_description)
3 |
4 | find_package(catkin REQUIRED)
5 |
6 | catkin_package()
7 |
8 | install(DIRECTORY launch meshes rviz urdf world
9 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
10 | )
11 |
--------------------------------------------------------------------------------
/robosense_description/launch/example.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/robosense_description/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | robosense_description
4 | 1.0.0
5 |
6 | URDF and meshes describing Robosense laser scanners.
7 |
8 |
9 | BSD
10 | Thomas SIMON
11 | Thomas SIMON
12 | http://wiki.ros.org/robosense_description
13 |
15 |
16 | catkin
17 |
18 | urdf
19 | xacro
20 |
21 |
22 |
--------------------------------------------------------------------------------
/robosense_description/rviz/example.rviz:
--------------------------------------------------------------------------------
1 | Panels:
2 | - Class: rviz/Displays
3 | Help Height: 78
4 | Name: Displays
5 | Property Tree Widget:
6 | Expanded:
7 | - /Global Options1
8 | - /Status1
9 | Splitter Ratio: 0.5
10 | Tree Height: 719
11 | - Class: rviz/Selection
12 | Name: Selection
13 | - Class: rviz/Tool Properties
14 | Expanded:
15 | - /2D Pose Estimate1
16 | - /2D Nav Goal1
17 | - /Publish Point1
18 | Name: Tool Properties
19 | Splitter Ratio: 0.5886790156364441
20 | - Class: rviz/Views
21 | Expanded:
22 | - /Current View1
23 | Name: Views
24 | Splitter Ratio: 0.5
25 | - Class: rviz/Time
26 | Experimental: false
27 | Name: Time
28 | SyncMode: 0
29 | SyncSource: PointCloud2
30 | Preferences:
31 | PromptSaveOnExit: true
32 | Toolbars:
33 | toolButtonStyle: 2
34 | Visualization Manager:
35 | Class: ""
36 | Displays:
37 | - Alpha: 0.5
38 | Cell Size: 1
39 | Class: rviz/Grid
40 | Color: 160; 160; 164
41 | Enabled: true
42 | Line Style:
43 | Line Width: 0.029999999329447746
44 | Value: Lines
45 | Name: Grid
46 | Normal Cell Count: 0
47 | Offset:
48 | X: 0
49 | Y: 0
50 | Z: 0
51 | Plane: XY
52 | Plane Cell Count: 10
53 | Reference Frame:
54 | Value: true
55 | - Alpha: 1
56 | Autocompute Intensity Bounds: true
57 | Autocompute Value Bounds:
58 | Max Value: 10
59 | Min Value: -10
60 | Value: true
61 | Axis: Z
62 | Channel Name: intensity
63 | Class: rviz/PointCloud2
64 | Color: 255; 255; 255
65 | Color Transformer: Intensity
66 | Decay Time: 0
67 | Enabled: true
68 | Invert Rainbow: false
69 | Max Color: 255; 255; 255
70 | Max Intensity: 0
71 | Min Color: 0; 0; 0
72 | Min Intensity: 0
73 | Name: PointCloud2
74 | Position Transformer: XYZ
75 | Queue Size: 10
76 | Selectable: true
77 | Size (Pixels): 3
78 | Size (m): 0.009999999776482582
79 | Style: Flat Squares
80 | Topic: /rs_points
81 | Unreliable: false
82 | Use Fixed Frame: true
83 | Use rainbow: true
84 | Value: true
85 | - Class: rviz/TF
86 | Enabled: true
87 | Frame Timeout: 15
88 | Frames:
89 | All Enabled: true
90 | base_footprint:
91 | Value: true
92 | base_link:
93 | Value: true
94 | robosense:
95 | Value: true
96 | robosense_base_link:
97 | Value: true
98 | Marker Scale: 1
99 | Name: TF
100 | Show Arrows: true
101 | Show Axes: true
102 | Show Names: true
103 | Tree:
104 | base_footprint:
105 | base_link:
106 | robosense_base_link:
107 | robosense:
108 | {}
109 | Update Interval: 0
110 | Value: true
111 | - Alpha: 1
112 | Class: rviz/RobotModel
113 | Collision Enabled: false
114 | Enabled: true
115 | Links:
116 | All Links Enabled: true
117 | Expand Joint Details: false
118 | Expand Link Details: false
119 | Expand Tree: false
120 | Link Tree Style: Links in Alphabetic Order
121 | base_footprint:
122 | Alpha: 1
123 | Show Axes: false
124 | Show Trail: false
125 | base_link:
126 | Alpha: 1
127 | Show Axes: false
128 | Show Trail: false
129 | Value: true
130 | robosense:
131 | Alpha: 1
132 | Show Axes: false
133 | Show Trail: false
134 | robosense_base_link:
135 | Alpha: 1
136 | Show Axes: false
137 | Show Trail: false
138 | Value: true
139 | Name: RobotModel
140 | Robot Description: robot_description
141 | TF Prefix: ""
142 | Update Interval: 0
143 | Value: true
144 | Visual Enabled: true
145 | Enabled: true
146 | Global Options:
147 | Background Color: 48; 48; 48
148 | Default Light: true
149 | Fixed Frame: base_footprint
150 | Frame Rate: 30
151 | Name: root
152 | Tools:
153 | - Class: rviz/Interact
154 | Hide Inactive Objects: true
155 | - Class: rviz/MoveCamera
156 | - Class: rviz/Select
157 | - Class: rviz/FocusCamera
158 | - Class: rviz/Measure
159 | - Class: rviz/SetInitialPose
160 | Theta std deviation: 0.2617993950843811
161 | Topic: /initialpose
162 | X std deviation: 0.5
163 | Y std deviation: 0.5
164 | - Class: rviz/SetGoal
165 | Topic: /move_base_simple/goal
166 | - Class: rviz/PublishPoint
167 | Single click: true
168 | Topic: /clicked_point
169 | Value: true
170 | Views:
171 | Current:
172 | Class: rviz/Orbit
173 | Distance: 5.06912899017334
174 | Enable Stereo Rendering:
175 | Stereo Eye Separation: 0.05999999865889549
176 | Stereo Focal Distance: 1
177 | Swap Stereo Eyes: false
178 | Value: false
179 | Focal Point:
180 | X: 0
181 | Y: 0
182 | Z: 0
183 | Focal Shape Fixed Size: true
184 | Focal Shape Size: 0.05000000074505806
185 | Invert Z Axis: false
186 | Name: Current View
187 | Near Clip Distance: 0.009999999776482582
188 | Pitch: 0.570398211479187
189 | Target Frame:
190 | Value: Orbit (rviz)
191 | Yaw: 0.6853981018066406
192 | Saved: ~
193 | Window Geometry:
194 | Displays:
195 | collapsed: false
196 | Height: 1016
197 | Hide Left Dock: false
198 | Hide Right Dock: true
199 | QMainWindow State: 000000ff00000000fd0000000400000000000001560000035afc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000035a000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000035afc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d0000035a000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073a0000003efc0100000002fb0000000800540069006d006501000000000000073a000002eb00fffffffb0000000800540069006d00650100000000000004500000000000000000000005de0000035a00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
200 | Selection:
201 | collapsed: false
202 | Time:
203 | collapsed: false
204 | Tool Properties:
205 | collapsed: false
206 | Views:
207 | collapsed: true
208 | Width: 1850
209 | X: 70
210 | Y: 27
211 |
--------------------------------------------------------------------------------
/robosense_description/urdf/RS-16.urdf.xacro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | 0 0 0 0 0 0
53 | false
54 | ${hz}
55 |
56 |
57 |
58 | ${samples}
59 | 1
60 | ${min_angle}
61 | ${max_angle}
62 |
63 |
64 | ${lasers}
65 | 1
66 | -${15.0*M_PI/180.0}
67 | ${15.0*M_PI/180.0}
68 |
69 |
70 |
71 | ${collision_range}
72 | ${max_range}
73 | 0.001
74 |
75 |
76 | gaussian
77 | 0.0
78 | 0.0
79 |
80 |
81 |
82 | ${topic}
83 | ${name}
84 | ${min_range}
85 | ${max_range}
86 | ${noise}
87 |
88 |
89 |
90 |
91 |
92 | 0 0 0 0 0 0
93 | false
94 | ${hz}
95 |
96 |
97 |
98 | ${samples}
99 | 1
100 | ${min_angle}
101 | ${max_angle}
102 |
103 |
104 | ${lasers}
105 | 1
106 | -${15.0*M_PI/180.0}
107 | ${15.0*M_PI/180.0}
108 |
109 |
110 |
111 | ${collision_range}
112 | ${max_range+1}
113 | 0.001
114 |
115 |
116 | gaussian
117 | 0.0
118 | 0.0
119 |
120 |
121 |
122 | ${topic}
123 | ${name}
124 | ${min_range}
125 | ${max_range}
126 | ${noise}
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/robosense_description/urdf/example.urdf.xacro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/robosense_description/world/example.world:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | model://sun
7 |
8 |
9 |
10 | model://ground_plane
11 |
12 |
13 |
14 | -1.5 2.5 0.5 0 -0 0
15 |
16 |
17 | 1
18 |
19 | 0.166667
20 | 0
21 | 0
22 | 0.166667
23 | 0
24 | 0.166667
25 |
26 |
27 |
28 |
29 |
30 | 1 1 1
31 |
32 |
33 | 10
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1 1 1
51 |
52 |
53 |
54 |
58 |
59 |
60 | 0
61 | 0
62 | 1
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/robosense_gazebo_plugins/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | Changelog for package robosense_gazebo_plugins
3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 |
--------------------------------------------------------------------------------
/robosense_gazebo_plugins/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(robosense_gazebo_plugins)
3 |
4 | find_package(catkin REQUIRED COMPONENTS
5 | roscpp
6 | sensor_msgs
7 | tf
8 | gazebo_ros
9 | )
10 | find_package(gazebo REQUIRED)
11 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GAZEBO_CXX_FLAGS}")
12 |
13 | catkin_package(
14 | INCLUDE_DIRS include ${GAZEBO_INCLUDE_DIRS}
15 | LIBRARIES gazebo_ros_robosense_laser gazebo_ros_robosense_gpu_laser
16 | CATKIN_DEPENDS roscpp sensor_msgs gazebo_ros
17 | )
18 |
19 | include_directories(
20 | include
21 | ${catkin_INCLUDE_DIRS}
22 | ${GAZEBO_INCLUDE_DIRS}
23 | )
24 |
25 | link_directories(
26 | ${GAZEBO_LIBRARY_DIRS}
27 | )
28 |
29 | add_library(gazebo_ros_robosense_laser src/GazeboRosRoboSenseLaser.cpp)
30 | target_link_libraries(gazebo_ros_robosense_laser
31 | ${catkin_LIBRARIES}
32 | ${GAZEBO_LIBRARIES}
33 | RayPlugin
34 | )
35 |
36 | add_library(gazebo_ros_robosense_gpu_laser src/GazeboRosRoboSenseLaser.cpp)
37 | target_link_libraries(gazebo_ros_robosense_gpu_laser
38 | ${catkin_LIBRARIES}
39 | ${GAZEBO_LIBRARIES}
40 | GpuRayPlugin
41 | )
42 | target_compile_definitions(gazebo_ros_robosense_gpu_laser PRIVATE GAZEBO_GPU_RAY=1)
43 |
44 | install(TARGETS gazebo_ros_robosense_laser gazebo_ros_robosense_gpu_laser
45 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
46 | )
47 |
48 | install(DIRECTORY include/${PROJECT_NAME}/
49 | DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
50 | )
51 |
--------------------------------------------------------------------------------
/robosense_gazebo_plugins/include/robosense_gazebo_plugins/GazeboRosRoboSenseLaser.h:
--------------------------------------------------------------------------------
1 | /*********************************************************************
2 | * Software License Agreement (BSD License)
3 | *
4 | * Copyright (c) 2019-2020, ENSTA.
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions
9 | * are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright
12 | * notice, this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above
14 | * copyright notice, this list of conditions and the following
15 | * disclaimer in the documentation and/or other materials provided
16 | * with the distribution.
17 | * * Neither the name of Dataspeed Inc. nor the names of its
18 | * contributors may be used to endorse or promote products derived
19 | * from this software without specific prior written permission.
20 | *
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 | * POSSIBILITY OF SUCH DAMAGE.
33 | *********************************************************************/
34 |
35 | #ifndef GAZEBO_ROS_ROBOSENSE_LASER_H_
36 | #define GAZEBO_ROS_ROBOSENSE_LASER_H_
37 |
38 | // Use the same source code for CPU and GPU plugins
39 | #ifndef GAZEBO_GPU_RAY
40 | #define GAZEBO_GPU_RAY 0
41 | #endif
42 |
43 | // Custom Callback Queue
44 | #include
45 | #include
46 | #include
47 |
48 | #include
49 | #include
50 | #include
51 | #include
52 |
53 | #include
54 | #include
55 | #include
56 | #if GAZEBO_GPU_RAY
57 | #include
58 | #else
59 | #include
60 | #endif
61 |
62 | #include
63 | #include
64 | #include
65 | #include
66 | #include
67 |
68 | #if GAZEBO_GPU_RAY
69 | #define GazeboRosRobosenseGpuLaser GazeboRosRobosenseGpuLaser
70 | #define RayPlugin GpuRayPlugin
71 | #define RaySensorPtr GpuRaySensorPtr
72 | #endif
73 |
74 | namespace gazebo
75 | {
76 |
77 | class GazeboRosRobosenseLaser : public RayPlugin
78 | {
79 | /// \brief Constructor
80 | /// \param parent The parent entity, must be a Model or a Sensor
81 | public: GazeboRosRobosenseLaser();
82 |
83 | /// \brief Destructor
84 | public: ~GazeboRosRobosenseLaser();
85 |
86 | /// \brief Load the plugin
87 | /// \param take in SDF root element
88 | public: void Load(sensors::SensorPtr _parent, sdf::ElementPtr _sdf);
89 |
90 | /// \brief Subscribe on-demand
91 | private: void ConnectCb();
92 |
93 | /// \brief The parent ray sensor
94 | private: sensors::RaySensorPtr parent_ray_sensor_;
95 |
96 | /// \brief Pointer to ROS node
97 | private: ros::NodeHandle* nh_;
98 |
99 | /// \brief ROS publisher
100 | private: ros::Publisher pub_;
101 |
102 | /// \brief topic name
103 | private: std::string topic_name_;
104 |
105 | /// \brief frame transform name, should match link name
106 | private: std::string frame_name_;
107 |
108 | /// \brief the intensity beneath which points will be filtered
109 | private: double min_intensity_;
110 |
111 | /// \brief Minimum range to publish
112 | private: double min_range_;
113 |
114 | /// \brief Maximum range to publish
115 | private: double max_range_;
116 |
117 | /// \brief Gaussian noise
118 | private: double gaussian_noise_;
119 |
120 | /// \brief Gaussian noise generator
121 | private: static double gaussianKernel(double mu, double sigma)
122 | {
123 | // using Box-Muller transform to generate two independent standard normally distributed normal variables
124 | // see wikipedia
125 | double U = (double)rand() / (double)RAND_MAX; // normalized uniform random variable
126 | double V = (double)rand() / (double)RAND_MAX; // normalized uniform random variable
127 | return sigma * (sqrt(-2.0 * ::log(U)) * cos(2.0 * M_PI * V)) + mu;
128 | }
129 |
130 | /// \brief A mutex to lock access
131 | private: boost::mutex lock_;
132 |
133 | /// \brief For setting ROS name space
134 | private: std::string robot_namespace_;
135 |
136 | // Custom Callback Queue
137 | private: ros::CallbackQueue laser_queue_;
138 | private: void laserQueueThread();
139 | private: boost::thread callback_laser_queue_thread_;
140 |
141 | // Subscribe to gazebo laserscan
142 | private: gazebo::transport::NodePtr gazebo_node_;
143 | private: gazebo::transport::SubscriberPtr sub_;
144 | private: void OnScan(const ConstLaserScanStampedPtr &_msg);
145 |
146 | };
147 |
148 | } // namespace gazebo
149 |
150 | #endif /* GAZEBO_ROS_ROBOSENSE_LASER_H_ */
151 |
152 |
--------------------------------------------------------------------------------
/robosense_gazebo_plugins/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | robosense_gazebo_plugins
4 | 1.0.0
5 |
6 | Gazebo plugin to provide simulated data from Robosense laser scanners.
7 |
8 |
9 | BSD
10 | Thomas SIMON
11 | Thomas SIMON
12 |
13 | catkin
14 |
15 | roscpp
16 | sensor_msgs
17 | tf
18 | gazebo_ros
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/robosense_gazebo_plugins/src/GazeboRosRoboSenseLaser.cpp:
--------------------------------------------------------------------------------
1 | /*********************************************************************
2 | * Software License Agreement (BSD License)
3 | *
4 | * Copyright (c) 2019-2020, ENSTA.
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions
9 | * are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright
12 | * notice, this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above
14 | * copyright notice, this list of conditions and the following
15 | * disclaimer in the documentation and/or other materials provided
16 | * with the distribution.
17 | * * Neither the name of Dataspeed Inc. nor the names of its
18 | * contributors may be used to endorse or promote products derived
19 | * from this software without specific prior written permission.
20 | *
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 | * POSSIBILITY OF SUCH DAMAGE.
33 | *********************************************************************/
34 |
35 | #include
36 |
37 | #include
38 | #include
39 |
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #if GAZEBO_GPU_RAY
46 | #include
47 | #else
48 | #include
49 | #endif
50 | #include
51 | #include
52 |
53 | #include
54 |
55 | #include
56 |
57 | #if GAZEBO_GPU_RAY
58 | #define RaySensor GpuRaySensor
59 | #define STR_Gpu "Gpu"
60 | #define STR_GPU_ "GPU "
61 | #else
62 | #define STR_Gpu ""
63 | #define STR_GPU_ ""
64 | #endif
65 |
66 | namespace gazebo
67 | {
68 | // Register this plugin with the simulator
69 | GZ_REGISTER_SENSOR_PLUGIN(GazeboRosRobosenseLaser)
70 |
71 | ////////////////////////////////////////////////////////////////////////////////
72 | // Constructor
73 | GazeboRosRobosenseLaser::GazeboRosRobosenseLaser() : nh_(NULL), gaussian_noise_(0), min_range_(0), max_range_(0)
74 | {
75 | }
76 |
77 | ////////////////////////////////////////////////////////////////////////////////
78 | // Destructor
79 | GazeboRosRobosenseLaser::~GazeboRosRobosenseLaser()
80 | {
81 | ////////////////////////////////////////////////////////////////////////////////
82 | // Finalize the controller / Custom Callback Queue
83 | laser_queue_.clear();
84 | laser_queue_.disable();
85 | if (nh_) {
86 | nh_->shutdown();
87 | delete nh_;
88 | nh_ = NULL;
89 | }
90 | callback_laser_queue_thread_.join();
91 | }
92 |
93 | ////////////////////////////////////////////////////////////////////////////////
94 | // Load the controller
95 | void GazeboRosRobosenseLaser::Load(sensors::SensorPtr _parent, sdf::ElementPtr _sdf)
96 | {
97 | // Load plugin
98 | RayPlugin::Load(_parent, _sdf);
99 |
100 | // Initialize Gazebo node
101 | gazebo_node_ = gazebo::transport::NodePtr(new gazebo::transport::Node());
102 | gazebo_node_->Init();
103 |
104 | // Get the parent ray sensor
105 | #if GAZEBO_MAJOR_VERSION >= 7
106 | parent_ray_sensor_ = std::dynamic_pointer_cast(_parent);
107 | #else
108 | parent_ray_sensor_ = boost::dynamic_pointer_cast(_parent);
109 | #endif
110 | if (!parent_ray_sensor_) {
111 | gzthrow("GazeboRosRobosense" << STR_Gpu << "Laser controller requires a " << STR_Gpu << "Ray Sensor as its parent");
112 | }
113 |
114 | robot_namespace_ = "/";
115 | if (_sdf->HasElement("robotNamespace")) {
116 | robot_namespace_ = _sdf->GetElement("robotNamespace")->Get();
117 | }
118 |
119 | if (!_sdf->HasElement("frameName")) {
120 | ROS_INFO("Robosense laser plugin missing , defaults to /world");
121 | frame_name_ = "/world";
122 | } else {
123 | frame_name_ = _sdf->GetElement("frameName")->Get();
124 | }
125 |
126 | if (!_sdf->HasElement("min_range")) {
127 | ROS_INFO("Robosense laser plugin missing , defaults to 0");
128 | min_range_ = 0;
129 | } else {
130 | min_range_ = _sdf->GetElement("min_range")->Get();
131 | }
132 |
133 | if (!_sdf->HasElement("max_range")) {
134 | ROS_INFO("Robosense laser plugin missing , defaults to infinity");
135 | max_range_ = INFINITY;
136 | } else {
137 | max_range_ = _sdf->GetElement("max_range")->Get();
138 | }
139 |
140 | min_intensity_ = std::numeric_limits::lowest();
141 | if (!_sdf->HasElement("min_intensity")) {
142 | ROS_INFO("Robosense laser plugin missing , defaults to no clipping");
143 | } else {
144 | min_intensity_ = _sdf->GetElement("min_intensity")->Get();
145 | }
146 |
147 | if (!_sdf->HasElement("topicName")) {
148 | ROS_INFO("Robosense laser plugin missing , defaults to /points");
149 | topic_name_ = "/points";
150 | } else {
151 | topic_name_ = _sdf->GetElement("topicName")->Get();
152 | }
153 |
154 | if (!_sdf->HasElement("gaussianNoise")) {
155 | ROS_INFO("Robosense laser plugin missing , defaults to 0.0");
156 | gaussian_noise_ = 0;
157 | } else {
158 | gaussian_noise_ = _sdf->GetElement("gaussianNoise")->Get();
159 | }
160 |
161 | // Make sure the ROS node for Gazebo has already been initialized
162 | if (!ros::isInitialized()) {
163 | ROS_FATAL_STREAM("A ROS node for Gazebo has not been initialized, unable to load plugin. "
164 | << "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
165 | return;
166 | }
167 |
168 | // Create node handle
169 | nh_ = new ros::NodeHandle(robot_namespace_);
170 |
171 | // Resolve tf prefix
172 | std::string prefix;
173 | nh_->getParam(std::string("tf_prefix"), prefix);
174 | if (robot_namespace_ != "/") {
175 | prefix = robot_namespace_;
176 | }
177 | boost::trim_right_if(prefix, boost::is_any_of("/"));
178 | frame_name_ = tf::resolve(prefix, frame_name_);
179 |
180 | // Advertise publisher with a custom callback queue
181 | if (topic_name_ != "") {
182 | ros::AdvertiseOptions ao = ros::AdvertiseOptions::create(
183 | topic_name_, 1,
184 | boost::bind(&GazeboRosRobosenseLaser::ConnectCb, this),
185 | boost::bind(&GazeboRosRobosenseLaser::ConnectCb, this),
186 | ros::VoidPtr(), &laser_queue_);
187 | pub_ = nh_->advertise(ao);
188 | }
189 |
190 | // Sensor generation off by default
191 | parent_ray_sensor_->SetActive(false);
192 |
193 | // Start custom queue for laser
194 | callback_laser_queue_thread_ = boost::thread( boost::bind( &GazeboRosRobosenseLaser::laserQueueThread,this ) );
195 |
196 | #if GAZEBO_MAJOR_VERSION >= 7
197 | ROS_INFO("Robosense %slaser plugin ready, %i lasers", STR_GPU_, parent_ray_sensor_->VerticalRangeCount());
198 | #else
199 | ROS_INFO("Robosense %slaser plugin ready, %i lasers", STR_GPU_, parent_ray_sensor_->GetVerticalRangeCount());
200 | #endif
201 | }
202 |
203 | ////////////////////////////////////////////////////////////////////////////////
204 | // Subscribe on-demand
205 | void GazeboRosRobosenseLaser::ConnectCb()
206 | {
207 | boost::lock_guard lock(lock_);
208 | if (pub_.getNumSubscribers()) {
209 | if (!sub_) {
210 | #if GAZEBO_MAJOR_VERSION >= 7
211 | sub_ = gazebo_node_->Subscribe(this->parent_ray_sensor_->Topic(), &GazeboRosRobosenseLaser::OnScan, this);
212 | #else
213 | sub_ = gazebo_node_->Subscribe(this->parent_ray_sensor_->GetTopic(), &GazeboRosRobosenseLaser::OnScan, this);
214 | #endif
215 | }
216 | parent_ray_sensor_->SetActive(true);
217 | } else {
218 | #if GAZEBO_MAJOR_VERSION >= 7
219 | if (sub_) {
220 | sub_->Unsubscribe();
221 | sub_.reset();
222 | }
223 | #endif
224 | parent_ray_sensor_->SetActive(false);
225 | }
226 | }
227 |
228 | void GazeboRosRobosenseLaser::OnScan(ConstLaserScanStampedPtr& _msg)
229 | {
230 | #if GAZEBO_MAJOR_VERSION >= 7
231 | const ignition::math::Angle maxAngle = parent_ray_sensor_->AngleMax();
232 | const ignition::math::Angle minAngle = parent_ray_sensor_->AngleMin();
233 |
234 | const double maxRange = parent_ray_sensor_->RangeMax();
235 | const double minRange = parent_ray_sensor_->RangeMin();
236 |
237 | const int rayCount = parent_ray_sensor_->RayCount();
238 | const int rangeCount = parent_ray_sensor_->RangeCount();
239 |
240 | const int verticalRayCount = parent_ray_sensor_->VerticalRayCount();
241 | const int verticalRangeCount = parent_ray_sensor_->VerticalRangeCount();
242 |
243 | const ignition::math::Angle verticalMaxAngle = parent_ray_sensor_->VerticalAngleMax();
244 | const ignition::math::Angle verticalMinAngle = parent_ray_sensor_->VerticalAngleMin();
245 | #else
246 | math::Angle maxAngle = parent_ray_sensor_->GetAngleMax();
247 | math::Angle minAngle = parent_ray_sensor_->GetAngleMin();
248 |
249 | const double maxRange = parent_ray_sensor_->GetRangeMax();
250 | const double minRange = parent_ray_sensor_->GetRangeMin();
251 |
252 | const int rayCount = parent_ray_sensor_->GetRayCount();
253 | const int rangeCount = parent_ray_sensor_->GetRangeCount();
254 |
255 | const int verticalRayCount = parent_ray_sensor_->GetVerticalRayCount();
256 | const int verticalRangeCount = parent_ray_sensor_->GetVerticalRangeCount();
257 |
258 | const math::Angle verticalMaxAngle = parent_ray_sensor_->GetVerticalAngleMax();
259 | const math::Angle verticalMinAngle = parent_ray_sensor_->GetVerticalAngleMin();
260 | #endif
261 |
262 | const double yDiff = maxAngle.Radian() - minAngle.Radian();
263 | const double pDiff = verticalMaxAngle.Radian() - verticalMinAngle.Radian();
264 |
265 | const double MIN_RANGE = std::max(min_range_, minRange);
266 | const double MAX_RANGE = std::min(max_range_, maxRange);
267 | const double MIN_INTENSITY = min_intensity_;
268 |
269 | // Populate message fields
270 | const uint32_t POINT_STEP = 32;
271 | sensor_msgs::PointCloud2 msg;
272 | msg.header.frame_id = frame_name_;
273 | msg.header.stamp = ros::Time(_msg->time().sec(), _msg->time().nsec());
274 | msg.fields.resize(5);
275 | msg.fields[0].name = "x";
276 | msg.fields[0].offset = 0;
277 | msg.fields[0].datatype = sensor_msgs::PointField::FLOAT32;
278 | msg.fields[0].count = 1;
279 | msg.fields[1].name = "y";
280 | msg.fields[1].offset = 4;
281 | msg.fields[1].datatype = sensor_msgs::PointField::FLOAT32;
282 | msg.fields[1].count = 1;
283 | msg.fields[2].name = "z";
284 | msg.fields[2].offset = 8;
285 | msg.fields[2].datatype = sensor_msgs::PointField::FLOAT32;
286 | msg.fields[2].count = 1;
287 | msg.fields[3].name = "intensity";
288 | msg.fields[3].offset = 16;
289 | msg.fields[3].datatype = sensor_msgs::PointField::FLOAT32;
290 | msg.fields[3].count = 1;
291 | msg.fields[4].name = "ring";
292 | msg.fields[4].offset = 20;
293 | msg.fields[4].datatype = sensor_msgs::PointField::UINT16;
294 | msg.fields[4].count = 1;
295 | msg.data.resize(verticalRangeCount * rangeCount * POINT_STEP);
296 |
297 | int i, j;
298 | uint8_t *ptr = msg.data.data();
299 | for (i = 0; i < rangeCount; i++) {
300 | for (j = 0; j < verticalRangeCount; j++) {
301 |
302 | // Range
303 | double r = _msg->scan().ranges(i + j * rangeCount);
304 | // Intensity
305 | double intensity = _msg->scan().intensities(i + j * rangeCount);
306 | // Ignore points that lay outside range bands or optionally, beneath a
307 | // minimum intensity level.
308 | if ((MIN_RANGE >= r) || (r >= MAX_RANGE) || (intensity < MIN_INTENSITY) ) {
309 | continue;
310 | }
311 |
312 | // Noise
313 | if (gaussian_noise_ != 0.0) {
314 | r += gaussianKernel(0,gaussian_noise_);
315 | }
316 |
317 | // Get angles of ray to get xyz for point
318 | double yAngle;
319 | double pAngle;
320 |
321 | if (rangeCount > 1) {
322 | yAngle = i * yDiff / (rangeCount -1) + minAngle.Radian();
323 | } else {
324 | yAngle = minAngle.Radian();
325 | }
326 |
327 | if (verticalRayCount > 1) {
328 | pAngle = j * pDiff / (verticalRangeCount -1) + verticalMinAngle.Radian();
329 | } else {
330 | pAngle = verticalMinAngle.Radian();
331 | }
332 |
333 | // pAngle is rotated by yAngle:
334 | if ((MIN_RANGE < r) && (r < MAX_RANGE)) {
335 | *((float*)(ptr + 0)) = r * cos(pAngle) * cos(yAngle);
336 | *((float*)(ptr + 4)) = r * cos(pAngle) * sin(yAngle);
337 | #if GAZEBO_MAJOR_VERSION > 2
338 | *((float*)(ptr + 8)) = r * sin(pAngle);
339 | #else
340 | *((float*)(ptr + 8)) = -r * sin(pAngle);
341 | #endif
342 | *((float*)(ptr + 16)) = intensity;
343 | #if GAZEBO_MAJOR_VERSION > 2
344 | *((uint16_t*)(ptr + 20)) = j; // ring
345 | #else
346 | *((uint16_t*)(ptr + 20)) = verticalRangeCount - 1 - j; // ring
347 | #endif
348 | ptr += POINT_STEP;
349 | }
350 | }
351 | }
352 |
353 | // Populate message with number of valid points
354 | msg.point_step = POINT_STEP;
355 | msg.row_step = ptr - msg.data.data();
356 | msg.height = 1;
357 | msg.width = msg.row_step / POINT_STEP;
358 | msg.is_bigendian = false;
359 | msg.is_dense = true;
360 | msg.data.resize(msg.row_step); // Shrink to actual size
361 |
362 | // Publish output
363 | pub_.publish(msg);
364 | }
365 |
366 | // Custom Callback Queue
367 | ////////////////////////////////////////////////////////////////////////////////
368 | // Custom callback queue thread
369 | void GazeboRosRobosenseLaser::laserQueueThread()
370 | {
371 | while (nh_->ok()) {
372 | laser_queue_.callAvailable(ros::WallDuration(0.01));
373 | }
374 | }
375 |
376 | } // namespace gazebo
377 |
378 |
--------------------------------------------------------------------------------
/robosense_simulator/robosense_simulator/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | Changelog for package robosense_simulator
3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 |
5 |
--------------------------------------------------------------------------------
/robosense_simulator/robosense_simulator/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(robosense_simulator)
3 | find_package(catkin REQUIRED)
4 | catkin_metapackage()
5 |
--------------------------------------------------------------------------------
/robosense_simulator/robosense_simulator/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | robosense_simulator
4 | 1.0.0
5 |
6 | Metapackage allowing easy installation of Robosense simulation components.
7 |
8 |
9 | BSD
10 | Thomas SIMON
11 | Thomas SIMON
12 | http://wiki.ros.org/robosense_simulator
13 |
15 |
16 | catkin
17 |
18 | robosense_description
19 | robosense_gazebo_plugins
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------