-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmitecom-main.cpp
203 lines (159 loc) · 6.31 KB
/
mitecom-main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#ifdef MITECOM_EXAMPLE
#include "mitecom-network.h"
#include "mitecom-handler.h"
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <math.h>
#include <sys/time.h>
#include <string>
/*------------------------------------------------------------------------------------------------*/
// all team mates (including myself)
MixedTeamMates teamMates;
/*------------------------------------------------------------------------------------------------*/
/**
** returns the current time in milliseconds
**
** @return number of milliseconds since epoch (i.e. Jan 1, 1970, 0:00 UTC)
*/
uint64_t getCurrentTime () {
struct timeval tv;
gettimeofday(&tv, 0);
return static_cast<uint64_t>( static_cast<uint64_t>(tv.tv_sec) * 1000 + static_cast<uint64_t>(tv.tv_usec) / 1000 );
}
/*------------------------------------------------------------------------------------------------*/
/**
** Prints a help text on how to start this application.
*/
void usage(const char* programName) {
printf("Usage: %s <localport> <remoteport> <robotID> <teamID>\n", programName);
printf("where\n");
printf(" localport The local port number (receiving messages) (>1024).\n");
printf(" remoteport The port number to broadcast to (>1024).\n");
printf(" robotID ID of this robot (> 0)\n");
printf(" teamID The ID of the team this robot belongs to (>0)\n");
}
/*------------------------------------------------------------------------------------------------*/
/**
** Processes the data from a team mate.
*/
void process(const MixedTeamMate &mate) {
/* TODO: ignore messages from myself
if (mate.robotID == myRobotID)
return;
*/
if (teamMates.find(mate.robotID) == teamMates.end()) {
printf("Adding robot %d to my list of team mates. Welcome.\n", mate.robotID);
}
// add team mate to our map
teamMates[mate.robotID] = mate;
// remember the last time (i.e. now) that we heard from this robot
teamMates[mate.robotID].lastUpdate = getCurrentTime();
}
/*------------------------------------------------------------------------------------------------*/
/**
** Application entry point.
*/
int main(int argc, char* argv[]) {
if (argc != 5) {
fprintf(stderr, "Invalid number of arguments.\n");
usage(argv[0]);
return -1;
}
int localport = atoi(argv[1]);
int remoteport = atoi(argv[2]);
int robotID = atoi(argv[3]);
int teamID = atoi(argv[4]);
int sock = mitecom_open(localport);
if (sock == -1) {
return -1;
}
uint64_t lastBroadcast = getCurrentTime();
uint64_t lastReport = getCurrentTime();
while (true) {
const int bufferLength = SHRT_MAX;
char buffer[bufferLength];
// receive a message (if available), this call is nonblocking
ssize_t messageLength = mitecom_receive(sock, buffer, bufferLength);
if (messageLength > 0) {
// message received, process it
MixedTeamMate teamMate = MixedTeamParser::parseIncoming(buffer, messageLength, teamID);
if (teamMate.robotID && teamMate.robotID != robotID) {
process(teamMate);
}
} else {
// add some delay
usleep(100*1000 /* microseconds */);
}
// send our information out regularly, and check for expired team mates
if (lastBroadcast + 500 < getCurrentTime()) {
MixedTeamMate myInformation;
myInformation.robotID = robotID; // it is me, ME!!!
myInformation.data[ROBOT_CURRENT_ROLE] = ROLE_OTHER;
myInformation.data[ROBOT_ABSOLUTE_X] = mrand48() % SHRT_MAX; // millimeters
myInformation.data[ROBOT_ABSOLUTE_Y] = mrand48() % SHRT_MAX; // millimeters
myInformation.data[ROBOT_ABSOLUTE_ORIENTATION] = mrand48() % 360; // degree
myInformation.data[ROBOT_ABSOLUTE_BELIEF] = 0; // 0 to 255; 0 = no confidence
MixedTeamCommMessage *messageDataPtr = NULL;
uint32_t messageDataLength = 0;
// serialize and broadcast data
messageDataPtr = MixedTeamParser::create(&messageDataLength, myInformation, teamID, robotID);
mitecom_broadcast(sock, remoteport, messageDataPtr, messageDataLength);
free(messageDataPtr);
// expire team mates we haven't seen in a while
for (MixedTeamMates::iterator it = teamMates.begin(); it != teamMates.end(); ) {
if ((it->second).lastUpdate + 2000 < getCurrentTime()) {
printf("I didn't hear from %d for a while. Good bye, %d.\n", it->first, it->first);
teamMates.erase(it++);
} else
it++;
}
}
// print a report about the available team mates
if (lastReport + 2000 < getCurrentTime() && teamMates.size() > 0) {
printf("=== REPORT ============================================\n");
for (MixedTeamMates::iterator it = teamMates.begin(); it != teamMates.end(); it++) {
MixedTeamMate &mate = it->second;
MixedTeamMateData &data = mate.data;
// extract role
std::string currentRoleName;
if (data.find(ROBOT_CURRENT_ROLE) != data.end()) {
MixedTeamRoleEnum currentRole = (MixedTeamRoleEnum)( data[ROBOT_CURRENT_ROLE] );
switch (currentRole) {
case ROLE_IDLING: currentRoleName = "Idling"; break;
case ROLE_OTHER: currentRoleName = "Other"; break;
case ROLE_STRIKER: currentRoleName = "Striker"; break;
case ROLE_SUPPORTER: currentRoleName = "Supporter"; break;
case ROLE_DEFENDER: currentRoleName = "Defender"; break;
case ROLE_GOALIE: currentRoleName = "Goalie"; break;
default: currentRoleName = "Unknown"; break;
}
} else {
currentRoleName = "Not transmitted";
}
// extract ball distance
int ballDistance = -1;
if (data.find(BALL_RELATIVE_X) != data.end() && data.find(BALL_RELATIVE_Y) != data.end()) {
int ballRelX = data[BALL_RELATIVE_X];
int ballRelY = data[BALL_RELATIVE_Y];
ballDistance = sqrt(ballRelX*ballRelX + ballRelY*ballRelY);
}
printf("Team mate %d (team %d)\n", it->first, teamID);
printf(" Role: %s\n", currentRoleName.c_str());
printf(" Ball distance: %d mm\n", ballDistance);
if (data.find(ROBOT_ABSOLUTE_X) != data.end()) {
printf(" Position on field: (%d, %d) at %d degree\n",
data[ROBOT_ABSOLUTE_X],
data[ROBOT_ABSOLUTE_Y],
data[ROBOT_ABSOLUTE_ORIENTATION]);
printf(" Belief in this position: %.3f\n", data[ROBOT_ABSOLUTE_BELIEF]/255.);
}
printf("\n");
}
lastReport = getCurrentTime();
printf("\n");
}
}
return 0;
}
#endif