ROS2 clock stuck within inhereted class
Hello everyone, my clock always stuck at the moment the node start for the following code. I mimic the coding style of the demo talker node. Am I doing anything wrong?
#include <chrono>
#include "rclcpp/rclcpp.hpp"
#include "rclcpp/clock.hpp"
void xNode::timer_callback()
{
// do something here
rclcpp::TimeSource ts(shared_from_this());
rclcpp::Clock::SharedPtr clk2 = std::make_shared<rclcpp::Clock>(RCL_ROS_TIME);
ts.attachClock(clk2);
rclcpp::Clock clk3;//
if(conditions)
{
// stuck at node start time
RCLCPP_INFO(this->get_logger(), "CONTACT!!! time: %ld", clk2->now());
RCLCPP_INFO(this->get_logger(), "CONTACT!!! time: %ld", clk3.now());
}
return;
}
//====== Constructor ======//
xNode() : Node("node_name")
{
subscription_ = this->create_subscription<std_msgs::msg::String>(
"topic_sub", std::bind(&xNode::topic_callback, this, _1),
rmw_qos_profile_sensor_data);
timer_ = this->create_wall_timer(10ms, std::bind(&xNode::timer_callback, this));
}
Main:
int main(int argc, char *argv[])
{
rclcpp::init(argc, argv);
auto node = std::make_shared<xNode>();
rclcpp::spin(node);
printf("stop");
node.reset(); // calling destructor through shared_ptr
rclcpp::shutdown();
return 0;
}
You have my appreciation for any advice!
Edit: minimum file:
#include <stdio.h>
#include <chrono>
#include "rclcpp/rclcpp.hpp"
#include "rclcpp/clock.hpp"
#include "rclcpp/time_source.hpp"
#include "std_msgs/msg/string.hpp"
#define TOPIC_CMD "string_cmd"
using namespace std::chrono_literals;
using std::placeholders::_1;
class OmniTestNode : public rclcpp::Node
{
private:
//rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
rclcpp::TimerBase::SharedPtr timer_;
void topic_callback(const std_msgs::msg::String::SharedPtr msg)
{
// Print the received message
printf("------- Topic <\"%s\">: \"%s\" recieved.\n", TOPIC_CMD, msg->data.c_str());
return;
}
void timer_callback()
{
rclcpp::TimeSource ts(shared_from_this());
rclcpp::Clock::SharedPtr clk2 = std::make_shared<rclcpp::Clock>(RCL_ROS_TIME);
ts.attachClock(clk2);
rclcpp::Clock clk3;
RCLCPP_INFO(this->get_logger(), "clk2 time: %ld", clk2->now());
RCLCPP_INFO(this->get_logger(), "clk3 time: %ld", clk3.now());
RCLCPP_INFO(this->get_logger(), "this->now time: %ld", this->now());
RCLCPP_INFO(this->get_logger(), "CONTACT!!! time: %ld", std::chrono::system_clock::now());
return;
}
public:
rclcpp::Clock::SharedPtr clock_;
//====== Constructor ======//
explicit OmniTestNode() : Node("test_io")
{
//publisher_ = this->create_publisher<std_msgs::msg::String>(
// TOPIC_DATA, rmw_qos_profile_sensor_data);
subscription_ = this->create_subscription<std_msgs::msg::String>(
TOPIC_CMD, std::bind(&OmniTestNode::topic_callback, this, _1),
rmw_qos_profile_sensor_data);
timer_ = this->create_wall_timer(1000ms, std::bind(&OmniTestNode::timer_callback, this));
clock_ = std::make_shared<rclcpp::Clock>(RCL_ROS_TIME);
//ts_ = std::make_shared<rclcpp::TimeSource>(shared_from_this());
//ts_ = rclcpp::TimeSource(this);
}
//====== Destructor ======//
virtual ~OmniTestNode()
{
printf("Node shutting down, reset all GPIOs");
}
};
int main(int argc, char *argv[])
{
rclcpp::init(argc, argv);
auto node = std::make_shared<OmniTestNode>();
printf("spin");
rclcpp::spin(node);
printf("stop");
node.reset();
rclcpp::shutdown();
return 0;
}
output:
[INFO] [test_io]: clk2 time: 140729497633152
[INFO] [test_io]: clk3 time: 140729497633184
[INFO] [test_io]: this->now time: 140729497633216
[INFO] [test_io]: CONTACT!!! time: 1523415521337332304
[INFO] [test_io]: clk2 time: 140729497633152
[INFO] [test_io]: clk3 time: 140729497633184
[INFO] [test_io]: this->now time: 140729497633216
[INFO] [test_io]: CONTACT!!! time: 1523415522337518648
[INFO] [test_io]: clk2 time: 140729497633152
[INFO] [test_io]: clk3 time: 140729497633184
[INFO] [test_io]: this->now time: 140729497633216
[INFO] [test_io]: CONTACT!!! time: 1523415523338464997
What's the output you're getting and what is the output you expect?
clk2
will use the ROS time, and clk3 will default to system time, but unless you turn on sim time they will always be the same. Each call to the timer callback should produce a different timestamp, however.Also you can do
this->now()
rather than creating your own time source and clock and stuff.Hi @William,
this->now()
acted as same as clk2/clk3, it stucked at something like "CONTACT!!! time: 140735253311824" no matter how many time I called the function. Callingstd::chrono::system_clock::now()
gives the correct, advancing value like "1523409062194556622"Also, because this node need to access some motherboard stuff, I'm running ros2 under root access. I.e. executing after
sudo -sE
That's odd, I suppose it could be an issue with ROS time, can you narrow it down to a simpler program? Ideally just a single file that causes the issue? I don't think sudo should affect it.
@William, I've posted a one-file node that's still having this issue, thanks.