+commit 31cf047113ec72a78f4b500223a2c6be23bc86fd
+Merge: 2f0c977 afe74c0
+Author: Bdale Garbee <bdale@gag.com>
+Date: Fri Jun 17 10:00:10 2016 -0600
+
+ Merge branch 'master' into branch-1.6
+
+commit afe74c067a31ce420d0d4cdac2069c1d258a5114
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 17 08:58:06 2016 -0700
+
+ Bump version to 1.6.4
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 0c5a1bea3ffa7c4b6b1503733e33911cbfcb3e80
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 17 08:54:19 2016 -0700
+
+ altoslib: Stop reflective JSON class walk at Object instead of null
+
+ Android has classes above Object which are all tied together which
+ cause the object walking to fail in pretty spectacular ways. As Object
+ has no interesting fields, that serves as a fine barrier to the super
+ class walk and works on both android and real java.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 383dec4449f8160c06804fba06290e7a07335934
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 17 08:27:12 2016 -0700
+
+ altosui: Print filename before attempting to parse in --summary mode
+
+ Any problems handling the file are easier to debug if the filename is
+ visible above the error message.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit e8250fcb267a34fbbd8b88c6dcc8eec419bbcc68
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 17 08:26:31 2016 -0700
+
+ altoslib: Add back some JSON exception debugging printfs
+
+ These make it possible to figure out where the JSON code went wrong.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit a46df4f69984e3ef0064c2b211438c8d8ffaab68
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 17 08:17:57 2016 -0700
+
+ altoslib: Add construction for remaining primitive array types to JSON
+
+ AltosCompanion has an array of ints, which was missed until I tried a
+ telemetry file with companion data.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1ed6a3fb6356415c0d57ce2ce556435c6ff06e73
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 17 08:17:15 2016 -0700
+
+ altoslib: Add null constructor for AltosCompanion
+
+ This lets it be used by the JSON code.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1dce20f7eee56166ac61798ca26eeb323dc8f012
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 17 00:52:38 2016 -0700
+
+ altoslib: Get rid of manual JSON encoding stuff
+
+ Now that the reflective JSON stuff is working, we can delete all of
+ the manual code.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 7175774c4f60ed3efd54417f2035b50ea0108c7b
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 17 00:02:05 2016 -0700
+
+ altoslib: Improve AltosState save/restore debugging
+
+ When save/restore generate different values, write out the two
+ versions to one.json and two.json for easy comparison.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 8df6afe843e184e98e5d965cee3af562dfa30a3b
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 17 00:01:15 2016 -0700
+
+ altoslib: Use reflection JSON code for frequency preferences
+
+ This replaces the non-reflective JSON code with reflective code, which
+ is much shorter.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 93de1d7ec841c55f5a1a63d34b422780a6fbe3c3
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 17 00:00:09 2016 -0700
+
+ altoslib: Add JSON-based object saving/restoring code
+
+ This uses Java reflection to construct JSON strings for
+ most Java objects.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2a1b7c6c509d4d19de21abf02b63aeacba269d13
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu Jun 16 23:59:06 2016 -0700
+
+ altoslib: Add null constructors to AltosQuaternion and AltosRotation
+
+ These will be used in the reflection-based JSON code
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f7e2f7f430e612c682bf55478860054ce94b995f
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed Jun 15 22:52:08 2016 -0700
+
+ altoslib: Remove AltosHashSet code
+
+ Everything has switched to JSON now.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1b5ea911049a8afae6af475a4a2bf62a6e3aa57b
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed Jun 15 22:40:27 2016 -0700
+
+ altoslib: Switch preserved state format to JSON
+
+ This is much easier to debug than the icky strings with backslashes everywhere.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1de8b6c340cec0b5a327392686c5a4e00f201e98
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed Jun 15 22:39:31 2016 -0700
+
+ doc: Updates to 1.6.4 release notes.
+
+ Note USB fixes for host reboot and other changes.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f28db1102685c87b9f4278268f7e91f5df18374a
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed Jun 15 22:38:32 2016 -0700
+
+ altosui: Don't open command window when --graph is provided
+
+ When the user explicitly asks to open a graph, don't bring up the
+ command button window too.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2a4d741872449b5332f28e018fa3acc53ed7d891
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed Jun 15 22:37:39 2016 -0700
+
+ altosuilib: Track open frames, exit when none remain
+
+ This will let us not have the altosui window open by causing the
+ application to shut down when the last frame closes.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 04c6f4c54ac10f6464ffb8cab2186ac2b2eafb00
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed Jun 15 22:36:35 2016 -0700
+
+ altosui: Remove missing items from --summary output
+
+ Check all values for MISSING before printing them.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 7fd28830b6f7a20b35d85a92047ccb94c965fe29
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed Jun 15 22:33:55 2016 -0700
+
+ altosdroid: Auto save freq changes on 'ok'
+
+ Add any pending changes in the edit entries to the frequency set when
+ the user selects 'ok'.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 96eb350d3dfc83f6dfb31bbab1427f9206acde79
+Author: Bdale Garbee <bdale@gag.com>
+Date: Sun Jun 12 09:23:36 2016 -0600
+
+ extend "ok" temp range to 40C, since battery charger on bench can drive temp above
+ 35C at times in Bdale and Robert's production testing
+
+commit eee7fa303fb0d80ac5d7b9c5a86af60333f61951
+Author: Keith Packard <keithp@keithp.com>
+Date: Sat Jun 11 22:17:01 2016 -0700
+
+ altos/stmf0: Remove ao_usb_free
+
+ This can't work without a lot more effort.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1704d27248f1845c545ec61cf1bad58bf41189af
+Author: Keith Packard <keithp@keithp.com>
+Date: Sat Jun 11 22:16:12 2016 -0700
+
+ altos/stmf0: Rework the sram allocation to save a few text bytes
+
+ Boot loaders were going over 4096 bytes of ROM. I suspect we'll need
+ more serious work soon.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 36a08dc89ece6e2a2f0f69e3b31da17d66ceb2e2
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 10 14:40:26 2016 -0700
+
+ altos/cc1115l: Reduce trace buffer size
+
+ A 32-element trace buffer is all the larger we can fit in teledongle.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 7d21ff641a7bc35318f0f637589eabb5bb6c5152
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 10 14:39:25 2016 -0700
+
+ altos/stm: Handle USB reset in STM32L usb driver
+
+ Just like lpc and stmf0, deal with the host resetting the bus while
+ rebooting by restoring all usb-related data to the initial values.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 54f8d53584d0a902676b441cd122c01cd54f2283
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Jun 10 14:33:50 2016 -0700
+
+ altos/lpc: Handle USB reset by resetting internal state
+
+ Just like stmf0, this clears internal state at USB reset time so the
+ driver can survive host OS reboots.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 36ba97fabbed2f2a4a89da5be221c630ea3ff66f
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu Jun 9 22:06:30 2016 -0700
+
+ stmf0: Do not send more data than requested for GET_DESCRIPTOR
+
+ When Linux boots, it asks for only the first 8 bytes of the device
+ descriptor; we must limit the amount of data sent back to that amount
+ or USB will get wedged.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2970de9f92243b11d3beef56f3b1df3ef3579b95
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu Jun 9 22:05:24 2016 -0700
+
+ stmf0: Clear all USB state when resetting chip. Wakeup all sleepers
+
+ When USB is reset, but the board is not power cycled, all of the
+ internal USB state needs to be reset, and any tasks blocked on sending
+ or receiving packets need to be awoken so they can go wait for USB to
+ start running again.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 55c8e5aff2cc7b941503a04970f7d368261af52a
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu Jun 9 22:03:45 2016 -0700
+
+ telegps-v1.0: Document how SN 1959 was fixed
+
+ SN1959 was fixed by jumpering pin 8 to pin 10 so that the DONE_INT_PIN
+ could be switched from PIO 2 to PIO 4 as pin 8 appeared to have failed.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 4d57c8b87f29f23beb0d88f1cef179209b1c5992
+Author: Keith Packard <keithp@keithp.com>
+Date: Sun Jun 5 09:17:12 2016 -0700
+
+ altosuilib: Only display map debugging when serial_debug is enabled
+
+ This keeps the application quiet for most users.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f982248573c1b646ac53fde980a60ada5404f6aa
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri May 27 20:30:18 2016 -0700
+
+ altosuilib: Fill preload map on site or lat/lon change
+
+ This loads the map view with the selected area when the site entry is
+ changed or the user hits return in the lat/lon fields. This lets you
+ see the target launch site without having to load the whole preload set.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f5944ba4eb3f419f8cad461872d048b5adf7b566
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu May 26 14:33:44 2016 -0700
+
+ doc: pad/idle indicator table was busted
+
+ I stuck a pile of extra '|' characters in the table by mistake.
+
+ Reported-by: Stan <stanleyosmith@gmail.com>
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 0d966b74f756e88e5dffa92400b105f540429262
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 24 23:44:50 2016 -0700
+
+ altosuilib: Rename AltosUIMap*New.java to AltosUIMap*.java
+
+ This code isn't really new anymore...
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 59a9bdd73b580a9c934a574be7bf45c5033e14b5
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 24 23:40:47 2016 -0700
+
+ altosuilib: Have map preload respond to units and font size changes
+
+ Just add suitable listeners so that the display updates when
+ preferences change.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 7b5521966119fcc290591bf1b397506ef44cedea
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 24 23:40:03 2016 -0700
+
+ altoslib: use miles for distances > 1000ft.
+
+ This makes both the map line and the other distance displays use miles
+ for distances greater than 1000 feet.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 1ea855f95772a8a394407e0070be1ed9cc0f6650
+Author: Keith Packard <keithp@keithp.com>
+Date: Sun May 15 13:59:12 2016 -0700
+
+ telegps: Add monitor idle mode
+
+ This monitors directly connected devices. No support for doing monitor
+ idle using packet mode, as TeleGPS doesn't support that.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit df276262900551a5eecd94903eefe9a264b161ec
+Author: Keith Packard <keithp@keithp.com>
+Date: Sun May 15 13:58:41 2016 -0700
+
+ telegps: Use log_space when flight_log_max is missing
+
+ TeleGPS has this, but not flight_log_max
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 9287122edc0e2dec6b2542f4cc8cb9cf2900bb33
+Author: Keith Packard <keithp@keithp.com>
+Date: Sun May 15 13:57:28 2016 -0700
+
+ altoslib: Add AltosIdleReader
+
+ This provides an AltosFlightReader interface for monitor idle mode,
+ making that easier to provide in TeleGPS
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 3c4278a29082a2af5911e22e59f8f52549f549e3
+Author: Keith Packard <keithp@keithp.com>
+Date: Sun May 15 13:56:21 2016 -0700
+
+ altoslib: Add log_space to AltosState
+
+ TeleGPS doesn't have flight_log_max value, but does have log_space
+ which we can use for the same thing in monitor idle mode.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f484216e72f81decb2aaa7289d6f69678990b7af
+Author: Keith Packard <keithp@keithp.com>
+Date: Sun May 15 13:55:12 2016 -0700
+
+ altoslib: Set version and log space from AltosIdleFetch
+
+ Just more data for monitor idle mode
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 29123a60272777916e5aae08369d0f03c2f135b6
+Author: Keith Packard <keithp@keithp.com>
+Date: Sun May 15 13:53:38 2016 -0700
+
+ altoslib: Allow empty values in AltosHashSet representation
+
+ Check for value termination before appending the first character.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit b1a90adac9f6e2a609ce1ccd6749462bb5c9adbe
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu May 12 23:33:53 2016 -0700
+
+ altoslib: Store saved state in version-independent format
+
+ Use AltosHashSet for AltosState so that AltosDroid doesn't lose
+ tracker information when the application is upgraded.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit b13037fad0905c5933d1ff579122ba1357b02eea
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu May 12 19:13:05 2016 -0700
+
+ altoslib: Store common frequencies in library version-independent form
+
+ Serializable Objects in java are very specific to the class being
+ serialized. As we bump the name of the library on a regular basis to
+ note API/ABI issues, this mean a saved a Serializable object in
+ the preferences database will fail to load across library version
+ upgrades.
+
+ The saved tracker state and saved common frequencies were the only
+ objects saved in this form; this patch adds infrastructure for writing
+ objects in a version-independent form, and then adds support for
+ saving frequencies in that form.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2f4903f903223312d0a3a03dfd413059f24a07f5
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu May 12 19:10:19 2016 -0700
+
+ altosui/telegps/micropeak: Handle both MULTI_LIB and non-MULTI_LIB builds
+
+ On x86 systems with -m32 and -m64 compilers, both libaltos32.so and
+ libaltos64.so are built. Otherwise, we should use libaltos.so
+
+ altosui only dealt with libaltos32.so and libaltos64.so, so it only
+ worked on MULTI_LIB systems. telegps and micropeak only used
+ libaltos.so, so they wouldn't work correctly on multi-lib systems.
+
+ Fix all of them to work either way.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 64ed56fe3132faa8585c9cd7b0261ac85f70a7bd
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu May 12 18:05:14 2016 -0700
+
+ Automatically run 'git submodule update' if necessary
+
+ This makes sure pdclib exists by updating for the all and
+ all-recursive targets
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 97adfff4cfb67c17a96f3ff46606b4e439422b01
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu May 12 12:14:03 2016 -0700
+
+ Bump java library versions
+
+ Prepare for 1.6.4 release
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 3450efdf8bd736a33900493eeda348ec2dacf7e8
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu May 12 12:13:45 2016 -0700
+
+ Bump android app version
+
+ Prepare for 1.6.4 release
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit ba84b9c908d5909ea5a148c249709b21640f1eac
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed May 11 23:31:53 2016 -0700
+
+ telegps: Adapt to distance units switching changes
+
+ 'show_units' is no longer available; use 'parse_units' instead
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2ec7e14f0104e3a227ff566fa2fc1f6286ddd9d0
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed May 11 12:48:10 2016 -0700
+
+ altoslib: Get rid of AltosMap from AltosMapLoader
+
+ Cleans up the loader API and eliminates a AltosMapTile for every chunk
+ of map data.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit ab905d2f7d8929080042cfd16cc418ea5792c3cb
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed May 11 12:43:51 2016 -0700
+
+ altosdroid: make disconnect stick past pause/restart
+
+ Clear the active_device preference on disconnect so we don't reconnect
+ anytime the service gets activated.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 0a50669b1fde3e3c1cbc08c4836613b58ead219b
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed May 11 10:47:31 2016 -0700
+
+ altoslib: Clean up map file and url handling
+
+ move it all to AltosMapStore.java
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 471091d0fddf09ed69df75e4f2fdd92e5f57b9c5
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 10 23:13:14 2016 -0700
+
+ doc: Start update for 1.6.4
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit b2710128a715a109745ec40553a3d4149a7f49ab
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 10 23:04:23 2016 -0700
+
+ altosuilib: Don't flicker missing voltages when changing units
+
+ For some reason, a value of MISSING -1 was getting used, which caused
+ displays to light up briefly with a weird value when switching between
+ metric and imperial units.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 895cb58a6cd7424ee63c24d791b5988f41f85d31
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 10 23:03:45 2016 -0700
+
+ altosdroid: Rate limit map loading pacifier
+
+ Just like in altosui.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit c5f49d0ac254047f13c6c1ecfb5520eff72109ac
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 10 23:02:09 2016 -0700
+
+ altoslib: Allow map preloading to be aborted
+
+ Close the map preload dialog and it would be nice to stop loading map
+ bits.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2e551e7c5f82a7e35d39e8f73e8e526e5484cd5d
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 10 22:50:23 2016 -0700
+
+ altosuilib: Rate limit map loading pacifier updates
+
+ Just updating the pacifier was consuming a huge amount of CPU. Update
+ no more than once every 100ms.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 42021d9fdc6f7a74cc9b20ebf3cf60b4c5f4ea82
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 10 22:49:04 2016 -0700
+
+ altoslib: Remove some debug printf calls
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 60f4d69592c440ab7bb67a04f4c07fc7279d2c20
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 10 22:46:58 2016 -0700
+
+ altoslib: Switch distance from m/ft to km/miles for large values
+
+ This adds lots of infrastructure to deal with making the unit used
+ depend on the value itself, and then uses it only for distances.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 6a6da23335e6e5864387c7a22946f80f51056a4f
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 10 12:29:14 2016 -0700
+
+ Add TeleMega to spec list. Add TeleGPS RF output.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit d92ca1cd4dfbacebd7aa1bbcfc671daee35dc808
+Author: Keith Packard <keithp@keithp.com>
+Date: Tue May 10 12:28:51 2016 -0700
+
+ Publish firmware with keithp-fat
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit a371253bb5fc25e34d87507dc9b814530f4e28f6
+Author: Keith Packard <keithp@keithp.com>
+Date: Mon May 9 17:57:12 2016 -0700
+
+ altosdroid: Check for closed before writing/reading bluetooth
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit c57d86f6c9b56e90c986f460f93663a3e16cdf7a
+Author: Keith Packard <keithp@keithp.com>
+Date: Mon May 9 17:56:28 2016 -0700
+
+ altosui/telegps: Ship firmware for new hardware
+
+ TBT v3.0 and Tmega v2.0
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit f078235803a80403014b3e54039fd2d0e0704367
+Merge: 04759dd c457c82
+Author: Bdale Garbee <bdale@gag.com>
+Date: Mon May 9 15:52:38 2016 -0600
+
+ Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
+
+commit 04759dddeb29e4de9f7e6b3673dc06c633fa2369
+Author: Bdale Garbee <bdale@gag.com>
+Date: Mon May 9 15:52:21 2016 -0600
+
+ process updates made during 1.6.3 release cycle
+
+commit c457c827a7445098ba5effd410de754ff5c65843
+Author: Keith Packard <keithp@keithp.com>
+Date: Mon May 9 11:48:42 2016 -0700
+
+ Bump version to 1.6.3.1
+
+ Post 1.6.3 release
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit b25785ee0afebaf516b8a1b8d08d36fbdadd74ca
+Author: Keith Packard <keithp@keithp.com>
+Date: Mon May 9 11:33:48 2016 -0700
+
+ altos/cc1111: Use SW to drive UART RTS pin
+
+ Can't get the hw to work.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 2f0c977c747824d0798550ac64eceb1d66c50efd
+Author: Bdale Garbee <bdale@gag.com>
+Date: Fri May 6 18:12:20 2016 -0600
+
+ releasing 1.6.3
+
commit 15ae97fbdb4e75a74ea2e716194661d19dec46ff
Merge: ac7be4a 1216c0c
Author: Bdale Garbee <bdale@gag.com>
.PHONY: ChangeLog
+all: pdclib/Makefile
+all-recursive: pdclib/Makefile
+
+pdclib/Makefile:
+ git submodule update
+
ChangeLog:
(GIT_DIR=$(top_srcdir)/.git git log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || \
(touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2)
altosdroid/bin/AltosDroid-debug.apk \
altosdroid/bin/AltosDroid-release.apk
+fat_altos = \
+ src/easymega-v1.0/easymega-v1.0-$(VERSION).ihx \
+ src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx \
+ src/telebt-v1.0/telebt-v1.0-$(VERSION).ihx \
+ src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx \
+ src/teledongle-v0.2/teledongle-v0.2-$(VERSION).ihx \
+ src/teledongle-v3.0/teledongle-v3.0-$(VERSION).ihx \
+ src/telegps-v1.0/telegps-v1.0-$(VERSION).ihx \
+ src/telemega-v1.0/telemega-v1.0-$(VERSION).ihx \
+ src/telemega-v2.0/telemega-v2.0-$(VERSION).ihx \
+ src/telemetrum-v1.0/telemetrum-v1.0-$(VERSION).ihx \
+ src/telemetrum-v1.1/telemetrum-v1.1-$(VERSION).ihx \
+ src/telemetrum-v1.2/telemetrum-v1.2-$(VERSION).ihx \
+ src/telemetrum-v2.0/telemetrum-v2.0-$(VERSION).ihx \
+ src/telemini-v1.0/telemini-v1.0-$(VERSION).ihx
+
keithp-fat: fat
ssh keithp.com mkdir -p public_html/altos-$(VERSION)
- scp -p $(fat_linux) $(fat_mac) $(fat_windows) $(fat_android) keithp.com:public_html/altos-$(VERSION)
+ scp -p $(fat_linux) $(fat_mac) $(fat_windows) $(fat_android) $(fat_altos) keithp.com:public_html/altos-$(VERSION)
set-java-versions:
$(top_srcdir)/fix-java-versions org.altusmetrum.altoslib=$(ALTOSLIB_VERSION) org.altusmetrum.altosuilib=$(ALTOSUILIB_VERSION)
git checkout branch-<version> # the x.y parts only
- cherry-pick or merge appropriate content from master
- - make sure there is a doc/release-notes-<version>.xsl
- - make sure that doc/altusmetrum.xsl has the right copyright year,
- and add release to the revision history at the front (release notes
- will be pulled in automatically)
+ - make sure there is a doc/release-notes-<version>.inc
+ - make sure that doc/altusmetrum-docinfo.xml has the right copyright
+ year, and add release to the revision history at the front (release
+ notes will be pulled in automatically)
- make absolutely sure checked-out tree is "clean"
- make absolutely sure the pdclib/ submodule is on the master branch,
up to date, and "clean"
(cd ~/altusmetrumllc ; git add Binaries ; git commit -a)
(cd ~/altusmetrumllc ; git push)
- - copy the relevant release notes file from doc/ to
+ - copy the relevant release notes .html file from doc/ to
/home/bdale/web/altusmetrum/AltOS/releases/<rev>
(cd ~/web/altusmetrum/AltOS/releases/<rev> ; rm *.tar.bz2)
import android.os.Handler;
//import android.os.Message;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosBluetooth extends AltosDroidLink {
}
int write(byte[] buffer, int len) {
+ if (output == null)
+ return -1;
try {
output.write(buffer, 0, len);
} catch (IOException ie) {
}
int read(byte[] buffer, int len) {
+ if (input == null)
+ return -1;
try {
return input.read(buffer, 0, len);
} catch (IOException ie) {
import java.io.*;
import java.lang.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import android.app.Activity;
import android.graphics.*;
import android.graphics.*;
import android.graphics.drawable.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosDroid extends FragmentActivity implements AltosUnitsListener, LocationListener {
}
}
- private void disconnectDevice() {
+ private void disconnectDevice(boolean remember) {
try {
- mService.send(Message.obtain(null, TelemetryService.MSG_DISCONNECT, null));
+ mService.send(Message.obtain(null, TelemetryService.MSG_DISCONNECT, (Boolean) remember));
} catch (RemoteException e) {
}
}
case R.id.disconnect:
/* Disconnect the device
*/
- disconnectDevice();
+ disconnectDevice(false);
return true;
case R.id.quit:
AltosDebug.debug("R.id.quit");
- disconnectDevice();
+ disconnectDevice(true);
finish();
return true;
case R.id.setup:
import android.os.Handler;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public abstract class AltosDroidLink extends AltosLink {
import java.util.*;
import java.io.*;
import android.location.Location;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public interface AltosDroidMapInterface {
public void onCreateView(AltosDroid altos_droid);
import java.text.*;
import android.content.Context;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosDroidPreferences extends AltosPreferences {
public static void set_active_device(DeviceAddress address) {
synchronized(backend) {
active_device_address = address;
- backend.putString(activeDeviceAddressPreference, active_device_address.address);
- backend.putString(activeDeviceNamePreference, active_device_address.name);
+ if (active_device_address != null) {
+ backend.putString(activeDeviceAddressPreference, active_device_address.address);
+ backend.putString(activeDeviceNamePreference, active_device_address.name);
+ } else {
+ backend.remove(activeDeviceAddressPreference);
+ backend.remove(activeDeviceNamePreference);
+ }
flush_preferences();
}
}
import android.os.Environment;
import android.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosDroidPreferencesBackend extends AltosPreferencesBackend {
public final static String NAME = "org.altusmetrum.AltosDroid";
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import android.location.Location;
import android.app.Activity;
import android.graphics.Color;
import java.util.*;
import java.io.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import android.app.Activity;
import android.graphics.*;
AltosMap map;
AltosDroid altos_droid;
+ static int scale = 2;
+
AltosLatLon here;
AltosLatLon there;
AltosLatLon pad;
}
}
- public MapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
- super(cache, upper_left, center, zoom, maptype, px_size, 2);
+ public MapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+ super(cache, upper_left, center, zoom, maptype, px_size, scale);
}
}
- public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
- return new MapTile(cache, upper_left, center, zoom, maptype, px_size);
+ public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+ return new MapTile(cache, upper_left, center, zoom, maptype, px_size, scale);
}
public AltosMapPath new_path() {
public void onCreateView(AltosDroid altos_droid) {
this.altos_droid = altos_droid;
- map = new AltosMap(this);
+ map = new AltosMap(this, scale);
AltosPreferences.register_map_type_listener(this);
map.set_maptype(AltosPreferences.map_type());
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.*;
import android.app.*;
import android.os.Handler;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosUsb extends AltosDroidLink {
import android.speech.tts.TextToSpeech.OnInitListener;
import android.location.Location;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosVoice {
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class IdleModeActivity extends Activity {
private EditText callsign;
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
class IgniterItem {
public String name;
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
class FrequencyItem {
public AltosFrequency frequency;
private void done() {
+ set();
+
if (changed) {
AltosFrequency[] frequencies = new AltosFrequency[frequencies_adapter.count()];
for (int i = 0; i < frequencies.length; i++)
load_item();
}
+ private int find(AltosFrequency frequency) {
+ for (int pos = 0; pos < frequencies_adapter.getCount(); pos++) {
+ FrequencyItem item = frequencies_adapter.getItem(pos);
+ if (item.frequency.frequency == frequency.frequency &&
+ item.frequency.description.equals(frequency.description))
+ return pos;
+ }
+ return -1;
+ }
+
private int insert_item(AltosFrequency frequency) {
FrequencyItem new_item = new FrequencyItem(frequency);
int pos;
try {
double f = AltosParse.parse_double_locale(frequency_text);
+ AltosFrequency frequency = new AltosFrequency(f, description_text);
+ int pos;
- int pos = insert_item(new AltosFrequency(f, description_text));
+ pos = find(frequency);
+ if (pos < 0) {
+ pos = insert_item(frequency);
+ changed = true;
+ }
frequencies_adapter.selected_item = -1;
select_item(pos);
- changed = true;
} catch (ParseException pe) {
}
hide_keyboard();
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class MapTypeActivity extends Activity {
private Button hybrid;
import android.location.LocationListener;
import android.location.Criteria;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
/**
* This Activity appears as a dialog. It lists any paired devices and
* by the user, the MAC address of the device is sent back to the parent
* Activity in the result Intent.
*/
-public class PreloadMapActivity extends Activity implements AltosLaunchSiteListener, AltosMapInterface, AltosMapLoaderListener, LocationListener {
+public class PreloadMapActivity extends Activity implements AltosLaunchSiteListener, AltosMapLoaderListener, LocationListener {
private ArrayAdapter<AltosLaunchSite> known_sites_adapter;
private ProgressBar progress;
+ private AltosMapLoader loader;
+
+ long loader_notify_time;
+
/* AltosMapLoaderListener interfaces */
public void loader_start(final int max) {
+ loader_notify_time = System.currentTimeMillis();
+
this.runOnUiThread(new Runnable() {
public void run() {
progress.setMax(max);
}
public void loader_notify(final int cur, final int max, final String name) {
+ long now = System.currentTimeMillis();
+
+ if (now - loader_notify_time < 100)
+ return;
+
+ loader_notify_time = now;
+
this.runOnUiThread(new Runnable() {
public void run() {
progress.setProgress(cur);
}
public void loader_done(int max) {
+ loader = null;
this.runOnUiThread(new Runnable() {
public void run() {
progress.setProgress(0);
});
}
+ public void debug(String format, Object ... arguments) {
+ AltosDebug.debug(format, arguments);
+ }
+
/* AltosLaunchSiteListener interface */
+
public void notify_launch_sites(final List<AltosLaunchSite> sites) {
this.runOnUiThread(new Runnable() {
public void run() {
});
}
- AltosMap map;
-
- class PreloadMapImage implements AltosImage {
- public void flush() {
- }
-
- public PreloadMapImage(File file) {
- }
- }
-
- public AltosMapPath new_path() {
- return null;
- }
-
- public AltosMapLine new_line() {
- return null;
- }
-
- public AltosImage load_image(File file) throws Exception {
- return new PreloadMapImage(file);
- }
-
- public AltosMapMark new_mark(double lat, double lon, int state) {
- return null;
- }
-
- class PreloadMapTile extends AltosMapTile {
- public void paint(AltosMapTransform t) {
- }
-
- public PreloadMapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
- super(cache, upper_left, center, zoom, maptype, px_size, 2);
- }
-
- }
-
- public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
- return new PreloadMapTile(cache, upper_left, center, zoom, maptype, px_size);
- }
-
- public int width() {
- return AltosMap.px_size;
- }
-
- public int height() {
- return AltosMap.px_size;
- }
-
- public void repaint() {
- }
-
- public void repaint(AltosRectangle damage) {
- }
-
- public void set_zoom_label(String label) {
- }
-
- public void select_object(AltosLatLon latlon) {
- }
-
- public void debug(String format, Object ... arguments) {
- AltosDebug.debug(format, arguments);
- }
-
/* LocationProvider interface */
AltosLaunchSite current_location_site;
private double radius() {
double r = value_distance(radius);
if (AltosPreferences.imperial_units())
- r = AltosConvert.distance.inverse(r);
+ r = AltosConvert.miles_to_meters(r);
else
r = r * 1000;
return r;
}
private void load() {
+ if (loader != null)
+ return;
+
try {
double lat = latitude();
double lon = longitude();
AltosDebug.debug("PreloadMap load %f %f %d %d %f %d\n",
lat, lon, min, max, r, t);
- new AltosMapLoader(map, this, lat, lon, min, max, r, t);
+ loader = new AltosMapLoader(this, lat, lon, min, max, r, t, AltosMapOffline.scale);
} catch (ParseException e) {
AltosDebug.debug("PreloadMap load raised exception %s", e.toString());
}
known_sites_spinner.setAdapter(known_sites_adapter);
known_sites_spinner.setOnItemSelectedListener(new SiteListListener());
- map = new AltosMap(this);
-
// Listen for GPS and Network position updates
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
protected void onDestroy() {
super.onDestroy();
+ if (loader != null)
+ loader.abort();
+
// Stop listening for location updates
((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this);
}
import android.widget.*;
import android.widget.AdapterView.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class SetupActivity extends Activity {
private Spinner select_rate;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import android.app.Activity;
import android.os.Bundle;
import java.util.*;
import java.io.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import android.app.Activity;
import android.graphics.*;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import android.app.Activity;
import android.os.Bundle;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import android.app.Activity;
import android.os.Bundle;
package org.altusmetrum.AltosDroid;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import java.util.concurrent.*;
import android.os.Handler;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class TelemetryReader extends Thread {
import android.widget.Toast;
import android.location.Criteria;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class TelemetryService extends Service implements AltosIdleMonitorListener {
case MSG_DISCONNECT:
AltosDebug.debug("Disconnect command received");
s.address = null;
+ if (!(Boolean) msg.obj)
+ AltosDroidPreferences.set_active_device(null);
s.disconnect(true);
break;
case MSG_DELETE_SERIAL:
telemetry_state.latest_serial = AltosPreferences.latest_state();
+ AltosDebug.debug("latest serial %d\n", telemetry_state.latest_serial);
+
for (int serial : serials) {
AltosState saved_state = AltosPreferences.state(serial);
if (saved_state != null) {
telemetry_state.states.put(serial, saved_state);
} else {
AltosDebug.debug("Failed to recover state for %d", serial);
+ AltosPreferences.remove_state(serial);
}
}
}
package org.altusmetrum.AltosDroid;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import android.location.Location;
public class TelemetryState {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
-public class AltosAccel extends AltosUnits implements Serializable {
+public class AltosAccel extends AltosUnits {
public double value(double v, boolean imperial_units) {
if (imperial_units)
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosCRCException extends Exception {
public int rssi;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
-public class AltosCompanion implements Serializable {
+public class AltosCompanion {
public final static int board_id_telescience = 0x0a;
public final static int MAX_CHANNELS = 12;
channels = MAX_CHANNELS;
companion_data = new int[channels];
}
+
+ public AltosCompanion() {
+ channels = 0;
+ companion_data = new int[0];
+ }
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.*;
import java.text.*;
for (int i = 0; i < parts.length; i++) {
try {
- r[i] = AltosLib.fromdec(parts[i]);
+ r[i] = (int) AltosLib.fromdec(parts[i]);
} catch (NumberFormatException n) {
r[i] = 0;
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosConfigDataException extends Exception {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosConfigValues {
/* set and get all of the dialog values */
/*
* Sensor data conversion functions
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosConvert {
/*
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosDistance extends AltosUnits {
return 1;
return 0;
}
-}
\ No newline at end of file
+
+ public AltosDistance() {
+ range_metric = new AltosUnitsRange[2];
+
+ range_metric[0] = new AltosUnitsRange(0, "m", "meters") {
+ double value(double v) {
+ return v;
+ }
+ int show_fraction(int width) {
+ return width / 9;
+ }
+ int say_fraction() {
+ return 0;
+ }
+ };
+ range_metric[1] = new AltosUnitsRange(2000, "km", "kilometers") {
+ double value(double v) {
+ return v / 1000;
+ }
+ int show_fraction(int width) {
+ return width / 5;
+ }
+ int say_fraction() {
+ return 1;
+ }
+ };
+
+ range_imperial = new AltosUnitsRange[2];
+
+ range_imperial[0] = new AltosUnitsRange(0, "ft", "feet") {
+ double value(double v) {
+ return AltosConvert.meters_to_feet(v);
+ }
+ int show_fraction(int width) {
+ return width / 9;
+ }
+ int say_fraction() {
+ return 0;
+ }
+ };
+
+ range_imperial[1] = new AltosUnitsRange(AltosConvert.feet_to_meters(1000),
+ "mi", "miles") {
+ double value(double v) {
+ return AltosConvert.meters_to_miles(v);
+ }
+ int show_fraction(int width) {
+ return width / 5;
+ }
+ int say_fraction() {
+ return 1;
+ }
+ };
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.text.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.text.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosEepromMonitor {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.File;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosFlashListener {
public void position(String label, int percent);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosFlightDisplay extends AltosUnitsListener, AltosFontListener {
void reset();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.text.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosFontListener {
void font_size_changed(int font_size);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
import java.text.*;
-public class AltosFrequency implements Serializable {
+public class AltosFrequency {
public double frequency;
public String description;
return diff < 0.010;
}
-
public AltosFrequency(double f, String d) {
frequency = f;
description = d;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.text.*;
import java.util.concurrent.*;
import java.io.*;
-public class AltosGPS implements Cloneable, Serializable {
+public class AltosGPS implements Cloneable {
public final static int MISSING = AltosLib.MISSING;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
+
+import java.io.*;
import java.text.*;
+import java.util.*;
import java.util.concurrent.*;
-import java.io.*;
-public class AltosGPSSat implements Serializable {
+public class AltosGPSSat {
public int svid;
public int c_n0;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.lang.Math;
import java.io.*;
-public class AltosGreatCircle implements Cloneable, Serializable {
+public class AltosGreatCircle implements Cloneable {
public double distance;
public double bearing;
public double range;
course = 2 * Math.PI-course;
}
distance = d * earth_radius;
- bearing = course * 180/Math.PI;
+ if (Double.isNaN(course) || Double.isInfinite(course))
+ bearing = 0;
+ else
+ bearing = course * 180/Math.PI;
double height_diff = end_alt - start_alt;
range = Math.sqrt(distance * distance + height_diff * height_diff);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosHeight extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.LinkedList;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosHexsym {
String name;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.*;
import java.io.*;
-public class AltosIMU implements Cloneable, Serializable {
+public class AltosIMU implements Cloneable {
public int accel_along;
public int accel_across;
public int accel_through;
public int gyro_pitch;
public int gyro_yaw;
- public static double counts_per_g = 2048.0;
+ public static final double counts_per_g = 2048.0;
public static double convert_accel(double counts) {
return counts / counts_per_g * (-AltosConvert.GRAVITATIONAL_ACCELERATION);
}
- public static double counts_per_degsec = 16.4;
+ public static final double counts_per_degsec = 16.4;
public static double convert_gyro(double counts) {
return counts / counts_per_degsec;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
AltosLink link;
- double frequency;
- String callsign;
-
public void update_state(AltosState state) throws InterruptedException, AltosUnknownProduct {
try {
boolean matched = false;
state.set_ground_accel(config_data.accel_cal_plus);
state.set_accel_g(config_data.accel_cal_plus, config_data.accel_cal_minus);
state.set_product(config_data.product);
+ state.set_firmware_version(config_data.version);
+ state.set_log_space(config_data.log_space);
for (AltosIdler idler : idlers) {
if (idler.matches(config_data)) {
idler.update_state(state, link, config_data);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosIdleMonitorListener {
public void update(AltosState state, AltosListenerState listener_state);
--- /dev/null
+/*
+ * Copyright © 2016 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 org.altusmetrum.altoslib_11;
+
+import java.text.*;
+import java.io.*;
+import java.util.concurrent.*;
+
+public class AltosIdleReader extends AltosFlightReader {
+ AltosLink link;
+ boolean remote;
+ AltosState state = null;
+ AltosIdleFetch fetch;
+ long next_millis;
+ static final long report_interval = 5 * 1000;
+ static final long minimum_delay = 1 * 1000;
+
+ private void start_link() throws InterruptedException, TimeoutException {
+ if (remote) {
+ link.start_remote();
+ } else
+ link.flush_input();
+ }
+
+ private boolean stop_link() throws InterruptedException, TimeoutException {
+ if (remote)
+ link.stop_remote();
+ return link.reply_abort;
+ }
+
+ public AltosState read() throws InterruptedException, ParseException, AltosCRCException, IOException {
+ boolean worked = false;
+ boolean aborted = false;
+
+ if (state == null)
+ state = new AltosState();
+ else
+ state = state.clone();
+
+ long delay = next_millis - System.currentTimeMillis();
+
+ if (delay > 0)
+ Thread.sleep(delay);
+ next_millis = System.currentTimeMillis() + report_interval;
+ try {
+ try {
+ start_link();
+ fetch.update_state(state);
+ if (!link.has_error && !link.reply_abort)
+ worked = true;
+ } catch (TimeoutException te) {
+ } catch (AltosUnknownProduct ue) {
+ worked = true;
+ }
+ } finally {
+ try {
+ aborted = stop_link();
+ } catch (TimeoutException te) {
+ aborted = true;
+ }
+ if (worked) {
+ if (remote) {
+ try {
+ state.set_rssi(link.rssi(), 0);
+ } catch (TimeoutException te) {
+ state.set_rssi(0, 0);
+ }
+ }
+ }
+ }
+
+ long finish = System.currentTimeMillis();
+
+ if (next_millis - finish < minimum_delay)
+ next_millis = finish + minimum_delay;
+
+ return state;
+ }
+
+ public void close(boolean interrupted) {
+ try {
+ link.close();
+ } catch (InterruptedException ie) {
+ }
+ }
+
+ public void set_frequency(double frequency) throws InterruptedException, TimeoutException {
+ link.set_radio_frequency(frequency);
+ }
+
+ public void save_frequency() {
+ AltosPreferences.set_frequency(link.serial, link.frequency);
+ }
+
+ public void set_callsign(String callsign) throws InterruptedException, TimeoutException {
+ link.set_callsign(callsign);
+ }
+
+ public AltosIdleReader (AltosLink link, boolean remote)
+ throws IOException, InterruptedException, TimeoutException {
+ this.link = link;
+ this.remote = remote;
+ this.next_millis = System.currentTimeMillis();
+ fetch = new AltosIdleFetch(link);
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
--- /dev/null
+/*
+ * Copyright © 2016 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 org.altusmetrum.altoslib_11;
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.lang.*;
+import java.lang.reflect.*;
+
+class JsonUtil {
+ StringBuffer quote(StringBuffer result, String a) {
+ result.append("\"");
+ for (int i = 0; i < a.length(); i++) {
+ char c = a.charAt(i);
+
+ switch (c) {
+ case '"':
+ case '\\':
+ result.append('\\').append(c);
+ break;
+ case '\n':
+ result.append("\\n");
+ break;
+ default:
+ result.append(c);
+ break;
+ }
+ }
+ result.append("\"");
+ return result;
+ }
+
+ StringBuffer append(StringBuffer result, AltosJson value, int indent, boolean pretty) {
+ value.append(result, indent, pretty);
+ return result;
+ }
+
+ StringBuffer append(StringBuffer result, String string) {
+ result.append(string);
+ return result;
+ }
+
+ StringBuffer indent(StringBuffer result, int indent) {
+ result.append("\n");
+ for (int i = 0; i < indent; i++)
+ result.append("\t");
+ return result;
+ }
+ static NumberFormat get_nf_json() {
+ DecimalFormat nf = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ROOT);
+ nf.setParseIntegerOnly(false);
+ nf.setGroupingUsed(false);
+ nf.setMaximumFractionDigits(17);
+ nf.setMinimumFractionDigits(0);
+ nf.setMinimumIntegerDigits(1);
+ nf.setDecimalSeparatorAlwaysShown(false);
+ return nf;
+ }
+
+ static NumberFormat nf_json = get_nf_json();
+}
+
+class JsonHash extends JsonUtil {
+ Hashtable<String,AltosJson> hash;
+
+ void append_hash(StringBuffer result, int indent, boolean pretty) {
+ boolean first = true;
+
+ result.append("{");
+
+ ArrayList<String> key_list = new ArrayList<String>(hash.keySet());
+
+ Collections.sort(key_list, new Comparator<String>() {
+ @Override
+ public int compare(String a, String b) { return a.compareTo(b); }
+ });
+
+ for (String key : key_list) {
+ AltosJson value = hash.get(key);
+
+ if (!first)
+ result.append(",");
+ first = false;
+ if (pretty)
+ indent(result, indent+1);
+ quote(result, key);
+ append(result, ": ");
+ append(result, value, indent+1, pretty);
+ }
+ if (pretty)
+ indent(result, indent);
+ append(result, "}");
+ }
+
+ void put(String key, AltosJson value) {
+ hash.put(key, value);
+ }
+
+ AltosJson get(String key) {
+ return hash.get(key);
+ }
+
+ JsonHash() {
+ hash = new Hashtable<String,AltosJson>();
+ }
+}
+
+class JsonArray extends JsonUtil {
+ ArrayList<AltosJson> array;
+
+ void append_array(StringBuffer result, int indent, boolean pretty) {
+ boolean first = true;
+
+ append(result, "[");
+ for (int i = 0; i < array.size(); i++) {
+ AltosJson value = array.get(i);
+
+ if (!first)
+ append(result, ",");
+ first = false;
+ if (pretty)
+ indent(result, indent+1);
+ append(result, value, indent+1, pretty);
+ }
+ if (pretty)
+ indent(result, indent);
+ append(result, "]");
+ }
+
+ void put(int index, AltosJson value) {
+ if (index >= array.size())
+ array.add(index, value);
+ else
+ array.set(index, value);
+ }
+
+ AltosJson get(int index) {
+ if (index < 0 || index > array.size())
+ return null;
+ return array.get(index);
+ }
+
+ int size() {
+ return array.size();
+ }
+
+ JsonArray() {
+ array = new ArrayList<AltosJson>();
+ }
+}
+
+class JsonToken {
+ double dval;
+ long lval;
+ String sval;
+ boolean bval;
+ int token;
+
+ static final int _string = 0;
+ static final int _double = 1;
+ static final int _long = 2;
+ static final int _boolean = 3;
+ static final int _oc = 4;
+ static final int _cc = 5;
+ static final int _os = 6;
+ static final int _cs = 7;
+ static final int _comma = 8;
+ static final int _colon = 9;
+ static final int _end = 10;
+ static final int _error = 11;
+
+ static String token_name(int token) {
+ switch (token) {
+ case _string:
+ return "string";
+ case _double:
+ return "number";
+ case _long:
+ return "number";
+ case _boolean:
+ return "boolean";
+ case _oc:
+ return "{";
+ case _cc:
+ return "}";
+ case _os:
+ return "[";
+ case _cs:
+ return "]";
+ case _comma:
+ return ",";
+ case _colon:
+ return ":";
+ case _end:
+ return "<EOF>";
+ case _error:
+ return "<ERROR>";
+ default:
+ return "<UNKNOWN>";
+ }
+ }
+
+ String token_name() {
+ return token_name(token);
+ }
+
+ JsonToken(int token) {
+ this.token = token;
+ }
+
+ JsonToken(int token, boolean bval) {
+ this.token = token;
+ this.bval = bval;
+ }
+
+ JsonToken(int token, double dval) {
+ this.token = token;
+ this.dval = dval;
+ }
+
+ JsonToken(int token, long lval) {
+ this.token = token;
+ this.lval = lval;
+ }
+
+ JsonToken(int token, String sval) {
+ this.token = token;
+ this.sval = sval;
+ }
+
+ JsonToken(int token, StringBuffer bval) {
+ this(token, bval.toString());
+ }
+}
+
+/*
+ * Lexer for json
+ */
+class JsonLexer extends JsonUtil {
+ StringReader f;
+ int line;
+ int ungot = -2;
+ StringBuffer pending_token;
+ JsonToken token;
+
+ static class keyword {
+ String word;
+ JsonToken token;
+
+ JsonToken match(String value) {
+ if (word.equals(value))
+ return token;
+ return null;
+ }
+
+ keyword(String word, JsonToken token) {
+ this.word = word;
+ this.token = token;
+ }
+ }
+
+ /* boolean values are the only keywords in json
+ */
+ static keyword[] keywords = {
+ new keyword("true", new JsonToken(JsonToken._boolean, true)),
+ new keyword("false", new JsonToken(JsonToken._boolean, false)),
+ new keyword("NegInfinity", new JsonToken(JsonToken._double, Double.NEGATIVE_INFINITY)),
+ new keyword("Infinity", new JsonToken(JsonToken._double, Double.POSITIVE_INFINITY)),
+ new keyword("NaN", new JsonToken(JsonToken._double, Double.NaN))
+ };
+
+ static JsonToken keyword(String word) {
+ for (int i = 0; i < keywords.length; i++) {
+ JsonToken token = keywords[i].match(word);
+ if (token != null)
+ return token;
+ }
+ return null;
+ }
+
+ /* Get the next char (-1 for EOF) */
+ int ch() throws IOException {
+ int c;
+ if (ungot != -2) {
+ c = ungot;
+ ungot = -2;
+ } else
+ c = f.read();
+ if (c != -1)
+ pending_token.append((char) c);
+ if (c == '\n')
+ ++line;
+ return c;
+ }
+
+ void unch(int c) {
+ if (ungot != -2)
+ throw new IllegalArgumentException("ungot buffer full");
+ pending_token.deleteCharAt( pending_token.length()-1);
+ if (c == '\n')
+ --line;
+ ungot = c;
+ }
+
+ String last_token_string() {
+ if (pending_token == null)
+ return null;
+
+ return pending_token.toString();
+ }
+
+ static boolean is_long_range(double d) {
+ return -9223372036854775808.0 <= d && d <= 9223372036854775807.0;
+ }
+
+ JsonToken lex() {
+ pending_token = new StringBuffer();
+
+ try {
+ for (;;) {
+ int c = ch();
+
+ switch (c) {
+ case -1:
+ return new JsonToken(JsonToken._end);
+ case '\n':
+ case ' ':
+ case '\t':
+ continue;
+ case '{':
+ return new JsonToken(JsonToken._oc);
+ case '}':
+ return new JsonToken(JsonToken._cc);
+ case '[':
+ return new JsonToken(JsonToken._os);
+ case ']':
+ return new JsonToken(JsonToken._cs);
+ case ',':
+ return new JsonToken(JsonToken._comma);
+ case ':':
+ return new JsonToken(JsonToken._colon);
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case '.': case '-': case '+':
+ StringBuffer dbuf = new StringBuffer();
+ boolean is_double = false;
+ while (Character.isDigit(c) || c == '.' || c == '+' || c == '-' || c == 'e' || c == 'E') {
+ if (c == '.' || c == 'E')
+ is_double = true;
+ dbuf.appendCodePoint(c);
+ c = ch();
+ }
+ unch(c);
+ String dstr = dbuf.toString();
+ double dval;
+ try {
+ dval = nf_json.parse(dstr).doubleValue();
+ } catch (ParseException pe) {
+ return new JsonToken(JsonToken._error, dstr);
+ }
+ if (is_double || !is_long_range(dval))
+ return new JsonToken(JsonToken._double, dval);
+ else {
+ long lval = Long.parseLong(dstr);
+ return new JsonToken(JsonToken._long, lval);
+ }
+ case '"':
+ StringBuffer bval = new StringBuffer();
+ for (;;) {
+ c = ch();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ c = ch();
+ switch (c) {
+ case 'n':
+ c = '\n';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ default:
+ break;
+ }
+ }
+ bval.appendCodePoint(c);
+ }
+ return new JsonToken(JsonToken._string, bval);
+ default:
+ if (Character.isLetter(c)) {
+ StringBuffer tbuf = new StringBuffer();
+ do {
+ tbuf.appendCodePoint(c);
+ c = ch();
+ } while (Character.isLetter(c));
+ unch(c);
+ JsonToken token = keyword(tbuf.toString());
+ if (token != null)
+ return token;
+ }
+ break;
+ }
+ }
+ } catch (IOException ie) {
+ return new JsonToken(JsonToken._error, "<EIO>");
+ }
+ }
+
+ void next() {
+ token = lex();
+ }
+
+ JsonToken expect(int e) {
+ JsonToken t = token;
+ if (t.token != e)
+ throw new IllegalArgumentException(String.format("got \"%s\" while expecting \"%s\"",
+ token.token_name(),
+ JsonToken.token_name(e)));
+ next();
+ return t;
+ }
+
+ JsonLexer(String s) {
+ f = new StringReader(s);
+ line = 1;
+ token = null;
+ }
+}
+
+/*
+ * Parse a json string into a AltosJson object
+ */
+class JsonParse {
+ JsonLexer lexer;
+
+ void parse_error(String format, Object ... arguments) {
+ throw new IllegalArgumentException(String.format("line %d: JSON parse error %s\n",
+ lexer.line,
+ String.format(format, arguments)));
+ }
+
+ /* Hashes are { string: value ... } */
+ JsonHash hash() {
+ JsonHash hash = new JsonHash();
+
+ /* skip the open brace */
+ lexer.next();
+ for (;;) {
+ /* Allow for empty hashes */
+ if (lexer.token.token == JsonToken._cc) {
+ lexer.next();
+ return hash;
+ }
+
+ /* string : value */
+ String key = lexer.expect(JsonToken._string).sval;
+ lexer.expect(JsonToken._colon);
+ AltosJson value = value();
+ hash.put(key, value);
+
+ switch (lexer.token.token) {
+ case JsonToken._comma:
+ lexer.next();
+ break;
+ case JsonToken._cc:
+ lexer.next();
+ return hash;
+ default:
+ parse_error("got %s expect \",\" or \"}\"", lexer.token.token_name());
+ return null;
+ }
+ }
+ }
+
+ /* Arrays are [ value ... ] */
+ JsonArray array() {
+ JsonArray array = new JsonArray();
+
+ lexer.next();
+ for (int i = 0;; i++) {
+ /* Allow for empty arrays */
+ if (lexer.token.token == JsonToken._cs) {
+ lexer.next();
+ return array;
+ }
+
+ AltosJson value = value();
+ array.put(i, value);
+ switch (lexer.token.token) {
+ case JsonToken._comma:
+ lexer.next();
+ break;
+ case JsonToken._cs:
+ lexer.next();
+ return array;
+ default:
+ parse_error("got %s expect \",\" or \"]\"", lexer.token.token_name());
+ return null;
+ }
+ }
+ }
+
+ /* Json is a simple LL language; one token is sufficient to
+ * identify the next object in the input
+ */
+ AltosJson value() {
+ switch (lexer.token.token) {
+ case JsonToken._oc:
+ return new AltosJson(hash());
+ case JsonToken._os:
+ return new AltosJson(array());
+ case JsonToken._double:
+ double dval = lexer.token.dval;
+ lexer.next();
+ return new AltosJson(dval);
+ case JsonToken._long:
+ long lval = lexer.token.lval;
+ lexer.next();
+ return new AltosJson(lval);
+ case JsonToken._string:
+ String sval = lexer.token.sval;
+ lexer.next();
+ return new AltosJson(sval);
+ case JsonToken._boolean:
+ boolean bval = lexer.token.bval;
+ lexer.next();
+ return new AltosJson(bval);
+ default:
+ parse_error("Unexpected token \"%s\"", lexer.token.token_name());
+ }
+ return null;
+ }
+
+ AltosJson parse() {
+ lexer.next();
+ return value();
+ }
+
+ JsonParse(String s) {
+ lexer = new JsonLexer(s);
+ }
+}
+
+public class AltosJson extends JsonUtil {
+ private static final int type_none = 0;
+ private static final int type_hash = 1;
+ private static final int type_array = 2;
+ private static final int type_double = 3;
+ private static final int type_long = 4;
+ private static final int type_string = 5;
+ private static final int type_boolean = 6;
+
+ private int type;
+
+ private JsonHash hash;
+ private JsonArray array;
+ private double d_number;
+ private long l_number;
+ private String string;
+ private boolean bool;
+
+ /* Generate string representation of the value
+ */
+ StringBuffer append(StringBuffer result, int indent, boolean pretty) {
+ switch (type) {
+ case type_hash:
+ hash.append_hash(result, indent, pretty);
+ break;
+ case type_array:
+ array.append_array(result, indent, pretty);
+ break;
+ case type_double:
+ if (Double.isInfinite(d_number)) {
+ if (d_number < 0)
+ result.append("NegInfinity");
+ else
+ result.append("Infinity");
+ } else if (Double.isNaN(d_number)) {
+ result.append("NaN");
+ } else {
+ String dval = nf_json.format(d_number);
+ if (dval.equals("-0"))
+ dval = "0";
+ result.append(dval);
+ }
+ break;
+ case type_long:
+ result.append(new Long(l_number).toString());
+ break;
+ case type_string:
+ quote(result, string);
+ break;
+ case type_boolean:
+ result.append(bool ? "true" : "false");
+ break;
+ }
+ return result;
+ }
+
+ private String toString(int indent, boolean pretty) {
+ StringBuffer result = new StringBuffer();
+ append(result, indent, pretty);
+ return result.toString();
+ }
+
+ public String toString() {
+ return toString(0, false);
+ }
+
+ public String toPrettyString() {
+ return toString(0, true);
+ }
+
+ /* Parse string representation to a value
+ */
+
+ public static AltosJson fromString(String string) {
+ JsonParse parse = new JsonParse(string);
+ try {
+ return parse.parse();
+ } catch (IllegalArgumentException ie) {
+ System.out.printf("json:\n%s\n%s\n", string, ie.getMessage());
+ return null;
+ }
+ }
+
+ /* Accessor functions
+ */
+ private boolean assert_type(boolean setting, int type, int other_type, String error) {
+ if (setting && this.type == type_none) {
+ this.type = type;
+ return false;
+ }
+ if (this.type != type && this.type != other_type)
+ throw new IllegalArgumentException(error);
+ return true;
+ }
+
+ private boolean assert_type(boolean setting, int type, String error) {
+ return assert_type(setting, type, type, error);
+ }
+
+ private void assert_hash(boolean setting) {
+ if (!assert_type(setting, type_hash, "not a hash"))
+ hash = new JsonHash();
+ }
+
+ private void assert_array(boolean setting) {
+ if (!assert_type(setting, type_array, "not an array"))
+ array = new JsonArray();
+ }
+
+ private void assert_number() {
+ assert_type(false, type_double, type_long, "not a number");
+ }
+
+ private void assert_double() {
+ assert_type(true, type_double, type_long, "not a number");
+ }
+
+ private void assert_long() {
+ assert_type(true, type_long, type_double, "not a number");
+ }
+
+ private void assert_string(boolean setting) {
+ assert_type(setting, type_string, "not a string");
+ }
+
+ private void assert_boolean(boolean setting) {
+ assert_type(setting, type_boolean, "not a boolean");
+ }
+
+ /* Primitive accessors
+ */
+ public double number() {
+ assert_number();
+ if (type == type_double)
+ return d_number;
+ else
+ return (double) l_number;
+ }
+
+ public long l_number() {
+ assert_number();
+ if (type == type_double)
+ return (long) d_number;
+ else
+ return l_number;
+ }
+
+ public String string() {
+ assert_string(false);
+ return string;
+ }
+
+ public boolean bool() {
+ assert_boolean(false);
+ return bool;
+ }
+
+ public AltosJson get(int index) {
+ assert_array(false);
+ return array.get(index);
+ }
+
+ public AltosJson get(String key) {
+ assert_hash(false);
+ return hash.get(key);
+ }
+
+ public int size() {
+ assert_array(false);
+ return array.size();
+ }
+
+ /* Typed accessors with defaulting
+ */
+ public double get_double(String key, double def) {
+ AltosJson value = get(key);
+ if (value != null) {
+ return value.number();
+ }
+ return def;
+ }
+
+ public long get_long(String key, long def) {
+ AltosJson value = get(key);
+ if (value != null)
+ return value.l_number();
+ return def;
+ }
+
+ public int get_int(String key, int def) {
+ AltosJson value = get(key);
+ if (value != null)
+ return (int) value.l_number();
+ return def;
+ }
+
+ public String get_string(String key, String def) {
+ AltosJson value = get(key);
+ if (value != null)
+ return value.string();
+ return def;
+ }
+
+ public boolean get_boolean(String key, boolean def) {
+ AltosJson value = get(key);
+ if (value != null)
+ return value.bool();
+ return def;
+ }
+
+ public double get_double(int index, double def) {
+ AltosJson value = get(index);
+ if (value != null)
+ return value.number();
+ return def;
+ }
+
+ public long get_long(int index, long def) {
+ AltosJson value = get(index);
+ if (value != null)
+ return value.l_number();
+ return def;
+ }
+
+ public int get_int(int index, int def) {
+ AltosJson value = get(index);
+ if (value != null)
+ return (int) value.l_number();
+ return def;
+ }
+
+ public String get_string(int index, String def) {
+ AltosJson value = get(index);
+ if (value != null)
+ return value.string();
+ return def;
+ }
+
+ public boolean get_boolean(int index, boolean def) {
+ AltosJson value = get(index);
+ if (value != null)
+ return value.bool();
+ return def;
+ }
+
+ public double[] get_double_array(String key, double[] def) {
+ AltosJson value = get(key);
+ if (value != null) {
+ double[] ret = new double[value.size()];
+ for (int i = 0; i < value.size(); i++)
+ ret[i] = value.get_double(i, def == null ? 0 : def[i]);
+ return ret;
+ }
+ return def;
+ }
+
+ public int[] get_int_array(String key, int[] def) {
+ AltosJson value = get(key);
+ if (value != null) {
+ int[] ret = new int[value.size()];
+ for (int i = 0; i < value.size(); i++)
+ ret[i] = value.get_int(i, def == null ? 0 : def[i]);
+ return ret;
+ }
+ return def;
+ }
+
+ /* Array setter functions
+ */
+ public AltosJson put(int index, AltosJson value) {
+ assert_array(true);
+ array.put(index, value);
+ return value;
+ }
+
+ public Object put(int index, Object value) {
+ assert_array(true);
+ if (value != null)
+ array.put(index, new AltosJson(value));
+ return value;
+ }
+
+ public double put(int index, double value) {
+ assert_array(true);
+ array.put(index, new AltosJson(value));
+ return value;
+ }
+
+ public AltosJson put(int index, double[] value) {
+ if (value != null) {
+ assert_array(true);
+ array.put(index, new AltosJson(value));
+ }
+ return this;
+ }
+
+ public int[] put(int index, int[] value) {
+ if (value != null) {
+ assert_array(true);
+ array.put(index, new AltosJson(value));
+ }
+ return value;
+ }
+
+ public String put(int index, String value) {
+ if (value != null) {
+ assert_array(true);
+ array.put(index, new AltosJson(value));
+ }
+ return value;
+ }
+
+ public boolean put(int index, boolean value) {
+ assert_array(true);
+ array.put(index, new AltosJson(value));
+ return value;
+ }
+
+ /* Hash setter functions
+ */
+ public AltosJson put(String key, AltosJson value) {
+ assert_hash(true);
+ hash.put(key, value);
+ return value;
+ }
+
+ public Object put(String key, Object value) {
+ assert_hash(true);
+ if (value != null)
+ hash.put(key, new AltosJson(value));
+ return value;
+ }
+
+ public double put(String key, double value) {
+ assert_hash(true);
+ hash.put(key, new AltosJson(value));
+ return value;
+ }
+
+ public String put(String key, String value) {
+ if (value != null) {
+ assert_hash(true);
+ hash.put(key, new AltosJson(value));
+ }
+ return value;
+ }
+
+ public boolean put(String key, boolean value) {
+ assert_hash(true);
+ hash.put(key, new AltosJson(value));
+ return value;
+ }
+
+ public AltosJson[] put(String key, AltosJson[] value) {
+ if (value != null) {
+ assert_hash(true);
+ hash.put(key, new AltosJson(value));
+ }
+ return value;
+ }
+
+ public double[] put(String key, double[] value) {
+ if (value != null) {
+ assert_hash(true);
+ hash.put(key, new AltosJson(value));
+ }
+ return value;
+ }
+
+ public int[] put(String key, int[] value) {
+ if (value != null) {
+ assert_hash(true);
+ hash.put(key, new AltosJson(value));
+ }
+ return value;
+ }
+
+ /* Primitive setter functions
+ */
+ public double put(double value) {
+ assert_double();
+ d_number = value;
+ return value;
+ }
+
+ public byte put(byte value) {
+ assert_long();
+ l_number = value;
+ return value;
+ }
+
+ public char put(char value) {
+ assert_long();
+ l_number = value;
+ return value;
+ }
+
+ public int put(int value) {
+ assert_long();
+ l_number = value;
+ return value;
+ }
+
+ public long put(long value) {
+ assert_long();
+ l_number = value;
+ return value;
+ }
+
+ public String put(String value) {
+ assert_string(true);
+ string = value;
+ return value;
+ }
+
+ public boolean put(boolean value) {
+ assert_boolean(true);
+ bool = value;
+ return value;
+ }
+
+ private boolean isInnerClass(Class c) {
+ for (Field field : c.getDeclaredFields())
+ if (field.isSynthetic())
+ return true;
+ return false;
+ }
+
+ /* Construct an object of the specified class from the JSON
+ * representation.
+ *
+ * This works as long as the structure is non-recursive, and
+ * all inner classes are only members of their immediate outer
+ * class
+ */
+ private Object make(Class c, Class enclosing_class, Object enclosing_object) {
+ Object ret;
+ if (c == Boolean.TYPE) {
+ ret = bool();
+ } else if (c == Byte.TYPE) {
+ ret = (Byte) (byte) l_number();
+ } else if (c == Character.TYPE) {
+ ret = (Character) (char) l_number();
+ } else if (c == Integer.TYPE) {
+ ret = (Integer) (int) l_number();
+ } else if (c == Long.TYPE) {
+ ret = l_number();
+ } else if (c == Double.TYPE) {
+ ret = number();
+ } else if (c == String.class) {
+ ret = string();
+ } else if (c.isArray()) {
+ assert_array(false);
+
+ Class element_class = c.getComponentType();
+ if (element_class == Boolean.TYPE) {
+ boolean[] array = (boolean[]) Array.newInstance(element_class, size());
+ for (int i = 0; i < array.length; i++)
+ array[i] = (Boolean) get(i).make(element_class);
+ ret = array;
+ } else if (element_class == Byte.TYPE) {
+ byte[] array = (byte[]) Array.newInstance(element_class, size());
+ for (int i = 0; i < array.length; i++)
+ array[i] = (Byte) get(i).make(element_class);
+ ret = array;
+ } else if (element_class == Character.TYPE) {
+ char[] array = (char[]) Array.newInstance(element_class, size());
+ for (int i = 0; i < array.length; i++)
+ array[i] = (Character) get(i).make(element_class);
+ ret = array;
+ } else if (element_class == Integer.TYPE) {
+ int[] array = (int[]) Array.newInstance(element_class, size());
+ for (int i = 0; i < array.length; i++)
+ array[i] = (Integer) get(i).make(element_class);
+ ret = array;
+ } else if (element_class == Long.TYPE) {
+ long[] array = (long[]) Array.newInstance(element_class, size());
+ for (int i = 0; i < array.length; i++)
+ array[i] = (Long) get(i).make(element_class);
+ ret = array;
+ } else if (element_class == Double.TYPE) {
+ double[] array = (double[]) Array.newInstance(element_class, size());
+ for (int i = 0; i < array.length; i++)
+ array[i] = (Double) get(i).make(element_class);
+ ret = array;
+ } else {
+ Object[] array = (Object[]) Array.newInstance(element_class, size());
+ for (int i = 0; i < array.length; i++)
+ array[i] = get(i).make(element_class);
+ ret = array;
+ }
+ } else {
+ assert_hash(false);
+ Object object = null;
+ try {
+ /* Inner classes have a hidden extra parameter
+ * to the constructor. Assume that the enclosing object is
+ * of the enclosing class and construct the object
+ * based on that.
+ */
+ if (enclosing_class != null && isInnerClass(c)) {
+ Constructor<?> ctor = ((Class<?>)c).getDeclaredConstructor((Class<?>) enclosing_class);
+ object = ctor.newInstance(enclosing_object);
+ } else {
+ object = c.newInstance();
+ }
+ for (; c != Object.class; c = c.getSuperclass()) {
+ for (Field field : c.getDeclaredFields()) {
+ String fieldName = field.getName();
+ Class fieldClass = field.getType();
+
+ if (Modifier.isStatic(field.getModifiers()))
+ continue;
+ if (field.isSynthetic())
+ continue;
+ try {
+ AltosJson json = get(fieldName);
+ if (json != null) {
+ Object val = json.make(fieldClass, c, object);
+ field.setAccessible(true);
+ field.set(object, val);
+ }
+ } catch (IllegalAccessException ie) {
+ System.out.printf("%s:%s %s\n",
+ c.getName(), fieldName, ie.toString());
+ }
+ }
+ }
+ ret = object;
+ } catch (InvocationTargetException ie) {
+ System.out.printf("%s: %s\n",
+ c.getName(), ie.toString());
+ ret = null;
+ } catch (NoSuchMethodException ie) {
+ System.out.printf("%s: %s\n",
+ c.getName(), ie.toString());
+ ret = null;
+ } catch (InstantiationException ie) {
+ System.out.printf("%s: %s\n",
+ c.getName(), ie.toString());
+ ret = null;
+ } catch (IllegalAccessException ie) {
+ System.out.printf("%s: %s\n",
+ c.getName(), ie.toString());
+ ret = null;
+ }
+ }
+ return ret;
+ }
+
+ /* This is the public API for the
+ * above function which doesn't handle
+ * inner classes
+ */
+ public Object make(Class c) {
+ return make(c, null, null);
+ }
+
+ /* Constructors, one for each primitive type, String and Object */
+ public AltosJson(boolean bool) {
+ type = type_boolean;
+ this.bool = bool;
+ }
+
+ public AltosJson(byte number) {
+ type = type_long;
+ this.l_number = number;
+ }
+
+ public AltosJson(char number) {
+ type = type_long;
+ this.l_number = number;
+ }
+
+ public AltosJson(int number) {
+ type = type_long;
+ this.l_number = number;
+ }
+
+ public AltosJson(long number) {
+ type = type_long;
+ this.l_number = number;
+ }
+
+ public AltosJson(double number) {
+ type = type_double;
+ this.d_number = number;
+ }
+
+ public AltosJson(String string) {
+ type = type_string;
+ this.string = string;
+ }
+
+ public AltosJson(Object object) {
+ if (object instanceof Boolean) {
+ type = type_boolean;
+ bool = (Boolean) object;
+ } else if (object instanceof Byte) {
+ type = type_long;
+ l_number = (Byte) object;
+ } else if (object instanceof Character) {
+ type = type_long;
+ l_number = (Character) object;
+ } else if (object instanceof Integer) {
+ type = type_long;
+ l_number = (Integer) object;
+ } else if (object instanceof Long) {
+ type = type_long;
+ l_number = (Long) object;
+ } else if (object instanceof Double) {
+ type = type_double;
+ d_number = (Double) object;
+ } else if (object instanceof String) {
+ type = type_string;
+ string = (String) object;
+ } else if (object.getClass().isArray()) {
+ assert_array(true);
+
+ Class component_class = object.getClass().getComponentType();
+ if (component_class == Boolean.TYPE) {
+ boolean[] array = (boolean[]) object;
+ for (int i = 0; i < array.length; i++)
+ put(i, new AltosJson(array[i]));
+ } else if (component_class == Byte.TYPE) {
+ byte[] array = (byte[]) object;
+ for (int i = 0; i < array.length; i++)
+ put(i, new AltosJson(array[i]));
+ } else if (component_class == Character.TYPE) {
+ char[] array = (char[]) object;
+ for (int i = 0; i < array.length; i++)
+ put(i, new AltosJson(array[i]));
+ } else if (component_class == Integer.TYPE) {
+ int[] array = (int[]) object;
+ for (int i = 0; i < array.length; i++)
+ put(i, new AltosJson(array[i]));
+ } else if (component_class == Long.TYPE) {
+ long[] array = (long[]) object;
+ for (int i = 0; i < array.length; i++)
+ put(i, new AltosJson(array[i]));
+ } else if (component_class == Double.TYPE) {
+ double[] array = (double[]) object;
+ for (int i = 0; i < array.length; i++)
+ put(i, new AltosJson(array[i]));
+ } else {
+ Object[] array = (Object[]) object;
+ for (int i = 0; i < array.length; i++)
+ put(i, new AltosJson(array[i]));
+ }
+ } else {
+ assert_hash(true);
+ for (Class c = object.getClass(); c != Object.class; c = c.getSuperclass()) {
+ for (Field field : c.getDeclaredFields()) {
+ String fieldName = field.getName();
+
+ /* Skip static fields */
+ if (Modifier.isStatic(field.getModifiers()))
+ continue;
+
+ /* Skip synthetic fields. We're assuming
+ * those are always an inner class reference
+ * to the outer class object
+ */
+ if (field.isSynthetic())
+ continue;
+ try {
+ /* We may need to force the field to be accessible if
+ * it is private
+ */
+ field.setAccessible(true);
+ Object val = field.get(object);
+ if (val != null) {
+ AltosJson json = new AltosJson(val);
+ put(fieldName, json);
+ }
+ } catch (IllegalAccessException ie) {
+ System.out.printf("%s:%s %s\n",
+ c.getName(), fieldName, ie.toString());
+ }
+ }
+ }
+ }
+ }
+
+ /* Array constructors, one for each primitive type, String and Object */
+ public AltosJson(boolean[] bools) {
+ assert_array(true);
+ for(int i = 0; i < bools.length; i++)
+ put(i, new AltosJson(bools[i]));
+ }
+
+ public AltosJson(byte[] numbers) {
+ assert_array(true);
+ for(int i = 0; i < numbers.length; i++)
+ put(i, new AltosJson(numbers[i]));
+ }
+
+ public AltosJson(char[] numbers) {
+ assert_array(true);
+ for(int i = 0; i < numbers.length; i++)
+ put(i, new AltosJson(numbers[i]));
+ }
+
+ public AltosJson(int[] numbers) {
+ assert_array(true);
+ for(int i = 0; i < numbers.length; i++)
+ put(i, new AltosJson(numbers[i]));
+ }
+
+ public AltosJson(long[] numbers) {
+ assert_array(true);
+ for(int i = 0; i < numbers.length; i++)
+ put(i, new AltosJson(numbers[i]));
+ }
+
+ public AltosJson(double[] numbers) {
+ assert_array(true);
+ for(int i = 0; i < numbers.length; i++)
+ put(i, new AltosJson(numbers[i]));
+ }
+
+ public AltosJson(String[] strings) {
+ assert_array(true);
+ for(int i = 0; i < strings.length; i++)
+ put(i, new AltosJson(strings[i]));
+ }
+
+ public AltosJson(AltosJson[] jsons) {
+ assert_array(true);
+ for (int i = 0; i < jsons.length; i++)
+ put(i, jsons[i]);
+ }
+
+ public AltosJson(Object[] array) {
+ assert_array(true);
+ for (int i = 0; i < array.length; i++)
+ put(i, new AltosJson(array[i]));
+ }
+
+ /* Empty constructor
+ */
+ public AltosJson() {
+ type = type_none;
+ }
+
+ public AltosJson(JsonHash hash) {
+ type = type_hash;
+ this.hash = hash;
+ }
+
+ public AltosJson(JsonArray array) {
+ type = type_array;
+ this.array = array;
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosLatLon {
public double lat;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosLatitude extends AltosLocation {
public String pos() { return "N"; }
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.lang.*;
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.lang.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.lang.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.*;
import java.io.*;
return r;
}
- public static int fromdec(String s) throws NumberFormatException {
- int c, v = 0;
- int sign = 1;
+ public static long fromdec(String s) throws NumberFormatException {
+ int c;
+ long v = 0;
+ long sign = 1;
for (int i = 0; i < s.length(); i++) {
c = s.charAt(i);
if (i == 0 && c == '-') {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosLine {
public String line;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
-public class AltosListenerState implements Serializable {
+public class AltosListenerState {
public int crc_errors;
public double battery;
public boolean running;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public abstract class AltosLocation extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosLongitude extends AltosLocation {
public String pos() { return "E"; }
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.*;
import java.io.*;
-public class AltosMag implements Cloneable, Serializable {
+public class AltosMag implements Cloneable {
public int along;
public int across;
public int through;
- public static double counts_per_gauss = 1090;
+ public static final double counts_per_gauss = 1090;
public static double convert_gauss(double counts) {
return counts / counts_per_gauss;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.lang.*;
};
AltosMapInterface map_interface;
+ int scale;
AltosMapCache cache;
if (!tiles.containsKey(point)) {
AltosLatLon ul = transform.lat_lon(point);
AltosLatLon center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
- AltosMapTile tile = map_interface.new_tile(cache, ul, center, zoom, maptype, px_size);
+ AltosMapTile tile = map_interface.new_tile(cache, ul, center, zoom, maptype, px_size, scale);
+ debug("show state %s url %s\n", AltosMapTile.status_name(tile.store.status()), tile.store.url);
tile.add_listener(this);
tiles.put(point, tile);
}
drag_stop(x, y);
}
- public AltosMap(AltosMapInterface map_interface) {
+ public AltosMap(AltosMapInterface map_interface, int scale) {
this.map_interface = map_interface;
+ this.scale = scale;
cache = new AltosMapCache(map_interface);
line = map_interface.new_line();
path = map_interface.new_path();
set_zoom_label();
}
+
+ public AltosMap(AltosMapInterface map_interface) {
+ this(map_interface, 1);
+ }
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.net.*;
public synchronized void notify_tile(AltosMapTile tile, int status) {
if (status == AltosMapTile.fetched) {
- System.out.printf("tile fetched, loading image\n");
load();
}
}
elements[oldest].flush();
elements[oldest] = element;
- System.out.printf("AltosMapCache.get image ? %s\n",
- element.image == null ? "false" : "true");
return element.image;
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosMapCacheListener {
public void map_cache_changed(int map_cache);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.net.*;
public abstract AltosMapMark new_mark(double lat, double lon, int state);
- public abstract AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size);
+ public abstract AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale);
public abstract int width();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.lang.Math;
if (AltosConvert.imperial_units) {
distance = AltosConvert.meters_to_feet(distance);
- if (distance < 10000) {
+ if (distance < 1000) {
format = "%4.0fft";
} else {
distance /= 5280;
format = "%5.0fmi";
}
} else {
- if (distance < 10000) {
+ if (distance < 1000) {
format = "%4.0fm";
} else {
distance /= 1000;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
+import java.util.concurrent.*;
import java.text.*;
import java.lang.Math;
import java.net.URL;
import java.net.URLConnection;
-public class AltosMapLoader extends Thread implements AltosMapTileListener {
+public class AltosMapLoader extends Thread implements AltosMapStoreListener {
AltosMapLoaderListener listener;
double latitude, longitude;
int all_types;
int cur_type;
double radius;
+ int scale;
int tiles_loaded_layer;
int tiles_loaded_total;
int layers_total;
int layers_loaded;
- AltosMap map;
+ private static final int MAX_LOADING = 200;
+
+ private Semaphore loading = new Semaphore(MAX_LOADING);
+
+ boolean abort;
int tile_radius(int zoom) {
double delta_lon = AltosMapTransform.lon_from_distance(latitude, radius);
return (tile_radius * 2 + 1) * (tile_radius * 2 + 1);
}
- public void do_load() {
+ private boolean do_load() {
tiles_this_layer = tiles_per_layer(cur_z);
tiles_loaded_layer = 0;
listener.debug("tiles_this_layer %d (zoom %d)\n", tiles_this_layer, cur_z);
AltosLatLon load_centre = new AltosLatLon(latitude, longitude);
AltosMapTransform transform = new AltosMapTransform(256, 256, zoom, load_centre);
- map.centre(load_centre);
-
AltosPointInt upper_left;
AltosPointInt lower_right;
for (int y = (int) upper_left.y; y <= lower_right.y; y += AltosMap.px_size) {
for (int x = (int) upper_left.x; x <= lower_right.x; x += AltosMap.px_size) {
+ try {
+ loading.acquire();
+ } catch (InterruptedException ie) {
+ return false;
+ }
AltosPointInt point = new AltosPointInt(x, y);
AltosLatLon ul = transform.lat_lon(point);
AltosLatLon center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2));
- AltosMapTile tile = map.map_interface.new_tile(null, ul, center, zoom, maptype, AltosMap.px_size);
- tile.add_listener(this);
+ AltosMapStore store = AltosMapStore.get(center, zoom, maptype, AltosMap.px_size, scale);
+ listener.debug("load state %s url %s\n", AltosMapTile.status_name(store.status()), store.url);
+ store.add_listener(this);
+ if (abort)
+ return false;
}
}
+ return true;
}
- public int next_type(int start) {
+ private int next_type(int start) {
int next_type;
for (next_type = start;
next_type <= AltosMap.maptype_terrain && (all_types & (1 << next_type)) == 0;
return next_type;
}
- public void next_load() {
+ private boolean next_load() {
int next_type = next_type(cur_type + 1);
if (next_type > AltosMap.maptype_terrain) {
if (cur_z == max_z) {
- return;
+ return false;
} else {
cur_z++;
}
next_type = next_type(0);
}
cur_type = next_type;
- do_load();
+ return true;
}
public void run() {
listener.debug("total tiles %d layers %d\n", tiles_total, layers_total);
listener.loader_start(tiles_total);
- do_load();
+ do {
+ if (!do_load())
+ break;
+ } while (next_load());
+ if (abort)
+ listener.loader_done(tiles_total);
}
- public synchronized void notify_tile(AltosMapTile tile, int status) {
+ public synchronized void notify_store(AltosMapStore store, int status) {
boolean do_next = false;
if (status == AltosMapTile.fetching)
return;
- tile.remove_listener(this);
+ loading.release();
+
+ store.remove_listener(this);
if (layers_loaded >= layers_total)
return;
++tiles_loaded_total;
++tiles_loaded_layer;
- listener.debug("AltosMapLoader.notify_tile status %d total %d of %d layer %d of %d\n",
+ listener.debug("AltosMapLoader.notify_store status %d total %d of %d layer %d of %d\n",
status, tiles_loaded_total, tiles_total, tiles_loaded_layer, tiles_this_layer);
if (tiles_loaded_layer == tiles_this_layer) {
if (tiles_loaded_total == tiles_total)
listener.loader_done(tiles_total);
- else {
+ else
listener.loader_notify(tiles_loaded_total,
- tiles_total, tile.store.file.toString());
- if (do_next)
- next_load();
- }
+ tiles_total, store.file.toString());
+ }
+
+ public void abort() {
+ this.abort = true;
}
- public AltosMapLoader(AltosMap map, AltosMapLoaderListener listener,
- double latitude, double longitude, int min_z, int max_z, double radius, int all_types) {
+ public AltosMapLoader(AltosMapLoaderListener listener,
+ double latitude, double longitude, int min_z, int max_z, double radius, int all_types, int scale) {
listener.debug("lat %f lon %f min_z %d max_z %d radius %f all_types %d\n",
latitude, longitude, min_z, max_z, radius, all_types);
- this.map = map;
this.listener = listener;
this.latitude = latitude;
this.longitude = longitude;
this.max_z = max_z;
this.radius = radius;
this.all_types = all_types;
+ this.scale = scale;
+ this.abort = false;
start();
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosMapLoaderListener {
public abstract void loader_start(int max);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosMapRectangle {
AltosLatLon ul, lr;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.net.*;
int status;
+ private static File map_file(AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+ double lat = center.lat;
+ double lon = center.lon;
+ char chlat = lat < 0 ? 'S' : 'N';
+ char chlon = lon < 0 ? 'W' : 'E';
+
+ if (lat < 0) lat = -lat;
+ if (lon < 0) lon = -lon;
+ String maptype_string = String.format("%s-", AltosMap.maptype_names[maptype]);
+ String format_string;
+ if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
+ format_string = "jpg";
+ else
+ format_string = "png";
+ return new File(AltosPreferences.mapdir(),
+ String.format("map-%c%.6f,%c%.6f-%s%d%s.%s",
+ chlat, lat, chlon, lon, maptype_string, zoom, scale == 1 ? "" : String.format("-%d", scale), format_string));
+ }
+
+ private static String map_url(AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+ String format_string;
+ int z = zoom;
+
+ if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
+ format_string = "jpg";
+ else
+ format_string = "png32";
+
+ for (int s = 1; s < scale; s <<= 1)
+ z--;
+
+ if (AltosVersion.has_google_maps_api_key())
+ return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s&key=%s",
+ center.lat, center.lon, z, px_size/scale, px_size/scale, scale, AltosMap.maptype_names[maptype], format_string, AltosVersion.google_maps_api_key);
+ else
+ return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s",
+ center.lat, center.lon, z, px_size/scale, px_size/scale, AltosMap.maptype_names[maptype], format_string);
+ }
+
public int status() {
return status;
}
static HashMap<String,AltosMapStore> stores = new HashMap<String,AltosMapStore>();
- public static AltosMapStore get(String url, File file) {
+ public static AltosMapStore get(AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+ String url = map_url(center, zoom, maptype, px_size, scale);
+
AltosMapStore store;
synchronized(stores) {
if (stores.containsKey(url)) {
store = stores.get(url);
} else {
- store = new AltosMapStore(url, file);
+ store = new AltosMapStore(url, map_file(center, zoom, maptype, px_size, scale));
stores.put(url, store);
}
}
return store;
}
+
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosMapStoreListener {
abstract void notify_store(AltosMapStore store, int status);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
-public abstract class AltosMapTile implements AltosFontListener, AltosMapStoreListener {
+public class AltosMapTile implements AltosFontListener, AltosMapStoreListener {
LinkedList<AltosMapTileListener> listeners = new LinkedList<AltosMapTileListener>();
public AltosLatLon upper_left, center;
public int px_size;
static public final int bad_request = 4;/* downloading failed */
static public final int forbidden = 5; /* downloading failed */
- private File map_file() {
- double lat = center.lat;
- double lon = center.lon;
- char chlat = lat < 0 ? 'S' : 'N';
- char chlon = lon < 0 ? 'W' : 'E';
-
- if (lat < 0) lat = -lat;
- if (lon < 0) lon = -lon;
- String maptype_string = String.format("%s-", AltosMap.maptype_names[maptype]);
- String format_string;
- if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
- format_string = "jpg";
- else
- format_string = "png";
- return new File(AltosPreferences.mapdir(),
- String.format("map-%c%.6f,%c%.6f-%s%d%s.%s",
- chlat, lat, chlon, lon, maptype_string, zoom, scale == 1 ? "" : String.format("-%d", scale), format_string));
- }
-
- private String map_url() {
- String format_string;
- int z = zoom;
-
- if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
- format_string = "jpg";
- else
- format_string = "png32";
-
- for (int s = 1; s < scale; s <<= 1)
- z--;
-
- if (AltosVersion.has_google_maps_api_key())
- return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s&key=%s",
- center.lat, center.lon, z, px_size/scale, px_size/scale, scale, AltosMap.maptype_names[maptype], format_string, AltosVersion.google_maps_api_key);
- else
- return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s",
- center.lat, center.lon, z, px_size/scale, px_size/scale, AltosMap.maptype_names[maptype], format_string);
+ static public String status_name(int status) {
+ switch (status) {
+ case loaded:
+ return "loaded";
+ case fetched:
+ return "fetched";
+ case fetching:
+ return "fetching";
+ case failed:
+ return "failed";
+ case bad_request:
+ return "bad_request";
+ case forbidden:
+ return "forbidden";
+ default:
+ return "unknown";
+ }
}
public void font_size_changed(int font_size) {
}
public void notify_store(AltosMapStore store, int status) {
-// System.out.printf("AltosMapTile.notify_store %d\n", status);
notify_listeners(status);
}
notify_listeners(status);
}
- public abstract void paint(AltosMapTransform t);
+ public void paint(AltosMapTransform t) {
+ }
public AltosImage get_image() {
if (cache == null)
this.px_size = px_size;
this.scale = scale;
- store = AltosMapStore.get(map_url(), map_file());
+ store = AltosMapStore.get(center, zoom, maptype, px_size, scale);
store.add_listener(this);
}
-
- public AltosMapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
- this(cache, upper_left, center, zoom, maptype, px_size, 1);
- }
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosMapTileListener {
abstract public void notify_tile(AltosMapTile tile, int status);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.lang.Math;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosMapTypeListener {
public void map_type_changed(int map_type);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosMapZoomListener {
abstract public void zoom_changed(int zoom);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.*;
import java.io.*;
-public class AltosMs5607 implements Serializable {
+public class AltosMs5607 {
public int reserved;
public int sens;
public int off;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosNoSymbol extends Exception {
public AltosNoSymbol(String name) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosOrient extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.*;
import java.text.*;
}
public static int parse_int(String v) throws ParseException {
+ try {
+ return (int) AltosLib.fromdec(v);
+ } catch (NumberFormatException e) {
+ throw new ParseException("error parsing int " + v, 0);
+ }
+ }
+
+ public static long parse_long(String v) throws ParseException {
try {
return AltosLib.fromdec(v);
} catch (NumberFormatException e) {
}
}
- static NumberFormat nf_locale = NumberFormat.getInstance();
+ static NumberFormat get_nf_locale() {
+ NumberFormat nf = NumberFormat.getInstance();
+ nf.setParseIntegerOnly(false);
+ nf.setGroupingUsed(false);
+ return nf;
+ }
+
+ static NumberFormat nf_locale = get_nf_locale();
+
+ static NumberFormat get_nf_net() {
+ NumberFormat nf = NumberFormat.getInstance(Locale.ROOT);
+ nf.setParseIntegerOnly(false);
+ nf.setGroupingUsed(false);
+ return nf;
+ }
- static NumberFormat nf_net = NumberFormat.getInstance(Locale.ROOT);
+ static NumberFormat nf_net = get_nf_net();
public static double parse_double_locale(String str) throws ParseException {
try {
}
}
+ public static String format_double_locale(double number) {
+ return nf_locale.format(number);
+ }
+
public static double parse_double_net(String str) throws ParseException {
try {
- return nf_net.parse(str.trim()).doubleValue();
+ String t = str.trim();
+// System.out.printf("Parse string \"%s\" trim \"%s\"\n", str, t);
+ return nf_net.parse(t).doubleValue();
} catch (ParseException pe) {
throw new ParseException("error parsing double " + str, 0);
}
}
+ public static String format_double_net(double number) {
+ String ret = nf_net.format(number);
+// System.out.printf("format double %f \"%s\"\n", number, ret);
+ return ret;
+ }
+
public static double parse_coord(String coord) throws ParseException {
String[] dsf = coord.split("\\D+");
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosPointDouble {
public double x, y;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosPointInt {
public int x, y;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
public final static String frequency_count = "COUNT";
public final static String frequency_format = "FREQUENCY-%d";
public final static String description_format = "DESCRIPTION-%d";
- public final static String frequenciesPreference = "FREQUENCIES";
+ public final static String frequenciesPreference = "FREQUENCIES-1";
/* Units preference */
static int map_type;
public static AltosFrequency[] load_common_frequencies() {
-
AltosFrequency[] frequencies = null;
- frequencies = (AltosFrequency[]) backend.getSerializable(frequenciesPreference, null);
+ try {
+ AltosJson json = AltosJson.fromString(backend.getString(frequenciesPreference,
+ null));
+ frequencies = (AltosFrequency[]) json.make(frequencies.getClass());
+ } catch (Exception e) {
+ }
if (frequencies == null) {
if (backend.nodeExists(common_frequencies_node_name)) {
AltosPreferencesBackend node = backend.node(common_frequencies_node_name);
int count = node.getInt(frequency_count, 0);
- frequencies = new AltosFrequency[count];
- for (int i = 0; i < count; i++) {
- double frequency;
- String description;
+ if (count > 0) {
+ frequencies = new AltosFrequency[count];
+ for (int i = 0; i < count; i++) {
+ double frequency;
+ String description;
- frequency = node.getDouble(String.format(frequency_format, i), 0.0);
- description = node.getString(String.format(description_format, i), null);
- frequencies[i] = new AltosFrequency(frequency, description);
+ frequency = node.getDouble(String.format(frequency_format, i), 0.0);
+ description = node.getString(String.format(description_format, i), null);
+ frequencies[i] = new AltosFrequency(frequency, description);
+ }
}
}
}
return frequencies;
}
+ public static void save_common_frequencies() {
+ AltosJson json = new AltosJson(common_frequencies);
+ backend.putString(frequenciesPreference, json.toString());
+ flush_preferences();
+ }
+
public static int launcher_serial;
public static int launcher_channel;
public static void set_state(AltosState state) {
synchronized(backend) {
- backend.putSerializable(String.format(statePreferenceFormat, state.serial), state);
+ backend.putJson(String.format(statePreferenceFormat, state.serial), new AltosJson(state));
backend.putInt(statePreferenceLatest, state.serial);
flush_preferences();
}
public static void remove_state(int serial) {
synchronized(backend) {
backend.remove(String.format(statePreferenceFormat, serial));
+ flush_preferences();
}
}
public static AltosState state(int serial) {
synchronized(backend) {
try {
- return (AltosState) backend.getSerializable(String.format(statePreferenceFormat, serial), null);
+ AltosJson json = backend.getJson(String.format(statePreferenceFormat, serial));
+ if (json != null)
+ return (AltosState) (json.make(AltosState.class));
} catch (Exception e) {
- return null;
}
+ return null;
}
}
public static void set_common_frequencies(AltosFrequency[] frequencies) {
synchronized(backend) {
common_frequencies = frequencies;
- backend.putSerializable(frequenciesPreference, frequencies);
- flush_preferences();
+
+ save_common_frequencies();
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
public abstract byte[] getBytes(String key, byte[] def);
public abstract void putBytes(String key, byte[] value);
- public Serializable getSerializable(String key, Serializable def) {
- byte[] bytes = null;
-
- bytes = getBytes(key, null);
- if (bytes == null)
- return def;
-
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ public AltosJson getJson(String key) {
+ String value = getString(key, null);
+ if (value == null)
+ return null;
try {
- ObjectInputStream ois = new ObjectInputStream(bais);
- Serializable object = (Serializable) ois.readObject();
- return object;
- } catch (IOException ie) {
- debug("IO exception %s\n", ie.toString());
- } catch (ClassNotFoundException ce) {
- debug("ClassNotFoundException %s\n", ce.toString());
+ return AltosJson.fromString(value);
+ } catch (IllegalArgumentException ie) {
+ return null;
}
- return def;
}
- public void putSerializable(String key, Serializable object) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- try {
- ObjectOutputStream oos = new ObjectOutputStream(baos);
-
- oos.writeObject(object);
- byte[] bytes = baos.toByteArray();
-
- putBytes(key, bytes);
- } catch (IOException ie) {
- debug("set_state failed %s\n", ie.toString());
- }
+ public void putJson(String key, AltosJson j) {
+ putString(key, j.toString());
}
public abstract boolean nodeExists(String key);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.*;
import java.text.*;
units = pyro_to_units.get(flag);
if (units == null)
return name;
- return String.format ("%s (%s)", name, units.show_units());
+ return String.format ("%s (%s)", name, units.parse_units());
}
public static AltosUnits pyro_to_units(int flag) {
int value = 0;
++i;
try {
- value = AltosLib.fromdec(tokens[i]);
+ value = (int) AltosLib.fromdec(tokens[i]);
} catch (NumberFormatException n) {
throw new ParseException(String.format("Invalid pyro value \"%s\"",
tokens[i]), i);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosQuaternion {
double r; /* real bit */
}
public AltosQuaternion(AltosQuaternion q) {
- this.r = q.r;
- this.x = q.x;
- this.y = q.y;
- this.z = q.z;
+ r = q.r;
+ x = q.x;
+ y = q.y;
+ z = q.z;
+ }
+
+ public AltosQuaternion() {
+ r = 1;
+ x = 0;
+ y = 0;
+ z = 0;
}
static public AltosQuaternion vector(double x, double y, double z) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosRectangle {
public int x, y, width, height;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
-public class AltosRotation {
+public class AltosRotation extends AltosQuaternion {
private AltosQuaternion rotation;
public double tilt() {
AltosQuaternion up = new AltosQuaternion(0, 0, 0, sky);
rotation = up.vectors_to_rotation(orient);
}
+
+ public AltosRotation() {
+ rotation = new AltosQuaternion();
+ }
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
-public class AltosSavedState implements Serializable {
+public class AltosSavedState {
public AltosState state;
public AltosListenerState listener_state;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.util.concurrent.TimeoutException;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosSpeed extends AltosUnits {
* Track flight state from telemetry or eeprom data stream
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
-public class AltosState implements Cloneable, Serializable {
+public class AltosState implements Cloneable {
public static final int set_position = 1;
public static final int set_gps = 2;
private int prev_tick;
public int boost_tick;
- class AltosValue implements Serializable{
+ class AltosValue {
double value;
double prev_value;
private double max_value;
prev_value = AltosLib.MISSING;
max_value = AltosLib.MISSING;
}
+
}
- class AltosCValue implements Serializable {
+ class AltosCValue {
- class AltosIValue extends AltosValue implements Serializable {
+ class AltosIValue extends AltosValue {
boolean can_max() {
return c_can_max();
}
+
+ AltosIValue() {
+ super();
+ }
};
public AltosIValue measured;
computed.finish_update();
}
- AltosCValue() {
+ public AltosCValue() {
measured = new AltosIValue();
computed = new AltosIValue();
}
ground_altitude.set_measured(a, time);
}
- class AltosGpsGroundAltitude extends AltosValue implements Serializable {
+ class AltosGpsGroundAltitude extends AltosValue {
void set(double a, double t) {
super.set(a, t);
pad_alt = value();
pad_alt = value();
gps_altitude.set_gps_height();
}
+
+ AltosGpsGroundAltitude() {
+ super();
+ }
}
private AltosGpsGroundAltitude gps_ground_altitude;
gps_ground_altitude.set(a, time);
}
- class AltosGroundPressure extends AltosCValue implements Serializable {
+ class AltosGroundPressure extends AltosCValue {
void set_filtered(double p, double time) {
computed.set_filtered(p, time);
if (!is_measured())
super.set_measured(p, time);
ground_altitude.set_computed(pressure_to_altitude(p), time);
}
+
+ AltosGroundPressure () {
+ super();
+ }
}
private AltosGroundPressure ground_pressure;
ground_pressure.set_measured(pressure, time);
}
- class AltosAltitude extends AltosCValue implements Serializable {
+ class AltosAltitude extends AltosCValue {
private void set_speed(AltosValue v) {
if (!acceleration.is_measured() || !ascent)
set_speed(measured);
set |= set_position;
}
+
+ AltosAltitude() {
+ super();
+ }
}
private AltosAltitude altitude;
- class AltosGpsAltitude extends AltosValue implements Serializable {
+ class AltosGpsAltitude extends AltosValue {
private void set_gps_height() {
double a = value();
super.set(a, t);
set_gps_height();
}
+
+ AltosGpsAltitude() {
+ super();
+ }
}
private AltosGpsAltitude gps_altitude;
return gps_speed.max();
}
- class AltosPressure extends AltosValue implements Serializable {
+ class AltosPressure extends AltosValue {
void set(double p, double time) {
super.set(p, time);
if (state == AltosLib.ao_flight_pad)
double a = pressure_to_altitude(p);
altitude.set_computed(a, time);
}
+
+ AltosPressure() {
+ super();
+ }
}
private AltosPressure pressure;
return AltosLib.MISSING;
}
- class AltosSpeed extends AltosCValue implements Serializable {
+ class AltosSpeed extends AltosCValue {
boolean can_max() {
return state < AltosLib.ao_flight_fast || state == AltosLib.ao_flight_stateless;
super.set_measured(new_value, time);
set_accel();
}
+
+ AltosSpeed() {
+ super();
+ }
}
private AltosSpeed speed;
return AltosLib.MISSING;
}
- class AltosAccel extends AltosCValue implements Serializable {
+ class AltosAccel extends AltosCValue {
boolean can_max() {
return state < AltosLib.ao_flight_fast || state == AltosLib.ao_flight_stateless;
if (ascent)
speed.set_integral(this.measured);
}
+
+ AltosAccel() {
+ super();
+ }
}
AltosAccel acceleration;
public double ground_accel_avg;
public int log_format;
+ public int log_space;
public String product;
public AltosMs5607 baro;
ground_accel_avg = AltosLib.MISSING;
log_format = AltosLib.MISSING;
+ log_space = AltosLib.MISSING;
product = null;
serial = AltosLib.MISSING;
receiver_serial = AltosLib.MISSING;
ground_accel_avg = old.ground_accel_avg;
log_format = old.log_format;
+ log_space = old.log_space;
product = old.product;
serial = old.serial;
receiver_serial = old.receiver_serial;
}
}
+ public void set_log_space(int log_space) {
+ this.log_space = log_space;
+ }
+
public void set_flight_params(int apogee_delay, int main_deploy) {
this.apogee_delay = apogee_delay;
this.main_deploy = main_deploy;
public AltosState clone() {
AltosState s = new AltosState();
s.copy(this);
+
+ /* Code to test state save/restore. Enable only for that purpose
+ */
+ if (false) {
+ AltosJson json = new AltosJson(this);
+ String onetrip = json.toPrettyString();
+ AltosJson back = AltosJson.fromString(onetrip);
+ AltosState tripstate = (AltosState) back.make(this.getClass());
+ AltosJson tripjson = new AltosJson(tripstate);
+ String twotrip = tripjson.toPrettyString();
+
+ if (!onetrip.equals(twotrip)) {
+ try {
+ FileWriter one_file = new FileWriter("one.json", true);
+ one_file.write(onetrip);
+ one_file.flush();
+ FileWriter two_file = new FileWriter("two.json", true);
+ two_file.write(twotrip);
+ two_file.flush();
+ } catch (Exception e) {
+ }
+ System.out.printf("json error\n");
+ System.exit(1);
+ }
+ }
return s;
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
try {
in = new FileInputStream(file);
} catch (Exception e) {
- System.out.printf("Failed to open file '%s'\n", file);
return null;
}
if (file.getName().endsWith("telem"))
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosStateUpdate {
public void update_state(AltosState state) throws InterruptedException, AltosUnknownProduct;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetryCompanion extends AltosTelemetryStandard {
AltosCompanion companion;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetryConfiguration extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.io.*;
import java.util.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.text.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetryLocation extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.text.*;
import java.util.HashMap;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetryMegaData extends AltosTelemetryStandard {
int state;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetryMegaSensor extends AltosTelemetryStandard {
int accel;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetryMetrumData extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetryMetrumSensor extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetryMini extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetryRaw extends AltosTelemetryStandard {
public AltosTelemetryRaw(int[] bytes) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.text.*;
import java.io.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetrySatellite extends AltosTelemetryStandard {
int channels;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTelemetrySensor extends AltosTelemetryStandard {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public abstract class AltosTelemetryStandard extends AltosTelemetry {
int[] bytes;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosTemperature extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import java.text.*;
public abstract class AltosUnits {
+ AltosUnitsRange[] range_metric, range_imperial;
+
+ private AltosUnitsRange range(double v, boolean imperial_units) {
+ AltosUnitsRange[] ranges = imperial_units ? range_imperial : range_metric;
+
+ for (int i = ranges.length - 1; i > 0; i--)
+ if (v >= ranges[i].lower_limit)
+ return ranges[i];
+ return ranges[0];
+ }
+
+ private AltosUnitsRange first_range(boolean imperial_units) {
+ return imperial_units ? range_imperial[0] : range_metric[0];
+ }
+
public abstract double value(double v, boolean imperial_units);
public abstract double inverse(double v, boolean imperial_units);
public abstract int show_fraction(int width, boolean imperial_units);
- public double parse_locale(String s, boolean imperial_units) throws ParseException {
- double v = AltosParse.parse_double_locale(s);
- return inverse(v, imperial_units);
+ private double value(double v) {
+ return value(v, AltosConvert.imperial_units);
}
- public double parse_net(String s, boolean imperial_units) throws ParseException {
- double v = AltosParse.parse_double_net(s);
- return inverse(v, imperial_units);
+ private double inverse(double v) {
+ return inverse(v, AltosConvert.imperial_units);
}
- public double parse_locale(String s) throws ParseException {
- return parse_locale(s, AltosConvert.imperial_units);
+ private String show_units() {
+ return show_units(AltosConvert.imperial_units);
}
- public double parse_net(String s) throws ParseException {
- return parse_net(s, AltosConvert.imperial_units);
+ private String say_units() {
+ return say_units(AltosConvert.imperial_units);
}
- public double value(double v) {
- return value(v, AltosConvert.imperial_units);
+ private int show_fraction(int width) {
+ return show_fraction(width, AltosConvert.imperial_units);
}
- public double inverse(double v) {
- return inverse(v, AltosConvert.imperial_units);
+ private int say_fraction(boolean imperial_units) {
+ return 0;
}
- public String show_units() {
- return show_units(AltosConvert.imperial_units);
+ private String show_format(AltosUnitsRange range, int width) {
+ return String.format("%%%d.%df %s", width, range.show_fraction(width), range.show_units);
}
- public String say_units() {
- return say_units(AltosConvert.imperial_units);
+ private String say_format(AltosUnitsRange range) {
+ return String.format("%%1.%df", range.say_fraction());
}
- public int show_fraction(int width) {
- return show_fraction(width, AltosConvert.imperial_units);
+ private String say_units_format(AltosUnitsRange range) {
+ return String.format("%%1.%df %s", range.say_fraction(), range.say_units);
}
- int say_fraction(boolean imperial_units) {
- return 0;
+ public String show(int width, double v, boolean imperial_units) {
+ AltosUnitsRange range = range(v, imperial_units);
+
+ return String.format(show_format(range, width), range.value(v));
+ }
+
+ public String say(double v, boolean imperial_units) {
+ AltosUnitsRange range = range(v, imperial_units);
+
+ return String.format(say_format(range), range.value(v));
+ }
+
+ public String say_units(double v, boolean imperial_units) {
+ AltosUnitsRange range = range(v, imperial_units);
+
+ return String.format(say_units_format(range), range.value(v));
+ }
+
+ public String show(int width, double v) {
+ return show(width, v, AltosConvert.imperial_units);
+ }
+
+ public String say(double v) {
+ return say(v, AltosConvert.imperial_units);
+ }
+
+ public String say_units(double v) {
+ return say_units(v, AltosConvert.imperial_units);
+ }
+
+ /* Parsing functions. Use the first range of the type */
+ public String parse_units(boolean imperial_units) {
+ return first_range(imperial_units).show_units;
+ }
+
+ public String parse_units() {
+ return parse_units(AltosConvert.imperial_units);
+ }
+
+ public double parse_value(double v, boolean imperial_units) {
+ return first_range(imperial_units).value(v);
+ }
+
+ public double parse_value(double v) {
+ return parse_value(v, AltosConvert.imperial_units);
}
- private String show_format(int width, boolean imperial_units) {
- return String.format("%%%d.%df %s", width, show_fraction(width, imperial_units), show_units(imperial_units));
+ /* Graphing functions. Use the first range of the type */
+ public String graph_units(boolean imperial_units) {
+ return first_range(imperial_units).show_units;
}
- private String say_format(boolean imperial_units) {
- return String.format("%%1.%df", say_fraction(imperial_units));
+ public String graph_units() {
+ return graph_units(AltosConvert.imperial_units);
}
- private String say_units_format(boolean imperial_units) {
- return String.format("%%1.%df %s", say_fraction(imperial_units), say_units(imperial_units));
+ public double graph_value(double v, boolean imperial_units) {
+ return first_range(imperial_units).value(v);
+ }
+
+ public double graph_value(double v) {
+ return graph_value(v, AltosConvert.imperial_units);
+ }
+
+ private String graph_format(AltosUnitsRange range, int width) {
+ return String.format(String.format("%%%d.%df", width, range.show_fraction(width)), 0.0);
}
public String graph_format(int width, boolean imperial_units) {
- return String.format(String.format("%%%d.%df", width, show_fraction(width, imperial_units)), 0.0);
+ return graph_format(first_range(imperial_units), width);
}
public String graph_format(int width) {
return graph_format(width, AltosConvert.imperial_units);
}
- public String show(int width, double v, boolean imperial_units) {
- return String.format(show_format(width, imperial_units), value(v, imperial_units));
+ /* Parsing functions. */
+ public double parse_locale(String s, boolean imperial_units) throws ParseException {
+ double v = AltosParse.parse_double_locale(s);
+ return inverse(v, imperial_units);
}
- public String show(int width, double v) {
- return show(width, v, AltosConvert.imperial_units);
+ public double parse_net(String s, boolean imperial_units) throws ParseException {
+ double v = AltosParse.parse_double_net(s);
+ return inverse(v, imperial_units);
}
- public String say(double v, boolean imperial_units) {
- return String.format(say_format(imperial_units), value(v, imperial_units));
+ public double parse_locale(String s) throws ParseException {
+ return parse_locale(s, AltosConvert.imperial_units);
}
- public String say(double v) {
- return say(v, AltosConvert.imperial_units);
+ public double parse_net(String s) throws ParseException {
+ return parse_net(s, AltosConvert.imperial_units);
}
- public String say_units(double v, boolean imperial_units) {
- return String.format(say_units_format(imperial_units), value(v, imperial_units));
- }
+ public AltosUnits() {
+ range_metric = new AltosUnitsRange[1];
- public String say_units(double v) {
- return say_units(v, AltosConvert.imperial_units);
+ range_metric[0] = new AltosUnitsRange(this, false) {
+ double value(double v) {
+ return units.value(v, false);
+ }
+
+ int show_fraction(int width) {
+ return units.show_fraction(width, false);
+ }
+
+ int say_fraction() {
+ return units.say_fraction(false);
+ }
+ };
+
+ range_imperial = new AltosUnitsRange[1];
+
+ range_imperial[0] = new AltosUnitsRange(this, true) {
+ double value(double v) {
+ return units.value(v, true);
+ }
+
+ int show_fraction(int width) {
+ return units.show_fraction(width, true);
+ }
+
+ int say_fraction() {
+ return units.say_fraction(true);
+ }
+ };
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosUnitsListener {
public void units_changed(boolean imperial_units);
--- /dev/null
+/*
+ * Copyright © 2016 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 org.altusmetrum.altoslib_11;
+
+import java.text.*;
+
+public abstract class AltosUnitsRange {
+
+ AltosUnits units;
+
+ double lower_limit;
+ String show_units;
+ String say_units;
+
+ abstract double value(double v);
+ abstract int show_fraction(int width);
+ abstract int say_fraction();
+
+ AltosUnitsRange(AltosUnits units, boolean imperial_units) {
+ this.units = units;
+ this.show_units = units.show_units(imperial_units);
+ this.say_units = units.say_units(imperial_units);
+ }
+
+ AltosUnitsRange(double lower_limit, String show_units, String say_units) {
+ this.units = null;
+ this.lower_limit = lower_limit;
+ this.show_units = show_units;
+ this.say_units = say_units;
+ }
+}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosUnknownProduct extends Exception {
public String product;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosVersion {
public final static String version = "@VERSION@";
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public class AltosVoltage extends AltosUnits {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
public interface AltosWriter {
AltosIdleFetch.java \
AltosIdleMonitor.java \
AltosIdleMonitorListener.java \
+ AltosIdleReader.java \
AltosIgnite.java \
AltosIMU.java \
AltosKML.java \
AltosIMU.java \
AltosMag.java \
AltosUnits.java \
+ AltosUnitsRange.java \
AltosDistance.java \
AltosHeight.java \
AltosSpeed.java \
AltosMapLoaderListener.java \
AltosMapLoader.java \
AltosMapTypeListener.java \
+ AltosJson.java \
AltosVersion.java
JAR=altoslib_$(ALTOSLIB_VERSION).jar
import java.awt.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class Altos extends AltosUILib {
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosAscent extends AltosUIFlightTab {
JLabel cur, max;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosCompanionInfo extends JTable implements AltosFlightDisplay {
private AltosFlightInfoTableModel model;
import java.io.*;
import java.util.concurrent.*;
import java.text.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosConfig implements ActionListener {
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosConfigPyroUI
extends AltosUIDialog
double unit_value = new_value;
AltosUnits units = AltosPyro.pyro_to_units(flag);
if (units != null)
- unit_value = units.value(new_value);
+ unit_value = units.parse_value(new_value);
String format;
if (scale >= 100)
format = "%6.2f";
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosConfigTD implements ActionListener {
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosConfigTDUI
extends AltosUIDialog
import javax.swing.*;
import javax.swing.event.*;
import java.text.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosConfigUI
extends AltosUIDialog
}
String get_main_deploy_label() {
- return String.format("Main Deploy Altitude(%s):", AltosConvert.height.show_units());
+ return String.format("Main Deploy Altitude(%s):", AltosConvert.height.parse_units());
}
String[] main_deploy_values() {
}
String get_tracker_motion_label() {
- return String.format("Logging Trigger Motion (%s):", AltosConvert.height.show_units());
+ return String.format("Logging Trigger Motion (%s):", AltosConvert.height.parse_units());
}
void set_tracker_tool_tip() {
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosConfigureUI
extends AltosUIConfigure
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosDescent extends AltosUIFlightTab {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosFlightStatus extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
import java.text.*;
import java.util.prefs.*;
import java.util.concurrent.LinkedBlockingQueue;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosFlightStatusTableModel extends AbstractTableModel {
private String[] columnNames = {
package altosui;
import java.awt.event.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosFlightStatusUpdate implements ActionListener {
import javax.swing.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosFlightUI extends AltosUIFrame implements AltosFlightDisplay {
AltosVoice voice;
AltosDescent descent;
AltosLanded landed;
AltosCompanionInfo companion;
- AltosUIMapNew sitemap;
+ AltosUIMap sitemap;
boolean has_map;
boolean has_companion;
boolean has_state;
has_companion = false;
has_state = false;
- sitemap = new AltosUIMapNew();
+ sitemap = new AltosUIMap();
displays.add(sitemap);
has_map = false;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
JTabbedPane pane;
AltosGraph graph;
AltosUIEnable enable;
- AltosUIMapNew map;
+ AltosUIMap map;
AltosState state;
AltosGraphDataSet graphDataSet;
AltosFlightStats stats;
for (AltosState state : states) {
if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) {
if (map == null)
- map = new AltosUIMapNew();
+ map = new AltosUIMap();
map.show(state, null);
has_gps = true;
}
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
- setVisible(false);
- dispose();
AltosUIPreferences.unregister_font_listener(AltosGraphUI.this);
AltosPreferences.unregister_units_listener(AltosGraphUI.this);
}
import java.io.*;
import java.util.concurrent.*;
import java.util.Arrays;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosIdleMonitorUI extends AltosUIFrame implements AltosFlightDisplay, AltosIdleMonitorListener, DocumentListener {
AltosDevice device;
AltosFlightStatus flightStatus;
AltosIgnitor ignitor;
AltosIdleMonitor thread;
- AltosUIMapNew sitemap;
+ AltosUIMap sitemap;
int serial;
boolean remote;
boolean has_ignitor;
ignitor = new AltosIgnitor();
- sitemap = new AltosUIMapNew();
+ sitemap = new AltosUIMap();
/* Make the tabbed pane use the rest of the window space */
bag.add(pane, constraints(0, 4, GridBagConstraints.BOTH));
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosIgniteUI
extends AltosUIDialog
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosIgnitor extends AltosUIFlightTab {
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosLanded extends AltosUIFlightTab implements ActionListener {
import java.io.*;
import java.util.concurrent.*;
import java.awt.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosLaunch {
AltosDevice device;
throw new TimeoutException();
if (get_string(line, "Rssi: ", status_name)) {
try {
- rssi = Altos.fromdec(status_name.get());
+ rssi = (int) Altos.fromdec(status_name.get());
} catch (NumberFormatException ne) {
}
break;
device = in_device;
serial = new AltosSerial(device);
}
-}
\ No newline at end of file
+}
import java.io.*;
import java.text.*;
import java.util.concurrent.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
class FireButton extends JButton {
protected void processMouseEvent(MouseEvent e) {
package altosui;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosPad extends AltosUIFlightTab {
class ReceiverBattery extends AltosUIVoltageIndicator {
- public double voltage(AltosState state) { return AltosLib.MISSING; }
+ double last_voltage = AltosLib.MISSING;
+
+ public double voltage(AltosState state) {
+ return last_voltage;
+ }
public double good() { return AltosLib.ao_battery_good; }
public double value(AltosState state, AltosListenerState listener_state, int i) {
if (listener_state == null)
- return AltosLib.MISSING;
- return listener_state.battery;
+ last_voltage = AltosLib.MISSING;
+ else
+ last_voltage = listener_state.battery;
+ return last_voltage;
}
public ReceiverBattery (AltosUIFlightTab container, int y) {
}
}
- class PadAlt extends AltosUIIndicator {
+ class PadAlt extends AltosUIUnitsIndicator {
- double last_alt = AltosLib.MISSING - 1;
+ public double value(AltosState state, int i) {
+ if (report_pad(state))
+ return state.pad_alt;
+ else
+ return state.gps.alt;
+ }
public void show (AltosState state, AltosListenerState listener_state) {
- double alt = AltosLib.MISSING;
- String label = null;
+ String label = "Altitude";
- if (state != null) {
- if (report_pad(state)) {
- alt = state.pad_alt;
- label = "Pad Altitude";
- } else {
- alt = state.gps.alt;
- label = "Altitude";
- }
- }
- if (alt != last_alt) {
- if (alt != AltosLib.MISSING) {
- show(AltosConvert.height.show(5, alt));
- set_label(label);
- } else
- hide();
- last_alt = alt;
- }
- }
-
- public void reset() {
- super.reset();
- last_alt = AltosLib.MISSING - 1;
+ if (state != null && report_pad(state))
+ label = "Pad Altitude";
+ set_label(label);
+ super.show(state, listener_state);
}
public PadAlt (AltosUIFlightTab container, int y) {
- super (container, y, "Pad Altitude", 1, false, 2);
+ super (container, y, AltosConvert.height, "Pad Altitude", 1, false, 2);
}
}
public String getName() { return "Pad"; }
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class AltosUI extends AltosUIFrame {
public AltosVoice voice = new AltosVoice();
}
void LoadMaps() {
- new AltosUIMapPreloadNew(AltosUI.this);
+ new AltosUIMapPreload(AltosUI.this);
}
void LaunchController() {
if (states == null)
return false;
try {
+ System.out.printf("%s:\n", file.toString());
AltosFlightStats stats = new AltosFlightStats(states);
- if (stats.serial > 0)
+ if (stats.serial != AltosLib.MISSING)
System.out.printf("Serial: %5d\n", stats.serial);
- if (stats.flight > 0)
+ if (stats.flight != AltosLib.MISSING)
System.out.printf("Flight: %5d\n", stats.flight);
- if (stats.year > 0)
+ if (stats.year != AltosLib.MISSING)
System.out.printf("Date: %04d-%02d-%02d\n",
stats.year, stats.month, stats.day);
- if (stats.hour > 0)
+ if (stats.hour != AltosLib.MISSING)
System.out.printf("Time: %02d:%02d:%02d UTC\n",
stats.hour, stats.minute, stats.second);
- System.out.printf("Max height: %6.0f m %6.0f ft\n",
- stats.max_height,
- AltosConvert.meters_to_feet(stats.max_height));
- System.out.printf("Max speed: %6.0f m/s %6.0f ft/s %6.4f Mach\n",
- stats.max_speed,
- AltosConvert.meters_to_feet(stats.max_speed),
- AltosConvert.meters_to_mach(stats.max_speed));
+ if (stats.max_height != AltosLib.MISSING)
+ System.out.printf("Max height: %6.0f m %6.0f ft\n",
+ stats.max_height,
+ AltosConvert.meters_to_feet(stats.max_height));
+ if (stats.max_speed != AltosLib.MISSING)
+ System.out.printf("Max speed: %6.0f m/s %6.0f ft/s %6.4f Mach\n",
+ stats.max_speed,
+ AltosConvert.meters_to_feet(stats.max_speed),
+ AltosConvert.meters_to_mach(stats.max_speed));
if (stats.max_acceleration != AltosLib.MISSING) {
System.out.printf("Max accel: %6.0f m/s² %6.0f ft/s² %6.2f g\n",
stats.max_acceleration,
AltosConvert.meters_to_feet(stats.max_acceleration),
AltosConvert.meters_to_g(stats.max_acceleration));
}
- System.out.printf("Drogue rate: %6.0f m/s %6.0f ft/s\n",
- stats.state_speed[Altos.ao_flight_drogue],
- AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]));
- System.out.printf("Main rate: %6.0f m/s %6.0f ft/s\n",
- stats.state_speed[Altos.ao_flight_main],
- AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]));
- System.out.printf("Flight time: %6.0f s\n",
- stats.state_end[Altos.ao_flight_main] -
- stats.state_start[Altos.ao_flight_boost]);
+ if (stats.state_speed[Altos.ao_flight_drogue] != AltosLib.MISSING)
+ System.out.printf("Drogue rate: %6.0f m/s %6.0f ft/s\n",
+ stats.state_speed[Altos.ao_flight_drogue],
+ AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_drogue]));
+ if (stats.state_speed[Altos.ao_flight_main] != AltosLib.MISSING)
+ System.out.printf("Main rate: %6.0f m/s %6.0f ft/s\n",
+ stats.state_speed[Altos.ao_flight_main],
+ AltosConvert.meters_to_feet(stats.state_speed[Altos.ao_flight_main]));
+ if (stats.state_end[Altos.ao_flight_main] != AltosLib.MISSING &&
+ stats.state_start[Altos.ao_flight_boost] != AltosLib.MISSING)
+ System.out.printf("Flight time: %6.0f s\n",
+ stats.state_end[Altos.ao_flight_main] -
+ stats.state_start[Altos.ao_flight_boost]);
+ System.out.printf("\n");
return true;
} catch (InterruptedException ie) {
} catch (IOException ie) {
try {
AltosStateIterable eef = record_iterable(file);
- System.out.printf ("process cat\n");
for (AltosState state : eef) {
System.out.printf ("tick %d state %d height %g\n",
state.tick, state.state(), state.height());
File file = new File(args[i]);
switch (process) {
case process_none:
- case process_graph:
if (altosui == null)
altosui = new AltosUI();
+ case process_graph:
if (!process_graph(file))
++errors;
break;
case process_replay:
- if (altosui == null)
- altosui = new AltosUI();
if (!process_replay(file))
++errors;
break;
ALTOSUILIB_CLASS=\
altosuilib_$(ALTOSUILIB_VERSION).jar
+if MULTI_ARCH
+LIBALTOS_LINUX=libaltos32.so libaltos64.so
+else
+LIBALTOS_LINUX=libaltos.so
+endif
+
LIBALTOS= \
- libaltos32.so \
- libaltos64.so \
+ $(LIBALTOS_LINUX) \
libaltos.dylib \
- altos.dll
+ altos.dll \
+ altos64.dll
desktopdir = $(datadir)/applications
desktop_file = altusmetrum-altosui.desktop
FIRMWARE_TELEMINI=$(FIRMWARE_TELEMINI_1_0)
FIRMWARE_TBT_1_0=$(top_srcdir)/src/telebt-v1.0/telebt-v1.0-$(VERSION).ihx
-FIRMWARE_TBT=$(FIRMWARE_TBT_1_0)
+FIRMWARE_TBT_3_0=$(top_srcdir)/src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx
+FIRMWARE_TBT=$(FIRMWARE_TBT_1_0) $(FIRMWARE_TBT_3_0)
FIRMWARE_TMEGA_1_0=$(top_srcdir)/src/telemega-v1.0/telemega-v1.0-$(VERSION).ihx
-FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0)
+FIRMWARE_TMEGA_2_0=$(top_srcdir)/src/telemega-v2.0/telemega-v2.0-$(VERSION).ihx
+FIRMWARE_TMEGA=$(FIRMWARE_TMEGA_1_0) $(FIRMWARE_TMEGA_2_0)
FIRMWARE_EMINI_1_0=$(top_srcdir)/src/easymini-v1.0/easymini-v1.0-$(VERSION).ihx
FIRMWARE_EMINI=$(FIRMWARE_EMINI_1_0)
FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS)
-LINUX_LIBS=libaltos32.so libaltos64.so
+LINUX_LIBS=$(LIBALTOS_LINUX)
LINUX_FILES=$(FAT_FILES) $(LINUX_LIBS) $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
LINUX_EXTRA=altosui-fat
clean-local:
-rm -rf classes $(JAR) $(FATJAR) \
- $(LINUX_DIST) $(LINUX_SH) $(MACOSX_DIST) windows $(WINDOWS_DIST) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) \
+ Altos-Linux-*.tar.bz2 Altos-Linux-*.sh Altos-Mac-*.dmg Altos-Windows-*.exe \
+ windows altoslib_*.jar altosuilib_*.jar $(FREETTS_CLASS) \
$(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt altos-windows.log altos-windows.nsi \
altosui altosui-test altosui-jdb macosx linux *.desktop
echo 'exec jdb -classpath "classes:./*:../libaltos:$(FREETTS)/freetts.jar:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" altosui/AltosUI "$$@"' >> $@
chmod +x $@
+libaltos.so: build-libaltos
+ -rm -f "$@"
+ $(LN_S) ../libaltos/.libs/"$@" .
+
libaltos32.so: build-libaltos
-rm -f "$@"
$(LN_S) ../libaltos/.libs/"$@" .
../libaltos/.libs/libaltos32.so: build-libaltos
+../libaltos/.libs/libaltos.so: build-libaltos
+
../libaltos/altos.dll: build-altos-dll
../libaltos/altos64.dll: build-altos64-dll
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosBTDevice extends altos_bt_device implements AltosDevice {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.util.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosBTDeviceIterator implements Iterator<AltosBTDevice> {
AltosBTDevice current;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosBTKnown implements Iterable<AltosBTDevice> {
LinkedList<AltosBTDevice> devices = new LinkedList<AltosBTDevice>();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
import javax.swing.plaf.basic.*;
import java.util.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosBTManage extends AltosUIDialog implements ActionListener, Iterable<AltosBTDevice> {
LinkedBlockingQueue<AltosBTDevice> found_devices;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosCSVUI
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.text.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
class AltosEditFreqUI extends AltosUIDialog implements ActionListener {
Frame frame;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosDataChooser extends JFileChooser {
JFrame frame;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import libaltosJNI.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import javax.swing.*;
import java.awt.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import javax.swing.*;
import java.awt.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.text.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosDisplayThread extends Thread {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosEepromDelete implements Runnable {
AltosEepromList flights;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosEepromManage implements ActionListener {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosEepromMonitorUI extends AltosUIDialog implements AltosEepromMonitor {
JFrame owner;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
class AltosEepromItem implements ActionListener {
AltosEepromLog log;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosFlashUI
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import javax.swing.table.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosFlightStatsTable extends JComponent implements AltosFontListener {
GridBagLayout layout;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosGraphDataPoint implements AltosUIDataPoint {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.lang.*;
import java.io.*;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
class AltosGraphIterator implements Iterator<AltosUIDataPoint> {
AltosGraphDataSet dataSet;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosInfoTable extends JTable implements AltosFlightDisplay, HierarchyListener {
private AltosFlightInfoTableModel model;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import javax.swing.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import javax.swing.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
public interface AltosPositionListener {
public void position_changed(int position);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosRomconfigUI
extends AltosUIDialog
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;
import java.util.concurrent.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
class AltosScanResult {
String callsign;
* Deal with TeleDongle on a serial port
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import libaltosJNI.*;
/*
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
public class AltosSerialInUseException extends Exception {
public AltosDevice device;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
public final static int axis_default = axis_include_zero;
public void set_units() {
- String u = units.show_units();
+ String u = units.parse_units();
if (u != null)
setLabel(String.format("%s (%s)", label, u));
else
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
class DelegatingRenderer implements ListCellRenderer<Object> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
public class AltosUIDataMissing extends Exception {
public int id;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
public interface AltosUIDataPoint {
public abstract double x() throws AltosUIDataMissing;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
public interface AltosUIDataSet {
public abstract String name();
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public abstract class AltosUIFlightTab extends JComponent implements AltosFlightDisplay, HierarchyListener {
public GridBagLayout layout;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class AltosUIFrameListener extends WindowAdapter {
+ @Override
public void windowClosing (WindowEvent e) {
- AltosUIPreferences.unregister_ui_listener((AltosUIFrame) e.getWindow());
+ AltosUIFrame frame = (AltosUIFrame) e.getWindow();
+ AltosUIPreferences.unregister_ui_listener(frame);
+ AltosUIFrame.frame_closed();
+ frame.setVisible(false);
+ frame.dispose();
}
}
return constraints(x, width, GridBagConstraints.NONE);
}
+ static int open_frames;
+
+ public static void frame_opened() {
+ ++open_frames;
+ }
+
+ public static void frame_closed() {
+ --open_frames;
+ if (open_frames == 0)
+ System.exit(0);
+ }
+
void init() {
AltosUIPreferences.register_ui_listener(this);
AltosUIPreferences.register_position_listener(this);
position = AltosUIPreferences.position();
+ frame_opened();
addWindowListener(new AltosUIFrameListener());
/* Try to make menus live in the menu bar like regular Mac apps */
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosUIFreqList extends JComboBox<AltosFrequency> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_10;
+package org.altusmetrum.altoslib_11;
import javax.swing.*;
import javax.imageio.ImageIO;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public abstract class AltosUIIndicator implements AltosFontListener, AltosUnitsListener {
JLabel label;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosUILib extends AltosLib {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
public interface AltosUIListener {
public void ui_changed(String look_and_feel);
--- /dev/null
+/*
+ * Copyright © 2010 Anthony Towns <aj@erisian.com.au>
+ *
+ * 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 org.altusmetrum.altosuilib_11;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+import javax.swing.*;
+import java.io.*;
+import java.lang.Math;
+import java.awt.geom.*;
+import java.util.*;
+import java.util.concurrent.*;
+import javax.imageio.*;
+import org.altusmetrum.altoslib_11.*;
+
+public class AltosUIMap extends JComponent implements AltosFlightDisplay, AltosMapInterface {
+
+ AltosMap map;
+ Graphics2D g;
+ Font tile_font;
+ Font line_font;
+
+ static Point2D.Double point2d(AltosPointDouble pt) {
+ return new Point2D.Double(pt.x, pt.y);
+ }
+
+ static final AltosPointDouble point_double(Point pt) {
+ return new AltosPointDouble(pt.x, pt.y);
+ }
+
+ class MapMark extends AltosMapMark {
+ public void paint(AltosMapTransform t) {
+ AltosPointDouble pt = t.screen(lat_lon);
+
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+
+ if (0 <= state && state < AltosUIMap.stateColors.length)
+ g.setColor(AltosUIMap.stateColors[state]);
+ else
+ g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]);
+
+ g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
+ g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
+ g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
+ }
+
+ MapMark(double lat, double lon, int state) {
+ super(lat, lon, state);
+ }
+ }
+
+ class MapView extends JComponent implements MouseMotionListener, MouseListener, ComponentListener, MouseWheelListener {
+
+ private VolatileImage create_back_buffer() {
+ return getGraphicsConfiguration().createCompatibleVolatileImage(getWidth(), getHeight());
+ }
+
+ private void do_paint(Graphics my_g) {
+ g = (Graphics2D) my_g;
+
+ map.paint();
+ }
+
+ public void paint(Graphics my_g) {
+ VolatileImage back_buffer = create_back_buffer();
+
+ Graphics2D top_g = (Graphics2D) my_g;
+
+ do {
+ GraphicsConfiguration gc = getGraphicsConfiguration();
+ int code = back_buffer.validate(gc);
+ if (code == VolatileImage.IMAGE_INCOMPATIBLE)
+ back_buffer = create_back_buffer();
+
+ Graphics g_back = back_buffer.getGraphics();
+ g_back.setClip(top_g.getClip());
+ do_paint(g_back);
+ g_back.dispose();
+
+ top_g.drawImage(back_buffer, 0, 0, this);
+ } while (back_buffer.contentsLost());
+ back_buffer.flush();
+ }
+
+ public void repaint(AltosRectangle damage) {
+ repaint(damage.x, damage.y, damage.width, damage.height);
+ }
+
+ private boolean is_drag_event(MouseEvent e) {
+ return e.getModifiers() == InputEvent.BUTTON1_MASK;
+ }
+
+ /* MouseMotionListener methods */
+
+ public void mouseDragged(MouseEvent e) {
+ map.touch_continue(e.getPoint().x, e.getPoint().y, is_drag_event(e));
+ }
+
+ public void mouseMoved(MouseEvent e) {
+ }
+
+ /* MouseListener methods */
+ public void mouseClicked(MouseEvent e) {
+ }
+
+ public void mouseEntered(MouseEvent e) {
+ }
+
+ public void mouseExited(MouseEvent e) {
+ }
+
+ public void mousePressed(MouseEvent e) {
+ map.touch_start(e.getPoint().x, e.getPoint().y, is_drag_event(e));
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ }
+
+ /* MouseWheelListener methods */
+
+ public void mouseWheelMoved(MouseWheelEvent e) {
+ int zoom_change = e.getWheelRotation();
+
+ map.set_zoom_centre(map.get_zoom() - zoom_change, new AltosPointInt(e.getPoint().x, e.getPoint().y));
+ }
+
+ /* ComponentListener methods */
+
+ public void componentHidden(ComponentEvent e) {
+ }
+
+ public void componentMoved(ComponentEvent e) {
+ }
+
+ public void componentResized(ComponentEvent e) {
+ map.set_transform();
+ }
+
+ public void componentShown(ComponentEvent e) {
+ map.set_transform();
+ }
+
+ MapView() {
+ addComponentListener(this);
+ addMouseMotionListener(this);
+ addMouseListener(this);
+ addMouseWheelListener(this);
+ }
+ }
+
+ class MapLine extends AltosMapLine {
+
+ public void paint(AltosMapTransform t) {
+
+ if (start == null || end == null)
+ return;
+
+ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+ Line2D.Double line = new Line2D.Double(point2d(t.screen(start)),
+ point2d(t.screen(end)));
+
+ g.setColor(Color.WHITE);
+ g.setStroke(new BasicStroke(stroke_width+4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+ g.draw(line);
+
+ g.setColor(Color.BLUE);
+ g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+ g.draw(line);
+
+ String message = line_dist();
+ Rectangle2D bounds;
+ bounds = line_font.getStringBounds(message, g.getFontRenderContext());
+
+ float x = (float) line.x1;
+ float y = (float) line.y1 + (float) bounds.getHeight() / 2.0f;
+
+ if (line.x1 < line.x2) {
+ x -= (float) bounds.getWidth() + 2.0f;
+ } else {
+ x += 2.0f;
+ }
+
+ g.setFont(line_font);
+ g.setColor(Color.WHITE);
+ for (int dy = -2; dy <= 2; dy += 2)
+ for (int dx = -2; dx <= 2; dx += 2)
+ g.drawString(message, x + dx, y + dy);
+ g.setColor(Color.BLUE);
+ g.drawString(message, x, y);
+ }
+
+ public MapLine() {
+ }
+ }
+
+ class MapPath extends AltosMapPath {
+ public void paint(AltosMapTransform t) {
+ Point2D.Double prev = null;
+
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+
+ for (AltosMapPathPoint point : points) {
+ Point2D.Double cur = point2d(t.screen(point.lat_lon));
+ if (prev != null) {
+ Line2D.Double line = new Line2D.Double (prev, cur);
+ Rectangle bounds = line.getBounds();
+
+ if (g.hitClip(bounds.x, bounds.y, bounds.width, bounds.height)) {
+ if (0 <= point.state && point.state < AltosUIMap.stateColors.length)
+ g.setColor(AltosUIMap.stateColors[point.state]);
+ else
+ g.setColor(AltosUIMap.stateColors[AltosLib.ao_flight_invalid]);
+
+ g.draw(line);
+ }
+ }
+ prev = cur;
+ }
+ }
+ }
+
+ class MapTile extends AltosMapTile {
+ public MapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+ super(cache, upper_left, center, zoom, maptype, px_size, scale);
+ }
+
+ public void paint(AltosMapTransform t) {
+
+ AltosPointDouble point_double = t.screen(upper_left);
+ Point point = new Point((int) (point_double.x + 0.5),
+ (int) (point_double.y + 0.5));
+
+ if (!g.hitClip(point.x, point.y, px_size, px_size))
+ return;
+
+ AltosImage altos_image = get_image();
+ AltosUIImage ui_image = (AltosUIImage) altos_image;
+ Image image = null;
+
+ if (ui_image != null)
+ image = ui_image.image;
+
+ if (image != null) {
+ g.drawImage(image, point.x, point.y, null);
+ } else {
+ g.setColor(Color.GRAY);
+ g.fillRect(point.x, point.y, px_size, px_size);
+
+ if (t.has_location()) {
+ String message = null;
+ switch (status) {
+ case AltosMapTile.fetching:
+ message = "Fetching...";
+ break;
+ case AltosMapTile.bad_request:
+ message = "Internal error";
+ break;
+ case AltosMapTile.failed:
+ message = "Network error, check connection";
+ break;
+ case AltosMapTile.forbidden:
+ message = "Too many requests, try later";
+ break;
+ }
+ if (message != null && tile_font != null) {
+ g.setFont(tile_font);
+ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+ Rectangle2D bounds = tile_font.getStringBounds(message, g.getFontRenderContext());
+
+ float x = px_size / 2.0f;
+ float y = px_size / 2.0f;
+ x = x - (float) bounds.getWidth() / 2.0f;
+ y = y + (float) bounds.getHeight() / 2.0f;
+ g.setColor(Color.BLACK);
+ g.drawString(message, (float) point_double.x + x, (float) point_double.y + y);
+ }
+ }
+ }
+ }
+ }
+
+ public static final Color stateColors[] = {
+ Color.WHITE, // startup
+ Color.WHITE, // idle
+ Color.WHITE, // pad
+ Color.RED, // boost
+ Color.PINK, // fast
+ Color.YELLOW, // coast
+ Color.CYAN, // drogue
+ Color.BLUE, // main
+ Color.BLACK, // landed
+ Color.BLACK, // invalid
+ Color.CYAN, // stateless
+ };
+
+ /* AltosMapInterface functions */
+
+ public AltosMapPath new_path() {
+ return new MapPath();
+ }
+
+ public AltosMapLine new_line() {
+ return new MapLine();
+ }
+
+ public AltosImage load_image(File file) throws Exception {
+ return new AltosUIImage(ImageIO.read(file));
+ }
+
+ public AltosMapMark new_mark(double lat, double lon, int state) {
+ return new MapMark(lat, lon, state);
+ }
+
+ public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+ return new MapTile(cache, upper_left, center, zoom, maptype, px_size, scale);
+ }
+
+ public int width() {
+ return view.getWidth();
+ }
+
+ public int height() {
+ return view.getHeight();
+ }
+
+ public void repaint() {
+ view.repaint();
+ }
+
+ public void repaint(AltosRectangle damage) {
+ view.repaint(damage);
+ }
+
+ public void set_zoom_label(String label) {
+ zoom_label.setText(label);
+ }
+
+ public void select_object(AltosLatLon latlon) {
+ debug("select at %f,%f\n", latlon.lat, latlon.lon);
+ }
+
+ public void debug(String format, Object ... arguments) {
+ if (AltosUIPreferences.serial_debug())
+ System.out.printf(format, arguments);
+ }
+
+
+ /* AltosFlightDisplay interface */
+
+ public void set_font() {
+ tile_font = AltosUILib.value_font;
+ line_font = AltosUILib.status_font;
+ }
+
+ public void font_size_changed(int font_size) {
+ set_font();
+ repaint();
+ }
+
+ public void units_changed(boolean imperial_units) {
+ repaint();
+ }
+
+ JLabel zoom_label;
+
+ public void set_maptype(int type) {
+ map.set_maptype(type);
+ maptype_combo.setSelectedIndex(type);
+ }
+
+ /* AltosUIMapPreload functions */
+
+ public void set_zoom(int zoom) {
+ map.set_zoom(zoom);
+ }
+
+ public void add_mark(double lat, double lon, int status) {
+ map.add_mark(lat, lon, status);
+ }
+
+ public void clear_marks() {
+ map.clear_marks();
+ }
+
+ /* AltosFlightDisplay interface */
+ public void reset() {
+ // nothing
+ }
+
+ public void show(AltosState state, AltosListenerState listener_state) {
+ map.show(state, listener_state);
+ }
+
+ public String getName() {
+ return "Map";
+ }
+
+ /* AltosGraphUI interface */
+ public void centre(AltosState state) {
+ map.centre(state);
+ }
+
+ /* internal layout bits */
+ private GridBagLayout layout = new GridBagLayout();
+
+ JComboBox<String> maptype_combo;
+
+ MapView view;
+
+ public AltosUIMap() {
+
+ set_font();
+
+ view = new MapView();
+
+ view.setPreferredSize(new Dimension(500,500));
+ view.setVisible(true);
+ view.setEnabled(true);
+
+ GridBagLayout my_layout = new GridBagLayout();
+
+ setLayout(my_layout);
+
+ GridBagConstraints c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.BOTH;
+ c.gridx = 0;
+ c.gridy = 0;
+ c.gridwidth = 1;
+ c.gridheight = 10;
+ c.weightx = 1;
+ c.weighty = 1;
+ add(view, c);
+
+ int y = 0;
+
+ zoom_label = new JLabel("", JLabel.CENTER);
+
+ c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridx = 1;
+ c.gridy = y++;
+ c.weightx = 0;
+ c.weighty = 0;
+ add(zoom_label, c);
+
+ JButton zoom_reset = new JButton("0");
+ zoom_reset.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ map.set_zoom(map.default_zoom);
+ }
+ });
+
+ c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridx = 1;
+ c.gridy = y++;
+ c.weightx = 0;
+ c.weighty = 0;
+ add(zoom_reset, c);
+
+ JButton zoom_in = new JButton("+");
+ zoom_in.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ map.set_zoom(map.get_zoom() + 1);
+ }
+ });
+
+ c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridx = 1;
+ c.gridy = y++;
+ c.weightx = 0;
+ c.weighty = 0;
+ add(zoom_in, c);
+
+ JButton zoom_out = new JButton("-");
+ zoom_out.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ map.set_zoom(map.get_zoom() - 1);
+ }
+ });
+ c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridx = 1;
+ c.gridy = y++;
+ c.weightx = 0;
+ c.weighty = 0;
+ add(zoom_out, c);
+
+ maptype_combo = new JComboBox<String>(map.maptype_labels);
+
+ maptype_combo.setEditable(false);
+ maptype_combo.setMaximumRowCount(maptype_combo.getItemCount());
+ maptype_combo.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ map.set_maptype(maptype_combo.getSelectedIndex());
+ }
+ });
+
+ c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.CENTER;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridx = 1;
+ c.gridy = y++;
+ c.weightx = 0;
+ c.weighty = 0;
+ add(maptype_combo, c);
+
+ map = new AltosMap(this);
+ }
+}
+++ /dev/null
-/*
- * Copyright © 2010 Anthony Towns <aj@erisian.com.au>
- *
- * 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 org.altusmetrum.altosuilib_10;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-import javax.swing.*;
-import java.io.*;
-import java.lang.Math;
-import java.awt.geom.*;
-import java.util.*;
-import java.util.concurrent.*;
-import javax.imageio.*;
-import org.altusmetrum.altoslib_10.*;
-
-public class AltosUIMapNew extends JComponent implements AltosFlightDisplay, AltosMapInterface {
-
- AltosMap map;
- Graphics2D g;
- Font tile_font;
- Font line_font;
-
- static Point2D.Double point2d(AltosPointDouble pt) {
- return new Point2D.Double(pt.x, pt.y);
- }
-
- static final AltosPointDouble point_double(Point pt) {
- return new AltosPointDouble(pt.x, pt.y);
- }
-
- class MapMark extends AltosMapMark {
- public void paint(AltosMapTransform t) {
- AltosPointDouble pt = t.screen(lat_lon);
-
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
-
- if (0 <= state && state < AltosUIMapNew.stateColors.length)
- g.setColor(AltosUIMapNew.stateColors[state]);
- else
- g.setColor(AltosUIMapNew.stateColors[AltosLib.ao_flight_invalid]);
-
- g.drawOval((int)pt.x-5, (int)pt.y-5, 10, 10);
- g.drawOval((int)pt.x-20, (int)pt.y-20, 40, 40);
- g.drawOval((int)pt.x-35, (int)pt.y-35, 70, 70);
- }
-
- MapMark(double lat, double lon, int state) {
- super(lat, lon, state);
- }
- }
-
- class MapView extends JComponent implements MouseMotionListener, MouseListener, ComponentListener, MouseWheelListener {
-
- private VolatileImage create_back_buffer() {
- return getGraphicsConfiguration().createCompatibleVolatileImage(getWidth(), getHeight());
- }
-
- private void do_paint(Graphics my_g) {
- g = (Graphics2D) my_g;
-
- map.paint();
- }
-
- public void paint(Graphics my_g) {
- VolatileImage back_buffer = create_back_buffer();
-
- Graphics2D top_g = (Graphics2D) my_g;
-
- do {
- GraphicsConfiguration gc = getGraphicsConfiguration();
- int code = back_buffer.validate(gc);
- if (code == VolatileImage.IMAGE_INCOMPATIBLE)
- back_buffer = create_back_buffer();
-
- Graphics g_back = back_buffer.getGraphics();
- g_back.setClip(top_g.getClip());
- do_paint(g_back);
- g_back.dispose();
-
- top_g.drawImage(back_buffer, 0, 0, this);
- } while (back_buffer.contentsLost());
- back_buffer.flush();
- }
-
- public void repaint(AltosRectangle damage) {
- repaint(damage.x, damage.y, damage.width, damage.height);
- }
-
- private boolean is_drag_event(MouseEvent e) {
- return e.getModifiers() == InputEvent.BUTTON1_MASK;
- }
-
- /* MouseMotionListener methods */
-
- public void mouseDragged(MouseEvent e) {
- map.touch_continue(e.getPoint().x, e.getPoint().y, is_drag_event(e));
- }
-
- public void mouseMoved(MouseEvent e) {
- }
-
- /* MouseListener methods */
- public void mouseClicked(MouseEvent e) {
- }
-
- public void mouseEntered(MouseEvent e) {
- }
-
- public void mouseExited(MouseEvent e) {
- }
-
- public void mousePressed(MouseEvent e) {
- map.touch_start(e.getPoint().x, e.getPoint().y, is_drag_event(e));
- }
-
- public void mouseReleased(MouseEvent e) {
- }
-
- /* MouseWheelListener methods */
-
- public void mouseWheelMoved(MouseWheelEvent e) {
- int zoom_change = e.getWheelRotation();
-
- map.set_zoom_centre(map.get_zoom() - zoom_change, new AltosPointInt(e.getPoint().x, e.getPoint().y));
- }
-
- /* ComponentListener methods */
-
- public void componentHidden(ComponentEvent e) {
- }
-
- public void componentMoved(ComponentEvent e) {
- }
-
- public void componentResized(ComponentEvent e) {
- map.set_transform();
- }
-
- public void componentShown(ComponentEvent e) {
- map.set_transform();
- }
-
- MapView() {
- addComponentListener(this);
- addMouseMotionListener(this);
- addMouseListener(this);
- addMouseWheelListener(this);
- }
- }
-
- class MapLine extends AltosMapLine {
-
- public void paint(AltosMapTransform t) {
-
- if (start == null || end == null)
- return;
-
- g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-
- Line2D.Double line = new Line2D.Double(point2d(t.screen(start)),
- point2d(t.screen(end)));
-
- g.setColor(Color.WHITE);
- g.setStroke(new BasicStroke(stroke_width+4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
- g.draw(line);
-
- g.setColor(Color.BLUE);
- g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
- g.draw(line);
-
- String message = line_dist();
- Rectangle2D bounds;
- bounds = line_font.getStringBounds(message, g.getFontRenderContext());
-
- float x = (float) line.x1;
- float y = (float) line.y1 + (float) bounds.getHeight() / 2.0f;
-
- if (line.x1 < line.x2) {
- x -= (float) bounds.getWidth() + 2.0f;
- } else {
- x += 2.0f;
- }
-
- g.setFont(line_font);
- g.setColor(Color.WHITE);
- for (int dy = -2; dy <= 2; dy += 2)
- for (int dx = -2; dx <= 2; dx += 2)
- g.drawString(message, x + dx, y + dy);
- g.setColor(Color.BLUE);
- g.drawString(message, x, y);
- }
-
- public MapLine() {
- }
- }
-
- class MapPath extends AltosMapPath {
- public void paint(AltosMapTransform t) {
- Point2D.Double prev = null;
-
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- g.setStroke(new BasicStroke(stroke_width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
-
- for (AltosMapPathPoint point : points) {
- Point2D.Double cur = point2d(t.screen(point.lat_lon));
- if (prev != null) {
- Line2D.Double line = new Line2D.Double (prev, cur);
- Rectangle bounds = line.getBounds();
-
- if (g.hitClip(bounds.x, bounds.y, bounds.width, bounds.height)) {
- if (0 <= point.state && point.state < AltosUIMapNew.stateColors.length)
- g.setColor(AltosUIMapNew.stateColors[point.state]);
- else
- g.setColor(AltosUIMapNew.stateColors[AltosLib.ao_flight_invalid]);
-
- g.draw(line);
- }
- }
- prev = cur;
- }
- }
- }
-
- class MapTile extends AltosMapTile {
- public MapTile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
- super(cache, upper_left, center, zoom, maptype, px_size);
- }
-
- public void paint(AltosMapTransform t) {
-
- AltosPointDouble point_double = t.screen(upper_left);
- Point point = new Point((int) (point_double.x + 0.5),
- (int) (point_double.y + 0.5));
-
- if (!g.hitClip(point.x, point.y, px_size, px_size))
- return;
-
- AltosImage altos_image = get_image();
- AltosUIImage ui_image = (AltosUIImage) altos_image;
- Image image = null;
-
- if (ui_image != null)
- image = ui_image.image;
-
- if (image != null) {
- g.drawImage(image, point.x, point.y, null);
- } else {
- g.setColor(Color.GRAY);
- g.fillRect(point.x, point.y, px_size, px_size);
-
- if (t.has_location()) {
- String message = null;
- switch (status) {
- case AltosMapTile.fetching:
- message = "Fetching...";
- break;
- case AltosMapTile.bad_request:
- message = "Internal error";
- break;
- case AltosMapTile.failed:
- message = "Network error, check connection";
- break;
- case AltosMapTile.forbidden:
- message = "Too many requests, try later";
- break;
- }
- if (message != null && tile_font != null) {
- g.setFont(tile_font);
- g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
- Rectangle2D bounds = tile_font.getStringBounds(message, g.getFontRenderContext());
-
- float x = px_size / 2.0f;
- float y = px_size / 2.0f;
- x = x - (float) bounds.getWidth() / 2.0f;
- y = y + (float) bounds.getHeight() / 2.0f;
- g.setColor(Color.BLACK);
- g.drawString(message, (float) point_double.x + x, (float) point_double.y + y);
- }
- }
- }
- }
- }
-
- public static final Color stateColors[] = {
- Color.WHITE, // startup
- Color.WHITE, // idle
- Color.WHITE, // pad
- Color.RED, // boost
- Color.PINK, // fast
- Color.YELLOW, // coast
- Color.CYAN, // drogue
- Color.BLUE, // main
- Color.BLACK, // landed
- Color.BLACK, // invalid
- Color.CYAN, // stateless
- };
-
- /* AltosMapInterface functions */
-
- public AltosMapPath new_path() {
- return new MapPath();
- }
-
- public AltosMapLine new_line() {
- return new MapLine();
- }
-
- public AltosImage load_image(File file) throws Exception {
- return new AltosUIImage(ImageIO.read(file));
- }
-
- public AltosMapMark new_mark(double lat, double lon, int state) {
- return new MapMark(lat, lon, state);
- }
-
- public AltosMapTile new_tile(AltosMapCache cache, AltosLatLon upper_left, AltosLatLon center, int zoom, int maptype, int px_size) {
- return new MapTile(cache, upper_left, center, zoom, maptype, px_size);
- }
-
- public int width() {
- return view.getWidth();
- }
-
- public int height() {
- return view.getHeight();
- }
-
- public void repaint() {
- view.repaint();
- }
-
- public void repaint(AltosRectangle damage) {
- view.repaint(damage);
- }
-
- public void set_zoom_label(String label) {
- zoom_label.setText(label);
- }
-
- public void select_object(AltosLatLon latlon) {
- debug("select at %f,%f\n", latlon.lat, latlon.lon);
- }
-
- public void debug(String format, Object ... arguments) {
- System.out.printf(format, arguments);
- }
-
-
- /* AltosFlightDisplay interface */
-
- public void set_font() {
- tile_font = AltosUILib.value_font;
- line_font = AltosUILib.status_font;
- }
-
- public void font_size_changed(int font_size) {
- set_font();
- repaint();
- }
-
- public void units_changed(boolean imperial_units) {
- repaint();
- }
-
- JLabel zoom_label;
-
- public void set_maptype(int type) {
- map.set_maptype(type);
- maptype_combo.setSelectedIndex(type);
- }
-
- /* AltosUIMapPreload functions */
-
- public void set_zoom(int zoom) {
- map.set_zoom(zoom);
- }
-
- public void add_mark(double lat, double lon, int status) {
- map.add_mark(lat, lon, status);
- }
-
- public void clear_marks() {
- map.clear_marks();
- }
-
- /* AltosFlightDisplay interface */
- public void reset() {
- // nothing
- }
-
- public void show(AltosState state, AltosListenerState listener_state) {
- map.show(state, listener_state);
- }
-
- public String getName() {
- return "Map";
- }
-
- /* AltosGraphUI interface */
- public void centre(AltosState state) {
- map.centre(state);
- }
-
- /* internal layout bits */
- private GridBagLayout layout = new GridBagLayout();
-
- JComboBox<String> maptype_combo;
-
- MapView view;
-
- public AltosUIMapNew() {
-
- set_font();
-
- view = new MapView();
-
- view.setPreferredSize(new Dimension(500,500));
- view.setVisible(true);
- view.setEnabled(true);
-
- GridBagLayout my_layout = new GridBagLayout();
-
- setLayout(my_layout);
-
- GridBagConstraints c = new GridBagConstraints();
- c.anchor = GridBagConstraints.CENTER;
- c.fill = GridBagConstraints.BOTH;
- c.gridx = 0;
- c.gridy = 0;
- c.gridwidth = 1;
- c.gridheight = 10;
- c.weightx = 1;
- c.weighty = 1;
- add(view, c);
-
- int y = 0;
-
- zoom_label = new JLabel("", JLabel.CENTER);
-
- c = new GridBagConstraints();
- c.anchor = GridBagConstraints.CENTER;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.gridx = 1;
- c.gridy = y++;
- c.weightx = 0;
- c.weighty = 0;
- add(zoom_label, c);
-
- JButton zoom_reset = new JButton("0");
- zoom_reset.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- map.set_zoom(map.default_zoom);
- }
- });
-
- c = new GridBagConstraints();
- c.anchor = GridBagConstraints.CENTER;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.gridx = 1;
- c.gridy = y++;
- c.weightx = 0;
- c.weighty = 0;
- add(zoom_reset, c);
-
- JButton zoom_in = new JButton("+");
- zoom_in.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- map.set_zoom(map.get_zoom() + 1);
- }
- });
-
- c = new GridBagConstraints();
- c.anchor = GridBagConstraints.CENTER;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.gridx = 1;
- c.gridy = y++;
- c.weightx = 0;
- c.weighty = 0;
- add(zoom_in, c);
-
- JButton zoom_out = new JButton("-");
- zoom_out.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- map.set_zoom(map.get_zoom() - 1);
- }
- });
- c = new GridBagConstraints();
- c.anchor = GridBagConstraints.CENTER;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.gridx = 1;
- c.gridy = y++;
- c.weightx = 0;
- c.weighty = 0;
- add(zoom_out, c);
-
- maptype_combo = new JComboBox<String>(map.maptype_labels);
-
- maptype_combo.setEditable(false);
- maptype_combo.setMaximumRowCount(maptype_combo.getItemCount());
- maptype_combo.addItemListener(new ItemListener() {
- public void itemStateChanged(ItemEvent e) {
- map.set_maptype(maptype_combo.getSelectedIndex());
- }
- });
-
- c = new GridBagConstraints();
- c.anchor = GridBagConstraints.CENTER;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.gridx = 1;
- c.gridy = y++;
- c.weightx = 0;
- c.weighty = 0;
- add(maptype_combo, c);
-
- map = new AltosMap(this);
- }
-}
--- /dev/null
+/*
+ * 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 org.altusmetrum.altosuilib_11;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.lang.Math;
+import java.net.URL;
+import java.net.URLConnection;
+import org.altusmetrum.altoslib_11.*;
+
+class AltosUIMapPos extends Box implements ActionListener {
+ AltosUIMapPreload preload;
+ AltosUIFrame owner;
+ JLabel label;
+ JComboBox hemi;
+ JTextField deg;
+ JLabel deg_label;
+ JTextField min;
+ JLabel min_label;
+
+ /* ActionListener interface */
+ public void actionPerformed(ActionEvent e) {
+ preload.center_map();
+ }
+
+ public void set_value(double new_value) {
+ double d, m;
+ int h;
+
+ h = 0;
+ if (new_value < 0) {
+ h = 1;
+ new_value = -new_value;
+ }
+ d = Math.floor(new_value);
+ deg.setText(String.format("%3.0f", d));
+ m = (new_value - d) * 60.0;
+ min.setText(String.format("%7.4f", m));
+ hemi.setSelectedIndex(h);
+ }
+
+ public double get_value() throws ParseException {
+ int h = hemi.getSelectedIndex();
+ String d_t = deg.getText();
+ String m_t = min.getText();
+ double d, m, v;
+ try {
+ d = AltosParse.parse_double_locale(d_t);
+ } catch (ParseException pe) {
+ JOptionPane.showMessageDialog(owner,
+ String.format("Invalid degrees \"%s\"",
+ d_t),
+ "Invalid number",
+ JOptionPane.ERROR_MESSAGE);
+ throw pe;
+ }
+ try {
+ if (m_t.equals(""))
+ m = 0;
+ else
+ m = AltosParse.parse_double_locale(m_t);
+ } catch (ParseException pe) {
+ JOptionPane.showMessageDialog(owner,
+ String.format("Invalid minutes \"%s\"",
+ m_t),
+ "Invalid number",
+ JOptionPane.ERROR_MESSAGE);
+ throw pe;
+ }
+ v = d + m/60.0;
+ if (h == 1)
+ v = -v;
+ return v;
+ }
+
+ public AltosUIMapPos(AltosUIFrame in_owner,
+ AltosUIMapPreload preload,
+ String label_value,
+ String[] hemi_names,
+ double default_value) {
+ super(BoxLayout.X_AXIS);
+ owner = in_owner;
+ this.preload = preload;
+ label = new JLabel(label_value);
+ hemi = new JComboBox<String>(hemi_names);
+ hemi.setEditable(false);
+ deg = new JTextField(5);
+ deg.addActionListener(this);
+ deg.setMinimumSize(deg.getPreferredSize());
+ deg.setHorizontalAlignment(JTextField.RIGHT);
+ deg_label = new JLabel("°");
+ min = new JTextField(9);
+ min.addActionListener(this);
+ min.setMinimumSize(min.getPreferredSize());
+ min_label = new JLabel("'");
+ set_value(default_value);
+ add(label);
+ add(Box.createRigidArea(new Dimension(5, 0)));
+ add(hemi);
+ add(Box.createRigidArea(new Dimension(5, 0)));
+ add(deg);
+ add(Box.createRigidArea(new Dimension(5, 0)));
+ add(deg_label);
+ add(Box.createRigidArea(new Dimension(5, 0)));
+ add(min);
+ add(Box.createRigidArea(new Dimension(5, 0)));
+ add(min_label);
+ }
+}
+
+public class AltosUIMapPreload extends AltosUIFrame implements ActionListener, ItemListener, AltosLaunchSiteListener, AltosMapLoaderListener, AltosUnitsListener, AltosFontListener {
+ AltosUIFrame owner;
+ AltosUIMap map;
+
+ AltosUIMapPos lat;
+ AltosUIMapPos lon;
+
+ JProgressBar pbar;
+
+ JLabel site_list_label;
+ JComboBox<AltosLaunchSite> site_list;
+
+ JToggleButton load_button;
+ JButton close_button;
+
+ JCheckBox[] maptypes = new JCheckBox[AltosMap.maptype_terrain - AltosMap.maptype_hybrid + 1];
+
+ JComboBox<Integer> min_zoom;
+ JComboBox<Integer> max_zoom;
+ JLabel radius_label;
+ JComboBox<Double> radius;
+ int scale = 1;
+
+ Integer[] zooms = { -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 };
+
+ Double[] radius_mi = { 1.0, 2.0, 5.0, 10.0, 20.0 };
+ Double radius_def_mi = 5.0;
+ Double[] radius_km = { 2.0, 5.0, 10.0, 20.0, 30.0 };
+ Double radius_def_km = 10.0;
+
+ AltosMapLoader loader;
+
+ static final String[] lat_hemi_names = { "N", "S" };
+ static final String[] lon_hemi_names = { "E", "W" };
+
+ double latitude, longitude;
+
+ long loader_notify_time;
+
+ /* AltosMapLoaderListener interfaces */
+ public void loader_start(final int max) {
+ loader_notify_time = System.currentTimeMillis();
+
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ pbar.setMaximum(max);
+ pbar.setValue(0);
+ pbar.setString("");
+ }
+ });
+ }
+
+ public void loader_notify(final int cur, final int max, final String name) {
+ long now = System.currentTimeMillis();
+
+ if (now - loader_notify_time < 100)
+ return;
+
+ loader_notify_time = now;
+
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ pbar.setValue(cur);
+ pbar.setString(name);
+ }
+ });
+ }
+
+ public void loader_done(int max) {
+ loader = null;
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ pbar.setValue(0);
+ pbar.setString("");
+ load_button.setSelected(false);
+ }
+ });
+ }
+
+ public void debug(String format, Object ... arguments) {
+ if (AltosSerial.debug)
+ System.out.printf(format, arguments);
+ }
+
+
+ private int all_types() {
+ int all_types = 0;
+ for (int t = AltosMap.maptype_hybrid; t <= AltosMap.maptype_terrain; t++)
+ if (maptypes[t].isSelected())
+ all_types |= (1 << t);
+ return all_types;
+ }
+
+ void center_map(double latitude, double longitude) {
+ map.map.centre(new AltosLatLon(latitude, longitude));
+ map.clear_marks();
+ map.add_mark(latitude, longitude, AltosLib.ao_flight_boost);
+ }
+
+ void center_map() {
+ try {
+ center_map(lat.get_value(), lon.get_value());
+ } catch (ParseException pe) {
+ }
+ }
+
+ public void itemStateChanged(ItemEvent e) {
+ int state = e.getStateChange();
+
+ if (state == ItemEvent.SELECTED) {
+ Object o = e.getItem();
+ if (o instanceof AltosLaunchSite) {
+ AltosLaunchSite site = (AltosLaunchSite) o;
+ lat.set_value(site.latitude);
+ lon.set_value(site.longitude);
+ center_map(site.latitude, site.longitude);
+ }
+ }
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+
+ if (cmd.equals("close")) {
+ if (loader != null)
+ loader.abort();
+ setVisible(false);
+ }
+
+ if (cmd.equals("load")) {
+ if (loader == null) {
+ try {
+ latitude = lat.get_value();
+ longitude = lon.get_value();
+ int min_z = (Integer) min_zoom.getSelectedItem();
+ int max_z = (Integer) max_zoom.getSelectedItem();
+ if (max_z < min_z)
+ max_z = min_z;
+ Double r = (Double) radius.getSelectedItem();
+
+ if (AltosPreferences.imperial_units())
+ r = AltosConvert.miles_to_meters(r);
+ else
+ r = r * 1000;
+
+ center_map(latitude, longitude);
+
+ loader = new AltosMapLoader(this,
+ latitude, longitude,
+ min_z, max_z, r,
+ all_types(), scale);
+
+ } catch (ParseException pe) {
+ load_button.setSelected(false);
+ }
+ }
+ }
+ }
+
+ public void notify_launch_sites(final java.util.List<AltosLaunchSite> sites) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ int i = 1;
+ for (AltosLaunchSite site : sites) {
+ site_list.insertItemAt(site, i);
+ i++;
+ }
+ }
+ });
+ }
+
+ private void set_radius_values() {
+ radius_label.setText(String.format("Map Radius (%s)",
+ AltosPreferences.imperial_units() ? "mi" : "km"));
+
+ Double[] radii;
+
+ if (AltosPreferences.imperial_units())
+ radii = radius_mi;
+ else
+ radii = radius_km;
+
+ radius.removeAllItems();
+ for (Double r : radii) {
+ radius.addItem(r);
+ }
+ radius.setSelectedItem(radii[2]);
+ radius.setMaximumRowCount(radii.length);
+ }
+
+ public void units_changed(boolean imperial_units) {
+ map.units_changed(imperial_units);
+ set_radius_values();
+ }
+
+ public void font_size_changed(int font_size) {
+ map.font_size_changed(font_size);
+ }
+
+ public AltosUIMapPreload(AltosUIFrame in_owner) {
+ owner = in_owner;
+
+ Container pane = getContentPane();
+ GridBagConstraints c = new GridBagConstraints();
+ Insets i = new Insets(4,4,4,4);
+
+ setTitle("AltOS Load Maps");
+
+ pane.setLayout(new GridBagLayout());
+
+ addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ AltosUIPreferences.unregister_font_listener(AltosUIMapPreload.this);
+ AltosPreferences.unregister_units_listener(AltosUIMapPreload.this);
+ }
+ });
+
+
+ AltosPreferences.register_units_listener(this);
+ AltosUIPreferences.register_font_listener(this);
+
+ map = new AltosUIMap();
+
+ c.fill = GridBagConstraints.BOTH;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ c.weightx = 1;
+ c.weighty = 1;
+
+ c.gridx = 0;
+ c.gridy = 0;
+ c.gridwidth = 10;
+ c.anchor = GridBagConstraints.CENTER;
+
+ pane.add(map, c);
+
+ pbar = new JProgressBar();
+ pbar.setMinimum(0);
+ pbar.setMaximum(1);
+ pbar.setValue(0);
+ pbar.setString("");
+ pbar.setStringPainted(true);
+
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ c.weightx = 1;
+ c.weighty = 0;
+
+ c.gridx = 0;
+ c.gridy = 1;
+ c.gridwidth = 10;
+
+ pane.add(pbar, c);
+
+ site_list_label = new JLabel ("Known Launch Sites:");
+
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ c.weightx = 1;
+ c.weighty = 0;
+
+ c.gridx = 0;
+ c.gridy = 2;
+ c.gridwidth = 1;
+
+ pane.add(site_list_label, c);
+
+ site_list = new JComboBox<AltosLaunchSite>(new AltosLaunchSite[] { new AltosLaunchSite("Site List", 0, 0) });
+ site_list.addItemListener(this);
+
+ new AltosLaunchSites(this);
+
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ c.weightx = 1;
+ c.weighty = 0;
+
+ c.gridx = 1;
+ c.gridy = 2;
+ c.gridwidth = 1;
+
+ pane.add(site_list, c);
+
+ lat = new AltosUIMapPos(owner, this,
+ "Latitude:",
+ lat_hemi_names,
+ 37.167833333);
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ c.weightx = 0;
+ c.weighty = 0;
+
+ c.gridx = 0;
+ c.gridy = 3;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.CENTER;
+
+ pane.add(lat, c);
+
+ lon = new AltosUIMapPos(owner, this,
+ "Longitude:",
+ lon_hemi_names,
+ -97.73975);
+
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ c.weightx = 0;
+ c.weighty = 0;
+
+ c.gridx = 1;
+ c.gridy = 3;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.CENTER;
+
+ pane.add(lon, c);
+
+ load_button = new JToggleButton("Load Map");
+ load_button.addActionListener(this);
+ load_button.setActionCommand("load");
+
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ c.weightx = 1;
+ c.weighty = 0;
+
+ c.gridx = 0;
+ c.gridy = 4;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.CENTER;
+
+ pane.add(load_button, c);
+
+ close_button = new JButton("Close");
+ close_button.addActionListener(this);
+ close_button.setActionCommand("close");
+
+ c.fill = GridBagConstraints.NONE;
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = i;
+ c.weightx = 1;
+ c.weighty = 0;
+
+ c.gridx = 1;
+ c.gridy = 4;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.CENTER;
+
+ pane.add(close_button, c);
+
+ JLabel types_label = new JLabel("Map Types");
+ c.gridx = 2;
+ c.gridwidth = 2;
+ c.gridy = 2;
+ pane.add(types_label, c);
+
+ c.gridwidth = 1;
+
+ for (int type = AltosMap.maptype_hybrid; type <= AltosMap.maptype_terrain; type++) {
+ maptypes[type] = new JCheckBox(AltosMap.maptype_labels[type],
+ type == AltosMap.maptype_hybrid);
+ c.gridx = 2 + (type >> 1);
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridy = (type & 1) + 3;
+ pane.add(maptypes[type], c);
+ }
+
+ JLabel min_zoom_label = new JLabel("Minimum Zoom");
+ c.gridx = 4;
+ c.gridy = 2;
+ pane.add(min_zoom_label, c);
+
+ min_zoom = new JComboBox<Integer>(zooms);
+ min_zoom.setSelectedItem(zooms[10]);
+ min_zoom.setEditable(false);
+ c.gridx = 5;
+ c.gridy = 2;
+ pane.add(min_zoom, c);
+
+ JLabel max_zoom_label = new JLabel("Maximum Zoom");
+ c.gridx = 4;
+ c.gridy = 3;
+ pane.add(max_zoom_label, c);
+
+ max_zoom = new JComboBox<Integer>(zooms);
+ max_zoom.setSelectedItem(zooms[14]);
+ max_zoom.setEditable(false);
+ c.gridx = 5;
+ c.gridy = 3;
+ pane.add(max_zoom, c);
+
+ radius_label = new JLabel();
+
+ c.gridx = 4;
+ c.gridy = 4;
+ pane.add(radius_label, c);
+
+ radius = new JComboBox<Double>();
+ radius.setEditable(true);
+ c.gridx = 5;
+ c.gridy = 4;
+ pane.add(radius, c);
+
+ set_radius_values();
+
+ pack();
+ setLocationRelativeTo(owner);
+ setVisible(true);
+ }
+}
+++ /dev/null
-/*
- * 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 org.altusmetrum.altosuilib_10;
-
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-import java.io.*;
-import java.util.*;
-import java.text.*;
-import java.lang.Math;
-import java.net.URL;
-import java.net.URLConnection;
-import org.altusmetrum.altoslib_10.*;
-
-class AltosUIMapPos extends Box {
- AltosUIFrame owner;
- JLabel label;
- JComboBox hemi;
- JTextField deg;
- JLabel deg_label;
- JTextField min;
- JLabel min_label;
-
- public void set_value(double new_value) {
- double d, m;
- int h;
-
- h = 0;
- if (new_value < 0) {
- h = 1;
- new_value = -new_value;
- }
- d = Math.floor(new_value);
- deg.setText(String.format("%3.0f", d));
- m = (new_value - d) * 60.0;
- min.setText(String.format("%7.4f", m));
- hemi.setSelectedIndex(h);
- }
-
- public double get_value() throws ParseException {
- int h = hemi.getSelectedIndex();
- String d_t = deg.getText();
- String m_t = min.getText();
- double d, m, v;
- try {
- d = AltosParse.parse_double_locale(d_t);
- } catch (ParseException pe) {
- JOptionPane.showMessageDialog(owner,
- String.format("Invalid degrees \"%s\"",
- d_t),
- "Invalid number",
- JOptionPane.ERROR_MESSAGE);
- throw pe;
- }
- try {
- if (m_t.equals(""))
- m = 0;
- else
- m = AltosParse.parse_double_locale(m_t);
- } catch (ParseException pe) {
- JOptionPane.showMessageDialog(owner,
- String.format("Invalid minutes \"%s\"",
- m_t),
- "Invalid number",
- JOptionPane.ERROR_MESSAGE);
- throw pe;
- }
- v = d + m/60.0;
- if (h == 1)
- v = -v;
- return v;
- }
-
- public AltosUIMapPos(AltosUIFrame in_owner,
- String label_value,
- String[] hemi_names,
- double default_value) {
- super(BoxLayout.X_AXIS);
- owner = in_owner;
- label = new JLabel(label_value);
- hemi = new JComboBox<String>(hemi_names);
- hemi.setEditable(false);
- deg = new JTextField(5);
- deg.setMinimumSize(deg.getPreferredSize());
- deg.setHorizontalAlignment(JTextField.RIGHT);
- deg_label = new JLabel("°");
- min = new JTextField(9);
- min.setMinimumSize(min.getPreferredSize());
- min_label = new JLabel("'");
- set_value(default_value);
- add(label);
- add(Box.createRigidArea(new Dimension(5, 0)));
- add(hemi);
- add(Box.createRigidArea(new Dimension(5, 0)));
- add(deg);
- add(Box.createRigidArea(new Dimension(5, 0)));
- add(deg_label);
- add(Box.createRigidArea(new Dimension(5, 0)));
- add(min);
- add(Box.createRigidArea(new Dimension(5, 0)));
- add(min_label);
- }
-}
-
-public class AltosUIMapPreloadNew extends AltosUIFrame implements ActionListener, ItemListener, AltosLaunchSiteListener, AltosMapLoaderListener {
- AltosUIFrame owner;
- AltosUIMapNew map;
-
- AltosUIMapPos lat;
- AltosUIMapPos lon;
-
- JProgressBar pbar;
-
- JLabel site_list_label;
- JComboBox<AltosLaunchSite> site_list;
-
- JToggleButton load_button;
- boolean loading;
- JButton close_button;
-
- JCheckBox[] maptypes = new JCheckBox[AltosMap.maptype_terrain - AltosMap.maptype_hybrid + 1];
-
- JComboBox<Integer> min_zoom;
- JComboBox<Integer> max_zoom;
- JComboBox<Double> radius;
-
- Integer[] zooms = { -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 };
-
- Double[] radius_mi = { 1.0, 2.0, 5.0, 10.0, 20.0 };
- Double radius_def_mi = 5.0;
- Double[] radius_km = { 2.0, 5.0, 10.0, 20.0, 30.0 };
- Double radius_def_km = 10.0;
-
-
- static final String[] lat_hemi_names = { "N", "S" };
- static final String[] lon_hemi_names = { "E", "W" };
-
- double latitude, longitude;
-
- /* AltosMapLoaderListener interfaces */
- public void loader_start(final int max) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- pbar.setMaximum(max);
- pbar.setValue(0);
- pbar.setString("");
- map.clear_marks();
- map.add_mark(latitude, longitude, AltosLib.ao_flight_boost);
- }
- });
- }
-
- public void loader_notify(final int cur, final int max, final String name) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- pbar.setValue(cur);
- pbar.setString(name);
- }
- });
- }
-
- public void loader_done(int max) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- pbar.setValue(0);
- pbar.setString("");
- load_button.setSelected(false);
- loading = false;
- }
- });
- }
-
- public void debug(String format, Object ... arguments) {
- if (AltosSerial.debug)
- System.out.printf(format, arguments);
- }
-
-
- private int all_types() {
- int all_types = 0;
- for (int t = AltosMap.maptype_hybrid; t <= AltosMap.maptype_terrain; t++)
- if (maptypes[t].isSelected())
- all_types |= (1 << t);
- return all_types;
- }
-
- public void itemStateChanged(ItemEvent e) {
- int state = e.getStateChange();
-
- if (state == ItemEvent.SELECTED) {
- Object o = e.getItem();
- if (o instanceof AltosLaunchSite) {
- AltosLaunchSite site = (AltosLaunchSite) o;
- lat.set_value(site.latitude);
- lon.set_value(site.longitude);
- }
- }
- }
-
- public void actionPerformed(ActionEvent e) {
- String cmd = e.getActionCommand();
-
- if (cmd.equals("close"))
- setVisible(false);
-
- if (cmd.equals("load")) {
- if (!loading) {
- try {
- latitude = lat.get_value();
- longitude = lon.get_value();
- int min_z = (Integer) min_zoom.getSelectedItem();
- int max_z = (Integer) max_zoom.getSelectedItem();
- if (max_z < min_z)
- max_z = min_z;
- Double r = (Double) radius.getSelectedItem();
-
- if (AltosPreferences.imperial_units())
- r = AltosConvert.distance.inverse(r);
- else
- r = r * 1000;
- loading = true;
-
- new AltosMapLoader(map.map, this,
- latitude, longitude,
- min_z, max_z, r, all_types());
-
- } catch (ParseException pe) {
- load_button.setSelected(false);
- }
- }
- }
- }
-
- public void notify_launch_sites(final java.util.List<AltosLaunchSite> sites) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- int i = 1;
- for (AltosLaunchSite site : sites) {
- site_list.insertItemAt(site, i);
- i++;
- }
- }
- });
- }
-
- public AltosUIMapPreloadNew(AltosUIFrame in_owner) {
- owner = in_owner;
-
- Container pane = getContentPane();
- GridBagConstraints c = new GridBagConstraints();
- Insets i = new Insets(4,4,4,4);
-
- setTitle("AltOS Load Maps");
-
- pane.setLayout(new GridBagLayout());
-
- map = new AltosUIMapNew();
-
- c.fill = GridBagConstraints.BOTH;
- c.anchor = GridBagConstraints.CENTER;
- c.insets = i;
- c.weightx = 1;
- c.weighty = 1;
-
- c.gridx = 0;
- c.gridy = 0;
- c.gridwidth = 10;
- c.anchor = GridBagConstraints.CENTER;
-
- pane.add(map, c);
-
- pbar = new JProgressBar();
- pbar.setMinimum(0);
- pbar.setMaximum(1);
- pbar.setValue(0);
- pbar.setString("");
- pbar.setStringPainted(true);
-
- c.fill = GridBagConstraints.HORIZONTAL;
- c.anchor = GridBagConstraints.CENTER;
- c.insets = i;
- c.weightx = 1;
- c.weighty = 0;
-
- c.gridx = 0;
- c.gridy = 1;
- c.gridwidth = 10;
-
- pane.add(pbar, c);
-
- site_list_label = new JLabel ("Known Launch Sites:");
-
- c.fill = GridBagConstraints.NONE;
- c.anchor = GridBagConstraints.CENTER;
- c.insets = i;
- c.weightx = 1;
- c.weighty = 0;
-
- c.gridx = 0;
- c.gridy = 2;
- c.gridwidth = 1;
-
- pane.add(site_list_label, c);
-
- site_list = new JComboBox<AltosLaunchSite>(new AltosLaunchSite[] { new AltosLaunchSite("Site List", 0, 0) });
- site_list.addItemListener(this);
-
- new AltosLaunchSites(this);
-
- c.fill = GridBagConstraints.HORIZONTAL;
- c.anchor = GridBagConstraints.CENTER;
- c.insets = i;
- c.weightx = 1;
- c.weighty = 0;
-
- c.gridx = 1;
- c.gridy = 2;
- c.gridwidth = 1;
-
- pane.add(site_list, c);
-
- lat = new AltosUIMapPos(owner,
- "Latitude:",
- lat_hemi_names,
- 37.167833333);
- c.fill = GridBagConstraints.NONE;
- c.anchor = GridBagConstraints.CENTER;
- c.insets = i;
- c.weightx = 0;
- c.weighty = 0;
-
- c.gridx = 0;
- c.gridy = 3;
- c.gridwidth = 1;
- c.anchor = GridBagConstraints.CENTER;
-
- pane.add(lat, c);
-
- lon = new AltosUIMapPos(owner,
- "Longitude:",
- lon_hemi_names,
- -97.73975);
-
- c.fill = GridBagConstraints.NONE;
- c.anchor = GridBagConstraints.CENTER;
- c.insets = i;
- c.weightx = 0;
- c.weighty = 0;
-
- c.gridx = 1;
- c.gridy = 3;
- c.gridwidth = 1;
- c.anchor = GridBagConstraints.CENTER;
-
- pane.add(lon, c);
-
- load_button = new JToggleButton("Load Map");
- load_button.addActionListener(this);
- load_button.setActionCommand("load");
-
- c.fill = GridBagConstraints.NONE;
- c.anchor = GridBagConstraints.CENTER;
- c.insets = i;
- c.weightx = 1;
- c.weighty = 0;
-
- c.gridx = 0;
- c.gridy = 4;
- c.gridwidth = 1;
- c.anchor = GridBagConstraints.CENTER;
-
- pane.add(load_button, c);
-
- close_button = new JButton("Close");
- close_button.addActionListener(this);
- close_button.setActionCommand("close");
-
- c.fill = GridBagConstraints.NONE;
- c.anchor = GridBagConstraints.CENTER;
- c.insets = i;
- c.weightx = 1;
- c.weighty = 0;
-
- c.gridx = 1;
- c.gridy = 4;
- c.gridwidth = 1;
- c.anchor = GridBagConstraints.CENTER;
-
- pane.add(close_button, c);
-
- JLabel types_label = new JLabel("Map Types");
- c.gridx = 2;
- c.gridwidth = 2;
- c.gridy = 2;
- pane.add(types_label, c);
-
- c.gridwidth = 1;
-
- for (int type = AltosMap.maptype_hybrid; type <= AltosMap.maptype_terrain; type++) {
- maptypes[type] = new JCheckBox(AltosMap.maptype_labels[type],
- type == AltosMap.maptype_hybrid);
- c.gridx = 2 + (type >> 1);
- c.fill = GridBagConstraints.HORIZONTAL;
- c.gridy = (type & 1) + 3;
- pane.add(maptypes[type], c);
- }
-
- JLabel min_zoom_label = new JLabel("Minimum Zoom");
- c.gridx = 4;
- c.gridy = 2;
- pane.add(min_zoom_label, c);
-
- min_zoom = new JComboBox<Integer>(zooms);
- min_zoom.setSelectedItem(zooms[10]);
- min_zoom.setEditable(false);
- c.gridx = 5;
- c.gridy = 2;
- pane.add(min_zoom, c);
-
- JLabel max_zoom_label = new JLabel("Maximum Zoom");
- c.gridx = 4;
- c.gridy = 3;
- pane.add(max_zoom_label, c);
-
- max_zoom = new JComboBox<Integer>(zooms);
- max_zoom.setSelectedItem(zooms[14]);
- max_zoom.setEditable(false);
- c.gridx = 5;
- c.gridy = 3;
- pane.add(max_zoom, c);
-
- JLabel radius_label = new JLabel(String.format("Map Radius (%s)",
- AltosPreferences.imperial_units() ? "miles" : "km"));
- c.gridx = 4;
- c.gridy = 4;
- pane.add(radius_label, c);
-
- Double[] radii;
- Double radius_default;
-
- if (AltosPreferences.imperial_units())
- radii = radius_mi;
- else
- radii = radius_km;
- radius = new JComboBox<Double>(radii);
- radius.setSelectedItem(radii[2]);
- radius.setEditable(true);
- c.gridx = 5;
- c.gridy = 4;
- pane.add(radius, c);
-
- pack();
- setLocationRelativeTo(owner);
- setVisible(true);
- }
-}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.io.*;
import java.util.*;
import java.awt.Component;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosUIPreferences extends AltosPreferences {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.io.File;
import java.util.prefs.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import javax.swing.filechooser.FileSystemView;
public class AltosUIPreferencesBackend extends AltosPreferencesBackend {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosUIRateList extends JComboBox<String> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
String example = units.graph_format(7);
ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})",
- units.show_units()),
+ units.graph_units()),
new java.text.DecimalFormat(time_example),
new java.text.DecimalFormat(example));
renderer.setBaseToolTipGenerator(ttg);
public void add(AltosUIDataPoint dataPoint) {
try {
- super.add(dataPoint.x(), units.value(dataPoint.y(fetch)));
+ super.add(dataPoint.x(), units.graph_value(dataPoint.y(fetch)));
} catch (AltosUIDataMissing dm) {
}
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.util.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class AltosUITelemetryList extends JComboBox<String> {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public abstract class AltosUIUnitsIndicator extends AltosUIIndicator {
public double[] last_values;
- public void show(double... v) {
+ private void show(boolean force, double... v) {
show();
for (int i = 0; i < values.length; i++) {
- if (v[i] != last_values[i]) {
+ if (force || v[i] != last_values[i]) {
String value_text;
boolean good = false;
}
}
+ boolean hide = false;
+
+ public void show(double... v) {
+ show(false, v);
+ }
+
public void units_changed(boolean imperial_units) {
- show(last_values);
+ if (!hide)
+ show(true, last_values);
}
public void show (AltosState state, AltosListenerState listener_state) {
double[] v = new double[values.length];
- boolean hide = false;
for (int i = 0; i < values.length; i++) {
if (state != null)
public void reset() {
for (int i = 0; i < last_values.length; i++)
- last_values[i] = AltosLib.MISSING - 1;
+ last_values[i] = AltosLib.MISSING;
}
public AltosUIUnitsIndicator (Container container, int x, int y, int label_width, AltosUnits units, String name, int number_values, boolean has_lights, int width) {
this.units = units;
last_values = new double[values.length];
for (int i = 0; i < last_values.length; i++)
- last_values[i] = AltosLib.MISSING - 1;
+ last_values[i] = AltosLib.MISSING;
}
public AltosUIUnitsIndicator (Container container, int x, int y, AltosUnits units, String name, int number_values, boolean has_lights, int width) {
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public abstract class AltosUIVoltageIndicator extends AltosUIUnitsIndicator {
return voltage(state);
}
- double last_voltage = -1;
+ double last_voltage = AltosLib.MISSING;
public AltosUIVoltageIndicator (Container container, int x, int y, String name, int width) {
super(container, x, y, AltosConvert.voltage, name, 1, true, width);
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.util.*;
import libaltosJNI.*;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.awt.*;
import java.awt.event.*;
AltosBTDeviceIterator.java \
AltosBTManage.java \
AltosBTKnown.java \
- AltosUIMapNew.java \
- AltosUIMapPreloadNew.java \
+ AltosUIMap.java \
+ AltosUIMapPreload.java \
AltosUIFlightTab.java \
AltosUIIndicator.java \
AltosUIUnitsIndicator.java \
*/
-package org.altusmetrum.altosuilib_10;
+package org.altusmetrum.altosuilib_11;
import java.lang.reflect.*;
import java.util.HashMap;
return 0;
}
- if (temperature < 20 || 35 < temperature) {
+ if (temperature < 20 || 40 < temperature) {
printf ("weird temperature %f\n", temperature);
free_baro(b);
return 0;
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
-AC_INIT([altos], 1.6.3)
-ANDROID_VERSION=11
+AC_INIT([altos], 1.6.4)
+ANDROID_VERSION=12
AC_CONFIG_SRCDIR([src/kernel/ao.h])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
dnl ==========================================================================
dnl Java library versions
-ALTOSUILIB_VERSION=10
-ALTOSLIB_VERSION=10
+ALTOSUILIB_VERSION=11
+ALTOSLIB_VERSION=11
AC_SUBST(ALTOSLIB_VERSION)
AC_DEFINE(ALTOSLIB_VERSION,$ALTOSLIB_VERSION,[Version of the AltosLib package])
#
RELNOTES_INC=\
+ release-notes-1.6.4.inc \
release-notes-1.6.3.inc \
release-notes-1.6.2.inc \
release-notes-1.6.1.inc \
</legalnotice>
<revhistory>
<?dbhtml filename="altusmetrum-revhistory.html"?>
+ <revision>
+ <revnumber>1.6.4</revnumber>
+ <date>10 May 2016</date>
+ <revremark>
+ Minor release fixing TeleBT v1.0 flow control and a few minor
+ application bugs.
+ </revremark>
+ </revision>
<revision>
<revnumber>1.6.3</revnumber>
<date>21 April 2016</date>
--- /dev/null
+= Release Notes for Version 1.6.4
+:toc!:
+:doctype: article
+
+ Version 1.6.4 fixes a bluetooth communication problem with
+ TeleBT v1.0 devices, along with some altosui and altosdroid
+ minor nits. It also now ships firmware for some newer devices.
+
+ == AltOS
+
+ AltOS fixes:
+
+ * Fix hardware flow control on TeleBT v1.0. Hardware RTS/CTS
+ doesn't seem to work, switch from using the hardware to
+ driving these pins with software.
+
+ * Fix ARM USB drivers to deal with OS restarts. Needed to
+ reset all USB-related state when the USB bus is reset. These
+ fixes affect all STM32L, STM32F0 and LPC11U14 based devices.
+
+ == AltosUI, TeleGPS and AltosDroid Applications
+
+ AltosUI, TeleGPS and AltosDroid New Features:
+
+ * Automatically switch from meters or feet to kilometers or
+ miles for distance units.
+
+ * Add Monitor Idle mode to TeleGPS application.
+
+ AltosUI, TeleGPS and AltosDroid Fixes:
+
+ * Abort map preloading when the preload map dialog is closed.
+
+ * In AltosDroid, Don't reconnect to last device if the user
+ had disconnected it the last time the application was
+ active.
+
+ == Documentation
+
+ * Mention TeleMega v2.0 in hardware specs table.
+
+ * Document TeleGPS RF output in telegps manual.
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.6.4.raw[]
+
+ <<<<
+
:leveloffset: 2
include::release-notes-1.6.3.raw[]
|8MB
|40mW
|3.7V
+
+ |TeleMega v2.0
+ |MS5607 30km (100k')
+ |MMA6555 102g
+ |uBlox Max-7Q
+ |MPU6000 HMC5883
+ |8MB
+ |40mW
+ |3.7V
endif::telemega[]
ifdef::easymega[]
</legalnotice>
<revhistory>
<?dbhtml filename="telegps-revhistory.html"?>
+ <revision>
+ <revnumber>1.6.4</revnumber>
+ <date>10 May 2016</date>
+ <revremark>
+ Minor release fixing TeleBT v1.0 flow control and a few minor
+ application bugs.
+ </revremark>
+ </revision>
<revision>
<revnumber>1.6.1</revnumber>
<date>15 July 2015</date>
TeleGPS uses the u-Blox Max-7Q GPS receiver.
+ === 70cm Transmitter
+
+ TeleGPS uses a TI CC115L transmitter. This radio
+ produces 10mW of RF output.
+
=== Micro-controller
TeleGPS uses an NXP LPC11U14 micro-controller. This
signals, but no record of the flight will be
stored in on-board flash.
+ ifdef::easymega,telemega[]
|Additional Igniters
|four very short beeps
|Continuity indication for the four additional pyro
- |channels on TeleMega and EasyMega. One high tone for
- |no continuity, one low tone for continuity. These are
- |produced after the continuity indicators for the two
- |primary igniter channels.
+ channels on TeleMega and EasyMega. One high tone for
+ no continuity, one low tone for continuity. These are
+ produced after the continuity indicators for the two
+ primary igniter channels.
+ endif::easymega,telemega[]
|====
FATJAR=micropeak-fat.jar
+if MULTI_ARCH
+LIBALTOS_LINUX=libaltos32.so libaltos64.so
+else
+LIBALTOS_LINUX=libaltos.so
+endif
+
LIBALTOS= \
- libaltos.so \
+ $(LIBALTOS_LINUX) \
libaltos.dylib \
altos64.dll \
altos.dll
clean-local:
-rm -rf classes $(JAR) $(FATJAR) \
MicroPeak-Linux-*.tar.bz2 MicroPeak-Mac-*.dmg MicroPeak-Windows-*.exe \
- $(ALTOSLIB_CLASS) \
- $(ALTOSUILIB_CLASS) \
+ altoslib_*.jar altosuilib_*.jar \
$(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt \
micropeak micropeak-test micropeak-jdb macosx linux windows micropeak-windows.log \
micropeak-windows.nsi *.desktop
FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS)
-LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
+LINUX_FILES=$(FAT_FILES) $(LIBALTOS_LINUX) $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
LINUX_EXTRA=micropeak-fat $(desktop_file).in
MACOSX_DRIVER_0_URL=http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_18.dmg
-rm -f "$@"
$(LN_S) ../libaltos/.libs/"$@" .
+libaltos32.so: build-libaltos
+ -rm -f "$@"
+ $(LN_S) ../libaltos/.libs/"$@" .
+
+libaltos64.so: build-libaltos
+ -rm -f "$@"
+ $(LN_S) ../libaltos/.libs/"$@" .
+
libaltos.dylib:
-rm -f "$@"
$(LN_S) ../libaltos/"$@" .
-rm -f "$@"
$(LN_S) ../libaltos/"$@" .
+../libaltos/.libs/libaltos64.so: ../libaltos/.libs/libaltos32.so
+
+../libaltos/.libs/libaltos32.so: build-libaltos
+
../libaltos/.libs/libaltos.so: build-libaltos
../libaltos/altos.dll: build-altos-dll
import java.lang.*;
import java.io.*;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
class MicroIterator implements Iterator<MicroDataPoint> {
int i;
package org.altusmetrum.micropeak;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroDataPoint implements AltosUIDataPoint {
public double time;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroDeviceDialog extends AltosDeviceDialog {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroDownload extends AltosUIDialog implements Runnable, ActionListener, MicroSerialLog, WindowListener {
MicroPeak owner;
import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroExport extends JFileChooser {
import java.io.*;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroFile {
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroFileChooser extends JFileChooser {
JFrame frame;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroFrame extends AltosUIFrame {
static String[] micro_icon_names = {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
import org.jfree.ui.*;
import org.jfree.chart.*;
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroPeak extends MicroFrame implements ActionListener, ItemListener {
import java.awt.*;
import java.io.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroRaw extends JTextArea {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroSave extends JFileChooser {
import java.util.*;
import java.io.*;
import libaltosJNI.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroSerial extends InputStream {
SWIGTYPE_p_altos_file file;
import java.util.*;
import java.io.*;
import libaltosJNI.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
public interface MicroSerialLog {
package org.altusmetrum.micropeak;
import java.io.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroStats {
double coast_height;
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroStatsTable extends JComponent implements AltosFontListener {
GridBagLayout layout;
import java.util.*;
import libaltosJNI.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class MicroUSB extends altos_device implements AltosDevice {
#define AO_SERIAL_SPEED_MAX AO_SERIAL_SPEED_115200
+#if HAS_SERIAL_1_ALT_1
+#define SERIAL_1_RTS P0_3
+#else
+#define SERIAL_1_RTS P1_5
+#endif
+
+#if HAS_SERIAL_0_ALT_1
+#define SERIAL_0_RTS P0_5
+#else
+#define SERIAL_0_RTS P1_3
+#endif
+
#if HAS_SERIAL_0
volatile __xdata struct ao_fifo ao_serial0_rx_fifo;
#if USE_SERIAL_0_STDIN
ao_wakeup(&ao_stdin_ready);
#endif
+#if HAS_SERIAL_0_HW_FLOW
+ if (ao_fifo_mostly(ao_serial0_rx_fifo))
+ SERIAL_0_RTS = 1;
+#endif
}
static __xdata uint8_t ao_serial0_tx_started;
while (ao_fifo_empty(ao_serial0_rx_fifo))
ao_sleep(&ao_serial0_rx_fifo);
ao_fifo_remove(ao_serial0_rx_fifo, c);
+#if HAS_SERIAL_0_HW_FLOW
+ if (ao_fifo_barely(ao_serial0_rx_fifo))
+ SERIAL_0_RTS = 0;
+#endif
return c;
}
if (ao_fifo_empty(ao_serial0_rx_fifo))
return AO_READ_AGAIN;
ao_fifo_remove(ao_serial0_rx_fifo,c);
+#if HAS_SERIAL_0_HW_FLOW
+ if (ao_fifo_barely(ao_serial0_rx_fifo))
+ SERIAL_0_RTS = 0;
+#endif
return c;
}
#endif
#if USE_SERIAL_1_STDIN
ao_wakeup(&ao_stdin_ready);
#endif
+#if HAS_SERIAL_1_HW_FLOW
+ if (ao_fifo_mostly(ao_serial1_rx_fifo))
+ SERIAL_1_RTS = 1;
+#endif
}
static __xdata uint8_t ao_serial1_tx_started;
while (ao_fifo_empty(ao_serial1_rx_fifo))
ao_sleep(&ao_serial1_rx_fifo);
ao_fifo_remove(ao_serial1_rx_fifo, c);
+#if HAS_SERIAL_1_HW_FLOW
+ if (ao_fifo_barely(ao_serial1_rx_fifo))
+ SERIAL_1_RTS = 0;
+#endif
return c;
}
if (ao_fifo_empty(ao_serial1_rx_fifo))
return AO_READ_AGAIN;
ao_fifo_remove(ao_serial1_rx_fifo,c);
+#if HAS_SERIAL_1_HW_FLOW
+ if (ao_fifo_barely(ao_serial1_rx_fifo))
+ SERIAL_1_RTS = 0;
+#endif
return c;
}
#endif
/* Make the USART pins be controlled by the USART */
P0SEL |= (1 << 2) | (1 << 3);
#if HAS_SERIAL_0_HW_FLOW
- P0SEL |= (1 << 4) | (1 << 5);
+ SERIAL_0_RTS = 0;
+ P0DIR |= (1 << 5);
+
+ P0SEL |= (1 << 4);
+ P0INP |= (1 << 4);
#endif
#else
/* Set up the USART pin assignment */
/* Make the USART pins be controlled by the USART */
P1SEL |= (1 << 5) | (1 << 4);
#if HAS_SERIAL_0_HW_FLOW
- P1SEL |= (1 << 3) | (1 << 2);
+ SERIAL_0_RTS = 0;
+ P1DIR |= (1 << 3);
+
+ P1SEL |= (1 << 2);
+ P1INP |= (1 << 2);
#endif
#endif
/* Make the USART pins be controlled by the USART */
P0SEL |= (1 << 5) | (1 << 4);
#if HAS_SERIAL_1_HW_FLOW
- P0SEL |= (1 << 3) | (1 << 2);
+ /* SW RTS control (hw doesn't work) */
+ SERIAL_1_RTS = 0;
+ P0DIR |= 1 << 3;
+
+ /* HW CTS. Maybe this works? */
+ P0SEL |= 1 << 2;
+ P0INP |= 1 << 2;
#endif
#else
/* Set up the USART pin assignment */
/* Make the USART pins be controlled by the USART */
P1SEL |= (1 << 6) | (1 << 7);
#if HAS_SERIAL_1_HW_FLOW
- P1SEL |= (1 << 5) | (1 << 4);
+ /* SW RTS control (hw doesn't work) */
+ SERIAL_1_RTS = 0;
+ P1DIR |= (1 << 5);
+
+ /* HW CTS. Maybe this works? */
+ P1SEL |= (1 << 4);
+ P1INP |= (1 << 4);
#endif
#endif
const char *comment;
};
-#define NUM_TRACE 256
+#define NUM_TRACE 32
static struct ao_cc115l_trace trace[NUM_TRACE];
static int trace_i;
#include <ao_exti.h>
#include <ao_power.h>
-static struct ao_task ao_trng_send_task, ao_trng_send_raw_task;
+static struct ao_task ao_trng_send_task;
static uint8_t trng_running;
static AO_TICK_TYPE trng_power_time;
static uint8_t random_mutex;
+#if AO_USB_HAS_IN2
+
+static struct ao_task ao_trng_send_raw_task;
+
static void
ao_trng_get_raw(uint16_t *buf)
{
}
}
+#endif
+
/* Make sure there's at least 8 bits of variance in the samples */
#define MIN_VARIANCE (128 * 128)
if (failed > AO_TRNG_START_CHECK / 4)
ao_panic(AO_PANIC_DMA);
+#if AO_USB_HAS_IN2
ao_add_task(&ao_trng_send_raw_task, ao_trng_send_raw, "trng_send_raw");
+#endif
#ifdef AO_USB_START_DISABLED
ao_usb_enable();
return ao_usb_ep_count(ao_usb_epn_in(n, 0));
}
-static uint8_t *
-ao_usb_enable_ep(vuint32_t *ep, uint16_t nbytes, uint16_t set_nbytes)
+static void
+ao_usb_enable_ep(vuint32_t *ep, uint8_t *addr, uint16_t set_nbytes)
{
- uint8_t *addr = ao_usb_alloc_sram(nbytes);
-
ao_usb_set_ep(ep, addr, set_nbytes);
- return addr;
}
static void
static void
ao_usb_enable_epn(uint8_t n,
- uint16_t out_bytes, uint8_t *out_addrs[2],
- uint16_t in_bytes, uint8_t *in_addrs[2])
+ uint16_t out_bytes, uint8_t *out_addr,
+ uint8_t *in_addr)
{
- uint8_t *addr;
-
- addr = ao_usb_enable_ep(ao_usb_epn_out(n, 0), out_bytes * 2, out_bytes);
- if (out_addrs) {
- out_addrs[0] = addr;
- out_addrs[1] = addr + out_bytes;
- }
+ ao_usb_enable_ep(ao_usb_epn_out(n, 0), out_addr, out_bytes);
ao_usb_disable_ep(ao_usb_epn_out(n, 1));
- addr = ao_usb_enable_ep(ao_usb_epn_in(n, 0), in_bytes * 2, 0);
- if (in_addrs) {
- in_addrs[0] = addr;
- in_addrs[1] = addr + in_bytes;
- }
+ ao_usb_enable_ep(ao_usb_epn_in(n, 0), in_addr, 0);
ao_usb_disable_ep(ao_usb_epn_in(n, 1));
}
{
ao_usb_set_address(0);
ao_usb_configuration = 0;
+
+ ao_usb_ep0_state = AO_USB_EP0_IDLE;
+ ao_usb_ep0_in_data = NULL;
+ ao_usb_ep0_in_len = 0;
+ ao_usb_ep0_in_max = 0;
+
+ ao_usb_ep0_out_data = NULL;
+ ao_usb_ep0_out_len = 0;
}
static void
lpc_usb.intstat = 0xc00003ff;
- ao_usb_sram = lpc_usb_sram;
-
lpc_usb.epliststart = (uint32_t) (intptr_t) &lpc_usb_endpoint;
lpc_usb.databufstart = ((uint32_t) (intptr_t) ao_usb_sram) & 0xffc00000;
/* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */
- ao_usb_ep0_rx_buffer = ao_usb_enable_ep(ao_usb_ep0_out(), AO_USB_CONTROL_SIZE, AO_USB_CONTROL_SIZE);
- ao_usb_ep0_setup_buffer = ao_usb_alloc_sram(AO_USB_CONTROL_SIZE);
+ ao_usb_enable_ep(ao_usb_ep0_out(), ao_usb_ep0_rx_buffer, AO_USB_CONTROL_SIZE);
lpc_usb_endpoint.setup = ao_usb_sram_offset(ao_usb_ep0_setup_buffer);
- ao_usb_ep0_tx_buffer = ao_usb_enable_ep(ao_usb_ep0_in(), AO_USB_CONTROL_SIZE, 0);
+ ao_usb_enable_ep(ao_usb_ep0_in(), ao_usb_ep0_tx_buffer, 0);
/* Clear all of the other endpoints */
for (e = 1; e <= 4; e++)
debug ("ao_usb_set_configuration\n");
/* Set up the INT end point */
- ao_usb_enable_epn(AO_USB_INT_EP, 0, NULL, 0, NULL);
+ ao_usb_enable_epn(AO_USB_INT_EP, 0, NULL, NULL);
/* Set up the OUT end point */
- ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE, ao_usb_out_rx_buffer, 0, NULL);
+ ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE, ao_usb_out_rx_buffer[0], NULL);
/* Set the current RX pointer to the *other* buffer so that when buffer 0 gets
* data, we'll switch to it and pull bytes from there
ao_usb_out_rx_cur = 1;
/* Set up the IN end point */
- ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, AO_USB_IN_SIZE, ao_usb_in_tx_buffer);
+ ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, ao_usb_in_tx_buffer[0]);
ao_usb_in_tx_cur = 0;
+ ao_usb_in_flushed = 0;
+ ao_usb_in_pending = 0;
+ ao_wakeup(&ao_usb_in_pending);
+
+ ao_usb_out_avail = 0;
+ ao_usb_configuration = 0;
+
ao_usb_running = 1;
+ ao_wakeup(&ao_usb_running);
}
/* Send an IN data packet */
/* Walk through the list of descriptors and find a match
*/
static void
-ao_usb_get_descriptor(uint16_t value)
+ao_usb_get_descriptor(uint16_t value, uint16_t length)
{
const uint8_t *descriptor;
uint8_t type = value >> 8;
len = descriptor[2];
else
len = descriptor[0];
+ if (len > length)
+ len = length;
ao_usb_ep0_in_set(descriptor, len);
break;
}
break;
case AO_USB_REQ_GET_DESCRIPTOR:
debug ("get descriptor %d\n", ao_usb_setup.value);
- ao_usb_get_descriptor(ao_usb_setup.value);
+ ao_usb_get_descriptor(ao_usb_setup.value, ao_usb_setup.length);
break;
case AO_USB_REQ_GET_CONFIGURATION:
debug ("get configuration %d\n", ao_usb_configuration);
for (t = 0; t < 1000; t++)
ao_arch_nop();
+ ao_usb_sram = lpc_usb_sram;
+
+ ao_usb_ep0_rx_buffer = ao_usb_alloc_sram(AO_USB_CONTROL_SIZE);
+ ao_usb_ep0_tx_buffer = ao_usb_alloc_sram(AO_USB_CONTROL_SIZE);
+ ao_usb_ep0_setup_buffer = ao_usb_alloc_sram(AO_USB_CONTROL_SIZE);
+
+ ao_usb_out_rx_buffer[0] = ao_usb_alloc_sram(AO_USB_OUT_SIZE);
+ ao_usb_out_rx_buffer[1] = ao_usb_alloc_sram(AO_USB_OUT_SIZE);
+ ao_usb_in_tx_buffer[0] = ao_usb_alloc_sram(AO_USB_IN_SIZE);
+ ao_usb_in_tx_buffer[1] = ao_usb_alloc_sram(AO_USB_IN_SIZE);
+
ao_usb_set_ep0();
#if HAS_USB_PULLUP
#if HAS_USB_PULLUP
ao_enable_output(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0);
#endif
-
ao_usb_enable();
debug ("ao_usb_init\n");
}
ao_usb_set_address(0);
+
+ ao_usb_running = 0;
+
+ /* Reset our internal state
+ */
+
+ ao_usb_ep0_state = AO_USB_EP0_IDLE;
+
+ ao_usb_ep0_in_data = NULL;
+ ao_usb_ep0_in_len = 0;
+
+ ao_usb_ep0_out_data = 0;
+ ao_usb_ep0_out_len = 0;
}
static void
STM_USB_EPR_STAT_RX_DISABLED,
STM_USB_EPR_STAT_TX_NAK);
+ ao_usb_in_flushed = 0;
+ ao_usb_in_pending = 0;
+ ao_wakeup(&ao_usb_in_pending);
+
+ ao_usb_out_avail = 0;
+ ao_usb_configuration = 0;
+
ao_usb_running = 1;
+ ao_wakeup(&ao_usb_running);
}
static uint16_t control_count;
/* Walk through the list of descriptors and find a match
*/
static void
-ao_usb_get_descriptor(uint16_t value)
+ao_usb_get_descriptor(uint16_t value, uint16_t length)
{
const uint8_t *descriptor;
uint8_t type = value >> 8;
len = descriptor[2];
else
len = descriptor[0];
+ if (len > length)
+ len = length;
ao_usb_ep0_in_set(descriptor, len);
break;
}
break;
case AO_USB_REQ_GET_DESCRIPTOR:
debug ("get descriptor %d\n", ao_usb_setup.value);
- ao_usb_get_descriptor(ao_usb_setup.value);
+ ao_usb_get_descriptor(ao_usb_setup.value, ao_usb_setup.length);
break;
case AO_USB_REQ_GET_CONFIGURATION:
debug ("get configuration %d\n", ao_usb_configuration);
uint16_t *
ao_usb_alloc(void);
-void
-ao_usb_free(uint16_t *buffer);
-
void
ao_usb_write(uint16_t *buffer, uint16_t len);
/* Buffer description tables */
static union stm_usb_bdt *ao_usb_bdt;
/* USB address of end of allocated storage */
+#if AO_USB_DIRECTIO
static uint16_t ao_usb_sram_addr;
+#endif
/* Pointer to ep0 tx/rx buffers in USB memory */
static uint16_t *ao_usb_ep0_tx_buffer;
static void
ao_usb_alloc_buffers(void)
{
- ao_usb_sram_addr = 0;
+ uint16_t sram_addr = 0;
ao_usb_bdt = (void *) stm_usb_sram;
- ao_usb_sram_addr += 8 * STM_USB_BDT_SIZE;
+ sram_addr += 8 * STM_USB_BDT_SIZE;
- ao_usb_ep0_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
- ao_usb_sram_addr += AO_USB_CONTROL_SIZE;
+ ao_usb_ep0_tx_buffer = ao_usb_packet_buffer_addr(sram_addr);
+ sram_addr += AO_USB_CONTROL_SIZE;
- ao_usb_ep0_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
- ao_usb_sram_addr += AO_USB_CONTROL_SIZE;
+ ao_usb_ep0_rx_buffer = ao_usb_packet_buffer_addr(sram_addr);
+ sram_addr += AO_USB_CONTROL_SIZE;
#if AO_USB_HAS_INT
- ao_usb_int_tx_offset = ao_usb_sram_addr;
- ao_usb_sram_addr += AO_USB_INT_SIZE;
+ ao_usb_int_tx_offset = sram_addr;
+ sram_addr += AO_USB_INT_SIZE;
#endif
#if AO_USB_HAS_OUT
- ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
- ao_usb_out_rx_offset = ao_usb_sram_addr;
- ao_usb_sram_addr += AO_USB_OUT_SIZE;
+ ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(sram_addr);
+ ao_usb_out_rx_offset = sram_addr;
+ sram_addr += AO_USB_OUT_SIZE;
#endif
#if AO_USB_HAS_IN
- ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
- ao_usb_in_tx_offset = ao_usb_sram_addr;
- ao_usb_sram_addr += AO_USB_IN_SIZE;
+ ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(sram_addr);
+ ao_usb_in_tx_offset = sram_addr;
+ sram_addr += AO_USB_IN_SIZE;
#endif
#if AO_USB_HAS_IN2
- ao_usb_in2_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
- ao_usb_in2_tx_offset = ao_usb_sram_addr;
- ao_usb_sram_addr += AO_USB_IN_SIZE;
+ ao_usb_in2_tx_buffer = ao_usb_packet_buffer_addr(sram_addr);
+ ao_usb_in2_tx_offset = sram_addr;
+ sram_addr += AO_USB_IN_SIZE;
+#endif
+
+#if AO_USB_DIRECTIO
+ ao_usb_sram_addr = sram_addr;
#endif
}
ao_usb_set_address(0);
ao_usb_running = 0;
+
+ /* Reset our internal state
+ */
+
+ ao_usb_ep0_state = AO_USB_EP0_IDLE;
+
+ ao_usb_ep0_in_data = NULL;
+ ao_usb_ep0_in_len = 0;
+
+ ao_usb_ep0_out_data = 0;
+ ao_usb_ep0_out_len = 0;
}
static void
STM_USB_EPR_STAT_TX_NAK);
#endif
+ ao_usb_in_flushed = 0;
+ ao_usb_in_pending = 0;
+ ao_wakeup(&ao_usb_in_pending);
+#if AO_USB_HAS_IN2
+ ao_usb_in2_flushed = 0;
+ ao_usb_in2_pending = 0;
+ ao_wakeup(&ao_usb_in2_pending);
+#endif
+
+ ao_usb_out_avail = 0;
+ ao_usb_configuration = 0;
+
+ ao_wakeup(AO_USB_OUT_SLEEP_ADDR);
+
ao_usb_running = 1;
#if AO_USB_DIRECTIO
ao_wakeup(&ao_usb_running);
/* Walk through the list of descriptors and find a match
*/
static void
-ao_usb_get_descriptor(uint16_t value)
+ao_usb_get_descriptor(uint16_t value, uint16_t length)
{
const uint8_t *descriptor;
uint8_t type = value >> 8;
len = sizeof (ao_usb_serial);
}
#endif
+ if (len > length)
+ len = length;
ao_usb_ep0_in_set(descriptor, len);
break;
}
break;
case AO_USB_REQ_GET_DESCRIPTOR:
debug ("get descriptor %d\n", ao_usb_setup.value);
- ao_usb_get_descriptor(ao_usb_setup.value);
+ ao_usb_get_descriptor(ao_usb_setup.value, ao_usb_setup.length);
break;
case AO_USB_REQ_GET_CONFIGURATION:
debug ("get configuration %d\n", ao_usb_configuration);
return buffer;
}
-void
-ao_usb_free(uint16_t *addr)
-{
- uint16_t offset = ao_usb_packet_buffer_offset(addr);
- if (offset < ao_usb_sram_addr)
- ao_usb_sram_addr = offset;
-}
-
void
ao_usb_write(uint16_t *buffer, uint16_t len)
{
#define AO_CC115L_DONE_INT_PORT 0
#define AO_CC115L_DONE_INT_PIN 2
+/* SN 1959, owned by J. Patrick Bowers, had a hard landing and appears to have broken the
+ * internal connection between pin 8 and the chip. This board
+ * has been fixed by jumpering pin 8 to pin 10, which means that
+ * the DONE_INT_PIN is now 4 instead of 2. When building custom firmware for
+ * this board, just adjust the ao_pins.h value before compiling
+
+ #define AO_CC115L_DONE_INT_PIN_SN_1959 4
+
+ */
+
/*
* Flash (M25)
*/
FATJAR=telegps-fat.jar
+if MULTI_ARCH
+LIBALTOS_LINUX=libaltos32.so libaltos64.so
+else
+LIBALTOS_LINUX=libaltos.so
+endif
+
LIBALTOS= \
- libaltos.so \
+ $(LIBALTOS_LINUX) \
libaltos.dylib \
altos64.dll \
altos.dll
FIRMWARE_TD=$(FIRMWARE_TD_0_2) $(FIRMWARE_TD_3_0)
FIRMWARE_TBT_1_0=$(top_srcdir)/src/telebt-v1.0/telebt-v1.0-$(VERSION).ihx
-FIRMWARE_TBT=$(FIRMWARE_TBT_1_0)
+FIRMWARE_TBT_3_0=$(top_srcdir)/src/telebt-v3.0/telebt-v3.0-$(VERSION).ihx
+FIRMWARE_TBT=$(FIRMWARE_TBT_1_0) $(FIRMWARE_TBT_3_0)
FIRMWARE_TG_1_0=$(top_srcdir)/src/telegps-v1.0/telegps-v1.0-$(VERSION).ihx
FIRMWARE_TG=$(FIRMWARE_TG_1_0)
clean-local:
-rm -rf classes $(JAR) $(FATJAR) \
TeleGPS-Linux-*.tar.bz2 TeleGPS-Mac-*.dmg TeleGPS-Windows-*.exe \
- $(ALTOSLIB_CLASS) \
- $(ALTOSUILIB_CLASS) \
- $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt \
+ altoslib_*.jar altosuilib_*.jar \
+ $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(FREETTS_CLASS) $(LIBALTOS) Manifest.txt Manifest-fat.txt \
telegps telegps-test telegps-jdb macosx linux windows telegps-windows.log \
telegps-windows.nsi *.desktop
FAT_FILES=$(FATJAR) $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS)
-LINUX_FILES=$(FAT_FILES) libaltos.so $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
+LINUX_FILES=$(FAT_FILES) $(LIBALTOS_LINUX) $(FIRMWARE) $(DOC) $(desktop_file).in $(LINUX_ICONS) $(LINUX_MIMETYPE)
LINUX_EXTRA=telegps-fat $(desktop_file).in
MACOSX_INFO_PLIST=Info.plist
-rm -f "$@"
$(LN_S) ../libaltos/.libs/"$@" .
+libaltos32.so: build-libaltos
+ -rm -f "$@"
+ $(LN_S) ../libaltos/.libs/"$@" .
+
+libaltos64.so: build-libaltos
+ -rm -f "$@"
+ $(LN_S) ../libaltos/.libs/"$@" .
+
libaltos.dylib:
-rm -f "$@"
$(LN_S) ../libaltos/"$@" .
-rm -f "$@"
$(LN_S) ../libaltos/"$@" .
+../libaltos/.libs/libaltos64.so: ../libaltos/.libs/libaltos32.so
+
+../libaltos/.libs/libaltos32.so: build-libaltos
+
../libaltos/.libs/libaltos.so: build-libaltos
../libaltos/altos.dll: build-altos-dll
import java.util.concurrent.*;
import java.util.*;
import java.text.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class TeleGPS
extends AltosUIFrame
AltosFlightReader reader;
TeleGPSDisplayThread thread;
+ boolean idle_mode;
JMenuBar menu_bar;
JTabbedPane pane;
- AltosUIMapNew map;
+ AltosUIMap map;
TeleGPSInfo gps_info;
TeleGPSState gps_state;
AltosInfoTable info_table;
}
void load_maps() {
- new AltosUIMapPreloadNew(this);
+ new AltosUIMapPreload(this);
}
void disconnect() {
disable_rate_menu();
}
- void connect(AltosDevice device) {
- if (reader != null)
- disconnect();
+ void connect_flight(AltosDevice device) {
try {
AltosFlightReader reader = new AltosTelemetryReader(new AltosSerial(device));
- set_reader(reader, device);
+ set_reader(reader, device, false);
+ } catch (FileNotFoundException ee) {
+ JOptionPane.showMessageDialog(this,
+ ee.getMessage(),
+ String.format ("Cannot open %s", device.toShortString()),
+ JOptionPane.ERROR_MESSAGE);
+ } catch (AltosSerialInUseException si) {
+ JOptionPane.showMessageDialog(this,
+ String.format("Device \"%s\" already in use",
+ device.toShortString()),
+ "Device in use",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (IOException ee) {
+ JOptionPane.showMessageDialog(this,
+ String.format ("Unknown I/O error on %s", device.toShortString()),
+ "Unknown I/O error",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (TimeoutException te) {
+ JOptionPane.showMessageDialog(this,
+ String.format ("Timeout on %s", device.toShortString()),
+ "Timeout error",
+ JOptionPane.ERROR_MESSAGE);
+ } catch (InterruptedException ie) {
+ JOptionPane.showMessageDialog(this,
+ String.format("Interrupted %s", device.toShortString()),
+ "Interrupted exception",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ void connect_idle(AltosDevice device) {
+ try {
+ AltosFlightReader reader = new AltosIdleReader(new AltosSerial(device), false);
+ set_reader(reader, device, true);
} catch (FileNotFoundException ee) {
JOptionPane.showMessageDialog(this,
ee.getMessage(),
}
}
+ void connect(AltosDevice device) {
+ if (reader != null)
+ disconnect();
+ if (device.matchProduct(AltosLib.product_basestation))
+ connect_flight(device);
+ else
+ connect_idle(device);
+ }
+
void connect() {
AltosDevice device = AltosDeviceUIDialog.show(this,
- AltosLib.product_basestation);
+ AltosLib.product_any);
if (device == null)
return;
connect(device);
}
- public void set_reader(AltosFlightReader reader, AltosDevice device) {
+ public void set_reader(AltosFlightReader reader, AltosDevice device, boolean idle_mode) {
+ this.idle_mode = idle_mode;
status_update = new TeleGPSStatusUpdate(telegps_status);
telegps_status.start(status_update);
thread.start();
if (device != null) {
- enable_frequency_menu(device.getSerial(), reader);
- enable_rate_menu(device.getSerial(), reader);
+ if (idle_mode) {
+ disable_frequency_menu();
+ disable_rate_menu();
+ } else {
+ enable_frequency_menu(device.getSerial(), reader);
+ enable_rate_menu(device.getSerial(), reader);
+ }
}
}
/* Make the tabbed pane use the rest of the window space */
bag.add(pane, constraints(0, 3, GridBagConstraints.BOTH));
- map = new AltosUIMapNew();
+ map = new AltosUIMap();
pane.add(map.getName(), map);
displays.add(map);
add_window();
}
- public TeleGPS(AltosFlightReader reader) {
+ public TeleGPS(AltosFlightReader reader, boolean idle_mode) {
this();
- set_reader(reader, null);
+ set_reader(reader, null, idle_mode);
}
public TeleGPS(AltosDevice device) {
if (new_reader == null)
return false;
- new TeleGPS(new_reader);
+ new TeleGPS(new_reader, true);
return true;
}
import java.io.*;
import java.util.concurrent.*;
import java.text.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class TeleGPSConfig implements ActionListener {
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class TeleGPSConfigUI
extends AltosUIDialog
}
String get_tracker_motion_label() {
- return String.format("Logging Trigger Motion (%s):", AltosConvert.height.show_units());
+ return String.format("Logging Trigger Motion (%s):", AltosConvert.height.parse_units());
}
void set_tracker_tool_tip() {
import javax.swing.*;
import java.io.*;
import java.text.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class TeleGPSDisplayThread extends Thread {
import java.io.*;
import java.util.concurrent.*;
import java.util.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
JTabbedPane pane;
AltosGraph graph;
AltosUIEnable enable;
- AltosUIMapNew map;
+ AltosUIMap map;
AltosState state;
AltosFlightStats stats;
AltosGraphDataSet graphDataSet;
graph = new AltosGraph(enable, stats, graphDataSet);
statsTable = new AltosFlightStatsTable(stats);
- map = new AltosUIMapNew();
+ map = new AltosUIMap();
pane.add("Graph", graph.panel);
pane.add("Configure Graph", enable);
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class TeleGPSInfo extends AltosUIFlightTab {
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altosuilib_11.*;
public class TeleGPSPreferences
extends AltosUIConfigure
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class TeleGPSState extends AltosUIFlightTab {
class FlightLogMax extends AltosUIIndicator {
public void show(AltosState state, AltosListenerState listener_state) {
- if (state.flight_log_max == AltosLib.MISSING)
+ int storage = state.flight_log_max;
+ if (storage == AltosLib.MISSING)
+ storage = state.log_space >> 10;
+ if (storage == AltosLib.MISSING)
show("Missing");
else
- show(String.format("%dkB", state.flight_log_max));
+ show(String.format("%dkB", storage));
}
public FlightLogMax(Container container, int y) {
import java.awt.*;
import javax.swing.*;
-import org.altusmetrum.altoslib_10.*;
-import org.altusmetrum.altosuilib_10.*;
+import org.altusmetrum.altoslib_11.*;
+import org.altusmetrum.altosuilib_11.*;
public class TeleGPSStatus extends JComponent implements AltosFlightDisplay {
GridBagLayout layout;
package org.altusmetrum.telegps;
import java.awt.event.*;
-import org.altusmetrum.altoslib_10.*;
+import org.altusmetrum.altoslib_11.*;
public class TeleGPSStatusUpdate implements ActionListener {