A path is a pseudo object, representing a succession of points with orientation in space. pseudo object, since it is built using merely dummies and a customization script that describes its functionality and behaviour.

[Simple path containing 4 control points]

Path objects can be added to the scene with [Menu bar --> Add --> Path]. A path is composed by control points that define its curve in space. Control points can be shifted, copy/pasted or deleted. A path's basic properties are accessed and adjusted via its user parameters (implemented via a user config callback function), in the scene hierarchy:

[User parameter icon]

A path can also automatically generate extruded shapes; this functionality is enabled via its user parameters, and the shape profile, color and other details can be adjusted in its customization script, which uses the API function sim.generateShapefromPath:

function path.shaping(path,pathIsClosed,upVector) -- following section generates a square extrusion shape: local section={0.02,-0.02,0.02,0.02,-0.02,0.02,-0.02,-0.02,0.02,-0.02} local color={0.7,0.9,0.9} local options=0 if pathIsClosed then options=options|4 end local shape=sim.generateShapeFromPath(path,section,options,upVector) sim.setShapeColor(shape,nil,sim.colorcomponent_ambient_diffuse,color) return shape end

[Simple path generating an extruded square shape]

To generate an extruded circular shape, use following code to create the section data:

local section={} local radius=0.02 local sides=32 local da=math.pi*2/sides for i=0,sides-1,1 do section[2*i+1]=radius*math.cos(da*i) section[2*i+2]=radius*math.sin(da*i) end -- the section shoujld be closed (first and last points perfect overlap): section[#section+1]=section[1] section[#section+1]=section[2]

[Simple path generating an extruded circular shape]

Path data is stored inside of the path object, as custom object data. It can be accessed with:

-- control point data (each one has x,y,z,qx,qy,qz,qw (position and quaternion)): local ctrlPts=sim.unpackDoubleTable(sim.readCustomDataBlock(pathHandle,'PATHCTRLPTS')) -- path data (each one has x,y,z,qx,qy,qz,qw (position and quaternion)): local pathData=sim.unpackDoubleTable(sim.readCustomDataBlock(pathHandle,'PATH')

Various API functions related to paths are available, e.g. in order to have an object follow a path in position and orientation, one could use following script:

function sysCall_init() objectToFollowPath=sim.getObject('.') path=sim.getObject('/Path') pathData=sim.unpackDoubleTable(sim.readCustomDataBlock(path,'PATH')) local m=Matrix(#pathData//7,7,pathData) pathPositions=m:slice(1,1,m:rows(),3):data() pathQuaternions=m:slice(1,4,m:rows(),7):data() pathLengths,totalLength=sim.getPathLengths(pathPositions,3) velocity=0.04 -- m/s posAlongPath=0 previousSimulationTime=0 corout=coroutine.create(coroutineMain) end function sysCall_actuation() if coroutine.status(corout)~='dead' then local ok,errorMsg=coroutine.resume(corout) if errorMsg then error(debug.traceback(corout,errorMsg),2) end end end function coroutineMain() sim.setThreadAutomaticSwitch(false) while true do local t=sim.getSimulationTime() posAlongPath=posAlongPath+velocity*(t-previousSimulationTime) posAlongPath=posAlongPath % totalLength local pos=sim.getPathInterpolatedConfig(pathPositions,pathLengths,posAlongPath) local quat=sim.getPathInterpolatedConfig(pathQuaternions,pathLengths, posAlongPath,nil,{2,2,2,2}) sim.setObjectPosition(objectToFollowPath,path,pos) sim.setObjectQuaternion(objectToFollowPath,path,quat) previousSimulationTime=t sim.switchThread() end end