Skip to content

Commit

Permalink
Merge pull request #61 from ichiro-its/feature/create-tf2
Browse files Browse the repository at this point in the history
[Sprint 22/23 / PI-412] - [Feature] Implement TF2 Tree
  • Loading branch information
borednuna committed Jun 15, 2024
2 parents c1d8bf6 + acc7ef5 commit de1c57a
Show file tree
Hide file tree
Showing 12 changed files with 531 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ add_library(${PROJECT_NAME} SHARED
"src/${PROJECT_NAME}/joint/node/joint_node.cpp"
"src/${PROJECT_NAME}/joint/utils/middleware.cpp"
"src/${PROJECT_NAME}/joint/utils/node_control.cpp"
"src/${PROJECT_NAME}/joint/tf2/frame_id.cpp"
"src/${PROJECT_NAME}/joint/tf2/frame.cpp"
"src/${PROJECT_NAME}/joint/tf2/tf2_manager.cpp"
"src/${PROJECT_NAME}/node/tachimawari_node.cpp"
# TODO: Enable me later.
# "src/${PROJECT_NAME}/node/rviz_server_node.cpp"
Expand Down Expand Up @@ -170,6 +173,7 @@ ament_export_dependencies(
kansei_interfaces
keisan
rclcpp
tf2_ros
tachimawari_interfaces)
ament_export_include_directories("include")
ament_export_libraries(${PROJECT_NAME})
Expand Down
18 changes: 17 additions & 1 deletion include/tachimawari/joint/node/joint_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,19 @@
#include <memory>
#include <string>

#include "kansei_interfaces/msg/status.hpp"
#include "keisan/angle/angle.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp/time.hpp"
#include "tachimawari/joint/node/joint_manager.hpp"
#include "tachimawari/joint/tf2/tf2_manager.hpp"
#include "tachimawari/joint/utils/middleware.hpp"
#include "tachimawari_interfaces/msg/control_joints.hpp"
#include "tachimawari_interfaces/msg/current_joints.hpp"
#include "tachimawari_interfaces/msg/set_joints.hpp"
#include "tachimawari_interfaces/msg/set_torques.hpp"
#include "tf2_ros/buffer.h"
#include "tf2_ros/transform_broadcaster.h"

namespace tachimawari::joint
{
Expand All @@ -42,16 +48,21 @@ class JointNode
using CurrentJoints = tachimawari_interfaces::msg::CurrentJoints;
using SetJoints = tachimawari_interfaces::msg::SetJoints;
using SetTorques = tachimawari_interfaces::msg::SetTorques;
using Status = kansei_interfaces::msg::Status;

static std::string get_node_prefix();
static std::string control_joints_topic();
static std::string set_joints_topic();
static std::string set_torques_topic();
static std::string current_joints_topic();
static std::string status_topic();

JointNode(rclcpp::Node::SharedPtr node, std::shared_ptr<JointManager> joint_manager);
JointNode(
rclcpp::Node::SharedPtr node, std::shared_ptr<JointManager> joint_manager, const std::string & path);
keisan::Angle<double> imu_yaw;

void publish_current_joints();
void publish_frame_tree();
void update();

private:
Expand All @@ -63,8 +74,13 @@ class JointNode

rclcpp::Subscription<SetTorques>::SharedPtr set_torques_subscriber;

rclcpp::Subscription<Status>::SharedPtr status_subscriber;

Middleware middleware;
rclcpp::Subscription<ControlJoints>::SharedPtr control_joints_subscriber;

std::shared_ptr<tf2_ros::TransformBroadcaster> tf2_broadcaster;
std::shared_ptr<Tf2Manager> tf2_manager;
};

} // namespace tachimawari::joint
Expand Down
77 changes: 77 additions & 0 deletions include/tachimawari/joint/tf2/frame.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) 2021-2023 Ichiro ITS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef TACHIMAWARI__JOINT__TF2__FRAME_HPP_
#define TACHIMAWARI__JOINT__TF2__FRAME_HPP_

#include <memory>
#include <string>
#include <vector>

#include "geometry_msgs/msg/transform_stamped.hpp"
#include "keisan/angle/angle.hpp"
#include "nlohmann/json.hpp"
#include "rclcpp/time.hpp"
#include "tachimawari/joint/node/joint_manager.hpp"
#include "tachimawari/joint/tf2/frame_id.hpp"
#include "tf2/LinearMath/Quaternion.h"

namespace tachimawari::joint
{

class Frame
{
public:
Frame(
const uint8_t id, const double translation_x, const double translation_y,
const double translation_z, const double const_roll, const double const_pitch,
const double const_yaw);

void update_quaternion(const std::vector<Joint> & current_joints);
void update_quaternion(const keisan::Angle<double> & imu_yaw);
geometry_msgs::msg::TransformStamped get_transform_stamped(const rclcpp::Time & time_stamp);

uint8_t id;

double translation_x;
double translation_y;
double translation_z;

double quaternion_x;
double quaternion_y;
double quaternion_z;
double quaternion_w;

double const_roll;
double const_pitch;
double const_yaw;

private:
enum : uint8_t {
ROLL,
PITCH,
YAW,
};

double get_joint_angle(const uint8_t & quaternion_axis, const std::vector<Joint> & current_joints);
};
} // namespace tachimawari::joint

#endif // TACHIMAWARI__JOINT__TF2__FRAME_HPP_
58 changes: 58 additions & 0 deletions include/tachimawari/joint/tf2/frame_id.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2021-2023 Ichiro ITS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef TACHIMAWARI__JOINT_TF2__FRAME_ID_HPP_
#define TACHIMAWARI__JOINT_TF2__FRAME_ID_HPP_

#include <array>
#include <map>
#include <string>
#include <vector>

namespace tachimawari::joint
{

class FrameId
{
public:
enum : uint8_t {
ODOM,
BASE_LINK,
TORSO,
HEAD,
GAZE,
RIGHT_THIGH,
RIGHT_CALF,
RIGHT_FOOT,
LEFT_THIGH,
LEFT_CALF,
LEFT_FOOT
};

static const std::array<uint8_t, 10> frame_ids;
static const std::map<uint8_t, std::string> frame_id_string;
static const std::map<std::string, uint8_t> frame_string_id;
static const std::map<uint8_t, std::vector<uint8_t>> frame_joint_map;
static const std::map<uint8_t, std::string> parent_frame;
};

} // namespace tachimawari::joint

#endif // TACHIMAWARI__JOINT_TF2__FRAME_ID_HPP_
54 changes: 54 additions & 0 deletions include/tachimawari/joint/tf2/tf2_manager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) 2021-2023 Ichiro ITS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef TACHIMAWARI__JOINT__TF2__TF2_MANAGER_HPP_
#define TACHIMAWARI__JOINT__TF2__TF2_MANAGER_HPP_

#include <memory>
#include <string>
#include <vector>

#include "keisan/angle/angle.hpp"
#include "rclcpp/time.hpp"
#include "tachimawari/joint/model/joint.hpp"
#include "tachimawari/joint/model/joint_id.hpp"
#include "tachimawari/joint/node/joint_manager.hpp"
#include "tachimawari/joint/tf2/frame.hpp"
#include "tachimawari/joint/tf2/frame_id.hpp"
#include "tf2_ros/transform_broadcaster.h"

namespace tachimawari::joint
{

class Tf2Manager
{
public:
explicit Tf2Manager();

bool load_configuration(const std::string & path);
void update(const std::vector<Joint> & current_joints, const keisan::Angle<double> & imu_yaw);
std::vector<Frame> get_frames() { return frames; }

private:
std::vector<Frame> frames;
};
} // namespace tachimawari::joint

#endif // TACHIMAWARI__JOINT__TF2__TF2_MANAGER_HPP_
2 changes: 1 addition & 1 deletion include/tachimawari/node/tachimawari_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class TachimawariNode
explicit TachimawariNode(
rclcpp::Node::SharedPtr node, std::shared_ptr<control::ControlManager> control_manager);

void run_joint_manager();
void run_joint_manager(const std::string & path);

void run_imu_provider();

Expand Down
29 changes: 27 additions & 2 deletions src/tachimawari/joint/node/joint_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,20 @@ std::string JointNode::set_joints_topic() {return get_node_prefix() + "/set_join

std::string JointNode::set_torques_topic() {return get_node_prefix() + "/set_torques";}

std::string JointNode::status_topic() {return "measurement/status";}

std::string JointNode::current_joints_topic() {return get_node_prefix() + "/current_joints";}

JointNode::JointNode(rclcpp::Node::SharedPtr node, std::shared_ptr<JointManager> joint_manager)
: joint_manager(joint_manager), middleware()
JointNode::JointNode(
rclcpp::Node::SharedPtr node, std::shared_ptr<JointManager> joint_manager, const std::string & path)
: joint_manager(joint_manager),
middleware(),
tf2_broadcaster(std::make_shared<tf2_ros::TransformBroadcaster>(node)),
tf2_manager(std::make_shared<Tf2Manager>()),
imu_yaw(keisan::make_degree(0))
{
tf2_manager->load_configuration(path);

control_joints_subscriber = node->create_subscription<ControlJoints>(
control_joints_topic(), 10, [this](const ControlJoints::SharedPtr message) {
this->middleware.set_rules(message->control_type, message->ids);
Expand All @@ -70,6 +79,11 @@ JointNode::JointNode(rclcpp::Node::SharedPtr node, std::shared_ptr<JointManager>
this->joint_manager->torque_enable(joints, message->torque_enable);
});

status_subscriber =
node->create_subscription<Status>(status_topic(), 10, [this](const Status::SharedPtr message) {
imu_yaw = keisan::make_degree(message->orientation.yaw);
});

current_joints_publisher = node->create_publisher<CurrentJoints>(current_joints_topic(), 10);
}

Expand All @@ -90,4 +104,15 @@ void JointNode::publish_current_joints()
current_joints_publisher->publish(msg_joints);
}

void JointNode::publish_frame_tree()
{
const auto & current_joints = this->joint_manager->get_current_joints();
tf2_manager->update(current_joints, imu_yaw);

rclcpp::Time now = rclcpp::Clock().now();
for (auto & frame : tf2_manager->get_frames()) {
tf2_broadcaster->sendTransform(frame.get_transform_stamped(now));
}
}

} // namespace tachimawari::joint
Loading

0 comments on commit de1c57a

Please sign in to comment.