probe_robot.cc
Go to the documentation of this file.
1 
31 #include <serial/serial.h>
33 
34 struct Options {
35  bool robot = false;
36  bool firmware = false;
37  bool pcb_rev = false;
38  bool verbose = false;
39  bool help = false;
40  std::string serial_port = "";
41  int baud_rate = 0;
42 };
43 
44 bool find_switch(const std::vector<std::string> &args, const std::string &short_sw,
45  const std::string &long_sw) {
46  bool has_short = (std::find(args.cbegin(), args.cend(), short_sw)) != args.cend();
47  bool has_long = (std::find(args.cbegin(), args.cend(), long_sw)) != args.cend();
48 
49  return (has_long || has_short);
50 }
51 
52 std::string get_option(const std::vector<std::string> &args, const std::string &option,
53  const std::string &default_val) {
54  auto opt = std::find(args.cbegin(), args.cend(), option);
55  if (opt != args.cend() && std::next(opt) != args.cend()) {
56  return *(++opt);
57  } else {
58  return default_val;
59  }
60 }
61 
62 int get_option(const std::vector<std::string> &args, const std::string &option,
63  const int default_val) {
64  auto opt = std::find(args.cbegin(), args.cend(), option);
65  if (opt != args.cend() && std::next(opt) != args.cend()) {
66  return std::stoi(*(++opt));
67  } else {
68  return default_val;
69  }
70 }
71 
72 Options parse_args(const std::vector<std::string> &args) {
73  Options op;
74 
75  op.robot = find_switch(args, "-r", "--robot");
76  op.firmware = find_switch(args, "-f", "--firmware");
77  op.pcb_rev = find_switch(args, "-p", "--pcb");
78  op.verbose = find_switch(args, "-v", "--verbose");
79  op.help = find_switch(args, "-h", "--help");
80 
81  if (find_switch(args, "-a", "--all")) {
82  op.robot = true;
83  op.firmware = true;
84  op.pcb_rev = true;
85  }
86 
87  op.serial_port = get_option(args, "-D", "/dev/ttyAMA0");
88 
89  try {
90  op.baud_rate = get_option(args, "-B", 38400);
91  } catch (std::invalid_argument e) {
92  fprintf(stderr, "%s\n", "Expected integer for option -B");
93  throw e;
94  }
95 
96  return op;
97 }
98 
99 class TimeoutException : public std::exception {
100  // Disable copy constructors
102  std::string e_what_;
103 
104 public:
105  TimeoutException(const char *description) { e_what_ = description; }
107  virtual ~TimeoutException() throw() {}
108  virtual const char *what() const throw() { return e_what_.c_str(); }
109 };
110 
112  MotorMessage req;
113  req.setRegister(reg);
115  req.setData(0);
116 
117  RawMotorMessage out = req.serialize();
118  robot.write(out.c_array(), out.size());
119 
120  robot.flush();
121 
122  bool timedout = false;
123  struct timespec start, current_time;
124  clock_gettime(CLOCK_MONOTONIC, &current_time);
125  start = current_time;
126 
127  while (robot.isOpen() && !timedout) {
128  if (robot.waitReadable()) {
129  RawMotorMessage innew = {0, 0, 0, 0, 0, 0, 0, 0};
130 
131  robot.read(innew.c_array(), 1);
132  if (innew[0] != MotorMessage::delimeter) continue;
133 
134  robot.waitByteTimes(innew.size() - 1);
135  robot.read(&innew.c_array()[1], 7);
136 
137  MotorMessage rsp;
138  if (!rsp.deserialize(innew)) {
139  if (rsp.getType() == MotorMessage::TYPE_RESPONSE && rsp.getRegister() == reg) {
140  return rsp;
141  }
142  }
143  }
144 
145  clock_gettime(CLOCK_MONOTONIC, &current_time);
146  timedout = (current_time.tv_sec >= start.tv_sec + 5);
147  }
148 
149  if (timedout) {
150  throw TimeoutException("Timed Out Waiting for Serial Response");
151  }
152  else {
153  throw std::runtime_error("unknown error while wating for serial");
154  }
155 }
156 
157 int main(int argc, char const *argv[]) {
158  std::vector<std::string> args(argv + 1, argv + argc);
159 
160  int ret_code = 0;
161  Options op;
162 
163  try {
164  op = parse_args(args);
165  }
166  catch (...) {
167  fprintf(stderr, "%s\n", "Error parsing arguments");
168  return 2;
169  }
170 
171  if (op.help) {
172  printf("%s\n", "Used to probe Ubiquity Robotics robots for version info");
173  printf("%s\n", "Options:");
174  printf("%s\n", " -D {PATH TO PORT}: Set the Serial Port to use (e.g. /dev/ttyAMA0)");
175  printf("%s\n", " -B {BAUD RATE}: Set the Baud Rate to use (e.g. 38400)");
176  printf("%s\n", "Switches:");
177  printf("%s\n", " -a --all: Print out all options.");
178  printf("%s\n", " -r --robot: Print out robot platform (e.g. loki, magni, none)");
179  printf("%s\n", " -f --firmware: Print out firmware revision");
180  printf("%s\n", " -p --pcb: Print out the PCB revision");
181  printf("%s\n", " -v --verbose: Print out debugging information.");
182  printf("%s\n", " -h --help: Print out this help");
183 
184  return 0;
185  }
186 
187  if (op.verbose) {
188  fprintf(stderr, "%s\n", "Parsed Args:");
189  fprintf(stderr, " Robot ID: %d\n", op.robot);
190  fprintf(stderr, " Firmware: %d\n", op.firmware);
191  fprintf(stderr, " PCB: %d\n", op.pcb_rev);
192  fprintf(stderr, " Verbose: %d\n", op.verbose);
193  fprintf(stderr, " Help: %d\n", op.help);
194  fprintf(stderr, " Serial Port: %s\n", op.serial_port.c_str());
195  fprintf(stderr, " Baud Rate: %d\n", op.baud_rate);
196  }
197 
198  try {
200 
201  if (op.robot) {
202  try {
204  int id_num = robot_id.getData();
205  if (id_num == 0x00) {
206  printf("%s\n", "magni");
207  } else if (id_num == 0x01) {
208  printf("%s\n", "loki");
209  } else {
210  printf("%s\n", "unknown");
211  }
212  } catch (TimeoutException e) {
213  printf("%s\n", "none");
214  ret_code = 2;
215  }
216  }
217  if (op.firmware) {
218  try {
220  printf("%d\n", firmware.getData());
221  } catch (TimeoutException e) {
222  fprintf(stderr, "%s\n", "Timeout getting firmware version");
223  ret_code = 2;
224  }
225  }
226  if (op.pcb_rev) {
227  try {
229  printf("%d\n", hardware.getData());
230  } catch (TimeoutException e) {
231  fprintf(stderr, "%s\n", "Timeout getting hardware version");
232  ret_code = 2;
233  }
234  }
235  } catch (const serial::IOException &e) {
236  if (op.verbose) {
237  fprintf(stderr, "Error opening Serial Port %s\n", op.serial_port.c_str());
238  }
239  return 1;
240  }
241 
242  return ret_code;
243 }
Options::pcb_rev
bool pcb_rev
Definition: probe_robot.cc:37
MotorMessage::deserialize
MotorMessage::ErrorCodes deserialize(const RawMotorMessage &serialized)
Definition: motor_message.cc:151
MotorMessage::TYPE_RESPONSE
@ TYPE_RESPONSE
Definition: motor_message.h:77
MotorMessage::delimeter
const static uint8_t delimeter
Definition: motor_message.h:267
MotorMessage::getType
MotorMessage::MessageTypes getType() const
Definition: motor_message.cc:112
test_pi_gpio.args
args
Definition: test_pi_gpio.py:91
MotorMessage::REG_FIRMWARE_VERSION
@ REG_FIRMWARE_VERSION
Definition: motor_message.h:131
TimeoutException::operator=
TimeoutException & operator=(const TimeoutException &)
get_option
std::string get_option(const std::vector< std::string > &args, const std::string &option, const std::string &default_val)
Definition: probe_robot.cc:52
TimeoutException::TimeoutException
TimeoutException(const TimeoutException &other)
Definition: probe_robot.cc:106
Options::help
bool help
Definition: probe_robot.cc:39
serial::Serial::flush
void flush()
Definition: serial.cc:352
MotorMessage::TYPE_READ
@ TYPE_READ
Definition: motor_message.h:75
TimeoutException::~TimeoutException
virtual ~TimeoutException()
Definition: probe_robot.cc:107
TimeoutException::TimeoutException
TimeoutException(const char *description)
Definition: probe_robot.cc:105
TimeoutException::what
virtual const char * what() const
Definition: probe_robot.cc:108
MotorMessage::setData
void setData(int32_t data)
Definition: motor_message.cc:126
Options::verbose
bool verbose
Definition: probe_robot.cc:38
serial::Serial::waitReadable
bool waitReadable()
Definition: serial.cc:105
Options
Definition: probe_robot.cc:34
MotorMessage::Registers
Registers
Definition: motor_message.h:82
serial::IOException
Definition: serial.h:688
MotorMessage::REG_HARDWARE_VERSION
@ REG_HARDWARE_VERSION
Definition: motor_message.h:130
MotorMessage::REG_ROBOT_ID
@ REG_ROBOT_ID
Definition: motor_message.h:148
ret_code
ret_code
serial::Timeout::simpleTimeout
static Timeout simpleTimeout(uint32_t timeout)
Definition: serial.h:112
MotorMessage::serialize
RawMotorMessage serialize() const
Definition: motor_message.cc:141
serial::Serial
Definition: serial.h:147
MotorMessage::getData
int32_t getData() const
Definition: motor_message.cc:135
serial.h
readRegister
MotorMessage readRegister(MotorMessage::Registers reg, serial::Serial &robot)
Definition: probe_robot.cc:111
start
ROSCPP_DECL void start()
Options::robot
bool robot
Definition: probe_robot.cc:35
main
int main(int argc, char const *argv[])
Definition: probe_robot.cc:157
motor_message.h
Options::serial_port
std::string serial_port
Definition: probe_robot.cc:40
MotorMessage::getRegister
MotorMessage::Registers getRegister() const
Definition: motor_message.cc:122
TimeoutException::e_what_
std::string e_what_
Definition: probe_robot.cc:102
serial::Serial::isOpen
bool isOpen() const
Definition: serial.cc:93
find_switch
bool find_switch(const std::vector< std::string > &args, const std::string &short_sw, const std::string &long_sw)
Definition: probe_robot.cc:44
TimeoutException
Definition: probe_robot.cc:99
serial::Serial::waitByteTimes
void waitByteTimes(size_t count)
Definition: serial.cc:112
args
RawMotorMessage
boost::array< uint8_t, 8 > RawMotorMessage
Definition: motor_message.h:38
Options::baud_rate
int baud_rate
Definition: probe_robot.cc:41
serial::Serial::write
size_t write(const uint8_t *data, size_t size)
Definition: serial.cc:252
serial::Serial::read
size_t read(uint8_t *buffer, size_t size)
Definition: serial.cc:124
parse_args
Options parse_args(const std::vector< std::string > &args)
Definition: probe_robot.cc:72
MotorMessage::setRegister
void setRegister(MotorMessage::Registers reg)
Definition: motor_message.cc:116
MotorMessage::setType
void setType(MotorMessage::MessageTypes type)
Definition: motor_message.cc:106
Options::firmware
bool firmware
Definition: probe_robot.cc:36
MotorMessage
Definition: motor_message.h:67


ubiquity_motor
Author(s):
autogenerated on Thu Nov 16 2023 03:30:55