V-rep学习笔记:外部函数调用方式

  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:

  1. most remote API functions return a similar value: a return code.
  2. 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.

参考:

Remote API modus operandi

https://www.zhihu.com/question/19732473

网络IO之阻塞、非阻塞、同步、异步总结

时间: 2024-12-18 17:16:06

V-rep学习笔记:外部函数调用方式的相关文章

EasyARM i.mx28学习笔记——文件IO方式操作GPIO

0 前言 本文描述如果通过文件IO sysfs方式控制EasyARM GPIO端口.通过sysfs方式控制GPIO,先访问/sys/class/gpio目录,向export文件写入GPIO编号,使得该GPIO的操作接口从内核空间暴露到用户空间,GPIO的操作接口包括direction和value等,direction控制GPIO方向,而value可控制GPIO输出或获得GPIO输入. Linux学习可从应用出发,先不纠结Linux驱动编写,先把Linux给玩起来. [相关博文] [EasyARM

树莓派学习笔记—— 源码方式安装opencv

0.前言 ? ? 本文介绍怎样在树莓派中通过编译源码的方式安装opencv,并通过一个简单的样例说明怎样使用opencv. ? ? 很多其它内容请參考--[树莓派学习笔记--索引博文] 1.下载若干依赖项 ? ? 在開始安装之前.最好更新树莓派软件源. 假设更新时间太长,请參考博文改动软件源网络地址--[树莓派学习笔记--改动树莓派软件源] sudo apt-get update ? ? 请依次安装下面依赖项,这些必须安装的依赖项来自于opencv官网的说明,在多数debian系统中都能够採用这

FreeRTOS学习笔记5-静态方式创建任务函数

配置完成后的进行任务创建,使用静态方式创建任务时需要使将宏 configSUPPORT_STATIC_ALLOCATION设置为 1,即使用静态内存.还需要将函数 vApplicationGetIdleTaskMemory()和 ApplicationGetTimerTaskMemory()进行实现.通过这两个函数来给空闲任务 和定时器服的任务堆 栈和任务控制块分配内存.在maiinc.c中进行定义.定义静态的任务堆栈和任务控制块内存,然后将这些内存传递给函数参数.最后创建空闲任务和定时器任务的

js学习笔记31----工厂方式

工厂方式构造对象: 1.原料---构造函数,创建一个对象 2.加工---属性,方法 3.出厂---返回结果 示例代码: <!DOCTYPE html> <html lang="en"> <head> <title>工厂方式</title> <meta charset="UTF-8"> <meta name="viewport" content="width=d

HashMap之put(K key, V value)学习笔记 jdk8版 (一)

    /**      * Associates the specified value with the specified key in this map.      * If the map previously contained a mapping for the key, the old      * value is replaced.      *      * @param key key with which the specified value is to be ass

Hive 学习笔记(启动方式,内置服务)

一.Hive介绍 Hive是基于Hadoop的一个数据仓库,Hive能够将SQL语句转化为MapReduce任务进行运行. Hive架构图分为以下四部分. 1.用户接口 Hive有三个用户接口: 命令行接口(CLI):以命令行的形式输入SQL语句进行数据数据操作 Web界面:通过Web方式进行访问. http://p.baidu.com/itopic/main/qlog?qid=e0f26162633565663838623000&type=questionlog http://p.baidu.

【C#学习笔记】函数调用

using System; namespace ConsoleApplication { class Program { static int Add(int a, int b) { return a + b; } static void Main(string[] args) { int a = 1,b = 2; int c = Add(a, b); Console.Write(c); Console.Read(); } } }

bootstrap学习笔记--bootstrap布局方式

Bootstrap 3 是移动设备优先的,在这个意义上,Bootstrap 代码从小屏幕设备(比如移动设备.平板电脑)开始,然后扩展到大屏幕设备(比如笔记本电脑.台式电脑)上的组件和网格. 移动设备优先策略 内容 决定什么是最重要的. 布局 优先设计更小的宽度. 基础的 CSS 是移动设备优先,媒体查询是针对于平板电脑.台式电脑. 渐进增强 随着屏幕大小的增加而添加元素. 响应式网格系统随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列.如下图: Bootstrap 网格系统

jQuery 学习笔记(函数调用机制)

最近在学前端框架amazeui,之前用其中的CSS样式搭建了一个伪360网页,学会了点布局的东西,但是始终觉得有点无聊.所以这几天就开始研究jquery代码了. 对于我这样一个初学者来说,有很多东西都只能用懵逼来形容,比如我看到这么一段代码(复制自amazeui): var checkin = $myStart2.datepicker({ onRender: function(date, viewMode) { // 默认 days 视图,与当前日期比较 var viewDate = nowDa