The remote API functions are interacting with V-REP via socket communication in a way that reduces lag and network load to a great extent. The remote API can let one or several external applications interact with V-REP.
A remote API function is called in a similar fashion as a regular API function, however with 2 major differences:
- most remote API functions return a similar value: a return code.
- most remote API functions require two additional argument: the operation mode, and the clientID (identifier returned by the simxStart function)
由於客戶端和服務器使用socket套接字進行通信,因此就涉及到網絡編程時常見的同步(Sync)/異步(Async),阻塞(Block)/非阻塞(Unblock)等調用方式。The need for an operation mode and a specific return code comes from the fact that the remote API function has to travel via socket communication to the server (V-REP), execute a task, then return to the caller (the client). A naive (or regular) approach would be to have the client send a request, and wait until the server processed the request and replied: in most situations this would take too much time and the lag would penalize the client application. Instead, the remote API lets the user chose the type of operation mode and the way simulation advances by providing four main mechanisms to execute function calls or to control the simulation progress:
- Blocking function calls(a blocking function call is the naive or regular approach)
- Non-blocking function calls
- Data streaming
- Synchronous operation
1. Blocking function calls(阻塞調用)
這種方式在調用結果返回之前,當前線程會被掛起。函數只有在得到結果之后才會返回。比如下面代碼獲取物體句柄,操作模式采用阻塞模式simx_opmode_blocking(A command is sent to the server for execution, and the function waits for the reply from the server)
// Following function (blocking mode) will retrieve an object handle: if (simxGetObjectHandle(clientID,"myJoint",&jointHandle,simx_opmode_blocking)==simx_return_ok) { // here we have the joint handle in variable jointHandle! }
下圖反映了阻塞調用的流程:
2. Non-blocking function calls(非阻塞調用)
非阻塞指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回。非阻塞調用適用於不需要服務端應答的場合(A non-blocking function call is meant for situations when we simply want to send data to V-REP without the need for a reply)。如下面例子,只是調用函數設置關節位置而不需要服務端返回數據,就可以使用非阻塞模式simx_opmode_oneshot。
// Following function (non-blocking mode) will set the position of a joint: simxSetJointPosition(clientID,jointHandle,jointPosition,simx_opmode_oneshot);
下圖反映了非阻塞調用的流程:

阻塞/非阻塞,是指程序在等待消息時的狀態。簡單理解為需要做一件事能不能立即得到應答返回。如果不能立即獲得返回,需要等待,那就阻塞了;否則就可以理解為非阻塞。詳細區別如下圖所示:

有時為了同時發送多條指令給服務端響應,我們可以先暫停通信。In some situations, it is important to be able to send various data within a same message, in order to have that data also applied at the same time on the server side (e.g. we want the 3 joints of a robot to be applied to its V-REP model in the exact same time, i.e. in the same simulation step). In that case, the user can temporarily halt the communication thread in order to achieve this, as shown in following example:
simxPauseCommunication(clientID,1); //Allows to temporarily halt the communication thread from sending data. simxSetJointPosition(clientID,joint1Handle,joint1Value,simx_opmode_oneshot); simxSetJointPosition(clientID,joint2Handle,joint2Value,simx_opmode_oneshot); simxSetJointPosition(clientID,joint3Handle,joint3Value,simx_opmode_oneshot); simxPauseCommunication(clientID,0); // Above's 3 joints will be received and set on the V-REP side at the same time
Following diagram illustrates the effect of temporarily halting the communication thread:

3. Data streaming(數據流模式)
這一模式下,客戶端可以向服務端發起請求連續的數據流。可以將其看做一種客戶與服務端之間的命令/信息訂閱模式(也可以類比模擬信號采集卡的連續采樣功能:Analog Input在采樣過程中每相鄰兩個采樣點的時間相等,采集過程中不停頓,連續不間斷的采集數據,直到用戶主動停止采集任務)。客戶端發起數據流請求及讀取的代碼如下所示:
// Streaming operation request (subscription) (function returns immediately (non-blocking)): simxGetJointPosition(clientID,jointHandle,&jointPosition,simx_opmode_streaming); // The control loop: while (simxGetConnectionId(clientID)!=-1) // while we are connected to the server.. { // Fetch the newest joint value from the inbox (func. returns immediately (non-blocking)): if (simxGetJointPosition(clientID,jointHandle,&jointPosition,simx_opmode_buffer)==simx_return_ok) { // here we have the newest joint position in variable jointPosition! } else { // once you have enabled data streaming, it will take a few ms until the first value has arrived. So if // we landed in this code section, this does not always mean we have an error!!! } } // Streaming operation is enabled/disabled individually for each command and // object(s) the command applies to. In above case, only the joint position of // the joint with handle jointHandle will be streamed.
simx_opmode_streaming: non-blocking mode. Similar to simx_opmode_oneshot, but with the difference that the command will be stored on the server side , continuously executed, and continuously sent back to the client. This mode is often used with "get-functions" (e.g. simxGetJointPosition), where the user requires a specific value constantly.
simx_opmode_buffer: non-blocking mode. No command is sent to the server, but just a reply to a same command, previously executed. This mode is often used in conjunction with the simx_opmode_streaming mode: first, a constant command execution is started with a streaming command, then only command replies fetched.
Following diagram illustrates data streaming:

當完成任務后,客戶端需要主動發送請求停止數據流(otherwise the server will continue to stream unessesary data and eventually slow down)。使用simx_opmode_discontinue操作模式來停止數據流。simx_opmode_discontinue: non-blocking mode. This mode is used to interrupt streaming commands.
參考:
