3 #include <std_srvs/Trigger.h>
9 typedef XmlRpcValue::ValueStruct::value_type
KeyValue;
10 using geometry_msgs::TransformStamped;
15 && (value.
size() == 8 || value.
size() == 9),
16 "Transform must be an array of 8 or 9 elements.");
20 msg.header.frame_id =
static_cast<std::string
>(value[value.
size() - 2]);
22 msg.child_frame_id =
static_cast<std::string
>(value[value.
size() - 1]);
24 msg.transform.translation.x =
static_cast<double>(value[0]);
25 msg.transform.translation.y =
static_cast<double>(value[1]);
26 msg.transform.translation.z =
static_cast<double>(value[2]);
28 if (value.
size() == 8)
31 double halfYaw =
static_cast<double>(value[3]) / 2;
32 double halfPitch =
static_cast<double>(value[4]) / 2;
33 double halfRoll =
static_cast<double>(value[5]) / 2;
34 double cy = std::cos(halfYaw);
35 double sy = std::sin(halfYaw);
36 double cp = std::cos(halfPitch);
37 double sp = std::sin(halfPitch);
38 double cr = std::cos(halfRoll);
39 double sr = std::sin(halfRoll);
41 msg.transform.rotation.x = sr * cp * cy - cr * sp * sy;
42 msg.transform.rotation.y = cr * sp * cy + sr * cp * sy;
43 msg.transform.rotation.z = cr * cp * sy - sr * sp * cy;
44 msg.transform.rotation.w = cr * cp * cy + sr * sp * sy;
46 else if (value.
size() == 9)
49 msg.transform.rotation.x =
static_cast<double>(value[3]);
50 msg.transform.rotation.y =
static_cast<double>(value[4]);
51 msg.transform.rotation.z =
static_cast<double>(value[5]);
52 msg.transform.rotation.w =
static_cast<double>(value[6]);
59 bool operator==(
const TransformStamped &lhs,
const TransformStamped &rhs)
61 return lhs.header.frame_id == rhs.header.frame_id &&
62 lhs.child_frame_id == rhs.child_frame_id &&
63 lhs.transform.translation.x == rhs.transform.translation.x &&
64 lhs.transform.translation.y == rhs.transform.translation.y &&
65 lhs.transform.translation.z == rhs.transform.translation.z &&
66 lhs.transform.rotation.x == rhs.transform.rotation.x &&
67 lhs.transform.rotation.y == rhs.transform.rotation.y &&
68 lhs.transform.rotation.z == rhs.transform.rotation.z &&
69 lhs.transform.rotation.w == rhs.transform.rotation.w;
84 std::lock_guard<std::mutex> lock(this->
paramMutex);
87 ROS_WARN_ONCE(
"Parameter 'transforms' was not found. Will not publish any transforms until it appears.");
93 this->
nh.
param(
"transforms", transforms, transforms);
97 ROS_ERROR(
"Error reading transforms from parameter %s: %s, error code %i",
104 if (transforms.
getType() != XmlRpcValue::TypeArray
105 && transforms.
getType() != XmlRpcValue::TypeStruct)
107 ROS_ERROR(
"Parameter %s must be array or struct of arrays, got type %i.",
112 std::vector<TransformStamped> msgs;
113 msgs.reserve(
static_cast<size_t>(transforms.
size()));
115 if (transforms.
getType() == XmlRpcValue::TypeArray)
118 for (
size_t i = 0; i < transforms.
size(); ++i)
120 auto& transform = transforms[i];
127 ROS_ERROR(
"Error reading static transform nr. %lu: %s, error code %i",
142 ROS_ERROR(
"Error reading static transform %s: %s, error code %i",
152 for (
const auto &msg : msgs)
154 ROS_DEBUG(
"Publishing static transform from %s to %s.",
155 msg.header.frame_id.c_str(),
156 msg.child_frame_id.c_str());
163 protected:
bool onReloadTrigger(std_srvs::Trigger::Request&, std_srvs::Trigger::Response& resp)
183 int main(
int argc,
char **argv)
185 ros::init(argc, argv,
"tf_static_publisher",
191 const auto reload_frequency = pnh.
param(
"reload_frequency", 0.0);
195 if (reload_frequency == 0.0)
202 std::thread reload_thread([&rate, &node]()
212 reload_thread.join();