Car/TaiChi/routeTaiChi.cpp

398 lines
12 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <Arduino.h>
#include "routeTaiChi.h"
#ifdef ROUTE_DEBUG
#include <NeoHWSerial.h>
#endif
//静态变量
Point* Route::head_point = NULL;
Point* Route::passed_point = NULL;
Route::Route()
{
//生成基本路径点链
InitBaseRoute();
//设置 passed_point = head_point
passed_point = head_point;
}
Point Route::GetPassedPoint(void)
{
return *passed_point;
}
Point Route::GetNextPoint(void)
{
return *passed_point->next;
}
Point Route::GetNextNextPoint(void)
{
return *passed_point->next->next;
}
void Route::SetPassedPoinType(uint8_t type)
{
SetPointType(passed_point, type);
}
void Route::SetNextPointType(uint8_t type)
{
SetPointType(passed_point->next, type);
}
void Route::SetNextNextPointType(uint8_t type)
{
SetPointType(passed_point->next->next, type);
}
//更新位置
void Route::UpdatePosition(void)
{
passed_point = passed_point->next;
#ifdef ROUTE_DEBUG
NeoSerialDebug.println(F("#ROUTE: UPDATE POSITION!"));
#endif
}
//更改路径
void Route::ChangeRoute(uint8_t choice)
{
switch (choice)
{
case JUMP_DEAD_ROAD:
{
Connect(passed_point, passed_point->next->next->next);
}
}
}
//设置点的 x 值
void Route::SetPointX(Point* point, int8_t x)
{
point->x = x;
}
//设置点的 y 值
void Route::SetPointY(Point* point, int8_t y)
{
point->y = y;
}
//设置点的 type 值
void Route::SetPointType(Point* point, uint8_t type)
{
point->type = type;
}
//设置点的 next 值
void Route::SetPointNext(Point* point, Point* next)
{
point->next = next;
}
//新建点
Point* Route::CreatePoint(int8_t x, int8_t y, uint8_t type)
{
Point* point = new Point;
SetPointX(point, x);
SetPointY(point, y);
SetPointType(point, type);
SetPointNext(point, NULL);
return point;
}
//连接 point_a 和 point_b使 point_a->next == point_b
//在主点链存在的情况下point_a 和 point_b 必须属于主点链,否则可能出现不可预料的结果。函数不对 point_a 和 point_b 是否属于主点链进行检查
//在主点链不存在的情况下point_a 和 point_b 必须属于单向点链,否则可能出现不可预料的结果。函数不对 point_a 和 point_b 是否属于单向点链进行检查
//若主点链为单向point_a 在 point_b 之前,则 point_a 和 point_b 之间的点将被删除
//若主点链为环形head_point 不在 point_a point_b 之间,则 point_a 和 point_b 之间的点将被删除
//若主点链为单向point_a 在 point_b 之后,则 point_b 之前和 point_a 之后的点将被删除point_b 成为 head_point形成环形点链
//若主点链为环形head_point 在 point_b point_a 之间,则 point_b point_a 之间的点将被删除point_b 成为 head_point
//若主点链为单向point_b head_point 均不为空,但 point_a 为空,则从 head_point 开始删除,并将 point_b 作为 head_point
//若主点链为环形point_b head_point 均不为空,但 point_a 为空,则从 head_point 开始删除,并将 point_b 作为 head_point形成单向点链
//若 point_a point_b 均不为空,但 head_point 为空(主点链不存在),则 point_a 成为 head_pointpoint_a 之前的点和 point_b 之前、之后的点不会被删除point_a 之后的点会被删除
//若 point_b 不为空point_a head_point 均为空(主点链不存在),则 point_b 成为 head_pointpoint_b 之后的点不会被删除
//若主点链为单向point_a head_point 均不为空,但 point_b 为空,则从 point_a 的下一点开始删除point_a 作为末尾点
//若主点链为环形point_a head_point 均不为空,但 point_b 为空,则从 point_a 的下一点开始删除point_a 作为末尾点,形成单向点链
//若 head_point 不为空point_a point_b 均为空,则删除整个点链
//若 point_a point_b head_point 均为空,不进行操作
void Route::Connect(Point* point_a, Point* point_b)
{
if (point_b) //point_b 不为空
{
if (head_point) //head_point 不为空
{
Point* temp_point;
Point* delete_point;
if (point_a) //point_a 不为空,则从 point_a 的下一点开始删除,并连接 point_a 和 point_b
{
temp_point = point_a->next;
point_a->next = point_b;
}
else //point_a 为空,则从 head_point 开始删除,并将 point_b 作为 head_point
{
temp_point = point_b;
while (!temp_point)
{
if (temp_point->next == head_point) //为环形链表,将尾部 next 置空,使其变为单向链表
temp_point->next = NULL;
temp_point = temp_point->next;
}
temp_point = head_point;
head_point = point_b;
}
while (temp_point != point_b)
{
if (!temp_point) //point_a 在 point_b 之后,则从 head_point 开始删除,并将 point_b 作为 head_point
{
temp_point = head_point;
head_point = point_b;
continue;
}
else if (temp_point == head_point) //主点链为环,且 head_point 在 point_b point_a 之间,则将 point_b 作为 head_point
{
head_point = point_b;
}
delete_point = temp_point;
temp_point = temp_point->next;
delete delete_point;
}
}
else if (point_a) //head_point 为空point_a 不为空,则 point_a 作为 head_point删除 point_a 之后的点
{
Point* temp_point;
Point* delete_point;
temp_point = point_a->next;
point_a->next = point_b;
head_point = point_a;
while (temp_point && temp_point != point_a)
{
delete_point = temp_point;
temp_point = temp_point->next;
delete delete_point;
}
}
else //head_point 为空point_a 为空,则 point_b 作为 head_point
{
head_point = point_b;
}
}
else //point_b 为空
{
if (head_point) //head_point 不为空
{
Point* temp_point;
Point* delete_point;
Point* former_head_point = head_point;
if (point_a) //point_a 不为空,则从 point_a 的下一点开始删除point_a 作为末尾点
{
temp_point = point_a->next;
point_a->next = NULL;
}
else //point_a 为空,则删除整个点链
{
temp_point = head_point;
head_point = NULL;
}
while (temp_point)
{
delete_point = temp_point;
temp_point = temp_point->next;
delete delete_point;
if (temp_point == former_head_point) //为环形链表,将尾部 next 置空,使其变为单向链表
temp_point->next = NULL;
}
}
else if (point_a) //head_point 为空point_a 不为空,则 point_a 作为 head_point删除point_a 之后的点
{
Point* temp_point;
Point* delete_point;
temp_point = point_a->next;
point_a->next = NULL;
head_point = point_a;
while (temp_point)
{
delete_point = temp_point;
temp_point = temp_point->next;
delete delete_point;
}
}
//head_point 为空point_a 为空,无需进行操作
}
}
//在 front_point 和 next_point 间插入新的点
//front_point 和 next_point 必须属于主点链
//将首先连接 front_point 和 next_point具体规则参见 Connect 函数
//若 front_point 为空,则新建的 point 为初始点
//若 next_point 为空,则新建的 point 为末尾点
//若 front_point 和 next_point 均为空,则删除整个点链,新建的 point 为初始点
Point* Route::AddPoint(Point* front_point, int8_t x, int8_t y, uint8_t type, Point* next_point)
{
Point* point = CreatePoint(x, y, type);
//连接 front_point 和 next_point
Connect(front_point, next_point);
if (front_point)
front_point->next = point;
else head_point = point; //若 front_point 为空,则新建的 point 为初始点
point->next = next_point;
return point;
}
//生成基本路径点链
void Route::InitBaseRoute(void)
{
//基本路径数组
const static int8_t base_route [][3] =
{
{0, 0, NORMAL_POINT},
{0, 1, NORMAL_POINT},
{1, 1, CATCH_POINT},
{2, 1, NORMAL_POINT},
{2, 2, CARRY_POINT},
{2, 3, NORMAL_POINT},
{3, 3, GETOUT_POINT},
{2, 3, NORMAL_POINT},
{2, 4, NORMAL_POINT},
{3, 4, RELEASE_POINT},
{2, 4, NORMAL_POINT},
{2, 3, NORMAL_POINT},
{1, 3, NORMAL_POINT},
{0, 3, NORMAL_POINT},
{-1, 3, NORMAL_POINT},
{-1, 4, GAIN_POINT},
{-1, 3, NORMAL_POINT},
{0, 3, NORMAL_POINT},
{1, 3, NORMAL_POINT},
{2, 3, NORMAL_POINT},
{2, 4, NORMAL_POINT},
{3, 4, RELEASE_POINT},
{2, 4, NORMAL_POINT},
{2, 3, NORMAL_POINT},
{1, 3, NORMAL_POINT},
{0, 3, NORMAL_POINT},
{0, 2, CATCH_POINT},
{1, 2, NORMAL_POINT},
{2, 2, NORMAL_POINT},
{3, 2, RELEASE_POINT},
{2, 2, NORMAL_POINT},
{1, 2, NORMAL_POINT},
{1, 1, NORMAL_POINT},
{0, 1, NORMAL_POINT},
{-1, 1, CATCH_POINT},
{-2, 1, NORMAL_POINT},
{-2, 2, CARRY_POINT},
{-1, 2, NORMAL_POINT},
{0, 2, NORMAL_POINT},
{0, 3, NORMAL_POINT},
{1, 3, NORMAL_POINT},
{2, 3, NORMAL_POINT},
{3, 3, GETOUT_POINT},
{2, 3, NORMAL_POINT},
{2, 2, NORMAL_POINT},
{3, 2, RELEASE_POINT},
{-1, 1, CARRY_POINT},
{-2, 1, NORMAL_POINT},
{-2, 2, CARRY_POINT},
{-1, 2, NORMAL_POINT},
{0, 2, CATCH_POINT},
{0, 3, NORMAL_POINT},
{1, 3, NORMAL_POINT},
{2, 3, NORMAL_POINT},
{3, 3, GETOUT_POINT},//
{2, 3, NORMAL_POINT},
{2, 4, NORMAL_POINT},
{3, 4, RELEASE_POINT},//
{2, 4, NORMAL_POINT},
{2, 3, NORMAL_POINT},
{2, 2, CATCH_POINT},
{3, 2, RELEASE_POINT},//
{2, 2, NORMAL_POINT},
{2, 1, NORMAL_POINT},
{1, 1, CATCH_POINT},
{1, 2, NORMAL_POINT},
{1, 3, NORMAL_POINT},
{2, 3, NORMAL_POINT},
{2, 4, NORMAL_POINT},
{3, 4, RELEASE_POINT},//
{2, 4, NORMAL_POINT},
{2, 5, NORMAL_POINT},
{2, 6, CATCH_POINT},
{3, 6, RELEASE_POINT},//
{2, 6, NORMAL_POINT},
{2, 7, NORMAL_POINT},
{1, 7, CATCH_POINT},
{0, 7, NORMAL_POINT},
{0, 6, CARRY_POINT},
{0, 5, NORMAL_POINT},
{1, 5, NORMAL_POINT},
{2, 5, NORMAL_POINT},
{3, 5, GETOUT_POINT},//
{2, 5, NORMAL_POINT},
{2, 4, NORMAL_POINT},
{3, 4, RELEASE_POINT}//
};
//计算数组元素个数
int route_amount = sizeof(base_route) / sizeof(base_route[0]);
//生成基本路径点链
Point* temp_point = NULL;
for (int i = 0; i < route_amount; i++)
temp_point = AddPoint(temp_point, base_route[i][X], base_route[i][Y], base_route[i][TYPE]);
//生成环形点链
Connect(temp_point, head_point);
}