PB using pypot and Vrep

I tried to use pypot+vrep on a toy example (NOT poppy, only 1 cuboid, 1 motor and another Cuboid) and I am stuck with a strange behavior. It seems that python is stuck as two threads are waiting for their time.sleep(0.02) to end… In the meanwhile, I still have a connexion with Vrep, but the “streaming” between the Robot and 'Vrep` is not assured.

I do not know if I should raise an issue on github or if there is a evident error in my code attempt.

In more details.
(primary files code.zip (197.1 KB))

This is the core of code I’m running (with modified pypot so as to get the the VRepIO object and to log some functions.

# tio is the VrepIO object, toy the Robot
toy,tio = pvrep.from_vrep( config ="toy.json", scene ="VRep/toy.ttt" )

time.sleep(4)
start = time.time()
ind = 0
tio.set_motor_position( 'moteur', deg2rad(-30))
while time.time() - start < 10:
    logger.debug ("one second")
    logger.debug ( "tio "+str(tio.get_simulation_current_time()) )
    logger.debug ( "mot="+str(tio.get_motor_position( 'moteur' )) )
    logger.debug ( "mot_pos="+str(toy.moteur.present_position) )
    if( ind == 2 ):
        logger.debug( "set motor" )
        tio.set_motor_position( 'moteur', deg2rad(30))
    ind += 1
    time.sleep(1)

In particular, I have modified pypot/vrep/__init__.py so that from_vrep returns the Robot and tne VrepIO
I have also logged the method make_update_loop in pypot/utils/stoppablethread.py (see below)

def make_update_loop(thread, update_func, origin):
    """ Makes a run loop which calls an update function at a predefined frequency. """
    logger = logging.getLogger( origin )
    logger.info( "Start periodic loop at period={0}".format(thread.period))
    while not thread.should_stop():
        logger.debug( "inside" );
        if thread.should_pause():
            thread.wait_to_resume()

        start = time.time()
        update_func()
        end = time.time()

        dt = thread.period - (end - start)
        logger.debug( "wait for dt={0}".format(dt) )
        if dt > 0:
            time.sleep(dt)
        logger.debug( "end sleep" )

And I end up with the following log (the comments are added manually)

=> python vrep_toy.py
from_vrep VrepIO(vrep_host, vrep_port)

## first created thread

('create', 'SafeCompliance', 'at StoppableLoopThread') 
INFO:pypot.robot.config:Instantiating motor 'moteur' id=1 direct=True offset=0.0
from_vrep VrepController(..)

## second created thread

('create', 'VrepController', 'at StoppableLoopThread')
VrepIO.start_simulation()
from_vrep _ini_vrep_streaming()
('create', 'PrimitiveManager', 'at StoppableLoopThread')
INFO:pypot.vrep.controller:update
INFO:pypot.vrep.controller:VrepController pos m=moteur p=0.0
INFO:pypot.vrep.controller:VrepController tor m=moteur t=1.2

## Both thread enter make_update_loop

DEBUG:VrepController:run
INFO:VrepController:Start periodic loop at period=0.02
DEBUG:VrepController:inside
DEBUG:PrimitiveManager:run
INFO:pypot.robot.robot:Starting robot synchronization.
INFO:PrimitiveManager:Start periodic loop at period=0.02
DEBUG:PrimitiveManager:inside
INFO:pypot.vrep.controller:update
INFO:pypot.vrep.controller:VrepController pos m=moteur p=0.0
DEBUG:pypot.primitive.manager:update with 1 motors
INFO:pypot.vrep.controller:VrepController tor m=moteur t=1.2

Both thread stuck -> streaming not assured

DEBUG:VrepController:wait for dt=0.02
DEBUG:PrimitiveManager:wait for dt=0.02
VrepIO.start_simulation()

stil I have a connection with Vrep and can change motor position “by hand”, but no streaming between Vrep and Robot

DEBUG:__main__:one second
DEBUG:__main__:tio 0.0
DEBUG:__main__:mot=-0.523598611355
DEBUG:__main__:mot_pos=0.0
DEBUG:__main__:one second
DEBUG:__main__:tio 0.0
DEBUG:__main__:mot=-0.523598611355
DEBUG:__main__:mot_pos=0.0
DEBUG:__main__:one second
DEBUG:__main__:tio 0.0
DEBUG:__main__:mot=-0.523598611355
DEBUG:__main__:mot_pos=0.0
DEBUG:__main__:set motor
DEBUG:__main__:one second
DEBUG:__main__:tio 0.0
DEBUG:__main__:mot=0.523598611355
DEBUG:__main__:mot_pos=0.0
INFO:__main__:__STOP

For info, my json file describing the Robot

 {
"controllers": {
    "simple_controller": {
        "sync_read":true,
        "attached_motors": ["moteur"],
        "protocole":1,
        "port":"/dev/ttyACM1"
    }
},
"motorgroups":{},
"motors":{
    "moteur":{
        "id":1,
        "orientation":"direct",
        "type":"AX-12",
        "offset":0.0,
    "angle_limit":[-90.0, 90.0]
    }
}

}

So, any advice or suggestion would be nice. Even (et même) in french :o)
Alain

As a complement, the modified pypot I’m using is here https://github.com/snowgoon88/pypot
in the etags branch

Alain

Hi Alain,

That was actually tricky :frowning: When using V-REP we kind of monkey patch the time module to use V-REP time instead of your computer time. So, in theory, your code works the same way not matter how fast you can run the V-REP simulation.

Yet, to do that we need to retrieve V-REP current simulation time manually. It’s not (or at least wasn’t) directly available through the Python API. So basically, I add a child script to the scene sending this information. I’ve modified your scene and it works now. toy.ttt.zip (196.6 KB)

For info, the child script is simply:

-- DO NOT WRITE CODE OUTSIDE OF THE if-then-end SECTIONS BELOW!!

if (sim_call_type==sim_childscriptcall_initialization) then
  simSetScriptAttribute(sim_handle_self,sim_childscriptattribute_automaticcascadingcalls,false)
end


if (sim_call_type==sim_childscriptcall_actuation) then
  if not firstTimeHere93846738 then
    firstTimeHere93846738=0
  end
  simSetScriptAttribute(sim_handle_self,sim_scriptattribute_executioncount,firstTimeHere93846738)
  firstTimeHere93846738=firstTimeHere93846738+1

------------------------------------------------------------------------------


-- Check the end of the script for some explanations!
  if (simGetScriptExecutionCount()==0) then

  end

  simHandleChildScripts(sim_call_type)

  local currentTime=simGetSimulationTime()

  simSetFloatSignal('CurrentTime',currentTime)

end


if (sim_call_type==sim_childscriptcall_sensing) then
  simHandleChildScripts(sim_call_type)
end


if (sim_call_type==sim_childscriptcall_cleanup) then

  -- Put some restoration code here

end

I’ll try to see if I can detect if this script is not running on V-REP side on raise a clear error instead of just blocking :blush:

P.S. The motor position is in degree in pypot.

1 Like

Hello Pierre,

your patch does the job wonderfully. I understand the logic of hacking time to provide a consistent behavior of pypot+VRep. I’ll now be able to simulate correctly our more complex “hand-made” robotic lamp.

Merci beaucoup, surtout pour la réactivité.
Alain

Cool!

Do not hesitate to post more info about your project. I kind like robotic lamp ^^