/* * Copyright (c) 2008, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the Willow Garage, Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include "tf2_ros/static_transform_broadcaster_node.hpp" #include "tf2/LinearMath/Quaternion.hpp" #include "tf2/LinearMath/Vector3.hpp" #include "rclcpp/executors.hpp" #include "rclcpp/logger.hpp" #include "rclcpp/logging.hpp" #include "rclcpp/node_options.hpp" #include "rclcpp/utilities.hpp" struct Option { explicit Option(bool has_arg) : has_argument(has_arg) { } bool has_argument{false}; virtual std::string visit(const std::string & optname, const std::string & stringval) = 0; virtual ~Option() {} }; struct DoubleOption final : Option { explicit DoubleOption(bool has_arg, std::function cb) : Option(has_arg), callback(cb) { } std::function callback; std::string visit(const std::string & optname, const std::string & stringval) override { double value; try { value = std::stod(stringval); } catch (const std::invalid_argument &) { return "Failed to parse " + optname + " argument as float"; } callback(value); return ""; } }; struct StringOption final : Option { explicit StringOption(bool has_arg, std::function cb) : Option(has_arg), callback(cb) { } std::function callback; std::string visit(const std::string & optname, const std::string & stringval) override { (void)optname; callback(stringval); return ""; } }; static std::string parse_args( const std::vector & args, bool & help, tf2::Quaternion & quat, tf2::Vector3 & trans, std::string & frame_id, std::string & child_frame_id) { size_t size = args.size(); help = false; if (size < 1) { return "Not enough arguments to parse"; } size_t last_index = size - 1; bool saw_frame_flag = false; bool saw_quat_flag = false; bool saw_rpy_flag = false; bool saw_trans_flag = false; double roll = 0.0; double pitch = 0.0; double yaw = 0.0; auto qx_opt = std::make_shared( true, [&quat, &saw_quat_flag](double value) { quat.setX(value); saw_quat_flag = true; }); auto qy_opt = std::make_shared( true, [&quat, &saw_quat_flag](double value) { quat.setY(value); saw_quat_flag = true; }); auto qz_opt = std::make_shared( true, [&quat, &saw_quat_flag](double value) { quat.setZ(value); saw_quat_flag = true; }); auto qw_opt = std::make_shared( true, [&quat, &saw_quat_flag](double value) { quat.setW(value); saw_quat_flag = true; }); auto roll_opt = std::make_shared( true, [&roll, &saw_rpy_flag](double value) { roll = value; saw_rpy_flag = true; }); auto pitch_opt = std::make_shared( true, [&pitch, &saw_rpy_flag](double value) { pitch = value; saw_rpy_flag = true; }); auto yaw_opt = std::make_shared( true, [&yaw, &saw_rpy_flag](double value) { yaw = value; saw_rpy_flag = true; }); auto trans_x_opt = std::make_shared( true, [&trans, &saw_trans_flag](double value) { trans.setX(value); saw_trans_flag = true; }); auto trans_y_opt = std::make_shared( true, [&trans, &saw_trans_flag](double value) { trans.setY(value); saw_trans_flag = true; }); auto trans_z_opt = std::make_shared( true, [&trans, &saw_trans_flag](double value) { trans.setZ(value); saw_trans_flag = true; }); auto frame_id_opt = std::make_shared( true, [&frame_id, &saw_frame_flag](const std::string & value) { frame_id = value; saw_frame_flag = true; }); auto child_frame_id_opt = std::make_shared( true, [&child_frame_id, &saw_frame_flag](const std::string & value) { child_frame_id = value; saw_frame_flag = true; }); auto help_opt = std::make_shared( false, [&help](const std::string & value) { (void)value; help = true; }); std::unordered_map> options = { {"--qx", qx_opt}, {"--qy", qy_opt}, {"--qz", qz_opt}, {"--qw", qw_opt}, {"--roll", roll_opt}, {"--pitch", pitch_opt}, {"--yaw", yaw_opt}, {"--x", trans_x_opt}, {"--y", trans_y_opt}, {"--z", trans_z_opt}, {"--frame-id", frame_id_opt}, {"--child-frame-id", child_frame_id_opt}, {"--help", help_opt}, {"-h", help_opt}, }; size_t i = 1; while (i < size) { const std::string & optname = args[i]; if (options.count(optname) != 0) { std::shared_ptr