文章目录
- 实现效果
- 一些设置
- 添加手爪
- 工具坐标中心点 TCP 的设置
- 代码实现
实现效果
- 注意:关于目标点的选取要合适,否则可能无法生成可以抵达该点的轨迹。
一些设置
添加手爪
- 这里我添加的是 ROBOTIQ_85 这款手爪,下面展示如何将手爪添加到机械臂末端:
工具坐标中心点 TCP 的设置
- 将 tip 和 target 移动到 TCP(不同的工具,其 TCP 的设置不同):
代码实现
getMatrixShiftedAlongZ=function(matrix,localZShift)
local m={}
for i=1,12,1 do
m[i]=matrix[i]
end
m[4]=m[4]+m[3]*localZShift
m[8]=m[8]+m[7]*localZShift
m[12]=m[12]+m[11]*localZShift
return m
end
forbidThreadSwitches=function(forbid)
if forbid then
forbidLevel=forbidLevel+1
if forbidLevel==1 then
sim.setThreadAutomaticSwitch(false)
end
else
forbidLevel=forbidLevel-1
if forbidLevel==0 then
sim.setThreadAutomaticSwitch(true)
end
end
end
findCollisionFreeConfigAndCheckApproach=function(matrix)
sim.setObjectMatrix(ikTarget,-1,matrix)
local c=sim.getConfigForTipPose(ikGroup,jh,0.65,10,nil,collisionPairs)
if c then
local m=getMatrixShiftedAlongZ(matrix,ikShift)
local path=generateIkPath(c,m,ikSteps)
if path==nil then
c=nil
end
end
return c
end
findSeveralCollisionFreeConfigsAndCheckApproach=function(matrix,trialCnt,maxConfigs)
forbidThreadSwitches(true)
sim.setObjectMatrix(ikTarget,-1,matrix)
local cc=getConfig()
local cs={}
local l={}
for i=1,trialCnt,1 do
local c=findCollisionFreeConfigAndCheckApproach(matrix)
if c then
local dist=getConfigConfigDistance(cc,c)
print('dist: ',dist)
local p=0
local same=false
for j=1,#l,1 do
if math.abs(l[j]-dist)<0.001 then
-- we might have the exact same config. Avoid that
same=true
for k=1,#jh,1 do
if math.abs(cs[j][k]-c[k])>0.01 then
same=false
break
end
end
end
if same then
break
end
end
if not same then
cs[#cs+1]=c
l[#l+1]=dist
end
end
if #l>=maxConfigs then
break
end
end
forbidThreadSwitches(false)
if #cs==0 then
cs=nil
end
return cs
end
getConfig=function()
-- Returns the current robot configuration
local config={}
for i=1,#jh,1 do
config[i]=sim.getJointPosition(jh[i])
end
return config
end
setConfig=function(config)
-- Applies the specified configuration to the robot
if config then
for i=1,#jh,1 do
sim.setJointPosition(jh[i],config[i])
end
end
end
getConfigConfigDistance=function(config1,config2)
-- Returns the distance (in configuration space) between two configurations
local d=0
for i=1,#jh,1 do
local dx=(config1[i]-config2[i])*metric[i]
d=d+dx*dx
end
return math.sqrt(d)
end
generateIkPath=function(startConfig,goalPose,steps)
-- Generates (if possible) a linear, collision free path between a robot config and a target pose
forbidThreadSwitches(true)
local currentConfig=getConfig()
setConfig(startConfig)
sim.setObjectMatrix(ikTarget,-1,goalPose)
local c=sim.generateIkPath(ikGroup,jh,steps,collisionPairs)
setConfig(currentConfig)
forbidThreadSwitches(false)
return c
end
getPathLength=function(path)
-- Returns the length of the path in configuration space
local d=0
local l=#jh
local pc=#path/l
for i=1,pc-1,1 do
local config1={path[(i-1)*l+1],path[(i-1)*l+2],path[(i-1)*l+3],path[(i-1)*l+4],path[(i-1)*l+5],path[(i-1)*l+6],path[(i-1)*l+7]}
local config2={path[i*l+1],path[i*l+2],path[i*l+3],path[i*l+4],path[i*l+5],path[i*l+6],path[i*l+7]}
d=d+getConfigConfigDistance(config1,config2)
end
return d
end
followPath=function(path)
-- Follows the specified path points. Each path point is a robot configuration. Here we don't do any interpolation
if path then
local l=#jh
local pc=#path/l
for i=1,pc,1 do
local config={path[(i-1)*l+1],path[(i-1)*l+2],path[(i-1)*l+3],path[(i-1)*l+4],path[(i-1)*l+5],path[(i-1)*l+6],path[(i-1)*l+7]}
setConfig(config)
sim.switchThread()
end
end
end
findPath=function(startConfig,goalConfigs,cnt)
-- Here we do path planning between the specified start and goal configurations. We run the search cnt times,
-- and return the shortest path, and its length
local task=simOMPL.createTask('task')
simOMPL.setAlgorithm(task,simOMPL.Algorithm.RRTConnect)
local j1_space=simOMPL.createStateSpace('j1_space',simOMPL.StateSpaceType.joint_position,jh[1],{-180*math.pi/180},{180*math.pi/180},1)
local j2_space=simOMPL.createStateSpace('j2_space',simOMPL.StateSpaceType.joint_position,jh[2],{-180*math.pi/180},{180*math.pi/180},2)
local j3_space=simOMPL.createStateSpace('j3_space',simOMPL.StateSpaceType.joint_position,jh[3],{-180*math.pi/180},{180*math.pi/180},3)
local j4_space=simOMPL.createStateSpace('j4_space',simOMPL.StateSpaceType.joint_position,jh[4],{-180*math.pi/180},{180*math.pi/180},0)
local j5_space=simOMPL.createStateSpace('j5_space',simOMPL.StateSpaceType.joint_position,jh[5],{-180*math.pi/180},{180*math.pi/180},0)
local j6_space=simOMPL.createStateSpace('j6_space',simOMPL.StateSpaceType.joint_position,jh[6],{-180*math.pi/180},{180*math.pi/180},0)
simOMPL.setStateSpace(task,{j1_space,j2_space,j3_space,j4_space,j5_space,j6_space})
simOMPL.setCollisionPairs(task,collisionPairs)
simOMPL.setStartState(task,startConfig)
simOMPL.setGoalState(task,goalConfigs[1])
for i=2,#goalConfigs,1 do
simOMPL.addGoalState(task,goalConfigs[i])
end
local path=nil
local l=999999999999
forbidThreadSwitches(true)
for i=1,cnt,1 do
local res,_path=simOMPL.compute(task,4,-1,300)
if res and _path then
local _l=getPathLength(_path)
if _l<l then
l=_l
path=_path
end
end
end
forbidThreadSwitches(false)
simOMPL.destroyTask(task)
return path,l
end
findShortestPath=function(startConfig,goalConfigs,searchCntPerGoalConfig)
forbidThreadSwitches(true)
local thePath=findPath(startConfig,goalConfigs,searchCntPerGoalConfig)
forbidThreadSwitches(false)
return thePath
end
function sysCall_threadmain()
-- Initialization phase:
jh={-1,-1,-1,-1,-1,-1}
for i=1,6,1 do
jh[i]=sim.getObjectHandle('UR3_joint'..i)
end
ikGroup=sim.getIkGroupHandle('ik')
ikTarget=sim.getObjectHandle('target')
collisionPairs={sim.getCollectionHandle('manipulator'),sim.getCollectionHandle('environment')}
metric={1,1,1,1,1,1}
forbidLevel=0
ikShift=0.1
ikSteps=50
local theTarget=sim.getObjectHandle('testTarget')
local m=sim.getObjectMatrix(theTarget,-1)
print('m0: ',m)
m=getMatrixShiftedAlongZ(m,-ikShift)
print('m1: ',m)
local c=findSeveralCollisionFreeConfigsAndCheckApproach(m,300,60)
print('c: ',c)
local path=findShortestPath(getConfig(),c,6)
print('path: ',path)
followPath(path)
end
评论(5)
您还未登录,请登录后发表或查看评论