X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=server%2Factuator.c;h=af69c7f195f0940d64a5158ce34baf4adf976b7d;hb=01d1e74d5b4cefd75d9ff4a5a2a404a71a225712;hp=ff51732bb38861b227b05d1f3f284c5931a82d88;hpb=7284f69ded90441c34efb8f86a515ef399d3ccf3;p=matches%2FMCTX3420.git diff --git a/server/actuator.c b/server/actuator.c index ff51732..af69c7f 100644 --- a/server/actuator.c +++ b/server/actuator.c @@ -1,6 +1,6 @@ /** * @file actuator.c - * @purpose Implementation of Actuator related functionality + * @brief Implementation of Actuator related functionality */ #include "actuator.h" @@ -28,61 +28,76 @@ void Actuator_Init() } /** - * Start an Actuator - * @param a - The Actuator to start - * @param experiment_name - Prepended to DataFile filename + * Sets the actuator to the desired mode. No checks are + * done to see if setting to the desired mode will conflict with + * the current mode - the caller must guarantee this itself. + * @param a The actuator whose mode is to be changed + * @param mode The mode to be changed to + * @param arg An argument specific to the mode to be set. + * e.g for CONTROL_START it represents the experiment name. */ -void Actuator_Start(Actuator * a, const char * experiment_name) +void Actuator_SetMode(Actuator * a, ControlModes mode, void *arg) { - // Set filename - char filename[BUFSIZ]; - if (sprintf(filename, "%s_a%d", experiment_name, a->id) >= BUFSIZ) + switch (mode) { - Fatal("Experiment name \"%s\" too long (>%d)", experiment_name, BUFSIZ); + case CONTROL_START: + { + char filename[BUFSIZ]; + const char *experiment_name = (const char*) arg; + int ret; + + if (snprintf(filename, BUFSIZ, "%s_a%d", experiment_name, a->id) >= BUFSIZ) + { + Fatal("Experiment name \"%s\" too long (>%d)", experiment_name, BUFSIZ); + } + + Log(LOGDEBUG, "Actuator %d with DataFile \"%s\"", a->id, filename); + // Open DataFile + Data_Open(&(a->data_file), filename); + + a->activated = true; // Don't forget this + a->allow_actuation = true; + + a->control_changed = false; + + // Create the thread + ret = pthread_create(&(a->thread), NULL, Actuator_Loop, (void*)(a)); + if (ret != 0) + { + Fatal("Failed to create Actuator_Loop for Actuator %d", a->id); + } + } + break; + + case CONTROL_EMERGENCY: //TODO add proper case for emergency + case CONTROL_PAUSE: + a->allow_actuation = false; + break; + case CONTROL_RESUME: + a->allow_actuation = true; + break; + case CONTROL_STOP: + a->allow_actuation = false; + a->activated = false; + Actuator_SetControl(a, NULL); + pthread_join(a->thread, NULL); // Wait for thread to exit + Data_Close(&(a->data_file)); // Close DataFile + break; + default: + Fatal("Unknown control mode: %d", mode); } - - Log(LOGDEBUG, "Actuator %d with DataFile \"%s\"", a->id, filename); - // Open DataFile - Data_Open(&(a->data_file), filename); - - a->activated = true; // Don't forget this - - a->control_changed = false; - - // Create the thread - pthread_create(&(a->thread), NULL, Actuator_Loop, (void*)(a)); -} - -/** - * Stop an Actuator - * @param s - The Actuator to stop - */ -void Actuator_Stop(Actuator * a) -{ - // Stop - a->activated = false; - Actuator_SetControl(a, NULL); - pthread_join(a->thread, NULL); // Wait for thread to exit - Data_Close(&(a->data_file)); // Close DataFile - } /** - * Stop all Actuators + * Sets all actuators to the desired mode. + * @see Actuator_SetMode for more information. + * @param mode The mode to be changed to + * @param arg An argument specific to the mode to be set. */ -void Actuator_StopAll() +void Actuator_SetModeAll(ControlModes mode, void * arg) { - for (int i = 0; i < NUMACTUATORS; ++i) - Actuator_Stop(g_actuators+i); -} - -/** - * Start all Actuators - */ -void Actuator_StartAll(const char * experiment_name) -{ - for (int i = 0; i < NUMACTUATORS; ++i) - Actuator_Start(g_actuators+i, experiment_name); + for (int i = 0; i < NUMACTUATORS; i++) + Actuator_SetMode(&g_actuators[i], mode, arg); } /** @@ -106,6 +121,8 @@ void * Actuator_Loop(void * arg) pthread_mutex_unlock(&(a->mutex)); if (!a->activated) break; + else if (!a->allow_actuation) + continue; Actuator_SetValue(a, a->control.value); } @@ -143,7 +160,7 @@ void Actuator_SetValue(Actuator * a, double value) struct timeval t; gettimeofday(&t, NULL); - DataPoint d = {TIMEVAL_DIFF(t, g_options.start_time), value}; + DataPoint d = {TIMEVAL_DIFF(t, *Control_GetStartTime()), value}; //TODO: Set actuator switch (a->id) { @@ -211,7 +228,7 @@ void Actuator_Handler(FCGIContext * context, char * params) { struct timeval now; gettimeofday(&now, NULL); - double current_time = TIMEVAL_DIFF(now, g_options.start_time); + double current_time = TIMEVAL_DIFF(now, *Control_GetStartTime()); int id = 0; double set = 0; double start_time = 0;