6 #include <eigen3/Eigen/Dense>
8 #include <unordered_map>
9 #include <unordered_set>
20 const static std::unordered_map<std::uint8_t, std::unordered_set<std::uint8_t>> TF_LINKS {
23 Joint::TYPE_BASE_SPINE, {
25 Joint::TYPE_RIGHT_HIP,
29 { Joint::TYPE_MID_SPINE, { Joint::TYPE_SHOULDER_SPINE } },
31 Joint::TYPE_SHOULDER_SPINE, {
33 Joint::TYPE_RIGHT_SHOULDER,
34 Joint::TYPE_LEFT_SHOULDER
38 { Joint::TYPE_LEFT_SHOULDER, { Joint::TYPE_LEFT_ELBOW } },
39 { Joint::TYPE_LEFT_ELBOW, { Joint::TYPE_LEFT_WRIST } },
40 { Joint::TYPE_LEFT_WRIST, { Joint::TYPE_LEFT_HAND } },
42 { Joint::TYPE_RIGHT_SHOULDER, { Joint::TYPE_RIGHT_ELBOW } },
43 { Joint::TYPE_RIGHT_ELBOW, { Joint::TYPE_RIGHT_WRIST } },
44 { Joint::TYPE_RIGHT_WRIST, { Joint::TYPE_RIGHT_HAND } },
46 { Joint::TYPE_LEFT_HIP, { Joint::TYPE_LEFT_FOOT } },
47 { Joint::TYPE_LEFT_KNEE, { Joint::TYPE_LEFT_FOOT } },
49 { Joint::TYPE_RIGHT_HIP, { Joint::TYPE_RIGHT_KNEE } },
50 { Joint::TYPE_RIGHT_KNEE, { Joint::TYPE_RIGHT_FOOT } }
53 const static std::unordered_map<std::uint8_t, std::string> TF_FRAME_NAMES {
55 { Joint::TYPE_NECK,
"neck" },
56 { Joint::TYPE_HEAD,
"head" },
58 { Joint::TYPE_BASE_SPINE,
"base_spine" },
59 { Joint::TYPE_MID_SPINE,
"mid_spine" },
60 { Joint::TYPE_SHOULDER_SPINE,
"shoulder_spine" },
62 { Joint::TYPE_LEFT_SHOULDER,
"left_shoulder" },
63 { Joint::TYPE_LEFT_ELBOW,
"left_elbow" },
64 { Joint::TYPE_LEFT_WRIST,
"left_wrist" },
65 { Joint::TYPE_LEFT_HAND,
"left_hand" },
67 { Joint::TYPE_RIGHT_SHOULDER,
"right_shoulder" },
68 { Joint::TYPE_RIGHT_ELBOW,
"right_elbow" },
69 { Joint::TYPE_RIGHT_WRIST,
"right_wrist" },
70 { Joint::TYPE_RIGHT_HAND,
"right_hand" },
72 { Joint::TYPE_LEFT_HIP,
"left_hip" },
73 { Joint::TYPE_LEFT_KNEE,
"left_knee" },
74 { Joint::TYPE_LEFT_FOOT,
"left_foot" },
76 { Joint::TYPE_RIGHT_HIP,
"right_hip" },
77 { Joint::TYPE_RIGHT_KNEE,
"right_knee" },
78 { Joint::TYPE_RIGHT_FOOT,
"right_foot" }
86 std::uint8_t parent_type;
92 const auto frame_id = [&](
const std::uint8_t type) -> std::string {
93 const auto it = TF_FRAME_NAMES.find(type);
94 if (it == TF_FRAME_NAMES.cend())
97 o <<
"Unknown frame name for joint type " <<
static_cast<std::size_t
>(type);
98 throw std::runtime_error(o.str());
101 std::ostringstream o;
102 o <<
"humanoid/" <<
static_cast<std::size_t
>(body.id) <<
"/" << it->second;
106 std::unordered_map<std::uint8_t, const Joint *> lookup_map;
111 const auto lookup = [&](std::uint8_t type) ->
const Joint * {
112 const auto it = lookup_map.find(type);
113 if (it != lookup_map.cend())
return it->second;
115 for (
const auto &joint : body.joints)
117 if (joint.type != type)
continue;
119 lookup_map[type] = &joint;
128 for (
const auto &joint : body.joints)
130 geometry_msgs::TransformStamped transform;
131 transform.header = body.header;
132 transform.child_frame_id = frame_id(joint.type);
134 auto &translation = transform.transform.translation;
135 translation.x = joint.pose.position.x;
136 translation.y = joint.pose.position.y;
137 translation.z = joint.pose.position.z;
139 transform.transform.rotation = joint.pose.orientation;
144 std::vector<geometry_msgs::TransformStamped> ret;
147 root.type = Joint::TYPE_BASE_SPINE;
148 root.parent_type = Joint::TYPE_UNKNOWN;
150 std::deque<Node> queue { root };
152 while (!queue.empty())
155 const Node current = queue.front();
159 current.parent_type != Joint::TYPE_UNKNOWN ? frame_id(current.parent_type) : body.header.frame_id,
160 frame_id(current.type),
165 const auto links_it = TF_LINKS.find(current.type);
166 if (links_it == TF_LINKS.cend())
continue;
168 for (
auto it = links_it->second.cbegin(); it != links_it->second.cend(); ++it)
172 child.parent_type = current.type;
173 queue.push_back(child);