-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
2,328 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,30 @@ | ||
# F3F-Tool-V1 | ||
F3F-Tool for Jeti transmitters. All Versions in this V1-Repository will support generation 1 hardware (with monochrome display) | ||
# F3F-Tool V1 | ||
This lua-app for Jeti transmitters is made for gps-based training of RC glider slope racing competitions (F3F) and also distance and speed tasks for F3B. | ||
|
||
All program releases in this 'V1'-repository are made to be compatible with generation 1 Jeti transmitters (with monochrome display). Please consider the requirements for those transmitters mentioned in the [**F3F-Tool manual**](docs/F3F-Tool%20Manual.md), so only use the binary form of the program (.lc) and do not use other lua-apps at the same time. | ||
|
||
## Program Installation | ||
For installation of a stable release please download the zip-file and the corresponding manual of the newest release from the [**releases-page**](https://github.com/frank-sc/F3F-Test-V1/releases), download of the 'source code' packages is not necessary. Copy all files and directories into your 'apps' directory on the transmitter, as described in the manual. Then please follow the further steps in the manual. | ||
|
||
For installation of the current development version (HEAD) please refer to the [**wiki**](https://github.com/frank-sc/F3F-Tool-V1/wiki) | ||
|
||
## Status | ||
The tool in Version 1.4 is working quite well on the slope for F3F. For F3B-tasks there are some issues, especially with the very hight speed reached in the speed-task and with slightly inaccurate determination of the course bearing. See more detailed description in [**issues**](https://github.com/frank-sc/F3F-Test-V1/issues). | ||
|
||
## Development notices | ||
The main program file 'f3f_\<version\> and the working directory 'f3fTool-\<version\> are always renamed for a new upcoming version. This is to make sure that everything fits together and to allow several versions to run independently on one transmitter. | ||
|
||
## Installation of GPS-sensor | ||
Information about choosing a GPS-sensor and the Installation in the glider can be found in the [**wiki**](https://github.com/frank-sc/F3F-Tool-V1/wiki) | ||
|
||
## Project Support | ||
If you have great ideas to improve the performance of the F3F-Tool you are welcome to give me feedback, maybe here: | ||
[**Discussions**](https://github.com/frank-sc/F3F-Test-V1/discussions) | ||
|
||
If you like the tool you can also support my work on the the project by making a donation, i appreciate :)<br><br> | ||
[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.PayPal.Me/f3frank)<br> | ||
|
||
### thanks to | ||
- Axel Barnitzke for giving me an idea how to work kind of object-oriented in LUA | ||
- Dave McQueeney for sharing his Sensor Emulator for Jeti Studio, which allowed me to do a lot of testing on the PC,<br> | ||
and also for bringing up the idea of unloading and reloading parts of code to meet the memory limitations |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
# F3F-Tool Version 1.4 / Installation guide and users manual | ||
### This manual describes how to install, configure and use the F3F-Tool for training of F3F and F3B tasks.<br><br> | ||
## Contents: | ||
1. [General Description](#generalDescription) | ||
2. [Program Installation](#programInstallation) | ||
3. [Program Configuration](#programConfiguration) | ||
4. [Usage](#usage) | ||
5. [Pricing and License](#pricing) | ||
6. [Changelog for Users of 1.3 Test Version](#changelog)<br><br> | ||
<a name="generalDescription"></a> | ||
# 1. General Description | ||
## 1.1. What it does | ||
This LUA-App for Jeti transmitters is made for training of slope racing competitions (F3F). Via GPS Sensor the turn lines are identified and an acoustic signal is given. Also the whole run is supported, starting with the countdown, the count of the 10 legs and time measurement. | ||
|
||
There is also a mode for F3B available, where in case of speed task the time for 4 legs is measured, in case of distance task only legs are counted. | ||
|
||
To use this app a GPS Sensor must be placed in the model and connected to Jeti telemetry. | ||
|
||
## 1.2. Known Limitations | ||
- due to GPS tolerance and telemetry latency the turn signal is not 100% precise, but gives a good F3F-experience | ||
- due to some speed related optimization the first fly out must be more than 50m to give the system the possibility | ||
to calculate the fly in signal accurately, so very short fly out / fly in at 50m is not possible.Depending on the speed of fly out the signal may be given at 60 or even 70 meters. | ||
- somtimes there is a GPS-drift of given start point. In this case the whole course might drift to left or right some meters, because the turn positions are calculated in relation to start. To handle this effect the app includes a function to compensate the drift during the flight. | ||
## 1.3. Requirements | ||
- Newest generation GPS-Sensor must be placed in the glider, needed telemetry values are: **latitude, longitude, speed** | ||
- If the sensor allows, not needed telemetry values should be disabled to speed up the telemetry transfer to transmitter. Also the usage of telemetry values from other sensors or from the receiver should be reduced. | ||
|
||
Special requirements for 'Generation 1' - transmitters with monochrome display: | ||
- a LUA-enabled firmware must be installed on the transmitter (check: **'System / Info / Version'** – must end with 'LUA') | ||
- **Safety Issue: | ||
For the model you use with 'f3fTool' no other LUA Application must be installed to consider the given memory limitations!** | ||
## 1.4. F3B Support | ||
To enable this tool also for F3B Training, some features are provided: | ||
- seperate length definitions for F3F / F3B course | ||
- adapted course-definition for F3B, started from A-Base instead of middle of course | ||
- time measurement after 4 legs in case of a F3B-course used for speed task | ||
- no time measurement, only leg count for distance task | ||
## 1.5. Language support | ||
Currently all menus and display texts are only available in english. All speech announcements are given in english or german, | ||
depending on the system language of the transmitter. For other languages supported by Jeti the audio configuration file must be created similar to 'audio-en.jsn'. | ||
|
||
<a name="programInstallation"></a> | ||
# 2. Program Installation | ||
## 2.1 Copy Files | ||
- Connect transmitter to PC via USB cable | ||
- unpack the zip-Archive **'f3fTool V1.4.zip'** on your computer | ||
- copy the whole contents (file: **'f3f_14.lc'** and directory: **'f3fTool-14'** into the directory 'apps' on your transmitter | ||
- Disconnect transmitter from PC | ||
## 2.2. Activate the tool for a model | ||
The following steps must be done done for every model you want to use with f3fTool: | ||
- Select the model you want to use with the tool on your transmitter | ||
- Select: **'Menu / Applications / User Applications'** | ||
- Press button below **'+'** | ||
- Select file **'f3f_14'** and press **'ok'** | ||
-> result is: **'1 F3F Tool 1.4 xx% Ok'** | ||
|
||
![screenshot of successfull installation](images/Installed.png) | ||
_Picture: Installed F3F-Tool_ | ||
|
||
## 2.3. Configure Telemetry Display | ||
'F3FTool' provides a telemetry window, where the countdown before entering the course, the flown legs and the flight time is shown. To add this window to your display: | ||
- Select **'Menu / Timers/Sensors / Displayed Telemetry'** | ||
- Press button below **'+'** | ||
- open folder **'LUA'** and add **'F3FTool – Vers. 1.4'** | ||
- now you can bring the telemetry windows into the desired order by using the arrow keys. | ||
|
||
![screenshot of Telemetry-Window](images/TeleWindow.jpg) | ||
_Picture: F3F-Tool telemetry display, here together | ||
with satellite count value from GPS_ | ||
<a name="programConfiguration"></a> | ||
# 3. Program Configuration | ||
## 3.1. Basic Configuration | ||
To enter th basic configuration select **'Menu / Applications / F3F Tool - Configuration'** | ||
|
||
![screenshot of empty configuration window](images/ConfigEmpty.png) | ||
![screenshot of configuration done](images/ConfigReady.png) | ||
_Picture: Basic Configuration_ | ||
|
||
**Please configure the tool as follows:** | ||
### Multi Switch | ||
This is a switch for different functions: | ||
- start the run with the countdown | ||
- F3F: toggle A-base | ||
- F3B: toggle speed / distance | ||
- redefine starting point | ||
|
||
please use a springloaded switch here | ||
|
||
### Center Adjust Control<br> | ||
This is used for compensation of GPS frift effects. The configuration is optional.<br> | ||
If you don't need your rudder trim control this can be used to comfortably adjust the course.<br> | ||
In this case | ||
- goto 'Menu / Fine Tuning / Digital trim' | ||
- set the rudder trim (Tr3) to '3-pos switch' | ||
- go back to 'F3F-Tool Configuration' | ||
- assign the control ( '+ / Digital Trim / Tr3' ) | ||
|
||
On DS 24 also the trim controls on the back are useful for this function. | ||
As an alternative the transmitter can be extended by a 2-way springloaded switch, which is available from Jeti.<br> | ||
**Please configure the control as proportional!** | ||
|
||
### F3B Dist. / F3F Dist.<br> | ||
Here you can adjust the length of the course, if needed for some reason. | ||
|
||
### Latitude / Longitude / Speed<br> | ||
Please assign the corresponding values of your GPS sensor here. | ||
|
||
## 3.2. F3F Course Setup (Slope) | ||
For calculation of the course the start position (center of the course) and the GPS-bearing of the slope is needed. Therefore the center position and two bearing points (left / right) on the slope must be scanned before first launch.<br> | ||
The resulting line through the bearing points should be parallel to the slope edge, it is not necessary to scan directly on the edge. It is also not necessary to scan the bearing at the turn positions (50m), but the precision increases with the distance of the two points. | ||
The start position can be adjusted later by redefinement or readjustment. | ||
|
||
The system calculates and shows the wind direction (90° to slope). | ||
|
||
_Technical information:<br> | ||
The slope data is stored in the file 'apps/f3fTool-14/slopeData.jsn'. Once scanned the slope is available to all models stored in the transmitter until it is overwritten._ | ||
|
||
To setup your slope for F3F:<br> | ||
- select **'Menu / Applications / F3F Tool – Course Setup'** | ||
- if the current course is a F3B-course, press buton below **'F3F'** to toggle mode | ||
- go with model and activated GPS (must be ready and have found its satellites !) to the three described points | ||
- on every point press the regarding key **(Start / Left / Right)** | ||
- When all points are scanned the Slope direction is shown in the display | ||
- press **'Ok'** | ||
|
||
![screenshot of slope setup](images/SlopeSetup.png) | ||
![screenshot of slope setup done](images/SlopeReady.png) | ||
_Picture: Slope setup before and after scanning the points.<br> '270 degrees' means, the slope orientation is exactly west._ | ||
|
||
## 3.3. F3B Course Setup | ||
Setup for a F3B Course is slightly different. To avoid running into the middle of the course the setup can be done from A-Base. Only the starting position (A-Base) and a secont point in direction of the course are scanned. Precision increases again with the distance of the two points. | ||
|
||
To setup your F3B-Course:<br> | ||
- select **'Menu / Applications / F3F Tool – Course Setup'** | ||
- press **'F3B'** to switch to the needed setup menu (if the current course is a F3B-course it will be preselected) | ||
- go with model and activated GPS (must be ready and have found its satellites !) to the described points | ||
- on every point press the regarding key **(Start / Bear)** | ||
- When both points are scanned the direction of the course is shown in the display | ||
- press **'Ok'** | ||
|
||
![screenshot of f3b-course setup](images/F3B-CourseSetup.png) | ||
![screenshot of f3b-course setup done](images/F3B-CourseReady.png) | ||
_Picture: F3B Course setup before and after scanning the points.<br> 0 degrees' means, that the course points directly to north_ | ||
|
||
<a name="usage"></a> | ||
# 4. Usage | ||
## 4.1 Start a run | ||
To start a run just **single click** the defined multi-Switch - the run starts with the 30 sec. countdown (F3F). | ||
In case of a F3B-speed run the countdown will be 60 sec., for F3B-distance there is no countdown. | ||
|
||
## 4.2. A-Base support | ||
When a slope is defined, the A-Base is initially on the left side. By doing a **double click** on the defined multi-switch you can toggle the A-base between left and right. | ||
For a F3B-course the A-Base is fix on the start position. | ||
|
||
## 4.3. Drift compensation | ||
Sometimes the whole course may be shifted some meters to left or right by GPS drift effects. If this happens you can compensate this by the defined **'Center adjust control'** | ||
(only if defined, this is optional). So you do not have to land and to rescan the course.<br> | ||
Every click (or move) of the control to left or right will shift the course 1m. This can be done for example between two training runs, or even – if you like – while beeing in a run. | ||
|
||
## 4.4. Redefinement of Start Position | ||
If you have the slope bearing scanned correctly, but want to start from a different position you can redefine the start position by a **'long click'** of the defined multi-switch | ||
what means to hold it pressed for 2 seconds. This is useful to: | ||
- just change position on the slope | ||
- redefine the start position before launch to avoid GPS drift effects. | ||
|
||
## 4.5. F3B: choose task | ||
If the current course is a F3B course, **double click** on the multi-switch toggles between speed and distance task. | ||
|
||
<a name="pricing"></a> | ||
# 5. Pricing and License | ||
The F3F-Tool software is provided free of costs as open source. It is published under the 'GNU General Public License V3.0' WITHOUT ANY WARRANTY (see: http://www.gnu.org/licenses/). | ||
So feel free to use it, i hope it is helpful.<br> | ||
If you like the tool and you are willing to support the project you are welcome to make a donation, i appreciate :) | ||
|
||
Link to paypal.me:<br> | ||
**https://www.PayPal.Me/f3frank** | ||
|
||
<a name="changelog"></a> | ||
# 6. Changelog for Users of 1.3 Test Version | ||
What is new in this Version 1.4? | ||
- Instead of only two points now three points are scanned to define a slope. Also it must be specified, what is left and right. | ||
This allows a greater distance between the left and right point to determine the slope bearing, what means more precision. Also the bearing is independent from the starting point definition. | ||
If you want it to do like in Version 1.3, you can set left or right together with the starting point and then just define the remaining point. | ||
- In F3F mode now the wind direction (90° to slope) is shown instead of direction of the slope edge | ||
- A-Base is supported, can be toggled left /right with the multi switch | ||
- The starting point can be redefined without affecting the slope bearing | ||
- The 'Start Switch' now is a 'Multi Switch' with three functions (start, toggle A-Base left/right, redefine start point) | ||
- The starting point can be adjusted in steps of 1m for compensation of GPS drift effects by a dedicated control | ||
- The speed is now measured and announced 1.5 sec. after course entry instead of directly at course entry | ||
- Countdown announcement now: 30, 25, 20, 15, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 beep | ||
- F3B Support mode with course definition not from center but from from A-Base, time measurement after 4 legs (speed) or count of legs (distance) | ||
- Currently only english Version available | ||
- Improved error management<br><br><br> | ||
|
||
Copyright © 2023 Frank Schreiber |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"audioStart":"F_Start.wav", | ||
"audioSpeed":"/Voice/de/Geschwin.wav", | ||
"audioCourse":"/Voice/en/Course.wav", | ||
"audioTime":"/Voice/de/Zeit.wav", | ||
"audioSeconds":"/Voice/de/Sekunden.wav", | ||
"audioALeft":"/Apps/f3fTool-14/audio/de/a-links.wav", | ||
"audioARight":"/Apps/f3fTool-14/audio/de/a-rechts.wav", | ||
"audioCenter":"/Apps/f3fTool-14/audio/de/mitte.wav", | ||
"audioF3bDistance":"F_Strecke.wav", | ||
"audioF3bSpeed":"F_Speed.wav" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"audioStart":"en/F_Launch.wav", | ||
"audioSpeed":"/Voice/en/Speed.wav", | ||
"audioCourse":"/Voice/en/Course.wav", | ||
"audioTime":"/Voice/en/Time.wav", | ||
"audioSeconds":"/Voice/en/Seconds.wav", | ||
"audioALeft":"/Apps/f3fTool-14/audio/en/a-left.wav", | ||
"audioARight":"/Apps/f3fTool-14/audio/en/a-right.wav", | ||
"audioCenter":"/Apps/f3fTool-14/audio/en/center.wav", | ||
"audioF3bDistance":"F_Distance.wav", | ||
"audioF3bSpeed":"F_Speed.wav" | ||
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# In the binary version the module .lc files go here |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
["Nord","NNO","Nordost","ONO","Ost","OSO","Suedost","SSO","Sued","SSW","Suedwest","WSW","West","WNW","Nordwest","NNW"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
["North","NNE","Northeast","ENE","East","ESE","Southeast","SSE","South","SSW","Southwest","WSW","West","WNW","Northwest","NNW"] |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
-- ############################################################################################### | ||
-- # F3F Tool for JETI DC/DS transmitters | ||
-- # Module: basicCfgForm | ||
-- # | ||
-- # Copyright (c) 2023 Frank Schreiber | ||
-- # | ||
-- # This program is free software: you can redistribute it and/or modify | ||
-- # it under the terms of the GNU General Public License as published by | ||
-- # the Free Software Foundation, either version 3 of the License, or | ||
-- # (at your option) any later version. | ||
-- # | ||
-- # This program 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 General Public License for more details. | ||
-- # | ||
-- # You should have received a copy of the GNU General Public License | ||
-- # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
-- # | ||
-- ############################################################################################### | ||
|
||
-- =============================================================================================== | ||
-- =============================================================================================== | ||
-- ========== Object: basicCfgForm ========== | ||
-- ========== contains form and functions for basic f3f-Tool configuration ========== | ||
-- =============================================================================================== | ||
-- =============================================================================================== | ||
|
||
local basicCfgForm = { | ||
cfgData = nil, | ||
gpsSensor = nil, | ||
handleErr = nil, | ||
dataDir = nil, | ||
|
||
sensorList = nil, | ||
|
||
compSwitch = nil, | ||
compCtrlCenterShift = nil, | ||
compF3bDistance = nil, | ||
compF3fDistance = nil, | ||
compSensorLat = nil, | ||
compSensorLon = nil, | ||
compSensorSpeed = nil | ||
} | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- Check: control valid ? | ||
|
||
function basicCfgForm:checkControl (value) | ||
if (not (value and system.getSwitchInfo (value).assigned)) then | ||
value = nil | ||
end | ||
return value | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- determine index of a sensor in the sensor list | ||
|
||
function basicCfgForm:findIndexForSensor (sensorId, paramId) | ||
local curIndex=-1 | ||
for index, sensor in ipairs(self.sensorList) do | ||
if(sensor.id==sensorId and sensor.param==paramId) then | ||
curIndex=index | ||
end | ||
end | ||
return curIndex | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
function basicCfgForm:initForm(formID) | ||
|
||
-- create sensor list | ||
self.sensorList = {} -- list of sensors, without 'label'-entries like 'GPSLog3' | ||
--local sysSensors = system.getSensors() -- system list of sensors and telemetry-entries / not used here directly for memory optimization | ||
local sysSensors | ||
local list={} -- display-list of telemetry-entries - with preceding Sensor-Label | ||
local curIndex=-1 -- index of configured sensor | ||
local descr = "" -- Sensor-Label (e.g. 'GPSLog3') | ||
|
||
-- get reduced system sensor data from saved json-file | ||
-- direct use of 'system.getSensors()' needs too much memory | ||
local file = io.readall(self.dataDir .. "/sensors.jsn") | ||
if( file ) then | ||
sysSensors = json.decode(file) | ||
|
||
-- convert id values back to number | ||
for i, sens in ipairs (sysSensors) do | ||
sens.id = tonumber (sens.id) | ||
end | ||
|
||
else | ||
self.handleErr ("could not read Sensor file") | ||
end | ||
|
||
-- for use of Dave McQueeney's SensorEmulator with Jeti Studio: | ||
-- use 'getSensors' directly, doesn't work the other way | ||
local device, devType = system.getDeviceType () | ||
if (devType == 1) then | ||
sysSensors = system.getSensors() | ||
end | ||
|
||
-- build the display list - sensor labels are removed from list and preceded to telemetry entries | ||
-- and a corresponding sensor reference list without sensor labels | ||
for index,sensor in ipairs(sysSensors) do | ||
if(sensor.param == 0) then | ||
descr = sensor.label | ||
else | ||
local unit = "" | ||
if (sensor.unit) then unit = "[" .. sensor.unit .. "]" end | ||
|
||
list[#list+1]=string.format("%s - %s %s",descr,sensor.label, unit) | ||
self.sensorList[#self.sensorList+1] = sensor | ||
end | ||
end | ||
|
||
-- print(" basic cfg - lists: " .. collectgarbage("count") .. " kB"); | ||
|
||
--cleanup | ||
collectgarbage("collect") | ||
|
||
-- multifunction button | ||
form.addRow (2) | ||
form.addLabel({label="Multi-Switch"}) | ||
self.compSwitch = form.addInputbox(self.cfgData.switch, false, nil) | ||
|
||
-- adjustment of center | ||
form.addRow (2) | ||
form.addLabel({label="Center adjust ctrl. (prop)", width = 250}) | ||
self.compCtrlCenterShift = form.addInputbox(self.cfgData.ctrlCenterShift, true, nil,{width=60}) | ||
|
||
-- definition of distance (F3B / F3F) | ||
form.addRow(4) | ||
form.addLabel({label="F3B Dist.[m]", width=100}) | ||
self.compF3bDistance = form.addIntbox (self.cfgData.f3bDistance, 5,200,150,0,1, nil, {width=55}) | ||
form.addLabel({label="F3F Dist.[m]", width=100}) | ||
self.compF3fDistance = form.addIntbox (self.cfgData.f3fDistance, 5,150,100,0,1, nil, {width=55}) | ||
|
||
-- sensors for GPS-position | ||
form.addLabel({label=" --------------------------- Sensors ------------------------------", font=FONT_MINI}) | ||
|
||
form.addRow (2) | ||
form.addLabel({label="- Latitude", width=110}) | ||
curIndex = self:findIndexForSensor (self.gpsSensor.lat.id, self.gpsSensor.lat.param) | ||
self.compSensorLat = form.addSelectbox (list, curIndex ,true, nil, {width=200}) | ||
|
||
form.addRow (2) | ||
form.addLabel({label="- Longitude", width=110}) | ||
curIndex = self:findIndexForSensor (self.gpsSensor.lon.id, self.gpsSensor.lon.param) | ||
self.compSensorLon = form.addSelectbox (list, curIndex ,true, nil, {width=200}) | ||
|
||
-- speed-sensor | ||
form.addRow (2) | ||
form.addLabel({label="- Speed", width=110}) | ||
curIndex = self:findIndexForSensor (self.gpsSensor.speed.id, self.gpsSensor.speed.param) | ||
self.compSensorSpeed = form.addSelectbox (list, curIndex,true, nil, {width=200}) | ||
|
||
print("GC Count after config init : " .. collectgarbage("count") .. " kB"); | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
function basicCfgForm:closeForm () | ||
|
||
local value | ||
|
||
value = form.getValue ( self.compSwitch ) | ||
self.cfgData.switch = self:checkControl(value) | ||
system.pSave("switch",value) | ||
|
||
value = form.getValue ( self.compCtrlCenterShift ) | ||
self.cfgData.ctrlCenterShift = self:checkControl(value) | ||
system.pSave("ctrlCenterShift", value) | ||
|
||
value = form.getValue ( self.compF3bDistance ) | ||
if (value) then | ||
self.cfgData.f3bDistance=value | ||
system.pSave("f3bDistance", value) | ||
end | ||
|
||
value = form.getValue ( self.compF3fDistance ) | ||
if (value) then | ||
self.cfgData.f3fDistance=value | ||
system.pSave("f3fDistance", value) | ||
end | ||
|
||
value = form.getValue ( self.compSensorLat ) | ||
if (value and value>0) then | ||
self.gpsSensor:setSensorValue ( self.gpsSensor.lat, self.sensorList[value]) | ||
end | ||
|
||
value = form.getValue ( self.compSensorLon ) | ||
if (value and value>0) then | ||
self.gpsSensor:setSensorValue ( self.gpsSensor.lon, self.sensorList[value]) | ||
end | ||
|
||
value = form.getValue ( self.compSensorSpeed ) | ||
if (value and value>0) then | ||
self.gpsSensor:setSensorValue ( self.gpsSensor.speed, self.sensorList[value]) | ||
end | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
return basicCfgForm | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,377 @@ | ||
-- ############################################################################################### | ||
-- # F3F Tool for JETI DC/DS transmitters | ||
-- # Module: f3fRun | ||
-- # | ||
-- # Copyright (c) 2023 Frank Schreiber | ||
-- # | ||
-- # This program is free software: you can redistribute it and/or modify | ||
-- # it under the terms of the GNU General Public License as published by | ||
-- # the Free Software Foundation, either version 3 of the License, or | ||
-- # (at your option) any later version. | ||
-- # | ||
-- # This program 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 General Public License for more details. | ||
-- # | ||
-- # You should have received a copy of the GNU General Public License | ||
-- # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
-- # | ||
-- ############################################################################################### | ||
|
||
-- =============================================================================================== | ||
-- =============================================================================================== | ||
-- ========== Object: f3fRun ========== | ||
-- ========== contains the necessary logic for the run ========== | ||
-- =============================================================================================== | ||
-- =============================================================================================== | ||
|
||
local f3fRun = { | ||
-- this needs too much memory for monochrome TX, use Integer directly | ||
-- status = { INIT=1, ON_HOLD=2, STARTPHASE=3, TIMEOUT=4, F3F_RUN=5 }, | ||
|
||
curPosition = nil, -- current position of model | ||
curDist = nil, -- current distance from home position | ||
curBearing = nil, -- current angle from slope | ||
curDir = nil, -- current position on left/right side from home | ||
nextTurnDir = nil, -- side of expected next turn | ||
curSpeed = nil, -- current speed (given from sensor) | ||
|
||
-- values for gps-optimization | ||
-- maxOffset = 25, -- max. offset value in [m] at 150 km/h and 100% effect | ||
-- this constant not used here for memory optimization | ||
|
||
-- 'offsets' and 'inside-flags' for launch phase and f3f run. | ||
-- the values are always calculated independently from the current | ||
-- f3f-status. So we know where we are if a status change occurs | ||
-- (from launch phase to f3f run or in case of reset from f3f run to launch phase) | ||
-- the values can differ, because the considered offsets work in opposite directions. | ||
|
||
launchPhaseData = { offset=0, insideFlag=0 }, | ||
f3fRunData = { offset=0, insideFlag=0 }, | ||
|
||
-- other stuff | ||
curStatus = nil, | ||
rounds = 0, | ||
|
||
launchTime = 0, -- time of launch, 30 seconds started | ||
countdownTime = 0, -- countdown from launch (F3F) or tow hook release (F3B) to fly in | ||
remainingCountdown = 0, -- remaining countdown for start time | ||
halfDistance = 0, -- half length of the course, depending on f3f / f3b | ||
|
||
f3fStartTime = 0, -- start time of f3f-run | ||
flightTime = 0, | ||
|
||
timerStartSpeed = -1, -- timer for speed-measuring 1,5 sec. after start of f3f-run | ||
|
||
-- Object references from main program | ||
globalVar = nil, | ||
basicCfg = nil, | ||
slope = nil, | ||
gpsSensor = nil | ||
} | ||
|
||
-- function f3fRun:isStatus ( status ) return self.curStatus == status end | ||
-- nice function, but not used for memory optimization | ||
|
||
-------------------------------------------------------------------------------------------- | ||
function f3fRun:init () | ||
-- initial status | ||
-- self.curStatus = self.status.INIT | ||
self.curStatus = 1 | ||
self.curDir = self.globalVar.direction.UNDEF | ||
self.nextTurnDir = self.globalVar.direction.UNDEF | ||
|
||
if self.slope.mode == 2 then -- F3B | ||
self.halfDistance = self.basicCfg.f3bDistance / 2 | ||
|
||
if ( self.basicCfg.f3bMode == 1 ) then -- speed | ||
self.countdownTime = 60 | ||
elseif ( self.basicCfg.f3bMode == 2 ) then -- distance | ||
self.countdownTime = 0 | ||
end | ||
|
||
else -- F3F | ||
self.countdownTime = 30 | ||
self.halfDistance = self.basicCfg.f3fDistance / 2 | ||
end | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
function f3fRun:setNextTurnDir () | ||
|
||
-- set side of next turn | ||
if ( self.curDir == self.globalVar.direction.LEFT ) then | ||
self.nextTurnDir = self.globalVar.direction.RIGHT | ||
elseif ( f3fRun.curDir == self.globalVar.direction.RIGHT ) then | ||
self.nextTurnDir = self.globalVar.direction.LEFT | ||
end | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- launch: start button was pressed | ||
|
||
function f3fRun:launch () | ||
|
||
-- slope not defined? ? | ||
if ( self.globalVar.errorStatus == 4 ) then | ||
-- cancel - beep | ||
system.playBeep (2, 1000, 200) | ||
return | ||
end | ||
|
||
-- check, if sensors are active | ||
self.globalVar.errorStatus = 0 | ||
self.gpsSensor:getCurPosition () | ||
if ( self.globalVar.errorStatus ~= 0 ) then | ||
-- cancel - beep | ||
system.playBeep (2, 1000, 200) | ||
return | ||
end | ||
|
||
-- start launch phase | ||
-- self.curStatus = self.status.STARTPHASE | ||
self.curStatus = 3 | ||
self.rounds = 0 | ||
|
||
self.launchTime = system.getTimeCounter() | ||
self.remainingCountdown = self.countdownTime | ||
|
||
system.playFile (self.globalVar.resource.audioStart, AUDIO_IMMEDIATE) | ||
|
||
-- in F3F and F3B-Speed mode announce countdown time | ||
if ((self.slope.mode ~= 2) or (self.basicCfg.f3bMode ~= 2)) then | ||
system.playNumber (self.remainingCountdown, 0) | ||
system.playFile (self.globalVar.resource.audioSeconds, AUDIO_QUEUE) | ||
end | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- start run: A-Base was passed from outside course or timeout occurred | ||
|
||
function f3fRun:startRun ( timeout ) | ||
|
||
-- in F3B-Distance mode go directly on hold and just count legs | ||
if ((self.slope.mode == 2) and (self.basicCfg.f3bMode == 2)) then | ||
-- self.curStatus = self.status.ON_HOLD | ||
self.curStatus = 2 | ||
|
||
-- timeout - late entry ocurred | ||
elseif (timeout) then | ||
-- self.curStatus = self.status.TIMEOUT | ||
self.curStatus = 4 | ||
else | ||
-- regular f3f-start | ||
-- self.curStatus = self.status.F3F_RUN | ||
self.curStatus = 5 | ||
end | ||
|
||
self.f3fStartTime = system.getTimeCounter() | ||
system.playFile (self.globalVar.resource.audioCourse, AUDIO_QUEUE) | ||
|
||
-- start timer for speed measurement after 1,5 sec. | ||
-- if ( self.curSpeed and self.curStatus == self.status.F3F_RUN) then | ||
if ( self.curSpeed and self.curStatus == 5) then | ||
self.timerStartSpeed = system.getTimeCounter() | ||
end | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- distance done: A-Base or B-Base was passed from inside course | ||
|
||
function f3fRun:distanceDone () | ||
|
||
-- if we are not in a valid f3f-run - just beep to practise | ||
-- if (self.curStatus ~= self.status.F3F_RUN) then | ||
if (self.curStatus ~= 5) then | ||
system.playBeep (0, 700, 300) | ||
end | ||
|
||
-- in F3B-mode: count more rounds after 4 rounds (status 2: ON_HOLD) | ||
if ( (self.slope.mode == 2) and ( self.curStatus == 2)) then | ||
self.rounds = self.rounds+1 | ||
end | ||
|
||
local maxRounds | ||
if ( self.slope.mode == 1 ) then | ||
maxRounds = 10 -- F3F mode | ||
elseif ( self.slope.mode == 2 ) then | ||
maxRounds = 4 -- F3B mode | ||
end | ||
|
||
-- are we in f3f-run ? | ||
-- if ( self:isStatus (self.status.F3F_RUN) ) then | ||
if ( self.curStatus == 5 ) then | ||
|
||
-- one more leg done | ||
self.rounds = self.rounds+1 | ||
|
||
-- perform the appropriate beep | ||
if (self.rounds <= maxRounds-2 ) then | ||
system.playBeep (0, 700, 300) | ||
elseif (self.rounds == maxRounds-1 ) then | ||
system.playBeep (1, 700, 300) | ||
else | ||
system.playBeep (2, 850, 200) | ||
end | ||
|
||
-- from leg 8 make an announcement | ||
if ( self.rounds > maxRounds-3 and self.rounds < maxRounds ) then | ||
system.playNumber (self.rounds, 0) | ||
end | ||
|
||
-- all legs done - get flight time, change status | ||
if ( self.rounds >= maxRounds ) then | ||
local endTime = system.getTimeCounter() | ||
self.flightTime = endTime-self.f3fStartTime | ||
|
||
system.playFile (self.globalVar.resource.audioTime, AUDIO_QUEUE) | ||
system.playNumber (self.flightTime / 1000, 1) | ||
system.playFile (self.globalVar.resource.audioSeconds, AUDIO_QUEUE) | ||
|
||
-- self.curStatus = self.status.ON_HOLD | ||
self.curStatus = 2 | ||
end | ||
end | ||
|
||
-- set side of next turn | ||
self:setNextTurnDir () | ||
|
||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- calc remaining time for launch phase and give some announcements | ||
|
||
function f3fRun:countdown () | ||
|
||
-- skip countdown for F3B-Distance mode | ||
if ((self.slope.mode == 2) and (self.basicCfg.f3bMode == 2)) then | ||
return | ||
end | ||
|
||
local prevValue = self.remainingCountdown | ||
local curTime = system.getTimeCounter() | ||
self.remainingCountdown = math.floor (self.countdownTime - (curTime-self.launchTime)/1000) | ||
|
||
if (self.remainingCountdown ~= prevValue) then | ||
|
||
-- Announcement | ||
if ( (self.remainingCountdown >= 30 and self.remainingCountdown % 10 == 0) or | ||
(self.remainingCountdown < 30 and self.remainingCountdown % 5 == 0) or | ||
(self.remainingCountdown <= 10) ) then | ||
|
||
system.playNumber (self.remainingCountdown, 0) | ||
end | ||
end | ||
|
||
-- Timeout: start F3F run / cancel F3B run | ||
if ( self.remainingCountdown == 0 ) then | ||
|
||
if ( self.slope.mode == 1 ) then -- F3F | ||
self:startRun ( true ) | ||
elseif ( self.slope.mode == 2 ) then -- F3B | ||
system.playBeep (2, 500, 400) | ||
self:init () | ||
end | ||
end | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- update current position, distance and bearing data | ||
|
||
function f3fRun:updatePositionData ( point ) | ||
|
||
if ( not point ) then return end | ||
self.curPosition = point | ||
|
||
------ calc current distance | ||
if (self.slope.gpsHome) then | ||
self.curDist = gps.getDistance (self.slope.gpsHome, self.curPosition) | ||
end | ||
|
||
------ calc current flight angle to slope | ||
if ( self.slope.gpsHome and self.slope.bearing ) then | ||
|
||
-- current flight angle from north | ||
self.curBearing = gps.getBearing (self.slope.gpsHome, self.curPosition) | ||
|
||
-- current flight angle to slope | ||
self.curBearing = self.slope.bearing - self.curBearing | ||
if (self.curBearing < 0) then | ||
self.curBearing = self.curBearing + 360 | ||
end | ||
|
||
-- determine, on which side of home position the model is located | ||
-- curBearing always meant clockwise from flight line to slope | ||
|
||
if (self.curBearing <= 90 or self.curBearing > 270) then -- 0-90 deg, 270-360 deg | ||
self.curDir = self.globalVar.direction.RIGHT | ||
else | ||
self.curDir = self.globalVar.direction.LEFT -- 90-270 deg | ||
end | ||
|
||
end | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- update current speed from sensor, calculate optimization offsets | ||
-- the whole magic of GPS and latency optimization | ||
|
||
function f3fRun:updateSpeedAndOptimizationData ( speed ) | ||
|
||
self.curSpeed = speed | ||
|
||
if ( self.curSpeed ) then | ||
|
||
-- offset determination | ||
-- for memory optimization we don't use configurable parameters but calculate it here absolutely | ||
|
||
-- self.f3fRunData.offset = (self.curSpeed / (150/self.maxOffset)) * (self.basicCfg.speedFaktorF3F / self.basicCfg.maxSpeedFaktor) | ||
-- self.launchPhaseData.offset = (-1) * (((self.curSpeed / (150/self.maxOffset)) * (self.basicCfg.speedFaktorLaunchPhase / self.basicCfg.maxSpeedFaktor)) + self.basicCfg.statOffsetLaunchPhase) | ||
|
||
-- 1/(150/25) * (65 / 100) = 0.65/6 | ||
-- stat. Offset bei Start: 8 | ||
|
||
self.f3fRunData.offset = self.curSpeed * 0.65/6 | ||
-- *(-1): in launch phase the offset works in the opposite direction to optimize the first fly in | ||
-- also add a static offset, this brought better results in flying tests, can't explain why | ||
self.launchPhaseData.offset = (-1) * ((self.curSpeed * 0.65/6) + 8) | ||
end | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- check, if a fly out occurred, consider the calculated offsets and the turn line calculation | ||
-- based on the cosinus | ||
|
||
function f3fRun:checkFlyOut ( trackData ) | ||
|
||
if ( trackData.insideFlag and | ||
(self.curDist + trackData.offset) * math.abs ( math.cos (math.rad ( self.curBearing ))) | ||
> self.halfDistance) then | ||
|
||
trackData.insideFlag = false | ||
return true | ||
end | ||
|
||
return false | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- check, if a fly in occurred, consider the calculated offsets and the turn line calculation | ||
-- based on the cosinus | ||
|
||
function f3fRun:checkFlyIn ( trackData ) | ||
|
||
if ( not trackData.insideFlag and | ||
(self.curDist + trackData.offset) * math.abs ( math.cos (math.rad ( self.curBearing ))) | ||
< self.halfDistance) then | ||
|
||
trackData.insideFlag = true | ||
return true | ||
end | ||
|
||
return false | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
return f3fRun |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,337 @@ | ||
-- ############################################################################################### | ||
-- # F3F Tool for JETI DC/DS transmitters | ||
-- # Module: slopeMgrForm | ||
-- # | ||
-- # Copyright (c) 2023 Frank Schreiber | ||
-- # | ||
-- # This program is free software: you can redistribute it and/or modify | ||
-- # it under the terms of the GNU General Public License as published by | ||
-- # the Free Software Foundation, either version 3 of the License, or | ||
-- # (at your option) any later version. | ||
-- # | ||
-- # This program 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 General Public License for more details. | ||
-- # | ||
-- # You should have received a copy of the GNU General Public License | ||
-- # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
-- # | ||
-- ############################################################################################### | ||
|
||
-- =============================================================================================== | ||
-- =============================================================================================== | ||
-- ========== Object: slopeMgrForm ========== | ||
-- ========== contains form and functions for course setup ========== | ||
-- =============================================================================================== | ||
-- =============================================================================================== | ||
|
||
local slopeMgrForm = { | ||
-- referenced objects, set from outside | ||
dataDir = nil, | ||
globalVar = nil, | ||
slope = nil, | ||
gpsSens = nil, | ||
errorTable = nil, | ||
f3bDist = nil, | ||
handleErr = nil | ||
|
||
-- internal stuff | ||
displayName = "", | ||
action = "", -- display information | ||
checkBoxSlope = nil, -- checkBox components | ||
checkBoxBearingL = nil, | ||
checkBoxBearingR = nil, | ||
|
||
gpsNewHome = nil, -- new Center point | ||
gpsBearLeft = nil, -- left bearing point | ||
gpsBearRight = nil, -- right bearing point | ||
|
||
mode = nil, -- 1: F3F / 2: F3B | ||
} | ||
|
||
-------------------------------------------------------------------------------------------- | ||
function slopeMgrForm:setF3FSlopeSetup () | ||
form.setTitle ("Setup F3F-Slope") | ||
|
||
form.addRow(3) | ||
form.addLabel({label="Start:", width=65, font=FONT_BOLD}) | ||
form.addLabel({label="center point (starting pos.)", width=195}) | ||
self.checkBoxSlope = form.addCheckbox( false, nil, {enabled=false}) | ||
|
||
form.addRow(3) | ||
form.addLabel({label="Left:", width=65, font=FONT_BOLD}) | ||
form.addLabel({label="left Bearing point", width=195}) | ||
self.checkBoxBearingL = form.addCheckbox( false, nil, {enabled=false}) | ||
|
||
form.addRow(3) | ||
form.addLabel({label="Right:", width=65, font=FONT_BOLD}) | ||
form.addLabel({label="right bearing point", width=195}) | ||
self.checkBoxBearingR = form.addCheckbox( false, nil, {enabled=false}) | ||
|
||
form.setButton(1,"Start", ENABLED) | ||
form.setButton(2,"Left",ENABLED) | ||
form.setButton(3,"Right",ENABLED) | ||
form.setButton(4,"F3B",ENABLED) | ||
|
||
-- slope already defined ? | ||
if ( self.slope:isDefined () ) then | ||
self.displayName = self.slope.name | ||
self.action = string.format("%s-Slope (%.0f degrees)", self:getWindDir (self.slope.bearing) ) | ||
end | ||
|
||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
function slopeMgrForm:setF3BCourseSetup () | ||
form.setTitle ("Setup F3B-Course") | ||
|
||
form.addRow(3) | ||
form.addLabel({label="Start:", width=65, font=FONT_BOLD}) | ||
form.addLabel({label="starting position", width=195}) | ||
self.checkBoxBearingL = form.addCheckbox( false, nil, {enabled=false}) | ||
|
||
form.addRow(3) | ||
form.addLabel({label="Bear:", width=65, font=FONT_BOLD}) | ||
form.addLabel({label="bearing point", width=195}) | ||
self.checkBoxBearingR = form.addCheckbox( false, nil, {enabled=false}) | ||
|
||
-- form.setButton(1,"Start", ENABLED) | ||
form.setButton(1,"Start", ENABLED) | ||
form.setButton(2,"Bear",ENABLED) | ||
form.setButton(4,"F3F",ENABLED) | ||
|
||
-- course already defined ? | ||
if ( self.slope:isDefined () ) then | ||
self.displayName = self.slope.name | ||
self.action = string.format("F3B-course (%.0f degrees)", self.slope.bearing ) | ||
end | ||
|
||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
function slopeMgrForm:initSlopeForm (formID) | ||
|
||
local freeMem = collectgarbage("count"); | ||
|
||
-- clear memory for new challenge | ||
collectgarbage("collect") | ||
|
||
-- set initial F3F/F3B mode from slope object | ||
if ( not self.mode) then | ||
self.mode = self.slope.mode | ||
end | ||
if (self.mode == 2) then formID = 2 end | ||
|
||
-- reset display action | ||
self.action = "" | ||
|
||
-- show form for mode | ||
if ( formID == 1) then | ||
self:setF3FSlopeSetup () | ||
|
||
elseif ( formID == 2) then | ||
self:setF3BCourseSetup () | ||
end | ||
|
||
-- show a cancel button, until all points are scanned | ||
form.setButton(5, "Cancel", ENABLED) | ||
|
||
local freeMem = collectgarbage("count"); | ||
print("GC Count after slopemgr init : " .. freeMem .. " kB"); | ||
|
||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- get GPS-position from Sensor | ||
function slopeMgrForm:scanGpsPoint ( checkBox, successMsg ) | ||
|
||
local gpsPoint | ||
gpsPoint = self.gpsSens:getCurPosition () | ||
|
||
if (self.globalVar.errorStatus >0) then | ||
self.action = self.errorTable [self.globalVar.errorStatus][1].." " | ||
..self.errorTable [self.globalVar.errorStatus][2].." " | ||
..self.errorTable [self.globalVar.errorStatus][3] | ||
end | ||
|
||
if ( gpsPoint ) then | ||
-- set status information | ||
if ( checkBox ) then form.setValue(checkBox, true ) end | ||
if ( successMsg ) then self.action = successMsg end | ||
end | ||
|
||
return gpsPoint | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
function slopeMgrForm:handleF3FSlopeKeys(key) | ||
|
||
-- start button | ||
if(key==KEY_1) then | ||
self.gpsNewHome = self:scanGpsPoint ( self.checkBoxSlope, "Starting position set" ) | ||
|
||
-- button bearing left | ||
elseif(key==KEY_2) then | ||
self.gpsBearLeft = self:scanGpsPoint ( self.checkBoxBearingL, "Left bearing point set" ) | ||
|
||
-- button bearing right | ||
elseif(key==KEY_3) then | ||
self.gpsBearRight = self:scanGpsPoint ( self.checkBoxBearingR, "Right bearing point set" ) | ||
|
||
-- toggle to F3B-mode | ||
elseif(key==KEY_4) then | ||
if not ( self.gpsNewHome or self.gpsBearLeft or self.gpsBearRight ) then | ||
self.mode = 2 | ||
form.reinit (2) | ||
end | ||
end | ||
|
||
-- disable F3B mode and hide course name if scan is started | ||
if ( self.gpsNewHome or self.gpsBearLeft or self.gpsBearRight ) then | ||
form.setButton(4,"F3B",DISABLED) | ||
self.displayName = "" | ||
end | ||
|
||
-- data complete ? -> show slope bearing and enable OK | ||
if ( self.gpsNewHome and self.gpsBearLeft and self.gpsBearRight ) then | ||
|
||
local bearing = gps.getBearing ( self.gpsBearLeft, self.gpsBearRight ) | ||
self.action = string.format("%s-Slope (%.0f degrees)", self:getWindDir (bearing) ) | ||
|
||
form.setButton(5, "Ok", ENABLED) | ||
end | ||
|
||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
function slopeMgrForm:handleF3BCourseKeys(key) | ||
|
||
-- start button (start point will be our left point in F3B) | ||
if(key==KEY_1) then | ||
self.gpsBearLeft = self:scanGpsPoint ( self.checkBoxBearingL, "Starting position set" ) | ||
|
||
-- button bearing (will be our right point in F3B) | ||
elseif(key==KEY_2) then | ||
self.gpsBearRight = self:scanGpsPoint ( self.checkBoxBearingR, "Bearing point set" ) | ||
|
||
-- toggle to F3F-mode | ||
elseif(key==KEY_4) then | ||
if not ( self.gpsNewHome or self.gpsBearLeft or self.gpsBearRight ) then | ||
self.mode = 1 | ||
form.reinit (1) | ||
end | ||
end | ||
|
||
-- disable F3F mode and hide course name if scan is started | ||
if ( self.gpsNewHome or self.gpsBearLeft or self.gpsBearRight ) then | ||
form.setButton(4,"F3F",DISABLED) | ||
self.displayName = "" | ||
end | ||
|
||
-- data complete | ||
if ( self.gpsBearLeft and self.gpsBearRight ) then | ||
|
||
local bearing = gps.getBearing ( self.gpsBearLeft, self.gpsBearRight ) | ||
|
||
-- calc home position, half distance away from start | ||
self.gpsNewHome = gps.getDestination ( self.gpsBearLeft, self.f3bDist / 2, bearing ) | ||
self.action = string.format("F3B-course (%.0f degrees)", bearing ) | ||
|
||
form.setButton(5, "Ok", ENABLED) | ||
end | ||
|
||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- observe keys of scan page | ||
function slopeMgrForm:slopeScanKeyPressed(key) | ||
|
||
if self.mode == 1 then | ||
self:handleF3FSlopeKeys(key) | ||
elseif self.mode == 2 then | ||
self:handleF3BCourseKeys(key) | ||
end | ||
|
||
-- button OK / Cancel | ||
if(key==KEY_5) then | ||
|
||
if ( self.gpsNewHome and self.gpsBearLeft and self.gpsBearRight ) then | ||
-- set home and calc bearing | ||
self.slope.gpsHome = self.gpsNewHome | ||
self.slope.bearing = gps.getBearing ( self.gpsBearLeft, self.gpsBearRight ) | ||
|
||
self.slope.mode = self.mode | ||
-- F3B: A-Base always left, left Base is defined as start point | ||
if (self.mode == 2) then | ||
self.slope.aBase = self.globalVar.direction.LEFT | ||
end | ||
|
||
-- new scan has no name yet | ||
self.slope.name = nil | ||
|
||
-- save it | ||
self.slope:persist () | ||
-- ok - beep | ||
system.playBeep (0, 700, 300) | ||
|
||
else | ||
-- cancel - beep | ||
system.playBeep (2, 1000, 200) | ||
end | ||
|
||
end | ||
|
||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- calculate wind direction | ||
function slopeMgrForm:getWindDir ( bearing ) | ||
|
||
local windDir = -1 | ||
local windDirDesc = "undefined" | ||
|
||
local angle, low, high | ||
|
||
-- read wind direction descriptions from file | ||
local filespec = self.dataDir .. "/windDir-" ..self.globalVar.lng.. ".jsn" | ||
local desc | ||
local file = io.readall( filespec ) | ||
if( file ) then | ||
desc = json.decode(file) | ||
else | ||
self.handleErr ("can not open file: '" ..filespec .."'") | ||
end | ||
|
||
-- get wind direction from slope bearing | ||
if bearing < 90 then windDir = bearing + 270 else windDir = bearing - 90 end | ||
|
||
for i = 0, 15, 1 do | ||
angle = i * 22.5 | ||
|
||
-- calculate range for wind direction | ||
low = angle - 11.25 | ||
if low < 0 then low = low+360 end | ||
local high = angle + 11.25 | ||
if high > 360 then high = high -360 end | ||
|
||
-- inside ? | ||
if ( windDir > low and windDir < high) then | ||
if (desc) then windDirDesc = desc [i+1] end | ||
break | ||
end | ||
end | ||
return windDirDesc, windDir -- maybe: ( South, 185 ) | ||
end | ||
|
||
|
||
-------------------------------------------------------------------------------------------- | ||
function slopeMgrForm:printSlopeForm() | ||
if ( self.displayName and self.displayName ~= "" ) then | ||
lcd.drawText(20,90, self.displayName .. ":", FONT_BIG) | ||
end | ||
lcd.drawText(20,115, self.action, FONT_BIG) | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
return slopeMgrForm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
-- ############################################################################################### | ||
-- # F3F Tool for JETI DC/DS transmitters | ||
-- # Module: storeSens | ||
-- # | ||
-- # Copyright (c) 2023 Frank Schreiber | ||
-- # | ||
-- # This program is free software: you can redistribute it and/or modify | ||
-- # it under the terms of the GNU General Public License as published by | ||
-- # the Free Software Foundation, either version 3 of the License, or | ||
-- # (at your option) any later version. | ||
-- # | ||
-- # This program 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 General Public License for more details. | ||
-- # | ||
-- # You should have received a copy of the GNU General Public License | ||
-- # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
-- # | ||
-- ############################################################################################### | ||
|
||
-- =============================================================================================== | ||
-- =============================================================================================== | ||
-- ========== Object: storeSens ========== | ||
-- ========== contains functions for temporary sensor list in a file ========== | ||
-- ========== needed for memory optimization ========== | ||
-- =============================================================================================== | ||
-- =============================================================================================== | ||
|
||
local storeSens = {} | ||
|
||
-------------------------------------------------------------------------------------------- | ||
function storeSens:isIn (element, list) | ||
|
||
for i, elem in ipairs ( list ) do | ||
if elem == element then | ||
return true | ||
end | ||
end | ||
return false | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
-- save Sensor data in a file for later use | ||
-- part of memory optimization for Gen1 - Hardware | ||
|
||
function storeSens:storeSensorData ( dir, filename ) | ||
|
||
collectgarbage("collect") | ||
-- print(" init:" .. collectgarbage("count") .. " kB") | ||
|
||
-- save sensor information in a file | ||
local sysSensors = system.getSensors() -- system list of sensors and telemetry-entries | ||
|
||
-- look for sensor id's which contain an entry with type '9' (GPS Coordinates) | ||
local gpsIds = {} | ||
for index,sensor in ipairs(sysSensors) do | ||
|
||
local id = sensor.id | ||
if ( sensor.type == 9 ) then -- type '9' = GPS-coordinates | ||
if not self:isIn ( id, gpsIds ) then | ||
gpsIds [ #gpsIds+1 ] = id | ||
end | ||
end | ||
end | ||
|
||
-- build new table with reduced entries and reduced data per entry | ||
local newSens = {} | ||
for index,sensor in ipairs(sysSensors) do | ||
|
||
-- store only GPS-relevant telemetry entries | ||
if self:isIn ( sensor.id, gpsIds ) then | ||
local entry = { label=sensor.label, param = sensor.param, unit = sensor.unit } | ||
|
||
-- important: explicitly convert the id to decimal, otherwise it is written as float by the | ||
-- json encoder and corrupted by loss of precision ! | ||
entry.id = string.format ("%d", sensor.id ) | ||
|
||
-- add to new list | ||
newSens [ #newSens+1 ] = entry | ||
end | ||
|
||
sysSensors [ index ] = nil | ||
collectgarbage("collect") | ||
end | ||
|
||
-- save list for later use in sensor configuration | ||
|
||
local f = io.open ( dir.."/"..filename, "w" ) | ||
if ( f ) then | ||
io.write(f, json.encode ( newSens ), "\n") | ||
io.close ( f ) | ||
else | ||
print ( "ERROR: can not write file: " .. fSpec) | ||
end | ||
|
||
-- print (" init - sensor list: " .. collectgarbage("count") .. " kB"); | ||
|
||
-- cleanup | ||
sysSensors = nil | ||
newSens=nil | ||
collectgarbage("collect") | ||
|
||
-- print(" init - after collect: " .. collectgarbage("count") .. " kB"); | ||
end | ||
|
||
-------------------------------------------------------------------------------------------- | ||
return storeSens |