refactor: added config file and moved constants
- Moved hardcoded configuration constants to a dedicated config.py file. - Created VideoConfig, AudioConfig, MainConfig, and Settings classes in config.py ref: N25B-236
This commit is contained in:
0
src/robot_interface/core/__init__.py
Normal file
0
src/robot_interface/core/__init__.py
Normal file
46
src/robot_interface/core/config.py
Normal file
46
src/robot_interface/core/config.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
class AgentSettings(object):
|
||||||
|
"""Agent port configuration."""
|
||||||
|
def __init__(self, actuating_receiver_port=5557, main_receiver_port=5555,video_sender_port=5556, audio_sender_port=5558):
|
||||||
|
self.actuating_receiver_port = actuating_receiver_port
|
||||||
|
self.main_receiver_port = main_receiver_port
|
||||||
|
self.video_sender_port = video_sender_port
|
||||||
|
self.audio_sender_port = audio_sender_port
|
||||||
|
|
||||||
|
class VideoConfig(object):
|
||||||
|
"""Video configuration constants."""
|
||||||
|
def __init__(self, camera_index=0, resolution=2, color_space=11, fps=15, stream_name="Pepper Video", image_buffer=6):
|
||||||
|
self.camera_index = camera_index
|
||||||
|
self.resolution = resolution
|
||||||
|
self.color_space = color_space
|
||||||
|
self.fps = fps
|
||||||
|
self.stream_name = stream_name
|
||||||
|
self.image_buffer = image_buffer
|
||||||
|
|
||||||
|
class AudioConfig(object):
|
||||||
|
"""Audio configuration constants."""
|
||||||
|
def __init__(self, sample_rate=16000, chunk_size=512, channels=1):
|
||||||
|
self.sample_rate = sample_rate
|
||||||
|
self.chunk_size = chunk_size
|
||||||
|
self.channels = channels
|
||||||
|
|
||||||
|
class MainConfig(object):
|
||||||
|
"""Main configuration"""
|
||||||
|
def __init__(self, poll_timeout_ms=100, max_handler_time_ms=50):
|
||||||
|
self.poll_timeout_ms = poll_timeout_ms
|
||||||
|
self.max_handler_time_ms = max_handler_time_ms
|
||||||
|
|
||||||
|
class Settings(object):
|
||||||
|
"""Global settings container."""
|
||||||
|
def __init__(self, agent_settings=None, video_config=None, audio_config=None, main_config=None):
|
||||||
|
self.agent_settings = agent_settings or AgentSettings()
|
||||||
|
self.video_config = video_config or VideoConfig()
|
||||||
|
self.audio_config = audio_config or AudioConfig()
|
||||||
|
self.main_config = main_config or MainConfig()
|
||||||
|
|
||||||
|
|
||||||
|
settings = Settings()
|
||||||
@@ -6,9 +6,11 @@ import zmq
|
|||||||
from robot_interface.endpoints.receiver_base import ReceiverBase
|
from robot_interface.endpoints.receiver_base import ReceiverBase
|
||||||
from robot_interface.state import state
|
from robot_interface.state import state
|
||||||
|
|
||||||
|
from robot_interface.core.config import settings
|
||||||
|
|
||||||
|
|
||||||
class ActuationReceiver(ReceiverBase):
|
class ActuationReceiver(ReceiverBase):
|
||||||
def __init__(self, zmq_context, port=5557):
|
def __init__(self, zmq_context, port= settings.agent_settings.actuating_receiver_port):
|
||||||
"""
|
"""
|
||||||
The actuation receiver endpoint, responsible for handling speech and gesture requests.
|
The actuation receiver endpoint, responsible for handling speech and gesture requests.
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ import zmq
|
|||||||
from robot_interface.endpoints.socket_base import SocketBase
|
from robot_interface.endpoints.socket_base import SocketBase
|
||||||
from robot_interface.state import state
|
from robot_interface.state import state
|
||||||
from robot_interface.utils.microphone import choose_mic
|
from robot_interface.utils.microphone import choose_mic
|
||||||
|
from robot_interface.core.config import settings
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AudioSender(SocketBase):
|
class AudioSender(SocketBase):
|
||||||
def __init__(self, zmq_context, port=5558):
|
def __init__(self, zmq_context, port= settings.agent_settings.audio_sender_port):
|
||||||
super(AudioSender, self).__init__(str("audio")) # Convert future's unicode_literal to str
|
super(AudioSender, self).__init__(str("audio")) # Convert future's unicode_literal to str
|
||||||
self.create_socket(zmq_context, zmq.PUB, port)
|
self.create_socket(zmq_context, zmq.PUB, port)
|
||||||
self.thread = None
|
self.thread = None
|
||||||
@@ -49,13 +49,14 @@ class AudioSender(SocketBase):
|
|||||||
self.thread = None
|
self.thread = None
|
||||||
|
|
||||||
def _stream(self):
|
def _stream(self):
|
||||||
chunk = 512 # 320 at 16000 Hz is 20ms, 512 is required for Silero-VAD
|
audio_settings = settings.audio_config
|
||||||
|
chunk = audio_settings.chunk_size # 320 at 16000 Hz is 20ms, 512 is required for Silero-VAD
|
||||||
|
|
||||||
# Docs say this only raises an error if neither `input` nor `output` is True
|
# Docs say this only raises an error if neither `input` nor `output` is True
|
||||||
stream = self.audio.open(
|
stream = self.audio.open(
|
||||||
format=pyaudio.paFloat32,
|
format=pyaudio.paFloat32,
|
||||||
channels=1,
|
channels=audio_settings.channels,
|
||||||
rate=16000,
|
rate=audio_settings.sample_rate,
|
||||||
input=True,
|
input=True,
|
||||||
input_device_index=self.microphone["index"],
|
input_device_index=self.microphone["index"],
|
||||||
frames_per_buffer=chunk,
|
frames_per_buffer=chunk,
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ import zmq
|
|||||||
from robot_interface.endpoints.receiver_base import ReceiverBase
|
from robot_interface.endpoints.receiver_base import ReceiverBase
|
||||||
from robot_interface.state import state
|
from robot_interface.state import state
|
||||||
|
|
||||||
|
from robot_interface.core.config import settings
|
||||||
|
|
||||||
class MainReceiver(ReceiverBase):
|
class MainReceiver(ReceiverBase):
|
||||||
def __init__(self, zmq_context, port=5555):
|
def __init__(self, zmq_context, port= settings.agent_settings.main_receiver_port):
|
||||||
"""
|
"""
|
||||||
The main receiver endpoint, responsible for handling ping and negotiation requests.
|
The main receiver endpoint, responsible for handling ping and negotiation requests.
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import logging
|
|||||||
|
|
||||||
from robot_interface.endpoints.socket_base import SocketBase
|
from robot_interface.endpoints.socket_base import SocketBase
|
||||||
from robot_interface.state import state
|
from robot_interface.state import state
|
||||||
|
from robot_interface.core.config import settings
|
||||||
|
|
||||||
class VideoSender(SocketBase):
|
class VideoSender(SocketBase):
|
||||||
def __init__(self, zmq_context, port=5556):
|
def __init__(self, zmq_context, port=settings.agent_settings.video_sender_port):
|
||||||
super(VideoSender, self).__init__("video")
|
super(VideoSender, self).__init__("video")
|
||||||
self.create_socket(zmq_context, zmq.PUB, port, [(zmq.CONFLATE,1)])
|
self.create_socket(zmq_context, zmq.PUB, port, [(zmq.CONFLATE,1)])
|
||||||
|
|
||||||
@@ -20,12 +20,13 @@ class VideoSender(SocketBase):
|
|||||||
return
|
return
|
||||||
|
|
||||||
video = state.qi_session.service("ALVideoDevice")
|
video = state.qi_session.service("ALVideoDevice")
|
||||||
|
video_settings = settings.video_config
|
||||||
camera_index = 0
|
camera_index = video_settings.camera_index
|
||||||
kQVGA = 2
|
kQVGA = video_settings.resolution
|
||||||
kRGB = 11
|
kRGB = video_settings.color_space
|
||||||
FPS = 15
|
FPS = video_settings.fps
|
||||||
vid_stream_name = video.subscribeCamera("Pepper Video", camera_index, kQVGA, kRGB, FPS)
|
video_name = video_settings.stream_name
|
||||||
|
vid_stream_name = video.subscribeCamera(video_name, camera_index, kQVGA, kRGB, FPS)
|
||||||
thread = threading.Thread(target=self.video_rcv_loop, args=(video, vid_stream_name))
|
thread = threading.Thread(target=self.video_rcv_loop, args=(video, vid_stream_name))
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
@@ -43,6 +44,6 @@ class VideoSender(SocketBase):
|
|||||||
try:
|
try:
|
||||||
img = vid_service.getImageRemote(vid_stream_name)
|
img = vid_service.getImageRemote(vid_stream_name)
|
||||||
#Possibly limit images sent if queuing issues arise
|
#Possibly limit images sent if queuing issues arise
|
||||||
self.socket.send(img[6])
|
self.socket.send(img[settings.video_config.image_buffer])
|
||||||
except:
|
except:
|
||||||
logging.warn("Failed to retrieve video image from robot.")
|
logging.warn("Failed to retrieve video image from robot.")
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from robot_interface.endpoints.actuation_receiver import ActuationReceiver
|
|||||||
from robot_interface.endpoints.main_receiver import MainReceiver
|
from robot_interface.endpoints.main_receiver import MainReceiver
|
||||||
from robot_interface.endpoints.video_sender import VideoSender
|
from robot_interface.endpoints.video_sender import VideoSender
|
||||||
from robot_interface.state import state
|
from robot_interface.state import state
|
||||||
|
from robot_interface.core.config import settings
|
||||||
from robot_interface.utils.timeblock import TimeBlock
|
from robot_interface.utils.timeblock import TimeBlock
|
||||||
|
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ def main_loop(context):
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
if state.exit_event.is_set(): break
|
if state.exit_event.is_set(): break
|
||||||
socks = dict(poller.poll(100))
|
socks = dict(poller.poll(settings.main_config.poll_timeout_ms))
|
||||||
|
|
||||||
for receiver in receivers:
|
for receiver in receivers:
|
||||||
if receiver.socket not in socks: continue
|
if receiver.socket not in socks: continue
|
||||||
@@ -59,7 +60,7 @@ def main_loop(context):
|
|||||||
logging.warn("Endpoint \"%s\" took too long (%.2f ms) on the main thread.",
|
logging.warn("Endpoint \"%s\" took too long (%.2f ms) on the main thread.",
|
||||||
message["endpoint"], time_ms)
|
message["endpoint"], time_ms)
|
||||||
|
|
||||||
with TimeBlock(overtime_callback, 50):
|
with TimeBlock(overtime_callback, settings.main_config.max_handler_time_ms):
|
||||||
response = receiver.handle_message(message)
|
response = receiver.handle_message(message)
|
||||||
|
|
||||||
if receiver.socket.getsockopt(zmq.TYPE) == zmq.REP:
|
if receiver.socket.getsockopt(zmq.TYPE) == zmq.REP:
|
||||||
|
|||||||
@@ -82,11 +82,12 @@ def choose_mic_arguments(audio):
|
|||||||
:rtype: dict | None
|
:rtype: dict | None
|
||||||
"""
|
"""
|
||||||
microphone_name = None
|
microphone_name = None
|
||||||
|
microhopone_prefix = "--microphone="
|
||||||
for i, arg in enumerate(sys.argv):
|
for i, arg in enumerate(sys.argv):
|
||||||
if arg == "--microphone" and len(sys.argv) > i+1:
|
if arg == microhopone_prefix and len(sys.argv) > i+1:
|
||||||
microphone_name = sys.argv[i+1].strip()
|
microphone_name = sys.argv[i+1].strip()
|
||||||
if arg.startswith("--microphone="):
|
if arg.startswith(microhopone_prefix):
|
||||||
microphone_name = arg[13:].strip()
|
microphone_name = arg[len(microhopone_prefix):].strip()
|
||||||
|
|
||||||
if not microphone_name: return None
|
if not microphone_name: return None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user