CoppeliaSim传送带仿真:动态生成不同尺寸和颜色的立方体
function sysCall_init()
sensor = sim.getObjectHandle('conveyorBelt_sensor')
pathHandle = sim.getObjectHandle('Path')
forwarder = sim.getObjectHandle('conveyorForwarder')
sim.setPathTargetNominalVelocity(pathHandle, 0) -- for backward compatibility
tick = 0
counter = 1
cubicSize = {0.05, 0.05, 0.05}
cubicSize_s = {0.05, 0.04, 0.05}
cubicWeight = 0.2
shapeType_Cubic = 0
red = {1.00, 0.29, 0.21}
green = {0.28, 1, 0.21}
math.randomseed(tostring(os.time()):reverse():sub(1, 7))
greenBigCounter = 18
greenSmallCounter = 9
redBigCounter = 18
redSmallCounter = 9
smallCounter = 18
bigCounter = 36
totalCounter = bigCounter + smallCounter
poseMatrix = sim.getObjectMatrix(forwarder, -1)
poseMatrix[4] = poseMatrix[4] + 0.4
poseMatrix[12] = poseMatrix[12] + 0.15
end
function sysCall_cleanup()
end
function sysCall_actuation()
beltVelocity = sim.getScriptSimulationParameter(sim.handle_self, 'conveyorBeltVelocity')
ss = sim.readProximitySensor(sensor)
--sim.addStatusbarMessage(string.format('ss=%f', ss))
if sim.readProximitySensor(sensor) > 0 or sim.getIntegerSignal('getdata') == 1 then
beltVelocity = 0
end
local dt = sim.getSimulationTimeStep()
local pos = sim.getPathPosition(pathHandle)
pos = pos + beltVelocity * dt
sim.setPathPosition(pathHandle, pos) -- update the path's intrinsic position
-- Here we 'fake' the transportation pads with a single static rectangle that we dynamically reset
-- at each simulation pass (while not forgetting to set its initial velocity vector) :
local relativeLinearVelocity = {-beltVelocity, 0, 0}
-- Reset the dynamic rectangle from the simulation (it will be removed and added again)
sim.resetDynamicObject(forwarder)
-- Compute the absolute velocity vector:
local m = sim.getObjectMatrix(forwarder, -1)
m[4] = 0 -- Make sure the translation component is discarded
m[8] = 0 -- Make sure the translation component is discarded
m[12] = 0 -- Make sure the translation component is discarded
local absoluteLinearVelocity = sim.multiplyVector(m, relativeLinearVelocity)
-- Now set the initial velocity of the dynamic rectangle:
sim.setObjectFloatParameter(forwarder, sim.shapefloatparam_init_velocity_x, absoluteLinearVelocity[1])
sim.setObjectFloatParameter(forwarder, sim.shapefloatparam_init_velocity_y, absoluteLinearVelocity[2])
sim.setObjectFloatParameter(forwarder, sim.shapefloatparam_init_velocity_z, absoluteLinearVelocity[3])
tick = tick + 1
cubicHandles = {}
if (tick % 4 == 0) and (totalCounter > 0) and (beltVelocity > 0) then
if (math.random(bigCounter + smallCounter) <= smallCounter) then
cubicHandles[counter] = sim.createPureShape(shapeType_Cubic, 14, cubicSize_s, cubicWeight, nil)
smallCounter = smallCounter - 1
if (math.random(redSmallCounter + greenSmallCounter) <= redSmallCounter) then
sim.setShapeColor(cubicHandles[counter], nil, sim.colorcomponent_ambient_diffuse, red)
redSmallCounter = redSmallCounter - 1
else
sim.setShapeColor(cubicHandles[counter], nil, sim.colorcomponent_ambient_diffuse, green)
greenSmallCounter = greenSmallCounter - 1
end
else
cubicHandles[counter] = sim.createPureShape(shapeType_Cubic, 14, cubicSize, cubicWeight, nil)
bigCounter = bigCounter - 1
if (math.random(redBigCounter + greenBigCounter) <= redBigCounter) then
sim.setShapeColor(cubicHandles[counter], nil, sim.colorcomponent_ambient_diffuse, red)
redBigCounter = redBigCounter - 1
else
sim.setShapeColor(cubicHandles[counter], nil, sim.colorcomponent_ambient_diffuse, green)
greenBigCounter = greenBigCounter - 1
end
end
--sim.setObjectSpecialProperty(cubicHandles[counter], sim.objectspecialproperty_renderable)
sim.setObjectSpecialProperty(cubicHandles[counter], (sim.objectspecialproperty_detectable_all + sim.objectspecialproperty_renderable))
totalCounter = totalCounter - 1
--sim.addStatusbarMessage(string.format('x=%f,y=%f,z=%f', poseMatrix[4], poseMatrix[8], poseMatrix[12]))
local CubicMatrix = poseMatrix
CubicMatrix[8] = poseMatrix[8] + 0.05 * math.random() - 0.03
--CubicMatrix[8] = poseMatrix[8] + 0.02 * math.random() - 0.01
if (CubicMatrix[8] > -2.0000e-01) then
CubicMatrix[8] = -2.0000e-01
end
if (CubicMatrix[8] < -3.0000e-01) then
CubicMatrix[8] = -3.0000e-01
end
sim.setObjectMatrix(cubicHandles[counter], -1, poseMatrix)
counter = counter + 1
end
end
这段代码模拟了传送带输送立方体的过程,并包含以下功能:
- 初始化函数
sysCall_init(): 获取场景中必要的对象句柄,设置传送带初始速度,定义立方体的尺寸、颜色等参数,并初始化计数器和随机数生成器。 - 清理函数
sysCall_cleanup(): 目前为空函数,没有执行任何操作。 - 执行函数
sysCall_actuation(): 在每个仿真步骤中,读取传感器数据控制传送带速度,更新传送带位置,动态生成不同尺寸和颜色的立方体,并设置立方体的初始位置和速度。
代码亮点:
- 使用
sim.createPureShape()函数创建立方体,并通过设置不同的尺寸参数生成大小不同的立方体。 - 使用
sim.setShapeColor()函数设置立方体的颜色,并通过随机数生成不同颜色的立方体。 - 使用
sim.setObjectSpecialProperty()函数设置立方体的属性,使其可以被检测到。 - 使用
sim.setObjectMatrix()函数设置立方体的初始位置,并通过随机数使立方体的位置产生随机偏移。 - 使用
sim.resetDynamicObject()函数重置传送带前进器的动态属性,使其可以在每个仿真步骤中重新设置速度。
代码改进建议:
- 可以将立方体的生成逻辑封装成一个独立的函数,提高代码可读性和可维护性。
- 可以使用 CoppeliaSim 的图形化界面设置一些参数,例如传送带速度、立方体生成概率等,方便用户调整仿真参数。
- 可以添加碰撞检测机制,避免立方体之间发生穿透现象。
总而言之,这段代码提供了一个简单的 CoppeliaSim 传送带仿真示例,展示了如何使用 Lua 脚本控制场景中的对象、生成物体并设置其属性。通过学习和修改这段代码,用户可以进一步探索 CoppeliaSim 的功能,实现更加复杂和逼真的仿真场景。
原文地址: https://www.cveoy.top/t/topic/f2sj 著作权归作者所有。请勿转载和采集!