-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #59 from ros-realtime/feature/exercise4-2-update
update exercise4-2
- Loading branch information
Showing
12 changed files
with
194 additions
and
41 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
#include "application_nodes.h" | ||
#include <cstdlib> | ||
#include <chrono> | ||
#include <list> | ||
#include <memory> | ||
#include <string> | ||
#include <thread> | ||
#include <vector> | ||
|
||
#include "utils.h" | ||
|
||
using cactus_rt::tracing::ThreadTracer; | ||
using camera_demo_interfaces::msg::FakeImage; | ||
|
||
CameraProcessingNode::CameraProcessingNode( | ||
std::shared_ptr<ThreadTracer> tracer_object_detector, | ||
std::shared_ptr<ThreadTracer> tracer_data_logger | ||
) : Node("obj_detect"), tracer_object_detector_(tracer_object_detector), tracer_data_logger_(tracer_data_logger) { | ||
realtime_group_ = this->create_callback_group( | ||
rclcpp::CallbackGroupType::MutuallyExclusive | ||
); | ||
besteffort_group_ = this->create_callback_group( | ||
rclcpp::CallbackGroupType::MutuallyExclusive | ||
); | ||
|
||
rclcpp::SubscriptionOptions data_logging_options; | ||
data_logging_options.callback_group = besteffort_group_; | ||
subscription_data_logger_ = this->create_subscription<FakeImage>( | ||
"/image", | ||
10, | ||
std::bind(&CameraProcessingNode::DataLoggerCallback, this, std::placeholders::_1), | ||
data_logging_options | ||
); | ||
|
||
rclcpp::SubscriptionOptions obj_det_options; | ||
obj_det_options.callback_group = realtime_group_; | ||
subscription_object_detector_ = this->create_subscription<FakeImage>( | ||
"/image", | ||
10, | ||
std::bind(&CameraProcessingNode::ObjectDetectorCallback, this, std::placeholders::_1), | ||
obj_det_options | ||
); | ||
|
||
publisher_ = this->create_publisher<std_msgs::msg::Int64>("/actuation", 10); | ||
|
||
// initialization of random variable for DataLogger latency | ||
srand((unsigned)time(NULL)); | ||
} | ||
|
||
void CameraProcessingNode::ObjectDetectorCallback(const FakeImage::SharedPtr image) { | ||
// A hack to trace the message passing delay between publisher and this node | ||
auto now = cactus_rt::NowNs(); | ||
tracer_object_detector_->StartSpan("MessageDelay", nullptr, image->published_at_monotonic_nanos); | ||
tracer_object_detector_->EndSpan(now); | ||
|
||
{ | ||
auto span = tracer_object_detector_->WithSpan("ObjectDetect"); | ||
|
||
WasteTime(std::chrono::microseconds(3000)); | ||
|
||
// Send a signal to the downstream actuation node | ||
std_msgs::msg::Int64 msg; | ||
msg.data = image->published_at_monotonic_nanos; | ||
publisher_->publish(msg); | ||
} | ||
} | ||
|
||
void CameraProcessingNode::DataLoggerCallback(const FakeImage::SharedPtr image) { | ||
// A hack to trace the message passing delay between publisher and this node | ||
auto now = cactus_rt::NowNs(); | ||
tracer_data_logger_->StartSpan("MessageDelay", nullptr, image->published_at_monotonic_nanos); | ||
tracer_data_logger_->EndSpan(now); | ||
|
||
{ | ||
auto span = tracer_data_logger_->WithSpan("DataLogger"); | ||
|
||
// variable duration to serialize the data between [5ms,10ms] | ||
unsigned int data_logger_latency = 5000 + (rand() % 5001); | ||
WasteTime(std::chrono::microseconds(data_logger_latency)); | ||
|
||
// Assume it takes about 1ms to write the data where it is blocking but yielded to the CPU. | ||
std::this_thread::sleep_for(std::chrono::microseconds(1000)); | ||
} | ||
} | ||
|
||
rclcpp::CallbackGroup::SharedPtr CameraProcessingNode::get_realtime_cbg() { | ||
if (!realtime_group_) { | ||
realtime_group_ = this->create_callback_group( | ||
rclcpp::CallbackGroupType::MutuallyExclusive | ||
); | ||
} | ||
return realtime_group_; | ||
} | ||
|
||
rclcpp::CallbackGroup::SharedPtr CameraProcessingNode::get_besteffort_cbg() { | ||
if (!besteffort_group_) { | ||
besteffort_group_ = this->create_callback_group( | ||
rclcpp::CallbackGroupType::MutuallyExclusive | ||
); | ||
} | ||
return besteffort_group_; | ||
} | ||
|
||
ActuationNode::ActuationNode( | ||
std::shared_ptr<cactus_rt::tracing::ThreadTracer> tracer | ||
) : Node("actuation"), tracer_(tracer) { | ||
subscription_ = this->create_subscription<std_msgs::msg::Int64>( | ||
"/actuation", | ||
10, | ||
std::bind(&ActuationNode::MessageCallback, this, std::placeholders::_1) | ||
); | ||
} | ||
|
||
void ActuationNode::MessageCallback(const std_msgs::msg::Int64::SharedPtr published_at_timestamp) { | ||
auto now = cactus_rt::NowNs(); | ||
|
||
// A hack to show the end to end latency, from the moment it was published to | ||
// the moment it is received by this node. | ||
tracer_->StartSpan("EndToEndDelay", nullptr, published_at_timestamp->data); | ||
tracer_->EndSpan(now); | ||
|
||
{ | ||
auto span = tracer_->WithSpan("Actuation"); | ||
WasteTime(std::chrono::microseconds(150)); | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#include <rclcpp/rclcpp.hpp> | ||
|
||
#include "application_nodes.h" | ||
#include "system_nodes.h" | ||
#include "tracing.h" | ||
|
||
int main(int argc, char** argv) { | ||
// initialization of ROS and DDS middleware | ||
rclcpp::init(argc, argv); | ||
|
||
StartImagePublisherNode(); | ||
|
||
auto actuation_tracer = std::make_shared<cactus_rt::tracing::ThreadTracer>("actuation"); | ||
auto actuation_node = std::make_shared<ActuationNode>(actuation_tracer); | ||
|
||
auto object_detector_tracer = std::make_shared<cactus_rt::tracing::ThreadTracer>("object_detector_callback"); | ||
auto data_logger_tracer = std::make_shared<cactus_rt::tracing::ThreadTracer>("data_logger_callback"); | ||
auto camera_processing_node = std::make_shared<CameraProcessingNode>(object_detector_tracer, data_logger_tracer); | ||
auto data_logger_group = camera_processing_node->get_besteffort_cbg(); | ||
auto object_detector_group = camera_processing_node->get_realtime_cbg(); | ||
|
||
StartTracing("camera_demo_4_2", "exercise4-2.perfetto"); | ||
RegisterThreadTracer(actuation_tracer); | ||
RegisterThreadTracer(object_detector_tracer); | ||
RegisterThreadTracer(data_logger_tracer); | ||
|
||
rclcpp::executors::SingleThreadedExecutor real_time_executor; | ||
rclcpp::executors::SingleThreadedExecutor best_effort_executor; | ||
|
||
best_effort_executor.add_callback_group(data_logger_group, camera_processing_node->get_node_base_interface()); | ||
real_time_executor.add_callback_group(object_detector_group, camera_processing_node->get_node_base_interface()); | ||
real_time_executor.add_node(actuation_node); | ||
|
||
// Launch real-time Executor in a thread | ||
std::thread real_time_thread([&real_time_executor]() { | ||
sched_param sch; | ||
sch.sched_priority = 60; | ||
if (sched_setscheduler(0, SCHED_FIFO, &sch) == -1) { | ||
perror("sched_setscheduler failed"); | ||
exit(-1); | ||
} | ||
real_time_executor.spin(); | ||
}); | ||
|
||
best_effort_executor.spin(); | ||
|
||
rclcpp::shutdown(); | ||
StopTracing(); | ||
|
||
JoinImagePublisherNode(); | ||
real_time_thread.join(); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters