Merge remote-tracking branch 'paparazzi/master' into datalink_functions

Conflicts:
	sw/airborne/subsystems/gps.c
This commit is contained in:
Gautier Hattenberger
2014-11-06 15:39:25 +01:00
29 changed files with 174 additions and 121 deletions
+1 -1
View File
@@ -18,10 +18,10 @@
<define name="LOITER_TRIM"/>
<subsystem name="radio_control" type="ppm"/>
<subsystem name="joystick"/>
<!-- Communication -->
<subsystem name="telemetry" type="transparent"/>
<define name="USE_JOYSTICK" value="TRUE"/>
<!-- Actuators are automatically chosen according to board-->
<subsystem name="control"/>
+1 -1
View File
@@ -18,10 +18,10 @@
<define name="LOITER_TRIM"/>
<subsystem name="radio_control" type="ppm"/>
<subsystem name="joystick"/>
<!-- Communication -->
<subsystem name="telemetry" type="transparent"/>
<define name="USE_JOYSTICK" value="TRUE"/>
<!-- Actuators are automatically chosen according to board-->
<subsystem name="control"/>
+1 -1
View File
@@ -26,8 +26,8 @@
<subsystem name="ahrs" type="infrared"/>
<subsystem name="gps" type="ublox_hitl"/>
<subsystem name="navigation"/>
<subsystem name="joystick"/>
<subsystem name="ins" type="gps_passthrough"/>
<define name="USE_JOYSTICK" value="TRUE"/>
</firmware>
<firmware name="setup">
@@ -136,7 +136,7 @@ else ifeq ($(BOARD), hbmini)
BARO_BOARD_CFLAGS += -DUSE_I2C1
BARO_BOARD_SRCS += peripherals/bmp085.c
BARO_BOARD_SRCS += $(SRC_BOARD)/baro_board.c
# krooz baro
else ifeq ($(BOARD), krooz)
BARO_BOARD_CFLAGS += -DBB_MS5611_I2C_DEV=i2c2
Executable → Regular
View File
View File
+3 -1
View File
@@ -162,7 +162,9 @@ value CDATA #REQUIRED>
<!ATTLIST call
fun CDATA #REQUIRED
until CDATA #IMPLIED>
until CDATA #IMPLIED
loop CDATA #IMPLIED
break CDATA #IMPLIED>
<!ATTLIST follow
ac_id CDATA #REQUIRED
+1 -1
View File
@@ -1320,7 +1320,7 @@
<field name="temp2" type="float" unit="deg_celsius" format="%.2f"/>
<field name="temp3" type="float" unit="deg_celsius" format="%.2f"/>
</message>
<message name="GUIDANCE_H_REF_INT" id="149">
<field name="sp_x" type="int32" alt_unit="m" alt_unit_coef="0.0039063"/>
<field name="ref_x" type="int32" alt_unit="m" alt_unit_coef="0.0039063"/>
+25 -2
View File
@@ -2,8 +2,32 @@
<module name="flight_benchmark" dir="benchmark">
<doc>
<description>Flight benchmark</description>
<description>
Flight benchmark.
This module allows a quantitative assessment of the flight. It calculates the sum of squared error of the two-dimensional course (x / y), the altitude and true airspeed. The sum of squared error of the course and altitude were separated, because they are regulated separately, and so they dependent on various parameters. The module was written to optimize the control parameters and has already been used successfully.
The measurement is not started until about the variable benchm_go is set to 1.
The sum of squared error can by reseted by changing the boolean variable benchm_reset to zero (will turn back to 1 automatically after it has done the reset). This can also be used in a flight plan, which allows a flight plan with auto-reset. So it is possible to fly an oval or a eight figure with a sum of squared error that will be reseted at the very same point of the figure.
</description>
<define name="BENCHMARK_AIRSPEED" description="enable airspeed benchmarking (only with airspeed module)"/>
<define name="BENCHMARK_ALTITUDE" description="enable altitude benchmarking"/>
<define name="BENCHMARK_POSITION" description="enable position (x/y) benchmarking. (shortest error to the path)"/>
<define name="BENCHMARK_TOLERANCE_AIRSPEED" value="0." description="define the tolerated value where the sum of squared error won't change. Set to zero to have no tolerance."/>
<define name="BENCHMARK_TOLERANCE_ALTITUDE" value="0." description="define the tolerated value where the sum of squared error won't change. Set to zero to have no tolerance."/>
<define name="BENCHMARK_TOLERANCE_POSITION" value="0." description="define the tolerated value where the sum of squared error won't change. Set to zero to have no tolerance."/>
</doc>
<settings>
<dl_settings>
<dl_settings NAME="Benchmark">
<dl_setting MAX="1" MIN="0" STEP="1" VAR="benchm_reset" shortname="bench_reset" module="modules/benchmark/flight_benchmark"/>
<dl_setting MAX="1" MIN="0" STEP="1" VAR="benchm_go" shortname="bench_go" />
<dl_setting MAX="20" MIN="0" STEP="0.1" VAR="ToleranceAispeed" shortname="AS_Tolerance" param="BENCHMARK_TOLERANCE_AIRSPEED"/>
<dl_setting MAX="20" MIN="0" STEP="0.1" VAR="ToleranceAltitude" shortname="Alt_Tolerance" param="BENCHMARK_TOLERANCE_ALTITUDE"/>
<dl_setting MAX="20" MIN="0" STEP="0.1" VAR="TolerancePosition" shortname="Pos_Tolerance" param="BENCHMARK_TOLERANCE_POSITION"/>
</dl_settings>
</dl_settings>
</settings>
<header>
<file name="flight_benchmark.h"/>
</header>
@@ -14,4 +38,3 @@
<file name="flight_benchmark.c"/>
</makefile>
</module>
+10 -3
View File
@@ -3,16 +3,23 @@
<module name="flight_time" dir="time">
<doc>
<description>
Flight time calculator
Flight time calculator.
Allows to check how much time is left before the end of the competition.
</description>
</doc>
<settings>
<dl_settings>
<dl_settings name="flight time">
<dl_setting var="time_until_land" module="modules/time/flight_time" min="0" step="1" max="1800" param="FLIGHT_TIME_LEFT"/>
</dl_settings>
</dl_settings>
</settings>
<header>
<file name="flight_time.h"/>
</header>
<init fun="flight_time_init()"/>
<periodic fun="flight_time_periodic()" freq="1"/> <!--(0.1171875) 1Hz only valid in case: the modules run a 512Hz but the module generator thinks it runs at 60Hz therefore the scaling factor should be 60/512-->
<periodic fun="flight_time_periodic()" freq="1"/>
<makefile>
<file name="flight_time.c"/>
</makefile>
</module>
</module>
+1 -1
View File
@@ -49,6 +49,6 @@ Note: a command may be reversed by exchanging min and max values
<channel ctl="A" function="YAW" min="1200" neutral="1510" max="1800" average="0"/>
<channel ctl="E" function="MODE" min="1140" neutral="1470" max="1840" average="1"/>
<channel ctl="G" function="CALIB" min="1890" neutral="1500" max="1100" average="0"/>
<channel ctl="f" function="GAINI" min="1100" neutral="1490" max="1880" average="0"/>
<channel ctl="f" function="GAINI" min="1100" neutral="1490" max="1880" average="0"/>
<!-- channel 9 is transmitted but cannot be controlled -->
</radio>
Executable → Regular
View File
-13
View File
@@ -1,13 +0,0 @@
<!DOCTYPE settings SYSTEM "../settings.dtd">
<settings>
<dl_settings>
<dl_settings NAME="Benchmark">
<dl_setting MAX="1" MIN="0" STEP="1" VAR="benchm_reset" shortname="bench_reset" module="modules/benchmark/flight_benchmark"/>
<dl_setting MAX="1" MIN="0" STEP="1" VAR="benchm_go" shortname="bench_go" />
<dl_setting MAX="20" MIN="0" STEP="0.1" VAR="ToleranceAispeed" shortname="AS_Tolerance" param="BENCHMARK_TOLERANCE_AIRSPEED"/>
<dl_setting MAX="20" MIN="0" STEP="0.1" VAR="ToleranceAltitude" shortname="Alt_Tolerance" param="BENCHMARK_TOLERANCE_ALTITUDE"/>
<dl_setting MAX="20" MIN="0" STEP="0.1" VAR="TolerancePosition" shortname="Pos_Tolerance" param="BENCHMARK_TOLERANCE_POSITION"/>
</dl_settings>
</dl_settings>
</settings>
-12
View File
@@ -1,12 +0,0 @@
<!DOCTYPE settings SYSTEM "../settings.dtd">
<settings>
<dl_settings>
<dl_settings NAME="DC">
<dl_setting MAX="1" MIN="0" STEP="1" VAR="autopilot_power_switch" module="autopilot" handler="SetPowerSwitch" shortname="Shutter">
<strip_button name="Photo" icon="digital-camera.png" value="1"/>
<strip_button name="Photo Off" icon="digital-camera-off.png" value="0"/>
</dl_setting>
</dl_settings>
</dl_settings>
</settings>
-14
View File
@@ -1,14 +0,0 @@
<!DOCTYPE settings SYSTEM "../settings.dtd">
<settings>
<dl_settings>
<dl_settings NAME="Drop">
<dl_setting var="booz_drop_ball" min="0" step="1" max="1" module="drop/booz_drop" values="Closed|Open">
<strip_button name="OPEN" value="1" group="drop"/>
<strip_button name="CLOSE" value="0" group="drop"/>
</dl_setting>
</dl_settings>
</dl_settings>
</settings>
-9
View File
@@ -1,9 +0,0 @@
<!DOCTYPE settings SYSTEM "../settings.dtd">
<settings>
<dl_settings>
<dl_settings name="IMAV 2013">
<dl_setting var="time_until_land" module="modules/time/flight_time" min="0" step="1" max="1800" param="FLIGHT_TIME_LEFT"/>
</dl_settings>
</dl_settings>
</settings>
+16 -9
View File
@@ -6,10 +6,13 @@ Q=@
UNAME = $(shell uname -s)
ifeq ("$(UNAME)","Darwin")
MKTEMP = gmktemp
SED = gsed
else
MKTEMP = mktemp
SED = sed
endif
all: $(PAPARAZZI_HOME)/conf/maps.xml
clean:
@@ -28,16 +31,20 @@ $(DATADIR)/maps.google.com: $(DATADIR) FORCE
exit 1)
$(PAPARAZZI_HOME)/conf/maps.xml: $(DATADIR)/maps.google.com
$(eval GOOGLE_VERSION := $(shell tr -s '[[:space:]]' '\n' < $(DATADIR)/maps.google.com | grep -E "http[s]?://khm[s]?[0-9]+.google.com/kh/v=[0-9]+.x26" | sed -e 's/.*http[s]\?:\/\/khm[s]\?[0-9]\+\.google\.com\/kh\/v=\([0-9]\+\)\\x26.*/\1/'))
$(eval GOOGLE_VERSION := $(shell tr -s '[[:space:]]' '\n' < $(DATADIR)/maps.google.com | grep -E "http[s]?://khm[s]?[0-9]+.google.com/kh/v=[0-9]+.x26" | $(SED) -r 's#.*http[s]?://khm[s]?[0-9]+.google.com/kh/v=##;s#.x26.*##'))
$(eval $@_TMP := $(shell $(MKTEMP)))
@echo "Updated google maps version to $(GOOGLE_VERSION)"
@echo "-----------------------------------------------"
$(Q)echo "<!DOCTYPE maps SYSTEM \"maps.dtd\">" > $($@_TMP)
$(Q)echo "" >> $($@_TMP)
$(Q)echo "<maps google_version=\"$(GOOGLE_VERSION)\"/>" >> $($@_TMP)
$(Q)echo "" >> $($@_TMP)
$(Q)mv $($@_TMP) $@
$(Q)chmod a+r $@
$(Q)if [ "$(GOOGLE_VERSION)" -eq "$(GOOGLE_VERSION)" ] 2>/dev/null ; then \
echo "Updated google maps version to $(GOOGLE_VERSION)" ; \
echo "-----------------------------------------------" ; \
echo "<!DOCTYPE maps SYSTEM \"maps.dtd\">" > $($@_TMP) ; \
echo "" >> $($@_TMP) ; \
echo "<maps google_version=\"$(GOOGLE_VERSION)\"/>" >> $($@_TMP) ; \
echo "" >> $($@_TMP) ; \
mv $($@_TMP) $@ ; \
chmod a+r $@ ; \
else \
echo "Extracted google maps version was not a valid number: $(GOOGLE_VERSION)" ; \
fi
FORCE:
.PHONY: all clean
@@ -393,7 +393,7 @@ void nav_init_stage( void ) {
#include <stdio.h>
void nav_periodic_task(void) {
RunOnceEvery(16, { stage_time++; block_time++; });
RunOnceEvery(NAV_FREQ, { stage_time++; block_time++; });
dist2_to_wp = 0;
@@ -30,6 +30,7 @@
#include "state.h"
#include "firmwares/rotorcraft/stabilization.h"
#include "firmwares/rotorcraft/stabilization/stabilization_attitude.h"
#include "firmwares/rotorcraft/stabilization/stabilization_attitude_rc_setpoint.h"
#include "paparazzi.h"
View File
+14 -8
View File
@@ -84,8 +84,14 @@ void dc_send_shot_position(void)
{
int16_t phi = DegOfRad(stateGetNedToBodyEulers_f()->phi*10.0f);
int16_t theta = DegOfRad(stateGetNedToBodyEulers_f()->theta*10.0f);
float gps_z = ((float)gps.hmsl) / 1000.0f;
int16_t course = (DegOfRad(gps.course)/((int32_t)1e6));
struct UtmCoor_f * utm = stateGetPositionUtm_f();
// east and north UTM position in cm
int32_t east = utm->east * 100;
int32_t north = utm->north * 100;
// course in decideg
int16_t course = DegOfRad(*stateGetHorizontalSpeedDir_f()) * 10;
// ground speed in cm/s
uint16_t speed = (*stateGetHorizontalSpeedNorm_f()) * 10;
int16_t photo_nr = -1;
if (dc_buffer < DC_IMAGE_BUFFER) {
@@ -96,14 +102,14 @@ void dc_send_shot_position(void)
DOWNLINK_SEND_DC_SHOT(DefaultChannel, DefaultDevice,
&photo_nr,
&gps.utm_pos.east,
&gps.utm_pos.north,
&gps_z,
&gps.utm_pos.zone,
&east,
&north,
&utm->alt,
&utm->zone,
&phi,
&theta,
&course,
&gps.gspeed,
&speed,
&gps.tow);
}
#endif /* SENSOR_SYNC_SEND */
@@ -205,7 +211,7 @@ void dc_periodic_4Hz(void)
case DC_AUTOSHOOT_DISTANCE:
{
uint32_t dist_to_100m_grid = (gps.utm_pos.north / 100) % 100;
uint32_t dist_to_100m_grid = (int32_t)stateGetPositionUtm_f()->north % 100;
if (dist_to_100m_grid < dc_autoshoot_meter_grid || 100 - dist_to_100m_grid < dc_autoshoot_meter_grid)
{
dc_send_command(DC_SHOOT);
+1 -1
View File
@@ -187,7 +187,7 @@ extern uint8_t dc_circle(float interval, float start);
* If both 'x' and 'y' are DC_IGNORE the current position
* will be used as reference point.
*
* @param interval minimum angle between shots in deg
* @param interval distance between shots in meters
* @param x x coordinate of reference point (or special DC_IGNORE)
* @param y y coordinate of reference point (or special DC_IGNORE)
* @return zero
+23 -9
View File
@@ -45,6 +45,22 @@ struct GpsTimeSync gps_time_sync;
#if PERIODIC_TELEMETRY
#include "subsystems/datalink/telemetry.h"
static void send_svinfo(struct transport_tx *trans, struct device *dev, uint8_t svid) {
if (svid < GPS_NB_CHANNELS) {
pprz_msg_send_SVINFO(trans, dev, AC_ID, &svid,
&gps.svinfos[svid].svid, &gps.svinfos[svid].flags,
&gps.svinfos[svid].qi, &gps.svinfos[svid].cno,
&gps.svinfos[svid].elev, &gps.svinfos[svid].azim);
}
}
/** send SVINFO message if there is information for satellite with svid */
static inline void send_svinfo_available(struct transport_tx *trans, struct device *dev, uint8_t svid) {
if (gps.svinfos[svid].cno > 0) {
send_svinfo(trans, dev, svid);
}
}
static void send_gps(struct transport_tx *trans, struct device *dev) {
static uint8_t i;
int16_t climb = -gps.ned_vel.z;
@@ -53,13 +69,13 @@ static void send_gps(struct transport_tx *trans, struct device *dev) {
&gps.utm_pos.east, &gps.utm_pos.north,
&course, &gps.hmsl, &gps.gspeed, &climb,
&gps.week, &gps.tow, &gps.utm_pos.zone, &i);
// send SVINFO for all satellites while no GPS fix,
// after 3D fix, send avialable sats with lower rate
if ((gps.fix != GPS_FIX_3D) && (i >= gps.nb_channels)) i = 0;
if (i >= gps.nb_channels * 2) i = 0;
if (i < gps.nb_channels && ((gps.fix != GPS_FIX_3D) || (gps.svinfos[i].cno > 0))) {
pprz_msg_send_SVINFO(trans, dev, AC_ID, &i,
&gps.svinfos[i].svid, &gps.svinfos[i].flags,
&gps.svinfos[i].qi, &gps.svinfos[i].cno,
&gps.svinfos[i].elev, &gps.svinfos[i].azim);
send_svinfo(trans, dev, i);
}
i++;
}
@@ -77,12 +93,10 @@ static void send_gps_int(struct transport_tx *trans, struct device *dev) {
&gps.pdop,
&gps.num_sv,
&gps.fix);
// send SVINFO for available satellites that have new data
if (i == gps.nb_channels) i = 0;
if (i < gps.nb_channels && gps.svinfos[i].cno > 0 && gps.svinfos[i].cno != last_cnos[i]) {
pprz_msg_send_SVINFO(trans, dev, AC_ID, &i,
&gps.svinfos[i].svid, &gps.svinfos[i].flags,
&gps.svinfos[i].qi, &gps.svinfos[i].cno,
&gps.svinfos[i].elev, &gps.svinfos[i].azim);
if (i < gps.nb_channels && gps.svinfos[i].cno != last_cnos[i]) {
send_svinfo_available(trans, dev, i);
last_cnos[i] = gps.svinfos[i].cno;
}
i++;
+6 -2
View File
@@ -92,8 +92,12 @@ void ins_reset_altitude_ref( void ) {
void ins_propagate(float __attribute__((unused)) dt) {
/* untilt accels and speeds */
float_rmat_transp_vmult(&ins_impl.ltp_accel, stateGetNedToBodyRMat_f(), &ahrs_impl.accel);
float_rmat_transp_vmult(&ins_impl.ltp_speed, stateGetNedToBodyRMat_f(), &ahrs_impl.speed);
float_rmat_transp_vmult((struct FloatVect3*)&ins_impl.ltp_accel,
stateGetNedToBodyRMat_f(),
(struct FloatVect3*)&ahrs_impl.accel);
float_rmat_transp_vmult((struct FloatVect3*)&ins_impl.ltp_speed,
stateGetNedToBodyRMat_f(),
(struct FloatVect3*)&ahrs_impl.speed);
//Add g to the accelerations
ins_impl.ltp_accel.z += 9.81;
+4 -2
View File
@@ -82,7 +82,9 @@ void nps_flightgear_send() {
if (sendto(flightgear.socket, (char*)(&gui), sizeof(gui), 0,
(struct sockaddr*)&flightgear.addr, sizeof(flightgear.addr)) == -1)
printf("error sending\n");
(struct sockaddr*)&flightgear.addr, sizeof(flightgear.addr)) == -1) {
fprintf(stderr, "error sending to FlightGear\n");
fflush(stderr);
}
}
+8 -6
View File
@@ -227,7 +227,7 @@ module Make(AircraftItl : AIRCRAFT_ITL) = struct
Aircraft.attitude_and_rates phi theta psi p q r in
(** Sending to Flight Gear *)
let fg_task = fun socket buffer () ->
let fg_task = fun socket buffer sockaddr () ->
match !last_gps_state with
None -> ()
| Some s ->
@@ -239,9 +239,9 @@ module Make(AircraftItl : AIRCRAFT_ITL) = struct
fg_msg buffer lat lon alt phi theta psi;
(** for i = 0 to String.length buffer - 1 do fprintf stderr "%x " (Char.code buffer.[i]) done; fprintf stderr "\n"; **)
try
ignore (Unix.send socket buffer 0 (String.length buffer) [])
ignore (Unix.sendto socket buffer 0 (String.length buffer) [] sockaddr)
with
Unix.Unix_error (e,f,a) -> Printf.fprintf stderr "Error fg: %s (%s(%s))\n" (Unix.error_message e) f a
Unix.Unix_error (e,f,a) -> Printf.fprintf stderr "Error sending to FlightGear: %s (%s(%s))\n" (Unix.error_message e) f a; flush stderr
in
let set_pos = fun _ ->
@@ -271,11 +271,13 @@ module Make(AircraftItl : AIRCRAFT_ITL) = struct
try
let inet_addr = Unix.inet_addr_of_string !fg_client in
let socket = Unix.socket Unix.PF_INET Unix.SOCK_DGRAM 0 in
Unix.connect socket (Unix.ADDR_INET (inet_addr, 5501));
(* Unix.connect socket (Unix.ADDR_INET (inet_addr, 5501)); *)
let buffer = String.create (fg_sizeof ()) in
Stdlib.timer ~scale:time_scale fg_period (fg_task socket buffer)
let sockaddr = (Unix.ADDR_INET (inet_addr, 5501)) in
Stdlib.timer ~scale:time_scale fg_period (fg_task socket buffer sockaddr);
fprintf stdout "Sending to FlightGear at %s\n" !fg_client; flush stdout
with
e -> fprintf stderr "Error while connecting to fg: %s" (Printexc.to_string e)
e -> fprintf stderr "Error setting up FlightGear viz: %s\n" (Printexc.to_string e); flush stderr
in
let take_off = fun () -> FlightModel.set_air_speed !state FM.nominal_airspeed in
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
fgfs --fdm=null --native-gui=socket,in,30,,5501,udp --prop:/sim/model/path=Models/Aircraft/paparazzi/mikrokopter.xml
+23 -12
View File
@@ -80,16 +80,27 @@ def search(string):
if __name__ == '__main__':
print("====HOME==== ", home_dir)
print("----MODULES---- ", modules_dir)
print(get_list_of_modules())
for mod in get_list_of_modules():
print(mod, " ---> ", get_module_information(mod))
print("----FIRMWARES---- ", firmwares_dir)
print(get_list_of_firmwares())
for firm in get_list_of_firmwares():
print(firm, " ---> ", get_list_of_subsystems(firm))
print("shared", " ---> ", get_list_of_subsystems("shared"))
print("----BOARDS---- ", firmwares_dir)
print(get_list_of_boards())
print("\nPAPARAZZI\n=========\n\nContent listing of current branch\n")
print("\nBOARDS\n------\n")
boards = get_list_of_boards()
for b in boards:
print(" - ```" + b + "```" )
print("\nFIRMWARES - SUBSYSTEMS\n---------\n")
firmwares = get_list_of_firmwares()
firmwares.append("shared")
for f in firmwares:
print(" - " + f)
subsystems = get_list_of_subsystems(f)
for s in subsystems:
print(" - ```", s, "```")
print("\nMODULES\n-------\n")
modules = get_list_of_modules()
for m in modules:
info = get_module_information(m)
d = info.description
if ((d is None) or (len(d) == 0)):
d = " "
print(" - ```" + m + "``` " + d.split('\n', 1)[0])
# for mod in get_list_of_modules():
# print(mod, " ---> ", get_module_information(mod))
+32 -10
View File
@@ -494,16 +494,38 @@ let rec print_stage = fun index_of_waypoints x ->
| "call" ->
stage ();
let statement = ExtXml.attrib x "fun" in
lprintf "if (! (%s))\n" statement;
lprintf " NextStageAndBreak();\n";
begin
try
let c = parsed_attrib x "until" in
lprintf "if (%s) NextStageAndBreak();\n" c
with
ExtXml.Error _ -> ()
end;
lprintf "break;\n"
(* by default, function is called while returning TRUE *)
(* otherwise, function is called once and returned value is ignored *)
let loop = String.uppercase (ExtXml.attrib_or_default x "loop" "TRUE") in
(* be default, go to next stage immediately *)
let break = String.uppercase (ExtXml.attrib_or_default x "break" "FALSE") in
begin match loop with
| "TRUE" ->
lprintf "if (! (%s)) {\n" statement;
begin match break with
| "TRUE" -> lprintf " NextStageAndBreak();\n";
| "FALSE" -> lprintf " NextStage();\n";
| _ -> failwith "FP: 'call' break attribute must be TRUE or FALSE";
end;
lprintf "} else {\n";
begin
try
let c = parsed_attrib x "until" in
lprintf " if (%s) NextStageAndBreak();\n" c
with
ExtXml.Error _ -> ()
end;
lprintf " break;\n";
lprintf "}\n"
| "FALSE" ->
lprintf "%s\n" statement;
begin match break with
| "TRUE" -> lprintf "NextStageAndBreak();\n";
| "FALSE" -> lprintf "NextStage();\n";
| _ -> failwith "FP: 'call' break attribute must be TRUE or FALSE";
end;
| _ -> failwith "FP: 'call' loop attribute must be TRUE or FALSE"
end
| "survey_rectangle" ->
let grid = parsed_attrib x "grid"
and wp1 = get_index_waypoint (ExtXml.attrib x "wp1") index_of_waypoints