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

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

    1. 搭建Simulink框图
      在想要发送的信号数据的框图后直接添加udp send模块即可。
      image.png
      2. 解包simulink传出的数据
      2.1 导入python struct模块
      Simulink默认传出来的数据是double格式,所以需要在python中添加解码double数据类型的代码,MALTAB中的double数据类型与C中的double类型一致,所以Python内置的struct库使用起来会很有效。(多亏网络调试助手才能知道这个思路!!)

    2.2 解包单个信号
    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中显示接收到的数据:
    image.png

    接收到数据后用matplotlib对其绘图可得以下图形:
    image.png
    2.3 解包多个信号
    上面说过,在解包单个信号的时候,unpack函数会返回一个size为1的元组。如果要传输多个double型数据(这里传输3个),可以在上面语句的基础上直接改为:recv_msg_decode = struct.unpack(“3d”, recv_msg),即改变unpack传入的string参数,再用for循环遍历返回的元组即可。

    附:解包单个正弦信号的完整代码(python)

    1. #!/usr/bin/env python
    2. # -*- coding: utf-8 -*
    3. import socket, struct, os
    4. import numpy as np
    5. import matplotlib.pyplot as plt
    6. def main():
    7. # -------------------------------- Initializing --------------------------------------------
    8. # Create a socket
    9. udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    10. # Bind the IP address and port.
    11. localaddr = ("127.0.0.1", 54320)
    12. udp_socket.bind(localaddr)
    13. # Create an increment for while loop
    14. count = 0
    15. # Create a list to restor the data from simulink.
    16. data_collect = []
    17. # Create a path to save figure:
    18. path = 'Your Path Here'
    19. print("Please open the Simulink file under the current working directory")
    20. print("The program is waiting until you run the Simulink file.")
    21. #----------------------------------- Data Receiving ----------------------------------------
    22. # Using a loop to receive data from Simulink
    23. while count < 101: # Can be modified by (simulationTime/sampleTime).
    24. # Start to receive data from Simulink.
    25. recv_data = udp_socket.recvfrom(1024)
    26. #print(recv_data)
    27. # recv_data will return tuple, the first element is DATA, and the second is address information
    28. recv_msg = recv_data[0]
    29. send_addr = recv_data[1]
    30. # Decode the data from Simulink whose type is double and return a tuple
    31. recv_msg_decode = struct.unpack("d", recv_msg)[0]
    32. # Restore the data to a list:
    33. data_collect.append(recv_msg_decode)
    34. # Set the condition to jump out of this loop ???
    35. # Print the address information and the received data
    36. print("Number from MATLAB %s is : %s" % (str(send_addr), recv_msg_decode))
    37. count += 1
    38. # Close the udp socket.
    39. udp_socket.close()
    40. # ------------------------------------ Visualization -----------------------------------------------
    41. # Set the time axis, 10 is the simulation end time that can be modified by user.
    42. index = list(np.linspace(0, 10, (len(data_collect))))
    43. plt.plot(index, data_collect)
    44. plt.title("Signal Received from Simulink")
    45. plt.xlabel("Time")
    46. plt.ylabel("Received Data")
    47. plt.savefig(os.path.join(path, 'data_figure.png'), dpi=600)
    48. print("Close the figure to restart.")
    49. plt.show()
    50. if __name__ == "__main__":
    51. main()

    (代码中循环的部分暂且用总的(仿真时间/采样时间)+1得到while后的参数,另外一种方法是导入time库,用time.sleep(0.1)可以识别KeyboardInterruption)

    ref
    https://blog.csdn.net/qq_41871826/article/details/104172653