1import logging; logger = logging.getLogger("morserobots." + __name__) 2from morse.builder import bpymorse 3from morse.builder import GroundRobot 4from morse.builder.actuators import Armature 5from morse.builder.sensors import ArmaturePose 6 7class Human(GroundRobot): 8 """ Append a human model to the scene. 9 10 Usage example: 11 12 .. code-block:: python 13 14 #! /usr/bin/env morseexec 15 16 from morse.builder import * 17 18 human = Human() 19 human.translate(x=5.5, y=-3.2, z=0.0) 20 human.rotate(z=-3.0) 21 22 human.skeleton.add_stream('pocolibs') 23 24 Currently, only one human per simulation is supported. 25 26 Detailed documentation 27 ---------------------- 28 29 The MORSE human avatar is based on a 3D model generated from MakeHuman, and 30 stored in human_rig.blend. 31 32 The model is rigged with an armature (`human.skeleton`), used to control the 33 postures of the human and to deform accordingly the human mesh. 34 35 This armature is used by MORSE as both a :doc:`sensor to read and export 36 the human pose <../sensors/armature_pose>` and :doc:`an actuator 37 <../actuators/armature>` to modify the pose. 38 39 TODO: give code examples to read and modify the pose 40 41 The armature defines 5 particular points (**IK targets**) that can be 42 manipulated to control the human model in a simpler way: the head, the two 43 wrists and the two feet. 44 45 """ 46 47 # list of human bones that we want to control via IK targets 48 IK_TARGETS = ["head", "wrist_L", "wrist_R", "foot_L", "foot_R"] 49 50 def __init__(self, filename='human_rig', name = None): 51 """ 52 :param filename: the human model. Default: 'human_rig' 53 """ 54 GroundRobot.__init__(self, filename, name) 55 self.properties(classpath = "morse.robots.human.Human") 56 57 self.skeleton = None 58 59 try: 60 self.skeleton = Armature(armature_name = self.get_child("HumanSkeleton").name) 61 self.append(self.skeleton) 62 except KeyError: 63 logger.error("Could not find the human armature! (I was looking " +\ 64 "for an object called 'HumanSkeleton' in the children " + \ 65 "objects of the human). I won't be able to export the " + \ 66 "human pose to any middleware.") 67 68 if self.skeleton: 69 self.skeleton.create_ik_targets(self.IK_TARGETS) 70 for t, name in self.skeleton.ik_targets: 71 t.parent = self._bpy_object 72 73 # Add an armature sensor. "joint_stateS" to match standard ROS spelling. 74 self.joint_states = ArmaturePose("joint_states") 75 self.skeleton.append(self.joint_states) 76 77 78 def add_interface(self, interface): 79 if interface == "socket": 80 self.joint_states.add_stream("socket") 81 self.joint_states.add_service("socket") 82 self.skeleton.add_service('socket') 83 84 elif interface == "ros": 85 86 self.joint_states.add_stream("ros") 87 88 self.skeleton.add_service("ros") 89 self.skeleton.add_overlay("ros", 90 "morse.middleware.ros.overlays.armatures.ArmatureController") 91 92 elif interface == "pocolibs": 93 self.skeleton.properties(classpath="morse.sensors.human_posture.HumanPosture") 94 self.add_stream(interface) 95 96