needle from magnetometer

This commit is contained in:
rgarcia-herrera 2020-07-16 19:17:49 -05:00
parent 328d8e3ebb
commit 586f1ebcfd
5 changed files with 104 additions and 23 deletions

View File

@ -14,9 +14,9 @@
title: 'Social Cycling' title: 'Social Cycling'
with_previous: False with_previous: False
ActionButton: ActionButton:
important: True important: True
text: 'we ride together' text: 'we ride together'
on_press: root.manager.current = 'compass' on_press: root.manager.current = 'compass'
MapView: MapView:
id: mapview id: mapview
@ -25,14 +25,15 @@
zoom: 15 zoom: 15
on_map_relocated: centermark.lat = mapview.lat; centermark.lon = mapview.lon on_map_relocated: centermark.lat = mapview.lat; centermark.lon = mapview.lon
MapMarker: MapMarker:
id: centermark source: 'marker.png'
id: centermark
anchor_x: 0.2 anchor_x: 0.2
anchor_y: 0.3 anchor_y: 0.3
lat: 28.89335172 lat: 28.89335172
lon: 76.59449171 lon: 76.59449171
<CompassScreen>: <CompassScreen>:
@ -73,9 +74,51 @@
text: str(root.y_calib) + ',' text: str(root.y_calib) + ','
Label: Label:
text: str(root.z_calib) + ')' text: str(root.z_calib) + ')'
Label:
text: app.gps_location
Label:
text: app.gps_status
BoxLayout:
size_hint_y: None
height: '48dp'
padding: '4dp'
ToggleButton:
text: 'Start' if self.state == 'normal' else 'Stop'
on_state:
app.start(1000, 0) if self.state == 'down' else \
app.stop()
FloatLayout:
canvas:
Color:
rgb: .98, .98, .98
Rectangle:
size: self.size
Image:
source: 'rose.png'
Image:
source: 'needle.png'
canvas.before:
PushMatrix
Rotate:
angle: root.needle_angle
axis: 0, 0, 1
origin: self.center
canvas.after:
PopMatrix
# BoxLayout: # BoxLayout:
# orientation: 'vertical' # orientation: 'vertical'
# canvas: # canvas:
# Color: # Color:
# rgb: .98, .98, .98 # rgb: .98, .98, .98
@ -86,9 +129,9 @@
# source: 'rose.png' # source: 'rose.png'
# Image: # Image:
# source: 'needle.png' # source: 'needle.png'
# ActionBar: # ActionBar:
# pos_hint: {'top':1} # pos_hint: {'top':1}
# ActionView: # ActionView:
@ -97,9 +140,9 @@
# title: 'Social Cycling' # title: 'Social Cycling'
# with_previous: False # with_previous: False
# ActionButton: # ActionButton:
# important: True # important: True
# text: 'set destination' # text: 'set destination'
# on_press: root.manager.current = 'map' # on_press: root.manager.current = 'map'
@ -108,4 +151,3 @@
# Label: # Label:
# text: app.gps_status # text: app.gps_status

59
main.py
View File

@ -7,33 +7,57 @@ from kivy_garden.mapview import MapView
from plyer import gps from plyer import gps
from kivy.clock import mainthread from kivy.clock import mainthread
from kivy.utils import platform from kivy.utils import platform
from kivy.vector import Vector
from kivy.animation import Animation
from math import floor
class MapScreen(Screen): class MapScreen(Screen):
hue = NumericProperty(0) hue = NumericProperty(0)
mapview = MapView(zoom=11, lat=50.6394, lon=3.057) mapview = MapView(zoom=11, lat=50.6394, lon=3.057)
class CompassScreen(Screen): class CompassScreen(Screen):
hue = NumericProperty(0) hue = NumericProperty(0)
x_calib = NumericProperty(0) x_calib = NumericProperty(0)
y_calib = NumericProperty(0) y_calib = NumericProperty(0)
z_calib = NumericProperty(0) z_calib = NumericProperty(0)
needle_angle = NumericProperty(0)
def enable(self): def enable(self):
self.facade.enable() self.facade.enable()
Clock.schedule_interval(self.get_field, 1 / 20.) Clock.schedule_interval(self.get_field, 1 / 20.)
gps.start(1000, 0)
def disable(self): def disable(self):
self.facade.disable() self.facade.disable()
Clock.unschedule(self.get_field) Clock.unschedule(self.get_field)
def get_field(self, dt): def get_field(self, dt):
needle_angle = 7
if self.facade.field != (None, None, None): if self.facade.field != (None, None, None):
self.x_calib, self.y_calib, self.z_calib = self.facade.field self.x_calib, self.y_calib, self.z_calib = self.facade.field
x, y, z = self.facade.field
needle_angle = Vector(x, y).angle((0, 1)) + 90.
# fix animation transition around the unit circle
if (self.needle_angle % 360) - needle_angle > 180:
needle_angle += 360
elif (self.needle_angle % 360) - needle_angle < -180:
needle_angle -= 360
# add the number of revolutions to the result
needle_angle += 360 * floor(self.needle_angle / 360.)
# animate the needle
if self._anim:
self._anim.stop(self)
self._anim = Animation(needle_angle=needle_angle, d=.2, t='out_quad')
self._anim.start(self)
class FlockompassApp(App): class FlockompassApp(App):
gps_location = StringProperty() gps_location = StringProperty()
@ -52,6 +76,20 @@ class FlockompassApp(App):
Permission.ACCESS_FINE_LOCATION], Permission.ACCESS_FINE_LOCATION],
callback) callback)
def start(self, minTime, minDistance):
gps.start(minTime, minDistance)
def stop(self):
gps.stop()
def on_pause(self):
gps.stop()
return True
def on_resume(self):
gps.start(1000, 0)
@mainthread @mainthread
def on_location(self, **kwargs): def on_location(self, **kwargs):
self.gps_location = '\n'.join([ self.gps_location = '\n'.join([
@ -60,8 +98,8 @@ class FlockompassApp(App):
@mainthread @mainthread
def on_status(self, stype, status): def on_status(self, stype, status):
self.gps_status = 'type={}\n{}'.format(stype, status) self.gps_status = 'type={}\n{}'.format(stype, status)
def build(self): def build(self):
try: try:
@ -75,11 +113,13 @@ class FlockompassApp(App):
if platform == "android": if platform == "android":
print("gps.py: Android detected. Requesting permissions") print("gps.py: Android detected. Requesting permissions")
self.request_android_permissions() self.request_android_permissions()
root = ScreenManager(transition=RiseInTransition()) root = ScreenManager(transition=RiseInTransition())
root.add_widget(MapScreen(name='map')) root.add_widget(MapScreen(name='map'))
root.add_widget(CompassScreen(name='compass')) cs = CompassScreen(name='compass')
cs._anim = None
root.add_widget(cs)
return root return root
@ -96,4 +136,3 @@ if __name__ == '__main__':
# Button: # Button:
# text: 'Use RiseInTransition' # text: 'Use RiseInTransition'
# on_release: root.manager.transition = RiseInTransition() # on_release: root.manager.transition = RiseInTransition()

BIN
marker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
needle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
rose.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB