3131#include < cstdio>
3232#include < mutex>
3333
34- #include " ur_client_library/control/script_command_interface.h"
3534#include " ur_client_library/example_robot_wrapper.h"
3635#include " ur_client_library/types.h"
3736
4039# include < conio.h>
4140char getChar ()
4241{
43- return _getch (); // Windows-specific
42+ char ch = ' \0 ' ;
43+ std::chrono::timepoint<std::chrono::steady_clock> start_time = std::chrono::steady_clock::now ();
44+ while (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now () - start_time).count () < 1 )
45+ {
46+ if (_kbhit ())
47+ {
48+ ch = _getch ();
49+ }
50+ }
51+ return ch;
4452}
4553#else
4654# include < termios.h>
4755# include < unistd.h>
56+ # include < fcntl.h>
57+ # include < sys/select.h>
4858char getChar ()
4959{
5060 termios oldt, newt;
@@ -53,8 +63,31 @@ char getChar()
5363 newt = oldt;
5464 newt.c_lflag &= ~(ICANON | ECHO);
5565 tcsetattr (STDIN_FILENO, TCSANOW, &newt);
56- std::ignore = read (STDIN_FILENO, &ch, 1 );
66+
67+ int oldf = fcntl (STDIN_FILENO, F_GETFL, 0 );
68+ fcntl (STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
69+
70+ fd_set set;
71+ FD_ZERO (&set);
72+ FD_SET (STDIN_FILENO, &set);
73+
74+ struct timeval timeout;
75+ timeout.tv_sec = 1 ;
76+ timeout.tv_usec = 0 ;
77+
78+ // Wait for input with timeout
79+ int rv = select (STDIN_FILENO + 1 , &set, NULL , NULL , &timeout);
80+ if (rv > 0 )
81+ {
82+ std::ignore = read (STDIN_FILENO, &ch, 1 );
83+ }
84+ else
85+ {
86+ ch = ' \0 ' ; // No input
87+ }
88+
5789 tcsetattr (STDIN_FILENO, TCSANOW, &oldt);
90+ fcntl (STDIN_FILENO, F_SETFL, oldf);
5891 return ch;
5992}
6093#endif
@@ -85,6 +118,11 @@ void ftInputTui()
85118
86119 switch (ch)
87120 {
121+ case ' \0 ' :
122+ {
123+ // No input
124+ continue ;
125+ }
88126 case ' x' :
89127 {
90128 local_ft_vec[0 ] += 10 ;
@@ -164,6 +202,7 @@ void ftInputTui()
164202 }
165203 std::cout << " Artificial FT input: " << local_ft_vec << std::endl;
166204 }
205+ std::cout << " FT input TUI thread finished." << std::endl;
167206}
168207
169208void rtdeWorker (const int second_to_run)
@@ -172,10 +211,7 @@ void rtdeWorker(const int second_to_run)
172211
173212 vector6d_t actual_tcp_force;
174213 auto start_time = std::chrono::steady_clock::now ();
175- while (g_RUNNING &&
176- (second_to_run <= 0 ||
177- std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now () - start_time).count () <
178- second_to_run))
214+ while (g_RUNNING)
179215 {
180216 urcl::vector6d_t local_ft_vec = g_FT_VEC;
181217 std::unique_ptr<rtde_interface::DataPackage> data_pkg = g_my_robot->getUrDriver ()->getDataPackage ();
@@ -210,6 +246,12 @@ void rtdeWorker(const int second_to_run)
210246 std::cout << " \033 [1;31mSending RTDE data failed." << " \033 [0m\n " << std::endl;
211247 return ;
212248 }
249+ if (second_to_run > 0 )
250+ {
251+ g_RUNNING =
252+ std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now () - start_time).count () <
253+ second_to_run;
254+ }
213255 }
214256}
215257
@@ -246,8 +288,10 @@ int main(int argc, char* argv[])
246288 ftInputTui ();
247289
248290 g_RUNNING = false ;
249- g_my_robot->getUrDriver ()->stopControl ();
250- rtde_thread.join ();
291+ if (rtde_thread.joinable ())
292+ {
293+ rtde_thread.join ();
294+ }
251295
252296 return 0 ;
253297}
0 commit comments