-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpath_copycat.cpp
More file actions
105 lines (88 loc) · 3.36 KB
/
path_copycat.cpp
File metadata and controls
105 lines (88 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* * * * * * * * * * * * * * * * * * * * * * * * *
* Path Copycat (path_copycat.cpp)
* Sabrina Button (sabrina.button@queensu.ca)
* aQuatonomous 2024-2025
* * * * * * * * * * * * * * * * * * * * * * * * */
#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
using namespace std::chrono_literals;
/*
This node reads from the joypad. If the 'start' button is pressed, the node will begin
saving movement commands to a file. When the 'start' button is pushed again, it will stop recording.
If the 'X' button is pressed, it will write the commands to the joypad topic, mimicking the
previous movement path.
*/
class PathCopycat : public rclcpp::Node
{
public:
PathCopycat()
: Node("path_copycat"), count_(0)
{
subscription_ = this->create_subscription<std_msgs::msg::String>(
"joypad", 10, std::bind(&PathCopycat::recieve_controls, this, _1));
publisher_ = this->create_publisher<std_msgs::msg::String>("joypad", 10);
// Attempt to transmit the path every 50ms
timer_ = this->create_wall_timer(
50ms, std::bind(&PathCopycat::transmit_path, this));
float base_rec_timestamp = std::chrono::system_clock::now();
float base_trans_timestamp = std::chrono::system_clock::now();
int trans_index = 0;
bool recording = false;
bool transmitting = false;
}
private:
void recieve_controls(const std_msgs::msg::String::SharedPtr msg) const
{
// TODO(sbutton): Change this to use the joypad data structure
if (msg->data == "start" && !recording)
{
base_rec_timestamp = std::chrono::system_clock::now();
recording = !recording;
RCLCPP_INFO(this->get_logger(), "Toggled recording to " + std::to_string(recording));
}
else if (msg->data == "X" && !transmitting)
{
base_trans_timestamp = std::chrono::system_clock::now();
transmitting = !transmitting;
RCLCPP_INFO(this->get_logger(), "Toggled transmission to " + std::to_string(transmitting);
}
if (recording)
{
// Zero the timestamp according to the base
msg->data.timestamp = std::chrono::system_clock::now() - base_rec_timestamp;
// Write the message to the file
with open("saved_path.txt", "w") as file : file.write(msg->data);
}
}
/*
Transmit the path to the joypad topic using the saved path timestamps.
*/
void transmit_path()
{
if (transmitting)
{
// Read the file
with open("saved_path.txt", "r") as file : path = file.read();
// Get the time since the last transmission
float delta = std::chrono::system_clock::now() - base_trans_timestamp;
// If delta is greater than the timestamp of the next message, send the message
while (delta > path[trans_index].timestamp)
{
publisher_->publish(path[trans_index]);
trans_index++;
}
}
}
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};
int main(int argc, char *argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalPublisher>());
rclcpp::shutdown();
return 0;
}