can't simxStartSimulation() immediately after simxStopSimulation()

Report crashes, strange behaviour, or apparent bugs
Post Reply
ctmakro
Posts: 2
Joined: 18 Apr 2017, 17:19

can't simxStartSimulation() immediately after simxStopSimulation()

Post by ctmakro »

the code below was modified from simpleSynchronousTest.py.

I'd like to run the simulation 5 times, 30 steps each; so I added a for loop.

Code: Select all

print ('Program started')
vrep.simxFinish(-1) # just in case, close all opened connections
clientID=vrep.simxStart('127.0.0.1',19997,True,True,5000,1) # Connect to V-REP
if clientID!=-1:
    print ('Connected to remote API server')
    # enable the synchronous mode on the client:
    vrep.simxSynchronous(clientID,True)
    for j in range(5):
        print('simulation',j)

        time.sleep(.5) # magic delay

        # start the simulation:
        e = vrep.simxStartSimulation(clientID,vrep.simx_opmode_blocking)
        print('start',e)

        # Now step a few times:
        for i in range(30):
            e = vrep.simxSynchronousTrigger(clientID)
            print('synct',e)
            # wait till simulation step finish
            e = vrep.simxGetPingTime(clientID)
            print('getping',e)

        # stop the simulation:
        e=vrep.simxStopSimulation(clientID,vrep.simx_opmode_blocking)
        print('stop',e)

    # Now close the connection to V-REP:
    vrep.simxFinish(clientID)
the code above will run the simulation 5 times. Let's call them simulation #0 #1 ... #4

However, if I comment out the 'magic delay' of 0.5 second, the simulation #0 will run as usual, but simulation #1, #2, #3, and sometimes #4, will not. It behaved like I forgot to call simxStartSimulation(), because all subsequent calls to simxSynchronousTrigger() returned error code 8.

There seems to be a period of time after simxStopSimulation() when simxStartSimulation() returns code 0 but the simulation won't actually start.

Tested on Win7 x64 and OS X 10.11.3

coppelia
Site Admin
Posts: 10338
Joined: 14 Dec 2012, 00:25

Re: can't simxStartSimulation() immediately after simxStopSimulation()

Post by coppelia »

Hello,

this is not a bug, that behaviour is intentional: when you send V-REP the "stop simulation" command, it will not immediately stop, but go through a stop procedure that might last several seconds. Have a look at this simulation state diagram.
The best would be to actively wait until the state is effectively stopped, before starting the simulation again.

From a remote API client, use something like: simxGetInMessageInfo(clientId,simx_headeroffset_server_state,info). That command will only return the state that was on, when the last data reached the client. Make sure you start at least one streaming command, so that you always read a fresh state info.

Cheers

ctmakro
Posts: 2
Joined: 18 Apr 2017, 17:19

Re: can't simxStartSimulation() immediately after simxStopSimulation()

Post by ctmakro »

After hours of trial and error I finally made the whole thing work. I'd like to share the method I use.

Ladies and Gentlemen, here I present:

HOW TO REPEATEDLY RUN A SIMULATION SYNCHRONOUSLY USING THE REMOTE API

(IF YOU DON'T DO WHAT I DID, YOU WILL GET YOURSELF INTO TROUBLE)

Code: Select all

print ('Connected to remote API server')

    # setup a useless signal
    vrep.simxSetIntegerSignal(
        clientID,'asdf',1,vrep.simx_opmode_blocking)

    for j in range(5):
        print('---------------------simulation',j)

        # IMPORTANT
        # you should poll the server state to make sure
        # the simulation completely stops before starting a new one
        while True:
            # poll the useless signal (to receive a message from server)
            vrep.simxGetIntegerSignal(
                clientID,'asdf',vrep.simx_opmode_blocking)

            # check server state (within the received message)
            e = vrep.simxGetInMessageInfo(clientID,
                vrep.simx_headeroffset_server_state)

            # check bit0
            not_stopped = e[1] & 1

            if not not_stopped:
                break
            else:
                print('not_stopped')

        # IMPORTANT
        # you should always call simxSynchronous()
        # before simxStartSimulation()
        vrep.simxSynchronous(clientID,True)
        # then start the simulation:
        e = vrep.simxStartSimulation(clientID,vrep.simx_opmode_blocking)
        print('start',e)

        # Now step a few times:
        for i in range(30):
            e = vrep.simxSynchronousTrigger(clientID)
            print('synct',e)
            # wait till simulation step finish
            e = vrep.simxGetPingTime(clientID)
            print('getping',e)

        # stop the simulation:
        vrep.simxStopSimulation(clientID,vrep.simx_opmode_blocking)

    # Now close the connection to V-REP:
    vrep.simxFinish(clientID)
Python 3.5
OS X 10.11.3

Post Reply