serial_node.cpp
Go to the documentation of this file.
1 
26 #include "ros/ros.h"
27 
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <termios.h>
31 
32 #include "nmea_comms/rx.h"
33 
34 
35 void manage_connection(const ros::TimerEvent& event, ros::NodeHandle& n, std::string port, int32_t baud, std::string frame_id)
36 {
37  if (rx_prune_threads() > 0)
38  {
39  // Serial thread already active. Nothing to do here.
40  return;
41  }
42 
43  // Only output error messages when things were previously peachy.
44  static int previous_success = 1;
45 
46  while (ros::ok())
47  {
48  ROS_DEBUG_STREAM("Opening serial port: " << port);
49  int serial_fd = open(port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
50 
51  if (serial_fd == -1)
52  {
53  if (previous_success)
54  {
55  ROS_ERROR_STREAM("Could not open " << port << ".");
56  }
57  goto retry_connection;
58  }
59 
60  if (!isatty(serial_fd))
61  {
62  if (previous_success)
63  {
64  ROS_ERROR_STREAM("File " << port << " is not a tty.");
65  }
66  goto close_serial;
67  }
68 
69  struct termios options;
70  tcgetattr(serial_fd, &options);
71  options.c_cflag = 0;
72  options.c_cflag |= CS8;
73 
74  options.c_cflag |= (CLOCAL | CREAD);
75 
76  ROS_DEBUG_STREAM("Setting baud rate: " << baud);
77  switch (baud)
78  {
79  case 9600:
80  cfsetispeed(&options, B9600);
81  cfsetospeed(&options, B9600);
82  break;
83  case 19200:
84  cfsetispeed(&options, B19200);
85  cfsetospeed(&options, B19200);
86  break;
87  case 38400:
88  cfsetispeed(&options, B38400);
89  cfsetospeed(&options, B38400);
90  break;
91  case 57600:
92  cfsetispeed(&options, B57600);
93  cfsetospeed(&options, B57600);
94  break;
95  case 115200:
96  cfsetispeed(&options, B115200);
97  cfsetospeed(&options, B115200);
98  break;
99  default:
100  ROS_FATAL_STREAM("Unsupported baud rate: " << baud);
101  ros::shutdown();
102  }
103  options.c_iflag = 0;
104  options.c_oflag = 0;
105  options.c_lflag = 0;
106  options.c_cc[VMIN] = 0;
107  options.c_cc[VTIME] = 1;
108  tcsetattr(serial_fd, TCSAFLUSH, &options);
109 
110  // Successful connection setup; kick off servicing thread.
111  ROS_INFO_STREAM("Successfully connected on " << port << ".");
112  previous_success = 1;
113  rx_thread_start(n, serial_fd, frame_id, 1000000000 / baud * 10);
114  break;
115 
116 close_serial:
117  close(serial_fd);
118 
119 retry_connection:
120  if (previous_success)
121  {
122  ROS_ERROR("Retrying connection every 1 second.");
123  previous_success = 0;
124  }
125 
126  ros::Duration(1.0).sleep();
127  }
128 }
129 
130 
131 int main(int argc, char **argv)
132 {
133  ros::init(argc, argv, "nmea_serial_node");
134  ros::NodeHandle n_local("~");
135  ros::NodeHandle n;
136 
137  std::string port;
138  int32_t baud;
139  n_local.param<std::string>("port", port, "/dev/ttyUSB0");
140  n_local.param("baud", baud, 115200);
141 
142  std::string frame_id;
143  n_local.param<std::string>("frame_id", frame_id, "navsat");
144 
145  ros::Timer timer = n.createTimer(ros::Duration(1.0),
146  boost::bind(manage_connection, _1, n, port, baud, frame_id));
147  ros::spin();
148 
149  rx_stop_all();
150 
151  return 0;
152 }
void rx_thread_start(ros::NodeHandle &n, int fd, std::string frame_id, uint32_t byte_time_ns=0)
Definition: rx.cpp:236
bool sleep() const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void rx_stop_all()
Definition: rx.cpp:213
#define ROS_FATAL_STREAM(args)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
int main(int argc, char **argv)
ROSCPP_DECL bool ok()
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
ROSCPP_DECL void spin()
#define ROS_DEBUG_STREAM(args)
int rx_prune_threads()
Definition: rx.cpp:195
void manage_connection(const ros::TimerEvent &event, ros::NodeHandle &n, std::string port, int32_t baud, std::string frame_id)
Definition: serial_node.cpp:35
#define ROS_INFO_STREAM(args)
ROSCPP_DECL void shutdown()
#define ROS_ERROR_STREAM(args)
#define ROS_ERROR(...)


nmea_comms
Author(s): Mike Purvis
autogenerated on Mon Aug 5 2019 03:53:18