I want to communicate using subprocess in ros melodic package.
Because ros uses python2 as default, I had some python version problems with python3 libraries. That's why I decided to use a subprocess.
Here are two of my codes: first is a node of ros(as a client), second is a python3 file as a server.
- Client(image_bus.py)
#!/usr/bin/env python
import rospy
import cv2
import numpy as np
import os
import subprocess
from cv_bridge import CvBridge, CvBridgeError
from std_msgs.msg import String
from sensor_msgs.msg import Image
from json_socket import Client
HOST_IP = "127.0.0.1"
HOST_PORT = 9989
class ImageBus:
    def __init__(self):
        self.sub_video_capture = rospy.Subscriber('/video_capture', Image, self.send_to_face_detector)
        self.cvb = CvBridge()
        self.rate = rospy.Rate(2)
        self.client = Client()
    def send_to_face_detector(self, image):
        try:
            cv_image = self.cvb.imgmsg_to_cv2(image, "bgr8")
        except CvBridgeError as e:
            print(e)
        filename = os.path.dirname(os.path.abspath(__file__)) + "/face_detector.py"
        p = subprocess.Popen(["python3", filename])
        print("p : ", p)
        self.rate.sleep()
        # client = Client()
        c = self.client.connect(HOST_IP, HOST_PORT)
        send_data = {}
        send_data['video_cap'] = cv_image
        self.client.send(send_data)
        recv_data = self.client.recv()
        self.rate.sleep()
        self.client.close()
if __name__ == '__main__':
    rospy.init_node('ImageBus', anonymous=False)
    ib = ImageBus()
    try:
        rospy.spin()
    except rospy.ROSInterruptException:
        pass
- Server(face_detector.py)
 
import cv2
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import math
from sklearn.decomposition import PCA
import os
import glob
from jsonsocket import Server
BIND_IP = "127.0.0.1"
BIND_PORT = 9989
class FaceDetector:
    def __init__(self):
        self.socket = Server(BIND_IP, BIND_PORT)
    # Some Codes Here
    def check_face(self, frame):
        # Some codes Here
                return boxed_frame
if __name__=="__main__":
    fd = FaceDetector()
    fd.socket.accept()
    while True:
        print("SERVER")
        recv_image = fd.socket.recv()
        if not recv_image:
            break
        video_cap = recv_data['video_cap']
        face_detected_image = fd.check_face(video_cap)
        send_image = {}
        send_image['face_detected_image'] = face_detected_image
        fd.socket.send(send_image)
    fd.socket.close()
And below code is my jsonsocket.py.
import socket
import json
def _send(socket, send_data):
    json_data = json.JSONEncoder().encode(send_data)
    socket.sendall(json_data.encode()) 
def _recv(socket):
    recv_data = socket.recv(4096)
    json_data = json.loads(recv_data.decode())
    return json_data
class Server(object):
    backlog =1
    client =None
    def __init__(self, host, port):
        self.socket = socket.socket()
        self.socket.bind((host, port))
        self.socket.listen(self.backlog)
    def __del__(self):
        self.close()
    def accept(self):
        if self.client:
            self.client.close()
        self.client, self.client_addr =self.socket.accept()
        return self
    def send(self, data):
        if not self.client:
            raise Exception('Cantnot send data, no client is connected.')
        _send(self.client, data)
        return self
    def recv(self):
        if not self.client:
            raise Exception('Cannot receive data, no client is connected.')
        return _recv(self.client)
    def close(self):
        if self.client:
            self.client.close()
            self.client =None
        if self.socket:
            self.socket.close()
            self.socket =None
class Client(object):
    socket =None
    def __del__(self):
        self.close()
    def connect(self, host, port):
        self.socket = socket.socket()
        self.socket.connect((host, port))
        return self
    def send(self, data):
        if not self.socket:
            raise Exception('You have to connect first before sending data.')           
        _send(self.socket, data)
        return self
    def recv(self):
        if not self.socket:
            raise Exception('You have to connect first before receving data.')
        return _recv(self.socket)
    def close(self):
        if self.socket:
            self.socket.close()
            self.socket =None
When I roslaunch this package with my launch file, then It outputs:
File "/catkin_ws/src/jetson/src/image_bus.py", line 37, in send_to_face_detector
    c = self.client.connect(HOST_IP, HOST_PORT)
  File "/catkin_ws/src/jetson/src/json_socket.py", line 67, in connect
    self.socket.connect((host, port))
  File "/usr/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 111] Connection refused
How can I solve this problem?
I tried to change the port number, change the variable name, check where the problem occurs exactly. However, I couldn't find out.
Help me, please. Thank you.