diff --git a/conf/flight_plans/flight_plan.dtd b/conf/flight_plans/flight_plan.dtd index f319596775..302c3503e9 100644 --- a/conf/flight_plans/flight_plan.dtd +++ b/conf/flight_plans/flight_plan.dtd @@ -142,6 +142,8 @@ value CDATA #REQUIRED> name CDATA #REQUIRED pre_call CDATA #IMPLIED post_call CDATA #IMPLIED +on_enter CDATA #IMPLIED +on_exit CDATA #IMPLIED strip_button CDATA #IMPLIED strip_icon CDATA #IMPLIED group CDATA #IMPLIED diff --git a/sw/airborne/firmwares/fixedwing/nav.c b/sw/airborne/firmwares/fixedwing/nav.c index 8c6256e203..59b18e20e7 100644 --- a/sw/airborne/firmwares/fixedwing/nav.c +++ b/sw/airborne/firmwares/fixedwing/nav.c @@ -531,8 +531,7 @@ static void send_survey(struct transport_tx *trans, struct link_device *dev) */ void nav_init(void) { - nav_block = 0; - nav_stage = 0; + common_flight_plan_init(); ground_alt = GROUND_ALT; nav_glide_pitch_trim = NAV_GLIDE_PITCH_TRIM; nav_radius = DEFAULT_CIRCLE_RADIUS; diff --git a/sw/airborne/firmwares/rotorcraft/navigation.c b/sw/airborne/firmwares/rotorcraft/navigation.c index a3bb4e6e8b..ca43506da3 100644 --- a/sw/airborne/firmwares/rotorcraft/navigation.c +++ b/sw/airborne/firmwares/rotorcraft/navigation.c @@ -70,9 +70,7 @@ static inline void nav_set_altitude(void); void nav_init(void) { waypoints_init(); - - nav_block = 0; - nav_stage = 0; + common_flight_plan_init(); nav.horizontal_mode = NAV_HORIZONTAL_MODE_WAYPOINT; nav.vertical_mode = NAV_VERTICAL_MODE_ALT; diff --git a/sw/airborne/firmwares/rover/navigation.c b/sw/airborne/firmwares/rover/navigation.c index 125029b220..d026988253 100644 --- a/sw/airborne/firmwares/rover/navigation.c +++ b/sw/airborne/firmwares/rover/navigation.c @@ -79,9 +79,7 @@ static void send_wp_moved(struct transport_tx *trans, struct link_device *dev) void nav_init(void) { waypoints_init(); - - nav_block = 0; - nav_stage = 0; + common_flight_plan_init(); nav.mode = NAV_MODE_WAYPOINT; diff --git a/sw/airborne/modules/com/generic_com.c b/sw/airborne/modules/com/generic_com.c index 4e876672b6..32367be11c 100644 --- a/sw/airborne/modules/com/generic_com.c +++ b/sw/airborne/modules/com/generic_com.c @@ -85,7 +85,7 @@ void generic_com_periodic(void) com_trans.buf[18] = charge; com_trans.buf[19] = (uint8_t)(command_get(COMMAND_THROTTLE) * 100 / MAX_PPRZ); com_trans.buf[20] = autopilot_get_mode(); - com_trans.buf[21] = nav_block; + com_trans.buf[21] = get_nav_block(); FillBufWith16bit(com_trans.buf, 22, autopilot.flight_time); i2c_transmit(&GENERIC_COM_I2C_DEV, &com_trans, GENERIC_COM_SLAVE_ADDR, NB_DATA); } diff --git a/sw/airborne/modules/datalink/missionlib/mission_manager.c b/sw/airborne/modules/datalink/missionlib/mission_manager.c index e980db1f3f..8ec17199fa 100644 --- a/sw/airborne/modules/datalink/missionlib/mission_manager.c +++ b/sw/airborne/modules/datalink/missionlib/mission_manager.c @@ -93,9 +93,9 @@ void mavlink_mission_message_handler(const mavlink_message_t *msg) void mavlink_mission_periodic(void) { // FIXME: really use the SCRIPT_ITEM message to indicate current block? - if (mission_mgr.current_block != nav_block) { - mission_mgr.current_block = nav_block; - mavlink_msg_script_current_send(MAVLINK_COMM_0, nav_block); + if (mission_mgr.current_block != get_nav_block()) { + mission_mgr.current_block = get_nav_block(); + mavlink_msg_script_current_send(MAVLINK_COMM_0, get_nav_block()); MAVLinkSendMessage(); } // check if we had a timeout on a transaction diff --git a/sw/airborne/modules/nav/common_flight_plan.c b/sw/airborne/modules/nav/common_flight_plan.c index b37b29ce01..33a4e7d1ba 100644 --- a/sw/airborne/modules/nav/common_flight_plan.c +++ b/sw/airborne/modules/nav/common_flight_plan.c @@ -37,24 +37,104 @@ uint8_t nav_stage, nav_block; uint8_t last_block, last_stage; uint8_t last_wp UNUSED; +static uint8_t private_nav_stage, private_nav_block; +static uint8_t private_last_block, private_last_stage; + +void common_flight_plan_init(void) { + private_nav_stage = 0; + nav_stage = 0; + private_nav_block = 0; + nav_block = 0; + private_last_stage = 0; + last_stage = 0; + private_last_block = 0; + last_block = 0; + stage_time = 0; + block_time = 0; +} void nav_init_block(void) { - if (nav_block >= NB_BLOCK) { - nav_block = NB_BLOCK - 1; + if (private_nav_block >= NB_BLOCK) { + private_nav_block = NB_BLOCK - 1; + nav_block = private_nav_block; } - nav_stage = 0; + private_nav_stage = 0; + nav_stage = private_nav_stage; block_time = 0; InitStage(); + nav_on_enter_block(private_nav_block); // generated by flight plan } void nav_goto_block(uint8_t b) { - if (b != nav_block) { /* To avoid a loop in a the current block */ - last_block = nav_block; - last_stage = nav_stage; + if (b != private_nav_block) { + /* To avoid a loop in a the current block */ + private_last_block = private_nav_block; + last_block = private_last_block; + private_last_stage = private_nav_stage; + last_stage = private_last_stage; } - nav_block = b; + nav_on_exit_block(private_nav_block); // generated by flight plan + private_nav_block = b; + nav_block = private_nav_block; nav_init_block(); } +void nav_goto_next_block(void) { + if (private_nav_block < NB_BLOCK - 1) { + nav_goto_block(private_nav_block + 1); + } else { + nav_goto_block(private_nav_block); + } +} + +void nav_goto_next_stage(void) { + private_nav_stage++; + nav_stage = private_nav_stage; + InitStage(); +} + +void nav_return(uint8_t reset) { + nav_on_exit_block(private_nav_block); // generated by flight plan + private_nav_block = private_last_block; + nav_block = private_nav_block; + if (reset == 1) { + private_nav_stage = 0; + } else { + private_nav_stage = private_last_stage; + } + nav_stage = private_nav_stage; + block_time = 0; + InitStage(); + nav_on_enter_block(private_nav_block); // generated by flight plan +} + +uint8_t get_nav_block() { + return private_nav_block; +} +uint8_t get_nav_stage() { + return private_nav_stage; +} +uint8_t get_last_block() { + return private_last_block; +} +uint8_t get_last_stage() { + return private_last_stage; +} + +void set_nav_block(uint8_t b){ + if (b >= NB_BLOCK) { + private_nav_block = NB_BLOCK - 1; + } + else { + private_nav_block = b; + } + nav_block = private_nav_block; +} + +void set_nav_stage(uint8_t s) { + private_nav_stage = s; + nav_stage = s; +} + diff --git a/sw/airborne/modules/nav/common_flight_plan.h b/sw/airborne/modules/nav/common_flight_plan.h index 7f16a11ad6..33f085217f 100644 --- a/sw/airborne/modules/nav/common_flight_plan.h +++ b/sw/airborne/modules/nav/common_flight_plan.h @@ -32,30 +32,53 @@ /** In s */ extern uint16_t stage_time, block_time; +/* The modification of the following variables do not affect + * the behavior of the flight plan + */ extern uint8_t nav_stage, nav_block; extern uint8_t last_block, last_stage; extern uint8_t last_wp __attribute__((unused)); -/** needs to be implemented by fixedwing and rotorcraft seperately */ -void nav_init_stage(void); +/* init function */ +extern void common_flight_plan_init(void); -void nav_init_block(void); -void nav_goto_block(uint8_t block_id); +/** needs to be implemented by fixedwing and rotorcraft seperately */ +extern void nav_init_stage(void); + +extern void nav_init_block(void); +extern void nav_goto_block(uint8_t block_id); +extern void nav_goto_next_block(void); +extern void nav_goto_next_stage(void); +extern void nav_return(uint8_t reset); + +/* Getter */ +extern uint8_t get_nav_block(); +extern uint8_t get_nav_stage(); +extern uint8_t get_last_block(); +extern uint8_t get_last_stage(); + +/* Setter */ +extern void set_nav_block(uint8_t block_id); +extern void set_nav_stage(uint8_t stage_id); + +/** Functions generated by the flight plan */ +extern void nav_on_enter_block(uint8_t block_id); +extern void nav_on_exit_block(uint8_t block_id); #define InitStage() nav_init_stage(); -#define Block(x) case x: nav_block=x; -#define NextBlock() nav_goto_block(nav_block + 1) +#define Block(x) case x: set_nav_block(x); +#define NextBlock() nav_goto_next_block() #define GotoBlock(b) nav_goto_block(b) -#define Stage(s) case s: nav_stage=s; -#define NextStage() { nav_stage++; InitStage(); } INTENTIONAL_FALLTHRU -#define NextStageAndBreak() { nav_stage++; InitStage(); break; } +#define Stage(s) case s: set_nav_stage(s); +#define NextStage() { nav_goto_next_stage(); } INTENTIONAL_FALLTHRU +#define NextStageAndBreak() { nav_goto_next_stage(); break; } #define NextStageAndBreakFrom(wp) { last_wp = wp; NextStageAndBreak(); } #define Label(x) label_ ## x: #define Goto(x) { goto label_ ## x; } -#define Return(x) { nav_block=last_block; if (x==1) {nav_stage=0;} else {nav_stage=last_stage;} block_time=0;} +#define Return(x) nav_return(x) /** Time in s since the entrance in the current block */ #define NavBlockTime() (block_time) @@ -64,3 +87,4 @@ void nav_goto_block(uint8_t block_id); #define Ptr(x) (&(x)) #endif /* COMMON_FLIGHT_PLAN_H */ + diff --git a/sw/tools/generators/gen_flight_plan.ml b/sw/tools/generators/gen_flight_plan.ml index fdd91abc29..f903e72ef3 100644 --- a/sw/tools/generators/gen_flight_plan.ml +++ b/sw/tools/generators/gen_flight_plan.ml @@ -918,6 +918,34 @@ let print_auto_init_bindings = fun out abi_msgs variables -> List.iter print_bindings variables; lprintf out "}\n\n" +let print_enter_exit_functions = fun out blocks -> + let print_functions = fun name -> + lprintf out "void nav_%s_block(uint8_t block_id) {\n" name; + right (); + lprintf out "switch (block_id) {\n"; + right (); + let block_id = ref (-1) in + List.iter (fun b -> + incr block_id; + try + let f_name = ExtXml.attrib b name in + lprintf out "case %d: // %s\n" !block_id (name_of b); + lprintf out " %s;\n" f_name; + lprintf out " break;\n" + with _ -> () + ) blocks; + lprintf out "default:\n"; + lprintf out " break;\n"; + left (); + lprintf out "}\n"; + left (); + lprintf out "}\n\n" + in + (* print enter block functions *) + print_functions "on_enter"; + (* print exit block functions *) + print_functions "on_exit" + (** * Print flight plan header *) @@ -1114,6 +1142,10 @@ let print_flight_plan_h = fun xml ref0 xml_file out_file -> lprintf out "\n"; print_auto_init_bindings out abi_msgs variables; + (* print on_enter and on_exit functions *) + lprintf out "\n"; + print_enter_exit_functions out blocks; + (* print main flight plan state machine *) lprintf out "static inline void auto_nav(void) {\n"; right ();