Robotic pick and place using computer vision for
object localization and sensory real-time collision
avoidance.
V-REP Vision Sensor Blob Detection
The script below is accociated with the vision sensor object and shows the implimentation of blob detection using the V-Rep API. For object localisation blob detection
has been implemented to return the x,y location of the center of
the front face of the box, however its depth cannot be perceived
without the use of a collocated second camera. Since the
depth of each box is constant it’s Y coordinate can be adjusted
by half the depth of the box to correspond the new point with
the center of the box. Once the object has been picked camera
one returns the RGB value for the box being manipulated and the
box is sorted accordingly to the correct drop point, youBot’s
base is then driven to a new target location where the box is
to be dropped.
function sysCall_init()
sensor=sim.getObjectAssociatedWithScript(sim.handle_self)
local res
res,nearClip=sim.getObjectFloatParameter(sensor,sim.visionfloatparam_near_clipping)
res,farClip=sim.getObjectFloatParameter(sensor,sim.visionfloatparam_far_clipping)
res,xAngle=sim.getObjectFloatParameter(sensor,sim.visionfloatparam_perspective_angle)
res,resX=sim.getObjectInt32Parameter(sensor,sim.visionintparam_resolution_x)
res,resY=sim.getObjectInt32Parameter(sensor,sim.visionintparam_resolution_y)
yAngle=xAngle
local ratio=resX/resY
if resX>resY then
yAngle=2*math.atan(math.tan(xAngle/2)/ratio)
else
xAngle=2*math.atan(math.tan(yAngle/2)/ratio)
end
end
function sysCall_sensing()
local m=sim.getObjectMatrix(sensor,-1)
local res,packet1,packet2=sim.handleVisionSensor(sensor)
if res>=0 then
local blobCnt=packet2[1]
local valCnt=packet2[2]
for i=0,blobCnt-1,1 do
local blobSize=packet2[2+valCnt*i+1]
local blobOrientation=packet2[2+valCnt*i+2]
local blobPositionX=packet2[2+valCnt*i+3]
local blobPositionY=packet2[2+valCnt*i+4]
local blobWidth=packet2[2+valCnt*i+5]
local blobHeight=packet2[2+valCnt*i+6]
local depthV=sim.getVisionSensorDepthBuffer(sensor,1+math.floor(blobPositionX*(resX-0.99)),1+math.floor(blobPositionY*(resY-0.99)),1,1)
local depth=nearClip+(farClip-nearClip)*depthV[1]
local coord={0,0,depth}
local x=0.5-blobPositionX
local y=blobPositionY-0.5
coord[1]=depth*math.tan(xAngle*0.5)*(0.5-blobPositionX)/0.5
coord[2]=depth*math.tan(yAngle*0.5)*(blobPositionY-0.5)/0.5
coord=sim.multiplyVector(m,coord)
sim.setFloatSignal('blobX', coord[1])
sim.setFloatSignal('blobY', coord[2])
sim.setFloatSignal('blobO', blobOrientation)
--print(blobOrientation)
-- coord now contains the position of the blob, in world coordinates
end
end
end
V-REP Kuka Youbot Forward & Inverse Kinematics
In order to move a robotic manipulator its
kinematic structure needs to be defined. Within v-rep the scene
hierarchy is used to build a kinematic structure formed as a
tree of joints and links. Using the simulators’ API a kinematic
group can be used to build an equivalent kinematic model via
the functions provided by the kinematics plugin.
Within the scenario detailed forward kinematics are used to
reach a pre-defined position that will be used as a reference
position for object manipulation. Forward kinematics is used
in the first instance of movement where the arm is initialised
to its reference position, due to the lower time complexity of
the algorithm that controls its movement, setting joint angles
is less processing heavy than inverse kinematics where joint
angles need to be calculated based on the position of the end-effector.
First the robot’s omni-directional base is translated to a new
target position, each wheel joint is given a set velocity to drive
the robot to the target position using forward kinematics. The
arm is then actuated to its reference position using forward
kinematics. Concurrently whist the arm is being actuated, the
front camera is active and a reading is taken from its image
frame blob detection is applied and a measurement is taken of
blob1 relative to the camera frame, this is then transformed to
the world cartesian coordinate system where the location of the
cube can be identified. YouBot’s arm can then be manipulated
to the target location using inverse kinematics and the object
can be picked.
-- This script controls the Youbot task. It is threaded. In next sections, there are a lot of function definitions
-- that ease the control of the robot. The arm of the robot is controlled in:
--
-- 1. Forward kinematics mode ( setFkMode() )
-- 2. Inverse kinematics mode in position only ( setIkMode(false) )
-- 3. Inverse kinematics mode in position and orientation (to keep the gripper vertical) ( setIkMode(true) )
--
-- The inverse kinematics calculations are then automatically applied to the physics engine, since the joints are in
-- "hybrid IK mode" (see the joint properties dialog)
--
-- All inverse kinematics tasks are define in the IK properties dialog. There are 4 tasks:
--
-- "youBotUndamped_group": handles the inverse kinematics in position only. Resolution is not damped
-- "youBotDamped_group": handles the inverse kinematics in position only. Resolution is damped. Useful when the previous IK task didn't succeed, because out of reach for instance
-- "youBotUndamped_group": handles the inverse kinematics in position and orientation. Resolution is not damped
-- "youBotDamped_group": handles the inverse kinematics in position and orientation. Resolution is damped. Useful when the previous IK task didn't succeed, because out of reach for instance
--
-- Above 4 tasks are enabled/disabled as needed. This is done with the "sim.setExplicitHandling" function.
setIkMode=function(withOrientation)
sim.setThreadAutomaticSwitch(false) -- Don't get interrupted for this function
if (ikMode==false) then
sim.setObjectPosition(gripperTarget,-1,sim.getObjectPosition(gripperTip,-1))
end
if (withOrientation) then
sim.setExplicitHandling(ikWithOrientation1,0)
sim.setExplicitHandling(ikWithOrientation2,0)
else
sim.setExplicitHandling(ik1,0)
sim.setExplicitHandling(ik2,0)
end
for i=1,5,1 do
sim.setJointMode(armJoints[i],sim.jointmode_ik,1)
end
ikMode=true
sim.setThreadAutomaticSwitch(true)
end
setFkMode=function()
sim.setThreadAutomaticSwitch(false) -- Don't get interrupted for this function
sim.setExplicitHandling(ik1,1)
sim.setExplicitHandling(ik2,1)
sim.setExplicitHandling(ikWithOrientation1,1)
sim.setExplicitHandling(ikWithOrientation2,1)
for i=1,5,1 do
sim.setJointMode(armJoints[i],sim.jointmode_force,0)
end
ikMode=false
sim.setThreadAutomaticSwitch(true)
end
openGripper=function()
sim.tubeWrite(gripperCommunicationTube,sim.packInt32Table({1}))
sim.wait(0.8)
end
closeGripper=function()
sim.tubeWrite(gripperCommunicationTube,sim.packInt32Table({0}))
sim.wait(0.8)
end
setGripperTargetMovingWithVehicle=function()
sim.setObjectParent(gripperTarget,vehicleReference,true)
end
setGripperTargetFixedToWorld=function()
sim.setObjectParent(gripperTarget,-1,true)
end
waitToReachVehicleTargetPositionAndOrientation=function()
repeat
sim.switchThread() -- don't waste your time waiting!
p1=sim.getObjectPosition(vehicleTarget,-1)
p2=sim.getObjectPosition(vehicleReference,-1)
p={p2[1]-p1[1],p2[2]-p1[2]}
pError=math.sqrt(p[1]*p[1]+p[2]*p[2])
oError=math.abs(sim.getObjectOrientation(vehicleReference,vehicleTarget)[3])
until (pError<0.001)and(oError<0.1*math.pi/180)
end
getBoxAdjustedMatrixAndFacingAngle=function(boxHandle)
p2=sim.getObjectPosition(boxHandle,-1)
p1=sim.getObjectPosition(vehicleReference,-1)
p={p2[1]-p1[1],p2[2]-p1[2],p2[3]-p1[3]}
pl=math.sqrt(p[1]*p[1]+p[2]*p[2]+p[3]*p[3])
p[1]=p[1]/pl
p[2]=p[2]/pl
p[3]=p[3]/pl
m=sim.getObjectMatrix(boxHandle,-1)
matchingScore=0
for i=1,3,1 do
v={m[0+i],m[4+i],m[8+i]}
score=v[1]*p[1]+v[2]*p[2]+v[3]*p[3]
if (math.abs(score)>matchingScore) then
s=1
if (score<0) then s=-1 end
matchingScore=math.abs(score)
bestMatch={v[1]*s,v[2]*s,v[3]*s}
end
end
angle=math.atan2(bestMatch[2],bestMatch[1])
m=sim.buildMatrix(p2,{0,0,angle})
return m, angle-math.pi/2
end
pickupBoxFromPlace=function(boxHandle,pickupConf)
local m,angle=getBoxAdjustedMatrixAndFacingAngle(boxHandle)
sim.setObjectPosition(vehicleTarget,-1,{m[4]-m[1]*dist1,m[8]-m[5]*dist1,0})
sim.setObjectOrientation(vehicleTarget,-1,{0,0,angle})
setFkMode()
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,pickupConf,nil)
waitToReachVehicleTargetPositionAndOrientation()
setIkMode(true)
setGripperTargetFixedToWorld()
local p=sim.getObjectPosition(gripperTarget,-1)
p[1]=m[4]
p[2]=m[8]
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
openGripper()
p[3]=m[12]
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
closeGripper()
p[3]=p[3]+0.1
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
setGripperTargetMovingWithVehicle()
setFkMode()
end
dropToPlatform=function(platform)
setFkMode()
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,{0.3,0.3,0.3,0.3,0.3},fkJerk,platform,nil)
openGripper()
end
pickupFromPlatformAndReorient=function(boxHandle)
setFkMode()
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,platformIntermediateDrop,nil)
setIkMode(false)
local p=sim.getObjectPosition(boxHandle,-1)
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
closeGripper()
setFkMode()
-- Move a bit back from current position:
local m=sim.getObjectMatrix(vehicleTarget,-1)
sim.setObjectPosition(vehicleTarget,-1,{m[4]-m[2]*dist1,m[8]-m[6]*dist1,0})
-- Now drop it
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,pickup2,nil)
end
dropToPlace=function(placeHandle,shift,verticalPos,startConf,noVerticalArmForUpMovement)
local m,angle=getBoxAdjustedMatrixAndFacingAngle(placeHandle)
m[4]=m[4]+m[2]*shift
m[8]=m[8]+m[6]*shift
sim.setObjectPosition(vehicleTarget,-1,{m[4]-m[1]*dist1,m[8]-m[5]*dist1,0})
sim.setObjectOrientation(vehicleTarget,-1,{0,0,angle})
setFkMode()
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,startConf,nil)
waitToReachVehicleTargetPositionAndOrientation()
setIkMode(true)
setGripperTargetFixedToWorld()
local p=sim.getObjectPosition(gripperTarget,-1)
p[1]=m[4]
p[2]=m[8]
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
p[3]=verticalPos
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
openGripper()
if (noVerticalArmForUpMovement) then
setIkMode(false)
end
p[3]=p[3]+0.1
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
setGripperTargetMovingWithVehicle()
setFkMode()
end
sortByColor=function(dropHeight)
RGBValue=sim.getVisionSensorImage(vS0,0,0,0.1,0.1,0)
print("RED=",RGBValue[1],"BLUE=",RGBValue[2],"GREEN= ",RGBValue[3])
if (RGBValue[1] < 1)and(RGBValue[2] < 1)and(RGBValue[3] == 1)then
dropToPlace(d0,0,dropHeight,pickup2,false)
end
if (RGBValue[1] < 1)and(RGBValue[2] == 1)and(RGBValue[3] < 1)then
dropToPlace(d1,0,dropHeight,pickup2,false)
end
if (RGBValue[1] == 1)and(RGBValue[2] < 1)and(RGBValue[3] < 1)then
dropToPlace(d2,0,dropHeight,pickup2,false)
end
end
getBoxAdjustedMatrixAndFacingAngle2=function(position,matrix)
p2=position
p1=sim.getObjectPosition(vehicleReference,-1)
p={p2[1]-p1[1],p2[2]-p1[2],p2[3]-p1[3]}
pl=math.sqrt(p[1]*p[1]+p[2]*p[2]+p[3]*p[3])
p[1]=p[1]/pl
p[2]=p[2]/pl
p[3]=p[3]/pl
m=matrix
matchingScore=0
for i=1,3,1 do
v={m[0+i],m[4+i],m[8+i]}
score=v[1]*p[1]+v[2]*p[2]+v[3]*p[3]
if (math.abs(score)>matchingScore) then
s=1
if (score<0) then s=-1 end
matchingScore=math.abs(score)
bestMatch={v[1]*s,v[2]*s,v[3]*s}
end
end
angle=math.atan2(bestMatch[2],bestMatch[1])
m=sim.buildMatrix(p2,{0,0,angle})
return m, angle-math.pi/2
end
pickupBoxFromPlaceWithVision=function(position,matrix,pickupConf)
local m,angle=getBoxAdjustedMatrixAndFacingAngle2(position,matrix)
sim.setObjectPosition(vehicleTarget,-1,{m[4]-m[1]*dist3,m[8]-m[5]*dist3,0})
sim.setObjectOrientation(vehicleTarget,-1,{0,0,angle})
waitToReachVehicleTargetPositionAndOrientation()
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,pickup1,nil)
setIkMode(true)
p=sim.getObjectPosition(gripperTarget,-1)
p[1]=m[4]
p[2]=m[8]
p[3]=m[12]
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
closeGripper()
p[3]=p[3]+0.05
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
--setGripperTargetMovingWithVehicle()
--setFkMode()
end
getPositionUsingVision=function()
local blobX=sim.getFloatSignal('blobX')
local blobY=sim.getFloatSignal('blobY')
local blobO=sim.getFloatSignal('blobO')
print("Position X =",blobX)
print("Position Y =",blobY)
return {(blobX+0.02),blobY,0.02}
end
getMatrixUsingVision=function()
local blobX=sim.getFloatSignal('blobX')
local blobY=sim.getFloatSignal('blobY')
local blobO=sim.getFloatSignal('blobO')
local m=sim.buildMatrix({(blobX),(blobY),0},{0,0,blobO})
return m
end
function sysCall_threadmain()
gripperTarget=sim.getObjectHandle('youBot_gripperPositionTarget')
gripperTip=sim.getObjectHandle('youBot_gripperPositionTip')
vehicleReference=sim.getObjectHandle('youBot_vehicleReference')
vehicleTarget=sim.getObjectHandle('youBot_vehicleTargetPosition')
armJoints={-1,-1,-1,-1,-1}
for i=0,4,1 do
armJoints[i+1]=sim.getObjectHandle('youBotArmJoint'..i)
end
ik1=sim.getIkGroupHandle('youBotUndamped_group')
ik2=sim.getIkGroupHandle('youBotDamped_group')
ikWithOrientation1=sim.getIkGroupHandle('youBotPosAndOrientUndamped_group')
ikWithOrientation2=sim.getIkGroupHandle('youBotPosAndOrientDamped_group')
gripperCommunicationTube=sim.tubeOpen(0,'youBotGripperState'..sim.getNameSuffix(nil),1)
d0=sim.getObjectHandle('dropPoint0')
d1=sim.getObjectHandle('dropPoint1')
d2=sim.getObjectHandle('dropPoint2')
pickupPosition0=sim.getObjectHandle('pickupPosition0')
vS0=sim.getObjectHandle('Vision_sensor')
vS1=sim.getObjectHandle('Vision_sensor0')
node0=sim.getObjectHandle('node0')
node0P=sim.getObjectPosition(node0,-1)
node1=sim.getObjectHandle('node1')
node1P=sim.getObjectPosition(node1,-1)
pickup1={0,-14.52*math.pi/180,-70.27*math.pi/180,-95.27*math.pi/180,0*math.pi/180}
pickup2={0,-13.39*math.pi/180,-93.91*math.pi/180,-72.72*math.pi/180,90*math.pi/180}
pickup3={0,-14.52*math.pi/180,-70.27*math.pi/180,-95.27*math.pi/180,90*math.pi/180}
platformIntermediateDrop={0,16*math.pi/180,52*math.pi/180,73*math.pi/180,0*math.pi/180}
platformDrop1={0,54.33*math.pi/180,32.88*math.pi/180,35.76*math.pi/180,0*math.pi/180}--{0,-0.4,0.2}
platformDrop2={0,40.74*math.pi/180,45.81*math.pi/180,59.24*math.pi/180,0*math.pi/180}--{0,-0.32,0.2}
platformDrop3={0,28.47*math.pi/180,55.09*math.pi/180,78.32*math.pi/180,0*math.pi/180}--{0,-0.24,0.2}
dist1=0.2
dist2=1
dist3=0.3
dropHeight1=0.035
dropHeight2=0.1
dropHeight3=0.155
ikSpeed={0.2,0.2,0.2,0.2}
ikAccel={0.1,0.1,0.1,0.1}
ikJerk={0.1,0.1,0.1,0.1}
fkSpeed={1,1,1,1,1}
fkAccel={0.6,0.6,0.6,0.6,0.6}
fkJerk={1,1,1,1,1}
shapePosition0={3.0000,-1.7300,0.4000}
shapePosition1={3.0000,-1.2528,0.4000}
size={6.0000e-02, 6.0000e-02, 6.0000e-02}
setGripperTargetMovingWithVehicle()
setFkMode()
openGripper()
--box1
shape1=sim.createPureShape(0,2 + 8,size,1,nil)
sim.setShapeColor(shape1,blue,sim.colorcomponent_ambient_diffuse,{0,0,255})
sim.setObjectPosition(shape1,-1,shapePosition0)
sim.setObjectSpecialProperty(shape1,sim.objectspecialproperty_renderable)
sim.setObjectPosition(vehicleTarget,-1,{1.1841,-1.7584,0})
sim.setObjectOrientation(vehicleTarget,-1,{0,0,4.71})
waitToReachVehicleTargetPositionAndOrientation()
m,angle=getBoxAdjustedMatrixAndFacingAngle2(getPositionUsingVision(),getMatrixUsingVision())
sim.setObjectPosition(vehicleTarget,-1,{m[4]-m[1]*dist3,m[8]-m[5]*dist3,0})
sim.setObjectOrientation(vehicleTarget,-1,{0,0,angle})
waitToReachVehicleTargetPositionAndOrientation()
sim.rmlMoveToJointPositions(armJoints,-1,nil,nil,fkSpeed,fkAccel,fkJerk,pickup1,nil)
setIkMode(true)
p=sim.getObjectPosition(gripperTarget,-1)
p[1]=m[4]
p[2]=m[8]
p[3]=m[12]
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
closeGripper()
p[3]=p[3]+0.05
sim.rmlMoveToPosition(gripperTarget,-1,-1,nil,nil,ikSpeed,ikAccel,ikJerk,p,nil,nil)
sortByColor(dropHeight1)
--box2
shape2=sim.createPureShape(0,2 + 8,size,1,nil)
sim.setShapeColor(shape2,blue,sim.colorcomponent_ambient_diffuse,{0,255,0})
sim.setObjectPosition(shape2,-1,shapePosition0)
sim.setObjectSpecialProperty(shape2,sim.objectspecialproperty_renderable)
sim.setObjectPosition(vehicleTarget,-1,{1.1841,-1.7584,0})
sim.setObjectOrientation(vehicleTarget,-1,{0,0,4.71})
waitToReachVehicleTargetPositionAndOrientation()
pickupBoxFromPlaceWithVision(getPositionUsingVision(),getMatrixUsingVision(),pickup1)
sortByColor(dropHeight1)
--box3
shape3=sim.createPureShape(0,2 + 8,size,1,nil)
sim.setShapeColor(shape3,blue,sim.colorcomponent_ambient_diffuse,{255,0,0})
sim.setObjectPosition(shape3,-1,shapePosition0)
sim.setObjectSpecialProperty(shape3,sim.objectspecialproperty_renderable)
sim.setObjectPosition(vehicleTarget,-1,{1.1841,-1.7584,0})
sim.setObjectOrientation(vehicleTarget,-1,{0,0,4.71})
waitToReachVehicleTargetPositionAndOrientation()
pickupBoxFromPlaceWithVision(getPositionUsingVision(),getMatrixUsingVision(),pickup1)
--node based navigation
sim.setObjectPosition(vehicleTarget,-1,node0P)
sim.setObjectOrientation(vehicleTarget,-1,{0,0,-4.71})
waitToReachVehicleTargetPositionAndOrientation()
sim.setObjectPosition(vehicleTarget,-1,node1P)
sim.setObjectOrientation(vehicleTarget,-1,{0,0,-4.71})
waitToReachVehicleTargetPositionAndOrientation()
sortByColor(dropHeight1)
--box 4
shape4=sim.createPureShape(0,2 + 8,size,1,nil)
sim.setShapeColor(shape4,blue,sim.colorcomponent_ambient_diffuse,{0,255,0})
sim.setObjectPosition(shape4,-1,shapePosition0)
sim.setObjectSpecialProperty(shape4,sim.objectspecialproperty_renderable)
--node based navigation
sim.setObjectPosition(vehicleTarget,-1,node1P)
sim.setObjectOrientation(vehicleTarget,-1,{0,0,4.71})
waitToReachVehicleTargetPositionAndOrientation()
sim.setObjectPosition(vehicleTarget,-1,node0P)
sim.setObjectOrientation(vehicleTarget,-1,{0,0,4.71})
waitToReachVehicleTargetPositionAndOrientation()
sim.setObjectPosition(vehicleTarget,-1,{1.1841,-1.7584,0})
sim.setObjectOrientation(vehicleTarget,-1,{0,0,4.71})
waitToReachVehicleTargetPositionAndOrientation()
pickupBoxFromPlaceWithVision(getPositionUsingVision(),getMatrixUsingVision(),pickup1)
sim.setObjectPosition(vehicleTarget,-1,{1.1841,-1.7584,0})
sim.setObjectOrientation(vehicleTarget,-1,{0,0,4.71})
waitToReachVehicleTargetPositionAndOrientation()
dropToPlatform(platformDrop2)
pickupFromPlatformAndReorient(shape4)
sortByColor(dropHeight2)
sim.stopSimulation()
end