CoppeliaSim笔记(1):remote API的使用

先简单说明一下CoppeliaSim中控制机器人仿真的7种方式:

  • 1.编写child script
    • 优点:这是最便捷的控制方法,且与最后三种控制方式比较,不会出现通信延迟.
    • 缺点:无法选择编程语言(只有Lua),执行速度比较慢,无法访问Lua以外的外部函数库。
  • 2.编写plugin
    • 这种方式通常与第一种方式联合使用;
    • 优点:可以访问外部函数库,同样没有通信延迟;
    • 缺点:比编程更加复杂,且需要外部工具编译。
  • 3,4.编写外部客户端应用(remote API)
    • 如果需要从外部应用(或机器人,或另一台计算机)运行控制程序,这是一种非常方便和简单的方法,它支持C/C++PythonMatlab等语言。
  • 5.通过ROS node
    • 该方法与remote API相似,是一种便利的方法让多个分布式进程互相通信。虽然remote API更加轻量和快速,但它只能与CoppeliaSim进行信息交互;
    • 可以与任意数量的进程通信,且存在大量可兼容的库可供使用;
    • 缺点:相比于remote API,该方法更加笨重且复杂。
  • 6.BlueZero node
    • 与ROS类似,是一种便利的方法让多个分布式进程互相通信;
    • 轻量,可跨平台。
  • 7.编写外部通信应用
    • 优点:可以选择编程语言,且控制代码可以运行在机器人或不同计算机上.
    • 缺点:相比于remote API,该方法更加单调乏味。

由于不熟悉Lua语言,于是最好的选择就是使用remote API进行仿真控制,因此主要需要熟悉这部分的操作。

1.remote API的简单介绍

remote API是整个CoppeliaSim API框架的一部分,它可以允许CoppeliaSim 与外部应用进行交互。最大的特点就是它支持C/C++PythonMatlab等语言。这对于不会Lua的人来说,十分友好。

remote API分为两个部分,分别为服务器端以及客户端。外部应用通过与服务器端进行交互,从而实现与CoppeliaSim的联合仿真。

  • the client side (i.e. your application):应用端,支持C/C++, Java, Python, Matlab, Octave and Lua。这部分内容是我们实现的仿真的重点。

  • the server side (i.e. CoppeliaSim):服务器端,只能通过CoppeliaSim的插件实现。服务器服务可以由两种方式开启:

    1.At CoppeliaSim start-up (continuous remote API server service). 这种启动方式会尝试读取相关的配置文件remoteApiConnections.txt ,根据其内容来启动服务器服务。通过这种方式启动,服务器会一直运行,即使仿真不在运行。

    2.From within a script (temporary remote API server service). 通过场景脚本启动,这是我们最常用的启动方式。 这种服务是暂时的,当仿真开始时,服务器会启动;当仿真结束后,服务器则会自动关闭。

    以下程序是一个简单的脚本,在初始化时会建立一个暂时的remote API的服务器。

    function sysCall_init()
        repeat until (simRemoteApi.start(19999,1300,false,true)~=-1)
    end
    
    function sysCall_actuation()
        -- put your actuation code here
    end
    
    function sysCall_sensing()
        -- put your sensing code here
    end
    
    function sysCall_cleanup()
        -- do some clean-up here
    end
    

    Enabling the remote API - server side (coppeliarobotics.com)

注:在使用remote API时,不要忘记在CoppeliaSim设置服务端的启动脚本。

目前为止,remote API有两个版本:

  • The B0-based remote API (v2):新版是基于BlueZero中间件和它对CoppeliaSim的接口插件的。 相比于第一版,新版的remote API的使用更加简单和灵活,而且易于扩展。目前它支持以下语言:C++, Java, Python, Matlab and Lua。
  • The legacy remote API(v1):旧版的remote API,相比于第二版,旧版更加轻量,而且需要的依赖少于新版。目前它支持以下语言:C/C++, Java, Python, Matlab, Octave and Lua。

无论是使用哪一个版本,都需要先在本地文件夹内放入指定的源文件。应该放哪些文件以及这些文件的位置,可以参考官方文档:

2.remote API的工作方式(如何与服务端通信)

Remote API modus operandi (coppeliarobotics.com)

remote API函数与regular API函数十分类似,但是有两个主要的区别:

  • 大部分remote API都会返回一个值:return code,它是服务端返回给客户端的应答。
  • 大部分remote API需要两个额外的输入参数:
    1. 运行模式operation mode
    2. 客户端IDclientID

remote API的工作方式本质上就是通过网络套接字,与服务端进行通信。传统的网络通信过程就是

  1. 客户端向服务端发送请求,比如获得机械臂某个关节的角度;
  2. 服务端接收到请求后,将需要的数据和应答发送回客户端。在这个过程中,客户端处于堵塞的情况。

在大多数情况下,这种通信方式会浪费大量时间。remote API允许用户选择允许方式的类型,提供了4种主要的运行机制来控制仿真的进程,用户可以根据需求灵活改变通信方式。 比如,对于一些重要的命令,可以采用堵塞方式,而对于如设置机械臂关节角的命令则可以使用非堵塞的形式。

4.1.Blocking function calls

这种运行方式就是最传统的堵塞机制,客户端在接收到服务端数据前会一直处于堵塞状态。

// 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!    
}

在这里插入图片描述

4.2.Non-blocking function calls

处于这种通信方式下,客户端只会向服务端发送请求,但没有必要等待服务端的回复。如以下情况,客户端发送请求后,服务端只需要设置相应的关节角度即可,没有必要向客户端发送回复。

// Following function (non-blocking mode) will set the position of a joint:
simxSetJointPosition(clientID,jointHandle,jointPosition,simx_opmode_oneshot); 

在这里插入图片描述

在一些情况下,我们需要用一条消息来发送多个数据,因为我们希望这些数据可以同时到达服务端。比如,我们希望机械臂的三个关节同时运动。在这种情况下,用户可以通过暂时中断通信来实现,如下所示:

simxPauseCommunication(clientID,1);  // 中断通信
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 CoppeliaSim side at the same time

在这里插入图片描述

4.3.Data streaming

这种通信方式比较特殊,类似于话题订阅的形式。客户端先向服务端说明需要什么类型的数据,然后当服务端有空时就会将这类数据发送给客户端。需要注意,服务端向客户端发送数据并不是一次就结束的,而是一直进行的。 相当于在客户端与服务端架设了一条数据流,服务端会一直向客户端发送客户端订阅的数据。

// 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.

// Before disconnecting from CoppeliaSim, make sure to disable the streamings you previously enabled:
simxGetJointPosition(clientID,jointHandle,&jointPosition,simx_opmode_discontinue);
simxGetPingTime(clientID,&pingTime); // needed to insure that above reaches CoppeliaSim before disconnection

在这里插入图片描述

若要服务端停止发送,则客户端必须向服务端发送一个停止的请求,使用simx_opmode_discontinue模式。 若客户端没有发送停止请求,那么服务端会一直发送无用的数据,最终会导致运行速度的下降。

此外,当我们用特定命令(如:simxGetJointPosition)架设好数据流之后,那么这个命令就不应该再使用除simx_opmode_buffersimx_opmode_discontinue之外的其它模式,否则客户端这边的数据流就会中断,但是服务端那边仍然会一直发送数据。但是,对于其它还没有架设数据流的命令来说,则没有这种限制。

4.4.Non-blocking, non-streaming data query

这种通信方式相当于一次性的Data streaming。它只会执行一次,而不会向Data streaming一样会一直发送数据。

// Request vision sensor data (function returns immediately (non-blocking)):
simxGetVisionSensorImage(clientID,sensorHandle,res,&img,0,simx_opmode_oneshot);
...
// Check later if some data has arrived (non-blocking):
if (simx_return_ok==simxGetVisionSensorImage(clientID,sensorHandle,res,&img,0,simx_opmode_buffer))
{ // yes, we have an image!
    ...
}

4.5.Synchronous operation

了解以上4种通信模式后,你可能会发现,在仿真运行时,这些方式都没有考虑客户端的运行情况。也就是说,服务端与客户端默认是异步运行的。这就会导致两边的仿真时间很可能会不一致。

Synchronous operation就是为了解决这个问题而设计的。在这种模式下,服务端的仿真运行完全交由客户端控制。 话句话说,只有当客户端发送可以运行下一步时,服务端才会运行下一步,否则就会一直停在之前一步。

remote API必须处于同步模式下才能使用这种通信方式。

simxSynchronous(clientID,true); // Enable the synchronous mode (Blocking function call)
simxStartSimulation(clientID,simx_opmode_oneshot);

// The first simulation step waits for a trigger before being executed

simxSynchronousTrigger(clientID); // Trigger next simulation step (Blocking function call)

// The first simulation step is now being executed

simxSynchronousTrigger(clientID); // Trigger next simulation step (Blocking function call)

// The second simulation step is now being executed

...

在这里插入图片描述

当调用simxSynchronousTrigger时,下一步仿真就会开始计算。但是这并不意味着当该函数返回后,这一步仿真就已经完成计算了。 因此,在使用时必须保证仿真已经运行结束,否则可能会得到错误的数据。

如下图所示,程序在第二次调用simxGetJointPosition时,显然上一步仿真还没有处理结束,因此获得的是上一步的数据;在第三次调用simxGetJointPosition时,仿真才处理结束。显然,程序已经无法保证获得的数据是哪一步的了。

在这里插入图片描述

下面提供了一个最简单的方法解决上述问题,即在每次调用simxSynchronousTrigger后,均调用一次simxGetPingTimesimxGetPingTime会在这一步仿真处理结束前,让程序一直处于堵塞状态,如下图所示。

simxSynchronous(clientID,true); // Enable the synchronous mode (Blocking function call)
simxStartSimulation(clientID,simx_opmode_oneshot);

// The first simulation step waits for a trigger before being executed

simxSynchronousTrigger(clientID); // Trigger next simulation step (Blocking function call)

// The first simulation step is now being executed

simxGetPingTime(clientID); // After this call, the first simulation step is finished (Blocking function call)

// Now we can safely read all streamed values

在这里插入图片描述

CoppeliaSim是一款强大的机器人仿真软件,可以用于机器人控制算法的开发和测试。它提供了丰富的功能和工具,可以模拟各种机器人和环境,并提供了远程API接口,使用户可以通过编程语言与仿真环境进行交互。 根据引用\[1\]和引用\[2\]的内容,你提到在使用CoppeliaSim时遇到了一些问题。你尝试了sim.simxStopSimulation来结束仿真,但无法重新启动。通过查阅资料和参考他人的代码,你发现了一个小改动,成功解决了问题。同时,引用\[2\]提供了一个简单的方法来解决这个问题,即在每次调用simxSynchronousTrigger后,调用simxGetPingTime来让程序处于堵塞状态,确保仿真处理结束。 此外,引用\[3\]提到了通过场景脚本启动CoppeliaSim的方式,这是最常用的启动方式之一。通过场景脚本启动的服务是临时的,当仿真开始时,服务器会启动,当仿真结束后,服务器会自动关闭。 综上所述,CoppeliaSim是一款功能强大的机器人仿真软件,可以通过远程API接口与其进行交互。在使用过程中,你遇到了一些问题,但通过查阅资料和参考他人的代码,成功解决了。同时,你还可以通过场景脚本启动CoppeliaSim来进行仿真。 #### 引用[.reference_title] - *1* [CoppeliaSim(原V-REP)新手上路](https://blog.csdn.net/qq_37051669/article/details/115324851)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [CoppeliaSim笔记1):remote API使用](https://blog.csdn.net/Azahaxia/article/details/119358892)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值