-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathims_device.py
More file actions
1918 lines (1623 loc) · 70.2 KB
/
Copy pathims_device.py
File metadata and controls
1918 lines (1623 loc) · 70.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
"""
IMS-SDデバイス接続管理モジュール
"""
import time
from typing import Optional, Tuple
from serial_comm import SerialCommunication
from enum import Enum
class DeviceStatus(Enum):
"""デバイス状態"""
NO_DEVICE = "NoDevice"
INITIALIZE = "Initialize"
IDLE = "IDLE"
MEASURE = "MEASURE"
EXT = "EXT"
LOAD_DATA = "LOAD_DATA"
ERR = "ERR"
class ImsDevice:
"""IMS-SDデバイス接続クラス"""
def __init__(self):
self.serial = SerialCommunication()
self.status = DeviceStatus.NO_DEVICE
self.is_connected = False
# デバイス情報
self.serial_number = ""
self.version = ""
self.step_number = 0
self.model = "HighEnd" # モデル (Standard/HighEnd)
self.device_type = "" # デバイスタイプ
# センサー設定
self.frequency = 100 # 測定周波数 [Hz]
self.matome_pc = 1 # PCまとめ数
self.matome_sd = 1 # SDまとめ数
self.acc_range = 2 # 加速度レンジ [G]
self.gyro_range = 4000 # ジャイロレンジ [deg/s]
self.acc_bw = 250 # 加速度センサーバンド帯域 [Hz]
self.gyro_bw = 200 # ジャイロセンサーバンド帯域 [Hz]
self.save_to_flash = False # SD保存有効/無効
self.sd_exist = False # SDカード有無
self.header = "" # ファイルヘッダ
self.save_time = 0 # 保存時間 [秒]
self.soc_meas_stop_en = False # 電池残量で測定停止する機能の有効/無効
self.meas_stop_soc = 0 # 測定停止する電池残量 [%]
self.pwr_on_st_en = False # 電源オン時測定開始機能の有効/無効
self.save_interval = 0 # データ保存間隔 [秒]
self.error_code = "" # エラーコード
# 校正値(辞書形式で格納)
self.acc_prf = {} # 加速度校正値 {range: {axis: value}}
self.acc_zero = {} # 加速度ゼロ点 {range: {axis: value}}
self.acc_itf = {} # 加速度干渉補正 {range: [9個の値]}
self.gyro_prf = {} # ジャイロ校正値 {range: {axis: value}}
self.gyro_zero = {} # ジャイロゼロ点 {range: {axis: value}}
self.gyro_itf = {} # ジャイロ干渉補正 {range: [9個の値]}
self.mag_zero = {} # 地磁気ゼロ点 {axis: value}
self.mag_prf = {} # 地磁気校正値 {axis: value}
self.mag_itf = [] # 地磁気干渉補正 [9個の値]
self.mag_offzero = {} # 地磁気OFFSETZERO {axis: value}
self.mag_off = {} # 地磁気OFFSET {axis: value}
self.mag_fineout = {} # 地磁気FINEOUTPUT {axis: value}
self.mag_sens = {} # 地磁気SENSITIVITY {axis: value}
self.mag_gainpara = [] # 地磁気GAINPARA [6個の値]
def connect(self, port_name: str) -> bool:
"""
デバイスに接続
Args:
port_name: COMポート名 (例: "COM3")
Returns:
bool: 接続成功時True
"""
print(f"接続処理開始: {port_name}")
# ポートオープン
if not self.serial.open_port(port_name):
print("ポートオープンに失敗")
self.status = DeviceStatus.NO_DEVICE
return False
self.status = DeviceStatus.INITIALIZE
print("ポートオープン成功")
# 測定中や処理中の場合を考慮してSTOP/LOAD_STOPコマンド送信
self._send_command("STOP")
self._send_command("LOAD_STOP")
# 未受信データが送信される可能性があるため500ms待機後バッファクリア
time.sleep(0.5)
self.serial.clear_buffers()
# デバイスパラメータ取得
print("デバイスパラメータ取得開始")
if self._get_parameters():
print("デバイスパラメータ取得成功")
self.status = DeviceStatus.IDLE
self.is_connected = True
return True
else:
print("デバイスパラメータ取得失敗")
self.disconnect()
return False
def disconnect(self) -> bool:
"""
デバイスから切断
Returns:
bool: 切断成功時True
"""
if self.is_connected:
self._send_command("STOP")
self._send_command("LOAD_STOP")
time.sleep(0.1)
result = self.serial.close_port()
self.status = DeviceStatus.NO_DEVICE
self.is_connected = False
# デバイス情報クリア
self.serial_number = ""
self.version = ""
self.step_number = 0
return result
def _send_command(self, command: str) -> bool:
"""
コマンド送信(内部使用)
Args:
command: 送信するコマンド文字列
Returns:
bool: 送信成功時True
"""
# コマンドは改行(LF)で終端
data = (command + "\n").encode('ascii')
return self.serial.write_bytes(data)
def _read_response(self, timeout: float = 1.0) -> Optional[str]:
"""
レスポンス読み込み(内部使用)
Args:
timeout: タイムアウト時間(秒)
Returns:
str: レスポンス文字列、タイムアウト時None
"""
start_time = time.time()
response = b''
while time.time() - start_time < timeout:
data = self.serial.read_available()
if data:
response += data
# 改行で終端されたら完了
if b'\n' in response:
try:
return response.decode('ascii').strip()
except:
return None
time.sleep(0.01)
return None
def _send_and_receive(self, command: str, timeout: float = 1.0) -> Tuple[bool, str]:
"""
コマンド送信とレスポンス受信
Args:
command: 送信するコマンド
timeout: タイムアウト時間(秒)
Returns:
Tuple[bool, str]: (成功フラグ, レスポンス文字列)
"""
# バッファクリア
self.serial.clear_buffers()
# コマンド送信
if not self._send_command(command):
return (False, "")
# レスポンス受信
response = self._read_response(timeout)
if response is None:
return (False, "")
return (True, response)
def _get_parameters(self) -> bool:
"""
デバイスパラメータ取得
Returns:
bool: 取得成功時True
"""
# STATUS取得でデバイス状態確認
success, status_response = self._send_and_receive("GET_STATUS")
if success and status_response.startswith("STATUS_"):
status = status_response.replace("STATUS_", "")
print(f"デバイス状態: {status}")
# MEASURE、EXTの場合はSTOPコマンド送信
if status in ["MEASURE", "EXT"]:
self._send_command("STOP")
time.sleep(0.1)
# LOAD_DATAの場合はLOAD_STOPコマンド送信
if status == "LOAD_DATA":
self._send_command("LOAD_STOP")
time.sleep(0.1)
else:
print("STATUS取得失敗")
return False
# 基本情報取得
if not self._get_serial():
return False
if not self._get_version():
return False
# バージョンチェック(2.2.0未満はエラー)
if not self._check_version():
return False
# モデル取得
if not self._get_model():
return False
# モデルチェック(HighEndでない場合はエラー)
if not self._check_model():
return False
# ステップ番号取得
if not self._get_step_number():
return False
# 共通パラメータ取得
if not self._get_frequency():
return False
if not self._get_matome():
return False
# センサー設定取得
if not self._get_sensor_range():
return False
# 校正値取得
if not self._get_calibration_values():
return False
# SD保存設定取得
if not self._get_save_settings():
return False
if not self._get_header():
return False
if not self._get_save_time():
return False
# 電池管理設定取得
if not self._get_soc_meas_stop_en():
return False
if not self._get_meas_stop_soc():
return False
# デバイスタイプ取得
if not self._get_device_type():
return False
# ICMセンサー帯域設定
success, response = self._send_and_receive("GET_ICM_ACC_BW")
if success and response.startswith("ICM_ACC_BW_"):
try:
bw_code = int(response.replace("ICM_ACC_BW_", ""))
bw_map = {0: 50, 1: 110, 2: 250, 3: 500}
self.acc_bw = bw_map.get(bw_code, 250)
print(f"加速度バンド帯域: {self.acc_bw} Hz")
except:
return False
else:
return False
success, response = self._send_and_receive("GET_ICM_GYRO_BW")
if success and response.startswith("ICM_GYRO_BW_"):
try:
bw_code = int(response.replace("ICM_GYRO_BW_", ""))
bw_map = {0: 50, 1: 120, 2: 200, 3: 400}
self.gyro_bw = bw_map.get(bw_code, 200)
print(f"ジャイロバンド帯域: {self.gyro_bw} Hz")
except:
return False
else:
return False
# 地磁気追加パラメータ取得
if not self._get_mag_additional_params():
return False
# 地磁気センサーオフセット値調整
is_over_range = False
for axis in ['X', 'Y', 'Z']:
if axis in self.mag_off:
offset_value = self.mag_off[axis]
if offset_value < 35 or 55 < offset_value:
is_over_range = True
break
# 電源オン時測定開始機能取得
if not self._get_pwr_on_st_en():
return False
# データ保存間隔取得
if not self._get_save_interval():
return False
# 地磁気オフセット値調整処理
if is_over_range:
print("地磁気オフセット値が範囲外のため調整が必要です")
print("オフセット値調整処理を開始")
# オフセット値が大きい場合の調整コマンド(3回実行)
for count in range(3):
print(f"MAG_WINDOW実行 ({count + 1}/3)")
if self._send_command("MAG_WINDOW"):
print("MAG_WINDOW成功")
else:
print("MAG_WINDOW失敗")
break
time.sleep(0.1)
# 調整後のオフセット値を再取得
print("オフセット値を再取得")
if self._get_mag_off():
print("オフセット値調整完了")
else:
print("オフセット値再取得失敗")
# ステータス取得
if not self._get_status():
return False
# エラー取得
if not self._get_error():
return False
return True
def _get_serial(self) -> bool:
"""シリアル番号取得"""
success, response = self._send_and_receive("GET_SERIAL")
if success and response.startswith("SERIAL_"):
self.serial_number = response.replace("SERIAL_", "")
print(f"シリアル番号: {self.serial_number}")
return True
return False
def _get_version(self) -> bool:
"""バージョン取得"""
success, response = self._send_and_receive("GET_VERSION")
if success and response.startswith("VERSION_"):
self.version = response.replace("VERSION_", "")
print(f"バージョン: {self.version}")
return True
return False
def _get_step_number(self) -> bool:
"""ステップ番号取得"""
success, response = self._send_and_receive("GET_STEP_NUMBER")
if success and response.startswith("STEP_NUMBER_"):
try:
self.step_number = int(response.replace("STEP_NUMBER_", ""))
print(f"ステップ番号: {self.step_number}")
return True
except Exception as e:
print(f"ステップ番号変換エラー: {e}")
return False
def _get_device_type(self) -> bool:
"""デバイスタイプ取得"""
success, response = self._send_and_receive("GET_TYPE")
if success and response.startswith("TYPE_"):
self.device_type = response.replace("TYPE_", "")
print(f"デバイスタイプ: {self.device_type}")
return True
return False
def _get_model(self) -> bool:
"""モデル取得"""
success, response = self._send_and_receive("GET_MS_SD_MODEL")
if success and response.startswith("MS_SD_MODEL_"):
try:
model_code = int(response.replace("MS_SD_MODEL_", ""))
if model_code == 0:
self.model = "Standard"
elif model_code == 1:
self.model = "HighEnd"
else:
self.model = "Unknown"
print(f"モデル: {self.model}")
return True
except:
pass
return False
def _check_version(self) -> bool:
"""バージョンチェック(2.2.0未満はエラー)"""
try:
# "Ver.2.2.0" の形式から数値部分を抽出
version_str = self.version.replace("Ver.", "").strip()
version_parts = version_str.split(".")
if len(version_parts) >= 3:
major = int(version_parts[0])
minor = int(version_parts[1])
patch = int(version_parts[2])
# 2.2.0未満かチェック
if major < 2 or (major == 2 and minor < 2):
print(f"エラー: バージョン {self.version} は対応していません(2.2.0以上が必要)")
return False
print(f"バージョンチェック: OK ({self.version})")
return True
else:
print(f"エラー: バージョン形式が不正です ({self.version})")
return False
except Exception as e:
print(f"エラー: バージョンチェック失敗 ({e})")
return False
def _check_model(self) -> bool:
"""モデルチェック(HighEndでない場合はエラー)"""
if self.model != "HighEnd":
print(f"エラー: モデル {self.model} は対応していません(HighEndが必要)")
return False
print(f"モデルチェック: OK ({self.model})")
return True
def _get_calibration_values(self) -> bool:
"""校正値取得"""
# 加速度校正値取得
if not self._get_acc_prf():
return False
# 加速度ゼロ点取得
if not self._get_acc_zero():
return False
# 加速度干渉補正取得
if not self._get_acc_itf():
return False
# ジャイロ校正値取得
if not self._get_gyro_prf():
return False
# ジャイロゼロ点取得
if not self._get_gyro_zero():
return False
# ジャイロ干渉補正取得
if not self._get_gyro_itf():
return False
# 地磁気ゼロ点取得
if not self._get_mag_zero():
return False
# 地磁気校正値取得
if not self._get_mag_prf():
return False
# 地磁気干渉補正取得
if not self._get_mag_itf():
return False
# 地磁気追加パラメータ取得
if not self._get_mag_additional_params():
return False
return True
def _get_acc_prf(self) -> bool:
"""加速度校正値取得"""
success, response = self._send_and_receive("GET_ACC_PRF")
if success and response.startswith("ACC_PRF_"):
try:
# データ部分を抽出(カンマ区切りの数値)
data_str = response.replace("ACC_PRF_", "")
values = [float(x.strip()) for x in data_str.split(",")]
# レンジ×軸の組み合わせで格納
ranges = [2, 4, 8, 16, 30] # G2, G4, G8, G16, G30
axes = ['X', 'Y', 'Z']
self.acc_prf = {}
for i, range_val in enumerate(ranges):
if self.model == "Standard" and range_val == 30:
continue # Standardモデルは30Gなし
self.acc_prf[range_val] = {}
for j, axis in enumerate(axes):
idx = i * 3 + j
if idx < len(values):
self.acc_prf[range_val][axis] = values[idx]
print(f"加速度校正値取得完了 ({len(values)}個)")
return True
except Exception as e:
print(f"加速度校正値解析エラー: {e}")
pass
return False
def _get_acc_zero(self) -> bool:
"""加速度ゼロ点取得"""
success, response = self._send_and_receive("GET_ACC_ZERO")
if success and response.startswith("ACC_ZERO_"):
try:
# データ部分を抽出(カンマ区切りの数値)
data_str = response.replace("ACC_ZERO_", "")
values = [float(x.strip()) for x in data_str.split(",")]
# レンジ×軸の組み合わせで格納
ranges = [2, 4, 8, 16, 30] # G2, G4, G8, G16, G30
axes = ['X', 'Y', 'Z']
self.acc_zero = {}
for i, range_val in enumerate(ranges):
if self.model == "Standard" and range_val == 30:
continue # Standardモデルは30Gなし
self.acc_zero[range_val] = {}
for j, axis in enumerate(axes):
idx = i * 3 + j
if idx < len(values):
self.acc_zero[range_val][axis] = values[idx]
print(f"加速度ゼロ点取得完了 ({len(values)}個)")
return True
except Exception as e:
print(f"加速度ゼロ点解析エラー: {e}")
pass
return False
def _get_acc_itf(self) -> bool:
"""加速度干渉補正取得"""
ranges = [2, 4, 8, 16, 30] # G2, G4, G8, G16, G30
range_codes = [0, 1, 2, 3, 4] # コマンドで使用するコード
self.acc_itf = {}
for i, range_val in enumerate(ranges):
if self.model == "Standard" and range_val == 30:
continue # Standardモデルは30Gなし
# コマンド形式: GET_ACC_ITF_<range_code>
success, response = self._send_and_receive(f"GET_ACC_ITF_{range_codes[i]}")
if success and response.startswith("ACC_ITF_"):
try:
# データ部分を抽出(カンマ区切りの数値)
# レスポンス形式: ACC_ITF_1,0,0,0,1,0,0,0,1 (ヘッダー + 9個のパラメータ)
data_part = response.replace("ACC_ITF_", "") # ヘッダーを除去
values = [float(x.strip()) for x in data_part.split(",")] # 9個のパラメータ
if len(values) == 9: # 9個のパラメータ
self.acc_itf[range_val] = values
except Exception as e:
print(f"加速度干渉補正解析エラー (±{range_val}G): {e}")
return False
else:
print(f"加速度干渉補正取得失敗 (±{range_val}G)")
return False
print(f"加速度干渉補正取得完了 ({len(self.acc_itf)}レンジ)")
return True
def _get_gyro_prf(self) -> bool:
"""ジャイロ校正値取得"""
success, response = self._send_and_receive("GET_GYRO_PRF")
if success and response.startswith("GYRO_PRF_"):
try:
# データ部分を抽出(カンマ区切りの数値)
data_str = response.replace("GYRO_PRF_", "")
values = [float(x.strip()) for x in data_str.split(",")]
# レンジ×軸の組み合わせで格納
ranges = [125, 250, 500, 1000, 2000, 4000] # deg/s
axes = ['X', 'Y', 'Z']
self.gyro_prf = {}
for i, range_val in enumerate(ranges):
self.gyro_prf[range_val] = {}
for j, axis in enumerate(axes):
idx = i * 3 + j
if idx < len(values):
self.gyro_prf[range_val][axis] = values[idx]
print(f"ジャイロ校正値取得完了 ({len(values)}個)")
return True
except Exception as e:
print(f"ジャイロ校正値解析エラー: {e}")
pass
return False
def _get_gyro_zero(self) -> bool:
"""ジャイロゼロ点取得"""
success, response = self._send_and_receive("GET_GYRO_ZERO")
if success and response.startswith("GYRO_ZERO_"):
try:
# データ部分を抽出(カンマ区切りの数値)
data_str = response.replace("GYRO_ZERO_", "")
values = [float(x.strip()) for x in data_str.split(",")]
# レンジ×軸の組み合わせで格納
ranges = [125, 250, 500, 1000, 2000, 4000] # deg/s
axes = ['X', 'Y', 'Z']
self.gyro_zero = {}
for i, range_val in enumerate(ranges):
self.gyro_zero[range_val] = {}
for j, axis in enumerate(axes):
idx = i * 3 + j
if idx < len(values):
self.gyro_zero[range_val][axis] = values[idx]
print(f"ジャイロゼロ点取得完了 ({len(values)}個)")
return True
except Exception as e:
print(f"ジャイロゼロ点解析エラー: {e}")
pass
return False
def _get_gyro_itf(self) -> bool:
"""ジャイロ干渉補正取得"""
ranges = [125, 250, 500, 1000, 2000, 4000] # deg/s
range_codes = [0, 1, 2, 3, 4, 5] # コマンドで使用するコード
self.gyro_itf = {}
for i, range_val in enumerate(ranges):
# コマンド形式: GET_GYRO_ITF_<range_code>
success, response = self._send_and_receive(f"GET_GYRO_ITF_{range_codes[i]}")
if success and response.startswith("GYRO_ITF_"):
try:
# データ部分を抽出(カンマ区切りの数値)
# レスポンス形式: GYRO_ITF_1,0,0,0,1,0,0,0,1 (ヘッダー + 9個のパラメータ)
data_part = response.replace("GYRO_ITF_", "") # ヘッダーを除去
values = [float(x.strip()) for x in data_part.split(",")] # 9個のパラメータ
if len(values) == 9: # 9個のパラメータ
self.gyro_itf[range_val] = values
except Exception as e:
print(f"ジャイロ干渉補正解析エラー (±{range_val}deg/s): {e}")
return False
else:
print(f"ジャイロ干渉補正取得失敗 (±{range_val}deg/s)")
return False
print(f"ジャイロ干渉補正取得完了 ({len(self.gyro_itf)}レンジ)")
return True
def _get_mag_zero(self) -> bool:
"""地磁気ゼロ点取得"""
success, response = self._send_and_receive("GET_MAG_ZERO")
if success and response.startswith("MAG_ZERO_"):
try:
# データ部分を抽出(カンマ区切りの数値)
# レスポンス形式: MAG_ZERO_x,x,x (X, Y, Z軸)
data_str = response.replace("MAG_ZERO_", "")
values = [float(x.strip()) for x in data_str.split(",")]
if len(values) == 3: # X, Y, Z軸
axes = ['X', 'Y', 'Z']
self.mag_zero = {}
for i, axis in enumerate(axes):
self.mag_zero[axis] = values[i]
print(f"地磁気ゼロ点取得完了 ({len(values)}軸)")
return True
except Exception as e:
print(f"地磁気ゼロ点解析エラー: {e}")
pass
return False
def _get_mag_prf(self) -> bool:
"""地磁気校正値取得"""
success, response = self._send_and_receive("GET_MAG_PRF")
if success and response.startswith("MAG_PRF_"):
try:
# データ部分を抽出(カンマ区切りの数値)
# レスポンス形式: MAG_PRF_x,x,x (X, Y, Z軸)
data_str = response.replace("MAG_PRF_", "")
values = [float(x.strip()) for x in data_str.split(",")]
if len(values) == 3: # X, Y, Z軸
axes = ['X', 'Y', 'Z']
self.mag_prf = {}
for i, axis in enumerate(axes):
self.mag_prf[axis] = values[i]
print(f"地磁気校正値取得完了 ({len(values)}軸)")
return True
except Exception as e:
print(f"地磁気校正値解析エラー: {e}")
pass
return False
def _get_mag_itf(self) -> bool:
"""地磁気干渉補正取得"""
success, response = self._send_and_receive("GET_MAG_ITF")
if success and response.startswith("MAG_ITF_"):
try:
# データ部分を抽出(カンマ区切りの数値)
# レスポンス形式: MAG_ITF_x,x,x,x,x,x,x,x,x (9個のパラメータ)
data_part = response.replace("MAG_ITF_", "") # ヘッダーを除去
values = [float(x.strip()) for x in data_part.split(",")] # 9個のパラメータ
if len(values) == 9: # 9個のパラメータ
self.mag_itf = values
print(f"地磁気干渉補正取得完了 (9パラメータ)")
return True
except Exception as e:
print(f"地磁気干渉補正解析エラー: {e}")
return False
else:
print("地磁気干渉補正取得失敗")
return False
def _get_mag_additional_params(self) -> bool:
"""地磁気追加パラメータ取得"""
# OFFSETZERO取得
if not self._get_mag_offzero():
return False
# OFFSET取得
if not self._get_mag_off():
return False
# FINEOUTPUT取得
if not self._get_mag_fineout():
return False
# SENSITIVITY取得
if not self._get_mag_sens():
return False
# GAINPARA取得
if not self._get_mag_gainpara():
return False
return True
def _get_mag_offzero(self) -> bool:
"""地磁気OFFSETZERO取得"""
success, response = self._send_and_receive("GET_MAG_OFFZERO")
if success and response.startswith("MAG_OFFZERO_"):
try:
# データ部分を抽出(カンマ区切りの数値)
# レスポンス形式: MAG_OFFZERO_x,x,x (X, Y, Z軸)
data_str = response.replace("MAG_OFFZERO_", "")
values = [float(x.strip()) for x in data_str.split(",")]
if len(values) == 3: # X, Y, Z軸
axes = ['X', 'Y', 'Z']
self.mag_offzero = {}
for i, axis in enumerate(axes):
self.mag_offzero[axis] = values[i]
print(f"地磁気OFFSETZERO取得完了 ({len(values)}軸)")
return True
except Exception as e:
print(f"地磁気OFFSETZERO解析エラー: {e}")
pass
return False
def _get_mag_off(self) -> bool:
"""地磁気OFFSET取得"""
success, response = self._send_and_receive("GET_MAG_OFF")
if success and response.startswith("MAG_OFF_"):
try:
# データ部分を抽出(カンマ区切りの数値)
# レスポンス形式: MAG_OFF_x,x,x (X, Y, Z軸)
data_str = response.replace("MAG_OFF_", "")
values = [float(x.strip()) for x in data_str.split(",")]
if len(values) == 3: # X, Y, Z軸
axes = ['X', 'Y', 'Z']
self.mag_off = {}
for i, axis in enumerate(axes):
self.mag_off[axis] = values[i]
print(f"地磁気OFFSET取得完了 ({len(values)}軸)")
return True
except Exception as e:
print(f"地磁気OFFSET解析エラー: {e}")
pass
return False
def _get_mag_fineout(self) -> bool:
"""地磁気FINEOUTPUT取得"""
success, response = self._send_and_receive("GET_MAG_FINEOUT")
if success and response.startswith("MAG_FINEOUT_"):
try:
# データ部分を抽出(カンマ区切りの数値)
# レスポンス形式: MAG_FINEOUT_x,x,x (X, Y, Z軸)
data_str = response.replace("MAG_FINEOUT_", "")
values = [float(x.strip()) for x in data_str.split(",")]
if len(values) == 3: # X, Y, Z軸
axes = ['X', 'Y', 'Z']
self.mag_fineout = {}
for i, axis in enumerate(axes):
self.mag_fineout[axis] = values[i]
print(f"地磁気FINEOUTPUT取得完了 ({len(values)}軸)")
return True
except Exception as e:
print(f"地磁気FINEOUTPUT解析エラー: {e}")
pass
return False
def _get_mag_sens(self) -> bool:
"""地磁気SENSITIVITY取得"""
success, response = self._send_and_receive("GET_MAG_SENS")
if success and response.startswith("MAG_SENS_"):
try:
# データ部分を抽出(カンマ区切りの数値)
# レスポンス形式: MAG_SENS_x,x,x (X, Y, Z軸)
data_str = response.replace("MAG_SENS_", "")
values = [float(x.strip()) for x in data_str.split(",")]
if len(values) == 3: # X, Y, Z軸
axes = ['X', 'Y', 'Z']
self.mag_sens = {}
for i, axis in enumerate(axes):
self.mag_sens[axis] = values[i]
print(f"地磁気SENSITIVITY取得完了 ({len(values)}軸)")
return True
except Exception as e:
print(f"地磁気SENSITIVITY解析エラー: {e}")
pass
return False
def _get_mag_gainpara(self) -> bool:
"""地磁気GAINPARA取得"""
success, response = self._send_and_receive("GET_MAG_GAINPARA")
if success and response.startswith("MAG_GAINPARA_"):
try:
# データ部分を抽出(カンマ区切りの数値)
# レスポンス形式: MAG_GAINPARA_x,x,x,x,x,x (6個のパラメータ)
data_part = response.replace("MAG_GAINPARA_", "") # ヘッダーを除去
values = [float(x.strip()) for x in data_part.split(",")] # 6個のパラメータ
if len(values) == 6: # 6個のパラメータ
self.mag_gainpara = values
print(f"地磁気GAINPARA取得完了 (6パラメータ)")
return True
except Exception as e:
print(f"地磁気GAINPARA解析エラー: {e}")
return False
else:
print("地磁気GAINPARA取得失敗")
return False
def _get_frequency(self) -> bool:
"""測定周波数取得"""
success, response = self._send_and_receive("GET_FREQUENCY")
if success and response.startswith("FREQUENCY_"):
try:
self.frequency = int(response.replace("FREQUENCY_", ""))
print(f"測定周波数: {self.frequency} Hz")
return True
except:
pass
return False
def _get_matome(self) -> bool:
"""まとめ数取得"""
# PCまとめ数
success, response = self._send_and_receive("GET_MATOME")
if success and response.startswith("MATOME_"):
try:
self.matome_pc = int(response.replace("MATOME_", ""))
print(f"PCまとめ数: {self.matome_pc}")
except:
return False
else:
return False
# SDまとめ数
success, response = self._send_and_receive("GET_MATOME_SD")
if success and response.startswith("MATOME_SD_"):
try:
self.matome_sd = int(response.replace("MATOME_SD_", ""))
print(f"SDまとめ数: {self.matome_sd}")
return True
except:
pass
return False
def _get_sensor_range(self) -> bool:
"""センサーレンジ取得"""
# 加速度レンジ
success, response = self._send_and_receive("GET_ACC_RANGE")
if success and response.startswith("ACC_RANGE_"):
try:
range_code = int(response.replace("ACC_RANGE_", ""))
# コード変換: 0=2G, 1=4G, 2=8G, 3=16G, 4=30G
range_map = {0: 2, 1: 4, 2: 8, 3: 16, 4: 30}
self.acc_range = range_map.get(range_code, 2)
print(f"加速度レンジ: ±{self.acc_range} G")
except:
return False
else:
return False
# ジャイロレンジ
success, response = self._send_and_receive("GET_GYRO_RANGE")
if success and response.startswith("GYRO_RANGE_"):
try:
range_code = int(response.replace("GYRO_RANGE_", ""))
# コード変換: 0=125, 1=250, 2=500, 3=1000, 4=2000, 5=4000
range_map = {0: 125, 1: 250, 2: 500, 3: 1000, 4: 2000, 5: 4000}
self.gyro_range = range_map.get(range_code, 250)
print(f"ジャイロレンジ: ±{self.gyro_range} deg/s")
return True
except:
return False
else:
return False
def _get_save_settings(self) -> bool:
"""SD保存設定取得"""
# SD保存設定
success, response = self._send_and_receive("GET_SAVE_TO_FLASH")
if success and response.startswith("SAVE_TO_FLASH_"):
try:
value = int(response.replace("SAVE_TO_FLASH_", ""))
self.save_to_flash = (value == 1)
print(f"SD保存: {'有効' if self.save_to_flash else '無効'}")
except:
return False
else:
return False
# SDカード有無
success, response = self._send_and_receive("GET_SD_EXIST")
if success and response.startswith("SD_EXIST_"):
try:
value = int(response.replace("SD_EXIST_", ""))
self.sd_exist = (value == 1)
print(f"SDカード: {'あり' if self.sd_exist else 'なし'}")
return True
except:
pass
return False
def _get_header(self) -> bool:
"""ファイルヘッダ取得"""
success, response = self._send_and_receive("GET_HEADER")
if success and response.startswith("HEADER_"):
self.header = response.replace("HEADER_", "")
print(f"ファイルヘッダ: {self.header}")
return True
return False
def _get_save_time(self) -> bool:
"""保存時間取得"""
success, response = self._send_and_receive("GET_SAVE_TIME")
if success and response.startswith("SAVE_TIME_"):
try:
self.save_time = int(response.replace("SAVE_TIME_", ""))
print(f"保存時間: {self.save_time} 秒")
return True
except Exception as e:
print(f"保存時間変換エラー: {e}")
return False
def _get_soc_meas_stop_en(self) -> bool:
"""電池残量測定停止機能取得"""
success, response = self._send_and_receive("GET_SOC_MEAS_STOP_EN")
if success and response.startswith("SOC_MEAS_STOP_EN_"):
try: