DashboardClient
For CB3 robots and PolyScope 5 the DashboardClient wraps the calls on the Dashboard server
directly into C++ functions.
For PolyScope X the so-called Robot API released with PolyScope X 10.11.0 is used. It offers a subset of the Dashboard Server from previous software versions.
After connecting to the dashboard server by using the connect() function, dashboard calls can
be done using the command...() functions such as commandCloseSafetyPopup(). These functions
are blocking and will wait for the necessary action being done. This can involve querying another
call to the dashboard server until the action is done. For example, commandPowerOn() will block
until the robot reports “Robotmode: RUNNING” or the given timeout is reached.
The return value of those functions indicate whether or not the call was successful. If you want to
get the call’s full response, use the command...WithResponse() calls, instead. They will return
a response struct
struct DashboardResponse
{
bool ok = false;
std::string message;
std::unordered_map<std::string, std::variant<std::string, int, bool>> data;
};
The data dictionary of that response struct is populated by each command individually. See the
commands’ docstrings for details.
The dashboard_example.cpp shows how to use the dashboard client:
80 auto my_dashboard = std::make_unique<DashboardClient>(robot_ip, policy);
81 if (!my_dashboard->connect())
82 {
83 URCL_LOG_ERROR("Could not connect to dashboard");
84 return 1;
85 }
86
87 // Bring the robot to a defined state being powered off.
88 if (version_information->major < 10)
89 {
90 if (!my_dashboard->commandPowerOff())
91 {
92 URCL_LOG_ERROR("Could not send power off");
93 return 1;
94 }
95 // Get the PolyScope version
96 std::string version;
97 my_dashboard->commandPolyscopeVersion(version);
98 URCL_LOG_INFO(version.c_str());
99
100 my_dashboard->commandCloseSafetyPopup();
101 }
102 else
103 {
104 // We're ignoring errors here since
105 // powering off an already powered off robot will return an error.
106 my_dashboard->commandPowerOff();
107 }
108
109 // Power it on
110 if (!my_dashboard->commandPowerOn())
111 {
112 URCL_LOG_ERROR("Could not send Power on command");
113 return 1;
114 }
115
116 // Release the brakes
117 if (!my_dashboard->commandBrakeRelease())
118 {
119 URCL_LOG_ERROR("Could not send BrakeRelease command");
120 return 1;
121 }
122
123 // Load existing program
124 std::string program_file_name_to_be_loaded("wait_program.urp");
125 if (version_information->major >= 10)
126 {
127 // For PolyScope X, the program doesn't have an ending
128 program_file_name_to_be_loaded = "wait_program";
129 }
130 if (!my_dashboard->commandLoadProgram(program_file_name_to_be_loaded))
131 {
132 URCL_LOG_ERROR("Could not load %s program", program_file_name_to_be_loaded.c_str());
133 return 1;
134 }
135
136 std::this_thread::sleep_for(std::chrono::seconds(1));
137
138 // Play loaded program
139 if (!my_dashboard->commandPlay())
140 {
141 URCL_LOG_ERROR("Could not play program");
142 return 1;
143 }
144
145 // Pause running program
146 if (!my_dashboard->commandPause())
147 {
148 URCL_LOG_ERROR("Could not pause program");
149 return 1;
150 }
151
152 // Continue
153 if (version_information->major >= 10)
154 {
155 // For PolyScope X, the command is called "resume"
156 if (!my_dashboard->commandResume())
157 {
158 URCL_LOG_ERROR("Could not resume program");
159 return 1;
160 }
161 }
162 else
163 {
164 // For e-Series, the command is called "play"
165 if (!my_dashboard->commandPlay())
166 {
167 URCL_LOG_ERROR("Could not resume program");
168 return 1;
169 }
170 }
171
172 // Stop program
173 if (!my_dashboard->commandStop())
174 {
175 URCL_LOG_ERROR("Could not stop program");
176 return 1;
177 }
178
179 // Power it off
180 if (!my_dashboard->commandPowerOff())
181 {
182 URCL_LOG_ERROR("Could not send Power off command");
183 return 1;
184 }
185
186 if (version_information->major < 10)
187 {
188 // Flush the log
189 if (!my_dashboard->commandSaveLog())
190 {
191 URCL_LOG_ERROR("Could not send the save log command");
192 return 1;
193 }
194
195 // Make a raw request and save the response
196 std::string program_state = my_dashboard->sendAndReceive("programState");
197 URCL_LOG_INFO("Program state: %s", program_state.c_str());
198
199 // The response can be checked with a regular expression
200 bool success = my_dashboard->sendRequest("power off", "Powering off");
201 URCL_LOG_INFO("Power off command success: %d", success);
202 }
203
204 return 0;
CB 3 and PolyScope 5 only
All commands are blocking and will wait for the necessary action being done. The dashboard server’s
response will be compared with an expected response. For example, when calling
commandPowerOn(timeout), it is checked that the dashboard server is answering "Powering on" and
then it is queried until the robot reports "Robotmode: IDLE" or until the timeout is reached.
The example contains more commands that follow the same scheme.
If you want to send a query / command to the dashboard server and only want to receive the
response, you can use the sendAndReceive() function:
195 // Make a raw request and save the response
196 std::string program_state = my_dashboard->sendAndReceive("programState");
197 URCL_LOG_INFO("Program state: %s", program_state.c_str());
For checking the response against an expected regular expression use sendRequest():
199 // The response can be checked with a regular expression
200 bool success = my_dashboard->sendRequest("power off", "Powering off");
201 URCL_LOG_INFO("Power off command success: %d", success);
PolyScope X only
Internally, the dashboard client makes calls against a RESTful (Representational State Transfer) API. Hence, all responses contain a JSON-encoded string of the received answer. For example, an answer to a pause request could be
{"state":"PAUSED","message":"Program state changed: PAUSED","details":"Pause successful"}