UDP communication between Simulink and Python
This paper summarizes the recent tasks, uses UDP to realize the communication between simulink and python, and focuses on the code of the Python udp receiver (see for the usage of python socket Previous: basic usage of socket module in python)
In fact, the principle of this task is very direct. First, localhost is used as the IP address, port customization (1024 ~ 65535) uses Simulink's built-in UDP sending module to send signals (in this paper, discrete sine signals are used) to python receiver.
Simulink block diagram
Import python struct module:
By default, the data from Simulink is in double format, so you need to add code to Python to decode the double data type. The double data type in MALTAB is the same as that in C, so Python's built-in struct library will be very effective.
The purpose of struct module is to transform the struct data structure of C into the type that Python can recognize when Python communicates with C program. In this case, the double type of MATLAB is unpacked. The corresponding statement is: recv ﹣ MSG ﹣ decode = struct.unpack ("d", recv ﹣ MSG) [0]. Here, recv ﹣ MSG is the original signal (bytes type) received by the python program. Struct.unpack ("d", recv ﹣ MSG) means to unpack recv ﹣ MSG with "d"(double type), and return a value with only one tuple. The first number is the decoded value.
Display received data in cmd:
After receiving the data, use matplotlib to draw the following figures:
Full python code
#!/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()
(the part of the loop in the code needs to be improved. Here we use the total (simulation time / sampling time) + 1 to get the parameters after while.)