PX4 Firmware
PX4 Autopilot Software http://px4.io
microRTPS_client_main.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright 2017 Proyectos y Sistemas de Mantenimiento SL (eProsima).
4  * Copyright (c) 2019 PX4 Development Team. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of the copyright holder nor the names of its contributors
17  * may be used to endorse or promote products derived from this software without
18  * specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 #include "microRTPS_transport.h"
35 #include "microRTPS_client.h"
36 
37 #include <inttypes.h>
38 #include <cstdio>
39 #include <cstdlib>
40 #include <ctime>
41 #include <termios.h>
42 
43 #include <px4_platform_common/px4_config.h>
44 #include <px4_platform_common/getopt.h>
45 #include <px4_platform_common/cli.h>
46 #include <px4_platform_common/module.h>
47 #include <px4_platform_common/posix.h>
48 #include <px4_platform_common/tasks.h>
49 #include <px4_platform_common/time.h>
50 
51 extern "C" __EXPORT int micrortps_client_main(int argc, char *argv[]);
52 
53 static int _rtps_task = -1;
54 bool _should_exit_task = false;
55 Transport_node *transport_node = nullptr;
57 
58 static void usage(const char *name)
59 {
60  PRINT_MODULE_USAGE_NAME("micrortps_client", "communication");
61  PRINT_MODULE_USAGE_COMMAND("start");
62 
63  PRINT_MODULE_USAGE_PARAM_STRING('t', "UART", "UART|UDP", "Transport protocol", true);
64  PRINT_MODULE_USAGE_PARAM_STRING('d', "/dev/ttyACM0", "<file:dev>", "Select Serial Device", true);
65  PRINT_MODULE_USAGE_PARAM_INT('b', 460800, 9600, 3000000, "Baudrate (can also be p:<param_name>)", true);
66  PRINT_MODULE_USAGE_PARAM_INT('p', -1, 1, 1000, "Poll timeout for UART in ms", true);
67  PRINT_MODULE_USAGE_PARAM_INT('l', 10000, -1, 100000, "Limit number of iterations until the program exits (-1=infinite)",
68  true);
69  PRINT_MODULE_USAGE_PARAM_INT('w', 1, 1, 1000, "Time in ms for which each iteration sleeps", true);
70  PRINT_MODULE_USAGE_PARAM_INT('r', 2019, 0, 65536, "Select UDP Network Port for receiving (local)", true);
71  PRINT_MODULE_USAGE_PARAM_INT('s', 2020, 0, 65536, "Select UDP Network Port for sending (remote)", true);
72  PRINT_MODULE_USAGE_PARAM_STRING('i', "127.0.0.1", "<x.x.x.x>", "Select IP address (remote)", true);
73 
74  PRINT_MODULE_USAGE_COMMAND("stop");
75  PRINT_MODULE_USAGE_COMMAND("status");
76 }
77 
78 static int parse_options(int argc, char *argv[])
79 {
80  int ch;
81  int myoptind = 1;
82  const char *myoptarg = nullptr;
83 
84  while ((ch = px4_getopt(argc, argv, "t:d:l:w:b:p:r:s:i:", &myoptind, &myoptarg)) != EOF) {
85  switch (ch) {
86  case 't': _options.transport = strcmp(myoptarg, "UDP") == 0 ?
89 
90  case 'd': if (nullptr != myoptarg) strcpy(_options.device, myoptarg); break;
91 
92  case 'l': _options.loops = strtol(myoptarg, nullptr, 10); break;
93 
94  case 'w': _options.sleep_ms = strtoul(myoptarg, nullptr, 10); break;
95 
96  case 'b': _options.baudrate = strtoul(myoptarg, nullptr, 10); break;
97 
98  case 'r': _options.recv_port = strtoul(myoptarg, nullptr, 10); break;
99 
100  case 's': _options.send_port = strtoul(myoptarg, nullptr, 10); break;
101 
102  case 'i': if (nullptr != myoptarg) strcpy(_options.ip, myoptarg); break;
103 
104  default:
105  usage(argv[1]);
106  return -1;
107  }
108  }
109 
110  if (_options.poll_ms < 1) {
111  _options.poll_ms = 1;
112  PX4_ERR("poll timeout too low, using 1 ms");
113  }
114 
115  return 0;
116 }
117 
118 static int micrortps_start(int argc, char *argv[])
119 {
120  if (0 > parse_options(argc, argv)) {
121  PX4_INFO("EXITING...");
122  _rtps_task = -1;
123  return -1;
124  }
125 
126  switch (_options.transport) {
129  PX4_INFO("UART transport: device: %s; baudrate: %d; sleep: %dms; poll: %dms",
131  }
132  break;
133 
136  PX4_INFO("UDP transport: ip address: %s; recv port: %u; send port: %u; sleep: %dms",
138  }
139  break;
140 
141  default:
142  _rtps_task = -1;
143  PX4_INFO("EXITING...");
144  return -1;
145  }
146 
147  if (0 > transport_node->init()) {
148  PX4_INFO("EXITING...");
149  _rtps_task = -1;
150  return -1;
151  }
152 
153  struct timespec begin;
154 
155  struct timespec end;
156 
157  uint64_t total_read = 0, received = 0;
158 
159  int loop = 0;
160 
161  micrortps_start_topics(begin, total_read, received, loop);
162 
163  px4_clock_gettime(CLOCK_REALTIME, &end);
164 
165  double elapsed_secs = static_cast<double>(end.tv_sec - begin.tv_sec + (end.tv_nsec - begin.tv_nsec) / 1e9);
166 
167  PX4_INFO("RECEIVED: %" PRIu64 " messages in %d LOOPS, %" PRIu64 " bytes in %.03f seconds - %.02fKB/s",
168  received, loop, total_read, elapsed_secs, static_cast<double>(total_read / (1e3 * elapsed_secs)));
169 
170  delete transport_node;
171 
172  transport_node = nullptr;
173 
174  PX4_INFO("Stopped!");
175 
176  fflush(stdout);
177 
178  _rtps_task = -1;
179 
180  return 0;
181 }
182 
183 int micrortps_client_main(int argc, char *argv[])
184 {
185  if (argc < 2) {
186  usage(argv[0]);
187  return -1;
188  }
189 
190  if (!strcmp(argv[1], "start")) {
191  if (_rtps_task != -1) {
192  PX4_INFO("Already running");
193  return -1;
194  }
195 
196  _rtps_task = px4_task_spawn_cmd("rtps",
197  SCHED_DEFAULT,
198  SCHED_PRIORITY_DEFAULT,
199  4096,
200  (px4_main_t) micrortps_start,
201  (char *const *)argv);
202 
203  if (_rtps_task < 0) {
204  PX4_WARN("Could not start task");
205  _rtps_task = -1;
206  return -1;
207  }
208 
209  return 0;
210  }
211 
212  if (!strcmp(argv[1], "status")) {
213  if (_rtps_task == -1) {
214  PX4_INFO("Not running");
215 
216  } else {
217  PX4_INFO("Running");
218  }
219 
220  return 0;
221  }
222 
223  if (!strcmp(argv[1], "stop")) {
224  if (_rtps_task == -1) {
225  PX4_INFO("Not running");
226  return -1;
227  }
228 
229  _should_exit_task = true;
230 
231  if (nullptr != transport_node) { transport_node->close(); }
232 
233  _rtps_task = -1;
234  return 0;
235  }
236 
237  usage(argv[0]);
238  return -1;
239 }
char ip[16]
eTransports transport
static int micrortps_start(int argc, char *argv[])
Transport_node * transport_node
Definition: I2C.hpp:51
void micrortps_start_topics(struct timespec &begin, uint64_t &total_read, uint64_t &received, int &loop)
char device[64]
static int parse_options(int argc, char *argv[])
uint32_t baudrate
uint32_t sleep_ms
uint16_t send_port
bool _should_exit_task
const char * name
Definition: tests_main.c:58
static int _rtps_task
uint16_t recv_port
struct options _options
static void usage(const char *name)
__EXPORT int micrortps_client_main(int argc, char *argv[])
uint32_t poll_ms