
仿真客户端, 代码中启动了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) then
- return(nil) -- 错误
- end
- if (header:byte(1)==59)and(header:byte(2)==57) then
- local l=header:byte(3)+header:byte(4)*256
- return(client:receive(l))
- else
- return(nil) -- 错误
- end
- end
-
- -- 感知系统调用
- function sysCall_sensing()
- local p=sim.getObjectPosition(robot)
- sim.addDrawingObjectItem(drawingCont,p)
- end
-
- -- 清理系统调用
- function sysCall_cleanup()
- if client then
- client: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+1
- if (newPortNb>=portStart+portRange) then
- newPortNb=portStart
- end
- sim.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' 无法启动。模拟将无法正常运行")
- else
- sim.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) then
- dataOut[1]=dist
- end
- -- 将数据打包成字符串:
- dataOut=sim.packFloatTable(dataOut)
- -- 发送数据:
- writeSocketData(client,dataOut)
- -- 从服务器读取回复:
- local returnData=readSocketData(client)
- if (returnData==nil) then
- break -- 读取错误
- end
- -- 解包接收到的数据:
- returnData=sim.unpackFloatTable(returnData)
- -- 将值应用为电机速度:
- sim.setJointTargetVelocity(leftMotor,returnData[1])
- sim.setJointTargetVelocity(rightMotor,returnData[2])
-
- -- 如果模拟时间未改变,请不要在这个循环中浪费时间!这也与主脚本同步
- sim.step() -- 这个协程将在下一个模拟步骤中恢复
- end
- end
- end
- end