バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/
はじめに
仮想ECU側が終わってHILSもどきに行くかと見せかけて
ECUの内部変数を波形表示するDAQリスナー作成をすることとなった。
CANを覗き見るだけなのでそれほど難しい機能ではない。はず。
というわけで、今回はDAQリスナーのPythonコードを確認する。
登場人物
博識フクロウのフクさん
イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん
イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
DAQリスナーのPythonコード
フクさん
ざっとDAQリスナーのPythonコードを書いてきたんで貼っとく。
import can
import matplotlib.pyplot as plt
import collections
import time
def xcp_mon(resid=2):
# バス接続
bus = can.interface.Bus(bustype='vector', channel='0', bitrate=500000)
queue_max=3000
deque_target = collections.deque(maxlen=queue_max)
deque_input = collections.deque(maxlen=queue_max)
deque_output = collections.deque(maxlen=queue_max)
deque_time = collections.deque(maxlen=queue_max)
plt.ion()
fig = plt.figure()
ax = plt.subplot(1,1,1)
ax.set_xlabel('Time')
ax.set_ylabel('Value')
fig.show()
# define plots
ax.plot([], [], label="target[rad/s]", color='Magenta', marker='.',linewidth=1,markersize=5)
ax.plot([], [], label="voltage[V]", color='Red', marker='.',linewidth=0.8,markersize=5)
ax.plot([], [], label="speed[rad/s]", color='Blue', marker='.',linewidth=0.7,markersize=5)
#ax.legend(bbox_to_anchor=(1, 1), loc='bottom right', borderaxespad=0, fontsize=10)
ax.legend(bbox_to_anchor=(1, 1), borderaxespad=0, fontsize=10)
ax.grid(which='both')
current_time = time.perf_counter()
# 受信
while True:
while True:
recv_msg = bus.recv(timeout=0.0)
if recv_msg != None:
if resid == recv_msg.arbitration_id:
if recv_msg.data[0] == 0x00 :
print('Recv msg : %s' % recv_msg)
target = float(int.from_bytes(recv_msg.data[1:3], byteorder='little', signed=True))/0x100
input = float(int.from_bytes(recv_msg.data[3:5], byteorder='little', signed=True))/0x100
output = float(int.from_bytes(recv_msg.data[5:7], byteorder='little', signed=True))/0x100
deque_target.append(target)
deque_input.append(input)
deque_output.append(output)
deque_time.append(time.perf_counter())
else:
break
if len(deque_time) != 0:
if time.perf_counter() > (current_time + 0.2):
ax.lines[0].set_data( deque_time, deque_target )
ax.lines[1].set_data( deque_time, deque_output )
ax.lines[2].set_data( deque_time, deque_input )
ax.relim() # recompute the data limits
ax.autoscale_view() # automatic axis scaling
ax.set_ylim(-50,200)
ax.set_xlim(deque_time[-1]-30,deque_time[-1])
fig.canvas.flush_events()
if __name__ == '__main__':
try:
xcp_mon()
except KeyboardInterrupt:
pass
DAQリスナーのPythonコード解説
太郎くん
基本的にはPython-canで受信して、それがDAQパケットだったら取り込んで、
matplotlibでリアルタイム描画するって感じか。
フクさん
まさにその通り。
太郎くん
matplotlibの更新は0.2秒周期にして描画負荷を下げてる感じか。
フクさん
ここら辺の事情はHILSもどきのリアルタイム描画と一緒だね。
太郎くん
じゃー、あとはこれを以前作ったxcp_canクラスと同時に起動して
ちゃんとDAQパケットを拾った上でリアルタイム描画できるかって確認か。
まとめ
フクさん
まとめだよ。
- DAQリスナーのPythonコードを開示。
- 基本的にはPython-canで受信。
- DAQパケットならば取り込む。
- 上記を元にmatplotlibで描画。
- 波形表示はリアルタイムではあるが負荷低減のため0.2秒周期。
- ここらへんの描画負荷の事情はHILSもどきの時と一緒。
バックナンバーはこちら。
コメント