pacmod_node.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019 AutonomouStuff, LLC
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
22 #include <unistd.h>
23 #include <time.h>
24 
25 #include <algorithm>
26 #include <mutex>
27 #include <string>
28 #include <thread>
29 #include <unordered_map>
30 #include <vector>
31 #include <memory>
32 #include <utility>
33 
34 #include <std_msgs/Int16.h>
35 #include <std_msgs/Bool.h>
36 #include <std_msgs/Float64.h>
37 #include <can_msgs/Frame.h>
38 
39 using namespace AS::Drivers::PACMod; // NOLINT
40 
42 const double watchdog_timeout = 0.3;
43 std::string veh_type_string = "POLARIS_GEM"; // NOLINT
45 std::unordered_map<int64_t, ros::Publisher> pub_tx_list;
47 
48 // Vehicle-Specific Publishers
69 
70 // Vehicle-Specific Subscribers
71 std::shared_ptr<ros::Subscriber> wiper_set_cmd_sub,
74 
75 // Advertise published messages
87 
88 std::unordered_map<int64_t, std::shared_ptr<LockedData>> rx_list;
89 std::unordered_map<int64_t, int64_t> rpt_cmd_list;
90 
91 bool enable_state = false;
92 std::mutex enable_mut;
93 bool override_state = false;
94 std::mutex override_mut;
95 bool global_keep_going = true;
96 std::mutex keep_going_mut;
97 
98 /*
99 pacmod_msgs::PacmodCmd global_cmd_msg;
100 pacmod_msgs::PacmodCmd::ConstPtr global_cmd_msg_cpr(&global_cmd_msg);
101 */
102 std::chrono::milliseconds can_error_pause = std::chrono::milliseconds(1000);
103 
104 // Sets the PACMod enable flag through CAN.
105 void set_enable(bool val)
106 {
107  std::lock_guard<std::mutex> lck(enable_mut);
108  enable_state = val;
109 }
110 
111 // Listens for incoming requests to enable the PACMod
112 void callback_pacmod_enable(const std_msgs::Bool::ConstPtr& msg)
113 {
114  set_enable(msg->data);
115 }
116 
117 // Listens for incoming requests to change the state of the turn signals
118 void callback_turn_signal_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr& msg)
119 {
120  int64_t can_id = TurnSignalCmdMsg::CAN_ID;
121  auto rx_it = rx_list.find(can_id);
122 
123  if (rx_it != rx_list.end())
124  {
125  rx_it->second->setData(PacmodRxRosMsgHandler::unpackAndEncode(can_id, msg));
126  rx_it->second->setIsValid(true);
127  }
128  else
129  {
130  ROS_WARN("Received command message for ID 0x%lx for which we did not have an encoder.", can_id);
131  }
132 }
133 
134 // Listens for incoming requests to change the state of the headlights
135 void callback_headlight_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr& msg)
136 {
137  int64_t can_id = HeadlightCmdMsg::CAN_ID;
138  auto rx_it = rx_list.find(can_id);
139 
140  if (rx_it != rx_list.end())
141  {
142  rx_it->second->setData(PacmodRxRosMsgHandler::unpackAndEncode(can_id, msg));
143  rx_it->second->setIsValid(true);
144  }
145  else
146  {
147  ROS_WARN("Received command message for ID 0x%lx for which we did not have an encoder.", can_id);
148  }
149 }
150 
151 // Listens for incoming requests to change the state of the horn
152 void callback_horn_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr& msg)
153 {
154  int64_t can_id = HornCmdMsg::CAN_ID;
155  auto rx_it = rx_list.find(can_id);
156 
157  if (rx_it != rx_list.end())
158  {
159  rx_it->second->setData(PacmodRxRosMsgHandler::unpackAndEncode(can_id, msg));
160  rx_it->second->setIsValid(true);
161  }
162  else
163  {
164  ROS_WARN("Received command message for ID 0x%lx for which we did not have an encoder.", can_id);
165  }
166 }
167 
168 // Listens for incoming requests to change the state of the windshield wipers
169 void callback_wiper_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr& msg)
170 {
171  int64_t can_id = WiperCmdMsg::CAN_ID;
172  auto rx_it = rx_list.find(can_id);
173 
174  if (rx_it != rx_list.end())
175  {
176  rx_it->second->setData(PacmodRxRosMsgHandler::unpackAndEncode(can_id, msg));
177  rx_it->second->setIsValid(true);
178  }
179  else
180  {
181  ROS_WARN("Received command message for ID 0x%lx for which we did not have an encoder.", can_id);
182  }
183 }
184 
185 // Listens for incoming requests to change the gear shifter state
186 void callback_shift_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr& msg)
187 {
188  int64_t can_id = ShiftCmdMsg::CAN_ID;
189  auto rx_it = rx_list.find(can_id);
190 
191  if (rx_it != rx_list.end())
192  {
193  rx_it->second->setData(PacmodRxRosMsgHandler::unpackAndEncode(can_id, msg));
194  rx_it->second->setIsValid(true);
195  }
196  else
197  {
198  ROS_WARN("Received command message for ID 0x%lx for which we did not have an encoder.", can_id);
199  }
200 }
201 
202 // Listens for incoming requests to change the position of the throttle pedal
203 void callback_accelerator_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr& msg)
204 {
205  int64_t can_id = AccelCmdMsg::CAN_ID;
206  auto rx_it = rx_list.find(can_id);
207 
208  if (rx_it != rx_list.end())
209  {
210  rx_it->second->setData(PacmodRxRosMsgHandler::unpackAndEncode(can_id, msg));
211  rx_it->second->setIsValid(true);
212  }
213  else
214  {
215  ROS_WARN("Received command message for ID 0x%lx for which we did not have an encoder.", can_id);
216  }
217 }
218 
219 // Listens for incoming requests to change the position of the steering wheel with a speed limit
220 void callback_steering_set_cmd(const pacmod_msgs::PositionWithSpeed::ConstPtr& msg)
221 {
222  int64_t can_id = SteerCmdMsg::CAN_ID;
223  auto rx_it = rx_list.find(can_id);
224 
225  if (rx_it != rx_list.end())
226  {
227  rx_it->second->setData(PacmodRxRosMsgHandler::unpackAndEncode(can_id, msg));
228  rx_it->second->setIsValid(true);
229  }
230  else
231  {
232  ROS_WARN("Received command message for ID 0x%lx for which we did not have an encoder.", can_id);
233  }
234 }
235 
236 // Listens for incoming requests to change the position of the brake pedal
237 void callback_brake_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr& msg)
238 {
239  int64_t can_id = BrakeCmdMsg::CAN_ID;
240  auto rx_it = rx_list.find(can_id);
241 
242  if (rx_it != rx_list.end())
243  {
244  rx_it->second->setData(PacmodRxRosMsgHandler::unpackAndEncode(can_id, msg));
245  rx_it->second->setIsValid(true);
246  }
247  else
248  {
249  ROS_WARN("Received command message for ID 0x%lx for which we did not have an encoder.", can_id);
250  }
251 }
252 
253 void send_can(int32_t id, const std::vector<unsigned char>& vec)
254 {
255  can_msgs::Frame frame;
256  frame.id = id;
257  frame.is_rtr = false;
258  frame.is_extended = false;
259  frame.is_error = false;
260  frame.dlc = 8;
261  std::copy(vec.begin(), vec.end(), frame.data.begin());
262 
263  frame.header.stamp = ros::Time::now();
264 
265  can_rx_pub.publish(frame);
266 }
267 
268 void can_write()
269 {
270  std::vector<unsigned char> data;
271 
272  const std::chrono::milliseconds loop_pause = std::chrono::milliseconds(33);
273  const std::chrono::milliseconds inter_msg_pause = std::chrono::milliseconds(1);
274  bool keep_going = true;
275 
276  // Set local to global value before looping.
277  keep_going_mut.lock();
278  keep_going = global_keep_going;
279  keep_going_mut.unlock();
280 
281  while (keep_going)
282  {
283  /*
284  // Create Global Command
285  enable_mut.lock();
286  global_cmd_msg.enable = enable_state;
287  enable_mut.unlock();
288 
289  global_cmd_msg.clear = true;
290  global_cmd_msg.ignore = false;
291 
292  auto rx_it = rx_list.find(GlobalCmdMsg::CAN_ID);
293  rx_it->second->setData(PacmodRxRosMsgHandler::unpackAndEncode(GlobalCmdMsg::CAN_ID, global_cmd_msg_cpr));
294  rx_it->second->setIsValid(true);
295  */
296 
297  // Temporarily write the Global message separately.
298  GlobalCmdMsg global_obj;
299  bool local_enable;
300 
301  enable_mut.lock();
302  local_enable = enable_state;
303  enable_mut.unlock();
304 
305  global_obj.encode(local_enable, true, false);
306 
307  // ret = can_writer.write(GlobalCmdMsg::CAN_ID, &global_obj.data[0], 8, true);
308  send_can(GlobalCmdMsg::CAN_ID, global_obj.data);
309 
310  std::this_thread::sleep_for(inter_msg_pause);
311 
312  if (local_enable)
313  {
314  // Write all the data that we have received.
315  for (const auto& element : rx_list)
316  {
317  // Make sure the data are valid.
318  if (element.second->isValid())
319  {
320  send_can(element.first, element.second->getData());
321  std::this_thread::sleep_for(inter_msg_pause);
322  }
323  }
324  }
325 
326  std::chrono::system_clock::time_point next_time = std::chrono::system_clock::now();
327  next_time += loop_pause;
328  std::this_thread::sleep_until(next_time);
329 
330  // Set local to global immediately before next loop.
331  keep_going_mut.lock();
332  keep_going = global_keep_going;
333  keep_going_mut.unlock();
334  }
335 }
336 
337 void can_read(const can_msgs::Frame::ConstPtr &msg)
338 {
339  std_msgs::Bool bool_pub_msg;
340  auto parser_class = PacmodTxMsg::make_message(msg->id);
341  auto pub = pub_tx_list.find(msg->id);
342 
343  // Only parse messages for which we have a parser and a publisher.
344  if (parser_class != NULL && pub != pub_tx_list.end())
345  {
346  parser_class->parse(const_cast<unsigned char *>(&msg->data[0]));
347  handler.fillAndPublish(msg->id, "pacmod", pub->second, parser_class);
348 
349  bool local_enable = false;
350 
351  enable_mut.lock();
352  local_enable = enable_state;
353  enable_mut.unlock();
354 
355  if (!local_enable)
356  {
357  // If we're disabled, set all of the system commands
358  // to be the current report values. This ensures that
359  // when we enable, we are in the same state as the vehicle.
360 
361  // Find the cmd value for this rpt.
362  auto cmd = rpt_cmd_list.find(msg->id);
363 
364  if (cmd != rpt_cmd_list.end())
365  {
366  // Find the data we need to set.
367  auto rx_it = rx_list.find(cmd->second);
368 
369  if (rx_it != rx_list.end())
370  {
371  if (msg->id == TurnSignalRptMsg::CAN_ID)
372  {
373  auto dc_parser = std::dynamic_pointer_cast<TurnSignalRptMsg>(parser_class);
374  TurnSignalCmdMsg encoder;
375 
376  encoder.encode(dc_parser->output);
377  rx_it->second->setData(encoder.data);
378  }
379  else if (msg->id == ShiftRptMsg::CAN_ID)
380  {
381  auto dc_parser = std::dynamic_pointer_cast<ShiftRptMsg>(parser_class);
382  ShiftCmdMsg encoder;
383 
384  encoder.encode(dc_parser->output);
385  rx_it->second->setData(encoder.data);
386  }
387  else if (msg->id == AccelRptMsg::CAN_ID)
388  {
389  auto dc_parser = std::dynamic_pointer_cast<AccelRptMsg>(parser_class);
390  AccelCmdMsg encoder;
391 
392  encoder.encode(dc_parser->output);
393  rx_it->second->setData(encoder.data);
394  }
395  else if (msg->id == SteerRptMsg::CAN_ID)
396  {
397  auto dc_parser = std::dynamic_pointer_cast<SteerRptMsg>(parser_class);
398  SteerCmdMsg encoder;
399 
400  encoder.encode(dc_parser->output, 2.0);
401  rx_it->second->setData(encoder.data);
402  }
403  else if (msg->id == BrakeRptMsg::CAN_ID)
404  {
405  auto dc_parser = std::dynamic_pointer_cast<BrakeRptMsg>(parser_class);
406  BrakeCmdMsg encoder;
407 
408  encoder.encode(dc_parser->output);
409  rx_it->second->setData(encoder.data);
410  }
411  else if (msg->id == WiperRptMsg::CAN_ID)
412  {
413  auto dc_parser = std::dynamic_pointer_cast<WiperRptMsg>(parser_class);
414  WiperCmdMsg encoder;
415 
416  encoder.encode(dc_parser->output);
417  rx_it->second->setData(encoder.data);
418  }
419  else if (msg->id == HornRptMsg::CAN_ID)
420  {
421  auto dc_parser = std::dynamic_pointer_cast<HornRptMsg>(parser_class);
422  HornCmdMsg encoder;
423 
424  encoder.encode(dc_parser->output);
425  rx_it->second->setData(encoder.data);
426  }
427 
428  rx_it->second->setIsValid(true);
429  }
430  }
431  }
432 
433  if (msg->id == GlobalRptMsg::CAN_ID)
434  {
435  auto dc_parser = std::dynamic_pointer_cast<GlobalRptMsg>(parser_class);
436 
437  bool_pub_msg.data = (dc_parser->enabled);
438  enable_pub.publish(bool_pub_msg);
439 
440  if (dc_parser->override_active)
441  {
442  set_enable(false);
443  }
444  }
445  else if (msg->id == VehicleSpeedRptMsg::CAN_ID)
446  {
447  auto dc_parser = std::dynamic_pointer_cast<VehicleSpeedRptMsg>(parser_class);
448 
449  // Now publish in m/s
450  std_msgs::Float64 veh_spd_ms_msg;
451  veh_spd_ms_msg.data = (dc_parser->vehicle_speed) * 0.44704;
452  vehicle_speed_ms_pub.publish(veh_spd_ms_msg);
453  }
454  }
455 }
456 
457 int main(int argc, char *argv[])
458 {
459  ros::init(argc, argv, "pacmod");
460  ros::AsyncSpinner spinner(2);
461  ros::NodeHandle n;
462  ros::NodeHandle priv("~");
463  ros::Rate loop_rate(1.0); // PACMod is sending at ~30Hz.
464 
465  // Wait for time to be valid
466  while (ros::Time::now().nsec == 0) {}
467 
468  // Get and validate parameters
469  if (priv.getParam("vehicle_type", veh_type_string))
470  {
471  ROS_INFO("PACMod - Got vehicle type of: %s", veh_type_string.c_str());
472 
473  if (veh_type_string == "POLARIS_GEM")
474  {
476  }
477  else if (veh_type_string == "POLARIS_RANGER")
478  {
480  }
481  else if (veh_type_string == "INTERNATIONAL_PROSTAR_122")
482  {
484  }
485  else if (veh_type_string == "LEXUS_RX_450H")
486  {
488  }
489  else
490  {
492  ROS_WARN("PACMod - An invalid vehicle type was entered. Assuming POLARIS_GEM.");
493  }
494  }
495 
496  // Advertise published messages
497  can_rx_pub = n.advertise<can_msgs::Frame>("can_rx", 20);
498  global_rpt_pub = n.advertise<pacmod_msgs::GlobalRpt>("parsed_tx/global_rpt", 20);
499  vin_rpt_pub = n.advertise<pacmod_msgs::VinRpt>("parsed_tx/vin_rpt", 5);
500  turn_rpt_pub = n.advertise<pacmod_msgs::SystemRptInt>("parsed_tx/turn_rpt", 20);
501  shift_rpt_pub = n.advertise<pacmod_msgs::SystemRptInt>("parsed_tx/shift_rpt", 20);
502  accel_rpt_pub = n.advertise<pacmod_msgs::SystemRptFloat>("parsed_tx/accel_rpt", 20);
503  steer_rpt_pub = n.advertise<pacmod_msgs::SystemRptFloat>("parsed_tx/steer_rpt", 20);
504  brake_rpt_pub = n.advertise<pacmod_msgs::SystemRptFloat>("parsed_tx/brake_rpt", 20);
505  vehicle_speed_pub = n.advertise<pacmod_msgs::VehicleSpeedRpt>("parsed_tx/vehicle_speed_rpt", 20);
506  vehicle_speed_ms_pub = n.advertise<std_msgs::Float64>("as_tx/vehicle_speed", 20);
507  enable_pub = n.advertise<std_msgs::Bool>("as_tx/enable", 20, true);
508 
509  std::string frame_id = "pacmod";
510 
511  // Populate handler list
512  pub_tx_list.insert(std::make_pair(GlobalRptMsg::CAN_ID, global_rpt_pub));
513  pub_tx_list.insert(std::make_pair(VinRptMsg::CAN_ID, vin_rpt_pub));
514  pub_tx_list.insert(std::make_pair(TurnSignalRptMsg::CAN_ID, turn_rpt_pub));
515  pub_tx_list.insert(std::make_pair(ShiftRptMsg::CAN_ID, shift_rpt_pub));
516  pub_tx_list.insert(std::make_pair(AccelRptMsg::CAN_ID, accel_rpt_pub));
517  pub_tx_list.insert(std::make_pair(SteerRptMsg::CAN_ID, steer_rpt_pub));
518  pub_tx_list.insert(std::make_pair(BrakeRptMsg::CAN_ID, brake_rpt_pub));
519  pub_tx_list.insert(std::make_pair(VehicleSpeedRptMsg::CAN_ID, vehicle_speed_pub));
520 
521  // Subscribe to messages
522  ros::Subscriber can_tx_sub = n.subscribe("can_tx", 20, can_read);
523  ros::Subscriber turn_set_cmd_sub = n.subscribe("as_rx/turn_cmd", 20, callback_turn_signal_set_cmd);
524  ros::Subscriber shift_set_cmd_sub = n.subscribe("as_rx/shift_cmd", 20, callback_shift_set_cmd);
525  ros::Subscriber accelerator_set_cmd = n.subscribe("as_rx/accel_cmd", 20, callback_accelerator_set_cmd);
526  ros::Subscriber steering_set_cmd = n.subscribe("as_rx/steer_cmd", 20, callback_steering_set_cmd);
527  ros::Subscriber brake_set_cmd = n.subscribe("as_rx/brake_cmd", 20, callback_brake_set_cmd);
528  ros::Subscriber enable_sub = n.subscribe("as_rx/enable", 20, callback_pacmod_enable);
529 
530  // Populate rx list
531  std::shared_ptr<LockedData> global_data(new LockedData);
532  std::shared_ptr<LockedData> turn_data(new LockedData);
533  std::shared_ptr<LockedData> shift_data(new LockedData);
534  std::shared_ptr<LockedData> accel_data(new LockedData);
535  std::shared_ptr<LockedData> steer_data(new LockedData);
536  std::shared_ptr<LockedData> brake_data(new LockedData);
537 
538  rx_list.insert(std::make_pair(GlobalCmdMsg::CAN_ID, global_data));
539  rx_list.insert(std::make_pair(TurnSignalCmdMsg::CAN_ID, turn_data));
540  rx_list.insert(std::make_pair(ShiftCmdMsg::CAN_ID, shift_data));
541  rx_list.insert(std::make_pair(AccelCmdMsg::CAN_ID, accel_data));
542  rx_list.insert(std::make_pair(SteerCmdMsg::CAN_ID, steer_data));
543  rx_list.insert(std::make_pair(BrakeCmdMsg::CAN_ID, brake_data));
544 
548  {
549  brake_rpt_detail_1_pub = n.advertise<pacmod_msgs::MotorRpt1>("parsed_tx/brake_rpt_detail_1", 20);
550  brake_rpt_detail_2_pub = n.advertise<pacmod_msgs::MotorRpt2>("parsed_tx/brake_rpt_detail_2", 20);
551  brake_rpt_detail_3_pub = n.advertise<pacmod_msgs::MotorRpt3>("parsed_tx/brake_rpt_detail_3", 20);
552  steering_rpt_detail_1_pub = n.advertise<pacmod_msgs::MotorRpt1>("parsed_tx/steer_rpt_detail_1", 20);
553  steering_rpt_detail_2_pub = n.advertise<pacmod_msgs::MotorRpt2>("parsed_tx/steer_rpt_detail_2", 20);
554  steering_rpt_detail_3_pub = n.advertise<pacmod_msgs::MotorRpt3>("parsed_tx/steer_rpt_detail_3", 20);
555 
556  pub_tx_list.insert(std::make_pair(BrakeMotorRpt1Msg::CAN_ID, brake_rpt_detail_1_pub));
557  pub_tx_list.insert(std::make_pair(BrakeMotorRpt2Msg::CAN_ID, brake_rpt_detail_2_pub));
558  pub_tx_list.insert(std::make_pair(BrakeMotorRpt3Msg::CAN_ID, brake_rpt_detail_3_pub));
559  pub_tx_list.insert(std::make_pair(SteerMotorRpt1Msg::CAN_ID, steering_rpt_detail_1_pub));
560  pub_tx_list.insert(std::make_pair(SteerMotorRpt2Msg::CAN_ID, steering_rpt_detail_2_pub));
561  pub_tx_list.insert(std::make_pair(SteerMotorRpt3Msg::CAN_ID, steering_rpt_detail_3_pub));
562  }
563 
565  {
566  wiper_rpt_pub = n.advertise<pacmod_msgs::SystemRptInt>("parsed_tx/wiper_rpt", 20);
567 
568  pub_tx_list.insert(std::make_pair(WiperRptMsg::CAN_ID, wiper_rpt_pub));
569 
570  wiper_set_cmd_sub = std::shared_ptr<ros::Subscriber>(new ros::Subscriber(n.subscribe("as_rx/wiper_cmd",
571  20,
573 
574  std::shared_ptr<LockedData> wiper_data(new LockedData);
575  rx_list.insert(std::make_pair(WiperCmdMsg::CAN_ID, wiper_data));
576  }
577 
579  {
580  horn_rpt_pub = n.advertise<pacmod_msgs::SystemRptInt>("parsed_tx/horn_rpt", 20);
581  steer_rpt_2_pub = n.advertise<pacmod_msgs::SystemRptFloat>("parsed_tx/steer_rpt_2", 20);
582  steer_rpt_3_pub = n.advertise<pacmod_msgs::SystemRptFloat>("parsed_tx/steer_rpt_3", 20);
583  wheel_speed_rpt_pub = n.advertise<pacmod_msgs::WheelSpeedRpt>("parsed_tx/wheel_speed_rpt", 20);
584  steering_pid_rpt_1_pub = n.advertise<pacmod_msgs::SteeringPIDRpt1>("parsed_tx/steer_pid_rpt_1", 20);
585  steering_pid_rpt_2_pub = n.advertise<pacmod_msgs::SteeringPIDRpt2>("parsed_tx/steer_pid_rpt_2", 20);
586  steering_pid_rpt_3_pub = n.advertise<pacmod_msgs::SteeringPIDRpt3>("parsed_tx/steer_pid_rpt_3", 20);
587  steering_pid_rpt_4_pub = n.advertise<pacmod_msgs::SteeringPIDRpt4>("parsed_tx/steer_pid_rpt_4", 20);
588  yaw_rate_rpt_pub = n.advertise<pacmod_msgs::YawRateRpt>("parsed_tx/yaw_rate_rpt", 20);
589  lat_lon_heading_rpt_pub = n.advertise<pacmod_msgs::LatLonHeadingRpt>("parsed_tx/lat_lon_heading_rpt", 20);
590  date_time_rpt_pub = n.advertise<pacmod_msgs::DateTimeRpt>("parsed_tx/date_time_rpt", 20);
591 
592  pub_tx_list.insert(std::make_pair(HornRptMsg::CAN_ID, horn_rpt_pub));
593  pub_tx_list.insert(std::make_pair(SteerRpt2Msg::CAN_ID, steer_rpt_2_pub));
594  pub_tx_list.insert(std::make_pair(SteerRpt3Msg::CAN_ID, steer_rpt_3_pub));
595  pub_tx_list.insert(std::make_pair(WheelSpeedRptMsg::CAN_ID, wheel_speed_rpt_pub));
596  pub_tx_list.insert(std::make_pair(SteeringPIDRpt1Msg::CAN_ID, steering_pid_rpt_1_pub));
597  pub_tx_list.insert(std::make_pair(SteeringPIDRpt2Msg::CAN_ID, steering_pid_rpt_2_pub));
598  pub_tx_list.insert(std::make_pair(SteeringPIDRpt3Msg::CAN_ID, steering_pid_rpt_3_pub));
599  pub_tx_list.insert(std::make_pair(SteeringPIDRpt4Msg::CAN_ID, steering_pid_rpt_4_pub));
600  pub_tx_list.insert(std::make_pair(YawRateRptMsg::CAN_ID, yaw_rate_rpt_pub));
601  pub_tx_list.insert(std::make_pair(LatLonHeadingRptMsg::CAN_ID, lat_lon_heading_rpt_pub));
602  pub_tx_list.insert(std::make_pair(DateTimeRptMsg::CAN_ID, date_time_rpt_pub));
603 
605  std::shared_ptr<ros::Subscriber>(new ros::Subscriber(n.subscribe("as_rx/headlight_cmd",
606  20,
609  std::shared_ptr<ros::Subscriber>(new ros::Subscriber(n.subscribe("as_rx/horn_cmd",
610  20,
612 
613  std::shared_ptr<LockedData> headlight_data(new LockedData);
614  std::shared_ptr<LockedData> horn_data(new LockedData);
615 
616  rx_list.insert(std::make_pair(HeadlightCmdMsg::CAN_ID, headlight_data));
617  rx_list.insert(std::make_pair(HornCmdMsg::CAN_ID, horn_data));
618  }
619 
621  {
622  headlight_rpt_pub = n.advertise<pacmod_msgs::SystemRptInt>("parsed_tx/headlight_rpt", 20);
623  parking_brake_status_rpt_pub =
624  n.advertise<pacmod_msgs::ParkingBrakeStatusRpt>("parsed_tx/parking_brake_status_rpt", 20);
625 
626  pub_tx_list.insert(std::make_pair(HeadlightRptMsg::CAN_ID, headlight_rpt_pub));
627  pub_tx_list.insert(std::make_pair(ParkingBrakeStatusRptMsg::CAN_ID, parking_brake_status_rpt_pub));
628  }
629 
630  // Populate report/command list.
632  rpt_cmd_list.insert(std::make_pair(ShiftRptMsg::CAN_ID, ShiftCmdMsg::CAN_ID));
633  rpt_cmd_list.insert(std::make_pair(AccelRptMsg::CAN_ID, AccelCmdMsg::CAN_ID));
634  rpt_cmd_list.insert(std::make_pair(SteerRptMsg::CAN_ID, SteerCmdMsg::CAN_ID));
635  rpt_cmd_list.insert(std::make_pair(BrakeRptMsg::CAN_ID, BrakeCmdMsg::CAN_ID));
636 
638  {
639  rpt_cmd_list.insert(std::make_pair(WiperRptMsg::CAN_ID, WiperCmdMsg::CAN_ID));
640  }
642  {
643  rpt_cmd_list.insert(std::make_pair(HornRptMsg::CAN_ID, HornCmdMsg::CAN_ID));
644  }
645 
646  // Set initial state
647  set_enable(false);
648 
649  // Start CAN sending thread.
650  std::thread can_write_thread(can_write);
651  // Start callback spinner.
652  spinner.start();
653 
655 
656  // Make sure it's disabled when node shuts down
657  set_enable(false);
658 
659  keep_going_mut.lock();
660  global_keep_going = false;
661  keep_going_mut.unlock();
662 
663  can_write_thread.join();
664 
665  return 0;
666 }
667 
void set_enable(bool val)
ros::Publisher steering_rpt_detail_2_pub
Definition: pacmod_node.cpp:64
ros::Publisher accel_rpt_pub
Definition: pacmod_node.cpp:80
static const int64_t CAN_ID
Definition: pacmod_core.h:468
ros::Publisher headlight_rpt_pub
Definition: pacmod_node.cpp:50
void callback_pacmod_enable(const std_msgs::Bool::ConstPtr &msg)
std::unordered_map< int64_t, std::shared_ptr< LockedData > > rx_list
Definition: pacmod_node.cpp:88
ros::Publisher vin_rpt_pub
Definition: pacmod_node.cpp:77
void can_read(const can_msgs::Frame::ConstPtr &msg)
ros::Publisher yaw_rate_rpt_pub
Definition: pacmod_node.cpp:62
bool global_keep_going
Definition: pacmod_node.cpp:95
const double watchdog_timeout
Definition: pacmod_node.cpp:42
void encode(uint8_t turn_signal_cmd)
ros::Publisher date_time_rpt_pub
Definition: pacmod_node.cpp:60
static const int64_t CAN_ID
Definition: pacmod_core.h:127
std::shared_ptr< ros::Subscriber > wiper_set_cmd_sub
Definition: pacmod_node.cpp:71
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::mutex enable_mut
Definition: pacmod_node.cpp:92
void callback_turn_signal_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr &msg)
void encode(double steer_pos, double steer_spd)
static const int64_t CAN_ID
Definition: pacmod_core.h:423
std::unordered_map< int64_t, int64_t > rpt_cmd_list
Definition: pacmod_node.cpp:89
ros::Publisher steer_rpt_pub
Definition: pacmod_node.cpp:81
static const int64_t CAN_ID
Definition: pacmod_core.h:450
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ros::Publisher vehicle_speed_ms_pub
Definition: pacmod_node.cpp:84
double last_global_rpt_msg_received
Definition: pacmod_node.cpp:41
static const int64_t CAN_ID
Definition: pacmod_core.h:166
ros::Publisher steering_pid_rpt_2_pub
Definition: pacmod_node.cpp:56
ros::Publisher turn_rpt_pub
Definition: pacmod_node.cpp:78
ros::Publisher can_rx_pub
Definition: pacmod_node.cpp:86
void callback_wiper_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr &msg)
ros::Publisher steer_rpt_3_pub
Definition: pacmod_node.cpp:53
ros::Publisher steering_pid_rpt_3_pub
Definition: pacmod_node.cpp:57
static const int64_t CAN_ID
Definition: pacmod_core.h:396
void encode(double accel_cmd)
#define ROS_WARN(...)
static const int64_t CAN_ID
Definition: pacmod_core.h:120
ros::Publisher steering_rpt_detail_1_pub
Definition: pacmod_node.cpp:63
ros::Publisher steering_pid_rpt_1_pub
Definition: pacmod_node.cpp:55
static std::shared_ptr< PacmodTxMsg > make_message(const int64_t &can_id)
Definition: pacmod_core.cpp:70
static const int64_t CAN_ID
Definition: pacmod_core.h:73
static const int64_t CAN_ID
Definition: pacmod_core.h:159
std::vector< uint8_t > data
Definition: pacmod_core.h:389
void encode(uint8_t horn_cmd)
ros::Publisher brake_rpt_detail_3_pub
Definition: pacmod_node.cpp:68
int main(int argc, char *argv[])
ros::Publisher wiper_rpt_pub
Definition: pacmod_node.cpp:49
ros::Publisher shift_rpt_pub
Definition: pacmod_node.cpp:79
void publish(const boost::shared_ptr< M > &message) const
static std::vector< uint8_t > unpackAndEncode(const int64_t &can_id, const pacmod_msgs::PacmodCmd::ConstPtr &msg)
std::string veh_type_string
Definition: pacmod_node.cpp:43
void can_write()
static const int64_t CAN_ID
Definition: pacmod_core.h:432
static const int64_t CAN_ID
Definition: pacmod_core.h:113
ros::Publisher horn_rpt_pub
Definition: pacmod_node.cpp:51
ros::Publisher wheel_speed_rpt_pub
Definition: pacmod_node.cpp:54
void encode(uint8_t shift_cmd)
static const int64_t CAN_ID
Definition: pacmod_core.h:441
void callback_brake_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr &msg)
#define ROS_INFO(...)
bool getParam(const std::string &key, std::string &s) const
VehicleType veh_type
Definition: pacmod_node.cpp:44
void callback_shift_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr &msg)
ros::Publisher steering_pid_rpt_4_pub
Definition: pacmod_node.cpp:58
static const int64_t CAN_ID
Definition: pacmod_core.h:56
ros::Publisher steer_rpt_2_pub
Definition: pacmod_node.cpp:52
std::chrono::milliseconds can_error_pause
ros::Publisher parking_brake_status_rpt_pub
Definition: pacmod_node.cpp:61
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::Publisher brake_rpt_detail_1_pub
Definition: pacmod_node.cpp:66
void encode(double brake_cmd)
void callback_horn_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr &msg)
ros::Publisher enable_pub
Definition: pacmod_node.cpp:85
static const int64_t CAN_ID
Definition: pacmod_core.h:145
void encode(bool enable, bool clear_override, bool ignore_overide)
std::mutex override_mut
Definition: pacmod_node.cpp:94
std::shared_ptr< ros::Subscriber > horn_set_cmd_sub
Definition: pacmod_node.cpp:71
PacmodTxRosMsgHandler handler
Definition: pacmod_node.cpp:46
ros::Publisher brake_rpt_detail_2_pub
Definition: pacmod_node.cpp:67
static const int64_t CAN_ID
Definition: pacmod_core.h:173
ros::Publisher vehicle_speed_pub
Definition: pacmod_node.cpp:83
void encode(uint8_t wiper_cmd)
ros::Publisher global_rpt_pub
Definition: pacmod_node.cpp:76
static Time now()
static const int64_t CAN_ID
Definition: pacmod_core.h:152
void fillAndPublish(const int64_t &can_id, std::string frame_id, const ros::Publisher &pub, const std::shared_ptr< PacmodTxMsg > &parser_class)
ros::Publisher lat_lon_heading_rpt_pub
Definition: pacmod_node.cpp:59
ros::Publisher steering_rpt_detail_3_pub
Definition: pacmod_node.cpp:65
void send_can(int32_t id, const std::vector< unsigned char > &vec)
ros::Publisher brake_rpt_pub
Definition: pacmod_node.cpp:82
std::mutex keep_going_mut
Definition: pacmod_node.cpp:96
std::unordered_map< int64_t, ros::Publisher > pub_tx_list
Definition: pacmod_node.cpp:45
static const int64_t CAN_ID
Definition: pacmod_core.h:459
void callback_steering_set_cmd(const pacmod_msgs::PositionWithSpeed::ConstPtr &msg)
std::shared_ptr< ros::Subscriber > headlight_set_cmd_sub
Definition: pacmod_node.cpp:71
void callback_headlight_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr &msg)
ROSCPP_DECL void waitForShutdown()
void callback_accelerator_set_cmd(const pacmod_msgs::PacmodCmd::ConstPtr &msg)
bool override_state
Definition: pacmod_node.cpp:93
bool enable_state
Definition: pacmod_node.cpp:91


pacmod
Author(s): Joe Driscoll , Josh Whitley
autogenerated on Mon Feb 28 2022 23:03:08