11#include " PositionProcessing.h"
2-
2+ # include " Utils/EnumsAndConstants.h "
33
44void PositionProcessing::saveXML ()
55{
@@ -26,14 +26,13 @@ void PositionProcessing::matchBlobs(cv::Mat& debugFrame){
2626 static Players empty_players;
2727
2828 vss.setPlayers (empty_players);
29- // printf("Team Color %d\n", getTeamColor());
3029
3130 // Settting team positions
3231 Players teamA;
3332 findTeam (teamA, debugFrame, groupedBlobs.team );
3433 setTeamColor (getTeamColor () == Color::YELLOW ? Color::BLUE : Color::YELLOW);
3534 Players teamB;
36- USE_PATTERN_FOR_ENEMIES ? findTeam (teamB, debugFrame, groupedBlobs.enemys ) : findEnemys (teamB, debugFrame, groupedBlobs. enemys );
35+ findTeam (teamB, debugFrame, groupedBlobs.enemies );
3736 setTeamColor (getTeamColor () == Color::YELLOW ? Color::BLUE : Color::YELLOW);
3837
3938 Players allPlayers;
@@ -48,65 +47,85 @@ void PositionProcessing::matchBlobs(cv::Mat& debugFrame){
4847}
4948
5049void PositionProcessing::findTeam (Players &players, cv::Mat& debugFrame, std::vector<Region> &teamRegions) {
51- players.clear ();
52-
53- std::bitset<MAX_PLAYERS> markedColors;
54- uint teamColor = static_cast <uint>(getTeamColor ());
55- // printf("color Index : ");
56- for (Region ®ion : teamRegions) {
57- if (region.distance < blobMaxDist ()) {
58- // int colorIndex = Utils::convertOldColorToNewColor(region.color);
59- int colorIndex = region.color ;
60- // printf(" %d", colorIndex);
61- if (!Utils::isRobotColor (colorIndex)) {
62- // cor invalida
63- continue ;
64- }
65-
66- if (markedColors[size_t (colorIndex)]){
67- continue ;
68- }
69-
70- markedColors[size_t (colorIndex)] = true ;
71- Blob b1, b2;
72- std::tie (b1, b2) = region.blobs ;
73- Player robot ((teamColor-1 )*100 + static_cast <uint>(colorIndex) - Color::RED);
74- robot.team (teamColor);
75- Point newPositionInPixels = (b1.position + b2.position ) * 0.5 ;
76- Point newPosition = Utils::convertPositionPixelToCm (newPositionInPixels);
77-
78- Float newAngle = Utils::angle (b1.position , b2.position );
7950
80- auto & playerPosVel = _kalmanFilterRobots[teamColor-2 ][robot.id ()%100 ].update (newPosition.x ,newPosition.y );
81-
82- Geometry::PT filtPoint (playerPosVel (0 , 0 ), playerPosVel (1 , 0 ));
83- Geometry::PT PlayVel (playerPosVel (2 , 0 ), playerPosVel (3 , 0 ));
84-
85- auto &playerRotVel = _dirFilteRobots[teamColor-2 ][robot.id ()%100 ].update (std::cos (newAngle), std::sin (newAngle));
86- double filterDir = std::atan2 (playerRotVel (1 , 0 ), playerRotVel (0 , 0 ));
87- robot.update (Point (filtPoint.x ,filtPoint.y ), filterDir);
88- players.push_back (robot);
89- cv::circle (debugFrame, Utils::convertPositionCmToPixel (Point (filtPoint.x ,filtPoint.y )), 15 , _colorCar[teamColor], 2 , cv::LINE_AA);
90- cv::circle (debugFrame, Utils::convertPositionCmToPixel (Point (filtPoint.x ,filtPoint.y )), 12 , _colorCar[colorIndex], 2 , cv::LINE_AA);
51+ players.clear ();
52+ filterPattern (teamRegions);
53+ uint teamColor = static_cast <uint>(getTeamColor ());
54+ for (Region ®ion : teamRegions) {
55+ if (USE_OLD_PATTERN){
56+
57+ int colorIndex = region.blobs [1 ].color ;
58+
59+ if (!Utils::isRobotColor (colorIndex)) {
60+ // cor invalida
61+ continue ;
62+ }
9163
64+ Blobs blobs = region.blobs ;
65+ Blob b1 = blobs[1 ], b2 = blobs[0 ];
66+ Player robot ((teamColor-1 )*100 + static_cast <uint>(colorIndex) - Color::RED); // seta o id da robo na regiao
67+ robot.team (teamColor);
68+ Point newPositionInPixels = (b1.position + b2.position ) * 0.5 ;
69+ Point newPosition = Utils::convertPositionPixelToCm (newPositionInPixels);
70+ Float newAngle = Utils::angle (b1.position , b2.position );
71+
72+ robot.update (Point (newPosition.x ,newPosition.y ), newAngle);
73+ players.push_back (robot);
74+ cv::circle (debugFrame, Utils::convertPositionCmToPixel (Point (newPosition.x ,newPosition.y )), 15 , _colorCar[teamColor], 2 , cv::LINE_AA);
75+ cv::circle (debugFrame, Utils::convertPositionCmToPixel (Point (newPosition.x ,newPosition.y )), 12 , _colorCar[colorIndex], 2 , cv::LINE_AA);
76+ }
77+ else if (region.blobs .size () == 3 ) {
78+ int firstSecondary = region.blobs [1 ].color ;
79+ int secondSecondary = region.blobs [2 ].color ;
80+ int colorIndex = ((teamColor) + (firstSecondary * MAX_ROBOTS) + (secondSecondary * MAX_ROBOTS * MAX_ROBOTS));
81+
82+ if (!Utils::isRobotColor (firstSecondary) || !Utils::isRobotColor (secondSecondary)) {
83+ continue ;
9284 }
93- }
9485
86+ // markedColors[size_t(newId(colorIndex))] = true;
87+ Blobs blobs = region.blobs ;
88+ Blob b1 = blobs[0 ], b2 = blobs[1 ], b3 = blobs[2 ];
89+ if (newId (colorIndex) > 12 )
90+ continue ;
91+
92+ Player robot (newId (colorIndex));
93+
94+ robot.team (teamColor);
95+
96+ cv::Point secondaryPosition = (b2.position + b3.position ) * 0.5 ;
97+ Point newPositionInPixels = (b1.position + secondaryPosition) * 0.5 ;
98+ Point newPosition = Utils::convertPositionPixelToCm (newPositionInPixels);
99+ Float newAngle = Utils::angle (secondaryPosition, b1.position );
100+
101+ auto & playerPosVel = _kalmanFilterRobots[teamColor-2 ][robot.id ()].update (newPosition.x ,newPosition.y );
102+
103+ Geometry::PT filtPoint (playerPosVel (0 , 0 ), playerPosVel (1 , 0 ));
104+ Geometry::PT PlayVel (playerPosVel (2 , 0 ), playerPosVel (3 , 0 ));
105+
106+ auto &playerRotVel = _dirFilteRobots[teamColor-2 ][robot.id ()%100 ].update (std::cos (newAngle), std::sin (newAngle));
107+ double filterDir = std::atan2 (playerRotVel (1 , 0 ), playerRotVel (0 , 0 ));
108+
109+ robot.update (Point (filtPoint.x ,filtPoint.y ), filterDir);
110+ players.push_back (robot);
111+
112+ cv::circle (debugFrame, Utils::convertPositionCmToPixel (newPosition), 15 , _colorCar[teamColor], 2 , cv::LINE_AA);
113+ cv::circle (debugFrame, Utils::convertPositionCmToPixel (newPosition), 12 , _colorCar[teamColor], 2 , cv::LINE_AA);
114+ }
115+ }
95116}
96117
97118void PositionProcessing::findEnemys (Entities &players, cv::Mat& debugFrame, std::vector<Region> &enemyRegions) {
98119
99120 players.clear ();
100121
101- // std::bitset<MAX_PLAYERS> markedColors;
102122 uint teamColor = this ->_teamId == Color::YELLOW ? Color::BLUE : Color::YELLOW;
103123
104-
105124 for (Region ®ion : enemyRegions) {
106125 if (region.distance < blobMaxDist ()) {
107- int colorIndex = region.color ;
108- Blob b1, b2 ;
109- std::tie (b1 , b2) = region. blobs ;
126+ int colorIndex = region.blobs [ 0 ]. color ;
127+ Blobs blobs = region. blobs ;
128+ Blob b1 = blobs[ 0 ] , b2 = blobs[ 1 ] ;
110129 Player robot ((teamColor-1 )*100 + static_cast <uint>(colorIndex) - Color::RED);
111130 robot.team (teamColor);
112131 Point newPositionInPixels = b2.position ;
@@ -115,7 +134,7 @@ void PositionProcessing::findEnemys(Entities &players, cv::Mat& debugFrame, std:
115134 // Debug
116135 cv::circle (debugFrame, newPositionInPixels, 12 , _colorCar[colorIndex], 2 , cv::LINE_AA);
117136
118- Float newAngle = Utils::angle (b2.position , b2 .position );
137+ Float newAngle = Utils::angle (b2.position , b1 .position );
119138 robot.update (newPosition, newAngle);
120139 players.push_back (robot);
121140 }
@@ -210,11 +229,101 @@ std::pair<PositionProcessing::Blob, PositionProcessing::NearestBlobInfo> Positio
210229
211230 result.distance = dMin;
212231 result.teamIndex = team;
232+ choosen.color = team;
213233
214234 return std::make_pair (choosen,result);
215235
216236}
217237
238+ void PositionProcessing::filterPattern (Regions ®ions) {
239+
240+ Regions f_regions;
241+ // Sort regions by leftmost blob
242+ for (auto &r : regions) {
243+ if (r.blobs .size () < 3 ) {
244+ continue ;
245+ }
246+
247+ Point b0 = r.blobs [0 ].position ;
248+ Point b1 = r.blobs [1 ].position ;
249+ Point b2 = r.blobs [2 ].position ;
250+
251+ // Compute robot center:
252+ Point robot = 0.5 * (b0 + 0.5 * (b1 + b2));
253+
254+ // Compute robot x and y axis vectors:
255+ Point vx = 0.5 * (b1 + b2) - robot;
256+ Point vy (-vx.y , vx.x );
257+
258+ // Compute b2 projection on vy
259+ // Swap blobs if projection is positive (should be the opposite, but it worked this way!)
260+ bool swap_blobs = ((b2.x -robot.x )*vy.x +(b2.y -robot.y )*vy.y >0 );
261+
262+ if (swap_blobs) {
263+ std::swap (r.blobs [1 ], r.blobs [2 ]);
264+ }
265+
266+ f_regions.push_back (r);
267+
268+ // cv::Point b2 = (r.blobs[1].position + r.blobs[2].position) * 0.5;
269+ //
270+ //
271+ // double angleThreshold = 10.0 * (M_PI / 180.0);
272+ // double angleDiffTo180 = std::abs(std::abs(Utils::angle(b2, b1)) - M_PI);
273+ //
274+ // if(std::abs(Utils::angle(b2, b1)) < angleThreshold || angleDiffTo180 < angleThreshold) {
275+ //
276+ // if (r.blobs[0].position.x > (r.blobs[1].position.x + r.blobs[2].position.x) / 2) {
277+ // if(r.blobs[1].position.y > r.blobs[2].position.y){
278+ // std::swap(r.blobs[1], r.blobs[2]);
279+ // }
280+ // }else{
281+ // if(r.blobs[1].position.y < r.blobs[2].position.y){
282+ // std::swap(r.blobs[1], r.blobs[2]);
283+ // }
284+ // }
285+ // }
286+ // else if(r.blobs[0].position.y < (r.blobs[1].position.y + r.blobs[2].position.y)/2) // Primary blob on top
287+ // {
288+ // if(r.blobs[1].position.x > r.blobs[2].position.x)
289+ // {
290+ // std::swap(r.blobs[1], r.blobs[2]);
291+ // }
292+ // }
293+ // else if(r.blobs[1].position.x < r.blobs[2].position.x) // Primary blob on bottom
294+ // {
295+ // std::swap(r.blobs[1], r.blobs[2]);
296+ // }
297+ // f_regions.push_back(r);
298+ }
299+ regions = f_regions;
300+ }
301+
302+ void PositionProcessing::filterTeam (Regions ®ions) {
303+ std::unordered_map<int ,Region> t_regions;
304+ Regions r_regions;
305+
306+ for (auto &r : regions) {
307+ int id = r.blobs [0 ].id ;
308+ if (t_regions.find (id) == t_regions.end ()) { // Didn't found region of with given id
309+ t_regions[id] = r; // Then, associate it with this region
310+ } else {
311+ Region &t_r = t_regions[r.blobs [0 ].id ]; // Get already existing region of same id
312+ t_r.blobs .push_back (r.blobs [1 ]); // Insert second secondary color
313+ }
314+ }
315+
316+ // Set all of the new merged regions into a vector
317+ for (auto &r_t : t_regions) {
318+ r_regions.push_back (r_t .second );
319+ }
320+ // Sort them by first blob id
321+ std::sort (r_regions.begin (),r_regions.end ());
322+
323+ // Update regions with filtered blobs
324+ regions.assign (r_regions.begin (),r_regions.end ());
325+ }
326+
218327PositionProcessing::FieldRegions PositionProcessing::pairBlobs () {
219328 FieldRegions result;
220329 std::pair<Blob, NearestBlobInfo> primary;
@@ -223,38 +332,44 @@ PositionProcessing::FieldRegions PositionProcessing::pairBlobs() {
223332 for (int idColor = Color::RED ; idColor < Color::BROWN+1 ; idColor++) {
224333 for (int i = 0 ; i < CLUSTERSPERCOLOR ; i++) {
225334 if (blob[idColor][i].valid ) {
335+ current.blobs .clear ();
226336 primary = this ->getNearestPrimary (blob[idColor][i]);
337+ blob[idColor][i].color = idColor;
227338
228- current.blobs = std::make_pair (blob[idColor][i], primary.first );
339+ current.blobs .push_back (primary.first );
340+ current.blobs .push_back (blob[idColor][i]);
229341 current.team = primary.second .teamIndex ;
230- current.color = idColor;
231342
232343 current.distance = primary.second .distance ;
233344 if (current.team == this ->_teamId ) result.team .push_back (current);
234- else if (USE_PATTERN_FOR_ENEMIES) result.enemys .push_back (current);
345+ else if (USE_PATTERN_FOR_ENEMIES) result.enemies .push_back (current);
235346 } else break ;
236347 }
237348 }
238349
239- if (!USE_PATTERN_FOR_ENEMIES && (result.enemys .empty () || result.enemys .size () < 3 ))
350+ if (!USE_PATTERN_FOR_ENEMIES && (result.enemies .empty () || result.enemies .size () < 3 ))
240351 {
241- int idColor = this ->_teamId == Color::YELLOW ? Color::BLUE : Color::YELLOW;
242- int qnt = 0 ;
243- for (int i = 0 ; i < CLUSTERSPERCOLOR ; i++) {
244- if (blob[idColor][i].valid ) {
245-
246- current.blobs = std::make_pair (blob[idColor][i], blob[idColor][i]);
247- current.team = idColor;
248- current.color = Color::RED + qnt++;
249- current.distance = 0.0 ;
250- result.enemys .push_back (current);
251- }
352+ int idColor = this ->_teamId == Color::YELLOW ? Color::BLUE : Color::YELLOW;
353+ int qnt = 0 ;
354+ for (int i = 0 ; i < CLUSTERSPERCOLOR ; i++) {
355+ if (blob[idColor][i].valid ) {
356+ current.blobs .clear ();
357+
358+ blob[idColor][i].color = current.team ;
359+ current.blobs .push_back (blob[idColor][i]);
360+ current.blobs .push_back (blob[idColor][i]);
361+ current.team = idColor;
362+ current.distance = 0.0 ;
363+ result.enemies .push_back (current);
252364 }
365+ }
253366 }
367+ filterTeam (result.team );
368+ filterTeam (result.enemies );
369+
254370 return result;
255371}
256372
257-
258373void PositionProcessing::setUp (std::string var, int value)
259374{
260375 this ->param [var] = value;
@@ -388,4 +503,20 @@ int PositionProcessing::blobMaxDist() {
388503 return _blobMaxDist;
389504}
390505
506+ int PositionProcessing::newId (int oldId){
507+ int id = 255 ;
508+
509+ auto it = std::find (idGenerated.begin (), idGenerated.end (), oldId);
510+
511+ if (it != idGenerated.end ()){
512+ id = std::distance (idGenerated.begin (), it);
513+ } else {
514+ it = std::find (idGenerated.begin (), idGenerated.end (), oldId-1 );
515+ if (it != idGenerated.end ()){
516+ id = std::distance (idGenerated.begin (), it);
517+ }
518+ }
519+ return id;
520+ }
521+
391522
0 commit comments