Skip to content

Commit 350563a

Browse files
committed
Simplify visual sensor parsing
Move basic attribute parsing routine to utils.h
1 parent c83c375 commit 350563a

File tree

3 files changed

+125
-215
lines changed

3 files changed

+125
-215
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*********************************************************************
2+
* Software License Agreement (BSD License)
3+
*
4+
* Copyright (c) 2016, CITEC, Bielefeld University
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
*
11+
* * Redistributions of source code must retain the above copyright
12+
* notice, this list of conditions and the following disclaimer.
13+
* * Redistributions in binary form must reproduce the above
14+
* copyright notice, this list of conditions and the following
15+
* disclaimer in the documentation and/or other materials provided
16+
* with the distribution.
17+
* * Neither the name of the copyright holder nor the names of its
18+
* contributors may be used to endorse or promote products derived
19+
* from this software without specific prior written permission.
20+
*
21+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32+
* POSSIBILITY OF SUCH DAMAGE.
33+
*********************************************************************/
34+
35+
/* Author: Robert Haschke */
36+
37+
#ifndef URDF_PARSER_UTIL_H
38+
#define URDF_PARSER_UTIL_H
39+
40+
#include <urdf_exception/exception.h>
41+
#include <urdf_model/utils.h>
42+
43+
namespace urdf {
44+
45+
template <typename T>
46+
T parseAttribute(const char* value);
47+
48+
template<>
49+
inline std::string parseAttribute<std::string>(const char* value)
50+
{
51+
return value;
52+
}
53+
54+
template<>
55+
inline double parseAttribute<double>(const char* value)
56+
{
57+
return strToDouble(value);
58+
}
59+
60+
template<>
61+
inline unsigned int parseAttribute<unsigned int>(const char* value)
62+
{
63+
return std::stoul(value);
64+
}
65+
66+
template <typename T>
67+
T parseAttribute(const TiXmlElement &tag, const char* attr, const T* default_value=NULL)
68+
{
69+
const char* value = tag.Attribute(attr);
70+
if (!value)
71+
{
72+
if (default_value) return *default_value;
73+
else throw ParseError(std::string("missing '") + attr + "'' attribute");
74+
}
75+
76+
try
77+
{
78+
return parseAttribute<T>(value);
79+
}
80+
catch (const std::exception &e)
81+
{
82+
throw ParseError(std::string("failed to parse '") + attr + "' attribute: " + e.what());
83+
}
84+
}
85+
86+
}
87+
88+
#endif

urdf_parser/src/sensor_parser.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,10 @@
3636

3737

3838
#include "urdf_parser/sensor_parser.h"
39+
3940
#include "urdf_parser/pose.h"
4041
#include <urdf_sensor/camera.h>
4142
#include <urdf_sensor/ray.h>
42-
43-
#include <boost/lexical_cast.hpp>
4443
#include <console_bridge/console.h>
4544

4645
namespace urdf {

urdf_parser/src/visual_sensor_parsers.cpp

Lines changed: 36 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -35,259 +35,82 @@
3535
/* Author: John Hsu */
3636

3737
#include "urdf_parser/visual_sensor_parsers.h"
38+
#include "urdf_parser/utils.h"
39+
#include "urdf_parser/pose.h"
3840
#include <urdf_sensor/camera.h>
3941
#include <urdf_sensor/ray.h>
4042

41-
#include <fstream>
42-
#include <locale>
43-
#include <sstream>
44-
#include <stdexcept>
45-
#include <string>
46-
#include <algorithm>
47-
#include <tinyxml.h>
4843
#include <console_bridge/console.h>
49-
#include "urdf_parser/pose.h"
5044

5145
namespace urdf {
5246

5347
SensorBaseSharedPtr CameraParser::parse(TiXmlElement &config)
5448
{
55-
CameraSharedPtr camera(new Camera());
56-
5749
TiXmlElement *image = config.FirstChildElement("image");
5850
if (image)
5951
{
60-
const char* width_char = image->Attribute("width");
61-
if (width_char)
62-
{
63-
try
64-
{
65-
camera->width = std::stoul(width_char);
66-
}
67-
catch (std::invalid_argument &e)
68-
{
69-
CONSOLE_BRIDGE_logError("Camera image width [%s] is not a valid int: %s", width_char, e.what());
70-
return CameraSharedPtr();
71-
}
72-
catch (std::out_of_range &e)
73-
{
74-
CONSOLE_BRIDGE_logError("Camera image width [%s] is out of range: %s", width_char, e.what());
75-
return CameraSharedPtr();
76-
}
77-
}
78-
else
79-
{
80-
CONSOLE_BRIDGE_logError("Camera sensor needs an image width attribute");
81-
return CameraSharedPtr();
82-
}
83-
84-
const char* height_char = image->Attribute("height");
85-
if (height_char)
86-
{
87-
try
88-
{
89-
camera->height = std::stoul(height_char);
90-
}
91-
catch (std::invalid_argument &e)
92-
{
93-
CONSOLE_BRIDGE_logError("Camera image height [%s] is not a valid int: %s", height_char, e.what());
94-
return CameraSharedPtr();
95-
}
96-
catch (std::out_of_range &e)
97-
{
98-
CONSOLE_BRIDGE_logError("Camera image height [%s] is out of range: %s", height_char, e.what());
99-
return CameraSharedPtr();
100-
}
101-
}
102-
else
103-
{
104-
CONSOLE_BRIDGE_logError("Camera sensor needs an image height attribute");
105-
return CameraSharedPtr();
106-
}
107-
108-
const char* format_char = image->Attribute("format");
109-
if (format_char)
110-
camera->format = std::string(format_char);
111-
else
112-
{
113-
CONSOLE_BRIDGE_logError("Camera sensor needs an image format attribute");
114-
return CameraSharedPtr();
115-
}
116-
117-
const char* hfov_char = image->Attribute("hfov");
118-
if (hfov_char)
119-
{
120-
try {
121-
camera->hfov = strToDouble(hfov_char);
122-
} catch(std::runtime_error &) {
123-
CONSOLE_BRIDGE_logError("Camera image hfov [%s] is not a valid float", hfov_char);
124-
return CameraSharedPtr();
125-
}
126-
}
127-
else
128-
{
129-
CONSOLE_BRIDGE_logError("Camera sensor needs an image hfov attribute");
130-
return CameraSharedPtr();
131-
}
132-
133-
const char* near_char = image->Attribute("near");
134-
if (near_char)
135-
{
136-
try {
137-
camera->near = strToDouble(near_char);
138-
} catch(std::runtime_error &) {
139-
CONSOLE_BRIDGE_logError("Camera image near [%s] is not a valid float", near_char);
140-
return CameraSharedPtr();
141-
}
142-
}
143-
else
144-
{
145-
CONSOLE_BRIDGE_logError("Camera sensor needs an image near attribute");
52+
try {
53+
CameraSharedPtr camera(new Camera());
54+
camera->width = parseAttribute<unsigned int>(*image, "width");
55+
camera->height = parseAttribute<unsigned int>(*image, "height");
56+
camera->format = parseAttribute<std::string>(*image, "format");
57+
camera->hfov = parseAttribute<double>(*image, "hfov");
58+
camera->near = parseAttribute<double>(*image, "near");
59+
camera->far = parseAttribute<double>(*image, "far");
60+
return camera;
61+
}
62+
catch (const std::exception &e)
63+
{
64+
CONSOLE_BRIDGE_logError("Camera sensor %s", e.what());
14665
return CameraSharedPtr();
14766
}
148-
149-
const char* far_char = image->Attribute("far");
150-
if (far_char)
151-
{
152-
try {
153-
camera->far = strToDouble(far_char);
154-
} catch(std::runtime_error &) {
155-
CONSOLE_BRIDGE_logError("Camera image far [%s] is not a valid float", far_char);
156-
return CameraSharedPtr();
157-
}
158-
}
159-
else
160-
{
161-
CONSOLE_BRIDGE_logError("Camera sensor needs an image far attribute");
162-
return CameraSharedPtr();
163-
}
164-
16567
}
16668
else
16769
{
16870
CONSOLE_BRIDGE_logError("Camera sensor has no <image> element");
16971
return CameraSharedPtr();
17072
}
171-
return camera;
17273
}
17374

17475

17576
SensorBaseSharedPtr RayParser::parse(TiXmlElement &config)
17677
{
177-
RaySharedPtr ray (new Ray());
178-
17978
TiXmlElement *horizontal = config.FirstChildElement("horizontal");
18079
if (horizontal)
18180
{
182-
const char* samples_char = horizontal->Attribute("samples");
183-
if (samples_char)
184-
{
185-
try
186-
{
187-
ray->horizontal_samples = std::stoul(samples_char);
188-
}
189-
catch (std::invalid_argument &e)
190-
{
191-
CONSOLE_BRIDGE_logError("Ray horizontal samples [%s] is not a valid float: %s", samples_char, e.what());
192-
return RaySharedPtr();
193-
}
194-
catch (std::out_of_range &e)
195-
{
196-
CONSOLE_BRIDGE_logError("Ray horizontal samples [%s] is out of range: %s", samples_char, e.what());
197-
return RaySharedPtr();
198-
}
199-
}
200-
201-
const char* resolution_char = horizontal->Attribute("resolution");
202-
if (resolution_char)
203-
{
204-
try {
205-
ray->horizontal_resolution = strToDouble(resolution_char);
206-
} catch(std::runtime_error &) {
207-
CONSOLE_BRIDGE_logError("Ray horizontal resolution [%s] is not a valid float", resolution_char);
208-
return RaySharedPtr();
209-
}
81+
try {
82+
RaySharedPtr ray (new Ray());
83+
ray->horizontal_samples = parseAttribute<unsigned int>(*horizontal, "samples");
84+
ray->horizontal_resolution = parseAttribute<double>(*horizontal, "resolution");
85+
ray->horizontal_min_angle = parseAttribute<double>(*horizontal, "min_angle");
86+
ray->horizontal_max_angle = parseAttribute<double>(*horizontal, "max_angle");
87+
return ray;
21088
}
211-
212-
const char* min_angle_char = horizontal->Attribute("min_angle");
213-
if (min_angle_char)
89+
catch (const std::exception &e)
21490
{
215-
try {
216-
ray->horizontal_min_angle = strToDouble(min_angle_char);
217-
} catch(std::runtime_error &) {
218-
CONSOLE_BRIDGE_logError("Ray horizontal min_angle [%s] is not a valid float", min_angle_char);
219-
return RaySharedPtr();
220-
}
221-
}
222-
223-
const char* max_angle_char = horizontal->Attribute("max_angle");
224-
if (max_angle_char)
225-
{
226-
try {
227-
ray->horizontal_max_angle = strToDouble(max_angle_char);
228-
} catch(std::runtime_error &) {
229-
CONSOLE_BRIDGE_logError("Ray horizontal max_angle [%s] is not a valid float", max_angle_char);
230-
return RaySharedPtr();
231-
}
91+
CONSOLE_BRIDGE_logError("Ray horizontal: %s", e.what());
92+
return RaySharedPtr();
23293
}
23394
}
23495

23596
TiXmlElement *vertical = config.FirstChildElement("vertical");
23697
if (vertical)
23798
{
238-
const char* samples_char = vertical->Attribute("samples");
239-
if (samples_char)
240-
{
241-
try
242-
{
243-
ray->vertical_samples = std::stoul(samples_char);
244-
}
245-
catch (std::invalid_argument &e)
246-
{
247-
CONSOLE_BRIDGE_logError("Ray vertical samples [%s] is not a valid float: %s", samples_char, e.what());
248-
return RaySharedPtr();
249-
}
250-
catch (std::out_of_range &e)
251-
{
252-
CONSOLE_BRIDGE_logError("Ray vertical samples [%s] is out of range: %s", samples_char, e.what());
253-
return RaySharedPtr();
254-
}
99+
try {
100+
RaySharedPtr ray (new Ray());
101+
ray->vertical_samples = parseAttribute<unsigned int>(*vertical, "samples");
102+
ray->vertical_resolution = parseAttribute<double>(*vertical, "resolution");
103+
ray->vertical_min_angle = parseAttribute<double>(*vertical, "min_angle");
104+
ray->vertical_max_angle = parseAttribute<double>(*vertical, "max_angle");
105+
return ray;
255106
}
256-
257-
const char* resolution_char = vertical->Attribute("resolution");
258-
if (resolution_char)
259-
{
260-
try {
261-
ray->vertical_resolution = strToDouble(resolution_char);
262-
} catch(std::runtime_error &) {
263-
CONSOLE_BRIDGE_logError("Ray vertical resolution [%s] is not a valid float", resolution_char);
264-
return RaySharedPtr();
265-
}
266-
}
267-
268-
const char* min_angle_char = vertical->Attribute("min_angle");
269-
if (min_angle_char)
270-
{
271-
try {
272-
ray->vertical_min_angle = strToDouble(min_angle_char);
273-
} catch(std::runtime_error &) {
274-
CONSOLE_BRIDGE_logError("Ray vertical min_angle [%s] is not a valid float", min_angle_char);
275-
return RaySharedPtr();
276-
}
277-
}
278-
279-
const char* max_angle_char = vertical->Attribute("max_angle");
280-
if (max_angle_char)
107+
catch (const std::exception &e)
281108
{
282-
try {
283-
ray->vertical_max_angle = strToDouble(max_angle_char);
284-
} catch(std::runtime_error &) {
285-
CONSOLE_BRIDGE_logError("Ray vertical max_angle [%s] is not a valid float", max_angle_char);
286-
return RaySharedPtr();
287-
}
109+
CONSOLE_BRIDGE_logError("Ray horizontal: %s", e.what());
110+
return RaySharedPtr();
288111
}
289112
}
290-
return ray;
113+
return RaySharedPtr();
291114
}
292115

293116
}

0 commit comments

Comments
 (0)