Skip to content
This repository was archived by the owner on Mar 2, 2023. It is now read-only.

Commit d3cd7a1

Browse files
committed
ros2 table tennis
1 parent d1cf2cb commit d3cd7a1

File tree

3 files changed

+179
-0
lines changed

3 files changed

+179
-0
lines changed

ros2/ros2_contestant/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,25 @@ ament_target_dependencies(ping rclcpp)
4040
rosidl_target_interfaces(ping
4141
${PROJECT_NAME} rosidl_typesupport_cpp)
4242

43+
add_executable(table_tennis_receiver table_tennis_receiver.cpp)
44+
ament_target_dependencies(table_tennis_receiver rclcpp)
45+
rosidl_target_interfaces(table_tennis_receiver
46+
${PROJECT_NAME} rosidl_typesupport_cpp)
47+
48+
add_executable(table_tennis_server table_tennis_server.cpp)
49+
ament_target_dependencies(table_tennis_server rclcpp)
50+
rosidl_target_interfaces(table_tennis_server
51+
${PROJECT_NAME} rosidl_typesupport_cpp)
52+
4353
ament_export_dependencies(rosidl_default_runtime)
4454

4555
install(TARGETS
4656
publisher
4757
subscriber
4858
echo
4959
ping
60+
table_tennis_receiver
61+
table_tennis_server
5062
DESTINATION lib/${PROJECT_NAME})
5163

5264
ament_package()
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include <memory>
2+
#include <vector>
3+
4+
#include "rclcpp/rclcpp.hpp"
5+
#include "ros2_contestant/msg/stamped_blob.hpp"
6+
using std::placeholders::_1;
7+
8+
class ReceiverNode : public rclcpp::Node
9+
{
10+
public:
11+
rclcpp::Subscription<ros2_contestant::msg::StampedBlob>::SharedPtr sub;
12+
rclcpp::Publisher<ros2_contestant::msg::StampedBlob>::SharedPtr pub;
13+
14+
ReceiverNode()
15+
: Node("table_tennis_receiver")
16+
{
17+
sub = create_subscription<ros2_contestant::msg::StampedBlob>(
18+
"echo_in", 10, std::bind(&ReceiverNode::callback, this, _1));
19+
20+
pub = create_publisher<ros2_contestant::msg::StampedBlob>("echo_out", 10);
21+
}
22+
23+
void callback(const ros2_contestant::msg::StampedBlob::SharedPtr msg)
24+
{
25+
pub->publish(*msg);
26+
}
27+
};
28+
29+
int main(int argc, char **argv)
30+
{
31+
rclcpp::init(argc, argv);
32+
rclcpp::spin(std::make_shared<ReceiverNode>());
33+
rclcpp::shutdown();
34+
return 0;
35+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include <memory>
2+
#include <vector>
3+
4+
#include "rclcpp/rclcpp.hpp"
5+
#include "ros2_contestant/msg/stamped_blob.hpp"
6+
using std::placeholders::_1;
7+
8+
class ServerNode : public rclcpp::Node
9+
{
10+
public:
11+
ros2_contestant::msg::StampedBlob tx_msg;
12+
13+
rclcpp::Publisher<ros2_contestant::msg::StampedBlob>::SharedPtr pub;
14+
rclcpp::Subscription<ros2_contestant::msg::StampedBlob>::SharedPtr sub;
15+
16+
rclcpp::TimerBase::SharedPtr timer;
17+
18+
rclcpp::Time t_start, t_last_serve;
19+
20+
uint64_t last_rx_counter = 0, last_tx_counter = 0;
21+
int max_message_count = 0;
22+
double startup_delay = 0;
23+
bool verbose = false;
24+
FILE *log = nullptr;
25+
const int MAX_BLOB_SIZE = 10000000;
26+
bool ball_returned = false;
27+
28+
ServerNode();
29+
void msg_cb(const ros2_contestant::msg::StampedBlob::SharedPtr msg);
30+
void timer_cb();
31+
void serve();
32+
};
33+
34+
ServerNode::ServerNode()
35+
: Node("table_tennis_server")
36+
{
37+
declare_parameter<bool>("verbose", false);
38+
get_parameter("verbose", verbose);
39+
40+
declare_parameter<int>("max_message_count", 0);
41+
get_parameter("max_message_count", max_message_count);
42+
43+
srandom(0);
44+
for (int i = 0; i < MAX_BLOB_SIZE; i++)
45+
tx_msg.blob.push_back(random() % 256);
46+
47+
sub = create_subscription<ros2_contestant::msg::StampedBlob>(
48+
"ball_return",
49+
10,
50+
std::bind(&ServerNode::msg_cb, this, _1));
51+
52+
pub = create_publisher<ros2_contestant::msg::StampedBlob>(
53+
"ball_serve",
54+
10);
55+
56+
declare_parameter<double>("startup_delay", 1.0);
57+
get_parameter("startup_delay", startup_delay);
58+
59+
t_start = get_clock()->now();
60+
t_last_serve = get_clock()->now();
61+
62+
timer = create_wall_timer(
63+
std::chrono::milliseconds(1),
64+
std::bind(&ServerNode::timer_cb, this));
65+
}
66+
67+
void ServerNode::msg_cb(
68+
const ros2_contestant::msg::StampedBlob::SharedPtr rx_msg)
69+
{
70+
const double latency = (get_clock()->now() - rx_msg->stamp).seconds();
71+
72+
if (rx_msg->counter == last_tx_counter)
73+
{
74+
fprintf(log, "%d,%.6f\n", (int)rx_msg->blob.size(), latency);
75+
ball_returned = true;
76+
}
77+
last_rx_counter = rx_msg->counter;
78+
79+
if (verbose)
80+
RCLCPP_INFO(get_logger(), "latency: %.6f", latency);
81+
}
82+
83+
void ServerNode::serve()
84+
{
85+
tx_msg.counter++;
86+
tx_msg.stamp = get_clock()->now();
87+
pub->publish(tx_msg);
88+
89+
last_tx_counter = tx_msg.counter;
90+
t_last_serve = get_clock()->now();
91+
}
92+
93+
void ServerNode::timer_cb()
94+
{
95+
const rclcpp::Time t(get_clock()->now());
96+
if ((t - t_start).seconds() < startup_delay)
97+
return;
98+
99+
// if we haven't received the ball back, assume it got lost
100+
if ((t - t_last_serve).seconds() > 1.0)
101+
{
102+
fprintf(log, "%d,10.0\n", (int)tx_msg.blob.size());
103+
104+
if (verbose)
105+
{
106+
RCLCPP_ERROR(
107+
get_logger(),
108+
"didn't get a response to %d-byte blob",
109+
(int)tx_msg.blob.size());
110+
}
111+
112+
serve();
113+
}
114+
else if (ball_returned)
115+
{
116+
serve();
117+
}
118+
119+
if (max_message_count && tx_msg.counter > (uint64_t)max_message_count)
120+
{
121+
RCLCPP_INFO(get_logger(), "shutting down...");
122+
rclcpp::shutdown();
123+
}
124+
}
125+
126+
int main(int argc, char **argv)
127+
{
128+
rclcpp::init(argc, argv);
129+
rclcpp::spin(std::make_shared<ServerNode>());
130+
rclcpp::shutdown();
131+
return 0;
132+
}

0 commit comments

Comments
 (0)