Skip to content

Commit ef3db1a

Browse files
authored
Brakebream availability in gameplay (UBC-Thunderbots#3462)
1 parent 7e27714 commit ef3db1a

12 files changed

Lines changed: 236 additions & 27 deletions

src/software/sensor_fusion/filter/robot_filter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ RobotFilter::RobotFilter(RobotDetection current_robot_state,
1616
}
1717

1818
std::optional<Robot> RobotFilter::getFilteredData(
19-
const std::vector<RobotDetection> &new_robot_data)
19+
const std::vector<RobotDetection> &new_robot_data,
20+
const std::optional<RobotId> breakbeam_tripped_id)
2021
{
2122
int data_num = 0;
2223
Timestamp latest_timestamp = Timestamp().fromSeconds(0);
@@ -88,11 +89,14 @@ std::optional<Robot> RobotFilter::getFilteredData(
8889
(filtered_data.timestamp.toSeconds() -
8990
current_robot_state.timestamp().toSeconds());
9091

92+
// find breakbeam_status
93+
bool breakbeam_tripped = breakbeam_tripped_id == getRobotId();
94+
9195
// update current_robot_state
9296
this->current_robot_state =
9397
Robot(this->getRobotId(), filtered_data.position, filtered_data.velocity,
9498
filtered_data.orientation, filtered_data.angular_velocity,
95-
filtered_data.timestamp);
99+
filtered_data.timestamp, breakbeam_tripped);
96100

97101
return std::make_optional(this->current_robot_state);
98102
}

src/software/sensor_fusion/filter/robot_filter.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,15 @@ class RobotFilter
4444
* The data does not all have to be for a particular Robot, the filter will only use
4545
* the new Robot data that matches the robot id the filter was constructed with.
4646
*
47+
* @param breakbeam_tripped_id The id of the robot with the tripped breakbeam
48+
* according to sensor fusion filtering logic (or none if no robot has a tripped
49+
* beam).
50+
*
4751
* @return The filtered data for the robot
4852
*/
4953
std::optional<Robot> getFilteredData(
50-
const std::vector<RobotDetection>& new_robot_data);
54+
const std::vector<RobotDetection>& new_robot_data,
55+
const std::optional<RobotId> breakbeam_tripped_id = std::nullopt);
5156

5257
/**
5358
* Returns the id of the Robot that this filter is filtering for

src/software/sensor_fusion/filter/robot_team_filter.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ RobotTeamFilter::RobotTeamFilter() {}
88

99
Team RobotTeamFilter::getFilteredData(
1010
const Team &current_team_state,
11-
const std::vector<RobotDetection> &new_robot_detections)
11+
const std::vector<RobotDetection> &new_robot_detections,
12+
const std::optional<RobotId> breakbeam_tripped_id)
1213
{
1314
// Add filters for any robot we haven't seen before
1415
for (auto detection : new_robot_detections)
@@ -28,7 +29,8 @@ Team RobotTeamFilter::getFilteredData(
2829
std::vector<Robot> new_filtered_robot_data;
2930
for (auto it = robot_filters.begin(); it != robot_filters.end(); it++)
3031
{
31-
auto data = it->second.getFilteredData(new_robot_detections);
32+
auto data =
33+
it->second.getFilteredData(new_robot_detections, breakbeam_tripped_id);
3234
if (data)
3335
{
3436
new_filtered_robot_data.emplace_back(*data);

src/software/sensor_fusion/filter/robot_team_filter.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@ class RobotTeamFilter
2020
*
2121
* @param current_team_state The current state of the Team
2222
* @param new_robot_detections A list of new SSL Robot detections
23+
* @param breakbeam_tripped_id The id of the robot with the tripped breakbeam
24+
* according to sensor fusion
2325
*
2426
* @return The updated state of the team given the new data
2527
*/
26-
Team getFilteredData(const Team& current_team_state,
27-
const std::vector<RobotDetection>& new_robot_detections);
28+
Team getFilteredData(
29+
const Team& current_team_state,
30+
const std::vector<RobotDetection>& new_robot_detections,
31+
const std::optional<RobotId> breakbeam_tripped_id = std::nullopt);
2832

2933

3034
// A map used to store a separate robot filter for each robot on this team, so

src/software/sensor_fusion/sensor_fusion.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,8 @@ std::optional<Ball> SensorFusion::createBall(
362362

363363
Team SensorFusion::createFriendlyTeam(const std::vector<RobotDetection> &robot_detections)
364364
{
365-
Team new_friendly_team =
366-
friendly_team_filter.getFilteredData(friendly_team, robot_detections);
365+
Team new_friendly_team = friendly_team_filter.getFilteredData(
366+
friendly_team, robot_detections, friendly_robot_id_with_ball_in_dribbler);
367367
return new_friendly_team;
368368
}
369369

@@ -431,7 +431,8 @@ void SensorFusion::updateDribbleDisplacement()
431431

432432
Team SensorFusion::createEnemyTeam(const std::vector<RobotDetection> &robot_detections)
433433
{
434-
Team new_enemy_team = enemy_team_filter.getFilteredData(enemy_team, robot_detections);
434+
Team new_enemy_team =
435+
enemy_team_filter.getFilteredData(enemy_team, robot_detections, false);
435436
return new_enemy_team;
436437
}
437438

src/software/sensor_fusion/sensor_fusion_test.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,3 +1010,88 @@ TEST_F(SensorFusionTest, breakbeam_fail_test_ssl)
10101010
// did it not use robot position
10111011
EXPECT_TRUE(ball_position != robot_state.position());
10121012
}
1013+
1014+
TEST_F(SensorFusionTest, breakbeam_in_robot_test)
1015+
{
1016+
// Check that breakbeam status is propagated to the Robot
1017+
SensorProto sensor_msg;
1018+
1019+
std::unique_ptr<SSLProto::SSL_DetectionFrame> frame = initDetectionFrame();
1020+
std::unique_ptr<SSLProto::SSL_DetectionFrame> frame_2 =
1021+
initDetectionFrameWithFutureTime();
1022+
// creating robot status
1023+
auto robot_msg = std::make_unique<TbotsProto::RobotStatus>();
1024+
robot_msg->set_robot_id(2);
1025+
1026+
auto power_status_msg = std::make_unique<TbotsProto::PowerStatus>();
1027+
power_status_msg->set_breakbeam_tripped(true);
1028+
*(robot_msg->mutable_power_status()) = *power_status_msg;
1029+
1030+
auto geometry_data = initSSLDivBGeomData();
1031+
1032+
// use frame 1 to create sensor_msg
1033+
auto ssl_wrapper_packet =
1034+
createSSLWrapperPacket(std::move(geometry_data), std::move(frame));
1035+
*(sensor_msg.mutable_ssl_vision_msg()) = *ssl_wrapper_packet;
1036+
*(sensor_msg.add_robot_status_msgs()) = *robot_msg;
1037+
sensor_fusion.processSensorProto(sensor_msg);
1038+
1039+
// use frame 2 that is at a future time to give sensor fusion
1040+
// a chance to use the breakbeam id it got from the previous sensor proto
1041+
auto ssl_wrapper_packet_2 =
1042+
createSSLWrapperPacket(std::move(geometry_data), std::move(frame_2));
1043+
*(sensor_msg.mutable_ssl_vision_msg()) = *ssl_wrapper_packet_2;
1044+
sensor_fusion.processSensorProto(sensor_msg);
1045+
1046+
1047+
std::optional<World> current_world = sensor_fusion.getWorld();
1048+
bool breakbeam_tripped =
1049+
current_world.value().friendlyTeam().getRobotById(2)->breakbeamTripped();
1050+
1051+
// is the breakbeam_tripped on the robot
1052+
EXPECT_TRUE(breakbeam_tripped);
1053+
}
1054+
1055+
1056+
TEST_F(SensorFusionTest, breakbeam_not_in_robot_test)
1057+
{
1058+
// Check that breakbeam status is false when propagated to the Robot
1059+
SensorProto sensor_msg;
1060+
1061+
std::unique_ptr<SSLProto::SSL_DetectionFrame> frame = initDetectionFrame();
1062+
std::unique_ptr<SSLProto::SSL_DetectionFrame> frame_2 =
1063+
initDetectionFrameWithFutureTime();
1064+
// creating robot status
1065+
auto robot_msg = std::make_unique<TbotsProto::RobotStatus>();
1066+
robot_msg->set_robot_id(2);
1067+
1068+
auto power_status_msg = std::make_unique<TbotsProto::PowerStatus>();
1069+
power_status_msg->set_breakbeam_tripped(false);
1070+
*(robot_msg->mutable_power_status()) = *power_status_msg;
1071+
1072+
// create ssl wrapper packet
1073+
auto geometry_data = initSSLDivBGeomData();
1074+
1075+
1076+
// use frame 1 to create sensor_msg
1077+
auto ssl_wrapper_packet =
1078+
createSSLWrapperPacket(std::move(geometry_data), std::move(frame));
1079+
*(sensor_msg.mutable_ssl_vision_msg()) = *ssl_wrapper_packet;
1080+
*(sensor_msg.add_robot_status_msgs()) = *robot_msg;
1081+
sensor_fusion.processSensorProto(sensor_msg);
1082+
1083+
// use frame 2 that is at a future time to give sensor fusion
1084+
// a chance to use the breakbeam id it got from the previous sensor proto
1085+
auto ssl_wrapper_packet_2 =
1086+
createSSLWrapperPacket(std::move(geometry_data), std::move(frame_2));
1087+
*(sensor_msg.mutable_ssl_vision_msg()) = *ssl_wrapper_packet_2;
1088+
sensor_fusion.processSensorProto(sensor_msg);
1089+
1090+
1091+
std::optional<World> current_world = sensor_fusion.getWorld();
1092+
bool breakbeam_tripped =
1093+
current_world.value().friendlyTeam().getRobotById(2)->breakbeamTripped();
1094+
1095+
// is the break_beam correct
1096+
EXPECT_FALSE(breakbeam_tripped);
1097+
}

src/software/world/robot.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,27 @@
44
#include "software/ai/evaluation/time_to_travel.h"
55
#include "software/logger/logger.h"
66

7+
Robot::Robot(RobotId id, const Point &position, const Vector &velocity,
8+
const Angle &orientation, const AngularVelocity &angular_velocity,
9+
const Timestamp &timestamp, bool breakbeam_tripped,
10+
const std::set<RobotCapability> &unavailable_capabilities,
11+
const RobotConstants_t &robot_constants)
12+
: id_(id),
13+
current_state_(position, velocity, orientation, angular_velocity,
14+
breakbeam_tripped),
15+
timestamp_(timestamp),
16+
unavailable_capabilities_(unavailable_capabilities),
17+
robot_constants_(robot_constants)
18+
{
19+
}
20+
721
Robot::Robot(RobotId id, const Point &position, const Vector &velocity,
822
const Angle &orientation, const AngularVelocity &angular_velocity,
923
const Timestamp &timestamp,
1024
const std::set<RobotCapability> &unavailable_capabilities,
1125
const RobotConstants_t &robot_constants)
1226
: id_(id),
13-
current_state_(position, velocity, orientation, angular_velocity),
27+
current_state_(position, velocity, orientation, angular_velocity, false),
1428
timestamp_(timestamp),
1529
unavailable_capabilities_(unavailable_capabilities),
1630
robot_constants_(robot_constants)
@@ -90,6 +104,11 @@ Angle Robot::orientation() const
90104
return current_state_.orientation();
91105
}
92106

107+
bool Robot::breakbeamTripped() const
108+
{
109+
return current_state_.breakbeamTripped();
110+
}
111+
93112
AngularVelocity Robot::angularVelocity() const
94113
{
95114
return current_state_.angularVelocity();
@@ -99,17 +118,19 @@ bool Robot::isNearDribbler(const Point &test_point, double TOLERANCE) const
99118
{
100119
const double POSSESSION_THRESHOLD_METERS = DIST_TO_FRONT_OF_ROBOT_METERS + TOLERANCE;
101120

121+
bool breakbeam = this->breakbeamTripped();
102122
Vector vector_to_test_point = test_point - position();
103123
if (vector_to_test_point.length() > POSSESSION_THRESHOLD_METERS)
104124
{
105-
return false;
125+
return breakbeam;
106126
}
107127
else
108128
{
109129
// check that ball is in a 90-degree cone in front of the robot
110130
auto ball_to_robot_angle =
111131
orientation().minDiff(vector_to_test_point.orientation());
112-
return (ball_to_robot_angle < Angle::fromDegrees(45.0));
132+
bool vision_confirm_ball = (ball_to_robot_angle < Angle::fromDegrees(45.0));
133+
return breakbeam || vision_confirm_ball;
113134
}
114135
}
115136

src/software/world/robot.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,38 @@ class Robot
2626
* per second
2727
* @param timestamp The timestamp at which the robot was observed to be in the given
2828
* state
29+
* @param breakbeam_tripped The new status of the breakbeam
2930
* @param unavailable_capabilities The set of unavailable capabilities for this robot
3031
* @param robot_constants The robot constants for this robot
3132
*/
3233
explicit Robot(RobotId id, const Point &position, const Vector &velocity,
3334
const Angle &orientation, const AngularVelocity &angular_velocity,
34-
const Timestamp &timestamp,
35+
const Timestamp &timestamp, bool breakbeam_tripped = false,
3536
const std::set<RobotCapability> &unavailable_capabilities =
3637
std::set<RobotCapability>(),
3738
const RobotConstants_t &robot_constants = DEFAULT_ROBOT_CONSTANTS);
3839

40+
/**
41+
* Creates a new robot given robot data
42+
*
43+
* @param id The id of the robot to create
44+
* @param position the new position of the robot. Coordinates are in metres.
45+
* @param velocity the new velocity of the robot, in metres / second.
46+
* @param orientation the new orientation of the robot, in Radians.
47+
* @param angular_velocity the new angular velocity of the robot, in Radians
48+
* per second
49+
* @param timestamp The timestamp at which the robot was observed to be in the given
50+
* state
51+
* @param unavailable_capabilities The set of unavailable capabilities for this robot
52+
* @param robot_constants The robot constants for this robot
53+
*/
54+
explicit Robot(RobotId id, const Point &position, const Vector &velocity,
55+
const Angle &orientation, const AngularVelocity &angular_velocity,
56+
const Timestamp &timestamp,
57+
const std::set<RobotCapability> &unavailable_capabilities,
58+
const RobotConstants_t &robot_constants);
59+
60+
3961
/**
4062
* Creates a new robot with the given initial state
4163
*
@@ -114,6 +136,13 @@ class Robot
114136
*/
115137
Angle orientation() const;
116138

139+
/**
140+
* Returns the current breakbeam status of the robot
141+
*
142+
* @return the current breakbeam status of the robot
143+
*/
144+
bool breakbeamTripped() const;
145+
117146
/**
118147
* Returns the current angular velocity of the robot
119148
*

src/software/world/robot_state.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#include "software/world/robot_state.h"
22

33
RobotState::RobotState(const Point &position, const Vector &velocity,
4-
const Angle &orientation, const AngularVelocity &angular_velocity)
4+
const Angle &orientation, const AngularVelocity &angular_velocity,
5+
const bool breakbeam_tripped)
56
: position_(position),
67
velocity_(velocity),
78
orientation_(orientation),
8-
angular_velocity_(angular_velocity)
9+
angular_velocity_(angular_velocity),
10+
breakbeam_tripped_(breakbeam_tripped)
911
{
1012
}
1113

@@ -16,7 +18,8 @@ RobotState::RobotState(const TbotsProto::RobotState &robot_state_proto)
1618
robot_state_proto.global_velocity().y_component_meters())),
1719
orientation_(Angle::fromRadians(robot_state_proto.global_orientation().radians())),
1820
angular_velocity_(AngularVelocity::fromRadians(
19-
robot_state_proto.global_angular_velocity().radians_per_second()))
21+
robot_state_proto.global_angular_velocity().radians_per_second())),
22+
breakbeam_tripped_(false)
2023
{
2124
}
2225

@@ -40,6 +43,11 @@ AngularVelocity RobotState::angularVelocity() const
4043
return angular_velocity_;
4144
}
4245

46+
bool RobotState::breakbeamTripped() const
47+
{
48+
return breakbeam_tripped_;
49+
}
50+
4351
bool RobotState::operator==(const RobotState &other) const
4452
{
4553
return this->position() == other.position() && this->velocity() == other.velocity() &&

src/software/world/robot_state.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ class RobotState
2626
* @param velocity The velocity of the robot, in metres per second
2727
* @param orientation The orientation of the robot
2828
* @param angular_velocity The angular velocity of the robot
29+
* @param breakbeam_tripped The breakbeam status of the robot
2930
*/
3031
explicit RobotState(const Point &position, const Vector &velocity,
31-
const Angle &orientation,
32-
const AngularVelocity &angular_velocity);
32+
const Angle &orientation, const AngularVelocity &angular_velocity,
33+
const bool breakbeam_tripped = false);
3334

3435
/**
3536
* Creates a new robot state based on the TbotsProto::RobotState protobuf
@@ -68,6 +69,13 @@ class RobotState
6869
*/
6970
AngularVelocity angularVelocity() const;
7071

72+
/**
73+
* Returns the breakbeam status of the robot represented by this state
74+
*
75+
* @return the breakbeam status of the robot represented by this state
76+
*/
77+
bool breakbeamTripped() const;
78+
7179
/**
7280
* Defines the equality operator for a RobotState. RobotStates are equal if
7381
* all their members are equal
@@ -94,6 +102,7 @@ class RobotState
94102
Vector velocity_;
95103
Angle orientation_;
96104
AngularVelocity angular_velocity_;
105+
bool breakbeam_tripped_;
97106
};
98107

99108
/**

0 commit comments

Comments
 (0)