72   return "hardware_interface/EffortJointInterface";
 
   75 std::string 
printXML(
const tinyxml2::XMLDocument& doc)
 
   77   tinyxml2::XMLPrinter printer;
 
   79   return printer.CStr();
 
   87   using tinyxml2::XMLElement;
 
   89   tinyxml2::XMLDocument doc;
 
   90   std::string urdf_string = 
urdf_config_->getURDFContents();
 
   91   doc.Parse(urdf_string.c_str());
 
   92   auto root = doc.RootElement();
 
   95   std::string orig_urdf = 
printXML(doc);
 
   98   std::map<std::string, XMLElement*> transmission_elements;
 
   99   for (XMLElement* element = root->FirstChildElement(
"transmission"); element != 
nullptr;
 
  100        element = element->NextSiblingElement(element->Value()))
 
  102     auto type_tag = element->FirstChildElement(
"type");
 
  103     auto joint_tag = element->FirstChildElement(
"joint");
 
  104     if (!type_tag || !type_tag->GetText() || !joint_tag || !joint_tag->Attribute(
"name"))
 
  106     if (std::string(type_tag->GetText()) == 
"transmission_interface/SimpleTransmission")
 
  107       transmission_elements[element->FirstChildElement(
"joint")->Attribute(
"name")] = element;
 
  111   for (XMLElement* element = root->FirstChildElement(); element != 
nullptr; element = element->NextSiblingElement())
 
  113     const std::string tag_name(element->Value());
 
  114     if (tag_name == 
"link" && element->FirstChildElement(
"collision"))
 
  116       XMLElement* inertial = 
uniqueInsert(doc, *element, 
"inertial");
 
  117       uniqueInsert(doc, *inertial, 
"mass", { { 
"value", 
"0.1" } });
 
  118       uniqueInsert(doc, *inertial, 
"origin", { { 
"xyz", 
"0 0 0" }, { 
"rpy", 
"0 0 0" } });
 
  127     else if (tag_name == 
"joint")
 
  129       const char* joint_type = element->Attribute(
"type");
 
  130       const char* joint_name = element->Attribute(
"name");
 
  131       if (!joint_type || !joint_name || strcmp(joint_type, 
"fixed") == 0)
 
  135       XMLElement* transmission;
 
  136       auto it = transmission_elements.find(joint_name);
 
  137       if (it != transmission_elements.end())
 
  138         transmission = it->second;
 
  141         transmission = doc.NewElement(
"transmission");
 
  142         root->InsertEndChild(transmission);
 
  143         transmission->SetAttribute(
"name", (std::string(
"trans_") + joint_name).c_str());
 
  146       uniqueInsert(doc, *transmission, 
"type", {}, 
"transmission_interface/SimpleTransmission");
 
  149       auto* joint = 
uniqueInsert(doc, *transmission, 
"joint", { { 
"name", joint_name } });
 
  150       uniqueInsert(doc, *joint, 
"hardwareInterface", {}, hw_interface.c_str());
 
  152       auto actuator_name = joint_name + std::string(
"_motor");
 
  153       auto* actuator = 
uniqueInsert(doc, *transmission, 
"actuator", { { 
"name", actuator_name.c_str() } });
 
  154       uniqueInsert(doc, *actuator, 
"hardwareInterface", {}, hw_interface.c_str());
 
  155       uniqueInsert(doc, *actuator, 
"mechanicalReduction", {}, 
"1");
 
  160   XMLElement* gazebo = 
uniqueInsert(doc, *root, 
"gazebo");
 
  161   XMLElement* plugin = 
uniqueInsert(doc, *gazebo, 
"plugin", { { 
"name", 
"gazebo_ros_control", 
true } });
 
  165   std::string new_urdf = 
printXML(doc);
 
  167   return orig_urdf == new_urdf ? std::string() : new_urdf;
 
  175   std::ofstream os(file_path, std::ios_base::trunc);
 
  178     RCLCPP_ERROR_STREAM(*
logger_, 
"Unable to open file for writing " << file_path);
 
  190   tinyxml2::XMLDocument doc;
 
  191   doc.Parse(new_urdf_contents.c_str());
 
  194     error_row = doc.ErrorLineNum();
 
  195     error_description = doc.ErrorStr();
 
DataWarehousePtr config_data_
 
std::shared_ptr< rclcpp::Logger > logger_
 
std::string gazebo_urdf_string_
Gazebo URDF robot model string.
 
void onInit() override
Overridable initialization method.
 
std::shared_ptr< URDFConfig > urdf_config_
 
bool isValidXML(const std::string &new_urdf_contents, int &error_row, std::string &error_description) const
Check if the given xml is valid.
 
bool outputGazeboURDFFile(const std::filesystem::path &file_path)
 
std::string getGazeboCompatibleURDF()
Parses the existing urdf and constructs a string from it with the elements required by gazebo simulat...
 
std::string getJointHardwareInterface(const std::string &joint_name)
Helper function to get the controller that is controlling the joint.
 
std::string printXML(const tinyxml2::XMLDocument &doc)
 
tinyxml2::XMLElement * uniqueInsert(tinyxml2::XMLDocument &doc, tinyxml2::XMLElement &element, const char *tag, const std::vector< XMLAttribute > &attributes={}, const char *text=nullptr)
Insert a new XML element with a given tag, attributes, and text.