@@ -55,11 +55,21 @@ const std::string CALIBRATION_CHECKSUM = "calib_12788084448423163542";
5555std::unique_ptr<UrDriver> g_my_driver;
5656std::unique_ptr<DashboardClient> g_my_dashboard;
5757
58+ std::condition_variable g_program_running_cv_;
59+ std::mutex g_program_running_mutex_;
60+ bool g_program_running;
61+
5862// We need a callback function to register. See UrDriver's parameters for details.
5963void handleRobotProgramState (bool program_running)
6064{
6165 // Print the text in green so we see it better
6266 std::cout << " \033 [1;32mProgram running: " << std::boolalpha << program_running << " \033 [0m\n " << std::endl;
67+ if (program_running)
68+ {
69+ std::lock_guard<std::mutex> lk (g_program_running_mutex_);
70+ g_program_running = program_running;
71+ g_program_running_cv_.notify_one ();
72+ }
6373}
6474
6575void sendFreedriveMessageOrDie (const control::FreedriveControlMessage freedrive_action)
@@ -72,6 +82,17 @@ void sendFreedriveMessageOrDie(const control::FreedriveControlMessage freedrive_
7282 }
7383}
7484
85+ bool waitForProgramRunning (int milliseconds = 100 )
86+ {
87+ std::unique_lock<std::mutex> lk (g_program_running_mutex_);
88+ if (g_program_running_cv_.wait_for (lk, std::chrono::milliseconds (milliseconds)) == std::cv_status::no_timeout ||
89+ g_program_running == true )
90+ {
91+ return true ;
92+ }
93+ return false ;
94+ }
95+
7596int main (int argc, char * argv[])
7697{
7798 urcl::setLogLevel (urcl::LogLevel::INFO);
@@ -130,7 +151,16 @@ int main(int argc, char* argv[])
130151 std::unique_ptr<ToolCommSetup> tool_comm_setup;
131152 const bool HEADLESS = true ;
132153 g_my_driver.reset (new UrDriver (robot_ip, SCRIPT_FILE, OUTPUT_RECIPE, INPUT_RECIPE, &handleRobotProgramState, HEADLESS,
133- std::move (tool_comm_setup), CALIBRATION_CHECKSUM));
154+ std::move (tool_comm_setup)));
155+
156+ if (!g_my_driver->checkCalibration (CALIBRATION_CHECKSUM))
157+ {
158+ URCL_LOG_ERROR (" Calibration checksum does not match actual robot." );
159+ URCL_LOG_ERROR (" Use the ur_calibration tool to extract the correct calibration from the robot and pass that into "
160+ " the description. See "
161+ " [https://github.com/UniversalRobots/Universal_Robots_ROS_Driver#extract-calibration-information] "
162+ " for details." );
163+ }
134164
135165 // Once RTDE communication is started, we have to make sure to read from the interface buffer, as
136166 // otherwise we will get pipeline overflows. Therefore, do this directly before starting your main
@@ -141,15 +171,37 @@ int main(int argc, char* argv[])
141171 std::chrono::duration<double > timeout (second_to_run);
142172 auto stopwatch_last = std::chrono::steady_clock::now ();
143173 auto stopwatch_now = stopwatch_last;
144- g_my_driver->writeKeepalive ();
174+ // Make sure that external control script is running
175+ if (!waitForProgramRunning ())
176+ {
177+ URCL_LOG_ERROR (" External Control script not running." );
178+ return 1 ;
179+ }
145180 // Task frame at the robot's base with limits being large enough to cover the whole workspace
146181 // Compliance in z axis and rotation around z axis
147- g_my_driver->startForceMode ({ 0 , 0 , 0 , 0 , 0 , 0 }, // Task frame at the robot's base
148- { 0 , 0 , 1 , 0 , 0 , 1 }, // Compliance in z axis and rotation around z axis
149- { 0 , 0 , 0 , 0 , 0 , 0 }, // do not apply any active wrench
150- 2 , // do not transform the force frame at all
151- { 0.1 , 0.1 , 1.5 , 3.14 , 3.14 , 0.5 }); // limits. See ScriptManual for
152- // details.
182+ bool success;
183+ if (g_my_driver->getVersion ().major < 5 )
184+ success = g_my_driver->startForceMode ({ 0 , 0 , 0 , 0 , 0 , 0 }, // Task frame at the robot's base
185+ { 0 , 0 , 1 , 0 , 0 , 1 }, // Compliance in z axis and rotation around z axis
186+ { 0 , 0 , 0 , 0 , 0 , 0 }, // do not apply any active wrench
187+ 2 , // do not transform the force frame at all
188+ { 0.1 , 0.1 , 1.5 , 3.14 , 3.14 , 0.5 }, // limits
189+ 0.025 ); // damping_factor. See ScriptManual for details.
190+ else
191+ {
192+ success = g_my_driver->startForceMode ({ 0 , 0 , 0 , 0 , 0 , 0 }, // Task frame at the robot's base
193+ { 0 , 0 , 1 , 0 , 0 , 1 }, // Compliance in z axis and rotation around z axis
194+ { 0 , 0 , 0 , 0 , 0 , 0 }, // do not apply any active wrench
195+ 2 , // do not transform the force frame at all
196+ { 0.1 , 0.1 , 1.5 , 3.14 , 3.14 , 0.5 }, // limits
197+ 0.025 , // damping_factor
198+ 0.8 ); // gain_scaling. See ScriptManual for details.
199+ }
200+ if (!success)
201+ {
202+ URCL_LOG_ERROR (" Failed to start force mode." );
203+ return 1 ;
204+ }
153205
154206 while (true )
155207 {
0 commit comments