【仮想ECU】最小構成のMBD事例 第2章 その216【PID制御⑦】

【仮想ECU】最小構成のMBD事例 第2章 その216【PID制御⑦】 事例
【仮想ECU】最小構成のMBD事例 第2章 その216【PID制御⑦】

バックナンバーはこちら。
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もどきの時と一緒。

バックナンバーはこちら。

コメント

タイトルとURLをコピーしました