refactor: removed hardcoded IP and port and moved video functions from main to the VideoSender class
ref: N25B-171
This commit is contained in:
@@ -15,7 +15,7 @@ class SocketBase(object):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.socket = None
|
self.socket = None
|
||||||
|
|
||||||
def create_socket(self, zmq_context, socket_type, port):
|
def create_socket(self, zmq_context, socket_type, port, options=[]):
|
||||||
"""
|
"""
|
||||||
Create a ZeroMQ socket.
|
Create a ZeroMQ socket.
|
||||||
|
|
||||||
@@ -27,8 +27,16 @@ class SocketBase(object):
|
|||||||
|
|
||||||
:param port: The port to use.
|
:param port: The port to use.
|
||||||
:type port: int
|
:type port: int
|
||||||
|
|
||||||
|
:param options: A list of options to be set on the socket. The list contains tuples where the first element contains the option
|
||||||
|
and the second the value, for example (zmq.CONFLATE, 1).
|
||||||
|
:type options: [(zmq socket option, option value)]
|
||||||
"""
|
"""
|
||||||
self.socket = zmq_context.socket(socket_type)
|
self.socket = zmq_context.socket(socket_type)
|
||||||
|
|
||||||
|
for option, arg in options:
|
||||||
|
self.socket.setsockopt(option,arg)
|
||||||
|
|
||||||
self.socket.connect("tcp://localhost:{}".format(port))
|
self.socket.connect("tcp://localhost:{}".format(port))
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
|||||||
@@ -1,8 +1,61 @@
|
|||||||
import zmq
|
import zmq
|
||||||
|
import threading
|
||||||
|
import qi
|
||||||
|
import logging
|
||||||
|
|
||||||
from robot_interface.endpoints.socket_base import SocketBase
|
from robot_interface.endpoints.socket_base import SocketBase
|
||||||
|
from robot_interface.state import state
|
||||||
|
|
||||||
|
|
||||||
class VideoSender(SocketBase):
|
class VideoSender(SocketBase):
|
||||||
def __init__(self, zmq_context, port=5556):
|
def __init__(self, zmq_context, port=5556):
|
||||||
super(VideoSender, self).__init__("video")
|
super(VideoSender, self).__init__("video")
|
||||||
self.create_socket(zmq_context, zmq.PUB, port)
|
self.create_socket(zmq_context, zmq.PUB, port, [(zmq.CONFLATE,1)])
|
||||||
|
|
||||||
|
def start_video_rcv(self):
|
||||||
|
"""
|
||||||
|
Prepares arguments for retrieving video images from Pepper and starts video loop on a separate thread.
|
||||||
|
|
||||||
|
:param robot_ip: The ip address of the robot to connect with.
|
||||||
|
:type robot_ip: String
|
||||||
|
|
||||||
|
:param port: The port of the robot.
|
||||||
|
:type port: int
|
||||||
|
|
||||||
|
:param socket: The ZMQ socket to send the video images over.
|
||||||
|
:type: VideoSender
|
||||||
|
"""
|
||||||
|
app = qi.Application()
|
||||||
|
app.start()
|
||||||
|
session = app.session
|
||||||
|
|
||||||
|
video = session.service("ALVideoDevice")
|
||||||
|
|
||||||
|
camera_index = 0
|
||||||
|
kQVGA = 2
|
||||||
|
kRGB = 11
|
||||||
|
FPS = 15
|
||||||
|
vid_stream_name = video.subscribeCamera("Pepper Video", camera_index, kQVGA, kRGB, FPS)
|
||||||
|
thread = threading.Thread(target=self.video_rcv_loop, args=(video, vid_stream_name))
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
def video_rcv_loop(self, vid_service, vid_stream_name):
|
||||||
|
"""
|
||||||
|
The main loop of retrieving video images from the robot.
|
||||||
|
|
||||||
|
:param vid_stream: The name of a camera subscription on the video service object vid_service
|
||||||
|
:type vid_stream: String
|
||||||
|
|
||||||
|
:param vid_service: The video service object that the active Qi session is connected to.
|
||||||
|
:type vid_service: Object (Qi service object)
|
||||||
|
|
||||||
|
:param socket: The ZMQ socket to send the video images over.
|
||||||
|
:type: VideoSender
|
||||||
|
"""
|
||||||
|
while not state.exit_event.is_set():
|
||||||
|
try:
|
||||||
|
img = vid_service.getImageRemote(vid_stream_name)
|
||||||
|
#Possibly limit images sent if queuing issues arise
|
||||||
|
self.socket.send(img[6])
|
||||||
|
except:
|
||||||
|
logging.warn("Failed to retrieve video image from robot.")
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
import qi
|
|
||||||
import threading
|
|
||||||
|
|
||||||
import zmq
|
import zmq
|
||||||
|
|
||||||
@@ -24,11 +22,7 @@ def main_loop(context):
|
|||||||
video_sender = VideoSender(context)
|
video_sender = VideoSender(context)
|
||||||
state.sockets.append(video_sender)
|
state.sockets.append(video_sender)
|
||||||
|
|
||||||
# ip address of robot
|
video_sender.start_video_rcv()
|
||||||
robot_ip = "10.211.55.3"
|
|
||||||
# port of robot
|
|
||||||
port = 54321
|
|
||||||
start_video_rcv(robot_ip, port, video_sender)
|
|
||||||
|
|
||||||
# Sockets that can run on the main thread. These sockets' endpoints should not block for long (say 50 ms at most).
|
# Sockets that can run on the main thread. These sockets' endpoints should not block for long (say 50 ms at most).
|
||||||
receivers = [main_receiver]
|
receivers = [main_receiver]
|
||||||
@@ -54,55 +48,6 @@ def main_loop(context):
|
|||||||
if time_spent_ms > 50:
|
if time_spent_ms > 50:
|
||||||
logging.warn("Endpoint \"%s\" took too long (%.2f ms) on the main thread.", receiver.name, time_spent_ms)
|
logging.warn("Endpoint \"%s\" took too long (%.2f ms) on the main thread.", receiver.name, time_spent_ms)
|
||||||
|
|
||||||
def start_video_rcv(robot_ip, port, socket):
|
|
||||||
"""
|
|
||||||
Prepares arguments for retrieving video images from Pepper and starts video loop on a separate thread.
|
|
||||||
|
|
||||||
:param robot_ip: The ip address of the robot to connect with.
|
|
||||||
:type robot_ip: String
|
|
||||||
|
|
||||||
:param port: The port of the robot.
|
|
||||||
:type port: int
|
|
||||||
|
|
||||||
:param socket: The ZMQ socket to send the video images over.
|
|
||||||
:type: VideoSender
|
|
||||||
"""
|
|
||||||
socket.socket.setsockopt(zmq.CONFLATE,1)
|
|
||||||
|
|
||||||
app = qi.Application(["cam", "--qi-url", "tcp://{}:{}".format(robot_ip, port)])
|
|
||||||
app.start()
|
|
||||||
session = app.session
|
|
||||||
|
|
||||||
video = session.service("ALVideoDevice")
|
|
||||||
|
|
||||||
camera_index = 0
|
|
||||||
kQVGA = 2
|
|
||||||
kRGB = 11
|
|
||||||
FPS = 15
|
|
||||||
vid_stream_name = video.subscribeCamera("Pepper Video", camera_index, kQVGA, kRGB, FPS)
|
|
||||||
thread = threading.Thread(target=video_rcv_loop, args=(video, vid_stream_name, socket))
|
|
||||||
thread.start()
|
|
||||||
|
|
||||||
def video_rcv_loop(vid_service, vid_stream_name, socket):
|
|
||||||
"""
|
|
||||||
The main loop of retrieving video images from the robot.
|
|
||||||
|
|
||||||
:param vid_stream: The name of a camera subscription on the video service object vid_service
|
|
||||||
:type vid_stream: String
|
|
||||||
|
|
||||||
:param vid_service: The video service object that the active Qi session is connected to.
|
|
||||||
:type vid_service: Object (Qi service object)
|
|
||||||
|
|
||||||
:param socket: The ZMQ socket to send the video images over.
|
|
||||||
:type: VideoSender
|
|
||||||
"""
|
|
||||||
while not state.exit_event.is_set():
|
|
||||||
try:
|
|
||||||
img = vid_service.getImageRemote(vid_stream_name)
|
|
||||||
#Possibly limit images sent if queuing issues arise
|
|
||||||
socket.socket.send(img[6])
|
|
||||||
except:
|
|
||||||
logging.warn("Failed to retrieve video image from robot.")
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
context = zmq.Context()
|
context = zmq.Context()
|
||||||
|
|||||||
Reference in New Issue
Block a user