*
*/
+#define DEBUG
+
#include <sys/time.h>
#include <time.h>
#include "trgen.h"
p_perpen: 10 // dy gain
};
-//#define MOTION_PERIOD_NS (500/*ms*/*1000*1000)
#define MOTION_PERIOD_NS (50/*ms*/*1000*1000)
-#define SIG_TIMER (SIGRTMIN+0)
-#define SIG_NEWDATA (SIGRTMIN+1)
+#define SIG_DO_CONTROL_NOW (SIGRTMIN+1)
// Global varibles
pthread_t thr_trajectory_follower;
// only if the trajectory is already prepared
if (switch_to_trajectory != NULL && t >= switch_time) {
pthread_mutex_lock(&switch_to_trajectory_lock);
-#ifdef NEVER // DEBUG
+#ifdef DEBUG
printf("SWITCHING to new trajectory\n");
- fflush(stdout);
#endif
go(switch_to_trajectory);
// nothing prepared now
est_pos.phi = ref_pos.phi;
#endif
-#ifdef NEVER //DEBUG
+#ifdef DEBUG
printf("rx=%5.02f ry=%5.02f, rphi=%4.0f v=%-4.02f omega=%-4.02f, time=%lf \r", ref_pos.x, ref_pos.y, ref_pos.phi/M_PI*180, ref_pos.v, ref_pos.omega, t);
fflush(stdout);
#endif
pthread_mutex_unlock(&actual_trajectory_lock);
}
+void dummy_handler(int)
+{
+}
+
/**
* A thread running the controller.
*
*/
void *thread_trajectory_follower(void *arg)
{
- struct itimerspec ts;
- sigset_t sigset;
- struct sigevent sigevent;
- timer_t timer;
-
- ts.it_value.tv_sec = 0;
- ts.it_value.tv_nsec = MOTION_PERIOD_NS;
- ts.it_interval.tv_sec = 0;
- ts.it_interval.tv_nsec = MOTION_PERIOD_NS;
-
- sigemptyset(&sigset);
- sigaddset(&sigset, SIG_TIMER);
- sigaddset(&sigset, SIG_NEWDATA);
-
- pthread_sigmask(SIG_BLOCK, &sigset, (sigset_t*) NULL);
-
- sigevent.sigev_notify = SIGEV_SIGNAL;
- sigevent.sigev_signo = SIG_TIMER;
- sigevent.sigev_value.sival_int = 0;
-
- if (timer_create(CLOCK_REALTIME, &sigevent, &timer) < 0) {
- perror("move: timer_create");
- return NULL;
- }
+ struct timespec next;
+ int ret;
- if (timer_settime(timer, 0, &ts, NULL) < 0) {
- perror("move: timer_settimer");
- return NULL;
- }
+ // Register an empty handler, so that clock_nanosleep bellow
+ // is interrupted by this signal.
+ signal(SIG_DO_CONTROL_NOW, dummy_handler);
+ clock_gettime(CLOCK_MONOTONIC, &next);
while (1) {
- int sig;
- // Wait for start of new period or new data
- sigwait(&sigset, &sig);
- //DBG("signal %d ", sig - SIGRTMIN);
+ ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);
+
do_control();
+
+ next.tv_nsec += MOTION_PERIOD_NS;
+ if (next.tv_nsec >= 1000000000) {
+ next.tv_sec++;
+ next.tv_nsec -= 1000000000;
+ }
}
}
void stop()
{
delete_actual_trajectory();
- pthread_kill(thr_trajectory_follower, SIG_NEWDATA);
+
+ // Interrupt clock_nanosleep in thread_trajectory_follower(),
+ // so we stop immediately.
+ pthread_kill(thr_trajectory_follower, SIG_DO_CONTROL_NOW);
}
/**