ProjectGenerator.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
10 #include <rtm/Manager.h>
11 #include <rtm/CorbaNaming.h>
12 #include <hrpModel/Body.h>
13 #include <hrpModel/Link.h>
14 #include <hrpModel/Sensor.h>
15 #include <hrpModel/ModelLoaderUtil.h>
16 #include <libxml/encoding.h>
17 #include <libxml/xmlwriter.h>
18 #include <string>
19 #include <sstream>
20 #include <fstream>
21 
22 void xmlTextWriterWriteProperty(const xmlTextWriterPtr writer, const std::string name, const std::string value) {
23  xmlTextWriterStartElement(writer, BAD_CAST "property");
24  xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST name.c_str());
25  xmlTextWriterWriteAttribute(writer, BAD_CAST "value", BAD_CAST value.c_str());
26  xmlTextWriterEndElement(writer);
27 }
28 
29 std::string basename(const std::string name){
30  std::string ret = name.substr(name.find_last_of('/')+1);
31  return ret.substr(0,ret.find_last_of('.'));
32 }
33 
34 int main (int argc, char** argv)
35 {
36  std::string output;
37  std::vector<std::string> inputs, filenames; // filenames is for conf file
38  std::string conf_file_option, robothardware_conf_file_option, integrate("true"), dt("0.005"), timeStep(dt), joint_properties;
39  bool use_highgain_mode(true);
40 
41  int rtmargc=0;
42  std::vector<char *> rtmargv;
43  rtmargv.push_back(argv[0]);
44  rtmargc++;
45  for (int i = 1; i < argc; ++ i) {
46  std::string arg(argv[i]);
47  coil::normalize(arg);
48  if ( arg == "--output" ) {
49  if (++i < argc) output = argv[i];
50  } else if ( arg == "--integrate" ) {
51  if (++i < argc) integrate = argv[i];
52  } else if ( arg == "--dt" ) {
53  if (++i < argc) dt = argv[i];
54  } else if ( arg == "--timestep" ) {
55  if (++i < argc) timeStep = argv[i];
56  } else if ( arg == "--conf-file-option" ) {
57  if (++i < argc) conf_file_option += std::string("\n") + argv[i];
58  } else if ( arg == "--robothardware-conf-file-option" ) {
59  if (++i < argc) robothardware_conf_file_option += std::string("\n") + argv[i];
60  } else if ( arg == "--joint-properties" ) {
61  if (++i < argc) joint_properties = argv[i];
62  } else if ( arg == "--use-highgain-mode" ) {
63  if (++i < argc) use_highgain_mode = (std::string(argv[i])==std::string("true")?true:false);
64  } else if ( arg.find("--gtest_output") == 0 ||arg.find("--text") == 0 || arg.find("__log") == 0 || arg.find("__name") == 0 ) { // skip
65  } else if ( arg[0] == '-' ) {
66  rtmargv.push_back(argv[i]);
67  rtmargv.push_back(argv[i+1]);
68  rtmargc+=2;
69  ++i;
70  } else {
71  inputs.push_back(argv[i]);
72  }
73  }
74 
76  manager = RTC::Manager::init(rtmargc, rtmargv.data());
77 
78  std::string nameServer = manager->getConfig()["corba.nameservers"];
79  int comPos = nameServer.find(",");
80  if (comPos < 0){
81  comPos = nameServer.length();
82  }
83  nameServer = nameServer.substr(0, comPos);
84  RTC::CorbaNaming naming(manager->getORB(), nameServer.c_str());
85 
86  xmlTextWriterPtr writer;
87  writer = xmlNewTextWriterFilename(output.c_str(), 0);
88  xmlTextWriterSetIndent(writer, 4);
89  xmlTextWriterStartElement(writer, BAD_CAST "grxui");
90  {
91  xmlTextWriterStartElement(writer, BAD_CAST "mode");
92  xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST "Simulation");
93  {
94  xmlTextWriterStartElement(writer, BAD_CAST "item");
95  xmlTextWriterWriteAttribute(writer, BAD_CAST "class", BAD_CAST "com.generalrobotix.ui.item.GrxSimulationItem");
96  xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST "simulationItem");
97  {
98  xmlTextWriterWriteProperty(writer, "integrate", integrate);
99  xmlTextWriterWriteProperty(writer, "timeStep", timeStep);
100  xmlTextWriterWriteProperty(writer, "totalTime", "2000000.0");
101  xmlTextWriterWriteProperty(writer, "method", "EULER");
102  }
103  xmlTextWriterEndElement(writer); // item
104  // default WAIST offset
105  hrp::Vector3 WAIST_offset_pos = hrp::Vector3::Zero();
106  Eigen::AngleAxis<double> WAIST_offset_rot = Eigen::AngleAxis<double>(0, hrp::Vector3(0,0,1)); // rotation in VRML is represented by axis + angle
107  for (std::vector<std::string>::iterator it = inputs.begin();
108  it != inputs.end();
109  it++) {
110  // argument for VRML supports following two mode:
111  // 1. xxx.wrl
112  // To specify VRML file. WAIST offsets is 0 transformation.
113  // 2. xxx.wrl,0,0,0,0,0,1,0
114  // To specify both VRML and WAIST offsets.
115  // WAIST offset: for example, "0,0,0,0,0,1,0" -> position offset (3dof) + axis for rotation offset (3dof) + angle for rotation offset (1dof)
116  coil::vstring filename_arg_str = coil::split(*it, ",");
117  std::string filename = filename_arg_str[0];
118  filenames.push_back(filename);
119  if ( filename_arg_str.size () > 1 ){ // if WAIST offset is specified
120  for (size_t i = 0; i < 3; i++) {
121  coil::stringTo(WAIST_offset_pos(i), filename_arg_str[i+1].c_str());
122  coil::stringTo(WAIST_offset_rot.axis()(i), filename_arg_str[i+1+3].c_str());
123  }
124  coil::stringTo(WAIST_offset_rot.angle(), filename_arg_str[1+3+3].c_str());
125  }
126  hrp::BodyPtr body(new hrp::Body());
127  if (!loadBodyFromModelLoader(body, filename.c_str(),
128  CosNaming::NamingContext::_duplicate(naming.getRootContext()),
129  true)){
130  std::cerr << "failed to load model[" << filename << "]" << std::endl;
131  return 1;
132  }
133  std::string name = body->name();
134 
135  xmlTextWriterStartElement(writer, BAD_CAST "item");
136  xmlTextWriterWriteAttribute(writer, BAD_CAST "class", BAD_CAST "com.generalrobotix.ui.item.GrxRTSItem");
137  xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST name.c_str());
138  xmlTextWriterWriteAttribute(writer, BAD_CAST "select", BAD_CAST "true");
139 
140  xmlTextWriterWriteProperty(writer, name+"(Robot)0.period", dt);
141  if (use_highgain_mode) {
142  xmlTextWriterWriteProperty(writer, "HGcontroller0.period", dt);
143  xmlTextWriterWriteProperty(writer, "HGcontroller0.factory", "HGcontroller");
144  if (it==inputs.begin()) {
145  xmlTextWriterWriteProperty(writer, "connection", "HGcontroller0.qOut:"+name+"(Robot)0.qRef");
146  xmlTextWriterWriteProperty(writer, "connection", "HGcontroller0.dqOut:"+name+"(Robot)0.dqRef");
147  xmlTextWriterWriteProperty(writer, "connection", "HGcontroller0.ddqOut:"+name+"(Robot)0.ddqRef");
148  }
149  } else {
150  xmlTextWriterWriteProperty(writer, "PDcontroller0.period", dt);
151  xmlTextWriterWriteProperty(writer, "PDcontroller0.factory", "PDcontroller");
152  if (it==inputs.begin()) {
153  xmlTextWriterWriteProperty(writer, "connection", "PDcontroller0.torque:"+name+"(Robot)0.tauRef");
154  xmlTextWriterWriteProperty(writer, "connection", ""+name+"(Robot)0.q:PDcontroller0.angle");
155  }
156  }
157  xmlTextWriterEndElement(writer); // item
158 
159 
160  xmlTextWriterStartElement(writer, BAD_CAST "item");
161  xmlTextWriterWriteAttribute(writer, BAD_CAST "class", BAD_CAST "com.generalrobotix.ui.item.GrxModelItem");
162  xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST (basename(*it).c_str()));
163  xmlTextWriterWriteAttribute(writer, BAD_CAST "url", BAD_CAST filename.c_str());
164 
165  xmlTextWriterWriteProperty(writer, "rtcName", name + "(Robot)0");
166  if (use_highgain_mode) {
167  xmlTextWriterWriteProperty(writer, "inport", "qRef:JOINT_VALUE");
168  xmlTextWriterWriteProperty(writer, "inport", "dqRef:JOINT_VELOCITY");
169  xmlTextWriterWriteProperty(writer, "inport", "ddqRef:JOINT_ACCELERATION");
170  if (integrate == "false") { // For kinematics only simultion
171  xmlTextWriterWriteProperty(writer, "inport", "basePoseRef:"+body->rootLink()->name+":ABS_TRANSFORM");
172  }
173  } else {
174  xmlTextWriterWriteProperty(writer, "inport", "tauRef:JOINT_TORQUE");
175  }
176  xmlTextWriterWriteProperty(writer, "outport", "q:JOINT_VALUE");
177  xmlTextWriterWriteProperty(writer, "outport", "tau:JOINT_TORQUE");
178 
179  // set outport for sensros
180  unsigned int nforce = body->numSensors(hrp::Sensor::FORCE);
181  if ( nforce > 0 ) std::cerr << "hrp::Sensor::FORCE";
182  for (unsigned int i=0; i<nforce; i++){
183  hrp::Sensor *s = body->sensor(hrp::Sensor::FORCE, i);
184  // port name and sensor name is same in case of ForceSensor
185  xmlTextWriterWriteProperty(writer, "outport", s->name + ":" + s->name + ":FORCE_SENSOR");
186  std::cerr << " " << s->name;
187  }
188  if ( nforce > 0 ) std::cerr << std::endl;
189  unsigned int ngyro = body->numSensors(hrp::Sensor::RATE_GYRO);
190  if ( ngyro > 0 ) std::cerr << "hrp::Sensor::GYRO";
191  if(ngyro == 1){
192  // port is named with no number when there is only one gyro
193  hrp::Sensor *s = body->sensor(hrp::Sensor::RATE_GYRO, 0);
194  xmlTextWriterWriteProperty(writer, "outport", s->name + ":" + s->name + ":RATE_GYRO_SENSOR");
195  std::cerr << " " << s->name;
196  }else{
197  for (unsigned int i=0; i<ngyro; i++){
198  hrp::Sensor *s = body->sensor(hrp::Sensor::RATE_GYRO, i);
199  std::stringstream str_strm;
200  str_strm << s->name << i << ":" + s->name << ":RATE_GYRO_SENSOR";
201  xmlTextWriterWriteProperty(writer, "outport", str_strm.str());
202  std::cerr << " " << s->name;
203  }
204  }
205  if ( ngyro > 0 ) std::cerr << std::endl;
206  unsigned int nacc = body->numSensors(hrp::Sensor::ACCELERATION);
207  if ( nacc > 0 ) std::cerr << "hrp::Sensor::ACCELERATION";
208  if(nacc == 1){
209  // port is named with no number when there is only one acc
210  hrp::Sensor *s = body->sensor(hrp::Sensor::ACCELERATION, 0);
211  xmlTextWriterWriteProperty(writer, "outport", s->name + ":" + s->name + ":ACCELERATION_SENSOR");
212  std::cerr << " " << s->name;
213  }else{
214  for (unsigned int i=0; i<nacc; i++){
215  hrp::Sensor *s = body->sensor(hrp::Sensor::ACCELERATION, i);
216  std::stringstream str_strm;
217  str_strm << s->name << i << ":" << s->name << ":ACCELERATION_SENSOR";
218  xmlTextWriterWriteProperty(writer, "outport", str_strm.str());
219  std::cerr << " " << s->name;
220  }
221  }
222  if ( nacc > 0 ) std::cerr << std::endl;
223 
224  //
225  std::string root_name = body->rootLink()->name;
226  xmlTextWriterWriteProperty(writer, root_name+".NumOfAABB", "1");
227 
228  // write waist pos and rot by considering both VRML original WAIST and WAIST_offset_pos and WAIST_offset_rot from arguments
229  std::ostringstream os;
230  os << body->rootLink()->p[0] + WAIST_offset_pos(0) << " "
231  << body->rootLink()->p[1] + WAIST_offset_pos(1) << " "
232  << body->rootLink()->p[2] + WAIST_offset_pos(2); // 10cm margin
233  xmlTextWriterWriteProperty(writer, root_name+".translation", os.str());
234  os.str(""); // reset ostringstream
235  Eigen::AngleAxis<double> tmpAA = Eigen::AngleAxis<double>(hrp::Matrix33(body->rootLink()->R * WAIST_offset_rot.toRotationMatrix()));
236  os << tmpAA.axis()(0) << " "
237  << tmpAA.axis()(1) << " "
238  << tmpAA.axis()(2) << " "
239  << tmpAA.angle();
240  xmlTextWriterWriteProperty(writer, root_name+".rotation", os.str());
241 
242  if ( ! body->isStaticModel() ) {
243  xmlTextWriterWriteProperty(writer, root_name+".mode", "Torque");
244  xmlTextWriterWriteProperty(writer, "controller", basename(output));
245  }
246 
247  // store joint properties
248  // [property 1],[value 1],....
249  // ex. --joint-properties RARM_JOINT0.angle,0.0,RARM_JOINT2.mode,HighGain,...
250  coil::vstring joint_properties_arg_str = coil::split(joint_properties, ",");
251  std::map <std::string, std::string> joint_properties_map;
252  for (size_t i = 0; i < joint_properties_arg_str.size()/2; i++) {
253  joint_properties_map.insert(std::pair<std::string, std::string>(joint_properties_arg_str[i*2], joint_properties_arg_str[i*2+1]));
254  }
255  if ( body->numJoints() > 0 ) std::cerr << "hrp::Joint";
256  for(unsigned int i = 0; i < body->numJoints(); i++){
257  if ( body->joint(i)->index > 0 ) {
258  std::cerr << " " << body->joint(i)->name << "(" << body->joint(i)->jointId << ")";
259  std::string joint_name = body->joint(i)->name;
260  std::string j_property = joint_name+".angle";
261  xmlTextWriterWriteProperty(writer, j_property,
262  (joint_properties_map.find(j_property) != joint_properties_map.end()) ? joint_properties_map[j_property] : "0.0");
263  j_property = joint_name+".mode";
264  xmlTextWriterWriteProperty(writer, j_property,
265  (joint_properties_map.find(j_property) != joint_properties_map.end()) ? joint_properties_map[j_property] : (use_highgain_mode?"HighGain":"Torque"));
266  j_property = joint_name+".NumOfAABB";
267  xmlTextWriterWriteProperty(writer, j_property,
268  (joint_properties_map.find(j_property) != joint_properties_map.end()) ? joint_properties_map[j_property] : "1");
269  }
270  }
271  xmlTextWriterEndElement(writer); // item
272  if ( body->numJoints() > 0 ) std::cerr << std::endl;
273 
274  //
275  // comment out self collision settings according to issues at https://github.com/fkanehiro/hrpsys-base/issues/122
276  // xmlTextWriterStartElement(writer, BAD_CAST "item");
277  // xmlTextWriterWriteAttribute(writer, BAD_CAST "class", BAD_CAST "com.generalrobotix.ui.item.GrxCollisionPairItem");
278  // xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST std::string("CP#"+name).c_str());
279  // xmlTextWriterWriteAttribute(writer, BAD_CAST "select", BAD_CAST "true");
280  // {
281  // xmlTextWriterWriteProperty(writer, "springConstant", "0 0 0 0 0 0");
282  // xmlTextWriterWriteProperty(writer, "slidingFriction", "0.5");
283  // xmlTextWriterWriteProperty(writer, "jointName2", "");
284  // xmlTextWriterWriteProperty(writer, "jointName1", "");
285  // xmlTextWriterWriteProperty(writer, "damperConstant", "0 0 0 0 0 0");
286  // xmlTextWriterWriteProperty(writer, "objectName2", name);
287  // xmlTextWriterWriteProperty(writer, "objectName1", name);
288  // xmlTextWriterWriteProperty(writer, "springDamperModel", "false");
289  // xmlTextWriterWriteProperty(writer, "staticFriction", "0.5");
290  // }
291  // xmlTextWriterEndElement(writer); // item
292 
293  xmlTextWriterStartElement(writer, BAD_CAST "view");
294  xmlTextWriterWriteAttribute(writer, BAD_CAST "class", BAD_CAST "com.generalrobotix.ui.view.GrxRobotHardwareClientView");
295  xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST "RobotHardware RTC Client");
296  xmlTextWriterWriteProperty(writer, "robotHost", "localhost");
297  xmlTextWriterWriteProperty(writer, "StateHolderRTC", "StateHolder0");
298  xmlTextWriterWriteProperty(writer, "interval", "100");
299  xmlTextWriterWriteProperty(writer, "RobotHardwareServiceRTC", "RobotHardware0");
300  xmlTextWriterWriteProperty(writer, "robotPort", "2809");
301  xmlTextWriterWriteProperty(writer, "ROBOT", name.c_str());
302  xmlTextWriterEndElement(writer); // item
303 
304  xmlTextWriterStartElement(writer, BAD_CAST "view");
305  xmlTextWriterWriteAttribute(writer, BAD_CAST "class", BAD_CAST "com.generalrobotix.ui.view.Grx3DView");
306  xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST "3DView");
307  xmlTextWriterWriteProperty(writer, "view.mode", "Room");
308  xmlTextWriterWriteProperty(writer, "showCoM", "false");
309  xmlTextWriterWriteProperty(writer, "showCoMonFloor", "false");
310  xmlTextWriterWriteProperty(writer, "showDistance", "false");
311  xmlTextWriterWriteProperty(writer, "showIntersection", "false");
312  xmlTextWriterWriteProperty(writer, "eyeHomePosition", "-0.70711 -0 0.70711 2 0.70711 -0 0.70711 2 0 1 0 0.8 0 0 0 1 ");
313  xmlTextWriterWriteProperty(writer, "showCollision", "true");
314  xmlTextWriterWriteProperty(writer, "showActualState", "true");
315  xmlTextWriterWriteProperty(writer, "showScale", "true");
316  xmlTextWriterEndElement(writer); // view
317  }
318 
319  {
320  for (std::vector<std::string>::iterator it1 = inputs.begin(); it1 != inputs.end(); it1++) {
321  std::string name1 = basename(*it1);
322  for (std::vector<std::string>::iterator it2 = it1+1; it2 != inputs.end(); it2++) {
323  std::string name2 = basename(*it2);
324 
325  xmlTextWriterStartElement(writer, BAD_CAST "item");
326  xmlTextWriterWriteAttribute(writer, BAD_CAST "class", BAD_CAST "com.generalrobotix.ui.item.GrxCollisionPairItem");
327  xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST std::string("CP#"+name2+"_#"+name1+"_").c_str());
328  {
329  xmlTextWriterWriteProperty(writer, "springConstant", "0 0 0 0 0 0");
330  xmlTextWriterWriteProperty(writer, "slidingFriction", "0.5");
331  xmlTextWriterWriteProperty(writer, "jointName2", "");
332  xmlTextWriterWriteProperty(writer, "jointName1", "");
333  xmlTextWriterWriteProperty(writer, "damperConstant", "0 0 0 0 0 0");
334  xmlTextWriterWriteProperty(writer, "objectName2", name2);
335  xmlTextWriterWriteProperty(writer, "objectName1", name1);
336  xmlTextWriterWriteProperty(writer, "springDamperModel", "false");
337  xmlTextWriterWriteProperty(writer, "staticFriction", "0.5");
338  }
339  xmlTextWriterEndElement(writer); // item
340  }
341  }
342  }
343  }
344  xmlTextWriterEndElement(writer); // mode
345  }
346  xmlTextWriterEndElement(writer); // grxui
347 
348  xmlFreeTextWriter(writer);
349 
350  {
351  std::string conf_file = output.substr(0,output.find_last_of('.'))+".conf";
352  std::fstream s(conf_file.c_str(), std::ios::out);
353 
354  s << "model: file://" << filenames[0] << std::endl;
355  s << "dt: " << dt << std::endl;
356  s << conf_file_option << std::endl;
357  }
358 
359  {
360  std::string conf_file = output.substr(0,output.find_last_of('.'))+".RobotHardware.conf";
361  std::fstream s(conf_file.c_str(), std::ios::out);
362 
363  s << "model: file://" << filenames[0] << std::endl;
364  s << "exec_cxt.periodic.type: hrpExecutionContext" << std::endl;
365  s << "exec_cxt.periodic.rate: " << static_cast<size_t>(1/atof(dt.c_str())+0.5) << std::endl; // rounding to specify integer rate value
366  s << robothardware_conf_file_option << std::endl;
367  }
368  std::cerr << "\033[1;31mProjectGenerator in hrpsys-base is old, so please use projectGenerator in openhrp3.\033[0m" << std::endl;
369  return 0;
370 }
std::string normalize(std::string &str)
char * filename
std::string name
bool stringTo(To &val, const char *str)
png_infop png_charpp name
RTC::ReturnCode_t ret(RTC::Local::ReturnCode_t r)
vstring split(const std::string &input, const std::string &delimiter, bool ignore_empty)
manager
CORBA::ORB_ptr getORB()
std::string basename(const std::string name)
png_uint_32 i
Eigen::Vector3d Vector3
Eigen::Matrix3d Matrix33
std::vector< std::string > vstring
coil::Properties & getConfig()
static Manager * init(int argc, char **argv)
int loadBodyFromModelLoader(::World *world, const char *name, const char *url, CosNaming::NamingContext_var cxt)
naming
void xmlTextWriterWriteProperty(const xmlTextWriterPtr writer, const std::string name, const std::string value)
char * arg
void * writer(void *arg)
int main(int argc, char **argv)
output(gif_dest_ptr dinfo, int code)


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Thu May 6 2021 02:41:50