Skip to content

Commit 5cbb1a6

Browse files
iBoot32Purdue RoboMasterpurduerm
authored
Split ControlCommunicatorNode Into xxxNode.cpp and xxx/cpp files (#9)
* add controlcommunicator cpp structure * add gtest and change file name * fix mat initialization (idk lol) * basic structure * work on structure * fix control_comm to build * add building code. set up tests using mocking to replace syscalls * basic uart connection test * port param tests * Got target color subscriber working in OpenCVArmorDetector * Irving said that we have to invert * update msg to get enemy color * fix vars * fix tests * fix tests * add debug and script to run on boot * fix port_fd and add some debug * debug * fix uart connect * print uart read every 500 auto_aim sends * fix startup script * fix enemy targeting color * fix NaN * revert aim model * fix uart if fails to align, and fix coord transform offsets I think * fix large armor threshold and coord transform * change to projectile_angle_convel from trig, add aim on boot, add lookup table * fixes for LUT * fix file pathing to allow lokup table to work, add 2 sec timer to refresh LUT for live tuning * make pitch += LUT, make values not huge * correct yaw/pitch computation --------- Co-authored-by: Purdue RoboMaster <me@purduerm.org> Co-authored-by: purduerm <rmc@purdue.edu>
1 parent 692df4c commit 5cbb1a6

16 files changed

Lines changed: 632 additions & 259 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.vscode/
22
.idea/
3+
log/

aim_on_boot.sh

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/bin/bash
2+
3+
# Automatically get the current user's username
4+
SERVICE_NAME="ros2_aiming_service"
5+
SERVICE_FILE="/etc/systemd/system/$SERVICE_NAME.service"
6+
7+
# Create the auto_aim_logs directory if it doesn't exist
8+
LOG_DIR="/home/purduerm/auto_aim_logs"
9+
mkdir -p "$LOG_DIR"
10+
11+
# Generate the log file name with current timestamp
12+
LOG_FILE="$LOG_DIR/$(date +'%Y-%m-%d_%H-%M-%S')_auto_aim_log.txt"
13+
14+
# Command to run the service
15+
COMMANDS_TO_RUN="source /opt/ros/humble/setup.bash && source /home/purduerm/ros2-ws/install/setup.bash && cd /home/purduerm/ros2-ws && ./auto-aiming/run run mv2control.py > $LOG_FILE 2>&1"
16+
17+
# Function to create the service
18+
create_service() {
19+
echo "Creating the systemd service..."
20+
21+
# Create the systemd service unit file
22+
cat <<EOL | sudo tee $SERVICE_FILE > /dev/null
23+
[Unit]
24+
Description=ROS 2 Auto Aiming Service
25+
After=network.target
26+
27+
[Service]
28+
ExecStart=/bin/bash -c "$COMMANDS_TO_RUN"
29+
WorkingDirectory=/home/purduerm/ros2-ws
30+
User=purduerm
31+
Group=purduerm
32+
Restart=always
33+
Environment=ROS_DISTRO=humble
34+
Environment=HOME=/home/purduerm
35+
36+
[Install]
37+
WantedBy=multi-user.target
38+
EOL
39+
40+
# Reload systemd to recognize the new service
41+
sudo systemctl daemon-reload
42+
}
43+
44+
# Function to enable the service to run on boot
45+
enable_service() {
46+
echo "Enabling the service to start on boot..."
47+
sudo systemctl enable $SERVICE_NAME.service
48+
sudo systemctl start $SERVICE_NAME.service
49+
echo "Service started and enabled."
50+
}
51+
52+
# Function to disable and remove the service
53+
disable_service() {
54+
if [ -f "$SERVICE_FILE" ]; then
55+
echo "Disabling and removing the service..."
56+
sudo systemctl stop $SERVICE_NAME.service
57+
sudo systemctl disable $SERVICE_NAME.service
58+
sudo rm $SERVICE_FILE
59+
sudo systemctl daemon-reload
60+
echo "Service stopped, disabled, and removed."
61+
else
62+
echo "Service does not exist. Nothing to disable."
63+
fi
64+
}
65+
66+
# Parse arguments
67+
if [[ "$1" == "--disable" ]]; then
68+
disable_service
69+
else
70+
# Create and enable the service by default
71+
create_service
72+
enable_service
73+
fi

src/prm_control/control_communicator/CMakeLists.txt

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,10 @@ add_executable(ControlCommunicatorNode
3636
src/ControlCommunicatorNode.cpp
3737
)
3838

39-
40-
# include_directories(controlhandler_node
41-
# PUBLIC
42-
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
43-
# $<INSTALL_INTERFACE:include>
44-
# )
39+
add_library(ControlCommunicator STATIC
40+
src/ControlCommunicator.cpp
41+
src/PitchLookupModel.cpp
42+
)
4543

4644
ament_target_dependencies(ControlCommunicatorNode
4745
rclcpp
@@ -53,7 +51,13 @@ ament_target_dependencies(ControlCommunicatorNode
5351
nav_msgs
5452
)
5553

56-
target_link_libraries(ControlCommunicatorNode Eigen3::Eigen)
54+
# GTest setup
55+
find_package(ament_cmake_gtest REQUIRED)
56+
ament_add_gtest(test_ControlCommunicator test/test_ControlCommunicator.cpp)
57+
target_include_directories(test_ControlCommunicator PRIVATE include)
58+
target_link_libraries(test_ControlCommunicator ControlCommunicator)
59+
target_link_libraries(ControlCommunicatorNode Eigen3::Eigen ControlCommunicator)
60+
ament_target_dependencies(test_ControlCommunicator rclcpp std_msgs geometry_msgs vision_msgs tf2_ros tf2 nav_msgs)
5761

5862
install(TARGETS
5963
ControlCommunicatorNode
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef CONTROL_COMMUNICATOR_HPP
2+
#define CONTROL_COMMUNICATOR_HPP
3+
4+
#include <cmath>
5+
#include <fcntl.h>
6+
#include <termios.h>
7+
#include <unistd.h>
8+
#include <cstring>
9+
#include "PitchLookupModel.hpp"
10+
11+
class ControlCommunicator
12+
{
13+
public:
14+
ControlCommunicator() {}
15+
~ControlCommunicator() {}
16+
17+
// Class methods
18+
void compute_aim(float bullet_speed, float target_x, float target_y, float target_z, float &yaw, float &pitch);
19+
bool start_uart_connection(const char *port);
20+
void read_uart();
21+
22+
PitchLookupModel *lut = new PitchLookupModel("/home/purduerm/ros2-ws/auto-aiming/src/prm_control/control_communicator/include/lookup_tables/pitch_lookup_table.txt");
23+
24+
int port_fd = -1;
25+
bool is_connected = false;
26+
private:
27+
};
28+
29+
#endif // CONTROL_COMMUNICATOR_HPP
Lines changed: 41 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,75 @@
1+
#ifndef CONTROL_COMMUNICATOR_NODE_HPP
2+
#define CONTROL_COMMUNICATOR_NODE_HPP
13

2-
#ifndef _CONTROL_COMMUNICATOR_NODE_H
3-
#define _CONTROL_COMMUNICATOR_NODE_H
4-
5-
#include <chrono>
6-
#include <functional>
7-
#include <memory>
8-
#include <string>
9-
#include <Eigen/Dense>
10-
#include <math.h>
4+
#include "rclcpp/rclcpp.hpp"
115

12-
#include <errno.h> // Error integer and strerror() function
6+
#include "vision_msgs/msg/predicted_armor.hpp"
7+
#include "geometry_msgs/msg/twist.hpp"
8+
#include "nav_msgs/msg/odometry.hpp"
9+
#include "vision_msgs/msg/yaw_pitch.hpp"
10+
#include "messages.h"
1311

14-
#include "rclcpp/rclcpp.hpp"
15-
#include "rclcpp/logger.hpp"
1612
#include "std_msgs/msg/string.hpp"
1713
#include "std_msgs/msg/bool.hpp"
18-
#include "std_msgs/msg/float64.hpp"
19-
#include "geometry_msgs/msg/pose.hpp"
20-
#include "geometry_msgs/msg/transform_stamped.hpp"
21-
#include <geometry_msgs/msg/twist_stamped.hpp>
22-
23-
#include "geometry_msgs/msg/transform_stamped.hpp"
24-
#include "tf2_ros/static_transform_broadcaster.h"
2514
#include "tf2_ros/transform_broadcaster.h"
26-
#include "tf2/LinearMath/Quaternion.h"
27-
#include "tf2/LinearMath/Matrix3x3.h"
15+
#include "tf2_ros/static_transform_broadcaster.h"
16+
#include "tf2/transform_datatypes.h"
2817
#include "tf2_ros/transform_listener.h"
2918
#include "tf2_ros/buffer.h"
3019

31-
#include "projectile_angle_convel.h"
32-
33-
#include "vision_msgs/msg/yaw_pitch.hpp"
34-
#include "vision_msgs/msg/predicted_armor.hpp"
35-
#include "nav_msgs/msg/odometry.hpp"
36-
#include "messages.h"
20+
#include <memory>
21+
#include <functional>
22+
#include <string>
23+
#include <chrono>
3724

38-
// using namespace std::chrono_literals;
39-
// using namespace std::placeholders;
40-
// namespace rmoss_msgs = rmoss_interfaces::msg;
25+
#include "ControlCommunicator.h"
4126

4227
class ControlCommunicatorNode : public rclcpp::Node
4328
{
4429
public:
4530
ControlCommunicatorNode(const char *port);
46-
4731
~ControlCommunicatorNode();
4832

33+
ControlCommunicator *control_communicator = new ControlCommunicator();
34+
35+
void auto_aim_handler(const std::shared_ptr<vision_msgs::msg::PredictedArmor> msg);
36+
void nav_handler(const std::shared_ptr<geometry_msgs::msg::Twist> msg);
37+
void read_uart();
38+
4939
private:
40+
void publish_static_tf(float x, float y, float z, float roll, float pitch, float yaw, const char *frame_id, const char *child_frame_id);
41+
void heart_beat_handler();
42+
43+
uint32_t auto_aim_frame_id = 0;
44+
uint32_t nav_frame_id = 0;
45+
uint32_t heart_beat_frame_id = 0;
46+
47+
// Read UART results
5048
float yaw_vel = 0; // rad/s (+ccw, -cw)
5149
float pitch_vel = 0; // rad/s
5250
float pitch = 0; // rad (+up, -down)?
53-
bool is_red = 0;
51+
bool is_enemy_red = 0;
5452
bool is_match_running = 0;
5553
bool valid_read = false;
56-
57-
uint32_t recive_frame_id = 0;
54+
std::string old_target_robot_color;
5855

5956
const char *port;
60-
int port_fd = -1;
61-
bool is_connected = false;
62-
63-
uint32_t auto_aim_frame_id = 0;
64-
uint32_t nav_frame_id = 0;
65-
uint32_t heart_beat_frame_id = 0;
6657

58+
bool is_connected;
59+
float aim_bullet_speed;
6760
int aim_stop_null_frame_count;
68-
int aim_null_frame_count = 0;
69-
70-
float aim_bullet_speed; // mm/s
71-
72-
int8_t curr_pois = 0;
73-
bool right = true;
74-
75-
std::unique_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster;
76-
std::shared_ptr<tf2_ros::StaticTransformBroadcaster> tf_static_broadcaster;
77-
std::unique_ptr<tf2_ros::Buffer> tf_buffer;
78-
std::shared_ptr<tf2_ros::TransformListener> tf_listener;
7961

62+
rclcpp::TimerBase::SharedPtr heart_beat_timer;
8063
rclcpp::Subscription<vision_msgs::msg::PredictedArmor>::SharedPtr auto_aim_subscriber;
8164
rclcpp::Subscription<geometry_msgs::msg::Twist>::SharedPtr nav_subscriber;
82-
8365
rclcpp::Publisher<nav_msgs::msg::Odometry>::SharedPtr odometry_publisher;
84-
std::shared_ptr<rclcpp::Publisher<std_msgs::msg::String>> target_robot_color_publisher = NULL;
85-
std::shared_ptr<rclcpp::Publisher<std_msgs::msg::Bool>> match_status_publisher = NULL;
86-
87-
66+
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr target_robot_color_publisher;
67+
rclcpp::Publisher<std_msgs::msg::Bool>::SharedPtr match_status_publisher;
8868
rclcpp::TimerBase::SharedPtr uart_read_timer;
89-
rclcpp::TimerBase::SharedPtr heart_beat_timer;
90-
91-
bool start_uart(const char *port);
92-
93-
void publish_static_tf(float, float, float, float, float, float, const char *, const char *);
94-
95-
void auto_aim_handler(const std::shared_ptr<vision_msgs::msg::PredictedArmor> msg);
96-
void nav_handler(const std::shared_ptr<geometry_msgs::msg::Twist> msg);
97-
void heart_beat_handler();
9869

99-
void read_uart();
70+
std::unique_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster;
71+
std::shared_ptr<tf2_ros::StaticTransformBroadcaster> tf_static_broadcaster;
72+
std::unique_ptr<tf2_ros::Buffer> tf_buffer;
73+
std::shared_ptr<tf2_ros::TransformListener> tf_listener;
10074
};
101-
102-
#endif // CONTROL_COMMUNICATOR_NODE_H
75+
#endif // CONTROL_COMMUNICATOR_NODE_HPP
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifndef PITCH_LOOKUP_MODEL_HPP
2+
#define PITCH_LOOKUP_MODEL_HPP
3+
4+
#include <climits>
5+
#include <iostream>
6+
#include <vector>
7+
#include <cmath>
8+
#include <cassert>
9+
#include <string>
10+
#include <thread>
11+
12+
class PitchLookupModel {
13+
public:
14+
PitchLookupModel();
15+
explicit PitchLookupModel(std::string filename);
16+
17+
int load_file();
18+
void write_file();
19+
float get_pitch(int distance, int height);
20+
21+
private:
22+
int lower_y = INT_MAX;
23+
int lower_z = INT_MAX;
24+
int upper_y = INT_MIN;
25+
int upper_z = INT_MIN;
26+
std::string filename;
27+
std::vector<std::vector<float>> pitch_lookup_table;
28+
std::thread timer;
29+
30+
float map(float value, float old_min, float old_max, float new_min, float new_max);
31+
};
32+
33+
#endif // PITCH_LOOKUP_MODEL_HPP
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
3 3
2+
500 0 1.44968
3+
1000 0 2.44968
4+
1500 0 3.44968
5+
2000 200 4.76067
6+
2500 0 5.44968
7+
3000 0 6.44968
8+
3500 0 7.44968
9+
4000 200 8.76067
10+
4500 0 9.44968

src/prm_control/control_communicator/include/projectile_angle_convel.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
#ifndef PROJECTILE_ANGLE_CONVEL_H
2+
#define PROJECTILE_ANGLE_CONVEL_H
13

24
#include <iostream>
35
#include <complex>
46
#include <algorithm>
57
#include <cmath>
68

7-
#define MUZZLE_VELOCITY 30.00
9+
#define MUZZLE_VELOCITY 25000
810
#define SHOT_IMPOSSIBLE -100
911
#define PI 3.14159
1012
#define RAD_2_DEG 180/PI
@@ -187,3 +189,4 @@ void pitch_yaw_gravity_model_movingtarget_const_v(vec3 Pos, vec3 Vel, vec3 G, do
187189
*pitch = *pitch * RAD_2_DEG;
188190
*yaw = *yaw * RAD_2_DEG;
189191
}
192+
#endif // PROJECTILE_ANGLE_CONVEL_H

0 commit comments

Comments
 (0)