@ -0,0 +1,42 @@ | |||
cmake_minimum_required(VERSION 2.8.11) | |||
project(ROSACE_Posix C) | |||
if (NOT CMAKE_BUILD_TYPE) | |||
message(STATUS "No build type selected, default to Debug") | |||
set(CMAKE_BUILD_TYPE "Debug") | |||
endif(NOT CMAKE_BUILD_TYPE) | |||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror") | |||
# Find external libraries | |||
find_library(MATH_LIBRARY m) | |||
find_package(Threads REQUIRED) | |||
add_executable(rosace_posix | |||
rosace.c | |||
io.c io.h | |||
assemblage_includes.c assemblage_includes.h | |||
assemblage.c assemblage.h | |||
threads.c threads.h | |||
types.h) | |||
add_executable(rosace_posix-float | |||
rosace.c | |||
io.c io.h | |||
assemblage_includes.c assemblage_includes.h | |||
assemblage.c assemblage.h | |||
threads.c threads.h | |||
types.h) | |||
set_target_properties(rosace_posix-float | |||
PROPERTIES COMPILE_FLAGS -DUSE_FLOAT) | |||
if(THREADS_HAVE_PTHREAD_ARG) | |||
target_compile_options(PUBLIC rosace_posix "-pthread") | |||
target_compile_options(PUBLIC rosace_posix-float "-pthread") | |||
endif() | |||
if(CMAKE_THREAD_LIBS_INIT) | |||
target_link_libraries(rosace_posix "${CMAKE_THREAD_LIBS_INIT}") | |||
target_link_libraries(rosace_posix-float "${CMAKE_THREAD_LIBS_INIT}") | |||
endif() | |||
target_link_libraries(rosace_posix ${MATH_LIBRARY}) | |||
target_link_libraries(rosace_posix-float ${MATH_LIBRARY}) |
@ -0,0 +1,22 @@ | |||
CC=gcc | |||
CFLAGS=-Wall | |||
LIBS=-pthread -lm | |||
OBJS = assemblage_includes.o io.o threads.o | |||
TARGET=rosace | |||
all: $(TARGET) | |||
%.o: %.c | |||
$(CC) $(CFLAGS) -c $< -o $@ | |||
$(TARGET): $(OBJS) | |||
$(CC) $(CFLAGS) $(OBJS) -o $@ $(LIBS) | |||
clean: | |||
rm -f $(OBJS) $(TARGET) | |||
@ -0,0 +1,12 @@ | |||
Hand-written C POSIX implementation of ROSACE Case Study. | |||
This implementation of ROSACE is autonomous and should | |||
execute properly on any POSIX compliant system with pthread support. | |||
Description: | |||
The implementation is made of 5 threads running at various frequencies. | |||
The frequencies are explained in the code itself. | |||
Synchronisation between threads is done using pthread_barrier primitives. | |||
TBC... | |||
@ -0,0 +1,431 @@ | |||
#include <stdlib.h> | |||
#include <stdbool.h> | |||
#include "assemblage.h" | |||
#include "assemblage_includes.h" | |||
double aircraft_dynamics495_Va_Va_filter_100449_Va[2]; | |||
double Vz_control_50483_delta_e_c_elevator489_delta_e_c; | |||
double Va_filter_100449_Va_f_Va_control_50474_Va_f[2]; | |||
double Vz_filter_100452_Vz_f_Va_control_50474_Vz_f[2]; | |||
double q_filter_100455_q_f_Va_control_50474_q_f[2]; | |||
double Va_c_Va_control_50474_Va_c; | |||
double h_filter_100446_h_f_altitude_hold_50464_h_f[2]; | |||
double h_c_altitude_hold_50464_h_c; | |||
double Va_control_50474_delta_th_c_delta_th_c; | |||
double aircraft_dynamics495_az_az_filter_100458_az[2]; | |||
double aircraft_dynamics495_Vz_Vz_filter_100452_Vz[2]; | |||
double aircraft_dynamics495_q_q_filter_100455_q[2]; | |||
double elevator489_delta_e_aircraft_dynamics495_delta_e[3]={0.0120096156525, 0.0120096156525, 0.0120096156525}; | |||
double engine486_T_aircraft_dynamics495_T[3]={41813.9211946, 41813.9211946, 41813.9211946}; | |||
double aircraft_dynamics495_h_h_filter_100446_h[2]; | |||
double Va_control_50474_delta_th_c_engine486_delta_th_c; | |||
double Vz_filter_100452_Vz_f_Vz_control_50483_Vz_f[2]; | |||
double altitude_hold_50464_Vz_c_Vz_control_50483_Vz_c; | |||
double q_filter_100455_q_f_Vz_control_50483_q_f[2]; | |||
double az_filter_100458_az_f_Vz_control_50483_az_f[2]; | |||
double Vz_control_50483_delta_e_c_delta_e_c; | |||
int Va_filter_100449_fun(void* args) | |||
{ | |||
double Va_f; | |||
static int Va_rcell=0; | |||
const struct write_proto_t Va_f_Va_control_50474_Va_f_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int Va_f_Va_control_50474_Va_f_wcell=0; | |||
static int instance=0; | |||
Va_f=Va_filter_100(aircraft_dynamics495_Va_Va_filter_100449_Va[Va_rcell]); | |||
Va_rcell=(Va_rcell+1)%2; | |||
if(must_write(Va_f_Va_control_50474_Va_f_write,instance)) { | |||
Va_filter_100449_Va_f_Va_control_50474_Va_f[Va_f_Va_control_50474_Va_f_wcell]=Va_f; | |||
Va_f_Va_control_50474_Va_f_wcell=(Va_f_Va_control_50474_Va_f_wcell+1)%2; | |||
} | |||
instance++; | |||
return 0; | |||
} | |||
int elevator489_fun(void* args) | |||
{ | |||
double delta_e; | |||
static int delta_e_aircraft_dynamics495_delta_e_wcell=1; | |||
static int instance=0; | |||
delta_e=elevator(Vz_control_50483_delta_e_c_elevator489_delta_e_c); | |||
elevator489_delta_e_aircraft_dynamics495_delta_e[delta_e_aircraft_dynamics495_delta_e_wcell]=delta_e; | |||
delta_e_aircraft_dynamics495_delta_e_wcell=(delta_e_aircraft_dynamics495_delta_e_wcell+1)%3; | |||
instance++; | |||
return 0; | |||
} | |||
int Va_control_50474_fun(void* args) | |||
{ | |||
double delta_th_c; | |||
static int Va_f_rcell=0; | |||
static int Vz_f_rcell=0; | |||
static int q_f_rcell=0; | |||
static int instance=0; | |||
delta_th_c=Va_control_50(Va_filter_100449_Va_f_Va_control_50474_Va_f[Va_f_rcell], | |||
Vz_filter_100452_Vz_f_Va_control_50474_Vz_f[Vz_f_rcell],q_filter_100455_q_f_Va_control_50474_q_f[q_f_rcell], | |||
Va_c_Va_control_50474_Va_c); | |||
Va_f_rcell=(Va_f_rcell+1)%2; | |||
Vz_f_rcell=(Vz_f_rcell+1)%2; | |||
q_f_rcell=(q_f_rcell+1)%2; | |||
Va_control_50474_delta_th_c_engine486_delta_th_c=delta_th_c; | |||
Va_control_50474_delta_th_c_delta_th_c=delta_th_c; | |||
instance++; | |||
return 0; | |||
} | |||
int Va_c0_fun(void* args) | |||
{ | |||
double Va_c; | |||
static int instance=0; | |||
Va_c=input_Va_c(); | |||
Va_c_Va_control_50474_Va_c=Va_c; | |||
instance++; | |||
return 0; | |||
} | |||
int altitude_hold_50464_fun(void* args) | |||
{ | |||
double Vz_c; | |||
static int h_f_rcell=0; | |||
static int instance=0; | |||
Vz_c=altitude_hold_50(h_filter_100446_h_f_altitude_hold_50464_h_f[h_f_rcell], | |||
h_c_altitude_hold_50464_h_c); | |||
h_f_rcell=(h_f_rcell+1)%2; | |||
altitude_hold_50464_Vz_c_Vz_control_50483_Vz_c=Vz_c; | |||
instance++; | |||
return 0; | |||
} | |||
int delta_th_c0_fun(void* args) | |||
{ | |||
static int instance=0; | |||
output_delta_th_c(Va_control_50474_delta_th_c_delta_th_c); | |||
instance++; | |||
return 0; | |||
} | |||
int az_filter_100458_fun(void* args) | |||
{ | |||
double az_f; | |||
static int az_rcell=0; | |||
const struct write_proto_t az_f_Vz_control_50483_az_f_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int az_f_Vz_control_50483_az_f_wcell=0; | |||
static int instance=0; | |||
az_f=az_filter_100(aircraft_dynamics495_az_az_filter_100458_az[az_rcell]); | |||
az_rcell=(az_rcell+1)%2; | |||
if(must_write(az_f_Vz_control_50483_az_f_write,instance)) { | |||
az_filter_100458_az_f_Vz_control_50483_az_f[az_f_Vz_control_50483_az_f_wcell]=az_f; | |||
az_f_Vz_control_50483_az_f_wcell=(az_f_Vz_control_50483_az_f_wcell+1)%2; | |||
} | |||
instance++; | |||
return 0; | |||
} | |||
int Vz_filter_100452_fun(void* args) | |||
{ | |||
double Vz_f; | |||
static int Vz_rcell=0; | |||
const struct write_proto_t Vz_f_Va_control_50474_Vz_f_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int Vz_f_Va_control_50474_Vz_f_wcell=0; | |||
const struct write_proto_t Vz_f_Vz_control_50483_Vz_f_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int Vz_f_Vz_control_50483_Vz_f_wcell=0; | |||
static int instance=0; | |||
Vz_f=Vz_filter_100(aircraft_dynamics495_Vz_Vz_filter_100452_Vz[Vz_rcell]); | |||
Vz_rcell=(Vz_rcell+1)%2; | |||
if(must_write(Vz_f_Va_control_50474_Vz_f_write,instance)) { | |||
Vz_filter_100452_Vz_f_Va_control_50474_Vz_f[Vz_f_Va_control_50474_Vz_f_wcell]=Vz_f; | |||
Vz_f_Va_control_50474_Vz_f_wcell=(Vz_f_Va_control_50474_Vz_f_wcell+1)%2; | |||
} | |||
if(must_write(Vz_f_Vz_control_50483_Vz_f_write,instance)) { | |||
Vz_filter_100452_Vz_f_Vz_control_50483_Vz_f[Vz_f_Vz_control_50483_Vz_f_wcell]=Vz_f; | |||
Vz_f_Vz_control_50483_Vz_f_wcell=(Vz_f_Vz_control_50483_Vz_f_wcell+1)%2; | |||
} | |||
instance++; | |||
return 0; | |||
} | |||
int q_filter_100455_fun(void* args) | |||
{ | |||
double q_f; | |||
static int q_rcell=0; | |||
const struct write_proto_t q_f_Va_control_50474_q_f_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int q_f_Va_control_50474_q_f_wcell=0; | |||
const struct write_proto_t q_f_Vz_control_50483_q_f_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int q_f_Vz_control_50483_q_f_wcell=0; | |||
static int instance=0; | |||
q_f=q_filter_100(aircraft_dynamics495_q_q_filter_100455_q[q_rcell]); | |||
q_rcell=(q_rcell+1)%2; | |||
if(must_write(q_f_Va_control_50474_q_f_write,instance)) { | |||
q_filter_100455_q_f_Va_control_50474_q_f[q_f_Va_control_50474_q_f_wcell]=q_f; | |||
q_f_Va_control_50474_q_f_wcell=(q_f_Va_control_50474_q_f_wcell+1)%2; | |||
} | |||
if(must_write(q_f_Vz_control_50483_q_f_write,instance)) { | |||
q_filter_100455_q_f_Vz_control_50483_q_f[q_f_Vz_control_50483_q_f_wcell]=q_f; | |||
q_f_Vz_control_50483_q_f_wcell=(q_f_Vz_control_50483_q_f_wcell+1)%2; | |||
} | |||
instance++; | |||
return 0; | |||
} | |||
int aircraft_dynamics495_fun(void* args) | |||
{ | |||
struct aircraft_dynamics_outs_t aircraft_dynamics495_fun_outs; | |||
static int delta_e_rcell=0; | |||
static int T_rcell=0; | |||
const struct write_proto_t Va_Va_filter_100449_Va_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int Va_Va_filter_100449_Va_wcell=0; | |||
const struct write_proto_t Vz_Vz_filter_100452_Vz_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int Vz_Vz_filter_100452_Vz_wcell=0; | |||
const struct write_proto_t q_q_filter_100455_q_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int q_q_filter_100455_q_wcell=0; | |||
const struct write_proto_t az_az_filter_100458_az_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int az_az_filter_100458_az_wcell=0; | |||
const struct write_proto_t h_h_filter_100446_h_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int h_h_filter_100446_h_wcell=0; | |||
static int instance=0; | |||
aircraft_dynamics(elevator489_delta_e_aircraft_dynamics495_delta_e[delta_e_rcell], | |||
engine486_T_aircraft_dynamics495_T[T_rcell],&aircraft_dynamics495_fun_outs); | |||
delta_e_rcell=(delta_e_rcell+1)%3; | |||
T_rcell=(T_rcell+1)%3; | |||
if(must_write(Va_Va_filter_100449_Va_write,instance)) { | |||
aircraft_dynamics495_Va_Va_filter_100449_Va[Va_Va_filter_100449_Va_wcell]=aircraft_dynamics495_fun_outs.Va; | |||
Va_Va_filter_100449_Va_wcell=(Va_Va_filter_100449_Va_wcell+1)%2; | |||
} | |||
if(must_write(Vz_Vz_filter_100452_Vz_write,instance)) { | |||
aircraft_dynamics495_Vz_Vz_filter_100452_Vz[Vz_Vz_filter_100452_Vz_wcell]=aircraft_dynamics495_fun_outs.Vz; | |||
Vz_Vz_filter_100452_Vz_wcell=(Vz_Vz_filter_100452_Vz_wcell+1)%2; | |||
} | |||
if(must_write(q_q_filter_100455_q_write,instance)) { | |||
aircraft_dynamics495_q_q_filter_100455_q[q_q_filter_100455_q_wcell]=aircraft_dynamics495_fun_outs.q; | |||
q_q_filter_100455_q_wcell=(q_q_filter_100455_q_wcell+1)%2; | |||
} | |||
if(must_write(az_az_filter_100458_az_write,instance)) { | |||
aircraft_dynamics495_az_az_filter_100458_az[az_az_filter_100458_az_wcell]=aircraft_dynamics495_fun_outs.az; | |||
az_az_filter_100458_az_wcell=(az_az_filter_100458_az_wcell+1)%2; | |||
} | |||
if(must_write(h_h_filter_100446_h_write,instance)) { | |||
aircraft_dynamics495_h_h_filter_100446_h[h_h_filter_100446_h_wcell]=aircraft_dynamics495_fun_outs.h; | |||
h_h_filter_100446_h_wcell=(h_h_filter_100446_h_wcell+1)%2; | |||
} | |||
instance++; | |||
return 0; | |||
} | |||
int h_filter_100446_fun(void* args) | |||
{ | |||
double h_f; | |||
static int h_rcell=0; | |||
const struct write_proto_t h_f_altitude_hold_50464_h_f_write = | |||
{ NULL, 0, (int []){ true , false }, 2 }; | |||
static int h_f_altitude_hold_50464_h_f_wcell=0; | |||
static int instance=0; | |||
h_f=h_filter_100(aircraft_dynamics495_h_h_filter_100446_h[h_rcell]); | |||
h_rcell=(h_rcell+1)%2; | |||
if(must_write(h_f_altitude_hold_50464_h_f_write,instance)) { | |||
h_filter_100446_h_f_altitude_hold_50464_h_f[h_f_altitude_hold_50464_h_f_wcell]=h_f; | |||
h_f_altitude_hold_50464_h_f_wcell=(h_f_altitude_hold_50464_h_f_wcell+1)%2; | |||
} | |||
instance++; | |||
return 0; | |||
} | |||
int engine486_fun(void* args) | |||
{ | |||
double T; | |||
static int T_aircraft_dynamics495_T_wcell=1; | |||
static int instance=0; | |||
T=engine(Va_control_50474_delta_th_c_engine486_delta_th_c); | |||
engine486_T_aircraft_dynamics495_T[T_aircraft_dynamics495_T_wcell]=T; | |||
T_aircraft_dynamics495_T_wcell=(T_aircraft_dynamics495_T_wcell+1)%3; | |||
instance++; | |||
return 0; | |||
} | |||
int Vz_control_50483_fun(void* args) | |||
{ | |||
double delta_e_c; | |||
static int Vz_f_rcell=0; | |||
static int q_f_rcell=0; | |||
static int az_f_rcell=0; | |||
static int instance=0; | |||
delta_e_c=Vz_control_50(Vz_filter_100452_Vz_f_Vz_control_50483_Vz_f[Vz_f_rcell], | |||
altitude_hold_50464_Vz_c_Vz_control_50483_Vz_c,q_filter_100455_q_f_Vz_control_50483_q_f[q_f_rcell], | |||
az_filter_100458_az_f_Vz_control_50483_az_f[az_f_rcell]); | |||
Vz_f_rcell=(Vz_f_rcell+1)%2; | |||
q_f_rcell=(q_f_rcell+1)%2; | |||
az_f_rcell=(az_f_rcell+1)%2; | |||
Vz_control_50483_delta_e_c_delta_e_c=delta_e_c; | |||
Vz_control_50483_delta_e_c_elevator489_delta_e_c=delta_e_c; | |||
instance++; | |||
return 0; | |||
} | |||
int delta_e_c0_fun(void* args) | |||
{ | |||
static int instance=0; | |||
output_delta_e_c(Vz_control_50483_delta_e_c_delta_e_c); | |||
instance++; | |||
return 0; | |||
} | |||
int h_c0_fun(void* args) | |||
{ | |||
double h_c; | |||
static int instance=0; | |||
h_c=input_h_c(); | |||
h_c_altitude_hold_50464_h_c=h_c; | |||
instance++; | |||
return 0; | |||
} | |||
#define PLUD_TASK_NUMBER 15 | |||
static struct nonencoded_task_params static_task_set[PLUD_TASK_NUMBER] = { | |||
{ "h_c0", 1000, 0, 1, 1000, h_c0_fun }, | |||
{ "delta_e_c0", 200, 0, 1, 200, delta_e_c0_fun }, | |||
{ "Vz_control_50483", 200, 0, 1, 200, Vz_control_50483_fun }, | |||
{ "engine486", 50, 0, 1, 50, engine486_fun }, | |||
{ "h_filter_100446", 100, 0, 1, 100, h_filter_100446_fun }, | |||
{ "aircraft_dynamics495", 50, 0, 1, 50, aircraft_dynamics495_fun }, | |||
{ "q_filter_100455", 100, 0, 1, 100, q_filter_100455_fun }, | |||
{ "Vz_filter_100452", 100, 0, 1, 100, Vz_filter_100452_fun }, | |||
{ "az_filter_100458", 100, 0, 1, 100, az_filter_100458_fun }, | |||
{ "delta_th_c0", 200, 0, 1, 200, delta_th_c0_fun }, | |||
{ "altitude_hold_50464", 200, 0, 1, 200, altitude_hold_50464_fun }, | |||
{ "Va_c0", 1000, 0, 1, 1000, Va_c0_fun }, | |||
{ "Va_control_50474", 200, 0, 1, 200, Va_control_50474_fun }, | |||
{ "elevator489", 50, 0, 1, 50, elevator489_fun }, | |||
{ "Va_filter_100449", 100, 0, 1, 100, Va_filter_100449_fun } | |||
}; | |||
void get_task_set (int* task_number, struct nonencoded_task_params** task_set) | |||
{ | |||
*task_number = PLUD_TASK_NUMBER; | |||
*task_set=static_task_set; | |||
} | |||
static struct job_prec engine486_aircraft_dynamics495_pcpat[1] = { {0,1} }; | |||
static struct job_prec Va_filter_100449_Va_control_50474_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec q_filter_100455_Va_control_50474_pcpat[1] = { {0,0} }; | |||
static struct job_prec q_filter_100455_Vz_control_50483_pcpat[1] = { {0,0} }; | |||
static struct job_prec aircraft_dynamics495_q_filter_100455_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec Va_c0_Va_control_50474_pcpat[1] = { {0,0} }; | |||
static struct job_prec Vz_control_50483_delta_e_c0_pcpat[1] = { {0,0} }; | |||
static struct job_prec Vz_control_50483_elevator489_pcpat[1] = { {0,0} }; | |||
static struct job_prec Vz_filter_100452_Va_control_50474_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec Vz_filter_100452_Vz_control_50483_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec h_filter_100446_altitude_hold_50464_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec aircraft_dynamics495_az_filter_100458_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec elevator489_aircraft_dynamics495_pcpat[1] = { {0,1} }; | |||
static struct job_prec aircraft_dynamics495_Vz_filter_100452_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec az_filter_100458_Vz_control_50483_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec h_c0_altitude_hold_50464_pcpat[1] = { {0,0} }; | |||
static struct job_prec altitude_hold_50464_Vz_control_50483_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec aircraft_dynamics495_Va_filter_100449_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec aircraft_dynamics495_h_filter_100446_pcpat[1] = { | |||
{0,0} }; | |||
static struct job_prec Va_control_50474_engine486_pcpat[1] = { {0,0} }; | |||
static struct job_prec Va_control_50474_delta_th_c0_pcpat[1] = { {0,0} }; | |||
#define PLUD_PREC_NUMBER 21 | |||
static struct multirate_precedence static_prec_set[PLUD_PREC_NUMBER] = { | |||
{ "engine486", "aircraft_dynamics495", 0, 1, NULL, | |||
engine486_aircraft_dynamics495_pcpat }, | |||
{ "Va_filter_100449", "Va_control_50474", 0, 1, NULL, | |||
Va_filter_100449_Va_control_50474_pcpat }, | |||
{ "q_filter_100455", "Va_control_50474", 0, 1, NULL, | |||
q_filter_100455_Va_control_50474_pcpat }, | |||
{ "q_filter_100455", "Vz_control_50483", 0, 1, NULL, | |||
q_filter_100455_Vz_control_50483_pcpat }, | |||
{ "aircraft_dynamics495", "q_filter_100455", 0, 1, NULL, | |||
aircraft_dynamics495_q_filter_100455_pcpat }, | |||
{ "Va_c0", "Va_control_50474", 0, 1, NULL, Va_c0_Va_control_50474_pcpat }, | |||
{ "Vz_control_50483", "delta_e_c0", 0, 1, NULL, | |||
Vz_control_50483_delta_e_c0_pcpat }, | |||
{ "Vz_control_50483", "elevator489", 0, 1, NULL, | |||
Vz_control_50483_elevator489_pcpat }, | |||
{ "Vz_filter_100452", "Va_control_50474", 0, 1, NULL, | |||
Vz_filter_100452_Va_control_50474_pcpat }, | |||
{ "Vz_filter_100452", "Vz_control_50483", 0, 1, NULL, | |||
Vz_filter_100452_Vz_control_50483_pcpat }, | |||
{ "h_filter_100446", "altitude_hold_50464", 0, 1, NULL, | |||
h_filter_100446_altitude_hold_50464_pcpat }, | |||
{ "aircraft_dynamics495", "az_filter_100458", 0, 1, NULL, | |||
aircraft_dynamics495_az_filter_100458_pcpat }, | |||
{ "elevator489", "aircraft_dynamics495", 0, 1, NULL, | |||
elevator489_aircraft_dynamics495_pcpat }, | |||
{ "aircraft_dynamics495", "Vz_filter_100452", 0, 1, NULL, | |||
aircraft_dynamics495_Vz_filter_100452_pcpat }, | |||
{ "az_filter_100458", "Vz_control_50483", 0, 1, NULL, | |||
az_filter_100458_Vz_control_50483_pcpat }, | |||
{ "h_c0", "altitude_hold_50464", 0, 1, NULL, h_c0_altitude_hold_50464_pcpat | |||
}, | |||
{ "altitude_hold_50464", "Vz_control_50483", 0, 1, NULL, | |||
altitude_hold_50464_Vz_control_50483_pcpat }, | |||
{ "aircraft_dynamics495", "Va_filter_100449", 0, 1, NULL, | |||
aircraft_dynamics495_Va_filter_100449_pcpat }, | |||
{ "aircraft_dynamics495", "h_filter_100446", 0, 1, NULL, | |||
aircraft_dynamics495_h_filter_100446_pcpat }, | |||
{ "Va_control_50474", "engine486", 0, 1, NULL, | |||
Va_control_50474_engine486_pcpat }, | |||
{ "Va_control_50474", "delta_th_c0", 0, 1, NULL, | |||
Va_control_50474_delta_th_c0_pcpat } | |||
}; | |||
void get_precedence_set (int* prec_number, struct multirate_precedence** prec_set) | |||
{ | |||
*prec_number = PLUD_PREC_NUMBER; | |||
*prec_set=static_prec_set; | |||
} |
@ -0,0 +1,33 @@ | |||
#ifndef _assemblage_H | |||
#define _assemblage_H | |||
#include "nonencoded_task_params.h" | |||
#include "multirate_precedence.h" | |||
#include "com_patterns.h" | |||
#include "types.h" | |||
void get_task_set(int* task_number, struct nonencoded_task_params** task_set); | |||
void get_precedence_set(int* prec_number, struct multirate_precedence** presc); | |||
#define H_C0 0 | |||
#define DELTA_E_C0 1 | |||
#define VZ_CONTROL 2 | |||
#define ENGINE 3 | |||
#define H_FILTER 4 | |||
#define AIRCRAFT_DYN 5 | |||
#define Q_FILTER 6 | |||
#define VZ_FILTER 7 | |||
#define AZ_FILTER 8 | |||
#define DELTA_TH_C0 9 | |||
#define ALTI_HOLD 10 | |||
#define VA_C0 11 | |||
#define VA_CONTROL 12 | |||
#define ELEVATOR 13 | |||
#define VA_FILTER 14 | |||
#endif |
@ -0,0 +1,241 @@ | |||
#ifndef ASSEMBLAGE_INCLUDES_H | |||
#define ASSEMBLAGE_INCLUDES_H | |||
#include "types.h" | |||
#include "io.h" | |||
/* *************************************************************************** | |||
* Shared constants | |||
* ************************************************************************* */ | |||
#define delta_th_eq (1.5868660794926) | |||
#define delta_e_eq (0.012009615652468) | |||
extern const REAL_TYPE h_eq; | |||
extern const REAL_TYPE Va_eq; | |||
#ifndef NBMAX_SAMPLE | |||
#define NBMAX_SAMPLE (6000000/4) | |||
#endif | |||
extern REAL_TYPE sample[SPL_SIZE][NBMAX_SAMPLE]; | |||
void print_inmemory_sample(); | |||
/* *************************************************************************** | |||
* The prelude imported node prototypes | |||
* ************************************************************************* */ | |||
/** | |||
* Va filter (100/50/33/25 Hz --> 10/20/30/40 ms period) | |||
* @param[in] Va, airspeed (m/s) | |||
* @return Va_f, filtered airspeed (m/s) | |||
* 2nd order Butterworth filter with fc = 0.5 Hz (Matlab function butter) | |||
* Discretized with Zero-order Hold method with Ts = 0.01/0.02/0.03/0.04 (Matlab function c2d) | |||
*/ | |||
REAL_TYPE | |||
Va_filter_100(REAL_TYPE Va); | |||
REAL_TYPE | |||
Va_filter_50(REAL_TYPE Va); | |||
REAL_TYPE | |||
Va_filter_33(REAL_TYPE Va); | |||
REAL_TYPE | |||
Va_filter_25(REAL_TYPE Va); | |||
/** | |||
* Vz filter (100/50/33/25 Hz --> 10/20/30/40 ms period) | |||
* @param[in] Vz, vertical speed (m/s) | |||
* @return Vz_f, filtered vertical airspeed (m/s) | |||
* 2nd order Butterworth filter with fc = 0.5 Hz (Matlab function butter) | |||
* Discretized with Zero-order Hold method with Ts = 0.01/0.02/0.03/0.04 (Matlab function c2d) | |||
*/ | |||
REAL_TYPE | |||
Vz_filter_100(REAL_TYPE Vz); | |||
REAL_TYPE | |||
Vz_filter_50 (REAL_TYPE Vz); | |||
REAL_TYPE | |||
Vz_filter_33 (REAL_TYPE Vz); | |||
REAL_TYPE | |||
Vz_filter_25 (REAL_TYPE Vz); | |||
/** | |||
* q filter (100/50/33/25 Hz --> 10/20/30/40 ms period) | |||
* @param[in] q, pitch rate (rad/s) | |||
* @return q_f, filtered pitch rate (rad/s) | |||
* 2nd order Butterworth filter with fc = 3.0 Hz (Matlab function butter) | |||
* Discretized with Zero-order Hold method with Ts = 0.01/0.02/0.03/0.04 (Matlab function c2d) | |||
*/ | |||
REAL_TYPE | |||
q_filter_100(REAL_TYPE q); | |||
REAL_TYPE | |||
q_filter_50 (REAL_TYPE q); | |||
REAL_TYPE | |||
q_filter_33 (REAL_TYPE q); | |||
REAL_TYPE | |||
q_filter_25 (REAL_TYPE q); | |||
/** | |||
* az filter (100/50/33/25 Hz --> 10/20/30/40 ms period) | |||
* @param[in] az, normal acceleration (m/s^2) | |||
* @return az_f, filtered normal acceleration (m/s^2) | |||
* 2nd order Butterworth filter with fc = 10.0 Hz (Matlab function butter) | |||
* Discretized with Zero-order Hold method with Ts = 0.01/0.02/0.03/0.04 (Matlab function c2d) | |||
*/ | |||
REAL_TYPE | |||
az_filter_100(REAL_TYPE az); | |||
REAL_TYPE | |||
az_filter_50 (REAL_TYPE az); | |||
REAL_TYPE | |||
az_filter_33 (REAL_TYPE az); | |||
REAL_TYPE | |||
az_filter_25 (REAL_TYPE az); | |||
/** | |||
* h filter (100/50/33/25 Hz --> 10/20/30/40 ms period) | |||
* @param[in] h, altitude (m) | |||
* @return h_f, filtered altitude (m) | |||
* 2nd order Butterworth filter with fc = 3.0 Hz (Matlab function butter) | |||
* Discretized with Zero-order Hold method with Ts = 0.01/0.02/0.03/0.04 (Matlab function c2d) | |||
*/ | |||
REAL_TYPE | |||
h_filter_100(REAL_TYPE h); | |||
REAL_TYPE | |||
h_filter_50 (REAL_TYPE h); | |||
REAL_TYPE | |||
h_filter_33 (REAL_TYPE h); | |||
REAL_TYPE | |||
h_filter_25 (REAL_TYPE h); | |||
/** | |||
* Altitude hold controller (rate 50/33/25/10 Hz sampling period 0.02/0.03/0.04/0.1) | |||
* @param[in] h_f, filtered altitude (m) | |||
* @param[in] h_c, commanded altitude (m) | |||
* @return Vz_c, commanded vertical speed (m/s) | |||
* Generates the vertical speed command Vz_c to track altitude change h_c | |||
*/ | |||
REAL_TYPE | |||
altitude_hold_50 (REAL_TYPE h_f, REAL_TYPE h_c); | |||
REAL_TYPE | |||
altitude_hold_33 (REAL_TYPE h_f, REAL_TYPE h_c); | |||
REAL_TYPE | |||
altitude_hold_25 (REAL_TYPE h_f, REAL_TYPE h_c); | |||
REAL_TYPE | |||
altitude_hold_10 (REAL_TYPE h_f, REAL_TYPE h_c); | |||
/** | |||
* Vz Speed controller (rate 50/33/25/10 Hz sampling period 0.02/0.03/0.04/0.1) | |||
* @param[in] Vz_f, filtered vertical speed (m/s) | |||
* @param[in] Vz_c, commanded vertical speed (m/s) | |||
* @param[in] q_f, filtered pitch rate (rad/s) | |||
* @param[in] az_f, filtered normal acceleration (m/s^2) | |||
* @return delta_e_c, commanded elevator deflection (rad) | |||
* Generates the elevator deflection command to track vertical speed command Vz_c | |||
*/ | |||
REAL_TYPE | |||
Vz_control_50 (REAL_TYPE Vz_f, REAL_TYPE Vz_c, REAL_TYPE q_f, REAL_TYPE az_f); | |||
REAL_TYPE | |||
Vz_control_33 (REAL_TYPE Vz_f, REAL_TYPE Vz_c, REAL_TYPE q_f, REAL_TYPE az_f); | |||
REAL_TYPE | |||
Vz_control_25 (REAL_TYPE Vz_f, REAL_TYPE Vz_c, REAL_TYPE q_f, REAL_TYPE az_f); | |||
REAL_TYPE | |||
Vz_control_10 (REAL_TYPE Vz_f, REAL_TYPE Vz_c, REAL_TYPE q_f, REAL_TYPE az_f); | |||
/** | |||
* Va Speed controller (rate 50/33/25/10 Hz sampling period 0.02/0.03/0.04/0.1) | |||
* @param[in] Va_f, filtered airspeed (m/s) | |||
* @param[in] Vz_f, filtered vertical speed (m/s) | |||
* @param[in] q_f, filtered pitch rate (rad/s) | |||
* @return delta_th_c, commanded throttle (-) | |||
* Generates the throttle command to track airspeed change Va_c | |||
*/ | |||
REAL_TYPE | |||
Va_control_50 (REAL_TYPE Va_f, REAL_TYPE Vz_f, REAL_TYPE q_f, REAL_TYPE Va_c); | |||
REAL_TYPE | |||
Va_control_33 (REAL_TYPE Va_f, REAL_TYPE Vz_f, REAL_TYPE q_f, REAL_TYPE Va_c); | |||
REAL_TYPE | |||
Va_control_25 (REAL_TYPE Va_f, REAL_TYPE Vz_f, REAL_TYPE q_f, REAL_TYPE Va_c); | |||
REAL_TYPE | |||
Va_control_10 (REAL_TYPE Va_f, REAL_TYPE Vz_f, REAL_TYPE q_f, REAL_TYPE Va_c); | |||
/** | |||
* Engine (200 Hz --> 5ms period) | |||
* @param[in] delta_th_c, commanded throttle (-) | |||
* @return T, Thrust (N) | |||
* 1st order system with time constant 0.5 s | |||
* ODE Solver: Euler method with fixed-step = 0.005 (200 Hz) | |||
*/ | |||
REAL_TYPE | |||
engine(REAL_TYPE delta_th_c); | |||
/** | |||
* Elevator (200 Hz --> 5ms period) | |||
* @param[in] delta_e_c, commanded elevator deflection (rad) | |||
* @return delta_e, elevator deflection (rad) | |||
* 2nd order system (natural frequency omega = 25.0 rad/s and damping xi = 0.85) | |||
* ODE Solver: Euler method with fixed-step = 0.005 s (200 Hz) | |||
*/ | |||
REAL_TYPE | |||
elevator(REAL_TYPE delta_e_c); | |||
/** | |||
* Flight dynamics (200 Hz --> 5ms period) | |||
* @param[in] i, the simulation step | |||
* @param[in] delta_e, elevator deflection (rad) | |||
* @param[in] T, Thrust (N) | |||
* @param[out] outputs, the outputs Va, Vz, q, az, h | |||
* Aircraft flight dynamics | |||
* ODE Solver: Euler method with fixed-step = 0.005 s (200 Hz) | |||
*/ | |||
void | |||
aircraft_dynamics (REAL_TYPE delta_e, REAL_TYPE T, struct aircraft_dynamics_outs_t *outputs); | |||
/* *************************************************************************** | |||
* The prelude sensor node prototypes | |||
* ************************************************************************* */ | |||
/** | |||
* (200 Hz --> 5ms period) | |||
*/ | |||
REAL_TYPE | |||
input_h_c(); | |||
REAL_TYPE | |||
input_Va_c(); | |||
/* *************************************************************************** | |||
* The prelude actuator node prototypes | |||
* ************************************************************************* */ | |||
/** | |||
* (200 Hz --> 5ms period) | |||
*/ | |||
void | |||
output_delta_th_c(REAL_TYPE delta_th_c); | |||
/** | |||
* (200 Hz --> 5ms period) | |||
*/ | |||
void | |||
output_delta_e_c(REAL_TYPE delta_e_c); | |||
#endif |
@ -0,0 +1,72 @@ | |||
/* ---------------------------------------------------------------------------- | |||
* SchedMCore - A MultiCore Scheduling Framework | |||
* Copyright (C) 2009-2011, ONERA, Toulouse, FRANCE - LIFL, Lille, FRANCE | |||
* | |||
* This file is part of Prelude | |||
* | |||
* Prelude is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public License | |||
* as published by the Free Software Foundation ; either version 2 of | |||
* the License, or (at your option) any later version. | |||
* | |||
* Prelude is distributed in the hope that it will be useful, but | |||
* WITHOUT ANY WARRANTY ; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with this program ; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | |||
* USA | |||
*---------------------------------------------------------------------------- */ | |||
#ifndef com_patterns_H_ | |||
#define com_patterns_H_ | |||
// Description of communication protocols using ultimately periodic | |||
// words: prefix.(periodic pattern). Each communication uses a circular | |||
// buffer shared between the writer and the reader. | |||
// The task instance i writes to the communication buffer iff proto[n] | |||
// is true (modulo the size of the periodic word). After each write, the | |||
// index where the writer writes is incremented. | |||
struct write_proto_t { | |||
int* write_pref; | |||
int wpref_size; | |||
int* write_pat; | |||
int wpat_size; | |||
}; | |||
// The task instance n must increment the index at which the task reads | |||
// in the communication buffer iff proto[n] is true (modulo the size of the | |||
// periodic word). | |||
struct read_proto_t { | |||
int* change_pref; | |||
int rpref_size; | |||
int* change_pat; | |||
int rpat_size; | |||
}; | |||
/** | |||
* Returns 1 if instance n must write in the com buffer. | |||
*/ | |||
static inline int must_write(struct write_proto_t wp, int n) | |||
{ | |||
if(n < wp.wpref_size) | |||
return wp.write_pref[n]; | |||
else | |||
return wp.write_pat[(n-wp.wpref_size)%wp.wpat_size]; | |||
} | |||
/** | |||
* Returns 1 if instance n must change the cell from which it reads. | |||
*/ | |||
static inline int must_change(struct read_proto_t rp, int n) | |||
{ | |||
if(n < rp.rpref_size) | |||
return rp.change_pref[n]; | |||
else | |||
return rp.change_pat[(n-rp.rpref_size)%rp.rpat_size]; | |||
} | |||
#endif |
@ -0,0 +1,30 @@ | |||
#include <stdio.h> | |||
#include "types.h" | |||
#include "io.h" | |||
#define FMTREAL "%5.15f" | |||
#define BASE_FREQUENCY 200.0 | |||
extern REAL_TYPE h_c; | |||
void ROSACE_update_altitude_command(REAL_TYPE h_cons){ | |||
h_c = h_cons; | |||
} | |||
void ROSACE_write_outputs(output_t* v){ | |||
static int first=1; | |||
if (first) { | |||
printf("# %15s, %15s, %15s, %15s, %15s, %15s, %15s, %15s\n", | |||
"T","Va","az","q","Vz","h","delta_th_c","delta_e_c"); | |||
first = 0; | |||
} | |||
//printf("%3.4f, ", (v->t_simu)/BASE_FREQUENCY); // The time is already in ms here | |||
printf("%3.4f, ", (v->t_simu)/1000.0); | |||
printf(FMTREAL", ", v->sig_outputs.Va); | |||
printf(FMTREAL", ", v->sig_outputs.az); | |||
printf(FMTREAL", ", v->sig_outputs.q); | |||
printf(FMTREAL", ", v->sig_outputs.Vz); | |||
printf(FMTREAL", ", v->sig_outputs.h); | |||
printf(FMTREAL", ", v->sig_delta_th_c); | |||
printf(FMTREAL"\n", v->sig_delta_e_c); | |||
} |
@ -0,0 +1,16 @@ | |||
#ifndef __DEF_ROSACE_IO_H | |||
#define __DEF_ROSACE_IO_H | |||
#include "types.h" | |||
typedef struct { | |||
struct aircraft_dynamics_outs_t sig_outputs; | |||
uint64_t t_simu; | |||
REAL_TYPE sig_delta_th_c; | |||
REAL_TYPE sig_delta_e_c; | |||
} output_t; | |||
void ROSACE_write_outputs(output_t* v); | |||
void ROSACE_update_altitude_command(REAL_TYPE h_cons); | |||
#endif |
@ -0,0 +1,43 @@ | |||
/* ---------------------------------------------------------------------------- | |||
* SchedMCore - A MultiCore Scheduling Framework | |||
* Copyright (C) 2009-2011, ONERA, Toulouse, FRANCE - LIFL, Lille, FRANCE | |||
* | |||
* This file is part of Prelude | |||
* | |||
* Prelude is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public License | |||
* as published by the Free Software Foundation ; either version 2 of | |||
* the License, or (at your option) any later version. | |||
* | |||
* Prelude is distributed in the hope that it will be useful, but | |||
* WITHOUT ANY WARRANTY ; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with this program ; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | |||
* USA | |||
*---------------------------------------------------------------------------- */ | |||
#ifndef _multirate_precedence_H | |||
#define _multirate_precedence_H | |||
#include <stdlib.h> | |||
// Description of a precedence between two tasks of different rates | |||
struct job_prec { | |||
int src_job; | |||
int dst_job; | |||
}; | |||
struct multirate_precedence { | |||
char* src_name; | |||
char* dst_name; | |||
int prec_pref_size; | |||
int prec_pat_size; | |||
struct job_prec* prec_pref; | |||
struct job_prec* prec_pat; | |||
}; | |||
#endif |
@ -0,0 +1,38 @@ | |||
/* ---------------------------------------------------------------------------- | |||
* SchedMCore - A MultiCore Scheduling Framework | |||
* Copyright (C) 2009-2011, ONERA, Toulouse, FRANCE - LIFL, Lille, FRANCE | |||
* | |||
* This file is part of Prelude | |||
* | |||
* Prelude is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public License | |||
* as published by the Free Software Foundation ; either version 2 of | |||
* the License, or (at your option) any later version. | |||
* | |||
* Prelude is distributed in the hope that it will be useful, but | |||
* WITHOUT ANY WARRANTY ; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with this program ; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | |||
* USA | |||
*---------------------------------------------------------------------------- */ | |||
#ifndef _nonencoded_task_params_H | |||
#define _nonencoded_task_params_H | |||
#include <stdlib.h> | |||
// Description of a real time task, without precedence encoding. | |||
struct nonencoded_task_params { | |||
char* ne_t_name; | |||
int ne_t_period; | |||
int ne_t_initial_release; | |||
int ne_t_wcet; | |||
int ne_t_deadline; | |||
int (*ne_t_body)(void*); // This is the code to execute at each | |||
// instance of the task. | |||
}; | |||
#endif |
@ -0,0 +1,16 @@ | |||
#include <stdlib.h> | |||
#include "threads.h" | |||
/* The only purpose of this file is to do | |||
* some configuration if required before | |||
* calling the actual rosace main function | |||
*/ | |||
int main(int argc, char* argv[]){ | |||
uint64_t tsimu=300*200; | |||
if (argc>1) { | |||
tsimu = atoi(argv[1])*200; | |||
} | |||
return run_rosace(tsimu); | |||
} | |||
@ -0,0 +1,237 @@ | |||
#include <unistd.h> // For sleep() | |||
#include <pthread.h> | |||
#include "types.h" | |||
#include "assemblage_includes.h" | |||
#include "assemblage.h" | |||
// This should be set to 1 to run in "real-time" in the sense | |||
// that the simulation time is close to the real world time | |||
#define RUN_WITH_REAL_TIME 0 | |||
// Task set | |||
struct nonencoded_task_params* tasks; | |||
// I/O | |||
output_t outs; | |||
uint64_t step_simu; | |||
uint64_t max_step_simu; | |||
// Barriers for thread synchro | |||
pthread_barrier_t cycle_start_b; | |||
pthread_barrier_t engine_elevator_b; | |||
pthread_barrier_t filter_b; | |||
pthread_barrier_t control_b; | |||
pthread_barrier_t output_b; | |||
// Output variables | |||
extern double aircraft_dynamics495_Va_Va_filter_100449_Va[2]; | |||
extern double aircraft_dynamics495_az_az_filter_100458_az[2]; | |||
extern double aircraft_dynamics495_Vz_Vz_filter_100452_Vz[2]; | |||
extern double aircraft_dynamics495_q_q_filter_100455_q[2]; | |||
extern double aircraft_dynamics495_h_h_filter_100446_h[2]; | |||
extern double Va_control_50474_delta_th_c_delta_th_c; | |||
extern double Vz_control_50483_delta_e_c_delta_e_c; | |||
void copy_output_vars(output_t* v, uint64_t step){ | |||
v->sig_outputs.Va = aircraft_dynamics495_Va_Va_filter_100449_Va[step%2]; | |||
v->sig_outputs.Vz = aircraft_dynamics495_Vz_Vz_filter_100452_Vz[step%2]; | |||
v->sig_outputs.q = aircraft_dynamics495_q_q_filter_100455_q[step%2]; | |||
v->sig_outputs.az = aircraft_dynamics495_az_az_filter_100458_az[step%2]; | |||
v->sig_outputs.h = aircraft_dynamics495_h_h_filter_100446_h[step%2]; | |||
v->sig_delta_th_c = Va_control_50474_delta_th_c_delta_th_c; | |||
v->sig_delta_e_c = Vz_control_50483_delta_e_c_delta_e_c; | |||
} | |||
void rosace_init() { | |||
// Init barriers | |||
pthread_barrier_init(&cycle_start_b, NULL, 5); | |||
pthread_barrier_init(&engine_elevator_b, NULL, 2); | |||
pthread_barrier_init(&filter_b, NULL, 5); | |||
pthread_barrier_init(&control_b, NULL, 2); | |||
pthread_barrier_init(&output_b, NULL, 2); | |||
// Initial values | |||
outs.sig_outputs.Va = 0; | |||
outs.sig_outputs.Vz = 0; | |||
outs.sig_outputs.q = 0; | |||
outs.sig_outputs.az = 0; | |||
outs.sig_outputs.h = 0; | |||
outs.t_simu = 0; | |||
step_simu = 0; | |||
// Get the task set (required for CALL() macro) | |||
int tmp; | |||
get_task_set(&tmp, &tasks); | |||
} | |||
#define CALL(val) tasks[(val)].ne_t_body(NULL) | |||
void* thread1(void* arg) { | |||
uint64_t mystep_simu = step_simu; | |||
while(step_simu<max_step_simu) { | |||
pthread_barrier_wait(&cycle_start_b); | |||
// --- 200 Hz --- | |||
CALL(ENGINE); | |||
pthread_barrier_wait(&engine_elevator_b); | |||
// --- End 200 Hz --- | |||
// --- 100 Hz --- | |||
if(mystep_simu%2 == 0) { | |||
pthread_barrier_wait(&filter_b); | |||
CALL(VZ_FILTER); | |||
} | |||
// --- End 100 Hz --- | |||
// --- 10 Hz --- | |||
if(mystep_simu%20 == 0) | |||
CALL(VA_C0); | |||
// --- End 10 Hz --- | |||
// --- 50 Hz --- | |||
if(mystep_simu%4 == 0) { | |||
pthread_barrier_wait(&control_b); | |||
CALL(VA_CONTROL); | |||
} | |||
if(mystep_simu%4 == 3) { | |||
pthread_barrier_wait(&output_b); | |||
CALL(DELTA_TH_C0); | |||
} | |||
// --- End 50 Hz --- | |||
step_simu = step_simu + 1; | |||
outs.t_simu += 5; | |||
// Print output | |||
copy_output_vars(&outs, step_simu); | |||
if (step_simu%10) | |||
ROSACE_write_outputs(&outs); | |||
if(RUN_WITH_REAL_TIME) | |||
usleep(5000); // "Real-time" execution | |||
mystep_simu++; | |||
} | |||
return NULL; | |||
} | |||
void* thread2(void* arg) { | |||
uint64_t mystep_simu = step_simu; | |||
while(step_simu<max_step_simu) { | |||
pthread_barrier_wait(&cycle_start_b); | |||
// --- 200 Hz --- | |||
CALL(ELEVATOR); | |||
pthread_barrier_wait(&engine_elevator_b); | |||
CALL(AIRCRAFT_DYN); | |||
// --- End 200 Hz --- | |||
// --- 100 Hz --- | |||
if(mystep_simu%2 == 0) { | |||
pthread_barrier_wait(&filter_b); | |||
CALL(H_FILTER); | |||
} | |||
// --- End 100 Hz --- | |||
// --- 10 Hz --- | |||
if(mystep_simu%20 == 0) | |||
CALL(H_C0); | |||
// --- End 10 Hz --- | |||
// --- 50 Hz --- | |||
if(mystep_simu%4 == 0) { | |||
CALL(ALTI_HOLD); | |||
pthread_barrier_wait(&control_b); | |||
CALL(VZ_CONTROL); | |||
} | |||
if(mystep_simu%4 == 3) { | |||
pthread_barrier_wait(&output_b); | |||
CALL(DELTA_E_C0); | |||
} | |||
// --- End 50 Hz --- | |||
mystep_simu++; | |||
} | |||
return NULL; | |||
} | |||
void* thread3(void* arg) { | |||
uint64_t mystep_simu = step_simu; | |||
while(step_simu<max_step_simu) { | |||
pthread_barrier_wait(&cycle_start_b); | |||
// --- 100 Hz --- | |||
if(mystep_simu%2 == 0) { | |||
pthread_barrier_wait(&filter_b); | |||
CALL(Q_FILTER); | |||
} | |||
// --- End 100 Hz --- | |||
mystep_simu++; | |||
} | |||
return NULL; | |||
} | |||
void* thread4(void* arg) { | |||
uint64_t mystep_simu = step_simu; | |||
while(step_simu<max_step_simu) { | |||
pthread_barrier_wait(&cycle_start_b); | |||
// --- 100 Hz --- | |||
if(mystep_simu%2 == 0) { | |||
pthread_barrier_wait(&filter_b); | |||
CALL(VA_FILTER); | |||
} | |||
// --- End 100 Hz --- | |||
mystep_simu++; | |||
} | |||
return NULL; | |||
} | |||
void* thread5(void* arg) { | |||
uint64_t mystep_simu = step_simu; | |||
while(step_simu<max_step_simu) { | |||
pthread_barrier_wait(&cycle_start_b); | |||
// --- 100 Hz --- | |||
if(mystep_simu%2 == 0) { | |||
pthread_barrier_wait(&filter_b); | |||
CALL(AZ_FILTER); | |||
} | |||
// --- End 100 Hz --- | |||
mystep_simu++; | |||
} | |||
return NULL; | |||
} | |||
int run_rosace(uint64_t nbstep){ | |||
int i; | |||
// Variables for thread management | |||
void* fcts[] = {&thread1, &thread2, &thread3, &thread4, &thread5}; | |||
pthread_t threads[5]; | |||
rosace_init(); | |||
max_step_simu = nbstep; | |||
// Set first command | |||
ROSACE_update_altitude_command(11000.0); | |||
// Create the 5 threads | |||
for(i=0; i<5; i++) | |||
pthread_create( &(threads[i]), NULL, fcts[i], NULL); | |||
// SCENARIO | |||
/* sleep(20); | |||
ROSACE_update_altitude_command(10500.0); | |||
sleep(20); | |||
ROSACE_update_altitude_command(11500.0); | |||
sleep(20); | |||
ROSACE_update_altitude_command(10000.0); | |||
sleep(20); | |||
ROSACE_update_altitude_command(9000.0); | |||
*/ | |||
// Exit | |||
for(i=0; i<5; i++) | |||
pthread_join(threads[i], NULL); | |||
return 0; | |||
} | |||
@ -0,0 +1,29 @@ | |||
#ifndef __DEF_ROSACE_THREADS_H | |||
#define __DEF_ROSACE_THREADS_H | |||
#include <pthread.h> | |||
#include "assemblage_includes.h" | |||
// Barriers | |||
extern pthread_barrier_t cycle_start_b; | |||
extern pthread_barrier_t engine_elevator_b; | |||
extern pthread_barrier_t filter_b; | |||
extern pthread_barrier_t control_b; | |||
extern pthread_barrier_t output_b; | |||
extern uint64_t step_simu; | |||
// Threads ... | |||
void* thread1(void* arg); | |||
void* thread2(void* arg); | |||
void* thread3(void* arg); | |||
void* thread4(void* arg); | |||
void* thread5(void* arg); | |||
void rosace_init(); | |||
int run_rosace(); | |||
#endif | |||
@ -0,0 +1,30 @@ | |||
#ifndef __DEF_ROSACE_TYPES_H | |||
#define __DEF_ROSACE_TYPES_H | |||
#ifdef USE_FLOAT | |||
#define REAL_TYPE float | |||
#else | |||
#define REAL_TYPE double | |||
#endif | |||
typedef unsigned long long uint64_t; | |||
/* we need forward declaration only in order | |||
* to avoid redefinition in assemblage_vX generated headers | |||
* Real "#include "assemblage.h" is only done in assemblage_includes.c | |||
*/ | |||
struct aircraft_dynamics_outs_t { | |||
REAL_TYPE Va; | |||
REAL_TYPE Vz; | |||
REAL_TYPE q; | |||
REAL_TYPE az; | |||
REAL_TYPE h; | |||
}; | |||
typedef enum SAMPLE_RANK { | |||
SPL_T, SPL_VA,SPL_AZ,SPL_Q,SPL_VZ,SPL_H, | |||
SPL_DELTA_TH_C, SPL_DELTA_E_C, | |||
SPL_SIZE | |||
} SampleRank_t; | |||
#endif |