Skip to content

Commit 3583216

Browse files
authored
Merge pull request #20 from hmakelin/hmakelin-autopilot-bridge
Add module to support different autopilots
2 parents c9aa7e3 + 43f5c7d commit 3583216

19 files changed

+1573
-553
lines changed

README.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,20 @@ You will need to have [NVIDIA Container Toolkit][2] for Docker installed.
2727
```bash
2828
git clone https://github.com/hmakelin/gisnav-docker.git
2929
cd gisnav-docker
30-
docker-compose build px4-sitl
30+
docker-compose build sitl
3131
```
3232

33-
> **Note** The build for the `px4-sitl` image takes a long time, especially if you are building it for the first time.
33+
> **Note** The build for the `sitl` image takes a long time.
3434
35-
Once the `px4-sitl` image has been built, run the `mapserver` and `px4-sitl` services:
35+
Once the `sitl` image has been built, run the `mapserver` and `px4-sitl` services:
3636

3737
```bash
38-
docker-compose up -d mapserver px4-sitl
38+
docker-compose up -d mapserver sitl
3939
```
4040

4141
> **Note**:
42-
> * The `mapserver` container needs to download roughly 1 GB of high-resolution aerial imagery, so it may take some
43-
> time until it starts serving the WMS endpoint.
44-
> * The `px4-sitl` container should pop up [Gazebo][4] and [QGroundControl][5] automatically once ran. The Gazebo
45-
> window may take several minutes to appear, while QGroundControl should appear in a few seconds after running the
46-
> container.
42+
> The `mapserver` container needs to download roughly 1 GB of high-resolution aerial imagery, so it may take some
43+
> time until it starts serving the WMS endpoint.
4744
4845
[4]: https://gazebosim.org/home
4946

config/test_typhoon_h480__ksql_airport.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ mock_gps_node:
1111
image_format: 'image/jpeg'
1212
request_timeout: 10
1313
misc:
14+
autopilot: 'gisnav.autopilots.px4_micrortps.PX4microRTPS'
15+
image_topic: '/camera/image_raw'
16+
camera_info_topic: '/camera/camera_info'
1417
mock_gps_selection: 1
1518
attitude_deviation_threshold: 10
1619
#max_pitch: 30

config/typhoon_h480__ksql_airport.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ mock_gps_node:
1010
image_format: 'image/jpeg'
1111
request_timeout: 10
1212
misc:
13+
autopilot: 'gisnav.autopilots.px4_micrortps.PX4microRTPS'
14+
image_topic: '/camera/image_raw'
15+
camera_info_topic: '/camera/camera_info'
1316
attitude_deviation_threshold: 10 # degrees
1417
max_pitch: 30 # 30 # Used by _should_match
1518
min_match_altitude: 50
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
mock_gps_node:
2+
ros__parameters:
3+
wms:
4+
url: 'http://localhost:80/wms'
5+
version: '1.3.0'
6+
layers: ['imagery']
7+
elevation_layers: ['osm-buildings']
8+
styles: ['']
9+
srs: 'EPSG:4326'
10+
image_format: 'image/jpeg'
11+
request_timeout: 10
12+
misc:
13+
autopilot: 'gisnav.autopilots.ardupilot_mavros.ArduPilotMAVROS'
14+
image_topic: '/camera/image_raw'
15+
camera_info_topic: '/camera/camera_info'
16+
attitude_deviation_threshold: 10 # degrees
17+
max_pitch: 50 # 30 # Make bigger with static_camera: True # Used by _should_match
18+
min_match_altitude: 50
19+
static_camera: True # Static down-facing camera (relative to vehicle body)
20+
map_update:
21+
update_delay: 1 # Keep low (e.g. 1 second) if vehicle flying fast or gimbal_projection: True
22+
gimbal_projection: False # set to False for ArduPilot (until gimbal is implemented)
23+
max_pitch: 30 # Applies if gimbal_projection: True, used by _should_update_map
24+
max_map_radius: 1000
25+
update_map_area_threshold: 0.85
26+
pose_estimator:
27+
#params_file: 'config/superglue_params.yaml' # For parsing args for matcher's static initializer method
28+
params_file: 'config/loftr_params.yaml'
29+
debug:
30+
export_position: ''
31+
export_projection: ''

docs/index.rst

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,34 @@ Welcome to GISNav's developer documentation!
55

66
This site contains the following pages:
77

8-
* `Get Started <pages/get_started.html>`_
8+
* `Get Started <pages/get_started.html>`_
99

10-
A quick demonstration of GNSS-free visual navigation with GISNav's :class:`.MockGPSNode`
10+
A quick demonstration of GNSS-free visual navigation with GISNav's :class:`.MockGPSNode`
1111

12-
* `Setup <pages/setup.html>`_
12+
* `Setup <pages/setup.html>`_
1313

14-
Instructions on how to to setup your own PX4 development and simulation environment
14+
Instructions on how to to setup your own PX4 development and simulation environment
1515

16-
* `Developer Guide <pages/developer_guide.html>`_
16+
* `Developer Guide <pages/developer_guide.html>`_
1717

18-
Instructions on how to integrate GISNav with your own project and how to extend its functionality
18+
Instructions on how to integrate GISNav with your own project and how to extend its functionality
1919

20-
* `API Documentation <pages/api_documentation.html>`_
20+
* `API Documentation <pages/api_documentation.html>`_
2121

22-
GISNav public API reference for developers
22+
GISNav public API reference for developers
2323

24-
* `Contribute <pages/contribute.html>`_
24+
* `Contribute <pages/contribute.html>`_
2525

26-
Contributions to GISNav are welcome! Please see this page for guidance.
26+
Contributions to GISNav are welcome! Please see this page for guidance.
2727

2828
.. seealso::
2929

30-
GISNav is built on ROS 2 and is designed to work with PX4 Autopilot. You may also be interested in their
30+
GISNav is built on ROS 2 and supports PX4 and ArduPilot. You may also be interested in their
3131
documentation:
3232

33-
* `ROS 2 Documentation <https://docs.ros.org/>`_
34-
* `PX4 Autopilot User Guide <https://docs.px4.io/master/en/>`_
33+
* `ROS 2 Documentation <https://docs.ros.org/>`_
34+
* `PX4 Autopilot User Guide <https://docs.px4.io/master/en/>`_
35+
* `ArduPilot Documentation <https://ardupilot.org/ardupilot/>`_
3536

3637
.. toctree::
3738
:maxdepth: 2

docs/pages/developer_guide.rst

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -62,32 +62,6 @@ The attributes in the :class:`.Position` input to the :meth:`.BaseNode.publish`
6262
For more information on the dimensions and units, please see the source code for :meth:`.Position`. The x and y
6363
coordinates (in ENU frame) are provided as a :class:`.GeoPoint`, which is a wrapper for :class:`geopandas.GeoSeries`.
6464

65-
.. _ROS 2 Topic Configuration:
66-
67-
ROS 2 Topic Configuration
68-
____________________________________________________
69-
To compute the position and attitude estimates, the :class:`.BaseNode` class automatically subscribes to the following
70-
required telemetry and video input ROS topics:
71-
72-
#. :class:`px4_msgs.VehicleGlobalPosition` messages via ``VehicleGlobalPosition_PubSubTopic``
73-
#. :class:`px4_msgs.VehicleLocalPosition` messages via ``VehicleLocalPosition_PubSubTopic``
74-
#. :class:`px4_msgs.VehicleAttitude` messages via ``VehicleAttitude_PubSubTopic``
75-
#. :class:`px4_msgs.GimbalDeviceSetAttitude` messages via ``GimbalDeviceSetAttitude_PubSubTopic``
76-
#. :class:`px4_msgs.Image` messages via ``image_raw``
77-
#. :class:`px4_msgs.CameraInfo` messages via ``camera_info``
78-
79-
.. note::
80-
In the Mock GPS Example, ``gscam`` is used to stream the UDP stream to the ``image_raw`` and ``camera_info`` ROS
81-
topics. They are not broadcast via the PX4-ROS 2 bridge.
82-
83-
You may need to add more subscribe and publish topics if you decide to implement your own node. You may need to edit
84-
the ``uorb_rtps_message_ids.yaml`` file as described in the
85-
`supported UORB messages <https://docs.px4.io/master/en/middleware/micrortps.html#supported-uorb-messages>`_ section of
86-
the PX4 User Guide.
87-
88-
.. seealso::
89-
`PX4-ROS 2 bridge <https://docs.px4.io/master/en/ros/ros2_comm.html>`_ for more information on the PX4-ROS 2 bridge
90-
9165
Modify ROS Parameters
9266
____________________________________________________
9367
ROS parameter server is used to manage the configuration of the :class:`.BaseNode` instance at runtime. An example
@@ -299,6 +273,47 @@ arguments in your ROS YAML parameter file:
299273
300274
See the provided ``loftr_params.yaml`` and ``superglue_params.yaml`` for examples on how to format the file.
301275

276+
.. _Autopilots:
277+
278+
Autopilots
279+
____________________________________________________
280+
The :py:mod:`.gisnav.autopilots` module has a :class:`.Autopilot` base class that you can extend to implement support
281+
for a custom autopilot setup. Example implementations are provided for PX4 over microRTPS bridge
282+
(:class:`.PX4microRTPS`) and ArduPilot over MAVROS (:class:`.ArduPilotMAVROS`). The autopilot adapter configured in
283+
the ``misc.autopilot`` ROS parameter and loaded when the :class:`.BaseNode` is initialized.
284+
285+
.. note::
286+
Currently when using :class:`.ArduPilotMAVROS` you need to set the ``misc.static_camera`` ROS
287+
parameter to ``True`` and the ``map_update.gimbal_projection`` ROS parameter to ``False``, because
288+
:meth:`.ArduPilotMAVROS.gimbal_attitude` and :meth:`.ArduPilotMAVROS.gimbal_set_attitude` are not implemented.
289+
See the ``config/typhoon_h480__ksql_airport_ardupilot.yaml`` file for an example.
290+
291+
.. _ROS 2 Topic Configuration:
292+
293+
ROS 2 Topic Configuration
294+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
295+
As an example, the :class:`.PX4microRTPS` adapter automatically subscribes to the following
296+
required telemetry and video input ROS topics:
297+
298+
#. :class:`px4_msgs.VehicleGlobalPosition` messages via ``VehicleGlobalPosition_PubSubTopic``
299+
#. :class:`px4_msgs.VehicleLocalPosition` messages via ``VehicleLocalPosition_PubSubTopic``
300+
#. :class:`px4_msgs.VehicleAttitude` messages via ``VehicleAttitude_PubSubTopic``
301+
#. :class:`px4_msgs.GimbalDeviceSetAttitude` messages via ``GimbalDeviceSetAttitude_PubSubTopic``
302+
#. :class:`px4_msgs.Image` messages via ``image_raw``
303+
#. :class:`px4_msgs.CameraInfo` messages via ``camera_info``
304+
305+
.. note::
306+
In the Mock GPS Example, ``gscam`` is used to stream the UDP stream to the ``image_raw`` and ``camera_info`` ROS
307+
topics. They are not broadcast via the PX4-ROS 2 bridge.
308+
309+
You may need to add more subscribe and publish topics if you decide to implement your own node. You may need to edit
310+
the ``uorb_rtps_message_ids.yaml`` file as described in the
311+
`supported UORB messages <https://docs.px4.io/master/en/middleware/micrortps.html#supported-uorb-messages>`_ section of
312+
the PX4 User Guide.
313+
314+
.. seealso::
315+
`PX4-ROS 2 bridge <https://docs.px4.io/master/en/ros/ros2_comm.html>`_ for more information on the PX4-ROS 2 bridge
316+
302317
Testing
303318
====================================================
304319
Unit & ROS 2 integration tests

docs/pages/setup.rst

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ Prerequisites
1717
CUDA versions with the ``nvidia-smi`` command line utility. If you don't have it installed, follow the `NVIDIA CUDA
1818
Installation Guide for Linux <https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html>`_.
1919

20+
.. _PX4 Autopilot:
21+
2022
PX4 Autopilot
2123
===================================================
22-
PX4 **v1.13** is the only autopilot that is currently supported by GISNav.
24+
PX4 **v1.13** is currently supported by GISNav. Earlier versions might work, but the :class:`.MockGPSNode` demo requires
25+
v1.13.
2326

2427
Follow the PX4 instructions to setup your `Ubuntu Development Environment
2528
<https://docs.px4.io/master/en/simulation/ros_interface.html>`_ with `Fast DDS
@@ -78,7 +81,7 @@ better either through the PX4 shell, through QGroundControl, or in the
7881
.. _ROS 2 Workspace:
7982

8083
ROS 2 Workspace
81-
===================================================
84+
___________________________________________________
8285
GISNav requires ROS 2 to communicate with PX4 Autopilot and is therefore structured as a ROS 2 package.
8386

8487
Follow the `PX4 instructions to setup ROS 2 and the PX4-ROS 2 bridge
@@ -99,7 +102,7 @@ manual repetition:
99102
.. _PX4-ROS 2 Bridge:
100103

101104
PX4-ROS 2 Bridge
102-
===================================================
105+
___________________________________________________
103106
The default configuration of the PX4-ROS 2 bridge is not sufficient for GISNav. The bridge must be reconfigured and
104107
the ``micrortps_agent`` re-generated.
105108

@@ -156,7 +159,7 @@ folders. You must configure the following send and receive flags for the followi
156159
script to automatically configure the above topics before building the PX4 SITL target.
157160

158161
PX4-ROS 2 Bridge Troubleshooting
159-
___________________________________________________
162+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
160163

161164
Ensure you have your new workspace sourced before moving on to next steps:
162165

@@ -194,7 +197,7 @@ before rebuilding again:
194197
want to restart ``micrortps_agent``.
195198

196199
gscam
197-
===================================================
200+
___________________________________________________
198201

199202
The ``typhoon_h480`` build target for Gazebo SITL supports UDP `video streaming
200203
<https://docs.px4.io/master/en/simulation/gazebo.html#video-streaming>`_ . Here we will use ``gscam`` to publish the
@@ -221,14 +224,41 @@ with the provided configuration files:
221224
on how to create a custom camera calibration file if you do not want to use the provided example
222225

223226
gscam Troubleshooting
224-
___________________________________________________
227+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
225228

226229
.. note::
227230
*Unverified*:
228231
When GISNav is running, it will try to exit cleanly when ``Ctrl+C`` is pressed. However, if the combination is
229232
mashed quickly in succession the clean exit may fail and leave some subscriptions hanging. In this case you may
230233
want to restart ``gscam``.
231234

235+
.. _ArduPilot:
236+
237+
ArduPilot
238+
===================================================
239+
ArduPilot is supported as an alternative to `PX4 Autopilot`_. The following tutorials should get you started with an
240+
ArduPilot SITL simulation environment:
241+
242+
* `Setting up SITL on Linux <https://ardupilot.org/dev/docs/setting-up-sitl-on-linux.html>`_
243+
* `Using Gazebo simulator with SITL <https://ardupilot.org/dev/docs/using-gazebo-simulator-with-sitl.html>`_
244+
* `Connecting with ROS <https://ardupilot.org/dev/docs/ros-connecting.html>`_
245+
246+
As of ``gisnav`` v0.61, :class:`.MockGPSNode` can be used in the ArduPilot SITL simulation included in the
247+
`gisnav-docker <https://github.com/hmakelin/gisnav-docker>`_ image. The included ``gazebo-iris`` model only has a static
248+
camera. Because the camera is not stabilized, it likely won't be reliable enough to act as a full replacement for GPS in
249+
ArduPilot's mission mode, while loitering will work. Use the following command to start the ``mock_gps_node`` with the
250+
ArduPilot bridge:
251+
252+
.. code-block:: bash
253+
254+
ros2 run gisnav mock_gps_node --mavros --ros-args --log-level info \
255+
--params-file src/gisnav/config/typhoon_h480__ksql_airport_ardupilot.yaml
256+
257+
258+
.. note::
259+
You may have to enable virtual joystick from QGroundControl settings and have it centered to maintain altitude in
260+
ArduPilot's Loiter mode in the SITL simulation.
261+
232262
.. _QGroundControl:
233263

234264
QGroundControl
@@ -392,28 +422,6 @@ Test your MapServer WMS service by opening the capabilities XML in your browser:
392422
393423
firefox "http://localhost:80/?map=/etc/mapserver/wms.map&service=WMS&request=GetCapabilities"
394424
395-
Docker commit the MapServer container with preloaded maps
396-
--------------------------------------------------------------
397-
To upload the image preloaded with maps to Docker Hub, first commit the container to an image:
398-
399-
.. code-block:: bash
400-
401-
export CONTAINER_ID=$(docker ps -q -f name=$CONTAINER_NAME)
402-
export IMAGE_NAME=gisnav-mapserver
403-
docker commit $CONTAINER_ID $IMAGE_NAME
404-
405-
Then push the image to Docker Hub:
406-
407-
.. note::
408-
Replace ``hmakelin`` with your own user account name, and ``latest`` with your own tag
409-
410-
.. code-block:: bash
411-
412-
export DOCKER_HUB_USER=hmakelin
413-
export tag=latest
414-
docker image tag $IMAGE_NAME $DOCKER_HUB_USER/$IMAGE_NAME:$tag
415-
docker image push $DOCKER_HUB_USER/$IMAGE_NAME
416-
417425
GISNav
418426
===================================================
419427

@@ -452,11 +460,19 @@ Build the GISNav package:
452460
Once GISNav is installed, you can run the included :class:`.MockGPSNode` either directly with ``ros2 run``:
453461

454462
.. code-block:: bash
463+
:caption: Run GISNav with PX4 microRTPS bridge
455464
456465
cd ~/px4_ros_com_ros2
457466
ros2 run gisnav mock_gps_node --ros-args --log-level info \
458467
--params-file src/gisnav/config/typhoon_h480__ksql_airport.yaml
459468
469+
.. code-block:: bash
470+
:caption: Run GISNav with ArduPilot MAVROS
471+
472+
cd ~/px4_ros_com_ros2
473+
ros2 run gisnav mock_gps_node --mavros --ros-args --log-level info \
474+
--params-file src/gisnav/config/typhoon_h480__ksql_airport_ardupilot.yaml
475+
460476
Or using the provided launch file:
461477

462478
.. code-block:: bash

gisnav/__main__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import cProfile
33
import pstats
44
import rclpy
5+
import sys
56

67
from ament_index_python.packages import get_package_share_directory
78

@@ -26,7 +27,8 @@ def main(args=None):
2627
mock_gps_node = None
2728
try:
2829
rclpy.init(args=args)
29-
mock_gps_node = MockGPSNode('mock_gps_node', get_package_share_directory(package_name))
30+
mock_gps_node = MockGPSNode('mock_gps_node', get_package_share_directory(package_name),
31+
px4_micrortps='--mavros' not in sys.argv)
3032
rclpy.spin(mock_gps_node)
3133
except KeyboardInterrupt as e:
3234
print(f'Keyboard interrupt received:\n{e}')
@@ -40,6 +42,7 @@ def main(args=None):
4042
finally:
4143
if mock_gps_node is not None:
4244
mock_gps_node.destroy_timers()
45+
mock_gps_node.unsubscribe_topics()
4346
mock_gps_node.terminate_pools()
4447
mock_gps_node.destroy_node()
4548
rclpy.shutdown()

gisnav/autopilots/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)