forked from kektobiologist/motion-simulation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ballinterception.hpp
111 lines (101 loc) · 3.94 KB
/
ballinterception.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#ifndef BALLINTERCEPTION_HPP
#define BALLINTERCEPTION_HPP
#include <math.h>
#include "pose.h"
#include "velocity-profile.hpp"
#include "trajectory.hpp"
#include "splines.hpp"
#include "controlpoint-optimization.hpp"
#include "trajectory-generators.hpp"
namespace BallInterception {
Vector2D<double> predictBallPose(Vector2D<double> ballPos, Vector2D<double> ballVel, double timeOfPrediction){
Vector2D<double> bPos;
bPos.x = ballPos.x + timeOfPrediction*ballVel.x;
bPos.y = ballPos.y + timeOfPrediction*ballVel.y;
while (bPos.x > HALF_FIELD_MAXX || bPos.x < -HALF_FIELD_MAXX || bPos.y > HALF_FIELD_MAXY || bPos.y < -HALF_FIELD_MAXY) {
if (bPos.y > HALF_FIELD_MAXY) {
bPos.y = 2 * HALF_FIELD_MAXY - bPos.y;
}
if (bPos.y < -HALF_FIELD_MAXY) {
bPos.y = - (2 * HALF_FIELD_MAXY + bPos.y);
}
if (bPos.x > HALF_FIELD_MAXX) {
bPos.x = 2 * HALF_FIELD_MAXX - bPos.x;
}
if (bPos.x < -HALF_FIELD_MAXX) {
bPos.x = - (2 * HALF_FIELD_MAXX + bPos.x);
}
}
return bPos;
}
double getBotBallDist(Pose botPos, Vector2D<double> ballPos) {
return sqrt((botPos.x() - ballPos.x)*(botPos.x() - ballPos.x) + (botPos.y() - ballPos.y)*(botPos.y() - ballPos.y));
}
SplineTrajectory* getIntTraj(Pose botPosStart, Vector2D<double> ballPos, Vector2D<double> ballVel, Vector2D<double> botVel) {
Vector2D<double> predictedBallPos;
double error = 0.1;
double T2 = 6.0;
double T1 = 0.0;
double S = 1.0;
Vector2D<double> goalCentre(HALF_FIELD_MAXX, 0);
SplineTrajectory *st = NULL;
double T = T1;
while (1) {
if (st)
delete st;
predictedBallPos = predictBallPose(ballPos, ballVel, T);
double endTheta = atan2(goalCentre.y - predictedBallPos.y, goalCentre.x - predictedBallPos.x);
Pose endPose(predictedBallPos.x, predictedBallPos.y, endTheta);
// add a cp behind the ball pos, distance of 500
// Pose cp1(predictedBallPos.x+500*cos(endTheta+M_PI), predictedBallPos.y+500*sin(endTheta+M_PI), 0);
vector<Pose> midPoints;
// midPoints.push_back(cp1);
//st = TrajectoryGenerators::cubic(botPosStart, endPose, 0,0, 40,40 , midPoints);
st = TrajectoryGenerators::cubic(botPosStart, endPose, botVel.x, botVel.y, 60, 60, midPoints);
double t = st->totalTime();
if (t < T)
break;
T += S;
if (T >= 6.0)
break;
}
if (T <= 6.0) {
T2 = T;
T1 = T - S;
}
//qDebug() << "here3" << endl;
int iter = 0;
while (1) {
// predictedBallPos: strategy coordinates
double mid = (T1+T2)/2;
predictedBallPos = predictBallPose(ballPos, ballVel, mid);
iter++;
double endTheta = atan2(goalCentre.y - predictedBallPos.y, goalCentre.x - predictedBallPos.x);
Pose endPose(predictedBallPos.x, predictedBallPos.y, endTheta);
if (st)
delete st;
// add a cp behind the ball pos, distance of 500
// Pose cp1(predictedBallPos.x+500*cos(endTheta+M_PI), predictedBallPos.y+500*sin(endTheta+M_PI), 0);
vector<Pose> midPoints;
// midPoints.push_back(cp1);
//st = TrajectoryGenerators::cubic(botPosStart, endPose, 0,0, 40, 40, midPoints);
st = TrajectoryGenerators::cubic(botPosStart, endPose, botVel.x, botVel.y, 60, 60, midPoints);
double t = st->totalTime();
// qDebug() << "mid = " << mid << ", bot-ka-time = " << t;
if (fabs(t-mid) < error)
break;
if (t > mid) {
T1 = mid;
} else if (t < mid) {
T2 = mid;
}
if (fabs(T2-T1) < error) {
// qDebug() << "T2, T1 almost same = " << T1 <<", t = " << t;
break;
}
}
qDebug() << "iterations getinttraj " << iter << ballPos.x << " " << ballPos.y << " " << predictedBallPos.x << " " << predictedBallPos.y << endl;
return st;
}
}
#endif // BALLINTERCEPTION_HPP