背景
对于高校或自动驾驶爱好者,跑通整套自动驾驶框架难度较大,所需精力较多。前面博客已经介绍了如何使用仿真来数据pnc代码,但control模块对实车动力学和线控系统依赖比较大,不同车辆不同线控会有不同的性能表现。因此,本文实现学习人工驾驶数据的方式,来调试实车control模块,从而达到提高实车调试效率的目的。
实现原理
在人工驾驶下,基于车上搭载的惯性导航设备,底盘线控信号,录取驾驶数据;基于录取的驾驶数据,做成类似planning的trajectory轨迹,供control模块解耦调试。
代码示例
录取人工驾驶数据的脚本tracking_recorder.cc示例
#include <cstdio>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "module/control/common/control_gflags.h"
#include "cyber/common/file.h"
#include "cyber/common/log.h"
#include "cyber/cyber.h"
#include "cyber/init.h"
#include "cyber/time/rate.h"
#include "cyber/time/time.h"
#include "gflags/gflags.h"
#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/math/math_utils.h"
#include "modules/common/utility/time/time.h"
#include "modules/common/utility/util/string_util.h"
#include "modules/common_msgs/localization_msgs/localization.pb.h"
#include "modules/common_msgs/chassis_msgs/chassis.pb.h"
#include "modules/common_msgs/sal/dmi/dmi.pb.h"
#include "modules/common_msgs/basic_msgs/pnc_point.pb.h"
using namespace std;
using apollo::cyber::Rapolloer;
using apollo::cyber::Time;
using apollo::canbus::Chassis;
using apollo::common::TrajectoryPoint;
using apollo::common::math::Clamp;
using apollo::common::math::fast_sqrtf;
using apollo::common::time::Clock;
using apollo::common::util::StrCat;
using apollo::localization::LocalizationEstimate;
using std::this_thrapollo::sleep_for;
DEFINE_double(feed_frequency, 100.0,
"Frequency with which protos are fed to control.");
DEFINE_bool(enable_speed_caculate_acc, false,
"caculate acceleration base speed.");
DEFINE_bool(enable_wheel_speed, false, "use wheel speed or not.");
DEFINE_bool(enable_localization_acc, false,
"use localization acceleration or not.");
struct TrackingRecorderStatus {
double carx;
double cary;
double carz;
double carspeed;
double caracceleration;
double carcurvature;
double carcurvature_change_rate;
double cartime;
double cartheta;
apollo::canbus::Chassis::GearPosition cargear;
double cars;
double throttle_percentage;
double brake_percentage;
double steering_percentage;
double chassis_acc;
};
double carmax_steer_angle = 490;
double carsteer_ratio = 20;
double carwheel_base = 2.87;
double last_carcurvature = 0.0;
double speed_epsilon = 1e-9;
double last_carspeed = 0.0;
double pre_acc = 0.0;
void ProcessLogs(const TrackingRecorderStatus *trackingrecorder_status);
void WriteHapolloers(std::ofstream &file_stream);
std::string GetLogFileName();
std::ofstream rtk_recorder_log_file_;
std::string GetLogFileName() {
time_t raw_time;
char name_buffer[80];
char sub_name_buffer[80];
std::time(&raw_time);
memset(sub_name_buffer, 0, sizeof(sub_name_buffer));
// std::string str = FLAGS_control_log_path;
std::string str = "/ssdata/log/control_log";
strcpy(sub_name_buffer, str.data());
strcat(sub_name_buffer, "/garage_%F_%H%M%S.csv");
strftime(name_buffer, 80, sub_name_buffer, localtime(&raw_time));
return std::string(name_buffer);
}
void WriteHapolloers(std::ofstream &file_stream) {
file_stream << "carx,"
<< "cary,"
<< "carz,"
<< "carspeed,"
<< "caracceleration,"
<< "carcurvature,"
<< "carcurvature_change_rate,"
<< "cartime,"
<< "cartheta,"
<< "cargear,"
<< "cars,"
<< "throttle_percentage,"
<< "brake_percentage,"
<< "steering_percentage,"
<< "chassis_acc" << std::endl;
}
void ProcessLogs(const TrackingRecorderStatus *trackingrecorder_status) {
const std::string log_str = StrCat(
StrCat(trackingrecorder_status->carx, ",", trackingrecorder_status->cary, ",",
trackingrecorder_status->carz, ",", trackingrecorder_status->carspeed, ","),
StrCat(trackingrecorder_status->caracceleration, ",",
trackingrecorder_status->carcurvature, ",",
trackingrecorder_status->carcurvature_change_rate, ",",
trackingrecorder_status->cartime, ","),
StrCat(trackingrecorder_status->cartheta, ",", trackingrecorder_status->cargear,
",", trackingrecorder_status->cars, ",",
trackingrecorder_status->throttle_percentage, ","),
StrCat(trackingrecorder_status->brake_percentage, ",",
trackingrecorder_status->steering_percentage, ",",
trackingrecorder_status->chassis_acc));
rtk_recorder_log_file_ << log_str << std::endl;
}
int main(int argc, char **argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
apollo::cyber::Init(argv[0]);
FLAGS_alsologtostderr = true;
rtk_recorder_log_file_.open(GetLogFileName());
rtk_recorder_log_file_ << std::fixed;
rtk_recorder_log_file_ << std::setprecision(6);
WriteHapolloers(rtk_recorder_log_file_);
shared_ptr<apollo::cyber::Node> node(
apollo::cyber::CreateNode("rtk_recorder"));
auto localization_ins_rapolloer = node->CreateRapolloer<LocalizationEstimate>(
FLAGS_localization_global_result_topic, nullptr);
auto chassis_rapolloer =
node->CreateRapolloer<Chassis>(FLAGS_chassis_topic, nullptr);
auto dmi_rapolloer = node->CreateRapolloer<apollo::sal::dmi::DMIRawDatas>(
FLAGS_dmi_raw_topic, nullptr);
TrackingRecorderStatus trackingrecorderstatus;
// init trackingrecorderstatus
trackingrecorderstatus.carx = 0.0;
trackingrecorderstatus.cary = 0.0;
trackingrecorderstatus.carz = 0.0;
trackingrecorderstatus.carspeed = 0.0;
trackingrecorderstatus.caracceleration = 0.0;
trackingrecorderstatus.carcurvature = 0.0;
trackingrecorderstatus.carcurvature_change_rate = 0.0;
trackingrecorderstatus.cartime = 0.0;
trackingrecorderstatus.cartheta = 0.0;
trackingrecorderstatus.cargear = apollo::canbus::Chassis::GEAR_NEUTRAL;
trackingrecorderstatus.cars = 0.0;
trackingrecorderstatus.throttle_percentage = 0.0;
trackingrecorderstatus.brake_percentage = 0.0;
trackingrecorderstatus.steering_percentage = 0.0;
trackingrecorderstatus.chassis_acc = 0.0;
while (apollo::cyber::OK()) {
double current_timestamp = Clock::NowInSeconds();
localization_ins_rapolloer->Observe();
chassis_rapolloer->Observe();
dmi_rapolloer->Observe();
const auto &localization_ins_msg =
localization_ins_rapolloer->GetLatestObserved();
const auto &chassis_msg = chassis_rapolloer->GetLatestObserved();
const auto &dmi_msg = dmi_rapolloer->GetLatestObserved();
trackingrecorderstatus.cartime = current_timestamp;
if (localization_ins_msg == nullptr) {
cout << "localization_ins_msg is empty!" << endl;
} else {
trackingrecorderstatus.carx = localization_ins_msg->global_localization().pose().position().x();
trackingrecorderstatus.cary = localization_ins_msg->global_localization().pose().position().y();
trackingrecorderstatus.carz = localization_ins_msg->global_localization().pose().position().z();
trackingrecorderstatus.cartheta =
localization_ins_msg->global_localization().pose().euler_angles().yaw();
trackingrecorderstatus.caracceleration = fast_sqrtf(
localization_ego_msg->local_localization().motion().linear_accel().x() *
localization_ego_msg->local_localization().motion().linear_accel().x() +
localization_ego_msg->local_localization().motion().linear_accel().y() *
localization_ego_msg->local_localization().motion().linear_accel().y());
if (trackingrecorderstatus.chassis_acc < 0) {
trackingrecorderstatus.caracceleration =
-trackingrecorderstatus.caracceleration;
}
cout << "Record log..." << endl;
}
if (chassis_msg == nullptr) {
cout << "localization_ins_msg is empty!" << endl;
} else {
if (!FLAGS_enable_wheel_speed) {
trackingrecorderstatus.carspeed = chassis_msg->speed_mps();
}
trackingrecorderstatus.chassis_acc = chassis_msg->acc_o();
if (!FLAGS_enable_speed_caculate_acc && !FLAGS_enable_localization_acc) {
trackingrecorderstatus.caracceleration = chassis_msg->acc_o();
}
trackingrecorderstatus.cargear = chassis_msg->gear_location();
trackingrecorderstatus.throttle_percentage = 0.0;
trackingrecorderstatus.brake_percentage = 0.0;
trackingrecorderstatus.steering_percentage =
chassis_msg->steering_percentage();
if (fabs(trackingrecorderstatus.carspeed) < speed_epsilon &&
fabs(last_carspeed) < speed_epsilon) {
trackingrecorderstatus.carcurvature = 0.0;
} else {
trackingrecorderstatus.carcurvature =
tan(chassis_msg->steering_percentage() / 100 * carmax_steer_angle *
(M_PI / 180) / carsteer_ratio) /
carwheel_base;
}
if (fabs(trackingrecorderstatus.carspeed) >= speed_epsilon) {
trackingrecorderstatus.carcurvature_change_rate =
(trackingrecorderstatus.carcurvature - last_carcurvature) /
(trackingrecorderstatus.carspeed * 0.01);
} else {
trackingrecorderstatus.carcurvature_change_rate = 0.0;
}
if (FLAGS_enable_speed_caculate_acc) {
trackingrecorderstatus.caracceleration =
(trackingrecorderstatus.carspeed - last_carspeed) /
(1 / FLAGS_feed_frequency);
}
trackingrecorderstatus.caracceleration =
apollo::common::math::Clamp(trackingrecorderstatus.caracceleration, -4.5, 4.0);
trackingrecorderstatus.caracceleration =
(pre_acc + trackingrecorderstatus.caracceleration) / 2;
pre_acc = trackingrecorderstatus.caracceleration;
last_carcurvature = trackingrecorderstatus.carcurvature;
last_carspeed = trackingrecorderstatus.carspeed;
trackingrecorderstatus.cars +=
trackingrecorderstatus.carspeed * (1 / FLAGS_feed_frequency);
cout << "Record localization_ins_msg..." << endl;
}
if (dmi_msg == nullptr) {
cout << "dmi_msg is empty!" << endl;
} else {
if (FLAGS_enable_wheel_speed) {
trackingrecorderstatus.carspeed =
(dmi_msg->wheel_speed_lr().speed() + dmi_msg->wheel_speed_rr().speed()) / 2;
}
cout << "Record dmi_msg data..." << endl;
}
ProcessLogs(&trackingrecorderstatus);
sleep_for(chrono::milliseconds(1000 / (int)FLAGS_feed_frequency));
}
return 0;
}
```
在tracking_recorder.cc录取好人工驾驶数据后,需要对数据进行分析,筛选出合理的数据,再给tracking_player.cc使用。
基于人工驾驶数据生成轨迹的tracking_player.cc示例:
```cpp
#include <cstdio>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "corelib/control/common/control_gflags.h"
#include "cyber/common/file.h"
#include "cyber/common/log.h"
#include "cyber/cyber.h"
#include "cyber/init.h"
#include "cyber/time/rate.h"
#include "cyber/time/time.h"
#include "gflags/gflags.h"
#include "idl/topic/adapterFlags.h"
#include "modules\common\math\math_utils.h"
#include "modules/common/utility/time/time.h"
#include "modules/common_msgs/localization_msgs/localization.pb.h"
#include "modules/common_msgs/planning_msgs/planning.pb.h"
#include "modules/common_msgs/chassis_msgs/chassis.pb.h"
#include "modules/common_msgs/sal/dmi/dmi.pb.h"
using namespace std;
using apollo::common::math::Clamp;
using apollo::common::time::Clock;
DEFINE_int32(feed_frequency, 10,
"Frequency with which protos are fed to control.");
DEFINE_double(speedmultiplier, 1.0, "Speed multiplier in percentage.");
DEFINE_double(replan_distance, 2.0,
"replan when distance is larger than replan_distance.");
DEFINE_string(
load_data_file,
"/ssdata/log/control_log/garage_2023-09_10_093859.csv",
"Used for load data from rtk_recorder.");
DEFINE_bool(enable_wheel_speed, false, "use wheel speed or not.");
#define SEARCH_INTERVAL 800
#define CHANGE_TO_COM false
struct TrackingPlayerStatus {
double carx;
double cary;
double carz;
double carspeed;
double caracceleration;
double carcurvature;
double carcurvature_change_rate;
double cartime;
double cartheta;
apollo::canbus::Chassis::GearPosition cargear;
double cars;
double throttle_percentage;
double brake_percentage;
double steering_percentage;
};
vector<vector<double>> test_data;
bool replan = false;
bool automode = false;
bool completepath = false;
bool estop = false;
double last_carspeed = 0.0;
double pre_acc = 0.0;
int closestpoint = 0;
double starttime = 0.0;
int start_ = 0;
int end_ = 0;
int data_size = 0;
double length = 4.986;
double back_edge_to_center = 1.1206;
int next_gear_switch_time(double start_, int length);
vector<vector<double>> LoadData(const char* strFilePath);
void restart(TrackingPlayerStatus* trackingplayer_status);
int closest_dist(TrackingPlayerStatus* trackingplayer_status);
int closest_time();
// void adc_position(apollo::pnc::planning::ADCTrajectory* planning_published_trajectory,
// const TrackingPlayerStatus* trackingplayer_status, const double time);
vector<vector<double>> LoadData(const char* strFilePath) {
// Read CSV Data
vector<vector<double>> vecData;
ifstream inFile(strFilePath);
string strLine;
int nRowCount = 0;
getline(inFile, strLine); // skip first row data
while (true) {
getline(inFile, strLine);
int nPos = strLine.find(",");
if (nPos < 0) break;
nRowCount++;
vector<double> vecTmp;
while (nPos > 0) {
string strTmp = strLine.substr(0, nPos);
double fTmp = atof(strTmp.c_str());
vecTmp.push_back(fTmp);
strLine.erase(0, nPos + 1);
nPos = strLine.find(",");
}
double fTmp = atof(strLine.c_str());
vecTmp.push_back(fTmp);
vecData.push_back(vecTmp);
}
int nColCount = 0;
if (nRowCount > 0) nColCount = vecData[0].size();
double fData[nRowCount][nColCount];
for (int nRow = 0; nRow < nRowCount; nRow++) {
vector<double> vecTmp = vecData[nRow];
vecTmp.resize(nColCount, 0);
for (int nCol = 0; nCol < nColCount; nCol++) {
fData[nRow][nCol] = vecTmp[nCol];
}
if (nRow < 5) cout << fData[nRow][0] << endl;
}
cout << "Data Row Count: " << nRowCount << " Column Count: " << nColCount << endl;
return vecData;
}
void restart(TrackingPlayerStatus* trackingplayer_status) {
replan = true;
cout << "replan!" << endl;
closestpoint = closest_dist(trackingplayer_status);
start_ = std::max(closestpoint - 1, 0);
starttime = Clock::NowInSeconds();
end_ = next_gear_switch_time(start_, data_size);
end_ = min(start_ + SEARCH_INTERVAL, data_size - 1); // add by cnblog
cout << "finish replan at time: " << starttime << '\t'
<< "closestpoint: " << closestpoint << endl;
}
int closest_dist(TrackingPlayerStatus* trackingplayer_status) {
double shortest_dist_sqr = std::numeric_limits<double>::infinity();
int search_start = std::max(start_ - (int)(SEARCH_INTERVAL / 2), 0);
int search_end = std::min(start_ + (int)(SEARCH_INTERVAL / 2), data_size);
int closest_dist_point = start_;
for (int i = search_start; i < search_end; i++) {
double dist_sqr = pow(trackingplayer_status->carx - test_data[i][0], 2) +
pow(trackingplayer_status->cary - test_data[i][1], 2);
if (dist_sqr <= shortest_dist_sqr &&
test_data[i][9] == trackingplayer_status->cargear) { // 9: cargear
closest_dist_point = i;
shortest_dist_sqr = dist_sqr;
}
}
if (shortest_dist_sqr == std::numeric_limits<double>::infinity()) {
cout << "no trajectory point matches current gear position, check gear "
"position"
<< endl;
return closest_dist_point + 1; // remain current start_ point
}
return closest_dist_point;
}
int closest_time() {
double time_elapsed = Clock::NowInSeconds() - starttime;
int closest_time = start_;
double time_diff =
test_data[closest_time][7] - test_data[closestpoint][7]; // 7: cartime
while (time_diff < time_elapsed && closest_time < data_size - 1) {
closest_time = closest_time + 1;
time_diff = test_data[closest_time][7] - test_data[closestpoint][7];
}
return closest_time;
}
int next_gear_switch_time(double start_, int length) {
int i = start_;
for (; i < length; i++) {
if (i < length - 1 &&
(test_data[i][9] == 1 || test_data[i][9] == 2) && // 9: cargear
test_data[i + 1][9] != test_data[i][9]) {
i += 1;
while (i < length && test_data[i][9] != 1 && test_data[i][9] != 2) {
i += 1;
}
return i - 1;
}
}
return min(i, length - 1);
}
void adc_position(apollo::pnc::planning::ADCTrajectory* planning_published_trajectory,
const TrackingPlayerStatus* trackingplayer_status, const double time) {
planning_published_trajectory->mutable_debug()
->mutable_planning_data()
->mutable_adc_position()
->mutable_header()
->set_timestamp(time);
planning_published_trajectory->mutable_debug()
->mutable_planning_data()
->mutable_adc_position()
->mutable_pose()
->mutable_position()
->set_x(trackingplayer_status->carx);
planning_published_trajectory->mutable_debug()
->mutable_planning_data()
->mutable_adc_position()
->mutable_pose()
->mutable_position()
->set_y(trackingplayer_status->cary);
planning_published_trajectory->mutable_debug()
->mutable_planning_data()
->mutable_adc_position()
->mutable_pose()
->mutable_position()
->set_z(trackingplayer_status->carz);
planning_published_trajectory->mutable_debug()
->mutable_planning_data()
->mutable_adc_position()
->mutable_pose()
->mutable_euler_angles()
->set_roll(0.0);
planning_published_trajectory->mutable_debug()
->mutable_planning_data()
->mutable_adc_position()
->mutable_pose()
->mutable_euler_angles()
->set_pitch(0.0);
planning_published_trajectory->mutable_debug()
->mutable_planning_data()
->mutable_adc_position()
->mutable_pose()
->mutable_euler_angles()
->set_yaw(trackingplayer_status->cartheta);
}
int main(int argc, char** argv) {
using apollo::cyber::Reader;
using apollo::cyber::Time;
using apollo::cyber::Writer;
using apollo::cyber::common::GetProtoFromFile;
using apollo::canbus::Chassis;
using apollo::localization::LocalizationEstimate;
using apollo::pnc::planning::ADCTrajectory;
using google::protobuf::TextFormat;
using google::protobuf::io::FileInputStream;
using google::protobuf::io::ZeroCopyInputStream;
using std::this_thread::sleep_for;
google::ParseCommandLineFlags(&argc, &argv, true);
apollo::cyber::Init(argv[0]);
FLAGS_alsologtostderr = true;
shared_ptr<apollo::cyber::Node> node(apollo::cyber::CreateNode("rtk_player"));
auto planning_writer =
node->CreateWriter<ADCTrajectory>(FLAGS_planning_trajectory_topic);
auto localization_reader = node->CreateReader<LocalizationEstimate>(
FLAGS_localization_global_result_topic, nullptr);
auto chassis_reader =
node->CreateReader<Chassis>(FLAGS_chassis_topic, nullptr);
auto dmi_reader = node->CreateReader<apollo::sal::dmi::DMIRawDatas>(
FLAGS_dmi_raw_topic, nullptr);
std::string str = FLAGS_load_data_file;
test_data = LoadData(str.data());
data_size = test_data.size();
TrackingPlayerStatus trackingplayerstatus;
// init trackingplayerstatus
trackingplayerstatus.carx = 0.0;
trackingplayerstatus.cary = 0.0;
trackingplayerstatus.carz = 0.0;
trackingplayerstatus.carspeed = 0.0;
trackingplayerstatus.caracceleration = 0.0;
trackingplayerstatus.carcurvature = 0.0;
trackingplayerstatus.carcurvature_change_rate = 0.0;
trackingplayerstatus.cartime = 0.0;
trackingplayerstatus.cartheta = 0.0;
trackingplayerstatus.cargear = apollo::canbus::Chassis::GEAR_NEUTRAL;
trackingplayerstatus.cars = 0.0;
trackingplayerstatus.throttle_percentage = 0.0;
trackingplayerstatus.brake_percentage = 0.0;
trackingplayerstatus.steering_percentage = 0.0;
int sequence_num = 0;
while (apollo::cyber::OK()) {
double current_timestamp = Clock::NowInSeconds();
localization_reader->Observe();
chassis_reader->Observe();
dmi_reader->Observe();
ADCTrajectory trajectory;
const auto& localization_ins_msg = localization_reader->GetLatestObserved();
const auto& chassis_msg = chassis_reader->GetLatestObserved();
const auto& dmi_msg = dmi_reader->GetLatestObserved();
if (localization_ins_msg == nullptr) {
cout << "localization_ins_msg is empty!" << endl;
} else {
trackingplayerstatus.carx = localization_ins_msg->global_localization().pose().position().x();
trackingplayerstatus.cary = localization_ins_msg->global_localization().pose().position().y();
trackingplayerstatus.carz = localization_ins_msg->global_localization().pose().position().z();
trackingplayerstatus.cartheta =
localization_ins_msg->global_localization().pose().euler_angles().yaw();
}
if (dmi_msg == nullptr) {
cout << "dmi_msg is empty!" << endl;
} else {
if (FLAGS_enable_wheel_speed) {
trackingplayerstatus.carspeed =
(dmi_msg->wheel_speed_lr().speed() + dmi_msg->wheel_speed_rr().speed()) / 2;
}
cout << "Record dmi_msg data..." << endl;
}
if (chassis_msg == nullptr) {
cout << "chassis_msg is empty!" << endl;
} else {
automode = chassis_msg->driving_mode() ==
apollo::canbus::Chassis::COMPLETE_AUTO_DRIVE
? true
: false;
if (!FLAGS_enable_wheel_speed) {
trackingplayerstatus.carspeed = chassis_msg->speed_mps();
}
trackingplayerstatus.cargear = chassis_msg->gear_location();
trackingplayerstatus.cars += trackingplayerstatus.carspeed * 0.01;
trackingplayerstatus.caracceleration =
(trackingplayerstatus.carspeed - last_carspeed) / 0.01;
trackingplayerstatus.caracceleration =
apollo::common::math::Clamp(trackingplayerstatus.caracceleration, -4.5, 4.0);
trackingplayerstatus.caracceleration =
(pre_acc + trackingplayerstatus.caracceleration) / 2;
last_carspeed = trackingplayerstatus.carspeed;
}
trajectory.mutable_header()->set_timestamp(current_timestamp);
trajectory.mutable_header()->mutable_module_info()->set_module_name("planning");
trajectory.mutable_header()->mutable_module_info()->set_module_id(1);
trajectory.mutable_header()->mutable_module_info()->set_sequence_num(sequence_num);
trajectory.mutable_debug()
->mutable_planning_data()
->mutable_scenario()
->set_scenario_type(apollo::pnc::planning::ScenarioConfig::LKA);
trajectory.set_is_replan(replan);
trajectory.set_trajectory_type(apollo::pnc::planning::ADCTrajectory::NORMAL);
sequence_num++;
if (sequence_num <= 1 || !automode) {
restart(&trackingplayerstatus);
} else {
replan = false;
int timepoint = closest_time();
int distpoint = closest_dist(&trackingplayerstatus);
if (test_data[timepoint][9] == test_data[distpoint][9]) { // 9: cargear
start_ = max(min(timepoint, distpoint), 0);
} else if (test_data[timepoint][9] == trackingplayerstatus.cargear) {
start_ = timepoint;
} else {
start_ = distpoint;
}
end_ = next_gear_switch_time(start_, data_size);
end_ = min(start_ + SEARCH_INTERVAL, data_size - 1); // add by cnblog
double xdiff_sqr = pow(test_data[timepoint][0] - trackingplayerstatus.carx, 2);
double ydiff_sqr = pow(test_data[timepoint][1] - trackingplayerstatus.cary, 2);
if (xdiff_sqr + ydiff_sqr >
FLAGS_replan_distance * FLAGS_replan_distance) {
cout << "distance is too far!" << endl;
if (end_ - start_ <= 2 &&
data_size - end_ <=
2) { // if finish the path from rtk_recorder, set estop!
estop = true;
} else {
restart(&trackingplayerstatus);
estop = false;
}
} else {
replan = false;
}
}
if (completepath) {
start_ = 0;
end_ = data_size - 1;
}
trajectory.set_total_path_length(test_data[end_][10] -
test_data[start_][10]);
// trajectory.set_gear(test_data[closest_time()][10]);
trajectory.set_gear(Chassis::GEAR_DRIVE);
trajectory.mutable_estop()->set_is_estop(estop);
// add for visulization adc_position
// adc_position(&trajectory, &trackingplayerstatus, current_timestamp);
auto path = trajectory.mutable_debug()->mutable_planning_data()->add_path();
path->set_name("DP_POLY_PATH_OPTIMIZER");
for (int i = start_; i < end_; i++) {
auto point = trajectory.add_trajectory_point();
point->mutable_path_point()->set_x(test_data[i][0]); // 0: carx
point->mutable_path_point()->set_y(test_data[i][1]); // 1: cary
point->mutable_path_point()->set_z(test_data[i][2]); // 2: carz
point->set_v(test_data[i][3] * FLAGS_speedmultiplier); // 3: carspeed
point->set_a(test_data[i][4] *
FLAGS_speedmultiplier); // 4: caracceleration
point->mutable_path_point()->set_kappa(
test_data[i][5]); // 5: carcurvature
point->mutable_path_point()->set_dkappa(
test_data[i][6]); // 6: carcurvature_change_rate
point->mutable_path_point()->set_theta(test_data[i][8]); // 8: cartheta
point->mutable_path_point()->set_s(test_data[i][10]); // 10: cars
auto path_point = path->add_path_point();
path_point->set_x(test_data[i][0]); // 0: carx
path_point->set_y(test_data[i][1]); // 1: cary
path_point->set_z(test_data[i][2]); // 2: carz
path_point->set_theta(test_data[i][8]); // 8: cartheta
path_point->set_kappa(test_data[i][5]); // 5: carcurvature
path_point->set_s(test_data[i][10]); // 10: cars
path_point->set_dkappa(test_data[i][6]); // 6: carcurvature_change_rate
path_point->set_ddkappa(0.0);
if (CHANGE_TO_COM) {
// translation vector length(length / 2 - back edge to center)
cout << "CHANGE_TO_COM" << endl;
point->mutable_path_point()->set_x(
point->mutable_path_point()->x() +
(length / 2 - back_edge_to_center) *
std::cos(point->mutable_path_point()->theta()));
point->mutable_path_point()->set_y(
point->mutable_path_point()->y() +
(length / 2 - back_edge_to_center) *
std::sin(point->mutable_path_point()->theta()));
}
double time_diff =
test_data[i][7] - test_data[closestpoint][7]; // 7: cartime
point->set_relative_time(time_diff - (current_timestamp - starttime));
}
planning_writer->Write(trajectory);
sleep_for(chrono::milliseconds(1000 / FLAGS_feed_frequency));
}
cout << "Successfully fed proto files." << endl;
return 0;
}