Skip to content

Commit

Permalink
Merge pull request #5 from interaction-lab/develop
Browse files Browse the repository at this point in the history
Merge from original repo
  • Loading branch information
micolspitale93 authored Apr 21, 2021
2 parents 70b7073 + 1802012 commit 37896a9
Show file tree
Hide file tree
Showing 198 changed files with 4,991 additions and 2,280 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ ENV/
#**/*.yaml
#**/*.wav
**/*.ogg
**/doc/html/**
**/private-keys.json
**/private-keys_en.json

Expand Down
17 changes: 9 additions & 8 deletions TEST-docker-compose-harmoni-swarm.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#This is an example of a swarm based compose file that can launch from a single PC. It works, but cannot do static IPs.
#It may requre setting up your own network and then treating it as an external network.
#To deploy: docker stack deploy -c TEST-docker-compose-harmoni-swarm.yml <stack_name>
# This is an example of a swarm based compose file that can launch from a single PC.
# It works, but cannot do static IPs.
# It may requre setting up your own network and then treating it as an external network.
# To deploy: docker stack deploy -c TEST-docker-compose-harmoni-swarm.yml <stack_name>
version: "3.8"
services:
harmoni_core:
Expand Down Expand Up @@ -55,7 +56,7 @@ services:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
working_dir: /root/harmoni_catkin_ws/src/HARMONI
entrypoint: /bin/bash --rcfile /root/setup_script.sh
entrypoint: /bin/bash --rcfile /root/setup_script.sh
stdin_open: true #get a interactive terminal when attaching.
tty: true
# command: roscore
Expand Down Expand Up @@ -89,7 +90,7 @@ services:
ipv4_address: 172.18.3.5
hostname: ros_hardware
# depends_on:
# - "harmoni_core"
# - "harmoni_core"
devices:
- /dev/dri:/dev/dri
- /dev/snd:/dev/snd
Expand All @@ -111,12 +112,12 @@ services:
- /etc/localtime:/etc/localtime:ro
working_dir: /root/harmoni_catkin_ws/src/HARMONI
#TODO: remove dumb-init and next line
entrypoint: /bin/bash --rcfile /root/setup_script.sh
entrypoint: /bin/bash --rcfile /root/setup_script.sh
stdin_open: true #get a interactive terminal when attaching.
tty: true
#command: bash -c "
# terminator -ue \"cd ../HARMONI && echo 'Entering harmoni_hardware Container... \\n start with rlhardwareservices' && bash\""
# terminator -ue \"cd ../HARMONI && echo 'Entering harmoni_hardware Container... \\n start with rlhardwareservices' && bash\""

networks:
ros_net:
driver: overlay
Expand Down
2 changes: 1 addition & 1 deletion docker-compose-full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ services:
# Configuration
- ~/.aws:/root/.aws/
- ./dockerfiles/config/.asoundrc:/root/.asoundrc
- ~/.gcp/private-keys.json:/root/private-keys.json
- ~/.gcp/private-keys.json:/root/.gcp/private-keys.json
# Other
- /tmp/.X11-unix:/tmp/.X11-unix
- /etc/timezone:/etc/timezone:ro
Expand Down
8 changes: 4 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ services:
- ../HARMONI/:/root/local_mount/HARMONI/
# Configuration
- ~/.aws:/root/.aws/
- ~/.gcp/private-keys.json:/root/private-keys.json
- ~/.gcp/private-keys.json:/root/.gcp/private-keys.json
# Other
- /tmp/.X11-unix:/tmp/.X11-unix
- /etc/timezone:/etc/timezone:ro
Expand Down Expand Up @@ -75,7 +75,7 @@ services:
- ../HARMONI/:/root/local_mount/HARMONI/
# Configuration
- ~/.aws:/root/.aws/
- ~/.gcp/private-keys.json:/root/private-keys.json
- ~/.gcp/private-keys.json:/root/.gcp/private-keys.json
# Other
- /tmp/.X11-unix:/tmp/.X11-unix
- /etc/timezone:/etc/timezone:ro
Expand Down Expand Up @@ -114,7 +114,7 @@ services:
- ../HARMONI/:/root/local_mount/HARMONI/
# Configuration
- ~/.aws:/root/.aws/
- ~/.gcp/private-keys.json:/root/private-keys.json
- ~/.gcp/private-keys.json:/root/.gcp/private-keys.json
# Other
- /tmp/.X11-unix:/tmp/.X11-unix
- /etc/timezone:/etc/timezone:ro
Expand Down Expand Up @@ -153,7 +153,7 @@ services:
- ../HARMONI/:/root/local_mount/HARMONI/
# Configuration
- ~/.aws:/root/.aws/
- ~/.gcp/private-keys.json:/root/private-keys.json
- ~/.gcp/private-keys.json:/root/.gcp/private-keys.json
# Other
- /tmp/.X11-unix:/tmp/.X11-unix
- /etc/timezone:/etc/timezone:ro
Expand Down
1 change: 1 addition & 0 deletions dockerfiles/harmoni/kinetic/base/dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ RUN APT_INSTALL="apt-get install -y --no-install-recommends" && \
packaging==19.1 \
soundfile \
empy \
wget \
PyAudio \
imutils \
--force-reinstall defusedxml \
Expand Down
1 change: 1 addition & 0 deletions dockerfiles/harmoni/noetic/base/dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ RUN \
# catkin_tools \
# AWS
boto3 \
wget \
awscli \
google-cloud-speech==1.3.2 \
dialogflow \
Expand Down
1 change: 1 addition & 0 deletions harmoni_actuators/harmoni_face/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,4 @@ include_directories(

## Add folders to be run by python nosetests
# catkin_add_nosetests(test)
catkin_add_nosetests(test)
27 changes: 9 additions & 18 deletions harmoni_actuators/harmoni_face/launch/face_service.launch
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,13 @@

<arg name="web_directory_path" value="$(find harmoni_face)/web"/>
<arg name="port" default="8081"/>
<arg name="use_face" default="true"/>
<arg name="test" default="false"/>
<arg name="test_input" default="[{'start': 0.075, 'time': 2,'type': 'action', 'id': 'QT/point_front'}, {'start': 0.075,'time': 2, 'type': 'viseme', 'id': 'POSTALVEOLAR'},{'start': 0.006, 'time': 2, 'type': 'action', 'id': 'happy_face'}]"/>
<arg name="test_id" default="default"/>
<group if="$(arg use_face)">
<rosparam file="$(find harmoni_face)/config/configuration.yaml"/>
<param name="test_face" value="$(arg test)"/>
<param name="test_input_face" value="$(arg test_input)"/>
<param name="test_id_face" value="$(arg test_id)"/>
<param name="name_face" value="face"/>
<node pkg="harmoni_face" type="http_server_runner.py" name="face_http_server" output="screen" args="$(arg web_directory_path) $(arg port)" />
<node pkg="harmoni_face" type="face_service.py" name="harmoni_face_$(arg test_id)" output="screen"/>
<include ns="bridge_face" file="$(find rosbridge_server)/launch/rosbridge_websocket.launch">
<arg name="port" value="9000"/>
</include>
</group>
<arg name="instance_id" default="default"/>
<param name="instance_id" value="$(arg instance_id)"/>
<rosparam file="$(find harmoni_face)/config/configuration.yaml"/>
<node pkg="harmoni_face" type="http_server_runner.py" name="face_http_server" output="screen" args="$(arg web_directory_path) $(arg port)" />
<node pkg="harmoni_face" type="face_service.py" name="harmoni_face_$(arg instance_id)" output="screen"/>
<include ns="bridge_face" file="$(find rosbridge_server)/launch/rosbridge_websocket.launch">
<arg name="port" value="9000"/>
</include>


</launch>
</launch>
2 changes: 2 additions & 0 deletions harmoni_actuators/harmoni_face/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
<exec_depend>message_runtime</exec_depend>
<build_export_depend>rospy</build_export_depend>
<exec_depend>rospy</exec_depend>
<test_depend>rosunit</test_depend>
<test_depend>rostest</test_depend>



Expand Down
2 changes: 1 addition & 1 deletion harmoni_actuators/harmoni_face/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# fetch values from package.xml
setup_args = generate_distutils_setup(
packages=["harmoni_face"], package_dir={"": "scripts"},
packages=["harmoni_face"], package_dir={"": "src"},
)

setup(**setup_args)
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

class EyesService(HarmoniServiceManager):
"""
Eyes service
TODO: Eyes service
"""

def __init__(self, name, param):
Expand All @@ -30,7 +30,7 @@ def __init__(self, name, param):
self.gaze_speed = param["gaze_speed"]
self.service_id = hf.get_child_id(self.name)
""" Setup the face """
# self.setup_face()
self.setup_face()
""" Setup the publisher for the face """
self.face_pub = rospy.Publisher(
ActuatorNameSpace.face.value + self.service_id + "/expressing",
Expand Down Expand Up @@ -87,17 +87,19 @@ def do(self, data):
rospy.sleep(valid_face_expression[-1]["au_ms"])
self.state = State.SUCCESS
self.actuation_completed = True
self.result_msg=""
except Exception:
self.state = State.FAILED
self.actuation_completed = True
self.result_msg=""
rospy.loginfo("Completed Expression")
return
return {"response": self.state, "message": self.result_msg}

def setup_face(self):
""" Setup the face """
rospy.loginfo("Setting up the %s eyes" % self.name)
rospy.loginfo("Checking that face is connected to ROS websocket")
rospy.wait_for_service("/harmoni/actuating/face/is_connected")
#rospy.wait_for_service("/harmoni/actuating/face/is_connected")
rospy.loginfo("Done, face is connected to ROS websocket")
[
self.face_expression,
Expand Down Expand Up @@ -155,9 +157,10 @@ def get_face_data(self, data):
# rospy.loginfo("The face expressions available are %s" % self.face_expression)

data = ast.literal_eval(data)
behavior_data = ast.literal_eval(data["behavior_data"])
# print(data)

if "behavior_data" in data:
behavior_data = ast.literal_eval(data["behavior_data"])
else:
behavior_data = data
viseme_set = []
facial_expression = []
sentence = []
Expand All @@ -178,18 +181,7 @@ def get_face_data(self, data):
validated_face_expr = []
for fexp in ordered_facial_data:
validated_face_expr.append(self.face_expression[fexp["id"]])

for i in range(0, len(viseme_set) - 1):
viseme_set[i]["duration"] = (
viseme_set[i + 1]["start"] - viseme_set[i]["start"]
)

viseme_set[-1]["duration"] = self.min_duration_viseme

viseme_behaviors = list(
filter(lambda b: b["duration"] >= self.min_duration_viseme, viseme_set)
)
ordered_visemes = list(sorted(viseme_behaviors, key=lambda b: b["start"]))
viseme_set = []
rospy.loginfo("The validated facial expressions are %s" % validated_face_expr)
rospy.loginfo("The validated visemes are %s" % viseme_set)
print("Finished getting face data for sentence:", sentence)
Expand All @@ -210,9 +202,7 @@ def __init__(self, name, param):
self.speed_viseme = param["speed_viseme"]
self.timer_interval = param["timer_interval"]
self.service_id = hf.get_child_id(self.name)
""" Setup the face """
self.setup_face()
""" Setup the publisher for the face """
self.face_pub = rospy.Publisher(
ActuatorNameSpace.face.value + self.service_id + "/expressing",
FaceRequest,
Expand All @@ -223,8 +213,18 @@ def __init__(self, name, param):
return

def do(self, data):
""" Do the expression"""
"""Do expression in web face
Args:
data ([str]): stringified json from tts results
Returns:
response (int): whether SUCCESS of FAIL
message (str): result message
"""
rospy.loginfo("Do expressions")
self.actuation_completed = False
self.result_msg=""
[valid_face_expression, visemes] = self.get_face_data(data)
try:
self.state = State.REQUEST
Expand Down Expand Up @@ -273,10 +273,11 @@ def do(self, data):
self.state = State.FAILED
self.actuation_completed = True
rospy.loginfo("Completed Expression")
return
return {"response": self.state, "message": self.result_msg}

def setup_face(self):
""" Setup the face """
"""Setup the face, waiting for the connection with the web page
"""
rospy.loginfo("Setting up the %s mouth" % self.name)
rospy.loginfo("Checking that face is connected to ROS websocket")
rospy.wait_for_service("/harmoni/actuating/face/is_connected")
Expand Down Expand Up @@ -337,8 +338,10 @@ def get_face_data(self, data):
# rospy.loginfo("The face expressions available are %s" % self.face_expression)

data = ast.literal_eval(data)
behavior_data = ast.literal_eval(data["behavior_data"])

if "behavior_data" in data:
behavior_data = ast.literal_eval(data["behavior_data"])
else:
behavior_data = data
viseme_set = []
facial_expression = []
sentence = []
Expand Down Expand Up @@ -380,38 +383,24 @@ def get_face_data(self, data):
return (validated_face_expr, viseme_set)



def main():
"""Set names, collect params, and give service to server"""
service_name = ActuatorNameSpace.face.name
name = rospy.get_param("/name_" + service_name + "/")
test = rospy.get_param("/test_" + service_name + "/")
test_input = rospy.get_param("/test_input_" + service_name + "/")
test_id = rospy.get_param("/test_id_" + service_name + "/")
instance_id = rospy.get_param("/instance_id")
service_id_mouth = f"{service_name}_mouth_{instance_id}"
service_id_eyes = f"{service_name}_eyes_{instance_id}"
try:
rospy.init_node(service_name)
param_eyes = rospy.get_param(name + "/" + test_id + "_param/eyes/")
param_mouth = rospy.get_param(name + "/" + test_id + "_param/mouth/")
if not hf.check_if_id_exist(service_name, test_id):
rospy.logerr(
"ERROR: Remember to add your configuration ID also in the harmoni_core config file"
)
return
service = hf.set_service_server(service_name, test_id)
s_eyes = EyesService(service + "_eyes_" + test_id, param_eyes)
s_mouth = MouthService(service + "_mouth_" + test_id, param_mouth)
service_server_eyes = HarmoniServiceServer(
name=service + "_eyes_" + test_id, service_manager=s_eyes
)
service_server_mouth = HarmoniServiceServer(
name=service + "_mouth_" + test_id, service_manager=s_mouth
)
if test:
rospy.loginfo("Testing the %s" % (service + "_mouth"))
rospy.sleep(1)
s_mouth.do(str({"behavior_data": str(test_input)}))
else:
service_server_eyes.update_feedback()
service_server_mouth.update_feedback()
rospy.spin()
param_eyes = rospy.get_param(service_name + "/" + instance_id + "_param/eyes/")
param_mouth = rospy.get_param(service_name + "/" + instance_id + "_param/mouth/")
s_eyes = EyesService(service_name + "_eyes_" + instance_id, param_eyes)
s_mouth = MouthService(service_name + "_mouth_" + instance_id, param_mouth)
service_server_eyes = HarmoniServiceServer(service_id_eyes, s_eyes)
service_server_mouth = HarmoniServiceServer(service_id_mouth, s_mouth)
service_server_eyes.start_sending_feedback()
service_server_mouth.start_sending_feedback()
rospy.spin()
except rospy.ROSInterruptException:
pass

Expand Down
13 changes: 13 additions & 0 deletions harmoni_actuators/harmoni_face/test/face.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<launch>
<param name="instance_id" value="default"/>
<arg name="web_directory_path" value="$(find harmoni_face)/web"/>
<arg name="port" default="8081"/>
<rosparam file="$(find harmoni_face)/config/configuration.yaml"/>
<node pkg="harmoni_face" type="http_server_runner.py" name="face_http_server" output="screen" args="$(arg web_directory_path) $(arg port)" />
<include ns="bridge_face" file="$(find rosbridge_server)/launch/rosbridge_websocket.launch">
<arg name="port" value="9000"/>
</include>
<node pkg="harmoni_face" type="face_service.py" name="harmoni_face_default" output="screen"/>
<param name="test_face_input" value="[{'start': 0.075, 'time': 2,'type': 'action', 'id': 'QT/point_front'}, {'start': 0.075,'time': 2, 'type': 'viseme', 'id': 'POSTALVEOLAR'},{'start': 0.006, 'time': 2, 'type': 'action', 'id': 'happy_face'}]"/>
<test test-name="test_face" pkg="harmoni_face" type="rostest_face.py" />
</launch>
Loading

0 comments on commit 37896a9

Please sign in to comment.