V-rep (Virtual robot experimentation platform)
V-rep Overview
http://www.coppeliarobotics.com/assets/v-repoverviewpresentation.pdf
V-rep Licenses
http://www.coppeliarobotics.com/assets/v-replicensingoverview.pdf
User Settings:
http://www.coppeliarobotics.com/helpFiles/en/settings.htm
Scene
.ttt
http://www.coppeliarobotics.com/helpFiles/en/scenes.htm
Each scene in V-REP has eight freely configurable pages. Individual pages can be accessed (i.e. displayed) through the page selector toolbar button:
Model
.ttm
http://www.coppeliarobotics.com/helpFiles/en/models.htm
Build clean model
http://www.coppeliarobotics.com/helpFiles/en/buildingAModelTutorial.htm
Shapes:
http://www.coppeliarobotics.com/helpFiles/en/shapes.htm
Object common properties:
Selectable: indicates whether the object can be selected in the scene. Objects can always be selected in the scene hierarchy. Refer also to the simSetObjectProperty function.
Invisible during selection: when enabled, then the object will be invisible for the selection process (i.e. you will be able to select through the object).
Ignored by depth pass: when enabled, then the object will be ignored during the depth rendering pass. The depth rendering pass is used to correctly position the red sphere for camera movements.
Select base of model instead: if enabled, then selecting the object in the scene will select its first parented object marked as object is model base instead (see further down). This property is convenient when protecting a model from faulty manipulations, allowing it to be manipulated as a single entity together with other objects. Refer to the section on models and also to the simSetObjectProperty function.
Don't show as inside model selection: when selected, and the object is part of a model, then the model bounding box (i.e. model selection bounding box) will not encompass that object. This is useful for invisible objects that might make the model bounding box appear too big. This property has no functional effect. Refer also to the simSetObjectProperty function.
Size factor: every object can be scaled (resized) at any time, also during simulation. The size factor will be scaled in a similar way and can be accessed programmatically in order to adjust a code's behavior (e.g. child script). Imagine a 2-wheeled kinematic robot whose movement is controlled in a simple way through a
child script: the child script will calculate the new position of the robot according to several parameters (wheel rotation velocity, wheel diameter and distance between the two wheels). If the user scales the robot, the child script should adjust its calculation according to the new size parameters (wheel diameter and distance between the two wheels). It can do that by using the simGetObjectSizeFactor API function.
Ignored for view-fitting: objects with this item selected will not be taken into account when fitting a scene to a view while no object is selected. Usually floors and similar will be tagged as such. Refer also to the view fitting toolbar button and to the simCameraFitToView api function.
Extension string: a string that describes additional object properties, mainly used by extension plugins (see also the simGetExtensionString API function).
Camera visibility layers: each object in V-REP can be assigned to one or several visibility layers. If there is at least one visibility layer that matches the layer selection dialog layers, then the object will be visible when seen from a camera. By default, a shape is assigned to the first layer, a joint to the second layer, a dummy to the third layer, etc.
Can be seen by: allows to specify a camera or vision sensor (or a collection containing cameras or vision sensors) that will be the only one able to see the object.
Collidable: allows enabling or disabling collision detection capability for the selected collidable object.
Measurable: allows enabling or disabling minimum distance calculation capability for the selected measurable object.
Detectable: allows enabling or disabling proximity sensor detection capability for the selected detectable object. Clicking details allows you to edit the detectable details. Renderable: allows enabling or disabling the vision sensor detection capability for the selected renderable object.
Cuttable: allows enabling or disabling the mill cutting capability for the selected cuttable object.
Object is model base: indicates whether the object should act as the base of a model. An object flagged as base of model has special properties (e.g. saving or copying the object will also automatically save/copy all its children and children's children, etc.). Additionally, when such an object is selected, the selection bounding box is displayed as thick stippled lines, encompassing the whole model. Refer to models, and to the select base of model instead item above.
Edit model properties: allows opening the model dialog. Object / model can transfer or accept DNA: when this feature is enabled for an object or a model, then it will share a same identifier with all of its copies. An Object or model can then transfer its DNA (i.e. copy an instance of itself) to all of its siblings (i.e. objects/models with the same identifier), via the transfer DNA toolbar button. Imagine having 100 same robots in your scene that you want to modify in a similar way: simply modify one of them, select it, then click the transfer DNA toolbar button. This item should almost always be checked for a model base (see further up), to facilitate model re-instanciation.
Main script:
http://www.coppeliarobotics.com/helpFiles/en/mainScript.htmeditor
Child scripts:
http://www.coppeliarobotics.com/helpFiles/en/childScripts.htm
Joints
Dynamically enabled joints are joints that are in force or torque mode or that operate in hybrid fashion, and that have a shape as parent object and exactly one child object which must be a non-static shape. In addition, it is possible to involve a joint in a loop closure configuration. In that case the joint has to connect to the two shapes through a dummy-dummy link (where the link type has to be Dynamics, overlap constraint).
Joint properties:
http://www.coppeliarobotics.com/helpFiles/en/jointProperties.htm
Joint dynamic properties:
http://www.coppeliarobotics.com/helpFiles/en/jointDynamicsProperties.htm
Joint control callback functions:
http://www.coppeliarobotics.com/helpFiles/en/jointCtrlCallbackScripts.htm
利用 Python remote API 設定 Joints 變數:
For the simxSetJointPosition function to work, the joint should not be in force/torque mode. If the joint is in force/torque mode, the motor enabled, and the position control enabled, then use the simxSetJointTargetPosition instead. Also make sure the joint is dynamically enabled.
參考程式:
try: import vrep except: print ('--------------------------------------------------------------') import time def connectVREP(): vrep.simxFinish(-1) # just in case, close all opened connections clientID=vrep.simxStart('127.0.0.1',19999,True,True,5000,5) # Connect to V-REP if clientID!=-1: print ('Connected Remote Api') vrep.simxStartSimulation(clientID,vrep.simx_opmode_oneshot_wait) vrep.simxSynchronous(clientID,True) return clientID else: print ('ERROR! Error connecting Remote Api') sys.exit(0); def startSim(clientID): vrep.simxStartSimulation(clientID,vrep.simx_opmode_oneshot) def stopSim(clientID): vrep.simxStopSimulation(clientID,vrep.simx_opmode_oneshot_wait) def disconnectVREP(clientID): # Now close the connection to V-REP: vrep.simxFinish(clientID) print('Connection finished') clientID=connectVREP() ret,joint1_handler = vrep.simxGetObjectHandle(\ clientID,"redundantRob_joint1",vrep.simx_opmode_oneshot_wait) ret,joint1 = vrep.simxGetJointPosition(\ clientID,joint1_handler,vrep.simx_opmode_streaming) ret,joint2_handler = vrep.simxGetObjectHandle(\ clientID,"redundantRob_joint2",vrep.simx_opmode_oneshot_wait) ret,joint2 = vrep.simxGetJointPosition(\ clientID,joint2_handler,vrep.simx_opmode_streaming) startSim(clientID) ret,joint1 = vrep.simxGetJointPosition(\ clientID,joint1_handler,vrep.simx_opmode_buffer) print joint1 #Get position joint 1 ret,joint2 = vrep.simxGetJointPosition(\ clientID,joint2_handler,vrep.simx_opmode_buffer) print joint2 #Get position joint 2 ret = vrep.simxSetJointPosition(\ clientID,joint1_handler,pi/2,vrep.simx_opmode_oneshot) #Set pi/2 to joint 1 time.sleep(2) stopSim(clientID) time.sleep(1) disconnectVREP(clientID)
利用 remote API 執行緒程式設定 Joint 變數:
import threading import time import sys import traceback sys.path.insert(0, 'C:\\Program Files\\V-REP3\\V-REP_PRO_EDU\\programming\\Python') import vrep class Joint(threading.Thread): def __init__(self, joint_name, port): threading.Thread.__init__(self) self.client_id = -1 self.port = port self.joint_name = joint_name def run(self): try: # connect to V-REP server self.client_id = vrep.simxStart("127.0.0.1", self.port, False, True, 5000, 5) if self.client_id == -1: raise Exception('Failed to connect V-REP remote API server.') # get handle res, p = vrep.simxGetObjectHandle(self.client_id, self.joint_name.encode(), vrep.simx_opmode_oneshot_wait) if res == vrep.simx_error_noerror: print('[Joint %s] handle= %s' % (self.joint_name, p)) else: raise Exception('Error in getting joint handles.') except Exception as e: print('[Joint %s] %s' % (self.joint_name, e.args[0])) traceback.print_exc() finally: # disconnect with V-REP server vrep.simxFinish(self.client_id) if __name__ == "__main__": joints = [Joint("joint1", 19999), Joint("joint2", 19998)] for joint in joints: joint.start() time.sleep(0.1) time.sleep(1) for joint in joints: joint.join() print("Done")
Dummy properties:
http://www.coppeliarobotics.com/helpFiles/en/dummyPropertiesDialog.htm
Dummy functions:
http://www.coppeliarobotics.com/helpFiles/en/dummiesDescription.htm
Loop closure:
Dynamic simulations:
http://www.coppeliarobotics.com/helpFiles/en/designingDynamicSimulations.htm#staticAndRespondable
Motion planning:
http://www.coppeliarobotics.com/helpFiles/en/motionPlanningModule.htm
Means of communication:
http://www.coppeliarobotics.com/helpFiles/en/meansOfCommunication.htm
V-rep API
Embedded scripts:
http://www.coppeliarobotics.com/helpFiles/en/scripts.htm
Lua crash course:
http://www.coppeliarobotics.com/helpFiles/en/luaCrashCourse.htm
http://www.lua.org/pil/contents.html
Access objects:
http://www.coppeliarobotics.com/helpFiles/en/accessingGeneralObjects.htm
V-rep API 函式列表:
http://www.coppeliarobotics.com/helpFiles/en/apiFunctionListCategory.htm
V-rep 外部控制方法:
http://www.coppeliarobotics.com/helpFiles/en/externalControllerTutorial.htm
V-rep remote API 範例
根據 http://www.coppeliarobotics.com/helpFiles/en/remoteApiServerSide.htm 中的說明.
V-rep 啟動時, 會根據系統目錄下 remoteApiConnections.txt 檔案中的設定, 啟動 rempte api 功能.
以下為 one-link robot 的 V-rep remote API 程式範例:
import vrep import sys # child threaded script: # 內建使用 port 19997 若要加入其他 port, 在 serve 端程式納入 #simExtRemoteApiStart(19999) vrep.simxFinish(-1) clientID = vrep.simxStart('127.0.0.1', 19997, True, True, 5000, 5) if clientID!= -1: print("Connected to remote server") else: print('Connection not successful') sys.exit('Could not connect') errorCode,Revolute_joint_handle=vrep.simxGetObjectHandle(clientID,'Revolute_joint',vrep.simx_opmode_oneshot_wait) if errorCode == -1: print('Can not find left or right motor') sys.exit() errorCode=vrep.simxSetJointTargetVelocity(clientID,Revolute_joint_handle,2, vrep.simx_opmode_oneshot_wait) while True: choice = input("(e to exit, p to pause and enter to exec)>") if choice == "e": print("exiting") vrep.simxStopSimulation(clientID, vrep.simx_opmode_oneshot_wait) break elif choice == "p": vrep.simxPauseSimulation(clientID, vrep.simx_opmode_oneshot_wait) else: vrep.simxStartSimulation(clientID, vrep.simx_opmode_oneshot_wait)
V-rep Remote API 呼叫模式
http://www.coppeliarobotics.com/helpFiles/en/remoteApiModusOperandi.htm
當 V-rep remote API 需要送出資料讓三軸同動時:
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
在 V-rep 端設定變數值:
simSetIntegerSignal("mySignalName",42)
之後, 可以從 client 端, 以 remote API streaming 模式取得該變數值:
res,signalValue=simxGetIntegerSignal(clientId,"mySignalName", vrep.simx_opmode_streaming)
當然, 也可以反方向, 從 V-rep 端取得 client 端的變數值.
參考範例:
# Make sure to have the server side running in V-REP: # in a child script of a V-REP scene, add following command # to be executed just once, at simulation start: # # simExtRemoteApiStart(19999) # # then start simulation, and run this program. # # IMPORTANT: for each successful call to simxStart, there # should be a corresponding call to simxFinish at the end! try: import vrep except: print '--------------------------------------------------------------' print '"vrep.py" could not be imported. This means very probably that' print 'either "vrep.py" or the remoteApi library could not be found.' print 'Make sure both are in the same folder as this file,' print 'or appropriately adjust the file "vrep.py"' print '--------------------------------------------------------------' print '' import time print ('Program started') vrep.simxFinish(-1) # just in case, close all opened connections clientID=vrep.simxStart('127.0.0.1',19999,True,True,5000,5) # Connect to V-REP if clientID!=-1: print ('Connected to remote API server') # Now try to retrieve data in a blocking fashion (i.e. a service call): res,objs=vrep.simxGetObjects(clientID,vrep.sim_handle_all,vrep.simx_opmode_oneshot_wait) if res==vrep.simx_return_ok: print ('Number of objects in the scene: ',len(objs)) else: print ('Remote API function call returned with error code: ',res) time.sleep(2) # Now retrieve streaming data (i.e. in a non-blocking fashion): startTime=time.time() vrep.simxGetIntegerParameter(clientID,vrep.sim_intparam_mouse_x,vrep.simx_opmode_streaming) # Initialize streaming while time.time()-startTime < 5: returnCode,data=vrep.simxGetIntegerParameter(clientID,vrep.sim_intparam_mouse_x,vrep.simx_opmode_streaming) # Try to retrieve the streamed data if returnCode==vrep.simx_return_ok: # After initialization of streaming, it will take a few ms before the first value arrives, so check the return code print ('Mouse position x: ',data) # Mouse position x is actualized when the cursor is over V-REP's window # Now send some data to V-REP in a non-blocking fashion: vrep.simxAddStatusbarMessage(clientID,'Hello V-REP!',vrep.simx_opmode_oneshot) # Before closing the connection to V-REP, make sure that the last command sent out had time to arrive. You can guarantee this with (for example): vrep.simxGetPingTime(clientID) # Now close the connection to V-REP: vrep.simxFinish(clientID) else: print ('Failed connecting to remote API server') print ('Program ended')
V-rep Remote API 函式列表:
http://www.coppeliarobotics.com/helpFiles/en/remoteApiFunctionListCategory.htm
V-rep 的 remote API 是以 V-rep plugin (動態連結程式庫) 的方式完成, 程式專案位於 programming/v_repExtRemoteApi 目錄中.
V-rep remote API 可以進一步在 embedded script 程式中利用 Lua 程式進行延伸:
myFunctionName=function(inInts,inFloats,inStrings,inBuffer) -- inInts, inFloats and inStrings are tables -- inBuffer is a string -- Perform any type of operation here. -- Always return 3 tables and a string, e.g.: return {},{},{},'' end
然後利用下列外部的 Python 程式進行呼叫:
inputInts=[1,2,3] inputFloats=[53.21,17.39] inputStrings=['Hello','world!'] inputBuffer=bytearray() inputBuffer.append(78) inputBuffer.append(42) res,retInts,retFloats,retStrings,retBuffer=vrep.simxCallScriptFunction(clientID,'objectName',vrep.sim_scripttype_childscript, 'myFunctionName',inputInts,inputFloats,inputStrings,inputBuffer,vrep.simx_opmode_blocking) if res==vrep.simx_return_ok: print (retInts) print (retFloats) print (retStrings) print (retBuffer)
以 remote API 取 camera 影像
from PIL import Image import array res, v0 = vrep.simxGetObjectHandle(clientID,'NAO_vision1',vrep.simx_opmode_oneshot_wait) res, resolution, image = vrep.simxGetVisionSensorImage(clientID,v0,0,vrep.simx_opmode_streaming) image_byte_array = array.array('b',image) # image resolution is 256x144 im = Image.frombuffer("RGB", (256,144), image_byte_array, "raw", "RGB", 0, 1) im.show()
取影片:
import vrep,time,sys import matplotlib.pyplot as plt from PIL import Image import array def streamVisionSensor(visionSensorName,clientID,pause=0.0001): #Get the handle of the vision sensor res1,visionSensorHandle=vrep.simxGetObjectHandle(clientID,visionSensorName,vrep.simx_opmode_oneshot_wait) print(visionSensorHandle) #Get the image res2,resolution,image=vrep.simxGetVisionSensorImage(clientID,visionSensorHandle,0,vrep.simx_opmode_streaming) print(res2, res1) #Allow the display to be refreshed plt.ion() #Initialiazation of the figure time.sleep(0.5) res,resolution,image=vrep.simxGetVisionSensorImage(clientID,visionSensorHandle,0,vrep.simx_opmode_buffer) im = Image.new("RGB", (resolution[0], resolution[1]), "white") #Give a title to the figure fig = plt.figure(1) fig.canvas.set_window_title(visionSensorName) #inverse the picture plotimg = plt.imshow(im,origin='lower') #Let some time to Vrep in order to let him send the first image, otherwise the loop will start with an empty image and will crash time.sleep(1) while (vrep.simxGetConnectionId(clientID)!=-1): #Get the image of the vision sensor res,resolution,image=vrep.simxGetVisionSensorImage(clientID,visionSensorHandle,0,vrep.simx_opmode_buffer) #Transform the image so it can be displayed using pyplot image_byte_array = array.array('b',image) im = Image.frombuffer("RGB", (resolution[0],resolution[1]), image_byte_array, "raw", "RGB", 0, 1) #Update the image plotimg.set_data(im) #Refresh the display plt.draw() #The mandatory pause ! (or it'll not work) plt.pause(pause) print('End of Simulation') if __name__ == '__main__': vrep.simxFinish(-1) clientID=vrep.simxStart('127.0.0.2',19999,True,True,5000,5) if clientID!=-1: print('Connected to remote API server') streamVisionSensor('NAO_vision1',clientID,0.0001) else: print('Connection non successful') sys.exit('Could not connect')
Execute Complex Commands
# This example illustrates how to execute complex commands from # a remote API client. You can also use a similar construct for # commands that are not directly supported by the remote API. # # Load the demo scene 'remoteApiCommandServerExample.ttt' in V-REP, then # start the simulation and run this program. # # IMPORTANT: for each successful call to simxStart, there # should be a corresponding call to simxFinish at the end! # # When running Python 3.x, add a 'b' prefix to strings, e.g.: # 'hello world' becomes b'hello world' def getCmdString(id,cnt,data): l=12+len(data) retData=vrep.simxPackInts([id,cnt,l]) return retData+data def waitForCmdReply(cnt): while True: result,string=vrep.simxReadStringStream(clientID,'repliesToRemoteApiClient',vrep.simx_opmode_streaming) if result==vrep.simx_return_ok: while len(string)!=0: headerPacked=string[0:12] header=vrep.simxUnpackInts(headerPacked) if cnt==header[1]: replyData='' if header[2]>12: replyData=string[12:header[2]] return replyData string=string[header[2]:len(string)] try: import vrep except: print ('--------------------------------------------------------------') print ('"vrep.py" could not be imported. This means very probably that') print ('either "vrep.py" or the remoteApi library could not be found.') print ('Make sure both are in the same folder as this file,') print ('or appropriately adjust the file "vrep.py"') print ('--------------------------------------------------------------') print ('') import ctypes print ('Program started') vrep.simxFinish(-1) # just in case, close all opened connections clientID=vrep.simxStart('127.0.0.1',19999,True,True,5000,5) # Connect to V-REP if clientID!=-1: print ('Connected to remote API server') # Commands are send via the string signal 'commandsFromRemoteApiClient'. # Commands are simply appended to that string signal # Each command is coded in following way: # 1. Command ID (integer, 4 chars) # 2. Command counter (integer, 4 chars). Simply start with 0 and increment for each command you send # 3. Command length (integer, includes the command ID, the command counter, the command length, and the additional data (i.e. command data)) # 4. Command data (chars, can be of any length, depending on the command) # # Replies are coded in a same way. An executed command should reply with the same command counter. # # Above simple protocol is just an example: you could use your own protocol! (but it has to be the same on the V-REP side) # 1. First send a command to display a specific message in a dialog box: cmdID=1 # this command id means: 'display a text in a message box' cmdCnt=0 cmdData='Hello world!' stringToSend=getCmdString(cmdID,cmdCnt,cmdData) raw_ubytes = (ctypes.c_ubyte * len(stringToSend)).from_buffer_copy(stringToSend) vrep.simxWriteStringStream(clientID,'commandsFromRemoteApiClient',raw_ubytes,vrep.simx_opmode_oneshot) print ('Return string: ',waitForCmdReply(cmdCnt)) # display the reply from V-REP (in this case, just a string) # 2. Now create a dummy object at coordinate 0.1,0.2,0.3: cmdID=2 # this command id means: 'create a dummy at a specific coordinate with a specific name' cmdCnt=cmdCnt+1 cmdData='MyDummyName'+vrep.simxPackFloats([0.1,0.2,0.3]) stringToSend=getCmdString(cmdID,cmdCnt,cmdData) raw_ubytes = (ctypes.c_ubyte * len(stringToSend)).from_buffer_copy(stringToSend) vrep.simxWriteStringStream(clientID,'commandsFromRemoteApiClient',raw_ubytes,vrep.simx_opmode_oneshot) replyData=waitForCmdReply(cmdCnt) print ('Dummy handle: ',vrep.simxUnpackInts(replyData)[0]) # display the reply from V-REP (in this case, the handle of the created dummy) # Now close the connection to V-REP: vrep.simxFinish(clientID) else: print ('Failed connecting to remote API server') print ('Program ended')
與上述 Client 端程式配合的 V-rep non-threaded child 程式碼:
if (sim_call_type==sim_childscriptcall_initialization) then simExtRemoteApiStart(19999) end if (sim_call_type==sim_childscriptcall_actuation) then local commands=simGetStringSignal('commandsFromRemoteApiClient') -- Read commands sent from a remote API client if commands then simClearStringSignal('commandsFromRemoteApiClient') -- Clear the signal -- Process the commands in following loop: while #commands>0 do local cmdID=simUnpackInts(commands,0,1)[1] local cmdCounter=simUnpackInts(commands,1,1)[1] local cmdLength=simUnpackInts(commands,2,1)[1] local cmdData='' if cmdLength>12 then cmdData=string.sub(commands,13,13+cmdLength-12) end commands=string.sub(commands,cmdLength+1) -- this contains the next commands -- Now process the command, and prepare a reply string signal: local reply='' if cmdID==1 then -- We have to process the command with ID 1, in this example, simply display a dialog box that prints the text stored in cmdData: simDisplayDialog('Message from the remote API client',cmdData,sim_dlgstyle_ok,false) reply='message was displayed' end if cmdID==2 then -- We have to process the command with ID 2, in this example, create a dummy object at coordinates specified in cmdData: local dummyHandle=simCreateDummy(0.05) local dummyNameSize=#cmdData-12 -- cmdData should contain the dummy name, plus the x/y/z coordinates local position=simUnpackFloats(cmdData,0,0,dummyNameSize) if dummyNameSize>0 then local errorReportMode=simGetIntegerParameter(sim_intparam_error_report_mode) simSetIntegerParameter(sim_intparam_error_report_mode,0) -- temporarily suppress error output (because we are not allowed to have two times the same object name) simSetObjectName(dummyHandle,string.sub(cmdData,1,dummyNameSize)) simSetIntegerParameter(sim_intparam_error_report_mode,errorReportMode) -- restore the original error report mode end simSetObjectPosition(dummyHandle,-1,position) reply=simPackInts({dummyHandle}) end if cmdID==3 then -- You can add as many commands as needed end -- Now, before setting up the reply string, append the cmdID, and a reply length: local replyLength=12+#reply local replyFromOtherCommands=simGetStringSignal('repliesToRemoteApiClient') if not replyFromOtherCommands then replyFromOtherCommands='' end local totalReplySignal=replyFromOtherCommands..simPackInts({cmdID})..simPackInts({cmdCounter})..simPackInts({replyLength})..reply simSetStringSignal('repliesToRemoteApiClient',totalReplySignal) -- update the reply signal end end end
Qt based custom UIs
http://www.coppeliarobotics.com/helpFiles/en/customUIPlugin.htm
V-rep Tutorials:
http://www.coppeliarobotics.com/helpFiles/en/bubbleRobTutorial.htm
http://www.coppeliarobotics.com/helpFiles/en/buildingAModelTutorial.htm
http://www.coppeliarobotics.com/helpFiles/en/lineFollowingBubbleRobTutorial.htm
Inverse Kinematics Tutorial
http://www.coppeliarobotics.com/helpFiles/en/inverseKinematicsTutorial.htm
http://www.coppeliarobotics.com/helpFiles/en/hexapodTutorial.htm
http://www.coppeliarobotics.com/helpFiles/en/externalControllerTutorial.htm
http://www.coppeliarobotics.com/helpFiles/en/pluginTutorial.htm
http://www.coppeliarobotics.com/helpFiles/en/conveyorBeltTutorial.htm
Compiling V-rep
http://www.coppeliarobotics.com/helpFiles/en/compilingVrep.htm
V-rep Other Interfaces
http://www.coppeliarobotics.com/helpFiles/en/otherInterfaces.htm
Extra contributions:
http://www.coppeliarobotics.com/contributions/