pinocchio  2.1.3
lua.cpp
1 //
2 // Copyright (c) 2015-2016 CNRS
3 //
4 
5 #include "pinocchio/parsers/lua/lua_tables.hpp"
6 #include "pinocchio/parsers/lua.hpp"
7 
8 #include <lua.hpp>
9 #include <iostream>
10 #include <map>
11 #include <sstream>
12 
13 #include "pinocchio/spatial/se3.hpp"
14 #include "pinocchio/spatial/motion.hpp"
15 #include "pinocchio/spatial/inertia.hpp"
16 #include "pinocchio/multibody/model.hpp"
17 
18 typedef pinocchio::SE3::Vector3 Vector3;
19 typedef pinocchio::SE3::Matrix3 Matrix3;
20 
21 template<> Vector3 LuaTableNode::getDefault<Vector3> (const Vector3 & default_value)
22 {
23  Vector3 result (default_value);
24 
25  if (stackQueryValue()) {
26  LuaTable vector_table = LuaTable::fromLuaState (luaTable->L);
27 
28  if (vector_table.length() != 3) {
29  std::cerr << "LuaModel Error: invalid 3d vector!" << std::endl;
30  abort();
31  }
32 
33  result[0] = vector_table[1];
34  result[1] = vector_table[2];
35  result[2] = vector_table[3];
36  }
37 
38  stackRestore();
39 
40  return result;
41 }
42 
43 template<> Matrix3 LuaTableNode::getDefault<Matrix3> (const Matrix3 & default_value)
44 {
45  Matrix3 result (default_value);
46 
47  if (stackQueryValue()) {
48  LuaTable vector_table = LuaTable::fromLuaState (luaTable->L);
49 
50  if (vector_table.length() != 3) {
51  std::cerr << "LuaModel Error: invalid 3d matrix!" << std::endl;
52  abort();
53  }
54 
55  if (vector_table[1].length() != 3
56  || vector_table[2].length() != 3
57  || vector_table[3].length() != 3) {
58  std::cerr << "LuaModel Error: invalid 3d matrix!" << std::endl;
59  abort();
60  }
61 
62  result(0,0) = vector_table[1][1];
63  result(0,1) = vector_table[1][2];
64  result(0,2) = vector_table[1][3];
65 
66  result(1,0) = vector_table[2][1];
67  result(1,1) = vector_table[2][2];
68  result(1,2) = vector_table[2][3];
69 
70  result(2,0) = vector_table[3][1];
71  result(2,1) = vector_table[3][2];
72  result(2,2) = vector_table[3][3];
73  }
74 
75  stackRestore();
76 
77  return result;
78 }
79 
80 template<> pinocchio::SE3 LuaTableNode::getDefault<pinocchio::SE3> (const pinocchio::SE3 & default_value)
81 {
82  pinocchio::SE3 result (default_value);
83 
84  if (stackQueryValue()) {
85  LuaTable vector_table = LuaTable::fromLuaState (luaTable->L);
86 
87  result.translation() = vector_table["r"].getDefault<Vector3> (Vector3::Zero (3));
88  result.rotation().transpose() = vector_table["E"].getDefault<Matrix3> (Matrix3::Identity (3,3));
89  }
90 
91  stackRestore();
92 
93  return result;
94 }
95 
96 template<> pinocchio::Inertia LuaTableNode::getDefault<pinocchio::Inertia> (const pinocchio::Inertia & default_value)
97 {
98  pinocchio::Inertia result (default_value);
99 
100  if (stackQueryValue()) {
101  LuaTable vector_table = LuaTable::fromLuaState (luaTable->L);
102 
103  double mass = 0.;
104  Vector3 com;
105  Matrix3 inertia_matrix;
106 
107  mass = vector_table["mass"];
108  com = vector_table["com"].getDefault<Vector3> (Vector3::Zero ());
109  inertia_matrix = vector_table["inertia"].getDefault<Matrix3> (Matrix3::Identity ());
110 
111  result = pinocchio::Inertia (mass, com, inertia_matrix);
112  }
113 
114  stackRestore();
115 
116  return result;
117 }
118 
119 namespace pinocchio
120 {
121  namespace lua
122  {
123 
124  template<typename JointModel>
125  Model::JointIndex addJointAndBody(Model & model, const JointModelBase<JointModel> & jmodel, const Model::JointIndex parent_id,
126  const SE3 & joint_placement, const std::string & joint_name, const Inertia & Y, const std::string & body_name)
127  {
128  Model::JointIndex idx;
129 
130  idx = model.addJoint(parent_id,jmodel,
131  joint_placement,joint_name);
132  model.addJointFrame(idx);
133  model.appendBodyToJoint(idx,Y);
134  model.addBodyFrame(body_name, idx);
135 
136  return idx;
137  }
138 
139  bool LuaModelReadFromTable (LuaTable & model_table, Model & model, bool freeFlyer, bool verbose)
140  {
141  typedef std::map<std::string, Model::Index> mapStringIndex_t;
142  mapStringIndex_t body_table_id_map;
143  mapStringIndex_t fixed_body_table_id_map;
144 
145  typedef std::map<std::string, SE3> mapStringSE3_t;
146  mapStringSE3_t fixed_placement_map;
147 
148  if (model_table["gravity"].exists())
149  {
150  model.gravity.linear() = model_table["gravity"].get<Vector3> ();
151 
152  if (verbose)
153  std::cout << "gravity = " << model.gravity.linear().transpose() << std::endl;
154  }
155 
156  if (! model_table["frames"].exists())
157  {
158  std::cerr << "Frames table missing from model table - Abort" << std::endl;
159  abort();
160  }
161 
162  size_t frame_count = model_table["frames"].length();
163 
164  body_table_id_map["ROOT"] = 0;
165 
166  for (int i = 1; i <= (int) frame_count; i++) {
167 
168  std::stringstream body_name_default;
169  body_name_default << "body " << i;
170  std::string body_name = model_table["frames"][i]["name"].getDefault<std::string> (body_name_default.str());
171 
172  std::string parent_name;
173  if (model_table["frames"][i]["parent"].exists ())
174  {
175  parent_name = model_table["frames"][i]["parent"].get<std::string> ();
176  }
177  else if (i == 1) // first body of the tree
178  {
179  parent_name = "ROOT";
180  }
181  else // no parent defined
182  {
183  std::cerr << "Parent not defined for frame " << i << "." << std::endl;
184  abort();
185  }
186 
187  Model::JointIndex parent_id;
188  SE3 fixed_placement_offset (SE3::Identity());
189 
190  if (body_table_id_map.find (parent_name) != body_table_id_map.end ())
191  {
192  parent_id = body_table_id_map[parent_name];
193  }
194  else if (fixed_body_table_id_map.find(parent_name) != fixed_body_table_id_map.end ()) // the parent is fixed in the kinematic tree
195  {
196  parent_id = fixed_body_table_id_map[parent_name];
197  fixed_placement_offset = fixed_placement_map[parent_name];
198  }
199  else
200  {
201  std::cerr << parent_name << " is not in the tree." << std::endl;
202  abort ();
203  }
204 
205  std::stringstream joint_name_default;
206  joint_name_default << "joint " << i;
207  std::string joint_name = model_table["frames"][i]["joint_name"].getDefault<std::string> (joint_name_default.str());
208 
209  SE3 joint_placement = model_table["frames"][i]["joint_frame"].getDefault<SE3> (SE3::Identity ());
210  SE3 global_placement (fixed_placement_offset * joint_placement); // placement due to the existence of fixed bodies
211 
212  if (! model_table["frames"][i]["body"].exists()) {
213  std::cerr << "body field not defined for frame " << i << "." << std::endl;
214  abort();
215  }
216 
217  Inertia Y = model_table["frames"][i]["body"].getDefault<Inertia> (Inertia::Identity ());
218 
219  std::string joint_type;
220  if (model_table["frames"][i]["joint"].exists())
221  {
222  if (model_table["frames"][i]["joint"].length() == 0)
223  joint_type = "JointTypeFixed";
224  else if (model_table["frames"][i]["joint"].length() == 1)
225  joint_type = model_table["frames"][i]["joint"][1].getDefault<std::string> ("");
226  else
227  {
228  joint_type = model_table["frames"][i]["joint"][1].getDefault<std::string> ("");
229  std::cerr << "Joint compouned not yet implemented. Take only the first joint." << std::endl;
230  }
231  }
232  else if (i == 1) // first body of the tree
233  {
234  if (freeFlyer)
235  joint_type = "JointTypeFloatbase";
236  else
237  {
238  std::cerr << "The first segment is defined without any definition of joint type relatily to the world." << std::endl;
239  abort ();
240  }
241  }
242  else
243  {
244  std::cerr << "joint field not defined for frame " << i << "." << std::endl;
245  abort();
246  }
247 
248  Model::JointIndex joint_id;
249  if (joint_type == "JointTypeRevoluteX")
250  {
251  joint_id = addJointAndBody(model,JointModelRX(),parent_id,global_placement,joint_name,Y,body_name);
252  }
253  else if (joint_type == "JointTypeRevoluteY")
254  {
255  joint_id = addJointAndBody(model,JointModelRY(),parent_id,global_placement,joint_name,Y,body_name);
256  }
257  else if (joint_type == "JointTypeRevoluteZ")
258  {
259  joint_id = addJointAndBody(model,JointModelRZ(),parent_id,global_placement,joint_name,Y,body_name);
260  }
261  else if (joint_type == "JointTypePrismaticX")
262  {
263  joint_id = addJointAndBody(model,JointModelPX(),parent_id,global_placement,joint_name,Y,body_name);
264  }
265  else if (joint_type == "JointTypePrismaticY")
266  {
267  joint_id = addJointAndBody(model,JointModelPY(),parent_id,global_placement,joint_name,Y,body_name);
268  }
269  else if (joint_type == "JointTypePrismaticZ")
270  {
271  joint_id = addJointAndBody(model,JointModelPZ(),parent_id,global_placement,joint_name,Y,body_name);
272  }
273  else if (joint_type == "JointTypeFloatingBase" || joint_type == "JointTypeFloatbase")
274  {
275  joint_id = addJointAndBody(model,JointModelFreeFlyer(),parent_id,global_placement,joint_name,Y,body_name);
276  }
277  else if (joint_type == "JointTypeSpherical")
278  {
279  joint_id = addJointAndBody(model,JointModelSpherical(),parent_id,global_placement,joint_name,Y,body_name);
280  }
281  else if (joint_type == "JointTypeEulerZYX")
282  {
283  joint_id = addJointAndBody(model,JointModelSphericalZYX(),parent_id,global_placement,joint_name,Y,body_name);
284  }
285  else if (joint_type == "JointTypeFixed")
286  {
287  model.appendBodyToJoint(parent_id, Y, global_placement);
288  // TODO Why not
289  // model.addBodyFrame(body_name, parent_id, global_placement);
290  // ???
291  model.addBodyFrame(randomStringGenerator(8), parent_id, global_placement);
292 
293  joint_id = (Model::JointIndex)model.njoints;
294 
295  fixed_body_table_id_map[body_name] = parent_id;
296  fixed_placement_map[body_name] = global_placement;
297  }
298  else
299  {
300  std::cerr << joint_type << " is not supported.." << std::endl;
301  abort ();
302  }
303 
304  body_table_id_map[body_name] = joint_id;
305 
306  if (verbose) {
307  std::cout << "==== Added Body ====" << std::endl;
308  std::cout << " joint name : " << joint_type << std::endl;
309  std::cout << " joint id : " << joint_id << std::endl;
310  std::cout << " joint parent id : " << parent_id << std::endl;
311  std::cout << " joint placement (wrt its parent):\n" << joint_placement << std::endl;
312  std::cout << " joint type : " << joint_type << std::endl;
313  std::cout << " body name : " << body_name << std::endl;
314  std::cout << " body inertia:\n" << Y << std::endl;
315  }
316  }
317 
318  return true;
319  }
320 
321  Model buildModel (const std::string & filename, bool freeFlyer, bool verbose)
322  {
323  Model model;
324 
325  LuaTable model_table = LuaTable::fromFile (filename.c_str ());
326  LuaModelReadFromTable (model_table, model, freeFlyer, verbose);
327 
328  return model;
329  }
330 
331  } // namespace lua
332 
333 } // namespace pinocchio
Main pinocchio namespace.
Definition: treeview.dox:24
std::string randomStringGenerator(const int len)
Generate a random string composed of alphanumeric symbols of a given length.