[Python] How to use "multi-threading" in python with ROS services and serial comunication?

Discussão em 'Python' iniciado por Stack, Junho 7, 2025.

  1. Stack

    Stack Membro Participativo

    I want to run multiple process in python with ROS services and serial communication (between Raspberry Pi and ESP32 Microcontroller) in my robot. The software schematic in the robot is shown in this image[​IMG]

    I start doing in C++ as can see from this link How to use ROS services and serial communication with posix and semaphores in C++? but I realized that my modules for serial communication and the ODOM(Pressure, IMU) read are in python.

    So, the structure of the program should be the following one. First I Open Serial port (Serial communication of the Raspberry PI 4). While the Serial is Open Two processes are running

    First one, the main one run automatically and do the following: The thread ask for ODOM Updates(Pressure and IMU from the microcontroller) and Publish them. Also every 0.3 seconds check the modem inbox and if something new it publish.

    The other one only on DEMAND from ROS Services detect that there is new message in the modem inbox do HALT( on the first main Process) and execute (publish) on the serial Port. Then the first process resume with normal work

    So I trying to do first some pseudo python code that looks like these But I need help as Im new to python and multithreading. Here it is

    #!/usr/bin/env python3

    from sys import ps1
    import rospy
    import numpy as np
    from os import system
    import time
    import threading
    import Microcontroller_Manager_Serial as Serial
    import IMU_Functions as IMU
    import Pressure_Functions as Pressure
    from std_msgs.msg import Float32

    mutex = threading.Lock()

    from std_msgs.msg import String
    Communication_Mode_ = 0 # Serial Communication

    pub_pressure = rospy.Publisher('depth',Float32,queue_size=1)

    P0 = 1.01325 #Default Pressure


    def callback(data):
    global P0
    mutex.acquire()
    while (Serial.Serial_Port_Standard()): # While serial Port is open

    try:
    data_received_pressure = Pressure.Pressure_Get_Final_Values(1,1)
    data_received_imu = IMU.IMU_Get_Values(1, 1)
    P1 = (np.int16((data_received_pressure[6]<<24) | (data_received_pressure[7]<<16) | (data_received_pressure[8]<<8) | (data_received_pressure[9])))/10000
    P0 = (np.int16((data_received_pressure[6]<<24) | (data_received_pressure[7]<<16) | (data_received_pressure[8]<<8) | (data_received_pressure[9])))/10000

    P = P1 - P0 # Relative Measured Pressure
    pressure = P
    pub_pressure.publish(pressure)
    except:
    print ("pressure not obtained")

    Modem.Send_Data(Communication_Mode, receiver_ID, data_size, data_to_send)

    def listener():

    # Not sure how to check every 0.3 seconds the modem inbox and if something new it publish. And also the DEMAND from ROS Services detect that there is new message in the modem inbox do HALT( on the first main Process) and execute (publish) on the serial Port. Then the first process resume with normal work


    For the modem check up I though need something like this , but im not sure.

    def callback_modem(data_in):

    data_in = Serial.Serial_Port_Receive_Data(20,0.2)
    if (data_in[0] == 91) # Received data from acoustic modem
    rt = RepeatedTimer(1, data_in, "Recieved Data") # it auto-starts, no need of rt.start()
    modem_data= data_in
    pub_modem.publish(modem_data)

    try:
    sleep(0.3) # your long-running job goes here...
    finally:
    rt.stop() # better in a try/finally block to make sure the program ends!


    The third thread with ROS Services callback should be like this?

    def handle_ros_service(req):
    data_received_temperature = TEMPERATURE.TEMPERATURE_Get_Values(1, 1)
    Tempetrature = (np.int16((data_received_imu[6]<<24) | (data_received_imu[7]<<16) | (data_received_imu[8]<<8) | (data_received_imu[9])))/10000
    mutex.acquire(blocking=True)
    return handle_ros_service(req.Tempetrature)


    def publish_on_serial():
    # send temperature over serial port
    mutex.release()

    Continue reading...

Compartilhe esta Página