function executePath(joints, path)
-- path is a list of configurations
local need_stop = false
disableDynamic(idx)
if sim.getSimulationStopping() then
need_stop = true
sim.startSimulation()
end
local sw=sim.setStepping(true)
for i, conf in ipairs(path) do
for j, joint in ipairs(joints) do
sim.setJointPosition(joint, conf[j])
end
sim.step()
end
sim.setStepping(sw)
if need_stop then
sim.stopSimulation()
end
end
And call it from a customization script's sysCall_thread
--script2:
function triggerPathExecution(args)
allCommands[#allCommands + 1] = {cmd = 'executePath', args = args}
end
function sysCall_thread()
allCommands = {}
while not sim.getSimulationStopping() do
if #allCommands > 0 then
local cmd = allCommands[1]
table.remove(allCommands, 1)
if cmd.cmd == 'executePath' then
-- handle the command here. sim.step is allowed.
end
else
sim.step()
end
end
end
Thank you. I'm still confused about coppeliaSim thread.
Based on my current understanding, coppeliaSim implements multi-threading through Lua coroutine, which is non-preemptive. CoppeliaSim provides preemptive-like experience by calling coroutine.yield and coroutine.resume periodically (2ms) to switch between simulation and user defined thread. Is my understanding correct?
And here are some more questions.
What would happen if there are multiple scripts calling sim.step? How many times would the main thread be yielded?
How to distinguish thread and non-thread script? Is there any coroutine if I have no sysCall_thread in any script?
1. sim.step acts only on the current script. So each time you call it (from within a thread (or coroutine)), the function immediately after it will be called only once the simulation time has increased to t+dt. Calling sim.step twice from within a thread will bring you to t+2*dt. Try this:
function sysCall_init()
sim = require('sim')
end
function sysCall_thread()
while not sim.getSimulationStopping() do
print(sim.getSimulationTime())
end
end
function sysCall_init()
sim = require('sim')
end
function sysCall_thread()
sim.setStepping(true)
while not sim.getSimulationStopping() do
print(sim.getSimulationTime())
end
end
function sysCall_init()
sim = require('sim')
end
function sysCall_thread()
sim.setStepping(true)
while not sim.getSimulationStopping() do
print(sim.getSimulationTime())
sim.step()
end
end
But technically, sysCall_thread is handled via hidden coroutine code.
2. You can check if you run a coroutine via following code: