├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── config
├── moving_base.txt
├── rover.txt
└── zed_f9p.yaml
├── launch
└── ublox.launch
├── package.xml
├── resources
└── gnss_hardware_setup.drawio
└── src
└── ublox2nmea.cc
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.16.3)
2 | project(ublox_utils)
3 |
4 | find_package(catkin
5 | REQUIRED COMPONENTS
6 | roscpp
7 | nmea_msgs
8 | ublox_msgs
9 | rtcm_msgs
10 | mavros_msgs
11 | )
12 |
13 | include_directories(include ${catkin_INCLUDE_DIRS})
14 |
15 | catkin_package()
16 |
17 | set(CMAKE_CXX_STANDARD 17)
18 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
19 | set(CMAKE_BUILD_TYPE Release)
20 |
21 | ############
22 | # Binaries #
23 | ############
24 | add_executable(ublox2nmea src/ublox2nmea.cc)
25 | target_link_libraries(ublox2nmea ${catkin_LIBRARIES})
26 |
27 | ##########
28 | # EXPORT #
29 | ##########
30 | install(TARGETS ublox2nmea
31 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
32 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
33 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
34 | )
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Rik Baehnemann, ASL, ETH Zurich, Switzerland
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ublox_utils
2 | Repository with ROS tools for the u-blox RTK receiver.
3 |
4 | ## Table of Contents
5 | 1. [Installation](#installation)
6 | 2. [Hardware Setup](#hardware-setup)
7 | 1. [Electronics](#electronics)
8 | 2. [Part List](#part-list)
9 | 3. [Firmware](#firmware)
10 | 4. [ROS Sensor Launch](#ros-sensor-launch)
11 | 1. [Single Receiver](#single-receiver)
12 | 2. [Dual Receivers](#dual-receivers)
13 | 3. [NTRIP Corrections](#ntrip-corrections)
14 | 4. [Dual Receivers with NTRIP](#dual-receivers-with-ntrip)
15 |
16 | ## Installation
17 | ```
18 | source /opt/ros/noetic/setup.bash
19 | export ROS_VERSION=`rosversion -d`
20 |
21 | sudo apt install -y python3-catkin-tools \
22 | ros-$ROS_VERSION-ublox \
23 | ros-$ROS_VERSION-ntrip-client \
24 | ros-$ROS_VERSION-nmea-msgs \
25 | ros-$ROS_VERSION-mavros-msgs \
26 | ros-$ROS_VERSION-rtcm-msgs
27 |
28 | cd ~
29 | mkdir -p catkin_ws/src
30 | cd catkin_ws
31 | catkin init
32 | cd ~/catkin_ws/src
33 | git clone git@github.com:ethz-asl/ublox_utils.git
34 | catkin build
35 | ```
36 |
37 | ## Hardware Setup
38 | This section describes the hardware setup with one or two receivers on the rover.
39 | The following considerations should be taken into account:
40 | - Optimal **sky coverage** of the antennas.
41 | - Antennas **far distanced** from other electronics to avoid interference (especially LiDAR and USB 3.0 devices).
42 | - **Omnidirectional helical antennas** preferable over patch antennas as they do not require ground plane and have a better attitude coverage (see [ZED-FP9 Moving base applications, p.8](https://content.u-blox.com/sites/default/files/ZED-F9P-MovingBase_AppNote_%28UBX-19009093%29.pdf)).
43 | - **Multi-band antennas** that support all receiver frequencies with well-defined phase center and small phase center variation (see for example [HC882 Dual-Band Helical Antenna + L-Band](https://www.tallysman.com/app/uploads/2018/03/Tallysman%C2%AE-HC882-Datasheet_March-2022.pdf)).
44 | - **Known phase center position** with respect to rover body frame (see r_BP and r_BM in Figure below).
45 | - Rover antenna **at least 20cm** distanced from moving base antenna (see [ZED-FP9 Moving base applications, p.7](https://content.u-blox.com/sites/default/files/ZED-F9P-MovingBase_AppNote_%28UBX-19009093%29.pdf)).
46 |
47 | 
48 |
49 | ### Electronics
50 | The NTRIP setup does not require a base station.
51 | Instead the corrections are provided by an NTRIP caster online.
52 | The wiring is shown in the Figure below.
53 | In case of a moving baseline setup, corrections from the moving base receiver (Receiver 1) will be sent to the rover (Receiver 2) via UART2.
54 |
55 | 
56 |
57 | ### Part List
58 | This is the part list for the standard moving baseline setup above.
59 | The prices are regular retail prices.
60 | For some, e.g., NTRIP corrections or Tallysman antennas research discounts may apply.
61 |
62 | | No. | Pc. No. | Description | Source Object | Supplier | Supplier Number | Cost per Unit | Cost Total |
63 | |:---:|:-------:|:---------------------------------------------|:----------------|:----------|:--------------------|:----------------|:----------------|
64 | | 1 | 2 | Sparkfun u-blox ZED-F9P GPS-RTK-SMA receiver | GPS-16481 | digikey | 1568-GPS-16481-ND | CHF 260.- | CHF 520.- |
65 | | 2 | 2 | Tallysman HC882 dual-band helical antenna | 33-HC882-28 | digikey | 1526-33-HC882-28-ND | CHF 250.- | CHF 500.- |
66 | | 3 | 1 | Swipos GIS/GEO NTRIP license | swipos GIS/GEO | swisstopo | swipos-GIS/GEO | CHF 2000.- p.a. | CHF 2000.- p.a. |
67 | | 4 | 2 | USB-C connector cable (300mm) | CAB-15426 | digikey | 1568-CAB-15426-ND | CHF 4.- | CHF 8.- |
68 | | 5 | 2 | Coaxial SMA to SMA (500mm) | 415-0031-MM500 | digikey | J10300-ND | CHF 16.- | CHF 32.- |
69 |
70 | ### Firmware
71 | The latest tested firmware was **1.32** on ZED-F9P receiver.
72 | To update the firmware follow the [sparkfun tutorial](https://learn.sparkfun.com/tutorials/how-to-upgrade-firmware-of-a-u-blox-gnss-receiver).
73 |
74 | When using a dual receiver setup update the configuration of the [moving base receiver](config/moving_base.txt) and [rover receiver](config/rover.txt).
75 | The configuration is elaborated in [ZED-FP9 Moving base applications, p.16](https://content.u-blox.com/sites/default/files/ZED-F9P-MovingBase_AppNote_%28UBX-19009093%29.pdf).
76 | To flash the configuration go to u-center and select `View->Generation 9 Configuration View->Advanced Configuration->Load from file...->Send config changes`
77 |
78 | **Note**: If you are only using a single rover, the default config is fine.
79 |
80 | To revert to the default config select `View->Messages view->UBX->CFG->CFG->Revert to default configuration->Send`.
81 | ## ROS Sensor Launch
82 | [ublox.launch](./launch/ublox.launch) provides the launch file to start the u-blox receivers ROS interface.
83 |
84 | ### Single Receiver
85 | The default startup with a single receiver is
86 | ```
87 | roslaunch ublox_utils ublox.launch device_position_receiver:=/dev/ttyACM0
88 | ```
89 | The relevant ROS topics are
90 | ```
91 | /ublox_position_receiver/fix
92 | /ublox_moving_baseline_receiver/fix_velocity
93 | ```
94 |
95 | Additionally, you should monitor the fix status.
96 | ```
97 | /ublox_position_receiver/navstatus
98 | ```
99 |
100 | ### Dual Receivers
101 | At first use, setup the [firmware](#firmware).
102 |
103 | To startup two receivers where the second receiver estimates the moving baseline run
104 | ```
105 | roslaunch ublox_utils ublox.launch device_position_receiver:=/dev/ttyACM0 use_moving_baseline:=true device_moving_baseline_receiver:=/dev/ttyACM1
106 | ```
107 | The relevant ROS topic is
108 | ```
109 | /ublox_moving_baseline_receiver/navheading
110 | ```
111 | Additionally, you should monitor a valid fix flag as well as the distance between the antennas in
112 | ```
113 | /ublox_moving_baseline_receiver/navrelposned
114 | ```
115 |
116 | **Note**: You may want to find a smart way to allocate the device ID.
117 |
118 | ### NTRIP Corrections
119 | We use the [swipos-GIS/GEO](https://www.swisstopo.admin.ch/de/geodata/geoservices/swipos/swipos-dienste/swipos-gisgeo.html) caster in conjunction with the [ROS ntrip client](http://wiki.ros.org/ntrip_client).
120 | Our [ublox2nmea](src/ublox2nmea.cc) node makes sure the caster receives the current VRS location.
121 | It receives the [NavPVT](http://docs.ros.org/en/noetic/api/ublox_msgs/html/msg/NavPVT.html) from the u-blox receiver and outputs it as [NMEA $GPGGA sentence](http://docs.ros.org/en/api/nmea_msgs/html/msg/Sentence.html).
122 | ```
123 | roslaunch ublox_utils ublox.launch device_position_receiver:=/dev/ttyACM0 use_ntrip:=true ntrip_username:=YOUR_USER ntrip_password:=YOUR_PASSWORD
124 | ```
125 |
126 | The rosgraph should look like this:
127 | 
128 |
129 | ### Dual Receivers with NTRIP
130 | ```
131 | roslaunch ublox_utils ublox.launch device_position_receiver:=/dev/ttyACM0 use_moving_baseline:=true device_moving_baseline_receiver:=/dev/ttyACM1 use_ntrip:=true ntrip_username:=YOUR_USER ntrip_password:=YOUR_PASSWORD
132 | ```
133 |
--------------------------------------------------------------------------------
/config/moving_base.txt:
--------------------------------------------------------------------------------
1 | # Config changes format version 1.0
2 | # created by u-center version 22.02 at 19:07:31 on Friday, 20 May 2022
3 | [del]
4 | [set]
5 | RAM CFG-RATE-MEAS 0x7d # write value 125 0x7d to item id 0x30210001 in layer 0
6 | Flash CFG-RATE-MEAS 0x7d # write value 125 0x7d to item id 0x30210001 in layer 2
7 | RAM CFG-UART1-BAUDRATE 0x70800 # write value 460800 0x70800 to item id 0x40520001 in layer 0
8 | Flash CFG-UART1-BAUDRATE 0x70800 # write value 460800 0x70800 to item id 0x40520001 in layer 2
9 | RAM CFG-UART2-BAUDRATE 0x70800 # write value 460800 0x70800 to item id 0x40530001 in layer 0
10 | Flash CFG-UART2-BAUDRATE 0x70800 # write value 460800 0x70800 to item id 0x40530001 in layer 2
11 | RAM CFG-MSGOUT-RTCM_3X_TYPE1074_UART2 0x1 # write value 1 0x1 to item id 0x20910360 i
12 | Flash CFG-MSGOUT-RTCM_3X_TYPE1074_UART2 0x1 # write value 1 0x1 to item id 0x20910360 i
13 | RAM CFG-MSGOUT-RTCM_3X_TYPE1084_UART2 0x1 # write value 1 0x1 to item id 0x20910365 i
14 | Flash CFG-MSGOUT-RTCM_3X_TYPE1084_UART2 0x1 # write value 1 0x1 to item id 0x20910365 i
15 | RAM CFG-MSGOUT-RTCM_3X_TYPE1094_UART2 0x1 # write value 1 0x1 to item id 0x2091036a i
16 | Flash CFG-MSGOUT-RTCM_3X_TYPE1094_UART2 0x1 # write value 1 0x1 to item id 0x2091036a i
17 | RAM CFG-MSGOUT-RTCM_3X_TYPE1124_UART2 0x1 # write value 1 0x1 to item id 0x2091036f i
18 | Flash CFG-MSGOUT-RTCM_3X_TYPE1124_UART2 0x1 # write value 1 0x1 to item id 0x2091036f i
19 | RAM CFG-MSGOUT-RTCM_3X_TYPE1230_UART2 0x1 # write value 1 0x1 to item id 0x20910305 i
20 | Flash CFG-MSGOUT-RTCM_3X_TYPE1230_UART2 0x1 # write value 1 0x1 to item id 0x20910305 i
21 | RAM CFG-MSGOUT-RTCM_3X_TYPE4072_0_UART2 0x1 # write value 1 0x1 to item id 0x20910300
22 | Flash CFG-MSGOUT-RTCM_3X_TYPE4072_0_UART2 0x1 # write value 1 0x1 to item id 0x20910300
23 |
24 |
--------------------------------------------------------------------------------
/config/rover.txt:
--------------------------------------------------------------------------------
1 | # Config changes format version 1.0
2 | # created by u-center version 22.02 at 19:14:30 on Friday, 20 May 2022
3 | [del]
4 | [set]
5 | RAM CFG-RATE-MEAS 0x7d # write value 125 0x7d to item id 0x30210001 in layer 0
6 | Flash CFG-RATE-MEAS 0x7d # write value 125 0x7d to item id 0x30210001 in layer 2
7 | RAM CFG-UART1-BAUDRATE 0x70800 # write value 460800 0x70800 to item id 0x40520001 in layer 0
8 | Flash CFG-UART1-BAUDRATE 0x70800 # write value 460800 0x70800 to item id 0x40520001 in layer 2
9 | RAM CFG-UART2-BAUDRATE 0x70800 # write value 460800 0x70800 to item id 0x40530001 in layer 0
10 | Flash CFG-UART2-BAUDRATE 0x70800 # write value 460800 0x70800 to item id 0x40530001 in layer 2
11 | RAM CFG-MSGOUT-UBX_NAV_RELPOSNED_UART1 0x1 # write value 1 0x1 to item id 0x2091008e
12 | Flash CFG-MSGOUT-UBX_NAV_RELPOSNED_UART1 0x1 # write value 1 0x1 to item id 0x2091008e
13 |
--------------------------------------------------------------------------------
/config/zed_f9p.yaml:
--------------------------------------------------------------------------------
1 | config_on_startup: false
2 | publish:
3 | nav:
4 | relposned: true
5 | status: true
6 | pvt: true
7 | rxm:
8 | rtcm: true
9 | gnss:
10 | gps: true
11 | glonass: true
12 | galileo: true
13 | beidou: true
14 | dynamic_model: airborne1
15 | debug: 0
--------------------------------------------------------------------------------
/launch/ublox.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
68 |
69 |
70 |
71 |
72 |
73 |
75 |
76 |
77 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ublox_utils
4 | 1.0.0
5 |
6 | Repository with ROS tools for the u-blox RTK receiver.
7 |
8 | Rik Bähnemann
9 | Rik Bähnemann
10 |
11 | MIT
12 |
13 | catkin
14 |
15 | roscpp
16 | nmea_msgs
17 | ublox_msgs
18 |
19 | roscpp
20 | nmea_msgs
21 | ublox_msgs
22 | mavros_msgs
23 | rtcm_msgs
24 | ntrip_client
25 |
26 |
--------------------------------------------------------------------------------
/resources/gnss_hardware_setup.drawio:
--------------------------------------------------------------------------------
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 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
--------------------------------------------------------------------------------
/src/ublox2nmea.cc:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 | Copyright (c) 2022 Rik Baehnemann, ASL, ETH Zurich, Switzerland
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 | SOFTWARE.
19 | */
20 |
21 | #include
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | class Transformer {
29 | public:
30 | Transformer();
31 |
32 | private:
33 | ros::Publisher nmea_pub_;
34 | ros::Subscriber navpvt_sub_;
35 |
36 | void receiveNavPVT(const ublox_msgs::NavPVT::ConstPtr &navsat_msg);
37 | };
38 |
39 | Transformer::Transformer() {
40 | ros::NodeHandle nh;
41 | navpvt_sub_ = nh.subscribe("navpvt", 1, &Transformer::receiveNavPVT, this);
42 | ROS_INFO("Subscribing to NavPVT topic %s", navpvt_sub_.getTopic().c_str());
43 | nmea_pub_ = nh.advertise("nmea", 1);
44 | ROS_INFO("Advertising NMEA topic %s", nmea_pub_.getTopic().c_str());
45 | }
46 |
47 | void Transformer::receiveNavPVT(const ublox_msgs::NavPVT::ConstPtr &navpvt_msg) {
48 | ROS_INFO_ONCE("Received first NavPVT message.");
49 |
50 | char buf[255];
51 |
52 | // Time conversion
53 | auto now = ros::Time::now();
54 | auto time = now.toBoost().time_of_day();
55 | long int deci_seconds = now.nsec / 1e7;
56 |
57 | // Lat conversion
58 | char lat_dir = navpvt_msg->lat < 0 ? 'S' : 'N';
59 | int8_t lat_degs = navpvt_msg->lat / 1e7;
60 | double lat_mins = (navpvt_msg->lat - lat_degs * 1e7) / 1e7 * 60.0;
61 |
62 | // Lon conversion
63 | char lon_dir = navpvt_msg->lon < 0 ? 'W' : 'E';
64 | int8_t lon_degs = navpvt_msg->lon / 1e7;
65 | double lon_mins = (navpvt_msg->lon - lon_degs * 1e7) / 1e7 * 60.0;
66 |
67 | // Status conversion
68 | int8_t status = (navpvt_msg->fixType == ublox_msgs::NavPVT::FIX_TYPE_3D) ? 1 : 0;
69 |
70 | uint8_t
71 | len = sprintf(buf,
72 | "$GPGGA,%02ld%02ld%02ld.%ld,%02d%08.5f,%c,%03d%08.5f,%c,%d,%d,%.1f,%d.%d,M,%d.%d,M,,",
73 | time.hours(),
74 | time.minutes(),
75 | time.seconds(),
76 | deci_seconds,
77 | lat_degs,
78 | lat_mins,
79 | lat_dir,
80 | lon_degs,
81 | lon_mins,
82 | lon_dir,
83 | status,
84 | navpvt_msg->numSV,
85 | navpvt_msg->pDOP / 100.0,
86 | navpvt_msg->hMSL / 1000,
87 | navpvt_msg->hMSL % 1000,
88 | (navpvt_msg->height - navpvt_msg->hMSL) / 1000,
89 | std::abs((navpvt_msg->height - navpvt_msg->hMSL)) % 1000
90 | );
91 | // Calculate checksum of sentence and add it to the end of the sentence
92 | uint8_t checksum = 0;
93 | for (int i = 1; i < len; i++) {
94 | checksum ^= buf[i];
95 | }
96 | sprintf(&buf[len], "*%02X\r\n", checksum);
97 |
98 | nmea_msgs::Sentence nmea_msg;
99 | nmea_msg.header.stamp = now;
100 | nmea_msg.header.frame_id = "gps";
101 | nmea_msg.sentence = buf;
102 | nmea_pub_.publish(nmea_msg);
103 | }
104 |
105 | int main(int argc, char **argv) {
106 | ros::init(argc, argv, "ublox2nmea");
107 |
108 | Transformer transformer;
109 |
110 | ros::spin();
111 | return 0;
112 | }
113 |
--------------------------------------------------------------------------------