ROS call third-party library tinyxml2 parsing XML file (to parse launch file, for example)

Introduction of 1.TinyXML2

Third-party libraries TinyXML2 is simple, compact, efficient and open source C ++ XML file parsing library, you can easily apply it to existing projects, ideal for parsing XML files, store simple data, configuration files, and object serialization and other data volume is not large operations.
TinyXML2 details and see: TinyXML2 official website .

Acquisition and installation of 2.TinyXML2

TinyXML2 by their Github page get the source code can be used specifically git cloneorder or directly download the ZIP archive, git clonecalling the situation a command is as follows:

git clone https://github.com/leethomason/tinyxml2

Entering the command line tinyxml2directory, using the following command to compile and install TinyXML2, command execution as follows (wherein the $symbol is a command shell prompt):

$ sudo make install
mkdir -p /usr/local
mkdir -p /usr/local/bin
mkdir -p /usr/local/lib
mkdir -p /usr/local/include
install xmltest /usr/local/bin/xmltest
install -m 644 tinyxml2.h /usr/local/include/tinyxml2.h
install -m 644 libtinyxml2.a /usr/local/lib/libtinyxml2.a

Accordingly, put tinyxml2library is installed into the local environment, tinyxml2run the following command directory, run the test code TinyXML2:

$ xmltest

This routine is executed when used xml files are located in tinyxml2the directory in resourcesthe directory, the terminal ends the procedure executed after the prompt as shown below:
Here Insert Picture Description
It showed tinyxml2library has been successfully installed.

Simple example of the use of 2.TinyXML2

After TinyXML2 installed on the local environment, the following simple demonstration of the use of TinyXML2:
the TinyXML2 source files in the folder xmltest.cppand resources/dream.xmlcopied to the destination folder for examples demonstrate.Here Insert Picture Description

Here, in xmltest.creference to the header file tinyxml2.h:

#include "tinyxml2.h"

At the same time declared namespace TinyXML2 of:

using namespace tinyxml2;

Further, in the main function is defined: If the program parameter is greater than 1, is created XMLDocumentobject and the loader file specified, if the last file successfully loaded, the output of the correlation processing time, the portion of the code is shown below.

	if ( argc > 1 ) {
		XMLDocument* doc = new XMLDocument();
		clock_t startTime = clock();
		doc->LoadFile( argv[1] );
 		clock_t loadTime = clock();
		int errorID = doc->ErrorID();
		delete doc; doc = 0;
 		clock_t deleteTime = clock();

		printf( "Test file '%s' loaded. ErrorID=%d\n", argv[1], errorID );
		if ( !errorID ) {
			printf( "Load time=%u\n",   (unsigned)(loadTime - startTime) );
			printf( "Delete time=%u\n", (unsigned)(deleteTime - loadTime) );
			printf( "Total time=%u\n",  (unsigned)(deleteTime - startTime) );
		}
		exit(0);
	}

Use the following command to compile the program:

$ g++ -o xmltest xmltest.cpp -ltinyxml2

If it can not find a file not found error message appears or static library, you can also manually specify the header file directory ( -I) and library files directory ( -L):

$ g++ -o xmltest xmltest.cpp -I /usr/local/include -L /usr/local/lib -ltinyxml2 

Enter the following command to execute the sample program:

$ xmltest dream.xml

You can see the program output is as follows, that is, the program successfully loaded the XML file dream.xml.
Here Insert Picture Description

3.TinyXML2 use of ROS

The following feature package to create a ROS ROS work in space by tinyxml_testusing Launch file TinyXML2 resolve the ROS, ROS in order to demonstrate the use of TnyXML2.
Here is the feature package package.xmlfile:

<?xml version="1.0"?>
<package format="2">
  <name>tinyxml_test</name>
  <version>0.0.0</version>
  <license>TODO</license>
  <maintainer email="[email protected]">jacky</maintainer>
  <description>The tinyxml_test package</description>
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>tf</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>tf</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>tf</exec_depend>
</package>

Node functions package source tinyxml_test_node.cppcode is as follows:

#include <ros/ros.h>
#include <ros/package.h>
#include <tf/transform_broadcaster.h>
#include <tinyxml2.h>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <map>

using namespace tinyxml2;//使用tinyxml2命名空间
using namespace std;

/* 功能函数 */
float String2Float(std::string numStr){
  std::stringstream ss(numStr);
  float num;
  ss>>num;
  return num;
}

int main(int argc, char **argv) {
  ros::init(argc, argv, "tinyxml_test_node");
  ros::NodeHandle nh("~"), nh_param("~");

  std::string tf_launch_file;
  //注:"test.launch"文件位于catkin_ws/src/tinyxml_test/launch/目录下
  nh_param.param<std::string>("tf_launch_file", tf_launch_file,"test.launch");

  /*Load launch file to get the tf args.*/
  XMLDocument* doc = new XMLDocument();
  std::map<std::string,tf::StampedTransform> stampedTransformMap;//用于存储多个不同坐标系之间的转换关系

  std::string filePath = ros::package::getPath("tinyxml_test");//获取tinyxml_test功能包的绝对路径
  filePath+="/launch/";
  filePath+=tf_launch_file;
  doc->LoadFile( filePath.c_str() );
  int errorID = doc->ErrorID();
  if(errorID){
      ROS_FATAL("[radar_freespace] Failed to load launch file %s.", filePath.c_str());
      return -1;
  }
  ROS_INFO( "[radar_freespace] Launch file '%s' loaded.", filePath.c_str());

  XMLElement* rootElement = doc->RootElement();//获得根元素,即launch
  std::cout<<"Root Element:"<<rootElement->Value()<<std::endl;
  for(const XMLElement* element =rootElement->FirstChildElement();element;element=element->NextSiblingElement()){
    const XMLAttribute* argsAttr = element->FindAttribute("args");
    
    std::string argsAttrStr=std::string(argsAttr->Value());
    std::cout<<"Args Attribute:"<<argsAttrStr<<std::endl;
    std::stringstream ss(argsAttrStr);
    std::vector<std::string> argStrVec;
    std::string tmpArgStr = "";
    while (std::getline(ss, tmpArgStr, ' ')) {
      argStrVec.push_back(tmpArgStr);
    }
    tf::Transform transform;
    transform.setOrigin(tf::Vector3(String2Float(argStrVec.at(0)),String2Float(argStrVec.at(1)),String2Float(argStrVec.at(2))));
    tf::Quaternion quaternion;
    quaternion.setRPY(String2Float(argStrVec.at(5)),String2Float(argStrVec.at(4)),String2Float(argStrVec.at(3)));
    transform.setRotation(quaternion);
    stampedTransformMap[argStrVec.at(6)]=tf::StampedTransform(transform,ros::Time::now(),argStrVec.at(6),argStrVec.at(7));
	
	//输出launch文件中记录的坐标系转换关系
    std::cout<<stampedTransformMap[argStrVec.at(6)].getOrigin().x()<<","<<stampedTransformMap[argStrVec.at(6)].getOrigin().y()<<","<<stampedTransformMap[argStrVec.at(6)].getOrigin().z()<<",";
    std::cout<<stampedTransformMap[argStrVec.at(6)].getRotation().getW()<<","<<stampedTransformMap[argStrVec.at(6)].getRotation().getX()<<","<<stampedTransformMap[argStrVec.at(6)].getRotation().getY()<<","<<stampedTransformMap[argStrVec.at(6)].getRotation().getZ()<<std::endl;
  }
  
  delete doc; //删除对象
  doc = NULL; //避免野指针

  ros::spin();
  return 0;
}

This can be utilized TinyXML2 Node Launch parse file (XML format) function present in the package, the file is located catkin_ws / src / tinyxml_test / launch / files in the directory test.launch, and wherein the final output can be saved according to launch a file read coordinates tf conversion information. test.launchContents of the file are as follows:

<?xml version="1.0"?>
<launch>
  <node pkg="tf" type="static_transform_publisher" name="sensor_frame_to_world" args="2 2 2 0 0 0 world sensor_frame 100" />
  <node pkg="tf" type="static_transform_publisher" name="imu_to_sensor_frame" args="0 0 0 0 0 0 sensor_frame imu 100" />
  <node pkg="tf" type="static_transform_publisher" name="lidar_to_sensor_frame" args="1 1 1 0 0 0 sensor_frame lidar 100" />
</launch>

To compile the feature pack, also you need to modify its CMakeLists.txt file, add the necessary feature pack, the directory containing the source code and libraries and so on. The complete contents of the file are as follows:

cmake_minimum_required(VERSION 2.8.3)
project(tinyxml_test)

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  roscpp
  roslib
  tf
)

###################################
## catkin specific configuration ##
###################################

catkin_package(
  LIBRARIES 
    ${PROJECT_NAME}
  CATKIN_DEPENDS
   roscpp tf
)

###########
## Build ##
###########

## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
  ${catkin_INCLUDE_DIRS}
)

## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(${PROJECT_NAME}_node src/tinyxml_test_node.cpp)

## Specify libraries to link a library or executable target against
target_link_libraries(${PROJECT_NAME}_node
  -ltinyxml2
  ${catkin_LIBRARIES}
)

#############
## Install ##
#############

## Mark executables and/or libraries for installation
install(
  TARGETS 
    ${PROJECT_NAME}_node
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

Note: Because the program needs to call third-party library TinyXML2, it is necessary in CMakeLists.txt file find_packageto add options roslibfeature pack, and target_link_librariesspecify the link to the static library option ( -ltinyxml2).

Finally, execute the command catkin_makewill feature pack after a successful compilation, use the following command to run the node (to be run in advance roscorenode):

$ rosrun tinyxml_test tinyxml_test_node 

Launch the program can output files stored tf coordinate conversion information:
Here Insert Picture Description
you're done!

Published 48 original articles · won praise 65 · views 70000 +

Guess you like

Origin blog.csdn.net/xiaolong361/article/details/94634611