Skip to content

Commit

Permalink
feat: command interpreter as a service
Browse files Browse the repository at this point in the history
  • Loading branch information
Oscar-gg committed Jan 23, 2025
1 parent e3fb6af commit 89b416d
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 21 deletions.
4 changes: 2 additions & 2 deletions frida_interfaces/hri/srv/CommandInterpreter.srv
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
string text_heard
string text
---
frida_interfaces/CommandList commands
frida_interfaces/Command[] commands
26 changes: 23 additions & 3 deletions hri/packages/nlp/scripts/command_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from std_msgs.msg import String

from frida_interfaces.msg import Command, CommandList
from frida_interfaces.srv import CommandInterpreter as CommandInterpreterSrv


class CommandShape(BaseModel):
Expand All @@ -41,6 +42,10 @@ def __init__(self):
self.declare_parameter("model", "gpt-4o-2024-08-06")
self.declare_parameter("speech_command_topic", "/speech/raw_command")
self.declare_parameter("publish_command_topic", "/task_manager/commands")
self.declare_parameter(
"COMMAND_INTERPRETER_SERVICE", "/nlp/command_interpreter"
)

self.declare_parameter("temperature", 0.5)

base_url = self.get_parameter("base_url").get_parameter_value().string_value
Expand All @@ -55,6 +60,11 @@ def __init__(self):
.get_parameter_value()
.string_value
)
command_interpreter_service = (
self.get_parameter("COMMAND_INTERPRETER_SERVICE")
.get_parameter_value()
.string_value
)

self.temperature = (
self.get_parameter("temperature").get_parameter_value().double_value
Expand All @@ -73,6 +83,9 @@ def __init__(self):
String, speech_command_topic, self._callback, 10
)
self.publisher = self.create_publisher(CommandList, publish_command_topic, 10)
self.create_service(
CommandInterpreterSrv, command_interpreter_service, self.command_service
)

self.get_logger().info("Initialized Command Interpreter")

Expand All @@ -83,6 +96,15 @@ def _callback(self, data: String) -> None:

def run(self, raw_command: str) -> None:
"""Method for running the interpretation of the commands"""
commands = self.get_commands(raw_command)
self.publisher.publish(commands)

def command_service(self, req, res):
commands = self.get_commands(req.text)
res.commands = commands.commands
return res

def get_commands(self, raw_command: str):
response = (
self.client.beta.chat.completions.parse(
model=self.model,
Expand All @@ -96,7 +118,6 @@ def run(self, raw_command: str) -> None:
.choices[0]
.message.content
)

try:
response_data = json.loads(response)
result = CommandListShape(**response_data)
Expand All @@ -105,7 +126,6 @@ def run(self, raw_command: str) -> None:
return

self.get_logger().debug(f"Commands interpreted: {result.commands}")

command_list = CommandList()
command_list.commands = [
Command(
Expand All @@ -115,7 +135,7 @@ def run(self, raw_command: str) -> None:
)
for command in result.commands
]
self.publisher.publish(command_list)
return command_list


def main(args=None):
Expand Down
3 changes: 3 additions & 0 deletions hri/packages/speech/assets/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

# Folder to include all the downloaded and asset files
download/
25 changes: 16 additions & 9 deletions task_manager/scripts/subtask_managers/hri_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ class HRITasks(metaclass=SubtaskMeta):
def __init__(self, task_manager, config=None) -> None:
self.node = task_manager

self.speak_service = self.node.create_client(Speak, SPEAK_SERVICE)
self.hear_service = self.node.create_client(STT, HEAR_SERVICE)
self.extract_data_service = self.node.create_client(
self.speak_client = self.node.create_client(Speak, SPEAK_SERVICE)
self.hear_client = self.node.create_client(STT, HEAR_SERVICE)
self.extract_data_client = self.node.create_client(
ExtractInfo, EXTRACT_DATA_SERVICE
)

self.command_interpreter_service = self.node.create_client(
self.command_interpreter_client = self.node.create_client(
CommandInterpreter, COMMAND_INTERPRETER_SERVICE
)
self.grammar_service = self.node.create_client(Grammar, GRAMMAR_SERVICE)
Expand All @@ -47,7 +47,7 @@ def say(self, text: str, wait: bool = False) -> None:
self.node.get_logger().info(f"Sending to saying service: {text}")
request = Speak.Request(text=text)

future = self.speak_service.call_async(request)
future = self.speak_client.call_async(request)

if wait:
rclpy.spin_until_future_complete(self.node, future)
Expand All @@ -60,13 +60,15 @@ def say(self, text: str, wait: bool = False) -> None:

def extract_data(self, query, complete_text) -> str:
request = ExtractInfo.Request(data=query, full_text=complete_text)
future = self.extract_data_service.call_async(request)
future = self.extract_data_client.call_async(request)
rclpy.spin_until_future_complete(self.node, future)
return future.result().result

# TODO
def hear(self, timeout: float = 15.0) -> str:
pass

# TODO
def interpret_keyword(self, keyword: str, timeout: float) -> str:
pass

Expand All @@ -76,15 +78,20 @@ def refactor_text(self, text: str) -> str:
rclpy.spin_until_future_complete(self.node, future)
return future.result().corrected_text

# TODO
def find_closest(self, query: str, options: Union[list[str], str]) -> str:
pass

# TODO
def ask(self, question: str) -> str:
"""Method to publish directly text to the speech node"""
pass

def command_interpreter(self, text: str) -> str:
pass
def command_interpreter(self, text: str) -> CommandInterpreter.Response:
request = CommandInterpreter.Request(text=text)
future = self.command_interpreter_client.call_async(request)
rclpy.spin_until_future_complete(self.node, future)

return future.result().commands


if __name__ == "__main__":
Expand Down
19 changes: 12 additions & 7 deletions task_manager/scripts/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,23 @@ def run(self):
"""testing vision tasks"""

user_request = self.subtask_manager["hri"].hear()
say_res = self.subtask_manager["hri"].say("Hi, my name is frida", wait=True)

print("user_request:", user_request)
print("say_res:", say_res)
self.subtask_manager["hri"].say("Hi, my name is frida", wait=True)

drink = self.subtask_manager["hri"].extract_data("Drink", user_request)

self.get_logger().info(f"Extracted data: {drink}")

fixed_text = self.subtask_manager["hri"].refactor_text(
"I will do: (action: go), (complement: kitchen)"
)
commands = self.subtask_manager["hri"].command_interpreter(user_request)

self.get_logger().info(f"Interpreted commands: {commands}")

command_strs = [
f"I will do action:{command.action}, ({command.complement}), ({command.characteristic})"
for command in commands
]
command_str = " and ".join(command_strs)

fixed_text = self.subtask_manager["hri"].refactor_text(command_str)
self.subtask_manager["hri"].say(fixed_text)


Expand Down

0 comments on commit 89b416d

Please sign in to comment.