Means of communication in and around V-REP

Make sure you understand the overall structure of the simulator, and its API framework before going ahead reading this section.


Signals

Signals can be seen as global variables. Three types of signals are currently supported: integer-type signals, floating-type signals and string-type signals. Signals can be defined, redefined, read and cleared. At simulation end, all signals created by the main script or any child script will be cleared. For example:

-- script 1 writes the data to string signal "mySignalName":

local myData={1,2,{"Hello","world",true,{value1=63,value2="aString"}}}
sim.setStringSignal("mySignalName",sim.packTable(myData))
-- script 2 reads the data from string signal "mySignalName":

local myData=sim.getStringSignal(,"mySignalName")
if myData then
    myData=sim.unpackTable(myData)
end

Custom data blocks

Custom data blocks is data that can be stored inside of an object, or inside of a scene. It can be used to store custom data to be saved together with a model or scene, but also as a means of communication. For example:

-- script 1 writes the data to the scene:

local myData={1,2,{"Hello","world",true,{value1=63,value2="aString"}}}
sim.writeCustomDataBlock(sim.handle_scene,"myTag",sim.packTable(myData))
-- script 2 reads the data from the scene:

local myData=sim.readCustomDataBlock(sim.handle_scene,"myTag")
if myData then
    myData=sim.unpackTable(myData)
end

ROS

For example:

-- script subscribes to a topic carrying an image:

function sysCall_init()
    sub=simROS.subscribe('/image', 'sensor_msgs/Image', 'imageMessage_callback')
    simROS.subscriberTreatUInt8ArrayAsString(sub)
end

function imageMessage_callback(msg)
    -- here we have:
    -- msg.data
    -- msg.height
    -- msg.width
    -- etc.
end

BlueZero

For example:

-- script subscribes to a topic carrying an image:

function sysCall_init()
    b0Node=simB0.create('b0Node')
    sub=simB0.createSubscriber(b0Node,'image','imageMessage_callback')
    simB0.init(b0Node)
end

function sysCall_sensing()
    simB0.spinOnce(b0Node)
end

function imageMessage_callback(msg)
    -- msg is a raw buffer. 
    -- If the image data was encoded in base64, we could have:
    msg=sim.transformBuffer(msg,sim.buffer_base64,1,0,sim.buffer_uint8)
end

Remote API

For example, from a Python client:

# Receiving and image from V-REP and sending it back:

import vrep
clientID=vrep.simxStart('127.0.0.1',19999,True,True,5000,5)
if clientID!=-1:
    res,v0=vrep.simxGetObjectHandle(clientID,'Vision_sensor',vrep.simx_opmode_oneshot_wait)
    res,v1=vrep.simxGetObjectHandle(clientID,'PassiveVision_sensor',vrep.simx_opmode_oneshot_wait)

    res,resolution,image=vrep.simxGetVisionSensorImage(clientID,v0,0,vrep.simx_opmode_streaming)
    while (vrep.simxGetConnectionId(clientID)!=-1):
        res,resolution,image=vrep.simxGetVisionSensorImage(clientID,v0,0,vrep.simx_opmode_buffer)
        if res==vrep.simx_return_ok:
            res=vrep.simxSetVisionSensorImage(clientID,v1,image,0,vrep.simx_opmode_oneshot)
    vrep.simxFinish(clientID)

Persistent Data

Persistent data blocks can be seen as persistent global buffers. Persistent data blocks can be defined, redefined, read and cleared, and are shared across all opened scenes. They persist until the simulator ends, but can also persist on file and automatically be reloaded next time V-REP starts.


Custom Lua functions

The main client application or any plugin can register custom Lua functions via the Lua customization API commands. The custom Lua commands will then, when called from a script, call back a registered function in the main client application or a plugin. This is very convenient to achieve high level Lua commands (e.g. one could imagine having a plugin handle a robot's movement with a single Lua command simRobot.moveAndAvoidObstacles() !)


Wireless communication simulation

V-REP allows simulating wireless communications in a very flexible way: data can be emitted into a specific direction, and over a specific distance. Emitted data can then be received if the receiver is located within the specified emission area. Refer to the corresponding functions in the regular API for more details. Wireless emission/reception activities can be visualized by enabling the Visualize wireless emissions and Visualize wireless receptions items in the environment dialog. Following figure illustrates the visualized wireless communication between two mobile robots:

[Wireless communication simulation between two mobile robots]


Serial port communication

V-REP implements specific functions in the API for serial port communication.


LuaSocket

V-REP ships with a Lua extension library called LuaSocket (see here for acknowledgements and credits related to this library). It allows performing various type of socket communication from within an embedded script or an add-on. Following code section illustrates how a threaded child script would fetch a webpage:

http=require("socket.http")
sim.setThreadIsFree(true) -- Allow real threading from here (to avoid blocking V-REP)
page=http.request("http://www.google.com")
sim.setThreadIsFree(false) -- Forbid real threading from here

Notice how the blocking part of the request command is put within a non-blocking section. For more information on how to avoid external commands to block, refer to the sim.setThreadIsFree API command.

If your application requires socket communication, it is very convenient to set-up a threaded script as a request server and have the other scripts access it for socket communication as in following example:

The threaded request server:

http = require("socket.http")
-- Open a communication tube:
tubeHandle=sim.tubeOpen(0,'http_communication_test',1)

while (sim.getSimulationState()~=sim.simulation_advancing_abouttostop) do
    -- Wait for a message in the tube and reat it:
    data=sim.tubeRead(tubeHandle,true)
    if (data) then
        -- Fetch the page:
        sim.setThreadIsFree(true) -- Allow real threading from here (to avoid blocking V-REP)
        reply=http.request(data)
        sim.setThreadIsFree(false) -- Forbid real threading from here
        -- Send back the page:
        if (reply) then
            sim.tubeWrite(tubeHandle,reply)
        else
            sim.tubeWrite(tubeHandle,'Page could not be retrieved')
        end
    else
        sim.switchThread() -- explicitely switch thread
    end
end

Following non-threaded child script example could then be used to access socket information:

function sysCall_init()
    -- Open a communication tube:
    tubeHandle=sim.tubeOpen(0,'http_communication_test',1)

    urlsToCheck={'http://www.google.com','http://www.yahoo.com','http://www.titech.co.jp'}
    urlIndex=1
end

function sysCall_sensing()
    s,r,w=sim.tubeStatus(tubeHandle)
    if (s==1)and(r==0)and(w==0) then
        -- Send a request for a page:
        sim.tubeWrite(tubeHandle,urlsToCheck[urlIndex])
    end
    if (s==1)and(r==1) then
        -- Read the reply (the page):
        page=sim.tubeRead(tubeHandle)
        print('URL: '..urlsToCheck[urlIndex])
        print(page:sub(1,200)) -- Only print the first 200 chars
        urlIndex=urlIndex+1
        if (urlIndex>3) then
            urlIndex=1
        end
    end
end

Lua extension library

It is possible to extend the means of communication of V-REP almost infinitely, by using Lua's extension library mechanism. As is done with the LuaSocket library (see above), you could add any other type of Lua extension library available online. You will just have to install the library in V-REP's installation directory according to the library's instructions. As illustrated with the LuaSocket here above, make sure you make use of a non-blocking section with the sim.setThreadIsFree API command should an extension library command block V-REP.


Calling script functions

From the main client application, from a plugin, from an embedded script, from a remote API client or from a ROS node it is possible to call a script function using simCallScriptFunctionEx, or simxCallScriptFunction. The called script function can perform various tasks, then send back data to the caller.


Setting a script variable

From the main client application or from a plugin it is possible to set/clear script variables (i.e. Lua variables) using sim.setScriptVariable.



Recommended topics

  • Writing code in and around V-REP
  • Embedded scripts
  • Add-ons
  • Plugins
  • The main client application
  • Regular API
  • Remote API
  • ROS interfaces
  • BlueZero interface