altos/test: Adjust CRC error rate after FEC fix
[fw/altos] / altoslib / AltosAccelCal.java
1 /*
2  * Copyright © 2017 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 package org.altusmetrum.altoslib_13;
20
21 import java.io.*;
22 import java.util.concurrent.*;
23
24 public class AltosAccelCal implements Runnable {
25
26         AltosLink               link;
27         AltosAccelCalListener   listener;
28
29         boolean                 remote;
30         boolean                 close_on_exit;
31         double                  frequency;
32         String                  callsign;
33
34         Thread                  accel_thread;
35
36         AltosConfigData         config_data;
37
38         public static final int phase_antenna_up = 0;
39         public static final int phase_antenna_down = 1;
40
41         void start_link() throws InterruptedException, TimeoutException {
42                 if (remote) {
43                         link.set_radio_frequency(frequency);
44                         link.set_callsign(callsign);
45                         link.start_remote();
46                 } else
47                         link.flush_input();
48         }
49
50         boolean stop_link() throws InterruptedException, TimeoutException {
51                 if (remote)
52                         link.stop_remote();
53                 return link.reply_abort;
54         }
55
56         public void set_frequency(double in_frequency) {
57                 frequency = in_frequency;
58                 link.abort_reply();
59         }
60
61         public void set_callsign(String in_callsign) {
62                 callsign = in_callsign;
63                 link.abort_reply();
64         }
65
66         public void abort() throws InterruptedException {
67                 while (accel_thread.isAlive()) {
68                         accel_thread.interrupt();
69                         link.abort_reply();
70                         Thread.sleep(100);
71                 }
72                 accel_thread.join();
73         }
74
75         static private final String press_msg = "press a key...";
76
77         private Semaphore ui_signal_semaphore;
78         private boolean ui_signal_reply;
79
80         public void signal(boolean reply) {
81                 System.out.printf("Signal cal semaphore %b\n", reply);
82                 ui_signal_reply = reply;
83                 ui_signal_semaphore.release();
84         }
85
86         private boolean wait_signal() throws InterruptedException {
87                 System.out.printf("\twait for cal signal...\n");
88                 ui_signal_semaphore.acquire();
89                 System.out.printf("\tgot cal signal %b\n", ui_signal_reply);
90                 return ui_signal_reply;
91         }
92
93         private boolean wait_press(int timeout) throws InterruptedException {
94                 for (;;) {
95                         String line = link.get_reply(timeout);
96                         if (line == null) {
97                                 System.out.printf("get_reply timeout\n");
98                                 return false;
99                         }
100                         System.out.printf("got line %s\n", line);
101                         if (line.contains(press_msg))
102                                 return true;
103                         if (line.contains("Invalid"))
104                                 return false;
105                         if (line.contains("Syntax"))
106                                 return false;
107                         if (line.contains("Calibrating"))
108                                 listener.message(this, line);
109                 }
110         }
111
112         static final int cal_timeout = 20 * 1000;
113
114         public void run() {
115                 System.out.printf("start accel cal procedure\n");
116                 try {
117                         AltosConfigData new_config = null;
118
119                         try {
120                                 start_link();
121                                 config_data = link.config_data();
122
123                                 /* set back to antenna up for calibration */
124                                 if (config_data.pad_orientation != 0)
125                                         link.printf("c o 0\n");
126
127                                 /* Start calibration */
128                                 try {
129                                         System.out.printf("*** start cal\n");
130                                         link.set_match(press_msg);
131                                         link.printf("c a 0\n");
132                                         System.out.printf("*** wait press\n");
133                                         if (!wait_press(cal_timeout))
134                                                 throw new TimeoutException("timeout");
135                                         System.out.printf("*** set_phase antenna_up\n");
136                                         listener.set_phase(this, phase_antenna_up);
137                                         System.out.printf("*** wait_signal\n");
138                                         if (!wait_signal())
139                                                 throw new InterruptedException("aborted");
140                                         link.set_match(press_msg);
141                                         System.out.printf("*** send newline\n");
142                                         link.printf("\n");
143                                         System.out.printf("*** wait press\n");
144                                         if (!wait_press(cal_timeout))
145                                                 throw new TimeoutException("timeout");
146                                         System.out.printf("***set_phase antenna_down\n");
147                                         listener.set_phase(this, phase_antenna_down);
148                                         System.out.printf("*** wait_signal\n");
149                                         if (!wait_signal())
150                                                 throw new InterruptedException("aborted");
151                                         System.out.printf("*** send newline and version command\n");
152                                         link.printf("\nv\n");
153                                 } catch (TimeoutException e) {
154                                         throw e;
155                                 } catch (InterruptedException e) {
156                                         throw e;
157                                 }
158                                 link.set_match(null);
159
160                                 boolean worked = true;
161                                 for (;;) {
162                                         String line = link.get_reply(cal_timeout);
163                                         if (line == null)
164                                                 throw new TimeoutException();
165                                         System.out.printf("*** waiting for finish: %s\n", line);
166                                         if (line.contains("Invalid"))
167                                                 worked = false;
168                                         if (line.contains("software-version"))
169                                                 break;
170                                         if (line.contains("Calibrating"))
171                                                 listener.message(this, line);
172                                 }
173                                 System.out.printf("*** worked: %b\n", worked);
174                                 if (worked)
175                                         new_config = new AltosConfigData(link);
176                         } finally {
177                                 int plus = config_data.accel_cal_plus(config_data.pad_orientation);
178                                 int minus = config_data.accel_cal_minus(config_data.pad_orientation);
179                                 System.out.printf("Restore orientation %d +g %d -g %d\n",
180                                                   config_data.pad_orientation,
181                                                   plus, minus);
182                                 if (config_data.pad_orientation != AltosLib.MISSING)
183                                         link.printf("c o %d\n", config_data.pad_orientation);
184                                 if (plus != AltosLib.MISSING && minus != AltosLib.MISSING)
185                                         link.printf("c a %d %d\n", plus, minus);
186                                 link.flush_output();
187                                 stop_link();
188                         }
189                         if (new_config != null) {
190                                 int plus = new_config.accel_cal_plus(AltosLib.AO_PAD_ORIENTATION_ANTENNA_UP);
191                                 int minus = new_config.accel_cal_minus(AltosLib.AO_PAD_ORIENTATION_ANTENNA_UP);
192                                 System.out.printf("*** +1g %d -1g %d\n", plus, minus);
193                                 listener.cal_done(this, plus, minus);
194                                 if (!wait_signal())
195                                         throw new InterruptedException("aborted");
196                         } else
197                                 listener.error(this, "Calibration failed");
198                 } catch (TimeoutException te) {
199                         System.out.printf("timeout");
200                         listener.error(this, "timeout");
201                 } catch (InterruptedException ie) {
202                         System.out.printf("interrupted\n");
203                         listener.error(this, "interrupted");
204                 }
205         }
206
207         public void start() {
208                 accel_thread = new Thread(this);
209                 listener.set_thread(this, accel_thread);
210                 accel_thread.start();
211         }
212
213         public AltosAccelCal(AltosLink link, AltosAccelCalListener listener) {
214                 this.link = link;
215                 this.listener = listener;
216                 ui_signal_semaphore = new Semaphore(0);
217         }
218 }