diff options
| author | Keith Packard <keithp@keithp.com> | 2011-08-08 01:47:29 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2011-08-08 12:13:29 -0700 | 
| commit | 0e3e4f9c1e6a6bf972514f12c9d622258aa2aec2 (patch) | |
| tree | c84c97e27556d0686bf26ea9e4f1af976cd9b1c7 | |
| parent | f03ca0ab8799bfa5100eaa2577cfd7b9c37d05bf (diff) | |
altosui: Convert from channels to frequencies
Major areas:
 * Preferences are stored as frequencies instead
   of channels
 * Serial configuration is done using frequencies
 * UI is presented with frequency lists
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | altosui/AltosConfig.java | 54 | ||||
| -rw-r--r-- | altosui/AltosConfigData.java | 4 | ||||
| -rw-r--r-- | altosui/AltosConfigFreqUI.java | 4 | ||||
| -rw-r--r-- | altosui/AltosConfigUI.java | 58 | ||||
| -rw-r--r-- | altosui/AltosConvert.java | 33 | ||||
| -rw-r--r-- | altosui/AltosEepromDelete.java | 15 | ||||
| -rw-r--r-- | altosui/AltosEepromDownload.java | 13 | ||||
| -rw-r--r-- | altosui/AltosFlightReader.java | 7 | ||||
| -rw-r--r-- | altosui/AltosFlightUI.java | 26 | ||||
| -rw-r--r-- | altosui/AltosFreqList.java | 87 | ||||
| -rw-r--r-- | altosui/AltosFrequency.java | 6 | ||||
| -rw-r--r-- | altosui/AltosIdleMonitorUI.java | 35 | ||||
| -rw-r--r-- | altosui/AltosIgnite.java | 37 | ||||
| -rw-r--r-- | altosui/AltosPreferences.java | 47 | ||||
| -rw-r--r-- | altosui/AltosScanUI.java | 125 | ||||
| -rw-r--r-- | altosui/AltosSerial.java | 72 | ||||
| -rw-r--r-- | altosui/AltosTelemetryReader.java | 27 | ||||
| -rw-r--r-- | altosui/AltosUI.java | 12 | ||||
| -rw-r--r-- | altosui/Makefile.am | 1 | 
19 files changed, 486 insertions, 177 deletions
| diff --git a/altosui/AltosConfig.java b/altosui/AltosConfig.java index 04d75528..694ef4db 100644 --- a/altosui/AltosConfig.java +++ b/altosui/AltosConfig.java @@ -64,6 +64,8 @@ public class AltosConfig implements ActionListener {  	AltosDevice	device;  	AltosSerial	serial_line;  	boolean		remote; +	AltosConfigData	remote_config_data; +	double		remote_frequency;  	int_ref		serial;  	int_ref		main_deploy;  	int_ref		apogee_delay; @@ -72,6 +74,7 @@ public class AltosConfig implements ActionListener {  	int_ref		flight_log_max;  	int_ref		ignite_mode;  	int_ref		pad_orientation; +	int_ref		radio_setting;  	string_ref	version;  	string_ref	product;  	string_ref	callsign; @@ -109,7 +112,7 @@ public class AltosConfig implements ActionListener {  		}  	} -	void start_serial() throws InterruptedException { +	void start_serial() throws InterruptedException, TimeoutException {  		serial_started = true;  		if (remote)  			serial_line.start_remote(); @@ -129,12 +132,13 @@ public class AltosConfig implements ActionListener {  		config_ui.set_version(version.get());  		config_ui.set_main_deploy(main_deploy.get());  		config_ui.set_apogee_delay(apogee_delay.get()); -		config_ui.set_radio_channel(radio_channel.get()); +		config_ui.set_radio_frequency(frequency());  		config_ui.set_radio_calibration(radio_calibration.get());  		config_ui.set_flight_log_max(flight_log_max.get());  		config_ui.set_ignite_mode(ignite_mode.get());  		config_ui.set_pad_orientation(pad_orientation.get());  		config_ui.set_callsign(callsign.get()); +		config_ui.set_radio_setting(radio_setting.get());  		config_ui.set_clean();  		config_ui.make_visible();  	} @@ -157,6 +161,7 @@ public class AltosConfig implements ActionListener {  		get_int(line, "Max flight log:", flight_log_max);  		get_int(line, "Ignite mode:", ignite_mode);  		get_int(line, "Pad orientation:", pad_orientation); +		get_int(line, "Radio setting:", radio_setting);  		get_string(line, "Callsign:", callsign);  		get_string(line,"software-version", version);  		get_string(line,"product", product); @@ -200,6 +205,7 @@ public class AltosConfig implements ActionListener {  					}  				}  			} catch (InterruptedException ie) { +			} catch (TimeoutException te) {  			} finally {  				try {  					stop_serial(); @@ -211,16 +217,20 @@ public class AltosConfig implements ActionListener {  		void save_data() {  			try { -				int	channel; +				double frequency = frequency(); +				boolean has_setting = radio_setting.get() != 0;  				start_serial();  				serial_line.printf("c m %d\n", main_deploy.get());  				serial_line.printf("c d %d\n", apogee_delay.get()); -				channel = radio_channel.get(); -				serial_line.printf("c r %d\n", channel); +				serial_line.set_radio_frequency(frequency, +								has_setting, +								radio_calibration.get());  				if (remote) {  					serial_line.stop_remote(); -					serial_line.set_channel(channel); -					AltosPreferences.set_channel(device.getSerial(), channel); +					serial_line.set_radio_frequency(frequency, +									has_setting, +									radio_calibration.get()); +					AltosPreferences.set_frequency(device.getSerial(), frequency);  					serial_line.start_remote();  				}  				if (!remote) @@ -234,6 +244,7 @@ public class AltosConfig implements ActionListener {  					serial_line.printf("c o %d\n", pad_orientation.get());  				serial_line.printf("c w\n");  			} catch (InterruptedException ie) { +			} catch (TimeoutException te) {  			} finally {  				try {  					stop_serial(); @@ -248,6 +259,7 @@ public class AltosConfig implements ActionListener {  				serial_line.printf("r eboot\n");  				serial_line.flush_output();  			} catch (InterruptedException ie) { +			} catch (TimeoutException te) {  			} finally {  				try {  					stop_serial(); @@ -308,11 +320,32 @@ public class AltosConfig implements ActionListener {  			update_ui();  	} +	double frequency() { +		int	setting = radio_setting.get(); + +		if (setting != 0) +			return AltosConvert.radio_setting_to_frequency(setting, radio_calibration.get()); +		else +			return AltosConvert.radio_channel_to_frequency(radio_channel.get()); +	} + +	void set_frequency(double freq) { +		int	setting = radio_setting.get(); + +		if (setting != 0) { +			radio_setting.set(AltosConvert.radio_frequency_to_setting(freq, +										  radio_calibration.get())); +			radio_channel.set(0); +		} else { +			radio_channel.set(AltosConvert.radio_frequency_to_channel(freq)); +		} +	} +  	void save_data() {  		main_deploy.set(config_ui.main_deploy());  		apogee_delay.set(config_ui.apogee_delay()); -		radio_channel.set(config_ui.radio_channel());  		radio_calibration.set(config_ui.radio_calibration()); +		set_frequency(config_ui.radio_frequency());  		flight_log_max.set(config_ui.flight_log_max());  		ignite_mode.set(config_ui.ignite_mode());  		pad_orientation.set(config_ui.pad_orientation()); @@ -348,6 +381,7 @@ public class AltosConfig implements ActionListener {  		main_deploy = new int_ref(250);  		apogee_delay = new int_ref(0);  		radio_channel = new int_ref(0); +		radio_setting = new int_ref(0);  		radio_calibration = new int_ref(1186611);  		flight_log_max = new int_ref(0);  		ignite_mode = new int_ref(-1); @@ -360,9 +394,9 @@ public class AltosConfig implements ActionListener {  		if (device != null) {  			try {  				serial_line = new AltosSerial(device); -				if (!device.matchProduct(Altos.product_telemetrum)) -					remote = true;  				try { +					if (!device.matchProduct(Altos.product_telemetrum)) +						remote = true;  					init_ui();  				} catch (InterruptedException ie) {  					abort(); diff --git a/altosui/AltosConfigData.java b/altosui/AltosConfigData.java index 1d50ade9..aa7a90de 100644 --- a/altosui/AltosConfigData.java +++ b/altosui/AltosConfigData.java @@ -47,6 +47,7 @@ public class AltosConfigData implements Iterable<String> {  	int	main_deploy;  	int	apogee_delay;  	int	radio_channel; +	int	radio_setting;  	String	callsign;  	int	accel_cal_plus, accel_cal_minus;  	int	radio_calibration; @@ -85,7 +86,7 @@ public class AltosConfigData implements Iterable<String> {  		serial_line.printf("c s\nv\n");  		lines = new LinkedList<String>();  		for (;;) { -			String line = serial_line.get_reply_no_dialog(5000); +			String line = serial_line.get_reply();  			if (line == null)  				throw new TimeoutException();  			if (line.contains("Syntax error")) @@ -95,6 +96,7 @@ public class AltosConfigData implements Iterable<String> {  			try { main_deploy = get_int(line, "Main deploy:"); } catch (Exception e) {}  			try { apogee_delay = get_int(line, "Apogee delay:"); } catch (Exception e) {}  			try { radio_channel = get_int(line, "Radio channel:"); } catch (Exception e) {} +			try { radio_setting = get_int(line, "Radio setting:"); } catch (Exception e) {}  			try {  				if (line.startsWith("Accel cal")) {  					String[] bits = line.split("\\s+"); diff --git a/altosui/AltosConfigFreqUI.java b/altosui/AltosConfigFreqUI.java index d68151ec..063d21b4 100644 --- a/altosui/AltosConfigFreqUI.java +++ b/altosui/AltosConfigFreqUI.java @@ -177,9 +177,9 @@ public class AltosConfigFreqUI extends JDialog implements ActionListener {  			int i;  			for (i = 0; i < list_model.size(); i++) {  				AltosFrequency	f = (AltosFrequency) list_model.get(i); -				if (f.frequency == frequency.frequency) +				if (frequency.frequency == f.frequency)  					return; -				if (f.frequency > frequency.frequency) +				if (frequency.frequency < f.frequency)  					break;  			}  			list_model.insertElementAt(frequency, i); diff --git a/altosui/AltosConfigUI.java b/altosui/AltosConfigUI.java index 1a48c1d3..c109924e 100644 --- a/altosui/AltosConfigUI.java +++ b/altosui/AltosConfigUI.java @@ -43,8 +43,9 @@ public class AltosConfigUI  	JLabel		serial_label;  	JLabel		main_deploy_label;  	JLabel		apogee_delay_label; -	JLabel		radio_channel_label; +	JLabel		frequency_label;  	JLabel		radio_calibration_label; +	JLabel		radio_frequency_label;  	JLabel		flight_log_max_label;  	JLabel		ignite_mode_label;  	JLabel		pad_orientation_label; @@ -58,7 +59,7 @@ public class AltosConfigUI  	JLabel		serial_value;  	JComboBox	main_deploy_value;  	JComboBox	apogee_delay_value; -	JComboBox	radio_channel_value; +	AltosFreqList	radio_frequency_value;  	JTextField	radio_calibration_value;  	JComboBox	flight_log_max_value;  	JComboBox	ignite_mode_value; @@ -98,13 +99,6 @@ public class AltosConfigUI  		"Antenna Down",  	}; -	static String[] radio_channel_values = new String[10]; -		{ -			for (int i = 0; i <= 9; i++) -				radio_channel_values[i] = String.format("Channel %1d (%7.3fMHz)", -									i, 434.550 + i * 0.1); -		} -  	/* A window listener to catch closing events and tell the config code */  	class ConfigListener extends WindowAdapter {  		AltosConfigUI	ui; @@ -245,7 +239,7 @@ public class AltosConfigUI  		apogee_delay_value.addItemListener(this);  		pane.add(apogee_delay_value, c); -		/* Radio channel */ +		/* Frequency */  		c = new GridBagConstraints();  		c.gridx = 0; c.gridy = 5;  		c.gridwidth = 4; @@ -253,8 +247,8 @@ public class AltosConfigUI  		c.anchor = GridBagConstraints.LINE_START;  		c.insets = il;  		c.ipady = 5; -		radio_channel_label = new JLabel("Radio Channel:"); -		pane.add(radio_channel_label, c); +		radio_frequency_label = new JLabel("Frequency:"); +		pane.add(radio_frequency_label, c);  		c = new GridBagConstraints();  		c.gridx = 4; c.gridy = 5; @@ -264,10 +258,9 @@ public class AltosConfigUI  		c.anchor = GridBagConstraints.LINE_START;  		c.insets = ir;  		c.ipady = 5; -		radio_channel_value = new JComboBox(radio_channel_values); -		radio_channel_value.setEditable(false); -		radio_channel_value.addItemListener(this); -		pane.add(radio_channel_value, c); +		radio_frequency_value = new AltosFreqList(); +		radio_frequency_value.addItemListener(this); +		pane.add(radio_frequency_value, c);  		/* Radio Calibration */  		c = new GridBagConstraints(); @@ -501,6 +494,7 @@ public class AltosConfigUI  	/* set and get all of the dialog values */  	public void set_product(String product) { +		radio_frequency_value.set_product(product);  		product_value.setText(product);  	} @@ -509,6 +503,7 @@ public class AltosConfigUI  	}  	public void set_serial(int serial) { +		radio_frequency_value.set_serial(serial);  		serial_value.setText(String.format("%d", serial));  	} @@ -528,12 +523,32 @@ public class AltosConfigUI  		return Integer.parseInt(apogee_delay_value.getSelectedItem().toString());  	} -	public void set_radio_channel(int new_radio_channel) { -		radio_channel_value.setSelectedIndex(new_radio_channel); +	public void set_radio_frequency(double new_radio_frequency) { +		int i; +		for (i = 0; i < radio_frequency_value.getItemCount(); i++) { +			AltosFrequency	f = (AltosFrequency) radio_frequency_value.getItemAt(i); +			 +			if (f.close(new_radio_frequency)) { +				radio_frequency_value.setSelectedIndex(i); +				return; +			} +		} +		for (i = 0; i < radio_frequency_value.getItemCount(); i++) { +			AltosFrequency	f = (AltosFrequency) radio_frequency_value.getItemAt(i); +			 +			if (new_radio_frequency < f.frequency) +				break; +		} +		String	description = String.format("%s serial %s", +						    product_value.getText(), +						    serial_value.getText()); +		AltosFrequency	new_frequency = new AltosFrequency(new_radio_frequency, description); +		AltosPreferences.add_common_frequency(new_frequency); +		radio_frequency_value.insertItemAt(new_frequency, i);  	} -	public int radio_channel() { -		return radio_channel_value.getSelectedIndex(); +	public double radio_frequency() { +		return radio_frequency_value.frequency();  	}  	public void set_radio_calibration(int new_radio_calibration) { @@ -548,6 +563,9 @@ public class AltosConfigUI  		callsign_value.setText(new_callsign);  	} +	public void set_radio_setting(int new_radio_setting) { +	} +  	public String callsign() {  		return callsign_value.getText();  	} diff --git a/altosui/AltosConvert.java b/altosui/AltosConvert.java index 8cc1df27..6a9b699c 100644 --- a/altosui/AltosConvert.java +++ b/altosui/AltosConvert.java @@ -189,4 +189,37 @@ public class AltosConvert {  	{  		return ignite / 32767 * 15.0;  	} + +	static double +	radio_setting_to_frequency(int setting, int cal) { +		double	f; + +		f = 434.550 * setting / cal; +		/* Round to nearest 50KHz */ +		f = Math.floor (20.0 * f + 0.5) / 20.0; +		return f; +	} + +	static int +	radio_frequency_to_setting(double frequency, int cal) { +		double	set = frequency / 434.550 * cal; + +		return (int) Math.floor (set + 0.5); +	} + +	static double +	radio_channel_to_frequency(int channel) { +		return 434.550 + channel * 0.100; +	} + +	static int +	radio_frequency_to_channel(double frequency) { +		int	channel = (int) Math.floor ((frequency - 434.550) / 0.100 + 0.5); + +		if (channel < 0) +			channel = 0; +		if (channel > 9) +			channel = 9; +		return channel; +	}  } diff --git a/altosui/AltosEepromDelete.java b/altosui/AltosEepromDelete.java index ecd82c18..94951ced 100644 --- a/altosui/AltosEepromDelete.java +++ b/altosui/AltosEepromDelete.java @@ -84,11 +84,11 @@ public class AltosEepromDelete implements Runnable {  	}  	public void run () { -		if (remote) -			serial_line.start_remote(); -  		success = false;  		try { +			if (remote) +				serial_line.start_remote(); +  			for (AltosEepromLog log : flights) {  				if (log.delete) {  					DeleteLog(log); @@ -103,11 +103,12 @@ public class AltosEepromDelete implements Runnable {  			show_error (String.format("Connection to \"%s\" failed",  						  serial_line.device.toShortString()),  				    "Connection Failed"); +		} finally { +			if (remote) +				serial_line.stop_remote(); +			serial_line.flush_output(); +			serial_line.close();  		} -		if (remote) -			serial_line.stop_remote(); -		serial_line.flush_output(); -		serial_line.close();  		if (listener != null) {  			Runnable r = new Runnable() {  					public void run() { diff --git a/altosui/AltosEepromDownload.java b/altosui/AltosEepromDownload.java index 82f01ef5..64dcdff7 100644 --- a/altosui/AltosEepromDownload.java +++ b/altosui/AltosEepromDownload.java @@ -264,11 +264,11 @@ public class AltosEepromDownload implements Runnable {  	}  	public void run () { -		if (remote) -			serial_line.start_remote(); -  		try {  			boolean	failed = false; +			if (remote) +				serial_line.start_remote(); +  			for (AltosEepromLog log : flights) {  				parse_exception = null;  				if (log.download) { @@ -295,11 +295,12 @@ public class AltosEepromDownload implements Runnable {  						   serial_line.device.toShortString()),  				     "Connection Failed",  				     JOptionPane.ERROR_MESSAGE); +		} finally { +			if (remote) +				serial_line.stop_remote(); +			serial_line.flush_output();  		} -		if (remote) -			serial_line.stop_remote();  		monitor.done(); -		serial_line.flush_output();  		if (listener != null) {  			Runnable r = new Runnable() {  					public void run() { diff --git a/altosui/AltosFlightReader.java b/altosui/AltosFlightReader.java index f665bda8..3a171444 100644 --- a/altosui/AltosFlightReader.java +++ b/altosui/AltosFlightReader.java @@ -20,6 +20,7 @@ package altosui;  import java.lang.*;  import java.text.*;  import java.io.*; +import java.util.concurrent.*;  public class AltosFlightReader {  	String name; @@ -32,9 +33,13 @@ public class AltosFlightReader {  	void close(boolean interrupted) { } -	void set_channel(int channel) { } +	void set_frequency(double frequency) throws InterruptedException, TimeoutException { } + +	void save_frequency() { }  	void set_telemetry(int telemetry) { } +	void save_telemetry() { } +  	void update(AltosState state) throws InterruptedException { }  } diff --git a/altosui/AltosFlightUI.java b/altosui/AltosFlightUI.java index 04bfc90d..8c3f821e 100644 --- a/altosui/AltosFlightUI.java +++ b/altosui/AltosFlightUI.java @@ -26,7 +26,7 @@ import java.io.*;  import java.util.*;  import java.text.*;  import java.util.prefs.*; -import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.*;  public class AltosFlightUI extends JFrame implements AltosFlightDisplay {  	AltosVoice		voice; @@ -118,7 +118,7 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {  	}  	Container	bag; -	JComboBox	channels; +	AltosFreqList	frequencies;  	JComboBox	telemetries;  	public AltosFlightUI(AltosVoice in_voice, AltosFlightReader in_reader, final int serial) { @@ -141,18 +141,25 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {  		/* Stick channel selector at top of table for telemetry monitoring */  		if (serial >= 0) {  			// Channel menu -			channels = new AltosChannelMenu(AltosPreferences.channel(serial)); -			channels.addActionListener(new ActionListener() { -				public void actionPerformed(ActionEvent e) { -					int channel = channels.getSelectedIndex(); -					reader.set_channel(channel); -				} +			frequencies = new AltosFreqList(AltosPreferences.frequency(serial)); +			frequencies.set_product("Monitor"); +			frequencies.set_serial(serial); +			frequencies.addActionListener(new ActionListener() { +					public void actionPerformed(ActionEvent e) { +						double frequency = frequencies.frequency(); +						reader.save_frequency(); +						try { +							reader.set_frequency(frequency); +						} catch (TimeoutException te) { +						} catch (InterruptedException ie) { +						} +					}  			});  			c.gridx = 0;  			c.gridy = 0;  			c.insets = new Insets(3, 3, 3, 3);  			c.anchor = GridBagConstraints.WEST; -			bag.add (channels, c); +			bag.add (frequencies, c);  			// Telemetry format menu  			telemetries = new JComboBox(); @@ -168,6 +175,7 @@ public class AltosFlightUI extends JFrame implements AltosFlightDisplay {  					public void actionPerformed(ActionEvent e) {  						int telemetry = telemetries.getSelectedIndex() + 1;  						reader.set_telemetry(telemetry); +						reader.save_telemetry();  					}  				});  			c.gridx = 1; diff --git a/altosui/AltosFreqList.java b/altosui/AltosFreqList.java new file mode 100644 index 00000000..59b0e127 --- /dev/null +++ b/altosui/AltosFreqList.java @@ -0,0 +1,87 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package altosui; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.*; +import java.io.*; +import java.util.*; +import java.text.*; +import java.util.prefs.*; +import java.util.concurrent.LinkedBlockingQueue; + +public class AltosFreqList extends JComboBox { + +	String	product; +	int	serial; +	int	calibrate; + +	public void set_frequency(double new_frequency) { +		int i; +		for (i = 0; i < getItemCount(); i++) { +			AltosFrequency	f = (AltosFrequency) getItemAt(i); +			 +			if (f.close(new_frequency)) { +				setSelectedIndex(i); +				return; +			} +		} +		for (i = 0; i < getItemCount(); i++) { +			AltosFrequency	f = (AltosFrequency) getItemAt(i); +			 +			if (new_frequency < f.frequency) +				break; +		} +		String	description = String.format("%s serial %d", product, serial); +		AltosFrequency	frequency = new AltosFrequency(new_frequency, description); +		AltosPreferences.add_common_frequency(frequency); +		insertItemAt(frequency, i); +		setMaximumRowCount(getItemCount()); +	} + +	public void set_product(String new_product) { +		product = new_product; +	} +		 +	public void set_serial(int new_serial) { +		serial = new_serial; +	} + +	public double frequency() { +		AltosFrequency	f = (AltosFrequency) getSelectedItem(); +		if (f != null) +			return f.frequency; +		return 434.550; +	} + +	public AltosFreqList () { +		super(AltosPreferences.common_frequencies()); +		setMaximumRowCount(getItemCount()); +		setEditable(false); +		product = "Unknown"; +		serial = 0; +	} + +	public AltosFreqList(double in_frequency) { +		this(); +		set_frequency(in_frequency); +	} +} diff --git a/altosui/AltosFrequency.java b/altosui/AltosFrequency.java index 8265eafc..0617ce74 100644 --- a/altosui/AltosFrequency.java +++ b/altosui/AltosFrequency.java @@ -44,6 +44,12 @@ public class AltosFrequency {  				     frequency, description);  	} +	public boolean close(double f) { +		double	diff = Math.abs(frequency - f); + +		return diff < 0.010; +	} +  	public AltosFrequency(double f, String d) {  		frequency = f;  		description = d; diff --git a/altosui/AltosIdleMonitorUI.java b/altosui/AltosIdleMonitorUI.java index a4262cae..0370efa9 100644 --- a/altosui/AltosIdleMonitorUI.java +++ b/altosui/AltosIdleMonitorUI.java @@ -167,7 +167,7 @@ class AltosIdleMonitor extends Thread {  	AltosIdleMonitorUI	ui;  	AltosState		state;  	boolean			remote; -	int			channel; +	double			frequency;  	AltosState		previous_state;  	AltosConfigData		config_data;  	AltosADC		adc; @@ -178,7 +178,7 @@ class AltosIdleMonitor extends Thread {  		try {  			if (remote) { -				set_channel(channel); +				serial.set_radio_frequency(frequency);  				serial.start_remote();  			} else  				serial.flush_input(); @@ -217,8 +217,8 @@ class AltosIdleMonitor extends Thread {  		state = new AltosState (record, state);  	} -	void set_channel(int in_channel) { -		channel = in_channel; +	void set_frequency(double in_frequency) { +		frequency = in_frequency;  	}  	public void post_state() { @@ -246,7 +246,7 @@ class AltosIdleMonitor extends Thread {  	}  	public AltosIdleMonitor(AltosIdleMonitorUI in_ui, AltosDevice in_device, boolean in_remote) -		throws FileNotFoundException, AltosSerialInUseException { +		throws FileNotFoundException, AltosSerialInUseException, InterruptedException, TimeoutException {  		device = in_device;  		ui = in_ui;  		serial = new AltosSerial(device); @@ -299,9 +299,10 @@ public class AltosIdleMonitorUI extends JFrame implements AltosFlightDisplay {  	}  	Container	bag; -	JComboBox	channels; +	AltosFreqList	frequencies; -	public AltosIdleMonitorUI(JFrame in_owner) throws FileNotFoundException, AltosSerialInUseException { +	public AltosIdleMonitorUI(JFrame in_owner) +		throws FileNotFoundException, AltosSerialInUseException, TimeoutException, InterruptedException {  		device = AltosDeviceDialog.show(in_owner, Altos.product_any);  		remote = false; @@ -320,21 +321,23 @@ public class AltosIdleMonitorUI extends JFrame implements AltosFlightDisplay {  		setTitle(String.format("AltOS %s", device.toShortString())); -		/* Stick channel selector at top of table for telemetry monitoring */ +		/* Stick frequency selector at top of table for telemetry monitoring */  		if (remote && serial >= 0) { -			// Channel menu -			channels = new AltosChannelMenu(AltosPreferences.channel(serial)); -			channels.addActionListener(new ActionListener() { -				public void actionPerformed(ActionEvent e) { -					int channel = channels.getSelectedIndex(); -					thread.set_channel(channel); -				} +			// Frequency menu +			frequencies = new AltosFreqList(AltosPreferences.frequency(serial)); +			frequencies.addActionListener(new ActionListener() { +					public void actionPerformed(ActionEvent e) { +						double frequency = frequencies.frequency(); +						thread.set_frequency(frequency); +						AltosPreferences.set_frequency(device.getSerial(), +									       frequency); +					}  			});  			c.gridx = 0;  			c.gridy = 0;  			c.insets = new Insets(3, 3, 3, 3);  			c.anchor = GridBagConstraints.WEST; -			bag.add (channels, c); +			bag.add (frequencies, c);  		} diff --git a/altosui/AltosIgnite.java b/altosui/AltosIgnite.java index 7a06c63d..3e52ea36 100644 --- a/altosui/AltosIgnite.java +++ b/altosui/AltosIgnite.java @@ -40,7 +40,7 @@ public class AltosIgnite {  	final static int	Active = 2;  	final static int	Open = 3; -	private void start_serial() throws InterruptedException { +	private void start_serial() throws InterruptedException, TimeoutException {  		serial_started = true;  		if (remote)  			serial.start_remote(); @@ -102,22 +102,25 @@ public class AltosIgnite {  		if (serial == null)  			return status;  		string_ref status_name = new string_ref(); -		start_serial(); -		serial.printf("t\n"); -		for (;;) { -			String line = serial.get_reply(5000); -			if (line == null) -				throw new TimeoutException(); -			if (get_string(line, "Igniter: drogue Status: ", status_name)) -				if (igniter == Apogee) -					status = status(status_name.get()); -			if (get_string(line, "Igniter:   main Status: ", status_name)) { -				if (igniter == Main) -					status = status(status_name.get()); -				break; +		try { +			start_serial(); +			serial.printf("t\n"); +			for (;;) { +				String line = serial.get_reply(5000); +				if (line == null) +					throw new TimeoutException(); +				if (get_string(line, "Igniter: drogue Status: ", status_name)) +					if (igniter == Apogee) +						status = status(status_name.get()); +				if (get_string(line, "Igniter:   main Status: ", status_name)) { +					if (igniter == Main) +						status = status(status_name.get()); +					break; +				}  			} +		} finally { +			stop_serial();  		} -		stop_serial();  		return status;  	} @@ -145,6 +148,7 @@ public class AltosIgnite {  				break;  			}  		} catch (InterruptedException ie) { +		} catch (TimeoutException te) {  		} finally {  			try {  				stop_serial(); @@ -166,7 +170,8 @@ public class AltosIgnite {  		serial.set_frame(frame);  	} -	public AltosIgnite(AltosDevice in_device) throws FileNotFoundException, AltosSerialInUseException { +	public AltosIgnite(AltosDevice in_device) +		throws FileNotFoundException, AltosSerialInUseException, TimeoutException, InterruptedException {  		device = in_device;  		serial = new AltosSerial(device); diff --git a/altosui/AltosPreferences.java b/altosui/AltosPreferences.java index e92b9532..8609f94e 100644 --- a/altosui/AltosPreferences.java +++ b/altosui/AltosPreferences.java @@ -34,6 +34,9 @@ class AltosPreferences {  	/* channel preference name */  	final static String channelPreferenceFormat = "CHANNEL-%d"; +	/* frequency preference name */ +	final static String frequencyPreferenceFormat = "FREQUENCY-%d"; +  	/* telemetry format preference name */  	final static String telemetryPreferenceFormat = "TELEMETRY-%d"; @@ -61,9 +64,6 @@ class AltosPreferences {  	/* Map directory -- hangs of logdir */  	static File mapdir; -	/* Channel (map serial to channel) */ -	static Hashtable<Integer, Integer> channels; -  	/* Frequency (map serial to frequency) */  	static Hashtable<Integer, Double> frequencies; @@ -148,7 +148,7 @@ class AltosPreferences {  		if (!mapdir.exists())  			mapdir.mkdirs(); -		channels = new Hashtable<Integer,Integer>(); +		frequencies = new Hashtable<Integer, Double>();  		telemetries = new Hashtable<Integer,Integer>(); @@ -242,20 +242,24 @@ class AltosPreferences {  		return mapdir;  	} -	public static void set_channel(int serial, int new_channel) { -		channels.put(serial, new_channel); +	public static void set_frequency(int serial, double new_frequency) { +		frequencies.put(serial, new_frequency);  		synchronized (preferences) { -			preferences.putInt(String.format(channelPreferenceFormat, serial), new_channel); +			preferences.putDouble(String.format(frequencyPreferenceFormat, serial), new_frequency);  			flush_preferences();  		}  	} -	public static int channel(int serial) { -		if (channels.containsKey(serial)) -			return channels.get(serial); -		int channel = preferences.getInt(String.format(channelPreferenceFormat, serial), 0); -		channels.put(serial, channel); -		return channel; +	public static double frequency(int serial) { +		if (frequencies.containsKey(serial)) +			return frequencies.get(serial); +		double frequency = preferences.getDouble(String.format(frequencyPreferenceFormat, serial), 0); +		if (frequency == 0.0) { +			int channel = preferences.getInt(String.format(channelPreferenceFormat, serial), 0); +			frequency = AltosConvert.radio_channel_to_frequency(channel); +		} +		frequencies.put(serial, frequency); +		return frequency;  	}  	public static void set_telemetry(int serial, int new_telemetry) { @@ -339,4 +343,21 @@ class AltosPreferences {  			flush_preferences();  		}  	} + +	public static void add_common_frequency(AltosFrequency frequency) { +		AltosFrequency[]	new_frequencies = new AltosFrequency[common_frequencies.length + 1]; +		int			i; + +		for (i = 0; i < common_frequencies.length; i++) { +			if (frequency.frequency == common_frequencies[i].frequency) +				return; +			if (frequency.frequency < common_frequencies[i].frequency) +				break; +			new_frequencies[i] = common_frequencies[i]; +		} +		new_frequencies[i] = frequency; +		for (; i < common_frequencies.length; i++) +			new_frequencies[i+1] = common_frequencies[i]; +		set_common_frequencies(new_frequencies); +	}  } diff --git a/altosui/AltosScanUI.java b/altosui/AltosScanUI.java index 96cab73b..9a483138 100644 --- a/altosui/AltosScanUI.java +++ b/altosui/AltosScanUI.java @@ -33,27 +33,27 @@ class AltosScanResult {  	String	callsign;  	int	serial;  	int	flight; -	int	channel; +	double	frequency;  	int	telemetry;  	boolean	interrupted = false;  	public String toString() { -		return String.format("%-9.9s serial %-4d flight %-4d (channel %-2d %s)", -				     callsign, serial, flight, channel, Altos.telemetry_name(telemetry)); +		return String.format("%-9.9s serial %-4d flight %-4d (frequency %7.3f %s)", +				     callsign, serial, flight, frequency, Altos.telemetry_name(telemetry));  	}  	public String toShortString() { -		return String.format("%s %d %d %d %d", -				     callsign, serial, flight, channel, telemetry); +		return String.format("%s %d %d %7.3f %d", +				     callsign, serial, flight, frequency, telemetry);  	}  	public AltosScanResult(String in_callsign, int in_serial, -			       int in_flight, int in_channel, int in_telemetry) { +			       int in_flight, double in_frequency, int in_telemetry) {  		callsign = in_callsign;  		serial = in_serial;  		flight = in_flight; -		channel = in_channel; +		frequency = in_frequency;  		telemetry = in_telemetry;  	} @@ -61,7 +61,7 @@ class AltosScanResult {  		return (callsign.equals(other.callsign) &&  			serial == other.serial &&  			flight == other.flight && -			channel == other.channel && +			frequency == other.frequency &&  			telemetry == other.telemetry);  	}  } @@ -107,20 +107,25 @@ public class AltosScanUI  {  	AltosUI				owner;  	AltosDevice			device; +	AltosConfigData			config_data;  	AltosTelemetryReader		reader;  	private JList			list;  	private JLabel			scanning_label; +	private JLabel			frequency_label; +	private JLabel			telemetry_label;  	private JButton			cancel_button;  	private JButton			monitor_button;  	javax.swing.Timer		timer;  	AltosScanResults		results = new AltosScanResults();  	int				telemetry; -	int				channel; +	double				frequency;  	final static int		timeout = 1200;  	TelemetryHandler		handler;  	Thread				thread; +	AltosFrequency[]		frequencies; +	int				frequency_index;  	void scan_exception(Exception e) {  		if (e instanceof FileNotFoundException) { @@ -167,7 +172,7 @@ public class AltosScanUI  							final AltosScanResult	result = new AltosScanResult(record.callsign,  												     record.serial,  												     record.flight, -												     channel, +												     frequency,  												     telemetry);  							Runnable r = new Runnable() {  									public void run() { @@ -190,26 +195,30 @@ public class AltosScanUI  	}  	void set_label() { -		scanning_label.setText(String.format("Scanning: channel %d %s", -						     channel, -						     Altos.telemetry_name(telemetry))); +		frequency_label.setText(String.format("Frequency: %s", frequencies[frequency_index].toString())); +		telemetry_label.setText(String.format("Telemetry: %s", Altos.telemetry_name(telemetry)));  	} -	void next() { +	void set_telemetry() { +		reader.set_telemetry(telemetry); +	} +	 +	void set_frequency() throws InterruptedException, TimeoutException { +		reader.set_frequency(frequencies[frequency_index].frequency); +	} +	 +	void next() throws InterruptedException, TimeoutException {  		reader.serial.set_monitor(false); -		try { -			Thread.sleep(100); -		} catch (InterruptedException ie){ -		} -		++channel; -		if (channel > 9) { -			channel = 0; +		Thread.sleep(100); +		++frequency_index; +		if (frequency_index >= frequencies.length) { +			frequency_index = 0;  			++telemetry;  			if (telemetry > Altos.ao_telemetry_max)  				telemetry = Altos.ao_telemetry_min; -			reader.serial.set_telemetry(telemetry); +			set_telemetry();  		} -		reader.serial.set_channel(channel); +		set_frequency();  		set_label();  		reader.serial.set_monitor(true);  	} @@ -229,31 +238,37 @@ public class AltosScanUI  		dispose();  	} -	void tick_timer() { +	void tick_timer() throws InterruptedException, TimeoutException {  		next();  	}  	public void actionPerformed(ActionEvent e) {  		String cmd = e.getActionCommand(); -		if (cmd.equals("cancel")) -			close(); - -		if (cmd.equals("tick")) -			tick_timer(); - -		if (cmd.equals("monitor")) { -			close(); -			AltosScanResult	r = (AltosScanResult) (list.getSelectedValue()); -			if (r != null) { -				if (device != null) { -					if (reader != null) { -						reader.set_telemetry(r.telemetry); -						reader.set_channel(r.channel); -						owner.telemetry_window(device); +		try { +			if (cmd.equals("cancel")) +				close(); + +			if (cmd.equals("tick")) +				tick_timer(); + +			if (cmd.equals("monitor")) { +				close(); +				AltosScanResult	r = (AltosScanResult) (list.getSelectedValue()); +				if (r != null) { +					if (device != null) { +						if (reader != null) { +							reader.set_telemetry(r.telemetry); +							reader.set_frequency(r.frequency); +							owner.telemetry_window(device); +						}  					}  				}  			} +		} catch (TimeoutException te) { +			close(); +		} catch (InterruptedException ie) { +			close();  		}  	} @@ -278,8 +293,8 @@ public class AltosScanUI  			return false;  		try {  			reader = new AltosTelemetryReader(device); -			reader.serial.set_channel(channel); -			reader.serial.set_telemetry(telemetry); +			set_frequency(); +			set_telemetry();  			try {  				Thread.sleep(100);  			} catch (InterruptedException ie) { @@ -306,6 +321,16 @@ public class AltosScanUI  						      device.toShortString(),  						      "Unkonwn I/O error",  						      JOptionPane.ERROR_MESSAGE); +		} catch (TimeoutException te) { +			JOptionPane.showMessageDialog(owner, +						      device.toShortString(), +						      "Timeout error", +						      JOptionPane.ERROR_MESSAGE); +		} catch (InterruptedException ie) { +			JOptionPane.showMessageDialog(owner, +						      device.toShortString(), +						      "Interrupted exception", +						      JOptionPane.ERROR_MESSAGE);  		}  		if (reader != null)  			reader.close(false); @@ -316,7 +341,8 @@ public class AltosScanUI  		owner = in_owner; -		channel = 0; +		frequencies = AltosPreferences.common_frequencies(); +		frequency_index = 0;  		telemetry = Altos.ao_telemetry_min;  		if (!open()) @@ -335,11 +361,13 @@ public class AltosScanUI  		pane.setLayout(new GridBagLayout());  		scanning_label = new JLabel("Scanning:"); +		frequency_label = new JLabel(""); +		telemetry_label = new JLabel("");  		set_label();  		c.fill = GridBagConstraints.NONE; -		c.anchor = GridBagConstraints.CENTER; +		c.anchor = GridBagConstraints.WEST;  		c.insets = i;  		c.weightx = 1;  		c.weighty = 1; @@ -347,9 +375,12 @@ public class AltosScanUI  		c.gridx = 0;  		c.gridy = 0;  		c.gridwidth = 2; -		c.anchor = GridBagConstraints.CENTER;  		pane.add(scanning_label, c); +		c.gridy = 1; +		pane.add(frequency_label, c); +		c.gridy = 2; +		pane.add(telemetry_label, c);  		list = new JList(results) {  				//Subclass JList to workaround bug 4832765, which can cause the @@ -417,7 +448,7 @@ public class AltosScanUI  		c.weighty = 1;  		c.gridx = 0; -		c.gridy = 1; +		c.gridy = 3;  		c.gridwidth = 2;  		c.anchor = GridBagConstraints.CENTER; @@ -434,7 +465,7 @@ public class AltosScanUI  		c.weighty = 1;  		c.gridx = 0; -		c.gridy = 2; +		c.gridy = 4;  		c.gridwidth = 1;  		c.anchor = GridBagConstraints.CENTER; @@ -451,7 +482,7 @@ public class AltosScanUI  		c.weighty = 1;  		c.gridx = 1; -		c.gridy = 2; +		c.gridy = 4;  		c.gridwidth = 1;  		c.anchor = GridBagConstraints.CENTER; diff --git a/altosui/AltosSerial.java b/altosui/AltosSerial.java index f45aa18b..6c687f5f 100644 --- a/altosui/AltosSerial.java +++ b/altosui/AltosSerial.java @@ -54,11 +54,12 @@ public class AltosSerial implements Runnable {  	int line_count;  	boolean monitor_mode;  	int telemetry; -	int channel; +	double frequency;  	static boolean debug;  	boolean remote;  	LinkedList<String> pending_output = new LinkedList<String>();  	Frame frame; +	AltosConfigData	config_data;  	static void set_debug(boolean new_debug) {  		debug = new_debug; @@ -154,7 +155,7 @@ public class AltosSerial implements Runnable {  		Object[] options = { "Cancel" };  		JOptionPane	pane = new JOptionPane(); -		pane.setMessage(String.format("Connecting to %s", device.getPath())); +		pane.setMessage(String.format("Connecting to %s, %7.3f MHz", device.toShortString(), frequency));  		pane.setOptions(options);  		pane.setInitialValue(null); @@ -208,20 +209,13 @@ public class AltosSerial implements Runnable {  		} while (got_some);  	} -	public String get_reply() throws InterruptedException { -		if (SwingUtilities.isEventDispatchThread()) -			System.out.printf("Uh-oh, reading serial device from swing thread\n"); -		flush_output(); -		AltosLine line = reply_queue.take(); -		return line.line; -	} -  	int	in_reply;  	public String get_reply(int timeout) throws InterruptedException {  		boolean	can_cancel = true;  		++in_reply; +		System.out.printf("get_reply %d\n", timeout);  		if (SwingUtilities.isEventDispatchThread()) {  			can_cancel = false;  			System.out.printf("Uh-oh, reading serial device from swing thread\n"); @@ -239,7 +233,6 @@ public class AltosSerial implements Runnable {  				--in_reply;  				return line.line;  			} -			System.out.printf("no line remote %b can_cancel %b\n", remote, can_cancel);  			if (!remote || !can_cancel || check_timeout()) {  				--in_reply;  				return null; @@ -247,8 +240,13 @@ public class AltosSerial implements Runnable {  		}  	} +	public String get_reply() throws InterruptedException { +		return get_reply(5000); +	} +  	public String get_reply_no_dialog(int timeout) throws InterruptedException, TimeoutException {  		flush_output(); +		System.out.printf("get_reply_no_dialog\n");  		AltosLine line = reply_queue.poll(timeout, TimeUnit.MILLISECONDS);  		if (line != null)  			return line.line; @@ -267,6 +265,8 @@ public class AltosSerial implements Runnable {  	}  	public void close() { +		if (remote) +			stop_remote();  		if (in_reply != 0)  			System.out.printf("Uh-oh. Closing active serial device\n"); @@ -328,19 +328,11 @@ public class AltosSerial implements Runnable {  		flush_output();  	} -	public void set_radio() { -		telemetry = AltosPreferences.telemetry(device.getSerial()); -		channel = AltosPreferences.channel(device.getSerial()); -		set_channel(channel); -		set_callsign(AltosPreferences.callsign()); -	} -  	private int telemetry_len() {  		return Altos.telemetry_len(telemetry);  	} -	public void set_channel(int in_channel) { -		channel = in_channel; +	private void set_channel(int channel) {  		if (altos != null) {  			if (monitor_mode)  				printf("m 0\nc r %d\nm %x\n", @@ -351,6 +343,33 @@ public class AltosSerial implements Runnable {  		}  	} +	private void set_radio_setting(int setting) { +		if (altos != null) { +			if (monitor_mode) +				printf("m 0\nc R %d\nc r 0\nm %x\n", +				       setting, telemetry_len()); +			else +				printf("c R %d\nc r 0\n", setting); +		} +	} + +	public void set_radio_frequency(double frequency, +					boolean has_setting, +					int cal) { +		if (has_setting) +			set_radio_setting(AltosConvert.radio_frequency_to_setting(frequency, cal)); +		else +			set_channel(AltosConvert.radio_frequency_to_channel(frequency)); +	} + +	public void set_radio_frequency(double in_frequency) throws InterruptedException, TimeoutException { +		frequency = in_frequency; +		config_data(); +		set_radio_frequency(frequency, +				    config_data.radio_setting != 0, +				    config_data.radio_calibration); +	} +  	public void set_telemetry(int in_telemetry) {  		telemetry = in_telemetry;  		if (altos != null) { @@ -378,10 +397,19 @@ public class AltosSerial implements Runnable {  		}  	} -	public void start_remote() { +	public AltosConfigData config_data() throws InterruptedException, TimeoutException { +		if (config_data == null) +			config_data = new AltosConfigData(this); +		return config_data; +	} + +	public void start_remote() throws TimeoutException, InterruptedException {  		if (debug)  			System.out.printf("start remote\n"); -		set_radio(); +		if (frequency == 0.0) +			frequency = AltosPreferences.frequency(device.getSerial()); +		set_radio_frequency(frequency); +		set_callsign(AltosPreferences.callsign());  		printf("p\nE 0\n");  		flush_input();  		remote = true; diff --git a/altosui/AltosTelemetryReader.java b/altosui/AltosTelemetryReader.java index 23524b2c..4512e761 100644 --- a/altosui/AltosTelemetryReader.java +++ b/altosui/AltosTelemetryReader.java @@ -27,6 +27,9 @@ class AltosTelemetryReader extends AltosFlightReader {  	AltosSerial	serial;  	AltosLog	log;  	AltosRecord	previous; +	AltosConfigData	config_data; +	double		frequency; +	int		telemetry;  	LinkedBlockingQueue<AltosLine> telem; @@ -49,18 +52,26 @@ class AltosTelemetryReader extends AltosFlightReader {  		serial.close();  	} -	void set_channel(int channel) { -		serial.set_channel(channel); -		AltosPreferences.set_channel(device.getSerial(), channel); +	public void set_frequency(double in_frequency) throws InterruptedException, TimeoutException { +		frequency = in_frequency; +		serial.set_radio_frequency(frequency);  	} -	void set_telemetry(int telemetry) { +	void save_frequency() { +		AltosPreferences.set_frequency(device.getSerial(), frequency); +	} + +	void set_telemetry(int in_telemetry) { +		telemetry = in_telemetry;  		serial.set_telemetry(telemetry); +	} + +	void save_telemetry() {  		AltosPreferences.set_telemetry(device.getSerial(), telemetry);  	}  	public AltosTelemetryReader (AltosDevice in_device) -		throws FileNotFoundException, AltosSerialInUseException, IOException { +		throws FileNotFoundException, AltosSerialInUseException, IOException, InterruptedException, TimeoutException {  		device = in_device;  		serial = new AltosSerial(device);  		log = new AltosLog(serial); @@ -68,7 +79,11 @@ class AltosTelemetryReader extends AltosFlightReader {  		previous = null;  		telem = new LinkedBlockingQueue<AltosLine>(); -		serial.set_radio(); +		frequency = AltosPreferences.frequency(device.getSerial()); +		set_frequency(frequency); +		telemetry = AltosPreferences.telemetry(device.getSerial()); +		set_telemetry(telemetry); +		serial.set_callsign(AltosPreferences.callsign());  		serial.add_monitor(telem);  	}  } diff --git a/altosui/AltosUI.java b/altosui/AltosUI.java index 033f233c..885e60cd 100644 --- a/altosui/AltosUI.java +++ b/altosui/AltosUI.java @@ -26,7 +26,7 @@ import java.io.*;  import java.util.*;  import java.text.*;  import java.util.prefs.*; -import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.*;  import libaltosJNI.*; @@ -67,6 +67,16 @@ public class AltosUI extends JFrame {  						      device.toShortString(),  						      "Unkonwn I/O error",  						      JOptionPane.ERROR_MESSAGE); +		} catch (TimeoutException te) { +			JOptionPane.showMessageDialog(this, +						      device.toShortString(), +						      "Timeout error", +						      JOptionPane.ERROR_MESSAGE); +		} catch (InterruptedException ie) { +			JOptionPane.showMessageDialog(this, +						      device.toShortString(), +						      "Interrupted exception", +						      JOptionPane.ERROR_MESSAGE);  		}  	} diff --git a/altosui/Makefile.am b/altosui/Makefile.am index d6fd0e6d..4bac6df1 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -52,6 +52,7 @@ altosui_JAVA = \  	AltosFlightStatus.java \  	AltosFlightUI.java \  	AltosFrequency.java \ +	AltosFreqList.java \  	AltosGPS.java \  	AltosGPSSat.java \  	AltosGreatCircle.java \ | 
