参考官方文档链接(可能需要梯子):http://www.coppeliarobotics.com/helpFiles/index.html

文章目录

  • 概述
  • 阻塞式函数调用模式(Blocking function calls)
    • 例1:读取UR5机械臂转轴句柄
  • 非阻塞式函数调用模式(Non-blocking function calls)
    • 例2:置位转轴角度
  • 数据流模式(Data streaming)
    • 例3:读取UR5机械臂转轴角度
  • 同步模式(Synchronous operation)
  • 附加内容

概述

remote API的使用方式与regularAPI类似,但是有2点不同:

  • 大多remote API都会返回一个位编码值:return code。因为return code是bit-coded的,所以需要测试每一个位来确定正确的含义。
  • 大多remote API都需要两个额外的参数:operation modeclientID(simxStart返回的标识符)。

需要operation modereturn code的原因是remote API函数需要通过socket通信机制从客户端到服务端(VREP),执行任务,返回客户端。一种简单的(或常规的)方法是让客户机发送请求,然后等待服务器处理请求并作出响应:在大多数情况下,这会花费太多的时间,而且延迟会损害客户机应用程序。实际上,remote API通过提供四种机制来执行函数或控制仿真过程,让用户选择operation mode和仿真进行的方式。

  • 阻塞式函数调用模式(Blocking function calls)
  • 非阻塞时函数调用模式(Blocking function calls)
  • 数据流模式(Data streaming)
  • 同步模式(Synchronous operation)

阻塞式函数调用模式(Blocking function calls)

阻塞式函数调用模式是一种简单常规的方式,适用于必须等待从服务端(VREP)返回信息的情形,比如如下情况:

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

下图阐明了阻塞式函数调用模式:

例1:读取UR5机械臂转轴句柄

详情:在场景中有一个UR5机械臂,以下代码读取机械臂各个轴的句柄值。
配套scene文件
链接:https://pan.baidu.com/s/1cAUe15T7FMDWrGgUjLm9aw
提取码:2w75

与下面例3场景一致。另外这个场景非常简单,就只是在空场景里拖拽一个UR5过去。自己操作就好,实在不放心可以再下载。

代码

import vrepvrep.simxFinish(-1) # just in case, close all opened connections
clientID=vrep.simxStart(  # clientID,经测试从0计数,若超时返回-1。若不返回-1,则应该在程序最后调用 simxFinish'127.0.0.1',          # 服务端(server)的IP地址,本机为127.0.0.119997,                # 端口号True,                 # True:程序等待服务端开启(或连接超时)True,                 # True:连接丢失时,通信线程不会尝试第二次连接2000,                 # 正:超时时间(ms)(此时阻塞函数时间为5s)负:阻塞函数时间(ms)(此时连接等待时间为5s)5)                    # 数据传输间隔,越小越快,默认5 # Connect to V-REPprint('Connected to remote API server')vrep.simxStartSimulation(clientID, vrep.simx_opmode_oneshot)RC1, UR5_joint1_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint1', vrep.simx_opmode_blocking)
RC2, UR5_joint2_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint2', vrep.simx_opmode_blocking)
RC3, UR5_joint3_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint3', vrep.simx_opmode_blocking)
RC4, UR5_joint4_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint4', vrep.simx_opmode_blocking)
RC5, UR5_joint5_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint5', vrep.simx_opmode_blocking)
RC6, UR5_joint6_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint6', vrep.simx_opmode_blocking)
print("RC1:",RC1)
print("UR5_joint1_Handle",UR5_joint1_Handle)
print("RC2:",RC1)
print("UR5_joint2_Handle",UR5_joint2_Handle)
print("RC3:",RC1)
print("UR5_joint3_Handle",UR5_joint3_Handle)
print("RC4:",RC1)
print("UR5_joint4_Handle",UR5_joint4_Handle)
print("RC5:",RC1)
print("UR5_joint5_Handle",UR5_joint5_Handle)
print("RC1:",RC1)
print("UR6_joint6_Handle",UR5_joint6_Handle)

非阻塞式函数调用模式(Non-blocking function calls)

非阻塞函数调用模式用在仅仅想给服务端(VREP)发送指令,而无需等待服务端返回信息的情况,例如如下情形:

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

下图阐明了非阻塞式函数调用模式:

例2:置位转轴角度

详情:在场景中有一个转轴(passive mode)A,连接着另一个转轴B。要把转轴A旋转1rad。
配套scene文件
链接:https://pan.baidu.com/s/1S5JPmIl_fz5qiovHEncINw
提取码:4scy
代码

import vrepvrep.simxFinish(-1) # just in case, close all opened connections
clientID=vrep.simxStart(  # clientID,经测试从0计数,若超时返回-1。若不返回-1,则应该在程序最后调用 simxFinish'127.0.0.1',          # 服务端(server)的IP地址,本机为127.0.0.119997,                # 端口号True,                 # True:程序等待服务端开启(或连接超时)True,                 # True:连接丢失时,通信线程不会尝试第二次连接2000,                 # 正:超时时间(ms)(此时阻塞函数时间为5s)负:阻塞函数时间(ms)(此时连接等待时间为5s)5)                    # 数据传输间隔,越小越快,默认5 # Connect to V-REPprint('Connected to remote API server')vrep.simxStartSimulation(clientID, vrep.simx_opmode_oneshot)
RC0, h= vrep.simxGetObjectHandle(clientID, 'j', vrep.simx_opmode_blocking)vrep.simxSetJointPosition(clientID,h,1,vrep.simx_opmode_oneshot)vrep.simxGetPingTime(clientID)  # 不可少,否则很可能不执行,后面会解释为什么

有些情形下,用一条指令传送多条信息是很重要的——这些信息会在服务端同时执行(例如让机器人的3个关节同时运动,即,在同一个仿真步中)。在这种情况下,用户可以暂停通信进程来实现,如下所示:

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 V-REP side at the same time

下图阐明了暂停通信进程的效果:

数据流模式(Data streaming)

服务端可以预测客户端需求的数据类型。要实现这一点,客户端必须用流(streaming)或者连续(continuous)操作模式flag向服务端发出此请求(即:函数被存放在服务端,在不需要客户端发出请求的情况下,定期执行并发送数据)。这可以看做是从客户端到服务端的命令(command)/信息(message)订阅,其中服务端像客户端提供数据流。在客户端这种数据流操作请求和读取流数据如下所示:

// 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_discontinue来实现停止传输。

例3:读取UR5机械臂转轴角度

详情:在场景中有一个UR5机械臂,以下代码读取机械臂各个轴的角度值。
配套scene文件
链接:https://pan.baidu.com/s/1cAUe15T7FMDWrGgUjLm9aw
提取码:2w75

与上面例1场景一致。另外这个场景非常简单,就只是在空场景里拖拽一个UR5过去。自己操作就好,实在不放心可以再下载。

代码:

import vrep
import timevrep.simxFinish(-1) # just in case, close all opened connections
clientID=vrep.simxStart(  # clientID,经测试从0计数,若超时返回-1。若不返回-1,则应该在程序最后调用 simxFinish'127.0.0.1',          # 服务端(server)的IP地址,本机为127.0.0.119997,                # 端口号True,                 # True:程序等待服务端开启(或连接超时)True,                 # True:连接丢失时,通信线程不会尝试第二次连接2000,                 # 正:超时时间(ms)(此时阻塞函数时间为5s)负:阻塞函数时间(ms)(此时连接等待时间为5s)!不太理解!5)                    # 数据传输间隔,越小越快,默认5 # Connect to V-REPprint('Connected to remote API server')vrep.simxStartSimulation(clientID, vrep.simx_opmode_oneshot)RC1, UR5_joint1_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint1', vrep.simx_opmode_blocking)
RC2, UR5_joint2_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint2', vrep.simx_opmode_blocking)
RC3, UR5_joint3_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint3', vrep.simx_opmode_blocking)
RC4, UR5_joint4_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint4', vrep.simx_opmode_blocking)
RC5, UR5_joint5_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint5', vrep.simx_opmode_blocking)
RC6, UR5_joint6_Handle = vrep.simxGetObjectHandle(clientID, 'UR5_joint6', vrep.simx_opmode_blocking)vrep.simxGetJointPosition(clientID, UR5_joint1_Handle, vrep.simx_opmode_streaming)
vrep.simxGetJointPosition(clientID, UR5_joint2_Handle, vrep.simx_opmode_streaming)
vrep.simxGetJointPosition(clientID, UR5_joint3_Handle, vrep.simx_opmode_streaming)
vrep.simxGetJointPosition(clientID, UR5_joint4_Handle, vrep.simx_opmode_streaming)
vrep.simxGetJointPosition(clientID, UR5_joint5_Handle, vrep.simx_opmode_streaming)
vrep.simxGetJointPosition(clientID, UR5_joint6_Handle, vrep.simx_opmode_streaming)while(True):if (vrep.simxGetJointPosition(clientID, UR5_joint1_Handle, vrep.simx_opmode_buffer)[0]  # 判断vrep是否开始回传数据& vrep.simxGetJointPosition(clientID, UR5_joint2_Handle, vrep.simx_opmode_buffer)[0]  # [0]是指return中的第0位,也即return code& vrep.simxGetJointPosition(clientID, UR5_joint2_Handle, vrep.simx_opmode_buffer)[0]& vrep.simxGetJointPosition(clientID, UR5_joint2_Handle, vrep.simx_opmode_buffer)[0]& vrep.simxGetJointPosition(clientID, UR5_joint2_Handle, vrep.simx_opmode_buffer)[0]& vrep.simxGetJointPosition(clientID, UR5_joint2_Handle, vrep.simx_opmode_buffer)[0])==vrep.simx_return_ok:for i in range(3):  # 提取3次关节角度rc1, j1_pos=vrep.simxGetJointPosition(clientID, UR5_joint1_Handle, vrep.simx_opmode_buffer)rc2, j2_pos=vrep.simxGetJointPosition(clientID, UR5_joint2_Handle, vrep.simx_opmode_buffer)rc3, j3_pos=vrep.simxGetJointPosition(clientID, UR5_joint3_Handle, vrep.simx_opmode_buffer)rc4, j4_pos=vrep.simxGetJointPosition(clientID, UR5_joint4_Handle, vrep.simx_opmode_buffer)rc5, j5_pos=vrep.simxGetJointPosition(clientID, UR5_joint5_Handle, vrep.simx_opmode_buffer)rc6, j6_pos=vrep.simxGetJointPosition(clientID, UR5_joint6_Handle, vrep.simx_opmode_buffer)print("j1_pos:", j1_pos)print("j2_pos:", j2_pos)print("j3_pos:", j3_pos)print("j4_pos:", j4_pos)print("j5_pos:", j5_pos)print("j6_pos:", j6_pos)print("-----------------------")time.sleep(0.2)breakelse:print("waiting for server response...")time.sleep(0.001)  # 0.001是我手调出来的,便于演示而已# 测试服务端是否继续在发送数据给客户端,以第一个关节为例
time.sleep(3)
if vrep.simxGetJointPosition(clientID, UR5_joint1_Handle, vrep.simx_opmode_buffer)[0]==vrep.simx_return_ok:print("客户端待机3秒后,服务端依然在发送数据。")print("关节1的角度为",vrep.simxGetJointPosition(clientID, UR5_joint1_Handle, vrep.simx_opmode_buffer)[1])elif vrep.simxGetJointPosition(clientID, UR5_joint1_Handle, vrep.simx_opmode_buffer)[0]==vrep.simx_return_novalue_flag:print("客户端待机3秒后,服务端已停止发送数据。")# 强制擦除存放在服务端的指令,再测试服务端是否还在发送数据
print('擦除存放在服务端的指令...')
while True:# 因为客户端到服务端的指令是有延迟的,所以需要这个While循环来确保确实已经擦除服务端的命令,实际使用时不必这样测试。# 另外这里面的逻辑需要注意一下,第一次检测到vrep.simx_return_novalue_flag时,应该是While循环第一个指令造成的,而不是# 当前的那个rc1, j1_pos=vrep.simxGetJointPosition(clientID, UR5_joint1_Handle, vrep.simx_opmode_discontinue)if rc1==vrep.simx_return_ok:print("waiting for server response...")time.sleep(0.001)  # 0.001是我手调出来的,便于演示而已elif rc1==vrep.simx_return_novalue_flag:print("server responds!")breakif vrep.simxGetJointPosition(clientID, UR5_joint1_Handle, vrep.simx_opmode_buffer)[0]==vrep.simx_return_ok:print("强制擦除后,服务端依然在发送数据。")print("关节1的角度为",vrep.simxGetJointPosition(clientID, UR5_joint1_Handle, vrep.simx_opmode_buffer)[1])
elif vrep.simxGetJointPosition(clientID, UR5_joint1_Handle, vrep.simx_opmode_buffer)[0]==vrep.simx_return_novalue_flag:print("强制擦除后,服务端已停止发送数据。")
Connected to remote API server
waiting for server response...
waiting for server response...
waiting for server response...
waiting for server response...
waiting for server response...
waiting for server response...
j1_pos: 0.04933595657348633
j2_pos: 0.04936075210571289
j3_pos: -0.049343109130859375
j4_pos: 0.04935884475708008
j5_pos: 0.04934239387512207
j6_pos: 0.049343109130859375
-----------------------
j1_pos: 0.9543983936309814
j2_pos: 0.9548768997192383
j3_pos: -0.955643892288208
j4_pos: 0.9558093547821045
j5_pos: 0.9556386470794678
j6_pos: 0.9556429386138916
-----------------------
j1_pos: 1.5655755996704102
j2_pos: 1.565735101699829
j3_pos: -1.5655508041381836
j4_pos: 1.5706815719604492
j5_pos: 1.5680694580078125
j6_pos: 1.568070411682129
-----------------------
客户端待机3秒后,服务端依然在发送数据。
关节1的角度为 -9.5367431640625e-07
擦除存放在服务端的指令...
waiting for server response...
waiting for server response...
waiting for server response...
waiting for server response...
waiting for server response...
server responds!
强制擦除后,服务端已停止发送数据。

同步模式(Synchronous operation)

以上3种模式在仿真进行时服务端只管往前运行,并不考虑客户端的进度。Remote API在默认情况下是异步运行的。但有时候,我们需要客户端与仿真过程同步——通过远程API控制仿真进度实现。这可以用Remote API的同步模式实现。此时服务端需要提前设置为同步模式。
服务端设置同步模式可以通过以下几种方式实现

  • simRemoteApi.start函数
  • 连续remote API服务端服务配置文件remoteApiConnections.txt
    以下是同步模式的例子
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 executedsimxSynchronousTrigger(clientID); // Trigger next simulation step (Blocking function call)// The first simulation step is now being executedsimxSynchronousTrigger(clientID); // Trigger next simulation step (Blocking function call)// The second simulation step is now being executed...

下图阐明了同步操作模式:

当调用同步触发器(simxSynchronousTrigger)时,下一个仿真步开始计算。这并不意味着当函数调用返回时,下一个模拟步骤将完成计算。因此,您必须确保读取正确的数据。如果没有采取特殊措施,则可能从之前的仿真步骤或当前仿真步骤读取数据,如下图所示:

有几种方式来克服以上的问题。
最简单的方法是在调用同步触发器(simxSynchronousTrigger)后直接以阻塞方式调用函数(其实这里官网想表达的意思是直接调用一个阻塞方式的函数,函数任意,比如simxGetPintTime,原因嘛,就是让这个阻塞过程来强制占用(这里不好解释了)):

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 executedsimxSynchronousTrigger(clientID); // Trigger next simulation step (Blocking function call)// The first simulation step is now being executedsimxGetPingTime(clientID); // After this call, the first simulation step is finished (Blocking function call)// Now we can safely read all streamed values

下图说明了上述过程

下图说明了如何在服务器端(即在V-REP远程API插件端)处理初始化的远程API命令:

附加内容

在客户端(即,你的IDE),最少会运行两个线程:①主线程(从中调用Remote API);②通信线程(从中传送数据)。在客户端,可以有任意多的通信线程(通信线):可用simxStart来启动每一个。在服务器端使用V-REP插件实现,以类似的方式运行。下图说明了Remote API的工作方式:

  • simx_opmode_oneshot:非阻塞模式(non-blocking mode)。命令送去服务端执行(1)-(b)-(3)。从本地缓冲区返回对先前执行的同一命令的响应(如果有的话(i)-(2))。函数不等待从服务端(7)-(i)的响应。
    在服务端,指令被暂存在(4)-(d),沿着(d)-(9)-(g)执行一次,并沿着(g)-(6)传送响应结果。这个模式常常被“设置类函数(set-functions)”(如simxSetJointPosition)使用,用户并不关心返回值。
  • simx_opmode_blocking:阻塞模式(blocking mode)。命令送去服务端执行(1)-(b)-(3),并等待从服务端返回的响应(7)-(i)-(2)。然后接收到的响应被从输入箱缓存中删除(i),这操作是阻塞模式独有的。
    在服务端,指令被暂存在(4)-(d),沿着(d)-(9)-(g)执行一次,并沿着(g)-(6)传送响应结果。这个模式常常被“得到类函数(get-functions)”(如simxGetObjectHandle)使用,用户需要得到响应。
  • simx_opmode_streaming:非阻塞模式(non-blocking mode)。命令送去服务端执行(1)-(b)-(3)。从本地缓冲区返回对先前执行的同一命令的响应(如果有的话(i)-(2))。函数不等待从服务端(7)-(i)的响应。
    simx_opmode_oneshot类似,但是在服务端指令被暂存在(4)-(e)(而非(4)-(d)),连续执行(e)-(9)-(g),并持续传送回客户端(g)-(6)。这个模式常常被“得到类函数(set-functions)”(如simxGetJointPosition)使用,用户经常需要一个特定的值。
  • simx_opmode_oneshot_split
  • simx_opmode_streaming_split
  • simx_opmode_discontinue
  • simx_opmode_buffer:非阻塞模式(non-blocking mode)。不向服务端传送指令,但是如果(i)-(2)可用,则从本地缓冲区返回对先前执行的相同命令的响应。此模式通常与simx_opmode_streamingsimx_opmode_streaming_split操作模式一起使用:首先,用一个streaming指令启动,然后提取数据。
  • simx_opmode_remove

VREP Remote API工作模式详解(未写完,完成度90%)相关推荐

  1. RabbitMQ工作流程和工作模式详解

    RabbitMQ工作流程 生产者发送消息的流程 生产者连接RabbitMQ,建立TCP连接( Connection),开启信道(Channel) 生产者声明一个Exchange(交换器),并设置相关属 ...

  2. linux apache两种工作模式详解

    apache两种工作模式详解 刚接触这两个配置时很迷糊,全部开启或全部注释没有几多变化.今天搜索到这么一篇讲得还不错的文章,看了几篇,还是不能完全记住,做一个收藏. 空闲子进程:是指没有正在处理请求的 ...

  3. 无线Wifi模块AP和STA工作模式详解

    无线Wifi模块AP和STA工作模式详解 Wifi模块包括两种工作模式AP和STA,在这两模式的支持下,无线图传产品可以实现一发多收的功能.下面我们就从AP和STA的基本概念开始了解它们. 一.AP和 ...

  4. ST MCU_GPIO的八种工作模式详解

    GPIO的八种工作模式详解 浮空输入_IN_FLOATING 带上拉输入_IPU 带下拉输入_IPD 模拟输入_AIN 开漏输出_OUT_OD 推挽输出_OUT_PP 开漏复用输出_AF_OD 推挽复 ...

  5. V90 PN伺服EPOS回零+点动JOG+MDI+程序步具体工作模式详解

    V90 PN伺服EPOS回零+点动JOG+MDI+程序步具体工作模式详解 1. 回零  增量式编码器主动回零 在配置回零参数界面,选择回参考点方式: 0:信号REF 即直接设定参考点方式(将当前位置 ...

  6. LVS工作原理以及三种工作模式详解

    1.负载均衡LVS基本介绍 LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director Server上,然后它把用户的请求根据设置好的调度算法,智能均衡地分发到后端真正服务器(r ...

  7. Linux下snort的运行模式,Snort工作模式详解

    Snort有3种工作模式,分别为嗅探器模式.分组数据包记录模式与网络**检测模式. m     嗅探器模式. Snort使用Libpcap包捕获库.在该模式下,Snort使用网络接口的混杂模式读取并解 ...

  8. GPIO工作模式详解(含Arduino实例)

    1. GPIO介绍 从最基础的51单片机,Arduino,到STM32,树莓派等等,这些上面都会有GPIO口这么一个概念,如果你点开了我这个博客,说明你大概率开始学习单片机,那么你应该了解的就是这些口 ...

  9. 摘抄--apache工作模式详解

    服务器优化配置 Apache的主要优势就是能更好地支持多处理器,在编译时通过使用--with-mpm选项来决定Apache的工作模式.如果知道当前的Apache使用的工作机制,则可以通过httpd - ...

最新文章

  1. 用c语言描述单链表的数据类型,数据结构—单链表(类C语言描述)
  2. Android 开发 技术大纲 某学课堂
  3. PHP页面间参数传递的四种方式
  4. springboot整合servlet
  5. RocketMQ源码解析:Filtersrv
  6. 【284天】我爱刷题系列(43)
  7. 在浏览器控制台输出内容 console.log(string);
  8. 这是一个我面试某公司的算法题目:对一个字符数组进行排序,根据给定的字符,大于它的,放在数组的左边,小于它的,放在数组的右边,且数组中的元素之间的相对位置要保持不变。...
  9. 五个温度带的分界线_亚热带,暖温带,到底是些什么带?
  10. oracle net conf启动无反应,weblogic突然无法启动,显示Server state changed to FORCE
  11. C++基础:第五章 表达式基础与详述
  12. linux zmq编译pgm,czmq交叉编译
  13. [地图代数]处理DEM中的高程异常值——ArcGIS栅格计算的应用
  14. 考研数学真题复盘(2013-2016)
  15. Acer 4750 安装黑苹果_超详细安装黑苹果教程
  16. 关于网络超时时间那些事
  17. mysql 数据库update_[数据库]MySQL 常用的UPDATE操作
  18. 【历史上的今天】3 月 2 日:雅虎正式成立;PC 设计先驱诞生;Excite@Home 破产
  19. 红帽linux员工数,红帽企业 Linux Atomic Host 管理
  20. srand c语言,C语言srand()rand()

热门文章

  1. RNA-seq数据下载
  2. 国内服务器证书,中国互联网协会-CNNIC推出国内首个服务器域名证书
  3. UNITY 虚拟相机 Cinemachine 第三人称视角 新输入系统 超简单
  4. python 窗口置顶_PyQt5 窗口置顶
  5. html 窗口置顶,通用窗口置上(窗口置顶)工具
  6. 窗口置顶工具v2.0.0
  7. 解决Mingw-w64下载太慢问题
  8. 查看apk的包名和启动页activity,adb命令启动app
  9. robomongo(robo3T)操作MongoDB数据库常用命令
  10. 博图安装msi失败_博途V13 安装的时候出现一个 MSI File initialization failed:ERROR_INSTALL_FAILURE 请问是怎么回事啊?...