仿真客户端, 代码中启动了tcp服务器。
sim=require'sim'
socket=require'socket'-- 以下函数将数据写入套接字(仅为简单起见只处理单个数据包):
writeSocketData=function(client,data)local header=string.char(59,57,math.mod(#data,256),math.floor(#data/256),0,0)-- 数据包头是(在这种情况下):headerID(59,57),数据大小(WORD),剩余包数(WORD)但在这里未使用client:send(header..data)
end-- 以下函数从套接字读取数据(仅为简单起见只处理单个数据包):
readSocketData=function(client)-- 数据包头是:headerID(59,57),数据大小(WORD),剩余包数(WORD)但在这里未使用local header=client:receive(6)if (header==nil) thenreturn(nil) -- 错误endif (header:byte(1)==59)and(header:byte(2)==57) thenlocal l=header:byte(3)+header:byte(4)*256return(client:receive(l))elsereturn(nil) -- 错误end
end-- 感知系统调用
function sysCall_sensing() local p=sim.getObjectPosition(robot)sim.addDrawingObjectItem(drawingCont,p)
end -- 清理系统调用
function sysCall_cleanup()if client thenclient:close()end
end-- 线程系统调用
function sysCall_thread()-- 初始化:robot=sim.getObject('.')drawingCont=sim.addDrawingObject(sim.drawing_linestrip+sim.drawing_cyclic,2,0,-1,400,{1,1,0},nil,nil,{1,1,0})sim.setStepping(true) -- 我们希望手动切换以同步(并且不浪费处理时间!)-- 获取一些句柄:local leftMotor=sim.getObject("./LeftMotor") -- 左电机的句柄local rightMotor=sim.getObject("./RightMotor") -- 右电机的句柄local noseSensor=sim.getObject("./SensingNose") -- 接近传感器的句柄-- 在可能未被使用的端口上启动服务器(尽量使用相似的代码):local portNb=sim.getInt32Param(sim.intparam_server_port_next)local portStart=sim.getInt32Param(sim.intparam_server_port_start)local portRange=sim.getInt32Param(sim.intparam_server_port_range)local newPortNb=portNb+1if (newPortNb>=portStart+portRange) thennewPortNb=portStartendsim.setInt32Param(sim.intparam_server_port_next,newPortNb)local result=sim.launchExecutable('bubbleRobServer',portNb,0) -- 将最后一个参数设置为1以查看启动服务器的控制台if (result==-1) then-- 无法启动可执行文件!sim.addLog(sim.verbosity_scripterrors,"'bubbleRobServer' 无法启动。模拟将无法正常运行")elsesim.wait(1,false)-- 可执行文件可以启动。现在构建一个套接字并连接到服务器:client=socket.tcp()local result=client:connect('127.0.0.1',portNb)if (result==1) then-- 我们可以连接到服务器while (true) do-- 发送接近传感器和模拟时间到bubbleRob服务器应用程序:-- 准备要发送的数据:local dataOut={0,sim.getSimulationTime()}local result,dist=sim.readProximitySensor(noseSensor)if (result>0) thendataOut[1]=distend-- 将数据打包成字符串:dataOut=sim.packFloatTable(dataOut)-- 发送数据:writeSocketData(client,dataOut)-- 从服务器读取回复:local returnData=readSocketData(client)if (returnData==nil) thenbreak -- 读取错误end-- 解包接收到的数据:returnData=sim.unpackFloatTable(returnData)-- 将值应用为电机速度:sim.setJointTargetVelocity(leftMotor,returnData[1])sim.setJointTargetVelocity(rightMotor,returnData[2])-- 如果模拟时间未改变,请不要在这个循环中浪费时间!这也与主脚本同步sim.step() -- 这个协程将在下一个模拟步骤中恢复endendend
end