[Documentation] [TitleIndex] [WordIndex

Only released in EOL distros:  

stdr_simulator: stdr_gui | stdr_launchers | stdr_msgs | stdr_parser | stdr_resources | stdr_robot | stdr_samples | stdr_server

Package Summary

Provides a library to STDR Simulator, to parse yaml and xml description files.

stdr_simulator: stdr_gui | stdr_launchers | stdr_msgs | stdr_parser | stdr_resources | stdr_robot | stdr_samples | stdr_server

Package Summary

Provides a library to STDR Simulator, to parse yaml and xml description files.

stdr_simulator: stdr_gui | stdr_launchers | stdr_msgs | stdr_parser | stdr_resources | stdr_robot | stdr_samples | stdr_server

Package Summary

Provides a library to STDR Simulator, to parse yaml and xml description files.

stdr_simulator: stdr_gui | stdr_launchers | stdr_msgs | stdr_parser | stdr_resources | stdr_robot | stdr_samples | stdr_server

Package Summary

Provides a library to STDR Simulator, to parse yaml and xml description files.

Overview

stdr_parser is a Yaml/XML parser created for STDR Simulator. Its job is to parse resource files (robots and sensors) and create the according stdr_msgs. Also, provided a stdr_msgs message stdr_parser can save it to a Yaml or XML file. The parser structure is such that it can be "easily" extended with more file types (such as JSON f.e.) by changing only specific source files (the filetype parser and writer). A brief overview of the parsing steps follow.

How the stdr_parser works

Step 1 : Recursive file parsing

stdr_parser takes as input a Yaml or XML file and initially does a "blind" parsing of the file, meaning that no validation is performed. Of course if the file does not exist or is malformed, a ParserException is thrown. This initial parsing creates a tree consisting of stdr_parser::Node objects and represents the initial file. As the following sections describe, for convenience reasons you can have filename tags in your robot or sensor file, which are used for including other resources (for example in a robot you can include laser and sonar sensors without writing them from the scratch). During the parsing the specific filenames are parsed also recursively.

When a filename tag is found, during the parsing step, a stdr_parser::Node is created tagged as filename. For example a robot XML resource follows:

<robot>
  <robot_specifications>
    <footprint>
      <radius>0.3</radius>
    </footprint>
    <laser>
      <filename>hokuyo.xml</filename>
      <laser_specifications>
        <pose>
          <theta>1.57</theta>
        </pose>
      </laser_specifications>
    </laser>
  </robot_specifications>
<robot>

where hokuyo.xml ,may contain the following (not fully functional, just to showcase):

<laser>
  <laser_specifications>
    <max_range>4</max_range>
    <pose>
      <x>0</x>
      <y>0</y>
      <theta>0</theta>
    </pose>
    <noise>
      <filename>gauss_small.xml</filename>
    </noise>
  </laser_specifications>
</laser>

and the gauss_small.xml

<noise>
  <noise_specifications>
    <noise_mean>0</noise_mean>
    <noise_std>0.03</noise_std>
  </noise_specifications>
</noise>

In addition, every stdr_parser::Node contains a level value that is increased when the recurrent file depth increases. After the first step, the tree will look like that (the levels in [ ]):

├ robot [0]
│ ├ robot_specifications [0]
│ │ ├ footprint [0]
│ │ │ ├ radius [0]
│ │ │ │ ├ 0.3 [0]
│ │ ├ laser [0]
│ │ │ ├  filename [0]
│ │ │ │ ├ laser [1]
│ │ │ │ │ ├ laser_specifications [1]
│ │ │ │ │ │ ├ max_range [1]
│ │ │ │ │ │ │ ├ 4 [1]
│ │ │ │ │ │ ├ pose [1]
│ │ │ │ │ │ │ ├ x [1]
│ │ │ │ │ │ │ │ ├ 0 [1]
│ │ │ │ │ │ │ ├ y [1]
│ │ │ │ │ │ │ │ ├ 0 [1]
│ │ │ │ │ │ │ ├ theta [1]
│ │ │ │ │ │ │ │ ├ 0 [1]
│ │ │ │ │ │ ├ noise [1]
│ │ │ │ │ │ │ ├ filename [1]
│ │ │ │ │ │ │ │ ├ noise [2]
│ │ │ │ │ │ │ │ │ ├ noise_specifications [2]
│ │ │ │ │ │ │ │ │ │ ├ noise_mean [2]
│ │ │ │ │ │ │ │ │ │ │ ├ 0 [2]
│ │ │ │ │ │ │ │ │ │ ├ noise_std [2]
│ │ │ │ │ │ │ │ │ │ │ ├ 0.03 [2]
│ │ │ ├ laser_specifications [0]
│ │ │ │ ├ pose [0]
│ │ │ │ │ ├ theta [0]
│ │ │ │ │ │ ├ 1.57 [0]

Step 2 : 'filename' tag elimination

The second step is to eliminate the filename tags from the tree. To do so a sanity check is performed: the parent node and the child node of a filename node must be the same. If the above holds, the filename node is eliminated, as well as its child and the child's children are connected to filename's parent. The result follows:

├ robot [0]
│ ├ robot_specifications [0]
│ │ ├ footprint [0]
│ │ │ ├ radius [0]
│ │ │ │ ├ 0.3 [0]
│ │ ├ laser [0]
│ │ │ ├ laser_specifications [1]
│ │ │ │ ├ max_range [1]
│ │ │ │ │ ├ 4 [1]
│ │ │ │ ├ pose [1]
│ │ │ │ │ ├ x [1]
│ │ │ │ │ │ ├ 0 [1]
│ │ │ │ │ ├ y [1]
│ │ │ │ │ │ ├ 0 [1]
│ │ │ │ │ ├ theta [1]
│ │ │ │ │ │ ├ 0 [1]
│ │ │ │ ├ noise [1]
│ │ │ │ │ ├ noise_specifications [2]
│ │ │ │ │ │ ├ noise_mean [2]
│ │ │ │ │ │ │ ├ 0 [2]
│ │ │ │ │ │ ├ noise_std [2]
│ │ │ │ │ │ │ ├ 0.03 [2]
│ │ │ ├ laser_specifications [0]
│ │ │ │ ├ pose [0]
│ │ │ │ │ ├ theta [0]
│ │ │ │ │ │ ├ 1.57 [0]

Step 3 : Node merging

The third step is the recursive node merging. In this step the stdr_multiple_allowed.xml file under stdr_resources/resources/specifications is of crucial importance. There, the tags that can have multiple occurrences under a specific tag are placed. The current implementation allows multiple occurrences in these tags:

All the other tags are recursively merged, if multiple occurrences exist under any other tag. The tree after this step follows:

├ robot [0]
│ ├ robot_specifications [0]
│ │ ├ footprint [0]
│ │ │ ├ radius [0]
│ │ │ │ ├ 0.3 [0]
│ │ ├ laser [0]
│ │ │ ├ laser_specifications [1]
│ │ │ │ ├ max_range [1]
│ │ │ │ │ ├ 4 [1]
│ │ │ │ ├ pose [1]
│ │ │ │ │ ├ x [1]
│ │ │ │ │ │ ├ 0 [1]
│ │ │ │ │ ├ y [1]
│ │ │ │ │ │ ├ 0 [1]
│ │ │ │ │ ├ theta [1]
│ │ │ │ │ │ ├ 0 [1]
│ │ │ │ │ │ ├ 1.57 [0]
│ │ │ │ ├ noise [1]
│ │ │ │ │ ├ noise_specifications [2]
│ │ │ │ │ │ ├ noise_mean [2]
│ │ │ │ │ │ │ ├ 0 [2]
│ │ │ │ │ │ ├ noise_std [2]
│ │ │ │ │ │ │ ├ 0.03 [2]

Step 4 : Value merging

In this step we have supposedly merged all the possible tags and we are prepared to merge the value nodes. Here the level value plays its role, as during the value merging, the values with higher level are overridden by those with lower level. This helps to easily write resource files by changing only some aspects of the included files (in the specific example the robot has a laser but the scientist wants to change the laser's orientation). The final tree follows:

├ robot [0]
│ ├ robot_specifications [0]
│ │ ├ footprint [0]
│ │ │ ├ radius [0]
│ │ │ │ ├ 0.3 [0]
│ │ ├ laser [0]
│ │ │ ├ laser_specifications [1]
│ │ │ │ ├ max_range [1]
│ │ │ │ │ ├ 4 [1]
│ │ │ │ ├ pose [1]
│ │ │ │ │ ├ x [1]
│ │ │ │ │ │ ├ 0 [1]
│ │ │ │ │ ├ y [1]
│ │ │ │ │ │ ├ 0 [1]
│ │ │ │ │ ├ theta [1]
│ │ │ │ │ │ ├ 1.57 [0]
│ │ │ │ ├ noise [1]
│ │ │ │ │ ├ noise_specifications [2]
│ │ │ │ │ │ ├ noise_mean [2]
│ │ │ │ │ │ │ ├ 0 [2]
│ │ │ │ │ │ ├ noise_std [2]
│ │ │ │ │ │ │ ├ 0.03 [2]

Step 5 : Validation

This is the final parsing step where the validation is performed. Crucial role plays the stdr_specifications.xml file under stdr_resources/resources/specifications. There for every valid tag, the allowed and required children are specified. (Look at the end of the page for the file's contents). The validation step reads this file and performs allowed and required checks for all tree nodes.

Message creation / saving messages to files

After the tree is fully created, stdr_parser can create the according stdr_msgs. This is performed seamlessly by using templates. An example of creating a stdr_msgs::RobotMsg follows:

stdr_msgs::RobotMsg msg = stdr_parser::Parser::createMessage<stdr_msgs::RobotMsg>("simple_robot.yaml");

In a similar way a stdr_msgs message can be saved to a Yaml or XML file:

stdr_msgs::RobotMsg msg = stdr_parser::Parser::createMessage<stdr_msgs::RobotMsg>("simple_robot.yaml");
stdr_parser::Parser::saveMessage(msg,"test.xml");

Exceptions

If anything goes wrong an ParserException is thrown. The way to use it in a source code file follows:

  try
  {
    stdr_parser::Parser::saveMessage(
      stdr_parser::Parser::createMessage
      <stdr_msgs::RobotMsg>      //!< Type
      ("pandora_robot.yaml"),    //!< Input file
      "test.xml"            //!< Output file
    );
  }
  catch(ParserException ex)
  {
    ROS_ERROR(" === STDR PARSER ERROR ===\n%s",ex.what());
  }

The ParserException exceptions hold a trail of the error for better debugging. Example:

STDR parser : noidse_mean is not allowed in a noise_specifications tag
Trail: 
  [noidse_mean] Line 17 of file 'hokuyo_laser_4L.xml'
  [noise] Line 16 of file 'hokuyo_laser_4L.xml'
  [laser_specifications] Line 14 of file 'hokuyo_laser_4L.xml'
  [laser] Line 14 of file 'pandora_robot.xml'
  [robot_specifications] Line 52 of file 'pandora_robot.xml'
  [robot] Line 2 of file 'pandora_robot.xml'
  [STDR_Parser_Root_Node] Line 1 of file 'pandora_robot.xml'

Using YAML files

In this section typical (and fully functional) YAML file examples for the five basic message types will be provided.

Noise

noise:
  noise_specifications:
    mean: 0.5
    std: 0.200000002980232

Footprint

footprint:
  footprint_specifications:
    radius: 0.5

Laser

laser:
  laser_specifications:
    max_angle: 2.35619258880615
    min_angle: -2.35619258880615
    max_range: 4
    min_range: 0
    num_rays: 270
    noise:
      noise_specifications:
        mean: 0.5
        std: 0.200000002980232
    frequency: 10
    frame_id: laser_0
    pose:
      x: 0.100000001490116
      y: 0
      theta: 0

Sonar

sonar:
  sonar_specifications:
    max_range: 3
    min_range: 0.300000011920929
    cone_angle: 0.523598313331604
    noise:
      filename: noises/noise_gauss.yaml
    frequency: 10
    frame_id: sonar_0
    pose:
      x: 0.100000001490116
      y: 0
      theta: 0

Robot

robot:  
  robot_specifications:
    - footprint:
        footprint_specifications:
          radius: 0.15
    - initial_pose:
        theta: 0
        x: 0
        y: 0
    - laser:
        filename: laser_sensors/hokuyo_laser_4L.yaml
        laser_specifications: 
          max_range: 10
    - sonar:
        filename: range_sensors/standard_sonar.yaml
        sonar_specifications:
          frame_id: sonar_0
          pose:
            x: 0.100000001490116
            y: 0
            theta: 0
    - sonar:
        filename: range_sensors/standard_sonar.yaml
        sonar_specifications:
          frame_id: sonar_1
          pose:
            x: 0
            y: 0.100000001490116
            theta: 1.570795
    - sonar:
        filename: range_sensors/standard_sonar.yaml
        sonar_specifications:
          frame_id: sonar_2
          pose:
            x: 0
            y: -0.100000001490116
            theta: -1.570795
    - sonar:
        filename: range_sensors/standard_sonar.yaml
        sonar_specifications:
          frame_id: sonar_3
          pose:
            x: -0.100000001490116
            y: -0.100000001490116
            theta: 2.79252444444444
    - sonar:
        filename: range_sensors/standard_sonar.yaml
        sonar_specifications:
          frame_id: sonar_4
          pose:
            x: -0.100000001490116
            y: 0.100000001490116
            theta: 3.49065555555556

Using XML files

In this section typical (and fully functional) XML file examples for the five basic message types will be provided.

Noise

<noise>
  <noise_specifications>
    <noise_mean>0.1</noise_mean>
    <noise_std>0.01</noise_std>
  </noise_specifications>
</noise>

Footprint

<footprint>
  <footprint_specifications>
    <radius>0.5</radius>
  </footprint_specifications>
</footprint>

Laser

<laser>
  <laser_specifications>
    <max_angle>1.570795</max_angle>
    <min_angle>-1.570795</min_angle>
    <max_range>4.0</max_range>
    <min_range>0.1</min_range>
    <num_rays>270</num_rays>
    <frequency>10</frequency>
    <pose>
      <x>0</x>
      <y>0</y>
      <theta>0</theta>
    </pose>
    <noise>
      <filename>noises/noise_gauss.xml</filename>
      <noise_specifications>
        <noise_mean>0.5</noise_mean>
        <noise_std>0.05</noise_std>
      </noise_specifications>
    </noise>
  </laser_specifications>
</laser>

Sonar

<sonar>
  <sonar_specifications>
    <cone_angle>0.87</cone_angle>
    <max_range>3.0</max_range>
    <min_range>0.15</min_range>
    <frequency>10</frequency>
    <pose>
      <x>0.1</x>
      <y>0</y>
      <theta>0</theta>
    </pose>
    <noise>
      <filename>noises/noise_gauss.xml</filename>
    </noise>
  </sonar_specifications>
</sonar>

Robot

<robot>
  <robot_specifications>
    <footprint>
      <footprint_specifications>
        <radius>0.2</radius>
      </footprint_specifications>
    </footprint>
    <initial_pose>
      <x>0</x>
      <y>0</y>
      <theta>0</theta>
    </initial_pose>
    <laser>
      <filename>laser_sensors/hokuyo_laser_4L.xml</filename>
    </laser>
    <sonar>
      <filename>range_sensors/standard_sonar.xml</filename>
      <sonar_specifications>
        <pose>
          <x>0.1</x>
        </pose>
      </sonar_specifications>
    </sonar>
    <sonar>
      <filename>range_sensors/standard_sonar.xml</filename>
      <sonar_specifications>
        <pose>
          <y>0.1</y>
          <theta>1.570795</theta>
        </pose>
      </sonar_specifications>
    </sonar>
    <sonar>
      <filename>range_sensors/standard_sonar.xml</filename>
      <sonar_specifications>
        <pose>
          <y>-0.1</y>
          <theta>-1.570795</theta>
        </pose>
      </sonar_specifications>
    </sonar>
    <sonar>
      <filename>range_sensors/standard_sonar.xml</filename>
      <sonar_specifications>
        <pose>
          <x>-0.1</x>
          <y>-0.1</y>
          <theta>2.79252444444444</theta>
        </pose>
      </sonar_specifications>
    </sonar>
    <sonar>
      <filename>range_sensors/standard_sonar.xml</filename>
      <sonar_specifications>
        <pose>
          <x>-0.1</x>
          <y>0.1</y>
          <theta>3.49065555555556</theta>
        </pose>
      </sonar_specifications>
    </sonar>
  </robot_specifications>
</robot>

stdr_specifications.xml

environment

map

map_specifications

origin

robot

robot_specifications

initial_pose

pose

footprint

footprint_specifications

points

point

laser

laser_specifications

noise

noise_specifications

sonar

sonar_specifications

rfid

rfid_specifications

kinematic

kinematic_specifications

rfid_tag

x

y

theta

max_angle

min_angle

max_range

min_range

num_rays

frequency

frame_id

frequency

noise_std

noise_std

cone_angle


2024-12-21 18:36