Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多线程-XMLRPC服务器在Python 2.7.12中将类对象注册为单个线程_Python_Multithreading_Xmlrpclib - Fatal编程技术网

多线程-XMLRPC服务器在Python 2.7.12中将类对象注册为单个线程

多线程-XMLRPC服务器在Python 2.7.12中将类对象注册为单个线程,python,multithreading,xmlrpclib,Python,Multithreading,Xmlrpclib,在服务器端,我准备了一个python脚本,其中执行了以下任务 任务1=>从传感器获取数据 任务2=>根据从传感器获取的数据,将机器人控制单元中的某个寄存器设置为1或0 为了完成上述任务,我实现了两个单独的线程。为了执行任务1,我定义了类“SensorEvaluationBoard(Thread)”,为了执行任务2,我定义了类“UR_RTDE(Thread)”。有关更多详细信息,请从服务器端查看以下python脚本 服务器端: #!/usr/bin/env python import tim

在服务器端,我准备了一个python脚本,其中执行了以下任务

  • 任务1=>从传感器获取数据
  • 任务2=>根据从传感器获取的数据,将机器人控制单元中的某个寄存器设置为1或0
为了完成上述任务,我实现了两个单独的线程。为了执行任务1,我定义了类“SensorEvaluationBoard(Thread)”,为了执行任务2,我定义了类“UR_RTDE(Thread)”。有关更多详细信息,请从服务器端查看以下python脚本

服务器端:

#!/usr/bin/env python

import time
from time import sleep
import sys
import string
import traceback
import logging

import socket
import struct
import copy

import xmlrpclib
# xmlrpclib.Marshaller.dispatch[type(0L)] = lambda _, v, w: w("<value><i8>%d</i8></value>" % v)
# xmlrpclib.dumps((2**63-1,))
xmlrpclib.Binary
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler

import threading
from threading import Thread, Lock

# "https://www.universal-robots.com/articles/ur-articles/real-time-data-exchange-rtde-guide/"
import rtde.rtde as rtde 
import rtde.rtde_config as rtde_config

# urHost = "127.0.0.1" # UR robot's IP address
# "https://www.universal-robots.com/articles/ur-articles/remote-control-via-tcpip/"
urPort = 30004 # Port number dedicated for UR robot's secondary interface 
config_filename = 'control_loop_configuration.xml'
mutexFreedriveMode = Lock()


loadCycleOfSensor1, loadCycleOfSensor2, loadCycleOfSensor3 = "", "", ""
c1, c2, c3 = 0, 0, 0
cnt = 0 
data = bytearray()

sensEvalBoard_ipAddr = "" # IP address of sensor evaluation board
sensEvalBoard_port = 0 # Port number of  of sensor evaluation board
DEFAULT_TIMEOUT = 1
mutexSensVal = Lock()
sebSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # initializing the socket object
mutexSEBSocket = Lock()

def set_ipaddr(new_daemon_host): 
    global sensEvalBoard_ipAddr 
    sensEvalBoard_ipAddr = new_daemon_host 
    return sensEvalBoard_ipAddr

def get_ipaddr():
    tmp = ""
    if str(sensEvalBoard_ipAddr):
        tmp = sensEvalBoard_ipAddr
    else:
        tmp = "No ip address set"
    return tmp

def set_portnum(new_daemon_port): 
    global sensEvalBoard_port 
    sensEvalBoard_port = int (new_daemon_port) 
    return sensEvalBoard_port

def get_portnum():
    tmp = 0
    if sensEvalBoard_port != 0:
        tmp = sensEvalBoard_port
    else:
        tmp = 0
    return tmp

class ConnectionState:
    DISCONNECTED = 0
    CONNECTED = 1
    STARTED = 2
    PAUSED = 3

class SensorEvaluationBoardException(Exception):
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return repr(self.msg)

class SensorEvaluationBoard(Thread): 
    def __init__(self, hostname, port): 
        # Call the Thread class's init function
        Thread.__init__(self)
        self.__hostname = hostname
        self.__port = port 
        self.__conn_state = ConnectionState.DISCONNECTED
        self.__sock = None 

        logging.basicConfig(level=logging.DEBUG)
        self.__logger = logging.getLogger(self.__class__.__name__)
        # self.__streamHandler = logging.StreamHandler()
        # self.__streamHandler.setLevel(logging.DEBUG)
        # self.__formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        # self.__streamHandler.setFormatter(self.__formatter)

        # self.__logger.addHandler(self.__streamHandler)
    
    def connect(self): 
        global sebSocket

        if self.__sock:
            return

        self.__buf = b''
        try:
            self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.__sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
            self.__sock.settimeout(DEFAULT_TIMEOUT)
            self.__sock.connect((self.__hostname, self.__port))
            self.__conn_state = ConnectionState.CONNECTED
            
            sebSocket = copy.deepcopy(self.__sock)
        except (socket.timeout, socket.error):
            self.__sock = None
            raise

    def disconnect(self):
        if self.__sock:
            self.__sock.close()
            self.__sock = None
        self.__conn_state = ConnectionState.DISCONNECTED
        
    def is_connected(self):
        return self.__conn_state is not ConnectionState.DISCONNECTED

    def get_connection_state(self):
        return self.__conn_state
    
    def send_input_data(self, data): 
        self.__sock.send(data)
    
    def receive_output_data(self, input_data): 
        self.send_input_data(input_data)
        self.__rcvData = self.__sock.recv(1024)
        return self.__rcvData
    
    def run(self): 
        global loadCycleOfSensor1, loadCycleOfSensor2, loadCycleOfSensor3
        
        self.connect()
        while True: 
            if self.is_connected: 
                # print("Socket => connection state: " + str(self.get_connection_state()) + " means CONNECTED")
                
                self.__input_data = bytearray()
                self.__input_data.append(0x1) 
                self.__rcvData = self.receive_output_data(self.__input_data)
                self.__unpacker_string = 3*'I I I I I B B B B'
                self.__unpacker = struct.Struct('<B '+ self.__unpacker_string)
                self.__unpacked = self.__unpacker.unpack(self.__rcvData) 
                # print("Slave 1: "+ repr(self.__unpacked[1:10]))
                # print("Slave 2: "+ repr(self.__unpacked[10:19]))
                # print("Slave 3: "+ repr(self.__unpacked[19:28]))
                
                mutexSensVal.acquire()
                loadCycleOfSensor1 = str(self.__unpacked[1])
                loadCycleOfSensor2 = str(self.__unpacked[12])
                loadCycleOfSensor3 = str(self.__unpacked[20]) 
                # print("Load cycle of sensors 1, 2 and 3: ["+ loadCycleOfSensor1 + ", " + loadCycleOfSensor2 + ", " + loadCycleOfSensor3 + "]")
                mutexSensVal.release() 
                sleep(0.1)
            else: 
                print("Socket => connection state: " + str(self.get_connection_state()) + " means DISCONNECTED")

class UR_RTDE(Thread): 
    def __init__(self, host, port, config_filename): 
        # Call the Thread class's init function
        Thread.__init__(self) 
        self.__host = host
        self.__port = port
        self.__config_filename = config_filename

        logging.basicConfig(level=logging.DEBUG)        
        self.__logger = logging.getLogger(self.__class__.__name__)
        # self.__streamHandler = logging.StreamHandler()
        # self.__streamHandler.setLevel(logging.INFO)
        # self.__formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        # self.__streamHandler.setFormatter(self.__formatter)
        # self.__logger.addHandler(self.__streamHandler)

        self.__con = None
        self._rtde_ok = False
        self._recept_ok = False 
        self._dataAccessConfig = Lock()
        
        self.__keep_running = True        

    def init_rtde(self):
        self.__logger.debug("init_rtde")
        if not self._rtde_ok :
            if self.__con is None:
                self.connect_rtde()
            if not self._recept_ok:
                self.init_conf()
                self.send_conf_to_robot()
            self.start_communication()
            self._rtde_ok = True
    
    def connect_rtde(self): 

        self.__logger.debug("connect_rtde")
        try:
            self.__con = rtde.RTDE(self.__host, self.__port)
            self.__con.connect()
        except socket.timeout as e:
            self.__logger.error("failed to connect with robot", exc_info=True)
            self.__controller_info = None
            self.__con = None

        self.__controller_info = self.__con.get_controller_version()
        self.__logger.info("connected with UR established")
        self.__logger.info(self.__controller_info)
        return True
    
    def disconnect_rtde(self): 
        self.__con.send_pause()
        self.__con.disconnect()
        self.__logger.debug("disconnect_rtde")

    def init_conf(self):
        self.__logger.debug("init_conf")
        with self._dataAccessConfig:            
            self._conf = rtde_config.ConfigFile(self.__config_filename)
            self._state_names, self._state_types = self._conf.get_recipe('state')
            self._set_freedrive_name, self._set_freedrive_type = self._conf.get_recipe('set_freedrive')
    
    def send_conf_to_robot(self):
        self.__logger.debug("send_conf_to_robot")
        print("in send conf")
        try:
            self.__con.send_output_setup(self._state_names, self._state_types)
            self.__set_freedrive = self.__con.send_input_setup(self._set_freedrive_name, self._set_freedrive_type)

            self.__set_freedrive.__dict__[b"input_bit_register_64"] = 0
            self._recept_ok = True
        except Exception as e:
            self.__set_freedrive = None
            self.__logger.error("rtde recepts error", exc_info=True)
            self._recept_ok = False
    
    def start_communication(self):
        self.__logger.debug("start_communication")
        if not self.__con.is_connected():
            self.__logger.warning("no connection established")
        if not self.__con.send_start():
            self.__logger.warning("starting data_sync failed")
            sys.exit()
        
        self.__logger.info("started communication")
        return True

    def run(self): 
        global loadCycleOfSensor1, loadCycleOfSensor2, loadCycleOfSensor3
        global c1, c2, c3

        lowerThr_loadCycleOfSensor1, upperThr_loadCycleOfSensor1 = 400, 700        
        lowerThr_loadCycleOfSensor2, upperThr_loadCycleOfSensor2 = 100, 400
        lowerThr_loadCycleOfSensor3, upperThr_loadCycleOfSensor3 = 200, 425

        lTh_c1 = lowerThr_loadCycleOfSensor1 
        uTh_c1 = upperThr_loadCycleOfSensor1 
        
        lTh_c2 = lowerThr_loadCycleOfSensor2 
        uTh_c2 = upperThr_loadCycleOfSensor2 
        
        lTh_c3 = lowerThr_loadCycleOfSensor3 
        uTh_c3 = upperThr_loadCycleOfSensor3 

        self.init_rtde() 

        # Set the 'input_bit_register_64' to 0 by default
        self.__set_freedrive.__dict__[b"input_bit_register_64"] = 0 
        
        if self.__con.is_connected(): 
           while self.__keep_running: 
               # receive the current state
                self.__state = self.__con.receive()
                
                if self.__state is None:
                    break
                
                mutexSensVal.acquire()
                c1 = int (loadCycleOfSensor1) 
                self.__logger.info("Loading cycle of CapSen1 is " + str(c1)) 
                c2 = int (loadCycleOfSensor2) 
                self.__logger.info("Loading cycle of CapSen2 is " + str(c2)) 
                c3 = int (loadCycleOfSensor3) 
                self.__logger.info("Loading cycle of CapSen3 is " + str(c3)) 
                mutexSensVal.release() 

                mutexFreedriveMode.acquire()
                #  input_bit_register_64 refers to "general purpose input register 64" 
                # if "general purpose input register 64" variable is set to 1 => Freedrive mode is activated
                if ((lTh_c1 < c1 < uTh_c1) and (lTh_c2 < c2 < uTh_c2)):
                    self.__set_freedrive.__dict__[b"input_bit_register_64"] = 1 
                    self.__logger.info("Capacitive sensors 1 and 2 are touched by the human operator, Freedrive mode activated")
                elif ((lTh_c2 < c2 < uTh_c2) and (lTh_c3 < c3 < uTh_c3)):
                    self.__set_freedrive.__dict__[b"input_bit_register_64"] = 1 
                    self.__logger.info("Capacitive sensors 2 and 3 are touched by the human operator, Freedrive mode activated") 
                elif ((lTh_c3 < c3 < uTh_c3) and (lTh_c1 < c1 < uTh_c1)):
                    self.__set_freedrive.__dict__[b"input_bit_register_64"] = 1 
                    self.__logger.info("Capacitive sensors 1 and 3 are touched by the human operator, Freedrive mode activated")
                else: 
                    self.__set_freedrive.__dict__[b"input_bit_register_64"] = 0 
                    self.__logger.info("No two capacitive sensors are touched by the human operator, Freedrive mode deactivated")
                
                self.__con.send(self.__set_freedrive) 
                mutexFreedriveMode.release()
                sleep(0.1)
                
        self.disconnect_rtde()

def main():
    try: 
        # threadevent = threading.Event()
        # Create an object of Thread
        th_sensevalboard = SensorEvaluationBoard(sensEvalBoard_ipAddr, sensEvalBoard_port)
        # start the SensorEvaluationBoard thread
        th_sensevalboard.start()

        sleep(1)

        # Create an object of Thread
        th_rtde = UR_RTDE(urHost, urPort, config_filename)
        # start the RTDE thread
        th_rtde.start()

        return "SensorEvaluationBoard and RTDE threads has started..."

    except KeyboardInterrupt: 
        print("Terminating communication with the sensor evaluation board... ") 
        th_sensevalboard.disconnect()
        print("Socket => connection state: " + str(th_sensevalboard.get_connection_state()) + " means DISCONNECTED")
        th_sensevalboard.join()
        print ("SensorEvaluationBoard thread successfully closed")

        print("Terminating communication with the RTDE server... ") 
        th_rtde.disconnect()
        th_rtde.join()
        print ("RTDE thread successfully closed")

        return "SensorEvaluationBoard and RTDE threads has stopped..."

sys.stdout.write("CapSens daemon started")
sys.stderr.write("CapSens daemon started with caught exception")

# server_addr = ("127.0.0.1", 40405)
# server = SimpleXMLRPCServer(server_addr, SimpleXMLRPCRequestHandler, allow_none=True)
server = SimpleXMLRPCServer(("127.0.0.1", 40405), allow_none=True)

server.register_function(set_ipaddr, "set_ipaddr")
server.register_function(get_ipaddr, "get_ipaddr")
server.register_function(set_portnum, "set_portnum")
server.register_function(get_portnum, "get_portnum")

server.register_instance(UR_RTDE(urHost, urPort, config_filename), allow_dotted_names=True)
server.register_instance(SensorEvaluationBoard(sensEvalBoard_ipAddr, sensEvalBoard_port), allow_dotted_names=True)
server.register_function(main, "main")
server.serve_forever()
        
#/usr/bin/env python
导入时间
从时间上导入睡眠
导入系统
导入字符串
导入回溯
导入日志记录
导入套接字
导入结构
导入副本
导入xmlrpclib
#xmlrpclib.Marshaller.dispatch[type(0L)]=lambda,v,w:w(“%d”%v)
#xmlrpclib.dumps((2**63-1,)
二进制文件
从SimpleXMLRPCServer导入SimpleXMLRPCServer,SimpleXMLRPCRequestHandler
导入线程
从线程导入线程,锁定
# "https://www.universal-robots.com/articles/ur-articles/real-time-data-exchange-rtde-guide/"
将rtde.rtde作为rtde导入
将rtde.rtde_配置导入为rtde_配置
#urHost=“127.0.0.1”#您的机器人的IP地址
# "https://www.universal-robots.com/articles/ur-articles/remote-control-via-tcpip/"
urPort=30004#专用于UR机器人二次接口的端口号
config\u filename='control\u loop\u configuration.xml'
mutexFreedriveMode=Lock()
loadCycleOfSensor1、loadCycleOfSensor2、loadCycleOfSensor3=“”、“”、“”
c1,c2,c3=0,0,0
cnt=0
数据=字节数组()
传感器评估板的IP地址
sensEvalBoard_端口=0#传感器评估板的端口号
默认超时=1
mutexsenval=Lock()
sebSocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#初始化套接字对象
mutexSEBSocket=Lock()
def set_ipaddr(新的守护进程主机):
全球感应板
sensEvalBoard\u ipAddr=新的\u守护进程\u主机
返回感应板\u ipAddr
def get_ipaddr():
tmp=“”
如果str(传感器板\u ipAddr):
tmp=传感器板\u ipAddr
其他:
tmp=“未设置ip地址”
返回tmp
def set_portnum(新的_守护进程_端口):
全球传感板端口
sensEvalBoard_端口=int(新的_守护进程_端口)
返回感应板\u端口
def get_portnum():
tmp=0
如果传感器板_端口!=0:
tmp=传感器板\u端口
其他:
tmp=0
返回tmp
类连接状态:
断开连接=0
已连接=1
开始=2
暂停=3
类SensorEvaluationBoardException(异常):
定义初始化(self,msg):
self.msg=msg
定义(自我):
返回报告(self.msg)
类传感器评估板(线程):
def uuu init uuuu(自身、主机名、端口):
#调用线程类的init函数
线程。\uuuu初始化\uuuuu(自)
self.\uuuhostname=主机名
self.\uuu端口=端口
self.\uuuu conn\u state=ConnectionState.DISCONNECTED
self.\uu sock=无
logging.basicConfig(级别=logging.DEBUG)
self.\uuuuu logger=logging.getLogger(self.\uuuuuuuuuu类\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu名称)
#self.\uuu streamHandler=logging.streamHandler()
#self.\uu streamHandler.setLevel(logging.DEBUG)
#self.\uu formatter=logging.formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
#self.\u streamHandler.setFormatter(self.\u格式化程序)
#self.\u logger.addHandler(self.\u streamHandler)
def连接(自):
全球SEB插座
如果是自吸式:
返回
自
尝试:
self.\u sock=socket.socket(socket.AF\u INET,socket.sock\u流)
self.\u sock.setsockopt(socket.SOL\u socket,socket.SO\u REUSEADDR,1)
self._sock.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,1)
self.\u sock.settimeout(默认超时)
self.\u sock.connect((self.\u主机名,self.\u端口))
self.\uuuu conn\u state=ConnectionState.CONNECTED
sebSocket=copy.deepcopy(self.\uu sock)
除了(socket.timeout、socket.error):
self.\uu sock=无
提升
def断开(自):
如果是自吸式:
self.\uu sock.close()
self.\uu sock=无
self.\uuuu conn\u state=ConnectionState.DISCONNECTED
def已连接(自):
返回自我。连接状态不是ConnectionState.DISCONNECTED
def获取连接状态(自身):
返回自我连接状态
def发送输入数据(自身、数据):
自存储发送(数据)
def接收\输出\数据(自身、输入\数据):
发送输入数据(输入数据)
self.\uu rcvData=self.\uu sock.recv(1024)
返回自我。\uu rcvData
def运行(自):
全局loadCycleOfSensor1、loadCycleOfSensor2、loadCycleOfSensor3
self.connect()
尽管如此:
如果self.u已连接:
#打印(“套接字=>连接状态:“+str(self.get\u connection\u state())+”表示已连接)
self.\uuuu input\u data=bytearray()
self.\u输入\u数据.append(0x1)
self.\uuu rcvData=self.接收输出数据(self.\uu输入数据)
self.\uu解包程序\u string=3*'I B'
self.\uu unpacker=struct.struct('Freedrive模式已激活
如果((长周期c1