7 #define DEBUG_STRING_MESSAGE
13 #include <webots/Supervisor.hpp>
14 #include <webots/Motor.hpp>
15 #include <webots/PositionSensor.hpp>
19 using namespace webots;
21 typedef string TCPMessage;
23 #ifdef DEBUG_STRING_MESSAGE
25 split(
const string& input,
char separator)
27 vector<string> result;
28 stringstream is(input);
30 while (getline(is, str, separator))
31 result.push_back(str);
37 static SOCKET open_socket(
const char* host,
int port) {
38 struct sockaddr_in address;
39 struct hostent *server;
46 rc = WSAStartup(MAKEWORD(1, 1), &info);
48 cout <<
"ERROR: Cannot initialize Winsock" << endl;
49 return INVALID_SOCKET;
54 fd = socket(AF_INET, SOCK_STREAM, 0);
55 if (fd == INVALID_SOCKET) {
56 cout <<
"ERROR: Cannot create socket" << endl;
57 return INVALID_SOCKET;
61 memset(&address, 0,
sizeof(
struct sockaddr_in));
62 address.sin_family = AF_INET;
63 address.sin_port = htons(port);
64 server = gethostbyname(host);
67 memcpy((
char *)&address.sin_addr.s_addr, (
char *)server->h_addr, server->h_length);
69 cout <<
"ERROR: Cannot resolve server name: " << host << endl;
75 return INVALID_SOCKET;
79 rc = connect(fd, (
struct sockaddr *)&address,
sizeof(
struct sockaddr));
81 cout <<
"ERROR: Cannot connect to the server at " << host <<
":" << port << endl;
90 cout <<
"Connected to server at " << host <<
":" << port << endl;
95 static int sendMessage(SOCKET fd,
const unique_ptr<TCPMessage>& msg)
99 #ifdef DEBUG_STRING_MESSAGE
102 out = msg->SerializeAsString();
106 string out_buffer =
"";
107 for (
int i = 0; i < 8; ++i) {
108 out_buffer += (
unsigned char)((
int)(((uint64_t)out.size() >> (i * 8)) & 0xFF));
115 int i_send_result = ::send(fd, &out_buffer[0], out_buffer.size(), 0);
116 if (i_send_result == SOCKET_ERROR) {
117 cout <<
"sendMessage failed" << endl;
120 return i_send_result;
124 static unique_ptr<TCPMessage> receiveMessage(SOCKET fd)
127 int received_bytes = 0;
130 uint64_t len_res = 0;
133 const int msg_length_buf_size = 8;
134 string tcp_msg_len_recv_buf;
135 tcp_msg_len_recv_buf.reserve(msg_length_buf_size);
137 while (len_res < msg_length_buf_size) {
138 received_bytes = ::recv(fd, &(tcp_msg_len_recv_buf[len_res]), msg_length_buf_size - len_res, 0);
139 if (received_bytes > 0) {
141 len_res += received_bytes;
143 else if (received_bytes == 0) {
146 cout <<
"Connection closing..." << endl;
151 cout <<
"recv failed during recv of data length" << endl;
157 uint64_t msg_len = 0;
158 for (
int i = msg_length_buf_size - 1; i >= 0; --i)
161 msg_len |= (
unsigned char)tcp_msg_len_recv_buf[i];
168 char* buf =
new char[msg_len]();
169 while (len_res < msg_len) {
170 received_bytes = recv(fd, &buf[len_res], msg_len - len_res, 0);
171 if (received_bytes > 0) {
172 len_res += received_bytes;
174 else if (received_bytes == 0) {
178 cout <<
"recv failed during recv of data message" << endl;
184 unique_ptr<TCPMessage> msg = make_unique<TCPMessage>();
185 #ifdef DEBUG_STRING_MESSAGE
186 *msg = string(buf, msg_len);
188 if (!msg->ParseFromArray(buf, msg_len)) {
189 cout <<
"ERROR: Parsing Message from String failed" << endl;
201 static int receiveIsReady(SOCKET fd) {
204 FD_SET tcp_client_fd_set;
205 FD_ZERO(&tcp_client_fd_set);
206 FD_SET(fd, &tcp_client_fd_set);
207 rc = ::select(fd + 1, &tcp_client_fd_set, NULL, NULL, &tv);
212 else if (rc == SOCKET_ERROR) {
219 const double position_offset = -15.0;
220 const double position_factor = 0.1;
221 const double bin_size = 5;
224 static get_position(
double angle) {
225 double position = angle / position_factor - position_offset;
227 return floor((position + bin_size/2) / bin_size) * bin_size;
232 int main(
int argc,
char **argv) {
233 SOCKET aera_fd = open_socket(
"127.0.0.1", 8080);
234 if (aera_fd == INVALID_SOCKET)
238 Supervisor* robot =
new Supervisor();
239 Node* sphere = robot->getFromDef(
"sphere");
240 Node* cube = robot->getFromDef(
"cube");
242 Node* ned = robot->getFromDef(
"Ned");
244 double ned_x = ned->getField(
"translation")->getSFVec3f()[0];
245 double ned_y = ned->getField(
"translation")->getSFVec3f()[1];
248 int timeStep = (int)robot->getBasicTimeStep();
250 const double arm_up = 0.65;
251 const double arm_down = 0.8;
252 const double jaw_open = 0.01;
253 const double jaw_closed = -0.0019;
255 Motor* joint_1 = robot->getMotor(
"joint_1");
257 joint_1->setControlPID(9, 0, 0);
258 Motor* joint_2 = robot->getMotor(
"joint_2");
259 Motor* joint_3 = robot->getMotor(
"joint_3");
260 Motor* joint_5 = robot->getMotor(
"joint_5");
261 Motor* joint_6 = robot->getMotor(
"joint_6");
262 Motor* joint_base_to_jaw_1 = robot->getMotor(
"joint_base_to_jaw_1");
263 Motor* joint_base_to_jaw_2 = robot->getMotor(
"joint_base_to_jaw_2");
265 joint_base_to_jaw_1->setControlPID(250, 0, 0);
266 joint_base_to_jaw_2->setControlPID(250, 0, 0);
268 PositionSensor* joint_1_sensor = robot->getPositionSensor(
"joint_1_sensor");
269 joint_1_sensor->enable(timeStep);
270 PositionSensor* joint_base_to_jaw_1_sensor = robot->getPositionSensor(
"joint_base_to_jaw_1_sensor");
271 joint_base_to_jaw_1_sensor->enable(timeStep);
272 PositionSensor* joint_base_to_jaw_2_sensor = robot->getPositionSensor(
"joint_base_to_jaw_2_sensor");
273 joint_base_to_jaw_2_sensor->enable(timeStep);
275 joint_2->setPosition(arm_up);
276 joint_3->setPosition(0.32);
277 joint_5->setPosition(-0.5);
278 joint_6->setPosition(M_PI/2);
280 joint_base_to_jaw_1->setPosition(jaw_open);
281 joint_base_to_jaw_2->setPosition(jaw_open);
284 unique_ptr<TCPMessage> msg = make_unique<TCPMessage>(
"setup");
285 sendMessage(aera_fd, std::move(msg));
288 while (receiveIsReady(aera_fd) == 0) {}
289 auto in_msg = receiveMessage(aera_fd);
290 if (*in_msg ==
"start")
293 cout <<
"While waiting for the start command, received unexpected \"" << *in_msg <<
"\"" << endl;
297 string command =
"move";
298 double target_h_position = 20;
299 int command_time = 0;
302 int receive_deadline = MAXINT;
303 while (robot->step(timeStep) != -1) {
305 aera_us += timeStep * 100;
307 if (aera_us == 1700*1000 + 65000) {
309 joint_1->setPosition((0 + position_offset) * position_factor);
310 joint_6->setPosition(M_PI/2);
311 joint_base_to_jaw_1->setPosition(jaw_open);
312 joint_base_to_jaw_2->setPosition(jaw_open);
313 sphere->resetPhysics();
314 cube->resetPhysics();
315 sphere->getField(
"rotation")->setSFRotation((
const double[]){0, 0, 1, 1.50014});
316 sphere->getField(
"translation")->setSFVec3f((
const double[]){-0.3, -0.025, 0.01});
317 cube->getField(
"rotation")->setSFRotation((
const double[]){0, 0, -1, 1.00257});
318 cube->getField(
"translation")->setSFVec3f((
const double[]){-0.257, -0.161, 0.01});
321 double h_position = get_position(joint_1_sensor->getValue());
324 if (aera_us > 0 && aera_us % 100000 == 0) {
325 const double* c_translation = cube->getField(
"translation")->getSFVec3f();
326 double c_offset_x = c_translation[0] - ned_x;
327 double c_offset_y = c_translation[1] - ned_y;
328 double c_position = get_position(atan2(c_offset_x, -c_offset_y));
330 const double* s_translation = sphere->getField(
"translation")->getSFVec3f();
331 double s_offset_x = s_translation[0] - ned_x;
332 double s_offset_y = s_translation[1] - ned_y;
333 double s_position = get_position(atan2(s_offset_x, -s_offset_y));
335 string holding =
"[]";
336 if (fabs(joint_base_to_jaw_1_sensor->getValue() - jaw_closed) < 0.0005 &&
337 fabs(joint_base_to_jaw_2_sensor->getValue() - jaw_closed)) {
339 if (c_position == h_position && c_translation[2] > 0.0103)
341 if (s_position == h_position && s_translation[2] > 0.0103)
346 unique_ptr<TCPMessage> msg = make_unique<TCPMessage>(
347 "h position " + to_string(h_position) +
348 "\nc position " + to_string(c_position) +
349 "\ns position " + to_string(s_position) +
350 "\nh holding " + holding);
351 sendMessage(aera_fd, std::move(msg));
352 receive_deadline = aera_us + 65000;
355 if (aera_us >= receive_deadline) {
357 while (receiveIsReady(aera_fd) == 0) {}
358 receive_deadline = MAXINT;
361 int ready = receiveIsReady(aera_fd);
363 cout <<
"select() == SOCKET_ERROR error" << endl;
366 if (command ==
"" && ready == 1) {
367 receive_deadline = MAXINT;
369 auto in_msg = receiveMessage(aera_fd);
374 vector<string> fields = split(*in_msg,
' ');
375 if (fields.size() == 2 && (fields[0] ==
"grab" || fields[0] ==
"release") && fields[1] ==
"h") {
378 else if (fields.size() == 3 && fields[0] ==
"move" && fields[1] ==
"h") {
380 double delta = std::stof(fields[2]);
383 else if (delta < -20)
385 target_h_position = h_position + delta;
388 cout <<
"ERROR: Unrecognized command " << *in_msg << endl;
392 int frame_start_us = (aera_us / 100000) * 100000;
393 command_time = frame_start_us + 65000;
394 if (command_time < aera_us)
396 command_time = aera_us;
400 if (command_time == aera_us) {
402 if (command ==
"grab") {
403 joint_2->setPosition(arm_down);
404 command =
"close_jaw_and_move_up";
405 command_time = command_time + 30000;
407 else if (command ==
"close_jaw_and_move_up") {
408 joint_base_to_jaw_1->setPosition(jaw_closed);
409 joint_base_to_jaw_2->setPosition(jaw_closed);
410 command =
"move_arm_up";
411 command_time = command_time + 4900;
413 else if (command ==
"move_arm_up") {
414 joint_2->setPosition(arm_up);
417 else if (command ==
"release") {
418 if (aera_us == 1500*1000 + 65000) {
420 joint_1->setPosition((-0.3 + position_offset) * position_factor);
421 joint_2->setPosition(0.73);
422 joint_6->setPosition(1);
425 joint_2->setPosition(arm_down);
426 command =
"open_jaw_and_move_up";
427 command_time = command_time + 30000;
429 else if (command ==
"open_jaw_and_move_up") {
430 joint_base_to_jaw_1->setPosition(jaw_open);
431 joint_base_to_jaw_2->setPosition(jaw_open);
432 command =
"move_arm_up";
433 command_time = command_time + 4900;
435 else if (command ==
"move") {
437 joint_1->setPosition((target_h_position + position_offset) * position_factor);