TraveSim Adapters  0.1
Protobuf adapters for TraveSim project
team_receiver.cpp
Go to the documentation of this file.
1 /**
2  * @file team_receiver.cpp
3  *
4  * @author Lucas Haug <lucas.haug@thunderatz.org>
5  *
6  * @brief Team control data receiver with UDP and protobuf
7  *
8  * @date 06/2021
9  *
10  * @copyright MIT License - Copyright (c) 2021 ThundeRatz
11  */
12 
13 #include <ros/console.h>
14 
16 
17 /*****************************************
18  * Private Constants
19  *****************************************/
20 
21 #define BUFFER_SIZE 1024U
22 
23 /*****************************************
24  * Public Methods Bodies Definitions
25  *****************************************/
26 
27 namespace travesim {
28 namespace proto {
29 TeamReceiver::TeamReceiver(const std::string receiver_address, const short receiver_port, bool is_yellow,
30  bool force_specific_source, TeamsFormation teams_formation) {
31  this->unicast_receiver =
32  std::unique_ptr<udp::UnicastReceiver>(new udp::UnicastReceiver(receiver_address, receiver_port));
33  this->unicast_receiver->force_specific_source(force_specific_source);
34 
35  this->is_yellow = is_yellow;
36 
37  this->last_team_cmd = std::unique_ptr<TeamCommand>(new TeamCommand(teams_formation));
38 }
39 
41  char buffer[BUFFER_SIZE];
42 
43  size_t data_size = 0;
44 
45  try {
46  data_size = this->unicast_receiver->receive_latest(buffer, BUFFER_SIZE);
47  } catch (std::exception& e) {
48  ROS_ERROR_STREAM((this->is_yellow ? "Yellow" : "Blue") << " team receiver: " << e.what());
49 
50  return false;
51  }
52 
53  if (data_size > 0) {
54  fira_message::sim_to_ref::Packet packet_data;
55  packet_data.ParseFromArray(buffer, BUFFER_SIZE);
56 
57  if (packet_data.has_cmd()) {
58  this->packet_pb_msg_to_team_command(&packet_data, p_team_cmd);
59 
60  *last_team_cmd = *p_team_cmd;
61 
62  return true;
63  } else {
64  *p_team_cmd = *last_team_cmd;
65  }
66  } else {
67  *p_team_cmd = *last_team_cmd;
68  }
69 
70  return false;
71 }
72 
73 void TeamReceiver::set_receiver_endpoint(const std::string receiver_address, const short receiver_port) {
74  this->unicast_receiver->set_receiver_endpoint(receiver_address,
75  receiver_port);
76 }
77 
78 void TeamReceiver::force_specific_source(bool force_specific_source) {
79  this->unicast_receiver->force_specific_source(force_specific_source);
80 }
81 
82 void TeamReceiver::reset(void) {
83  try {
84  this->unicast_receiver->reset();
85  } catch (std::exception& e) {
86  ROS_ERROR_STREAM((this->is_yellow ? "Yellow" : "Blue") << " team receiver: " << e.what());
87  }
88 }
89 
90 void TeamReceiver::packet_pb_msg_to_team_command(fira_message::sim_to_ref::Packet* p_packet, TeamCommand* p_team_cmd) {
91  for (const auto& robot_cmd : p_packet->cmd().robot_commands()) {
92  if (robot_cmd.yellowteam() == this->is_yellow) {
93  int robot_id = robot_cmd.id();
94 
95  if ((robot_id < 0) || (robot_id >= p_team_cmd->robots_per_team)) {
96  ROS_WARN_STREAM("Error: Invalid robot id in team receiver!\r\nReceived id is " <<
97  robot_id << " and max id is " << p_team_cmd->robots_per_team);
98  continue;
99  }
100 
101  if (isnanf(robot_cmd.wheel_left()) || isnanf(robot_cmd.wheel_right())) {
102  ROS_WARN_STREAM("Error: Invalid robot speed in team receiver!");
103  continue;
104  }
105 
106  p_team_cmd->robot_command[robot_id].left_speed = robot_cmd.wheel_left();
107  p_team_cmd->robot_command[robot_id].right_speed = robot_cmd.wheel_right();
108  } else {
109  ROS_WARN("Error: Team %s receiver and command colors don't match!",
110  this->is_yellow ? "yellow" : "blue");
111  }
112  }
113 }
114 } // namespace proto
115 } // namespace travesim
void force_specific_source(bool force_specific_source)
Set wheter to enable any source or source specific multicast. True for specific source,...
uint8_t robots_per_team
Public attributes.
Team control data receiver with UDP and protobuf.
Receiver class using UDP in unicast mode.
void set_receiver_endpoint(const std::string receiver_address, const short receiver_port)
Set the receiver endpoint.
std::vector< RobotCommand > robot_command
Data structure to hold the command for a team.
TeamReceiver(const std::string receiver_address, const short receiver_port, bool is_yellow, bool force_specific_source=false, TeamsFormation teams_formation=TeamsFormation::THREE_ROBOTS_PER_TEAM)
Construct a new TeamReceiver object.
std::unique_ptr< udp::UnicastReceiver > unicast_receiver
TeamsFormation
Formation of the teams.
Definition: data_common.hpp:40
void packet_pb_msg_to_team_command(fira_message::sim_to_ref::Packet *p_packet, TeamCommand *p_team_cmd)
Update a TeamCommand object from a Packet protobuf message.
void reset(void)
Reset the receiver.
std::unique_ptr< TeamCommand > last_team_cmd
#define BUFFER_SIZE
bool receive(TeamCommand *p_team_cmd)
Receive the command from a team.