Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ball placement obstacle with Stadium Shape on their ball placement #2294

Merged
merged 17 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from 15 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
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
build-and-test:
runs-on: ubuntu-latest
container:
image: robojackets/robocup-software:foxy
image: robojackets/robocup-software:humble
defaults:
run:
shell: bash
Expand All @@ -34,23 +34,23 @@ jobs:
- name: Build
run: |
echo "::add-matcher::ci/clang.json"
source /opt/ros/foxy/setup.bash
source /opt/ros/humble/setup.bash
source install/setup.bash
make all
echo "::remove-matcher owner=clang::"

- name: Test
run: |
echo "::add-matcher::ci/gtest.json"
source /opt/ros/foxy/setup.bash
source /opt/ros/humble/setup.bash
source install/setup.bash
./install/lib/rj_robocup/test-soccer
echo "::remove-matcher owner=gtest::"

- name: Run clang-tidy
run: |
echo "::add-matcher::ci/clang-tidy.json"
source /opt/ros/foxy/setup.bash
source /opt/ros/humble/setup.bash
source install/setup.bash
DIFFBASE=${{ github.base_ref }} make checktidy-lines
echo "::remove-matcher owner=clang-tidy::"
Expand All @@ -61,7 +61,7 @@ jobs:
if: startsWith(github.head_ref, 'fix-code-style') == false
runs-on: ubuntu-latest
container:
image: ros:foxy
image: ros:humble
defaults:
run:
shell: bash
Expand Down Expand Up @@ -94,7 +94,7 @@ jobs:
id: style-check
run: |
# check formatting style (C++)
git diff -U0 --no-color ${{ github.base_ref }} ${{ github.head_ref }} | python3 util/clang-format-diff.py -binary clang-format-10 -i -p1
git diff -U0 --no-color ${{ github.base_ref }} ${{ github.head_ref }} | python3 util/clang-format-diff.py -binary clang-format-14 -i -p1

if ! git diff-index --quiet HEAD; then
echo "::set-output name=changed::true"
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

# build directories
/build
/install
/gmon.out
*.swp
/.settings
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ endif()
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -march=native")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og")
set(CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG} -Werror=return-type -Werror=delete-non-virtual-dtor -Werror=switch")
"${CMAKE_CXX_FLAGS_DEBUG} -Werror=return-type -Werror=delete-non-virtual-dtor")

# ======================================================================
# Testing
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Use phusion/baseimage if problems arise
FROM ros:foxy-ros-base-focal
FROM ros:humble-ros-base-jammy
LABEL maintainer="oswinso@gmail.com"

# Setup apt to be happy with no console input
Expand Down
3 changes: 2 additions & 1 deletion docs/source/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ but here are some more hints.
* The motion command for driving in a straight line is :cpp:`"path_target"`.
* You will probably need to override some methods relating to passing, but you can leave their implementations empty. They don't need to do anything in your position, as your robot will not pass the ball
* The simulator tells you the coordinates of your cursor—these are the same coordinates you can use in your motion commands.
* You will need to add the new file name you create to ``soccer/src/soccer/CMakeLists.txt``. See how this is done for other positions.

Testing
~~~~~~~
Expand Down Expand Up @@ -668,4 +669,4 @@ Here are all the external links from this document, copied again for your easy r

* `C++ Inheritance`_

.. _C++ Inheritance: https://www.learncpp.com/cpp-tutorial/basic-inheritance-in-c/
.. _C++ Inheritance: https://www.learncpp.com/cpp-tutorial/basic-inheritance-in-c/
5 changes: 5 additions & 0 deletions install/env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Here are some useful environment variables for setting up a consistent ROS environment
# some information on this can be found here: https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.html
export ROS_DOMAIN_ID=19 # this is a random number, it's just important to keep it consistent across shells
export ROS_LOCALHOST_ONLY=1 # for our stack specifically, this is quite helpful.

2 changes: 1 addition & 1 deletion install/setup.bash
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ _pythonpath_add() {
# No direct replacement for the command exists, and in Ubuntu 22.04,
# this script will produce a warning about this. We may need to find a
# replacement library in the future.
_PYTHON_LIB_PATH=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(prefix='${_INSTALL_PATH}'))")
_PYTHON_LIB_PATH=$(python3 -c "import sysconfig; print(sysconfig.get_path('purelib'))")
_pythonpath_add "${_PYTHON_LIB_PATH}"
unset _PYTHON_LIB_PATH

Expand Down
2 changes: 1 addition & 1 deletion install/setup.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ _pythonpath_add() {
fi
}

_PYTHON_LIB_PATH=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(prefix='${_INSTALL_PATH}'))")
_PYTHON_LIB_PATH=$(python3 -c "import sysconfig; print(sysconfig.get_path('purelib'))")
_pythonpath_add "${_PYTHON_LIB_PATH}"
unset _PYTHON_LIB_PATH

Expand Down
2 changes: 1 addition & 1 deletion launch/framework.bash
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ if [ -z "$binary" ]; then
fi

# Run the binary in the background
"$binary" &
"$binary" -g 2020B --realism RC2021 &
binary_pid=$!

# Ensure that pressing Ctrl+C kills all subprocesses
Expand Down
6 changes: 3 additions & 3 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ run-sim:
# run our stack with default flags
# TODO: actually name our software stack something
run-our-stack:
ROS_LOCALHOST_ONLY=1 ros2 launch rj_robocup soccer.launch.py run_sim:=True
ros2 launch rj_robocup soccer.launch.py run_sim:=True

# run sim with external referee (SSL Game Controller)
run-sim-external:
ROS_LOCALHOST_ONLY=1 ros2 launch rj_robocup soccer.launch.py run_sim:=True use_internal_ref:=False
ros2 launch rj_robocup soccer.launch.py run_sim:=True use_internal_ref:=False

run-sim-ex: run-sim-external

Expand All @@ -95,7 +95,7 @@ run-manual:

# same as run-real, with different server port
run-alt-real:
ROS_DOMAIN_ID=2 ros2 launch rj_robocup soccer.launch.py run_sim:=False use_sim_radio:=False server_port:=25564 use_internal_ref:=False team_name:=AltRoboJackets team_flag:=-b
ros2 launch rj_robocup soccer.launch.py run_sim:=False use_sim_radio:=False server_port:=25564 use_internal_ref:=False team_name:=AltRoboJackets team_flag:=-b

# run sim2play (requires external referee)
run-sim2play:
Expand Down
1 change: 1 addition & 0 deletions rj_common/include/rj_common/field_dimensions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <rj_geometry/polygon.hpp>
#include <rj_geometry/rect.hpp>
#include <rj_geometry/shape_set.hpp>
#include <rj_geometry/stadium_shape.hpp>
#include <rj_msgs/msg/field_dimensions.hpp>

using namespace std;
Expand Down
93 changes: 93 additions & 0 deletions rj_geometry/include/rj_geometry/stadium_shape.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#pragma once

#include <memory>
#include <set>
#include <vector>

#include "point.hpp"
#include "polygon.hpp"
#include "segment.hpp"
#include "shape.hpp"
#include "shape_set.hpp"

namespace rj_geometry {

/**
* A rj_geometry::StadiumShape is a Shape that is made up of 2 circles and a polygon. It represents
* the shape of a track from track and field.
*/
class StadiumShape : public Shape {

Check warning on line 19 in rj_geometry/include/rj_geometry/stadium_shape.hpp

View workflow job for this annotation

GitHub Actions / build-and-test

class 'StadiumShape' defines a default destructor and a copy constructor but does not define a copy assignment operator, a move constructor or a move assignment operator
public:
~StadiumShape() = default;

Check warning on line 21 in rj_geometry/include/rj_geometry/stadium_shape.hpp

View workflow job for this annotation

GitHub Actions / build-and-test

annotate this function with 'override' or (rarely) 'final'

StadiumShape() = default;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a move constructor

StadiumShape(Point c1, Point c2, float r) { init(c1, c2, r); }

StadiumShape(const StadiumShape& other) {
for (const auto& shape : other.subshapes_) {
std::shared_ptr<Shape> itr_shape = std::shared_ptr<Shape>(shape->clone());
subshapes_.push_back(itr_shape);
}
drawshapes_ = other.drawshapes_;
}

[[nodiscard]] Shape* clone() const override;

[[nodiscard]] bool contains_point(Point pt) const override;
[[nodiscard]] bool near_point(Point pt, float threshold) const override;

using const_iterator = std::vector<std::shared_ptr<Shape>>::const_iterator;
using iterator = std::vector<std::shared_ptr<Shape>>::iterator;

[[nodiscard]] const_iterator begin() const { return subshapes_.begin(); }
[[nodiscard]] const_iterator end() const { return subshapes_.end(); }

iterator begin() { return subshapes_.begin(); }
iterator end() { return subshapes_.end(); }

[[nodiscard]] const std::vector<std::shared_ptr<Shape>>& subshapes() const {
return subshapes_;
}

[[nodiscard]] const rj_geometry::ShapeSet drawshapes() const { return drawshapes_; }

Check warning on line 53 in rj_geometry/include/rj_geometry/stadium_shape.hpp

View workflow job for this annotation

GitHub Actions / build-and-test

return type 'const rj_geometry::ShapeSet' is 'const'-qualified at the top level, which may reduce code readability without improving const correctness

std::shared_ptr<Shape> operator[](unsigned int index) { return subshapes_[index]; }

std::shared_ptr<const Shape> operator[](unsigned int index) const { return subshapes_[index]; }

template <typename T>
[[nodiscard]] bool hit(const T& obj) const {
for (const auto& it : *this) {

Check warning on line 61 in rj_geometry/include/rj_geometry/stadium_shape.hpp

View workflow job for this annotation

GitHub Actions / build-and-test

replace loop by 'std::any_of()'
if (it->hit(obj)) {
return true;
}
}

return false;
}

[[nodiscard]] bool hit(Point pt) const override { return hit<Point>(pt); }

[[nodiscard]] bool hit(const Segment& seg) const override { return hit<Segment>(seg); }

std::string to_string() override {
std::stringstream str;
str << "StadiumShape<";
for (auto& subshape : subshapes_) {
str << subshape->to_string() << ", ";
}
str << ">";

return str.str();
}

protected:
void init(Point c1, Point c2, float r);

private:
std::vector<std::shared_ptr<Shape>> subshapes_;
rj_geometry::ShapeSet drawshapes_;
};

} // namespace rj_geometry
1 change: 1 addition & 0 deletions rj_geometry/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set(GEOMETRY2D_SRCS
arc.cpp
circle.cpp
composite_shape.cpp
stadium_shape.cpp
line.cpp
point.cpp
polygon.cpp
Expand Down
55 changes: 55 additions & 0 deletions rj_geometry/src/stadium_shape.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <rj_geometry/stadium_shape.hpp>

namespace rj_geometry {

Shape* StadiumShape::clone() const { return new StadiumShape(*this); }

void StadiumShape::init(Point c1, Point c2, float r) {
rj_geometry::Circle first_circle = rj_geometry::Circle{c1, static_cast<float>(r)};
rj_geometry::Circle second_circle = rj_geometry::Circle{c2, static_cast<float>(r)};

rj_geometry::Segment vect{c1, c2};

rj_geometry::Point end1{c1.x() + r * (c2.x() - c1.x()) / vect.length(),
c1.y() + r * (c2.y() - c1.y()) / vect.length()};
rj_geometry::Point end2{c2.x() - r * (c2.x() - c1.x()) / vect.length(),
c2.y() - r * (c2.y() - c1.y()) / vect.length()};

rj_geometry::Segment vect_updated{end1, end2};
rj_geometry::Polygon rect_obs{vect_updated, r};

std::shared_ptr<rj_geometry::Circle> c1_obs_ptr =
std::make_shared<rj_geometry::Circle>(first_circle);
std::shared_ptr<rj_geometry::Polygon> rect_obs_ptr =
std::make_shared<rj_geometry::Polygon>(rect_obs);
std::shared_ptr<rj_geometry::Circle> c2_obs_ptr =
std::make_shared<rj_geometry::Circle>(second_circle);

subshapes_.push_back(c1_obs_ptr);
subshapes_.push_back(rect_obs_ptr);
subshapes_.push_back(c2_obs_ptr);

drawshapes_.add(c1_obs_ptr);
drawshapes_.add(rect_obs_ptr);
drawshapes_.add(c2_obs_ptr);
}

bool StadiumShape::contains_point(Point pt) const {
for (const auto& subshape : subshapes_) {

Check warning on line 38 in rj_geometry/src/stadium_shape.cpp

View workflow job for this annotation

GitHub Actions / build-and-test

replace loop by 'std::any_of()'
if (subshape->contains_point(pt)) {
return true;
}
}
return false;
}

bool StadiumShape::near_point(Point pt, float threshold) const {
for (const auto& subshape : subshapes_) {

Check warning on line 47 in rj_geometry/src/stadium_shape.cpp

View workflow job for this annotation

GitHub Actions / build-and-test

replace loop by 'std::any_of()'
if (subshape->near_point(pt, threshold)) {
return true;
}
}
return false;
}

} // namespace rj_geometry
1 change: 1 addition & 0 deletions soccer/src/soccer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ set(ROBOCUP_LIB_SRC
strategy/agent/position/position.cpp
strategy/agent/position/robot_factory_position.cpp
strategy/agent/position/goalie.cpp
strategy/agent/position/line.cpp
strategy/agent/position/offense.cpp
strategy/agent/position/idle.cpp
strategy/agent/position/defense.cpp
Expand Down
2 changes: 2 additions & 0 deletions soccer/src/soccer/planning/planner/line_kick_path_planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ Trajectory LineKickPathPlanner::final(const PlanRequest& plan_request) {

MotionCommand modified_command{"path_target", target,
FacePoint{plan_request.motion_command.target.position}};

modified_command.ignore_ball = true;
modified_request.motion_command = modified_command;

return path_target_.plan(modified_request);
Expand Down
17 changes: 17 additions & 0 deletions soccer/src/soccer/planning/planner/plan_request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,23 @@
}

out_static->add(std::make_shared<rj_geometry::Circle>(std::move(ball_obs)));

auto maybe_bp_point = in.play_state.ball_placement_point();
if (maybe_bp_point.has_value() && in.play_state.is_their_restart()) {
rj_geometry::Point bp_point = maybe_bp_point.value();
rj_geometry::StadiumShape stadium = rj_geometry::StadiumShape{
in.world_state->ball.position, bp_point, ball_obs.radius()};

Check warning on line 86 in soccer/src/soccer/planning/planner/plan_request.cpp

View workflow job for this annotation

GitHub Actions / build-and-test

'ball_obs' used after it was moved

std::shared_ptr<rj_geometry::StadiumShape> track_obs_ptr =
std::make_shared<rj_geometry::StadiumShape>(stadium);

out_static->add(track_obs_ptr);

if (in.debug_drawer != nullptr) {
QColor draw_color = Qt::red;
in.debug_drawer->draw_stadium(stadium, draw_color);
}
}
}
}

Expand Down
12 changes: 6 additions & 6 deletions soccer/src/soccer/planning/planner/settle_path_planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,9 @@ Trajectory SettlePathPlanner::intercept(const PlanRequest& plan_request, RobotIn

// Plan a path from our partial path start location to the intercept
// test location
Trajectory path = CreatePath::rrt(start_instant.linear_motion(), target_robot_intersection,
plan_request.constraints.mot, start_instant.stamp,
static_obstacles, dynamic_obstacles);
Trajectory path = CreatePath::intermediate(
start_instant.linear_motion(), target_robot_intersection, plan_request.constraints.mot,
start_instant.stamp, static_obstacles);

// Calculate the
RJ::Seconds buffer_duration = ball_time - path.duration();
Expand Down Expand Up @@ -332,9 +332,9 @@ Trajectory SettlePathPlanner::intercept(const PlanRequest& plan_request, RobotIn
LinearMotionInstant target{closest_pt,
settle::PARAM_ball_speed_percent_for_dampen * average_ball_vel_};

Trajectory shortcut =
CreatePath::rrt(start_instant.linear_motion(), target, plan_request.constraints.mot,
start_instant.stamp, static_obstacles, dynamic_obstacles);
Trajectory shortcut = CreatePath::intermediate(start_instant.linear_motion(), target,
plan_request.constraints.mot,
start_instant.stamp, static_obstacles);

if (!shortcut.empty()) {
plan_angles(&shortcut, start_instant, AngleFns::face_point(face_pos),
Expand Down
Loading
Loading