jeguzzi / robomaster_sim

A simulator/emulator of DJI Robomaster Robots (EP and S1)
MIT License
21 stars 2 forks source link

Can't connect to robot when turning on Synchronize mode #4

Open xander-2077 opened 1 year ago

xander-2077 commented 1 year ago

I cannot connect to the robot when turning on synchronize mode in CoppeliaSim. A small snippet of display code:

from zmqRemoteApi import RemoteAPIClient
from robomaster import robot, logger, logging

client = RemoteAPIClient()
sim = client.getObject('sim')
client.setStepping(True)
sim.startSimulation()

ep_robot = robot.Robot()
ep_robot.initialize(conn_type="sta")
# ep_robot.chassis.drive_speed(0.3, 0, 45, timeout=10)
for _ in range(20):
    client.step()
sim.stopSimulation()

An error occurred:

2023-04-14 12:35:13,594 ERROR conn.py:107 scan_robot_ip: exception timed out
2023-04-14 12:35:13,594 ERROR robot.py:1338 Robot: Connection Failed, Please Check Hareware Connections!!! conn_type sta, host None, target None.
2023-04-14 12:35:13,594 ERROR client.py:70 Client: __init__, create Connection, exception: module 'robomaster.config' has no attribute 'DEFAULT_CONN_PROTO'
2023-04-14 12:35:13,595 ERROR client.py:153 Client: send_sync_msg, client recv_task is not running.
2023-04-14 12:35:13,595 ERROR client.py:153 Client: send_sync_msg, client recv_task is not running.
2023-04-14 12:35:13,595 ERROR client.py:153 Client: send_sync_msg, client recv_task is not running.
2023-04-14 12:35:13,595 ERROR client.py:153 Client: send_sync_msg, client recv_task is not running.
2023-04-14 12:35:13,595 ERROR client.py:153 Client: send_sync_msg, client recv_task is not running.
Robot: Can not connect to robot, check connection please.
Traceback (most recent call last):
  File "/home/xander/.local/lib/python3.8/site-packages/robomaster/client.py", line 93, in remote_addr
    return self._conn.target_addr
AttributeError: 'NoneType' object has no attribute 'target_addr'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/xander/Documents/RSGE/zmq111.py", line 31, in <module>
    ep_robot.initialize(conn_type="sta")
  File "/home/xander/.local/lib/python3.8/site-packages/robomaster/robot.py", line 1312, in initialize
    self._ftp.connect(self.ip)
  File "/home/xander/.local/lib/python3.8/site-packages/robomaster/robot.py", line 1148, in ip
    return self.client.remote_addr[0]
  File "/home/xander/.local/lib/python3.8/site-packages/robomaster/client.py", line 95, in remote_addr
    raise print('Robot: Can not connect to robot, check connection please.')
TypeError: exceptions must derive from BaseException

Can I connect to robot in this mode? Thank you!

jeguzzi commented 1 year ago

Hi,

I never tried the ZMQ client of coppeliaSim but I will (you piqued my curiosity) and report back. The connection to the simulated robot should work the same as there is a dedicated [connection] thread. Make sure you first start the simulation (the equivalent of pressing play in the GUI), before trying to connect. In particular, the simulated robot should at least execute the init simRobomaster.create_{s1|ep}(...), else it won't start the connection thread.

jeguzzi commented 1 year ago

@xander-2077 I tested connecting to a robomaster while running the simulation using a ZMQ client, like in your script.

The short version is that you need to run the simulation while connecting to the client. The following works:

client.setStepping(False)
sim.startSimulation()
ep_robot = robot.Robot()
ep_robot.initialize(conn_type="sta")
client.setStepping(True)

The longer version

The real | simulated robomaster uses a discovery mechanism to announce itself to clients, for which it publishes a discovery message every second. When the client executes ep_robot.initialize(), it waits to receive one of these messages: if none are received, it fails, like your log. Now, in simulation, the timer that sends the discovery messages (https://github.com/jeguzzi/robomaster_sim/blob/main/src/discovery.cpp#L46) is triggered (indirectly) by the simulation step (https://github.com/jeguzzi/robomaster_sim/blob/main/coppeliaSim_plugin/plugin.cpp#L614). Therefore, while the simulation is paused (like between calls of client.step() if we set client.setStepping(True)), the discovery message are not sent and the client does not connect. Instead, when the simulation is running (like above), they are sent and the client connects. Once connected, we can pause the simulation.

An alternative would be to run ep_robot.initialize() and client.step() concurrently (e.g. in different threads).