Simulink与Python的UDP简单通信

感情迁移 提交于 2020-02-04 19:03:15

Simulink与Python的UDP通信

本文总结一下最近做的任务,用UDP实现simulink与python的通信,重点在于Python udp接收端的代码(python socket的用法见上一篇:python中socket模块基础用法

这个任务其实原理是非常直接的,首先是用localhost作为IP地址,端口自定义(1024 ~ 65535)用Simulink的内置UDP发送模块发送信号(本文中用的是离散的正弦信号)给python接收端即可。

Simulink框图

在这里插入图片描述

导入python struct模块:

Simulink默认传出来的数据是double格式,所以需要在python中添加解码double数据类型的代码,MALTAB中的double数据类型与C中的double类型一致,所以Python内置的struct库使用起来会很有效。

struct模块的目的就是在python与C程序通信的时候,将C的struct数据结构转化为python能够识别的类型。本例中就是将MATLAB的double类型进行解包。对应语句为:recv_msg_decode = struct.unpack("d", recv_msg)[0],这里的recv_msg是python程序接收到的原始信号(bytes类型),struct.unpack("d", recv_msg)的意思就是以"d"(double类型)对recv_msg进行解包,返回一个只有一个元组,第一个数为解码后的数值。

cmd中显示接收到的数据:
在这里插入图片描述
接收到数据后用matplotlib对其绘图可得以下图形:
在这里插入图片描述

完整python代码

#!/usr/bin/env python    
# -*- coding: utf-8 -*

import socket, struct, os
import numpy as np
import matplotlib.pyplot as plt


def main():	
	# -------------------------------- Initializing --------------------------------------------
	# Create a socket
	udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	# Bind the IP address and port.  
	localaddr = ("127.0.0.1", 54320)
	udp_socket.bind(localaddr)
	# Create an increment for while loop
	count = 0
	# Create a list to restor the data from simulink.
	data_collect = []
	# Create a path to save figure:
	path = 'Your Path Here'

	print("Please open the Simulink file under the current working directory")
	print("The program is waiting until you run the Simulink file.")

	#----------------------------------- Data Receiving ----------------------------------------
	# Using a loop to receive data from Simulink
	while count < 101: # Can be modified by (simulationTime/sampleTime).
		# Start to receive data from Simulink.
		recv_data = udp_socket.recvfrom(1024)
		#print(recv_data)
		# recv_data will return tuple, the first element is DATA, and the second is address information
		recv_msg = recv_data[0]
		send_addr = recv_data[1]
		# Decode the data from Simulink whose type is double and return a tuple
		recv_msg_decode = struct.unpack("d", recv_msg)[0]
		# Restore the data to a list:
		data_collect.append(recv_msg_decode)
		# Set the condition to jump out of this loop ???
		# Print the address information and the received data
		print("Number from MATLAB %s is : %s" % (str(send_addr), recv_msg_decode))
		count += 1
	# Close the udp socket.
	udp_socket.close()

	# ------------------------------------ Visualization ----------------------------------------------- 
	# Set the time axis, 10 is the simulation end time that can be modified by user.
	index = list(np.linspace(0, 10, (len(data_collect))))
	plt.plot(index, data_collect)
	plt.title("Signal Received from Simulink")
	plt.xlabel("Time")
	plt.ylabel("Received Data")
	plt.savefig(os.path.join(path, 'data_figure.png'), dpi=600)
	print("Close the figure to restart.")
	plt.show()

if __name__ == "__main__":
	main()

(代码中循环的部分还需要完善,这里暂且用总的(仿真时间/采样时间)+1得到while后的参数)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!