@@ -44,19 +44,6 @@ StealBall::StealBall(RobotCommandWrapperBase::SharedPtr & base)
4444 return skill_state == Status::SUCCESS ;
4545 });
4646
47- // 敵よりもボールに近い場合はパス
48- addTransition (StealBallState::MOVE_TO_FRONT , StealBallState::PASS , [this ]() {
49- auto theirs = world_model ()->theirs .getAvailableRobots ();
50- if (not theirs.empty ()) {
51- auto [their_attacker, their_distance] =
52- world_model ()->getNearestRobotWithDistanceFromPoint (world_model ()->ball .pos , theirs);
53- double our_distance = robot ()->getDistance (world_model ()->ball .pos );
54- return our_distance < their_distance - 0.2 ;
55- } else {
56- return true ;
57- }
58- });
59-
6047 addStateFunction (
6148 StealBallState::STEAL ,
6249 [this ]([[maybe_unused]] const ConsaiVisualizerWrapper::SharedPtr & visualizer) -> Status {
@@ -68,7 +55,7 @@ StealBall::StealBall(RobotCommandWrapperBase::SharedPtr & base)
6855 world_model ()->ball .pos , getAngle (world_model ()->ball .pos - robot ()->pose .pos ));
6956 command.dribble (0.5 );
7057 } else if (method == " side" ) {
71- if (robot ()->getDistance (world_model ()->ball .pos ) < (0.085 + 0.000 )) {
58+ if (robot ()->getDistance (world_model ()->ball .pos ) < (0.085 - 0.030 )) {
7259 // ロボット半径より近くに来れば急回転して刈り取れる
7360 command.setTargetTheta (getAngle (world_model ()->ball .pos - robot ()->pose .pos ) + M_PI / 2 );
7461 } else {
@@ -79,111 +66,5 @@ StealBall::StealBall(RobotCommandWrapperBase::SharedPtr & base)
7966 }
8067 return Status::RUNNING ;
8168 });
82-
83- // 敵よりもボールに近い場合はパス
84- addTransition (StealBallState::STEAL , StealBallState::PASS , [this ]() {
85- auto theirs = world_model ()->theirs .getAvailableRobots ();
86- if (not theirs.empty ()) {
87- auto [their_attacker, their_distance] =
88- world_model ()->getNearestRobotWithDistanceFromPoint (world_model ()->ball .pos , theirs);
89- double our_distance = robot ()->getDistance (world_model ()->ball .pos );
90- return our_distance < their_distance - 0.2 ;
91- } else {
92- return true ;
93- }
94- });
95-
96- addStateFunction (
97- StealBallState::PASS ,
98- [this ]([[maybe_unused]] const ConsaiVisualizerWrapper::SharedPtr & visualizer) -> Status {
99- if (attacker_skill == nullptr ) {
100- attacker_skill = std::make_shared<skills::SimpleAttacker>(command_base);
101- }
102- auto ours = world_model ()->ours .getAvailableRobots (robot ()->id );
103- ours.erase (
104- std::remove_if (
105- ours.begin (), ours.end (),
106- [this ](auto e) {
107- return e->getDistance (world_model ()->getTheirGoalCenter ()) >
108- robot ()->getDistance (world_model ()->getTheirGoalCenter ());
109- }),
110- ours.end ());
111- if (not ours.empty ()) {
112- auto [target_bot, distance] = world_model ()->getNearestRobotWithDistanceFromPoint (
113- world_model ()->getTheirGoalCenter (), ours);
114- attacker_skill->setParameter (" receiver_id" , target_bot->id );
115- }
116- return attacker_skill->run (visualizer);
117- });
118-
119- addTransition (StealBallState::PASS , StealBallState::MOVE_TO_FRONT , [this ]() {
120- auto theirs = world_model ()->theirs .getAvailableRobots ();
121- if (theirs.empty ()) {
122- return false ;
123- } else {
124- auto [their_attacker, their_distance] =
125- world_model ()->getNearestRobotWithDistanceFromPoint (world_model ()->ball .pos , theirs);
126- double our_distance = robot ()->getDistance (world_model ()->ball .pos );
127- return our_distance > their_distance;
128- }
129- });
130-
131- addTransition (StealBallState::PASS , StealBallState::INTERCEPT , [this ]() {
132- return world_model ()->ball .vel .norm () > 0.5 ;
133- });
134-
135- addTransition (StealBallState::STEAL , StealBallState::INTERCEPT , [this ]() {
136- return world_model ()->ball .vel .norm () > 0.5 ;
137- });
138-
139- addTransition (StealBallState::MOVE_TO_FRONT , StealBallState::INTERCEPT , [this ]() {
140- return world_model ()->ball .vel .norm () > 0.5 ;
141- });
142-
143- addStateFunction (StealBallState::INTERCEPT , [this ](const ConsaiVisualizerWrapper::SharedPtr &) {
144- Point vel_seg = world_model ()->ball .vel * 5.0 ;
145- if (vel_seg.norm () < 1.0 ) {
146- vel_seg = vel_seg.normalized () * 1.0 ;
147- }
148- Segment ball_line{world_model ()->ball .pos , world_model ()->ball .pos + vel_seg};
149-
150- Point across_point = [&]() {
151- const double OFFSET = 0.3 ;
152- const double X = world_model ()->field_size .x () / 2.0 - OFFSET ;
153- const double Y = world_model ()->field_size .y () / 2.0 - OFFSET ;
154-
155- Segment seg1{Point (X, Y), Point (X, -Y)};
156- Segment seg2{Point (-X, Y), Point (-X, -Y)};
157- Segment seg3{Point (Y, X), Point (-Y, X)};
158- Segment seg4{Point (Y, -X), Point (-Y, -X)};
159- std::vector<Point> intersections;
160- if (bg::intersection (ball_line, seg1, intersections); not intersections.empty ()) {
161- return intersections.front ();
162- } else if (bg::intersection (ball_line, seg2, intersections); not intersections.empty ()) {
163- return intersections.front ();
164- } else if (bg::intersection (ball_line, seg3, intersections); not intersections.empty ()) {
165- return intersections.front ();
166- } else if (bg::intersection (ball_line, seg4, intersections); not intersections.empty ()) {
167- return intersections.front ();
168- } else {
169- return ball_line.second ;
170- }
171- }();
172-
173- // ゴールとボールの中間方向を向く
174- auto [goal_angle, width] = world_model ()->getLargestGoalAngleRangeFromPoint (across_point);
175- auto to_goal = getNormVec (goal_angle);
176- auto to_ball = (world_model ()->ball .pos - across_point).normalized ();
177- double intermediate_angle = getAngle (2 * to_goal + to_ball);
178- command.liftUpDribbler ();
179- command.kickStraight (getParameter<double >(" kicker_power" ));
180- command.setDribblerTargetPosition (across_point, intermediate_angle);
181-
182- return Status::RUNNING ;
183- });
184-
185- addTransition (StealBallState::INTERCEPT , StealBallState::MOVE_TO_FRONT , [this ]() {
186- return world_model ()->ball .vel .norm () < 0.3 ;
187- });
18869}
18970} // namespace crane::skills
0 commit comments