import logging; logger = logging.getLogger("morse." + __name__)
import morse.core.actuator
from morse.core.services import service
from math import pi
from morse.core import mathutils
from morse.helpers.components import add_data
[docs]class MocapControl(morse.core.actuator.Actuator):
"""
Read the positions of the different joints at:
head, neck, shoulders, torso, elbows, hands, hips, knees and feet
And apply those positions to the control points (Empty's) of the armature
"""
_name = "Mocap controller"
_short_desc = "Controller for the motion of the human avatar, using the \
ASUS Xtion"
add_data('head_position', [0.0, 0.0, 0.0], "vec3<float>",
"Head position")
add_data('neck_position', [0.0, 0.0, 0.0], "vec3<float>",
"Neck position")
add_data('left_hand_position', [0.0, 0.0, 0.0], "vec3<float>",
"Left Hand position")
add_data('right_hand_position', [0.0, 0.0, 0.0], "vec3<float>",
"Right Hand position")
add_data('left_elbow_position', [0.0, 0.0, 0.0], "vec3<float>",
"Left elbow position")
add_data('right_elbow_position', [0.0, 0.0, 0.0], "vec3<float>",
"Right elbow position")
add_data('left_shoulder_position', [0.0, 0.0, 0.0], "vec3<float>",
"Left shoulder position")
add_data('right_shoulder_position', [0.0, 0.0, 0.0], "vec3<float>",
"Right shoulder position")
add_data('left_hip_position', [0.0, 0.0, 0.0], "vec3<float>",
"Left hip position")
add_data('right_hip_position', [0.0, 0.0, 0.0], "vec3<float>",
"Right hip position")
add_data('left_foot_position', [0.0, 0.0, 0.0], "vec3<float>",
"Left foot position")
add_data('right_foot_position', [0.0, 0.0, 0.0], "vec3<float>",
"Right foot position")
add_data('torso_position', [0.0, 0.0, 0.0], "vec3<float>",
"torso position")
add_data('left_knee_position', [0.0, 0.0, 0.0], "vec3<float>",
"left knee position")
add_data('right_knee_position', [0.0, 0.0, 0.0], "vec3<float>",
"right knee position")
def __init__(self, obj, parent=None):
logger.info('%s initialization' % obj.name)
# Call the constructor of the parent class
morse.core.actuator.Actuator.__init__(self, obj, parent)
parent = self.robot_parent
self.human_position = parent.bge_object.worldPosition
# Find the IK target empties
for obj in parent.bge_object.childrenRecursive:
#if obj.name == "Head_Empty":# in obj.name:
if "Head_Empty" in obj.name:
self._head_empty = obj
#if obj.name == "Neck_Empty":# in obj.name:
if "Neck_Empty" in obj.name:
self._neck_empty = obj
#if obj.name == "Torso_Empty":# in obj.name:
if "Torso_Empty" in obj.name:
self._torso_empty = obj
#if obj.name == "Hand_Empty.L":# in obj.name:
if "Hand_Empty.L" in obj.name:
self._hand_empty_l = obj
#if obj.name == "Hand_Empty.R":# in obj.name:
if "Hand_Empty.R" in obj.name:
self._hand_empty_r = obj
#if obj.name == "Elbow_Empty.L":# in obj.name:
if "Elbow_Empty.L" in obj.name:
self._elbow_empty_l = obj
#if obj.name == "Elbow_Empty.R":# in obj.name:
if "Elbow_Empty.R" in obj.name:
self._elbow_empty_r = obj
#if obj.name == "Shoulder_Empty.L":# in obj.name:
if "Shoulder_Empty.L" in obj.name:
self._shoulder_empty_l = obj
#if obj.name == "Shoulder_Empty.R":# in obj.name:
if "Shoulder_Empty.R" in obj.name:
self._shoulder_empty_r = obj
#if obj.name == "Hip_Empty.L":# in obj.name:
if "Hip_Empty.L" in obj.name:
self._hip_empty_l = obj
#if obj.name == "Hip_Empty.R":# in obj.name:
if "Hip_Empty.R" in obj.name:
self._hip_empty_r = obj
#if obj.name == "Knee_Empty.L":# in obj.name:
if "Knee_Empty.L" in obj.name:
self._knee_empty_l = obj
#if obj.name == "Knee_Empty.R":# in obj.name:
if "Knee_Empty.R" in obj.name:
self._knee_empty_r = obj
#if obj.name == "Foot_Empty.L":# in obj.name:
if "Foot_Empty.L" in obj.name:
self._foot_empty_l = obj
#if obj.name == "Foot_Empty.R":# in obj.name:
if "Foot_Empty.R" in obj.name:
self._foot_empty_r = obj
logger.info('Component initialized')
[docs] def default_action(self):
""" Apply the positions read to the IK targets of the joints """
# Compute a rotation angle for the whole body, based on the
# angle of the shoulders
world_x_vector = mathutils.Vector([1, 0, 0])
shoulders_vector = mathutils.Vector([
(self._shoulder_empty_l.worldPosition[0] -
self._shoulder_empty_r.worldPosition[0]),
(self._shoulder_empty_l.worldPosition[1] -
self._shoulder_empty_r.worldPosition[1]),
(self._shoulder_empty_l.worldPosition[2] -
self._shoulder_empty_r.worldPosition[2]) ])
logger.debug ("Shoulder Vector: [%.4f, %.4f, %.4f]" % \
(shoulders_vector[0], shoulders_vector[1], shoulders_vector[2]))
try:
# Measure the angle with respect to the X axis (in front of the man)
body_rotation = shoulders_vector.angle(world_x_vector)
# Correct the angle
body_rotation -= pi/2
except ValueError:
# There will be an error if there is no user being tracked
# by the Kinect
body_rotation = 0.0
logger.debug ("Angle with Y vector = %.4f" % body_rotation)
# Apply the rotation to the toroso. The rest of the body should follow
self._torso_empty.worldOrientation = [0.0, 0.0, body_rotation]
# Put the ik targets in the correct positions
self._set_object_position(self._head_empty.worldPosition,
self.local_data['head_position'])
self._set_object_position(self._neck_empty.worldPosition,
self.local_data['neck_position'])
self._set_object_position(self._torso_empty.worldPosition,
self.local_data['torso_position'])
self._set_object_position(self._hand_empty_l.worldPosition,
self.local_data['left_hand_position'])
self._set_object_position(self._hand_empty_r.worldPosition,
self.local_data['right_hand_position'])
self._set_object_position(self._elbow_empty_l.worldPosition,
self.local_data['left_elbow_position'])
self._set_object_position(self._elbow_empty_r.worldPosition,
self.local_data['right_elbow_position'])
self._set_object_position(self._shoulder_empty_l.worldPosition,
self.local_data['left_shoulder_position'])
self._set_object_position(self._shoulder_empty_r.worldPosition,
self.local_data['right_shoulder_position'])
self._set_object_position(self._hip_empty_l.worldPosition,
self.local_data['left_hip_position'])
self._set_object_position(self._hip_empty_r.worldPosition,
self.local_data['right_hip_position'])
self._set_object_position(self._knee_empty_l.worldPosition,
self.local_data['left_knee_position'])
self._set_object_position(self._knee_empty_r.worldPosition,
self.local_data['right_knee_position'])
self._set_object_position(self._foot_empty_l.worldPosition,
self.local_data['left_foot_position'])
self._set_object_position(self._foot_empty_r.worldPosition,
self.local_data['right_foot_position'])
#self._print_position("LEFT EMPTY", self._hand_empty_l.worldPosition)
#self._print_position("RIGHT EMPTY", self._hand_empty_r.worldPosition)
#self._print_position("HEAD", self._head_empty.worldPosition)
#self._print_position("SHOULDER.L", \
# self._shoulder_empty_l.worldPosition)
#self._print_position("SHOULDER.R", \
# self._shoulder_empty_r.worldPosition)
def _set_object_position(self, joint, position):
""" Add the position of the control point to the position of the
Human robot
"""
for i in range(3):
joint[i] = self.human_position[i] + position[i]
def _print_position(self, position_name, data):
""" Format the data from the positions,
in a way that the logger will like """
text = "%s POS = [%.4f, %.4f, %.4f]" % \
(position_name, data[0], data[1], data[2])
logger.debug (text)