coppelia wrote: ↑19 Mar 2025, 10:46
Hello,
can you create a minimalistic, self-contained scene that illustrates the problem, so that we can easily reproduce that behaviour?
What is calling
zmq_REQ_send_and_recv? Is that code threaded or non-threaded?
Cheers
I will post the lua code for the entire script below to help you reproduce the problem. This ur5 robot arm is the only thing in the scene.
Basically, our task is to calculate the error of the control in real time with the help of an external python script. Unfortunately, the current external algorithm is not perfect. In particular, it is very slow, which means that this calculation can take several seconds. But it will eventually return the result, so this shouldn't cause problems in a thread callback function, right?
I'm a bit confused by the error message, as it seems to be triggering some c-code issue directly, without any higher level hints?
Code: Select all
sim=require'sim'
simZMQ = require('simZMQ')
print('ZMQ connected. UR5 requester ready to receive control orders...')
context = simZMQ.ctx_new()
requester = simZMQ.socket(context, simZMQ.REQ)
simZMQ.setsockopt(requester,simZMQ.RCVTIMEO,sim.packInt32Table{2000})
simZMQ.setsockopt(requester,simZMQ.LINGER,sim.packInt32Table{500})
simZMQ.connect(requester, 'tcp://127.0.0.1:5557')
-- Choose use zmq or not
useZMQ = true
msg1={0,0}
jointHandle = sim.getObject('../joint',{index=1})
--jointHandle = sim.getObject('../../damn')
-- Control Parameters
Kp = 0.1 -- Proportional gain
Ki = 0.05 -- Integral gain
Kd = 0.01 -- Derivative gain
-- Target position (modify as needed)
targetPosition = 1 -- Target in radians
-- Choose control mode: true for PID, false for PI
usePID = true
--usePID = false
-- Initialize variables
previousError = 0
integralError = 0
function sysCall_thread()
while true do
-- Get the current joint position
currentPosition = sim.getJointPosition(jointHandle)
print(string.format("currentPosition: %.4f", currentPosition))
-- Compute error
if useZMQ then
msg1[1] = targetPosition
msg1[2] = currentPosition
msg2 = zmq_REQ_send_and_recv(msg1)
err = msg2[1]
else
err = targetPosition - currentPosition
end
if -0.1<err and err<0.1 then
sim.setJointTargetVelocity(jointHandle, 0)
print('Reached.')
-- Change direction for demonstration.
targetPosition = -targetPosition
end
-- Compute integral term
integralError = integralError + err * sim.getSimulationTimeStep()
-- Compute derivative term (only used in PID mode)
derivativeError = (err - previousError) / sim.getSimulationTimeStep()
-- Compute control output
if usePID then
velocityCommand = Kp * err + Ki * integralError + Kd * derivativeError
else
velocityCommand = Kp * err + Ki * integralError -- PI control only
end
-- Apply velocity command to joint
sim.setJointTargetVelocity(jointHandle, velocityCommand)
-- Update previous error
previousError = err
end
end
function sysCall_cleanup()
simZMQ.close(requester)
simZMQ.ctx_term(context)
end
function zmq_REQ_send_and_recv(dataSend)
---- SEND
printf('[requester] Sending "%s"...', dataSend)
dataSend=sim.packFloatTable(dataSend)
print(dataSend)
simZMQ.send(requester, dataSend, 0)
---- RECEIVE
local rc, returnData = simZMQ.recv(requester, 0)
if rc~=-1 then
dataRecv = sim.unpackFloatTable(returnData)
printf('[requester] Received "%s"', dataRecv)
end
return(dataRecv)
end