为了进行初步研究,我尝试将一个简单的模拟环境与基于神经网络的python控制器连接起来。在模拟的统一环境中,主人公应该根据自己的经验学习一种行为:主要角色扫描环境并将其存储在数据结构中
这个数据结构通过TCP发送到python中运行的服务器
在python中执行一个复杂的计算(基于从Unity接收到的数据),并产生一个结果(action)
结果(操作)通过TCP发送回Unity。角色执行与结果对应的操作。在
重复步骤1-4直到无穷大(除非客户机或服务器停止)。在
这个过程可以抽象为一个通过TCP发送的乒乓消息,其中Unity发送一个“Ping”,Python进行一些计算并生成一个“Pong”,这个“Pong”被发送回Unity,Unity更新模拟并再次生成一个“Ping”并将其发送给Python。。。在
我目前正在一个玩具项目中测试这个过程。我有一个脚本附加到Unity场景中的主摄像头上,如下所示:using UnityEngine;
using System.Collections;
using System;
using System.IO;
using System.Net.Sockets;
using Newtonsoft.Json;
using System.Threading;
public class networkSocketSO : MonoBehaviour
{
public String host = "localhost";
public Int32 port = 50000;
internal Boolean socket_ready = false;
internal String input_buffer = "";
TcpClient tcp_socket;
NetworkStream net_stream;
StreamWriter socket_writer;
StreamReader socket_reader;
private void Start()
{
setupSocket();
}
void Update()
{
string received_data = readSocket();
switch (received_data)
{
case "pong":
Debug.Log("Python controller sent: " + (string)received_data);
writeSocket("ping");
break;
default:
Debug.Log("Nothing received");
break;
}
}
void OnApplicationQuit()
{
closeSocket();
}
// Helper methods for:
//...setting up the communication
public void setupSocket()
{
try
{
tcp_socket = new TcpClient(host, port);
net_stream = tcp_socket.GetStream();
socket_writer = new StreamWriter(net_stream);
socket_reader = new StreamReader(net_stream);
socket_ready = true;
}
catch (Exception e)
{
// Something went wrong
Debug.Log("Socket error: " + e);
}
}
//... writing to a socket...
public void writeSocket(string line)
{
if (!socket_ready)
return;
line = line + "\r\n";
socket_writer.Write(line);
socket_writer.Flush();
}
//... reading from a socket...
public String readSocket()
{
if (!socket_ready)
return "";
if (net_stream.DataAvailable)
return socket_reader.ReadLine();
return "";
}
//... closing a socket...
public void closeSocket()
{
if (!socket_ready)
return;
socket_writer.Close();
socket_reader.Close();
tcp_socket.Close();
socket_ready = false;
}
}
以及一个包含以下代码的python服务器:
^{pr2}$
如果我启动服务器,然后运行Unity项目,就会发生奇怪的事情。也就是说,python服务器似乎不理解Unity客户端发送的“ping”字符串。此外,我希望Unity模拟中的帧在从python服务器接收到“Pong”消息之前不要更新。在
我读过关于使用协同路由或线程的类似问题的解决方案,但我担心它会建立另一个“时钟”,结果没有真正的ping pong updateframe ping pong updateframe。。。过程。在
有什么想法吗?在
提前谢谢!!!在
请注意,真正的消息不是“Ping”和“Pong”,而是适当的Json对象。这只是一个简化。在
编辑:
我首先启动python服务器,然后启动Unity模拟(在编辑器中)。
在python控制台上,我得到:Client connected.
Unity Sent Something Else: ping
…这证明了我的说法“python不理解通过Unity(C#)发送的字符串”
在Unity控制台中,我得到: