Android センサーの TYPE_GRAVITY でも少し遊ぶと何が違う? 「う」が違う。
正規重力やら重力異常なんか普通興味ないよね。重力加速度が測れてるなら「水準器もどき」でしょ、やっぱし。
ほれ:
1 title=Gravity Sensor Demo
2 author=hhsprings
3 orientation=all
ほれ:
1 # -*- coding: utf-8 -*-
2 from copy import deepcopy
3 from jnius import PythonJavaClass, java_method, autoclass, cast
4 from plyer.platforms.android import activity
5 from kivy.logger import Logger
6
7 Context = autoclass('android.content.Context')
8 Sensor = autoclass('android.hardware.Sensor')
9 SensorManager = autoclass('android.hardware.SensorManager')
10
11 class _SensorListener(PythonJavaClass):
12 __javainterfaces__ = ['android/hardware/SensorEventListener']
13
14 def __init__(self, sensor_manager, sensor_type):
15 super(_SensorListener, self).__init__()
16 self.SensorManager = sensor_manager
17 self.sensor = self.SensorManager.getDefaultSensor(sensor_type)
18 self.values = None
19
20 def enable(self):
21 self.SensorManager.registerListener(self, self.sensor,
22 SensorManager.SENSOR_DELAY_NORMAL)
23
24 def disable(self):
25 self.SensorManager.unregisterListener(self, self.sensor)
26
27 @java_method('(Landroid/hardware/SensorEvent;)V')
28 def onSensorChanged(self, event):
29 self.values = deepcopy(event.values)
30
31 @java_method('(Landroid/hardware/Sensor;I)V')
32 def onAccuracyChanged(self, sensor, accuracy):
33 # Maybe, do something in future?
34 pass
35
36
37 class GravitySensor(object):
38 def __init__(self):
39 self.SensorManager = cast('android.hardware.SensorManager',
40 activity.getSystemService(Context.SENSOR_SERVICE))
41 self._bState = False
42
43 def enable(self):
44 if not self._bState:
45 self._listener = _SensorListener(
46 self.SensorManager, Sensor.TYPE_GRAVITY)
47 self._listener.enable()
48 #
49 self._bState = True
50
51 def disable(self):
52 if self._bState:
53 self._bState = False
54 #
55 self._listener.disable()
56 del self._listener
57
58 @property
59 def values(self):
60 if self._bState and self._listener.values:
61 return self._listener.values[:3]
62
63 def __del__(self):
64 if self._bState:
65 self._disable()
66 super(self.__class__, self).__del__()
ほれ:
1 # -*- coding: utf-8 -*-
2 import math
3 from kivy.lang import Builder
4 from kivy.app import App
5 from kivy.clock import Clock, mainthread
6 from kivy.properties import StringProperty
7 from kivy.uix.boxlayout import BoxLayout
8 from kivy.graphics import Color, Line, Ellipse
9 from plyer import gps
10 from gravity_sensor import GravitySensor
11 grav_sensor = GravitySensor()
12
13 kv = '''
14 <GravityDemo>:
15 orientation: 'vertical'
16
17 face: face
18 detail_doc: detail_doc
19
20 Widget:
21 id: face
22 r: (min(root.size[0], root.size[1] - detail_doc.height)) / 2
23 canvas.after:
24 Color:
25 rgba: 1, 1, 1, 0.1
26 Ellipse:
27 size: self.size
28 pos: self.pos
29
30 RstDocument:
31 id: detail_doc
32 text: root.result
33 size_hint: 1, None
34 height: 600
35 '''
36 Builder.load_string(kv)
37
38 class GravityDemo(BoxLayout):
39 result = StringProperty()
40 lon = None
41 lat = None
42 alt = None
43
44 def __init__(self):
45 super(GravityDemo, self).__init__()
46
47 grav_sensor.enable()
48 gps.configure(on_location=self.on_location,
49 on_status=self.on_status)
50 gps.start()
51 Clock.schedule_interval(self.do_interval, 1./10)
52
53 @mainthread
54 def on_location(self, **kwargs):
55 #self.lon = float(kwargs['lon'])
56 self.lat = float(kwargs['lat'])
57 #self.alt = float(kwargs['altitude'])
58
59 @mainthread
60 def on_status(self, stype, status):
61 pass
62
63 def do_interval(self, *args, **kwargs):
64 if self.lat is None:
65 return
66
67 gv = grav_sensor.values
68 g = math.sqrt(gv[0]**2 + gv[1]**2 + gv[2]**2)
69
70 self.face.canvas.clear()
71
72 with self.face.canvas:
73 Color(0.7, 0.2, 0.2)
74 pos = (
75 self.face.center_x - self.face.r * gv[0] / g,
76 self.face.center_y - self.face.r * gv[1] / g
77 )
78 Line(points=[
79 self.face.center_x, self.face.center_y,
80 pos[0], pos[1]
81 ], width=5, cap="round")
82 ellips_r = 25
83 Ellipse(pos=[pos[0] - ellips_r,
84 pos[1] - ellips_r],
85 size=[ellips_r * 2, ellips_r * 2])
86 sc = math.sqrt(gv[0]**2 + gv[1]**2)
87 if sc > g / 3:
88 x, y = gv[0] / sc, gv[1] / sc
89 rx = x * math.cos(math.pi / 2) - y * math.sin(math.pi / 2)
90 ry = x * math.sin(math.pi / 2) + y * math.cos(math.pi / 2)
91 Color(0.2, 0.2, 0.7)
92 Line(points=[
93 self.face.center_x - self.face.r * rx,
94 self.face.center_y - self.face.r * ry,
95
96 self.face.center_x + self.face.r * rx,
97 self.face.center_y + self.face.r * ry
98 ], width=2, cap="round")
99
100 # Theoretical gravity (using GRS80)
101 # g(\phi)= 9.780327 \left(1+0.0053024\sin^2(\phi) - 0.0000058\sin^2(2 \phi) \right)\;[\frac{m}{s^2}]
102 gth = 9.780327 * (
103 1.0 + 0.0053024 * math.sin(math.radians(self.lat))**2 - \
104 0.0000058 * math.sin(math.radians(2 * self.lat))**2)
105
106 self.result = """
107 * latitude: {}
108 * observed gravity: {:.6f}
109
110 * X: {:.6f}
111 * Y: {:.6f}
112 * Z: {:.6f}
113
114 * theoretical gravity (using GRS80): {:.6f}
115 * gravity anomaly: {:.6f}
116 """.format(self.lat, g, gv[0], gv[1], gv[2], gth, g - gth)
117
118
119 class GravityDemoApp(App):
120 def build(self):
121 return GravityDemo()
122
123
124 if __name__ == '__main__':
125 GravityDemoApp().run()
ので:
ひたすらにかっちょ悪い GUI だが、気になるなら自分で直しなはれ。
水準器ね、ワタシもたまにこれは欲しいのでいいんだけどね、「正規重力と重力異常」はワタシにとってはオモロイのねん。ので相変わらず表示しとる。普通こんなん興味なかろうから、いらないなら自分で消したまえよ。