这种情况下如何让多个python程序进行通信?

How to make multiple python programs communicate in this situation?

我在 Python 有点新,我正在从事一个机器人项目。我的问题的简短形式是,我试图找到 最好的 方式(针对我的情况)同时 运行 多个 python 程序。

一点上下文,我的机器人是一个服务机器人平台,它能够使用图像算法跟踪标记和路径,还可以从远程计算机接收命令。我想有单独的程序来处理图像处理、驱动等,然后通过一个主程序来管理它们。我知道我不能使用像函数或 类 这样的基本东西,因为这些过程中的每一个都必须连续循环,而且我不想在一个 while 循环中将所有代码组合到 运行 ,因为它 运行 非常慢,而且管理起来要困难得多。

那么,简而言之,我如何制作两个独立的循环程序 "talk"?就像我想让成像程序将它看到的信息发送给驾驶和转向程序等

我做了一些研究,发现了一些关于多线程和 API 之类的信息,但我无法真正分辨出我真正要找的是哪一个。

为了澄清,我只需要指出正确的方向。这 似乎 不是一个非常高层次的东西,而且我知道那里肯定有教程,我只是很困惑,因为我正在自学这个我走的时候。

我认为 multiproccessing 库可能是一个解决方案。 您将能够 运行 多个并行进程,每个进程都可以执行其特定的工作,同时相互发送数据。

你可以检查这个example

这是通用目录 walker,它具有扫描目录树并将数据传递给其他进程的进程,该进程扫描已发现文件夹中的文件。所有这些都是并行完成的。

经过一番摸索,我发现使用 IPC 是一个很好的解决方案。我使用的过程并不太难,我只是制作了一些非常简单的服务器和客户端 classes 并让它们通过本地主机 IP 进行通信。毫无疑问,有更好的方法来做到这一点,但对于像我这样的初学者来说,这是一种无需过多修改代码即可让两个程序对话的简单方法。对于那些尝试做与我类似的事情的人,这里是我为自己制作的 classes。公平警告,它们并不完全原始甚至非常复杂,但它们完成了工作。

这是我为服务器制作的class:

import socket
from random import random
from time import sleep

class ServerObject:

    def __init__(self,host_address,port):

        self._host_address = host_address
        self._s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self._s.bind((self._host_address,port))

    def handshake(self):

        print "Server Started. Awaiting Connection"

        while True: 
            _data, _addr = self._s.recvfrom(1024)
            if str(self._s.recvfrom(1024)[0]) == 'marco':
                break

        print 'marco recieved. sending polo...'

        while True:
            self._s.sendto('polo',_addr)
            if str(self._s.recvfrom(1024)[0]) == 'confirm':
                break
            sleep(.5)

        print 'connection verified'

        self._addr = _addr

        return True

    def send(self,data):

        self._s.sendto(str(data),self._addr)

    def recieve(self,mode = 0):

        _data, _addr = self._s.recvfrom(1024)

        if mode == 0:
            return str(_data)
        if mode == 1:
            return int(_data)
        if mode == 2:
            return float(_data)
        if mode == 3:
            return tuple(_data)

    def change_port(self,port):

        self._s.bind((self._host_address,port))

    def close(self):
        self._s.close()
        print '_socket closed_'


if __name__ == '__main__':

    host = '127.0.0.1'

    talk = ServerObject(host,6003)
    talk.handshake()

这是我为客户制作的class:

import socket
from time import sleep

class ClientObject:

    def __init__(self,host_address,server_port,port = 0):

        self._server = (host_address,server_port)
        self._s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self._s.bind((host_address,port))


    def handshake(self):

        print ' sending marco'

        self._s.sendto('marco',self._server)
        sleep(.1)
        self._s.sendto('marco',self._server)

        while True:
            if str(self._s.recvfrom(1024)[0]) == 'polo':
                break

        #self._s.sendto('marco',self._server)
        #self._s.sendto('marco',self._server)

        print ' connection verified'
        self._s.sendto('confirm',self._server)

        self._s.setblocking(0)

        return True

    def recieve(self,mode = 0):

        _data, _addr = self._s.recvfrom(1024)

        if mode == 0:
            return str(_data)
        if mode == 1:
            return int(_data)
        if mode == 2:
            return float(_data)
        if mode == 3:
            return tuple(_data)

    def send(self,data):
        self._s.sendto(str(data),self._server)

    def close(self):
        self._s.close()
        print '_socket closed_'


if __name__ == '__main__':

    host = '127.0.0.1'
    port = 0

    talk = ClientObject(host,24603,port)
    talk.handshake()

    #while True:
        #print talk.recieve()

在主要发送数据的程序上使用 ServerObject class,在主要接收数据的程序上使用 ClientObject class。这些 可以 在许多情况下被翻转,但我发现最好以这种方式来利用 UDP。客户端 class 有一个可选的端口变量,默认设置为 0。这是因为对于 UDP,客户端需要另一个端口来建立自己。 0 表示它将选择一个可用端口,但如果您指定一个端口,则可以在客户端离线时重新建立连接而无需重新启动两个程序。

首先在两个程序上使用握手,确保使用相同的 IP 和端口(不是指客户端上的最后一个变量),然后使用发送和接收函数来回传递数据。

同样,这些都不是很好,实际上使用这种方法会出现很多问题,但是对于一个简单的任务,他们就完成了工作。我设置了握手来打印正在发生的事情的验证,但如果这些变得烦人,你可以删除这些行。

希望对您有所帮助!

这可能有点超出您的项目范围,但您是否考虑过使用 ROS?它允许您同时 运行 一堆不同的节点(可以是 Python 脚本),通过发布和订阅主题进行通信。它们可以在同一系统上(即机器人上的一个或多个节点)或不同的系统(即机器人上的一个节点,PC 上的多个节点)。 ROS 也有很多很棒的内置工具和库,专门为机器人系统制作,例如可视化、映射、里程计等。这里有一些入门信息:

https://en.wikipedia.org/wiki/Robot_Operating_System

http://wiki.ros.org/ROS/StartGuide

它通常用于比您描述的大得多的框架,并且注意它需要相当多的时间(根据我的经验)来实施,但它是一旦启动并 运行ning 就很容易扩展。就像我说的,这完全取决于您的项目范围!

祝你好运!