Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion install/setup.bash
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null
_colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash"

unset COLCON_CURRENT_PREFIX
unset _colcon_prefix_chain_bash_source_script
unset _colcon_prefix_chain_bash_source_script
2 changes: 1 addition & 1 deletion install/setup.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ COLCON_CURRENT_PREFIX="$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && p
_colcon_prefix_chain_zsh_source_script "$COLCON_CURRENT_PREFIX/local_setup.zsh"

unset COLCON_CURRENT_PREFIX
unset _colcon_prefix_chain_zsh_source_script
unset _colcon_prefix_chain_zsh_source_script
7 changes: 7 additions & 0 deletions launch/soccer.launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,13 @@ def generate_launch_description():
output="screen",
parameters=[param_config_filepath],
on_exit=Shutdown(),
),
Node(
package="rj_strategy",
executable="waller_node",
output="screen",
parameters=[param_config_filepath],
on_exit=Shutdown(),
)
]
)
2 changes: 2 additions & 0 deletions src/rj_msgs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ rosidl_generate_interfaces(

# Coordinators
msg/KickerPicker.msg
msg/Waller.msg

# Agent Request Messages
request/JoinWallRequest.msg
Expand All @@ -84,6 +85,7 @@ rosidl_generate_interfaces(
# Services
srv/AgentCommunication.srv
srv/KickerPicker.srv
srv/Waller.srv
srv/ListJoysticks.srv
srv/PlanHypotheticalPath.srv
srv/QuickCommands.srv
Expand Down
3 changes: 3 additions & 0 deletions src/rj_msgs/msg/Waller.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# This is a message for the waller coordinator
uint8[16] wall_list # Sorted IDs of robots on the wall
uint8 wall_size # Number of robots on the wall
5 changes: 5 additions & 0 deletions src/rj_msgs/srv/Waller.srv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Request a robot to be added to or removed from the waller selection group
uint8 robot_id # ID of the robot (0 to kNumShells-1)
bool joining # True to add robot to waller group, false to remove it
---
bool success # True if the ACTION succeded (True for joining means successfully joined, for leaving means successfully left)
21 changes: 19 additions & 2 deletions src/rj_strategy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ set(RJ_STRATEGY_SRC
src/agent/position/seeker.cpp
src/agent/position/smartidling.cpp
src/agent/position/solo_offense.cpp
src/agent/position/waller.cpp
src/agent/position/zoner.cpp

# Communication
src/agent/communication.cpp

# Coordinators
src/coordinator/kicker_picker_client.cpp
src/coordinator/waller_client.cpp
)

# rj_strategy library
Expand Down Expand Up @@ -115,6 +115,23 @@ ament_target_dependencies(kicker_picker_node
${RJ_STRATEGY_DEPS}
)

# Waller Node
add_executable(waller_node
${RJ_STRATEGY_SRC}
src/coordinator/waller_client.cpp
src/coordinator/waller.cpp
)

target_include_directories(waller_node
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

ament_target_dependencies(waller_node
${RJ_STRATEGY_DEPS}
)

# Agent Action Clients
add_executable(agent_action_clients
${RJ_STRATEGY_SRC}
Expand Down Expand Up @@ -146,7 +163,7 @@ install(
)

install(
TARGETS straight_line_test_node kicker_picker_node agent_action_clients
TARGETS straight_line_test_node kicker_picker_node waller_node agent_action_clients
DESTINATION lib/${PROJECT_NAME}
)

Expand Down
2 changes: 2 additions & 0 deletions src/rj_strategy/include/rj_strategy/agent/position.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

// Coordinators
#include "rj_strategy/coordinator/kicker_picker_client.hpp"
#include "rj_strategy/coordinator/waller_client.hpp"

// tell compiler this class exists, but no need to import the whole header
class AgentActionClient;
Expand All @@ -51,6 +52,7 @@ namespace strategy {
// Client Handles for coordinators
struct ClientHandles {
std::unique_ptr<KickerPickerClient> kicker_picker;
std::unique_ptr<WallerClient> waller;
};

/*
Expand Down
48 changes: 1 addition & 47 deletions src/rj_strategy/include/rj_strategy/agent/position/defense.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

#include "rj_strategy/agent/position.hpp"
#include "rj_strategy/agent/position/marker.hpp"
#include "rj_strategy/agent/position/waller.hpp"

namespace strategy {

Expand Down Expand Up @@ -72,54 +71,9 @@ class Defense : public Position {
};

State update_state();

State current_state_ = IDLING;
std::optional<RobotIntent> state_to_task(RobotIntent intent);

/**
* @brief Sends a JoinWallRequest in broadcast to the other robots
*/
void send_join_wall_request();

/**
* @brief Sends a LeaveWallRequest to each of the robots in walling_robots_.
*/
void send_leave_wall_request();

/**
* @brief Adds the new waller to this robot's list of wallers and updates this robot's position
* in the wall.
*
* @param join_request the request received from another robot about joining the wall
* @return communication::JoinWallResponse A confirmation for the other robot to join the wall
* with this robot's ID
*/
communication::JoinWallResponse handle_join_wall_request(
communication::JoinWallRequest join_request);

/**
* @brief Removes a given robot from this robot's list of wallers.
*
* @param leave_request the request from the robot who is leaving the wall
* @return communication::Acknowledge acknowledgement of the other robot's communication
*/
communication::Acknowledge handle_leave_wall_request(
communication::LeaveWallRequest leave_request);

/**
* @brief Handles the response from the currently walling robots to find this robot's place in
* the wall.
*
* @param join_response the response from another robot that this robot can join the wall
*/
void handle_join_wall_response(communication::JoinWallResponse join_response);

std::vector<u_int8_t> walling_robots_ = {};
int waller_id_ = -1;

// current state of the defense agent (state machine)
int get_waller_id();
State current_state_ = JOINING_WALL;

int get_marker_target_id();
Marker marker_;
};
Expand Down
49 changes: 0 additions & 49 deletions src/rj_strategy/include/rj_strategy/agent/position/waller.hpp

This file was deleted.

39 changes: 39 additions & 0 deletions src/rj_strategy/include/rj_strategy/coordinator/waller.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include <algorithm>
#include <array>

#include <rclcpp/rclcpp.hpp>

#include <rj_common/world_state.hpp>
#include <rj_constants/constants.hpp>
#include <rj_constants/topic_names.hpp>
#include <rj_convert/ros_convert.hpp>
#include <rj_msgs/msg/waller.hpp>
#include <rj_msgs/msg/world_state.hpp>
#include <rj_msgs/srv/waller.hpp>

#include "rj_strategy/coordinator.hpp"

namespace strategy {

class Waller : public Coordinator<Waller, rj_msgs::srv::Waller, rj_msgs::msg::Waller> {
public:
Waller();
~Waller() override = default;
Waller(const Waller&) = delete;
Waller& operator=(const Waller&) = delete;
Waller(Waller&&) = delete;
Waller& operator=(Waller&&) = delete;

void service_callback(RequestPtr request, ResponsePtr response);

private:
std::array<u_int8_t, kNumShells> walling_robots_;
u_int8_t num_wallers_ = 0;
static constexpr int kMaxWallers = 4;

void update_wallers();
};

} // namespace strategy
75 changes: 75 additions & 0 deletions src/rj_strategy/include/rj_strategy/coordinator/waller_client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#pragma once

#include <cmath>

#include <rclcpp/rclcpp.hpp>
#include <spdlog/spdlog.h>

#include <rj_common/field_dimensions.hpp>
#include <rj_msgs/msg/waller.hpp>
#include <rj_msgs/srv/waller.hpp>

#include "rj_strategy/coordinator/waller.hpp"

namespace strategy {

/**
* @brief Client for interacting with the Waller coordinator.
*
* Manages membership in the waller group and tracks the currently waller list.
*/
class WallerClient {
public:
struct Result {
bool success{false};
};

using StatusCallback = std::function<void(Result)>;

explicit WallerClient(rclcpp::Node::SharedPtr node, uint8_t robot_id);
~WallerClient() = default;
WallerClient(const WallerClient&) = delete;
WallerClient& operator=(const WallerClient&) = delete;
WallerClient(WallerClient&&) = delete;
WallerClient& operator=(WallerClient&&) = delete;

/**
* @brief Join the waller group.
* @param callback Called with current membership status after attempt to join.
*/
void join_group(StatusCallback callback = nullptr);

/**
* @brief Leave the waller group.
* @param callback Called with current membership status after attempt to leave.
*/
void leave_group(StatusCallback callback = nullptr);

/**
* @brief Check if this robot is a member of the waller group.
*/
[[nodiscard]] bool am_i_member() const;

/**
* @brief Get the target walling point
* @return target walling point of this robot.
*/
[[nodiscard]] std::optional<rj_geometry::Point> get_walling_point(
const WorldState* world_state, FieldDimensions field_dimensions) const;

private:
rclcpp::Node::SharedPtr node_;
const uint8_t robot_id_; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) -- class
// isn't move/copy-able anyway
rclcpp::Client<rj_msgs::srv::Waller>::SharedPtr client_;
rclcpp::Subscription<rj_msgs::msg::Waller>::SharedPtr subscription_;

bool am_i_member_ = false;
bool request_pending_ = false;
std::array<u_int8_t, kNumShells> walling_robots_;
int num_wallers_ = 0;

static constexpr double kRobotDiameterMultiplier = 1.5;
};

} // namespace strategy
Loading