ekfsm 0.11.0b1.post3__py3-none-any.whl → 0.12.0.post1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ekfsm might be problematic. Click here for more details.

@@ -66,3 +66,5 @@ children:
66
66
  sysstate:
67
67
  - wd_trigger
68
68
  - sw_shutdown
69
+ imu:
70
+ - sample: imu_sample
@@ -0,0 +1,41 @@
1
+ id: 69
2
+ name: "EKF SQ3-QUARTET"
3
+ slot_type: CPCI_S0_PER
4
+ children:
5
+ - device_type: I2CMux
6
+ name: "MUX"
7
+ addr: 0x70
8
+ slot_coding_mask: 0x07
9
+ children:
10
+ - device_type: MuxChannel
11
+ name: "CH00"
12
+ channel_id: 0
13
+ children:
14
+ - device_type: EKFIdentificationIOExpander
15
+ name: "GPIO"
16
+ addr: 0x3D
17
+ provides:
18
+ inventory:
19
+ - revision
20
+ - device_type: EKF_EEPROM
21
+ name: "EEPROM"
22
+ addr: 0x55
23
+ provides:
24
+ inventory:
25
+ - vendor
26
+ - serial
27
+ - model
28
+ - repaired_at
29
+ - manufactured_at
30
+ - device_type: MuxChannel
31
+ name: "CH01"
32
+ channel_id: 1
33
+ children:
34
+ - device_type: MuxChannel
35
+ name: "CH02"
36
+ channel_id: 2
37
+ children:
38
+ - device_type: MuxChannel
39
+ name: "CH03"
40
+ channel_id: 3
41
+ children:
ekfsm/core/components.py CHANGED
@@ -90,8 +90,11 @@ class HwModule(SystemComponent):
90
90
 
91
91
  nodes = findall(self, lambda node: isinstance(node, ProbeableDevice))
92
92
  for node in nodes:
93
- if node.probe(*args, **kwargs):
94
- return True
93
+ try:
94
+ if node.probe(*args, **kwargs):
95
+ return True
96
+ except Exception as e:
97
+ self.logger.error(f"Error probing {node}: {e}")
95
98
 
96
99
  return False
97
100
 
@@ -4,6 +4,7 @@ from enum import Enum
4
4
  from typing import Tuple
5
5
  from ekfsm.core.components import SystemComponent
6
6
  from ..exceptions import AcquisitionError
7
+ from .imu import ImuSample
7
8
  import struct
8
9
 
9
10
 
@@ -163,6 +164,68 @@ class EKFCcuUc(Device):
163
164
  self._i2c_addr, CcuCommands.PUSH_TEMPERATURE.value, list(data)
164
165
  )
165
166
 
167
+ def imu_sample(self) -> Tuple[ImuSample | None, bool]:
168
+ """
169
+ Read the next IMU sample from the CCU's IMU sample FIFO.
170
+
171
+ If no sample is available, this method returns None.
172
+ The second return value indicates if more samples are available in the FIFO.
173
+
174
+ The CCU periodically samples the accelerometer and gyroscope data from the IMU and
175
+ places it into a FIFO of 256 entries.
176
+ Application must periodically read the samples from the FIFO to avoid overflow.
177
+
178
+ FIFO overflow is indicated in the sample by the `lost` attribute.
179
+
180
+ Note that the x, y, and z axes of the accelerometer and gyroscope
181
+ are aligned to the mounting of the IMU on the CCU board. Please correct the axes if necessary
182
+ to match the orientation of the IMU in your application.
183
+
184
+ Returns
185
+ -------
186
+ Tuple[ImuSample | None, bool]
187
+ The IMU sample (or None) and a flag indicating if more samples are available in the FIFO.
188
+ """
189
+ more_samples = False
190
+ _data = self._smbus.read_block_data(
191
+ self._i2c_addr, CcuCommands.IMU_SAMPLES.value
192
+ )
193
+ data = bytes(_data)
194
+ if len(data) < 14:
195
+ return None, False # No data available
196
+ diag, fsr, acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z = struct.unpack(
197
+ "<BBhhhhhh", data
198
+ )
199
+ imu_data = ImuSample(
200
+ [
201
+ self._scale_imu_accel(acc_x, fsr),
202
+ self._scale_imu_accel(acc_y, fsr),
203
+ self._scale_imu_accel(acc_z, fsr),
204
+ ],
205
+ [
206
+ self._scale_imu_gyro(gyro_x, fsr),
207
+ self._scale_imu_gyro(gyro_y, fsr),
208
+ self._scale_imu_gyro(gyro_z, fsr),
209
+ ],
210
+ True if diag & 1 else False,
211
+ )
212
+
213
+ more_samples = True if (diag & 2 != 0) else False
214
+
215
+ return imu_data, more_samples
216
+
217
+ @staticmethod
218
+ def _scale_imu_accel(val: int, fsr: int) -> float:
219
+ fsr = fsr & 0xF
220
+ scale = 16 / (1 << fsr)
221
+ return val * (scale / 32768) * 9.80665 # convert to m/s^2
222
+
223
+ @staticmethod
224
+ def _scale_imu_gyro(val: int, fsr: int) -> float:
225
+ fsr = fsr >> 4 & 0xF
226
+ scale = 2000 / (1 << fsr)
227
+ return val * (scale / 32768)
228
+
166
229
  def sw_shutdown(self) -> None:
167
230
  """
168
231
  Tell CCU that the system is going to shutdown.
@@ -316,6 +379,9 @@ class EKFCcuUc(Device):
316
379
  chunk = self._get_parameterset_chunk(begin)
317
380
  if len(chunk) < 32:
318
381
  break
382
+ # if chunk ends with zero byte, remove it (workaround for I2C slave bug)
383
+ if chunk[-1] == 0:
384
+ chunk = chunk[:-1]
319
385
  json += chunk
320
386
  begin = False
321
387
  return json.decode("utf-8")
ekfsm/devices/gpio.py CHANGED
@@ -214,6 +214,7 @@ class EKFIdentificationIOExpander(GPIOExpander, ProbeableDevice):
214
214
 
215
215
  assert isinstance(self.root, HwModule)
216
216
  id, _ = self.read_board_id_rev()
217
+ self.logger.debug(f"Probing EKFIdentificationIOExpander: {id}")
217
218
 
218
219
  return self.root.id == id
219
220
 
ekfsm/devices/imu.py ADDED
@@ -0,0 +1,14 @@
1
+ class ImuSample:
2
+ """
3
+ Class to store IMU data sample
4
+
5
+ * accel: list[float] - Accelerometer data in m/s^2, [x, y, z]
6
+ * gyro: list[float] - Gyroscope data in degrees/s, [x, y, z]
7
+ * lost: bool - True if data was lost before that sample
8
+
9
+ """
10
+
11
+ def __init__(self, accel: list[float], gyro: list[float], lost: bool):
12
+ self.accel = accel
13
+ self.gyro = gyro
14
+ self.lost = lost
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ekfsm
3
- Version: 0.11.0b1.post3
3
+ Version: 0.12.0.post1
4
4
  Summary: The EKF System Management Library (ekfsm) is a sensor monitoring suite for Compact PCI Serial devices.
5
5
  Author-email: Klaus Popp <klaus.popp@ci4rail.com>, Jan Jansen <jan@ekf.de>, Felix Päßler <fp@ekf.de>
6
6
  Requires-Python: >=3.10
@@ -6,34 +6,36 @@ ekfsm/log.py,sha256=_GC8Y7a4fFV4_DNicbwQ-5rRzNQU6WSotXd2etXSrZk,866
6
6
  ekfsm/py.typed,sha256=1gNRtmxvYcVqDDEyAzBLnD8dAOweUfYxW2ZPdJzN1fg,102
7
7
  ekfsm/simctrl.py,sha256=dD7pO7EBTiWwSP8ZrGf9-H69g4yDQE3hGtQn5Y3MR1w,7002
8
8
  ekfsm/system.py,sha256=_4jkaoikSY5SbHtrzuwiAInE9EnorDh1IampC5v-gHw,10732
9
- ekfsm/boards/oem/ekf/ccu.yaml,sha256=WgENJDHBYFgUoiYxl4DNv5f6Mz_5oMA-cyD0y1aHvkg,2034
9
+ ekfsm/boards/oem/ekf/ccu.yaml,sha256=qgr7YZO0kEddD9K6tv6222NyozkRNuF7NFw6hyX0XgE,2094
10
10
  ekfsm/boards/oem/ekf/sc5-festival.yaml,sha256=_0kS5GegfyOt5CTJc9kY6HJbr9yZo4i18sVo6F4KE9c,772
11
11
  ekfsm/boards/oem/ekf/sc9-toccata.yaml,sha256=btLgQMSsW0tRipnUYUkVQSIsjzxfKq0NXaQ1fMMyBRI,771
12
12
  ekfsm/boards/oem/ekf/spv-mystic.yaml,sha256=zcLiNE7wVdXIT4vkwEYSqQ8ff-KEjCHfHnQzzPXJQ4E,1804
13
13
  ekfsm/boards/oem/ekf/sq1-track.yaml,sha256=YU83BQjGu-4ejirwnGxd38sJme859kdRovkZyiOJciU,1050
14
+ ekfsm/boards/oem/ekf/sq3-quartet.yaml,sha256=pBB7Tv0IWLkFUYBs3tFvZriA-uqPuPIgzjaN0aHT4e4,1052
14
15
  ekfsm/boards/oem/ekf/srf-fan.yaml,sha256=Mcu1Q8B1Ih10hoc_hbkGlppBmbOFcufsVUR42iW4Rwc,1368
15
16
  ekfsm/boards/oem/ekf/sur-uart.yaml,sha256=VaNP2BSlNTi1lDco16Ma9smPEAMaVKvx-ZNDcm3QptM,1890
16
17
  ekfsm/boards/oem/hitron/hdrc-300.yaml,sha256=juRO3ahLNNqCH099-QJGQRWRh5qg-brAob0maJ0R5tY,427
17
18
  ekfsm/core/__init__.py,sha256=nv3Rs-E953M9PBFV9ryejRY-KM6xG1NMlQTWwzCEQwo,212
18
- ekfsm/core/components.py,sha256=yCHU88DF4ECjzHiJ9ofg_ic7oX6dm3ACIbV7Ve6At_o,3558
19
+ ekfsm/core/components.py,sha256=_b48cXuOhAtczp_Ykekt1r5nNlrddSOXS6lMfWCFyp8,3682
19
20
  ekfsm/core/probe.py,sha256=DgJvkvMjVk09n0Rzn13ybRvidrmFn_D2PD56XS-KgxU,262
20
21
  ekfsm/core/slots.py,sha256=WOKYO-8TfpWexu3DsSjrYTvjtN4pAMiy22zMjjUI-qQ,6569
21
22
  ekfsm/core/sysfs.py,sha256=iW_XWtEjW7pZqpJc_RyMzhVjbetw0ydTH11lhfxrPbc,2541
22
23
  ekfsm/core/utils.py,sha256=RYX-rd0pBBXvwjyInDFD8BKZppIBvln9sT4o4kRRcMk,2504
23
24
  ekfsm/devices/__init__.py,sha256=h3pE3yPnquTIykpi7yxoTJOJ8YfVh_PqGiFMJGpXdCs,888
24
25
  ekfsm/devices/eeprom.py,sha256=ubeext9PC6FDQ1qoaYZp3ZNRlEhPYBzTe1oXJdm4qtU,31029
25
- ekfsm/devices/ekf_ccu_uc.py,sha256=H5nt51cu8oTPos-SYmoDvVioG4QoFs11XX7LiUySLwQ,12796
26
+ ekfsm/devices/ekf_ccu_uc.py,sha256=V3xwL156Y9akgRohl8HCR2FuvklPW65hapkLa_nSlko,15268
26
27
  ekfsm/devices/ekf_sur_led.py,sha256=KPr75RVQQKEUWj5gP0ciSJam9jWniG1ew3k_62onwrE,1887
27
28
  ekfsm/devices/generic.py,sha256=LuNpf0sn-TwZ1nkJc3Shu4-07mAhQIc6-CJwu7cNZwc,9273
28
- ekfsm/devices/gpio.py,sha256=6ofOlOm7toAHb7J2FSYqs0Wu8lhShCHDAWA0rhsZJLI,9510
29
+ ekfsm/devices/gpio.py,sha256=EXUcfxG8p8-B4ym4CFNwqT563Rp-roDNMs2Xlm4KzhU,9582
29
30
  ekfsm/devices/hwmon.py,sha256=EXBFTE6QfhpA-Xb7CnhlR_fVGIjw5tWt3JzrtkXKGic,1987
30
31
  ekfsm/devices/iio.py,sha256=gMOJGdg2PvFbAvlBpLfDTIc_-9i1Z3OLpuabTke6N3I,1480
31
32
  ekfsm/devices/iio_thermal_humidity.py,sha256=YjXHI2AXSDpAuAGHYc_Kk7wMO9LGimHSXnARw4rxYJ0,1212
33
+ ekfsm/devices/imu.py,sha256=bnSaTjGSLV90FyUbkK9oTon0dmF7N_JQ4uGmBPFA5Co,414
32
34
  ekfsm/devices/mux.py,sha256=mFd0Tr5XQp6MIMNV1xpsQETrELWkvx1ZTSAemiUasoU,1042
33
35
  ekfsm/devices/pmbus.py,sha256=Zf3JfMX1VTmmU2hoZkqOR9UTZcNRvnbqhhOlZ4sdoX4,2033
34
36
  ekfsm/devices/smbios.py,sha256=KC1D2dSRaertYLeMFF6C9hQUI_RcTzVdtQ1qh8Hbces,985
35
37
  ekfsm/devices/utils.py,sha256=4-0Kmvy4ou8R71afNj6RqdBTjLW4SMWPHqVrzB2RUZw,397
36
- ekfsm-0.11.0b1.post3.dist-info/METADATA,sha256=9gZmLcYKM0u-vjRTMXY9Fi6NzMssPZUpoD6CJZbyyOQ,3370
37
- ekfsm-0.11.0b1.post3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
38
- ekfsm-0.11.0b1.post3.dist-info/entry_points.txt,sha256=WhUR4FzuxPoGrbTOKLsNJO7NAnk2qd4T30fqzN1yLw8,45
39
- ekfsm-0.11.0b1.post3.dist-info/RECORD,,
38
+ ekfsm-0.12.0.post1.dist-info/METADATA,sha256=qslFxdmq98DMVXMIClGyL2DaZmbH95mE1hrkpikj0as,3368
39
+ ekfsm-0.12.0.post1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
40
+ ekfsm-0.12.0.post1.dist-info/entry_points.txt,sha256=WhUR4FzuxPoGrbTOKLsNJO7NAnk2qd4T30fqzN1yLw8,45
41
+ ekfsm-0.12.0.post1.dist-info/RECORD,,