41 using namespace std::chrono_literals;
45 DashboardClient::DashboardClient(
const std::string& host) : host_(host), port_(DASHBOARD_SERVER_PORT)
51 str.erase(str.find_last_not_of(chars) + 1);
58 URCL_LOG_ERROR(
"%s",
"Socket is already connected. Refusing to reconnect.");
71 TCPSocket::setReceiveTimeout(tv);
74 if (TCPSocket::setup(
host_,
port_, max_num_tries, reconnection_time))
86 URCL_LOG_WARN(
"Did not receive dashboard bootup message although connection was established. This should not "
87 "happen, please contact the package maintainers. Retrying anyway...");
92 TCPSocket::setReceiveTimeout(configured_tv);
108 size_t len = text.size();
109 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(text.c_str());
111 return TCPSocket::write(data, len, written);
116 std::stringstream result;
118 size_t read_chars = 99;
119 while (read_chars > 0)
121 if (!TCPSocket::read((uint8_t*)&character, 1, read_chars))
124 throw TimeoutException(
"Did not receive answer from dashboard server in time. Disconnecting from dashboard "
129 if (character ==
'\n')
139 std::string command = text;
140 if (text.back() !=
'\n')
142 command = text +
"\n";
144 std::string response =
"ERROR";
152 throw UrException(
"Failed to send request to dashboard server. Are you connected to the Dashboard Server?");
164 bool ret = std::regex_match(response, std::regex(expected));
167 URCL_LOG_WARN(
"Expected: \"%s\", but received: \"%s\"", expected.c_str(), response.c_str());
176 bool ret = std::regex_match(response, std::regex(expected));
179 throw UrException(
"Expected: " + expected +
", but received: " + response);
185 const std::chrono::duration<double> timeout)
187 const std::chrono::duration<double> wait_period = 100ms;
189 std::chrono::duration<double> time_done(0);
190 std::string response;
192 while (time_done < timeout)
198 if (std::regex_match(response, std::regex(expected)))
204 std::this_thread::sleep_for(wait_period);
205 time_done += wait_period;
208 URCL_LOG_WARN(
"Did not got the expected \"%s\" response within the timeout. Last response was: \"%s\"",
209 expected.c_str(), response.c_str());
214 const std::string& waitRequest,
const std::string& waitExpectedResponse,
215 const std::chrono::duration<double> timeout,
216 const std::chrono::duration<double> retry_period)
218 std::chrono::duration<double> time_done(0);
221 sendRequest(requestCommand, requestExpectedResponse);
222 time_done += retry_period;
224 if (
waitForReply(waitRequest, waitExpectedResponse, retry_period))
228 }
while (time_done < timeout);
241 return retryCommand(
"power on",
"Powering on",
"robotmode",
"Robotmode: IDLE", timeout);
257 return sendRequest(
"load " + program_file_name +
"",
"(?:Loading program: ).*(?:" + program_file_name +
").*") &&
258 waitForReply(
"programState",
"STOPPED " + std::filesystem::path{ program_file_name }.filename().
string());
264 return sendRequest(
"load installation " + installation_file_name,
265 "(?:Loading installation: ).*(?:" + installation_file_name +
").*");
289 return sendRequest(
"close popup",
"closing popup");
295 return sendRequest(
"close safety popup",
"closing safety popup");
301 return sendRequest(
"restart safety",
"Restarting safety") &&
waitForReply(
"robotmode",
"Robotmode: POWER_OFF");
307 return sendRequest(
"unlock protective stop",
"Protective stop releasing");
326 return std::regex_match(response, std::regex(
"Program running: true"));
332 return sendRequest(
"isProgramSaved",
"(?:true ).*");
339 bool ret = std::regex_match(response, std::regex(
"true"));
346 return sendRequest(
"popup " + popup_text,
"showing popup");
352 return sendRequest(
"addToLog " + log_text,
"Added log message");
357 std::string expected =
"(?:URSoftware ).*";
359 std::string version_string = polyscope_version.substr(polyscope_version.find(
" ") + 1,
360 polyscope_version.find(
" (") - polyscope_version.find(
" ") - 1);
362 return std::regex_match(polyscope_version, std::regex(expected));
368 std::string expected =
"(?:UR).*";
370 return std::regex_match(robot_model, std::regex(expected));
376 std::string expected =
"(?:20).*";
378 return std::regex_match(serial_number, std::regex(expected));
384 std::string expected =
"(?:Robotmode: ).*";
386 return std::regex_match(robot_mode, std::regex(expected));
392 std::string expected =
"(?:Loaded program: ).*";
394 return std::regex_match(loaded_program, std::regex(expected));
400 std::string expected =
"(?:Safetymode: ).*";
402 return std::regex_match(safety_mode, std::regex(expected));
408 std::string expected =
"(?:Safetystatus: ).*";
410 return std::regex_match(safety_status, std::regex(expected));
416 std::string expected =
"(?:).*";
418 return !std::regex_match(program_state, std::regex(
"(?:could not understand).*"));
424 std::string expected =
"(?:).*";
426 return !std::regex_match(operational_mode, std::regex(
"(?:could not understand).*"));
432 return sendRequest(
"set operational mode " + operational_mode,
433 "(?:Operational mode ).*(?:" + operational_mode +
").*");
439 return sendRequest(
"clear operational mode",
"(?:No longer controlling the operational mode. ).*");
445 return sendRequest(
"setUserRole " + user_role,
"(?:Setting user role: ).*");
451 std::string expected =
"(?:).*";
453 return !std::regex_match(user_role, std::regex(
"(?:could not understand).*"));
463 TCPSocket::setReceiveTimeout(tv);
464 bool ret =
sendRequest(
"generate flight report " + report_type,
"(?:Flight Report generated with id:).*");
465 TCPSocket::setReceiveTimeout(configured_tv);
476 TCPSocket::setReceiveTimeout(tv);
477 bool ret =
sendRequest(
"generate support file " + dir_path,
"(?:Completed successfully:).*");
478 TCPSocket::setReceiveTimeout(configured_tv);
485 return sendRequest(
"saveLog",
"Log saved to disk");
489 const std::string& required_call)
493 std::stringstream ss;
494 ss <<
"The dasboard call '" << required_call
495 <<
"' is only available on e-series robots, but you seem to be running version " <<
polyscope_version_;
501 std::stringstream ss;
502 ss <<
"The dasboard call '" << required_call
503 <<
"' is only available on pre-e-series robots (5.x.y), but you seem to be running version "
512 std::stringstream ss;
513 ss <<
"Polyscope version " <<
polyscope_version_ <<
" isn't recent enough to use dashboard call '" << required_call