Create Webots interface with other software using TCP / IP protocol in python

413 Views Asked by At

Webots allow me to connect my robot with other software through a TCP / IP protocol. It already comes with an implemented example, but all the code is in C I want to do a python implementation using socket.

The controller needs to check if the client has sent any commands, and for this reason I put a msg = con.recv (1024) inside the main loop, but the problem is that in each interaction of the loop it is stopped waiting to receive a message. How can I make the socket not lock the loop but still be able to capture any incoming message?

This is the link for the C server implementation: Link

This is my problem implementation:

import socket
from controller import Robot

robot = Robot()

# get the time step of the current world
timestep = 250
max_speed = 6.28
                
# Enable motors    
left_motor = robot.getMotor('left wheel motor')
right_motor = robot.getMotor('right wheel motor')
            
left_motor.setPosition(float('inf'))
left_motor.setVelocity(0.0)
            
right_motor.setPosition(float('inf'))
right_motor.setVelocity(0.0)

right_speed = 0.0
left_speed = 0.0

HOST = '10.0.0.6'             
PORT = 10020           
tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
orig = (HOST, PORT)
tcp.bind(orig)
tcp.listen(1)

con, cliente = tcp.accept()
print ('Connected by ', cliente)

# Main loop:
# - perform simulation steps until Webots is stopping the controller
while robot.step(timestep) != -1:
    msg = con.recv(1024)
    txt = msg.decode('UTF-8')

    if txt[0] == "D":      
    
        if float(txt[2]) < max_speed:
            right_motor.setVelocity(max_speed)
        else:
            print("Very high speed")        
    
        if float(txt[4]) < max_speed:
            left_motor.setVelocity(max_speed)
        else:
            print("Very high speed ")
            
        
print ('Ending client connection ', cliente)
con.close()
1

There are 1 best solutions below

0
On

You can set a timeout:

tcp.settimeout(0.1)

Then, in the while loop:

try:
  msg = s.recv(1024)
except socket.timeout, e:
  continue

(instead of msg = con.recv(1024))

Using the given implementation, your controller will wait for 0.1s for data. If there is no data received in 0.1s it will simply skip and execute a simulation step.