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 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录