31using ::apollo::canbus::ChassisDetail;
32using ::apollo::v2x::CarStatus;
33using ::apollo::v2x::StatusResponse;
34using ::apollo::v2x::obu::ObuRsi;
35using ::apollo::v2x::obu::ObuTrafficLight;
38 if (recv_thread_ !=
nullptr && recv_thread_->joinable()) {
41 if (planning_thread_ !=
nullptr && planning_thread_->joinable()) {
42 planning_thread_->join();
44 if (obs_thread_ !=
nullptr && obs_thread_->joinable()) {
50 : node_(::
apollo::cyber::CreateNode(
"v2x_proxy")), exit_(false) {
51 if (node_ ==
nullptr) {
52 AFATAL <<
"Create v2x proxy node failed.";
55 internal_ = std::make_shared<InternalData>();
56 hdmap_ = std::make_shared<::apollo::hdmap::HDMap>();
58 if (0 != hdmap_->LoadMapFromFile(hdmap_file)) {
59 AERROR <<
"Failed to load hadmap file: " << hdmap_file;
63 v2x_car_status_timer_option.
period =
64 static_cast<uint32_t
>((1000 + FLAGS_v2x_car_status_timer_frequency - 1) /
65 FLAGS_v2x_car_status_timer_frequency);
66 v2x_car_status_timer_option.
callback = [
this]() {
67 this->OnV2xCarStatusTimer();
69 v2x_car_status_timer_option.
oneshot =
false;
70 v2x_car_status_timer_.reset(
71 new ::apollo::cyber::Timer(v2x_car_status_timer_option));
74 recv_thread_.reset(
new std::thread([
this]() {
75 while (!exit_.load()) {
76 this->RecvTrafficlight();
79 CHECK(!!hdmap_ && !!v2x_car_status_timer_);
80 CHECK(!!os_interface_ && !!obu_interface_);
81 CHECK(os_interface_->InitFlag() && obu_interface_->InitFlag());
82 planning_thread_.reset(
new std::thread([
this]() {
83 while (!exit_.load()) {
84 this->RecvOsPlanning();
87 obs_thread_.reset(
new std::thread([
this]() {
88 while (!exit_.load()) {
89 std::shared_ptr<::apollo::v2x::V2XObstacles> obs = nullptr;
90 this->obu_interface_->GetV2xObstaclesFromObu(&obs);
91 this->os_interface_->SendV2xObstacles2Sys(obs);
94 v2x_car_status_timer_->Start();
100 std::set<std::string> *whitelist) {
101 if (
nullptr == whitelist) {
104 std::ifstream input_file(filename);
109 while (getline(input_file, line)) {
110 whitelist->insert(line);
112 return !whitelist->empty();
117void V2xProxy::RecvOsPlanning() {
118 auto adc_trajectory = std::make_shared<::apollo::planning::ADCTrajectory>();
120 std::make_shared<::apollo::perception::TrafficLightDetection>();
121 os_interface_->GetPlanningAdcFromOs(adc_trajectory);
123 std::shared_ptr<OSLight> last_os_light =
nullptr;
125 std::lock_guard<std::mutex> lock(lock_last_os_light_);
128 if (last_os_light_ ==
nullptr ||
129 2000LL * 1000 * 1000 < now_us - ts_last_os_light_) {
130 AWARN <<
"V2X Traffic Light is too old!";
131 last_os_light_ =
nullptr;
133 ADEBUG <<
"V2X Traffic Light is on time.";
134 last_os_light = std::make_shared<OSLight>();
135 last_os_light->CopyFrom(*last_os_light_);
139 bool res_proc_planning_msg = internal_->ProcPlanningMessage(
140 adc_trajectory.get(), last_os_light.get(), &res_light);
141 if (!res_proc_planning_msg) {
144 os_interface_->SendV2xTrafficLight4Hmi2Sys(res_light);
147void V2xProxy::RecvTrafficlight() {
149 std::shared_ptr<ObuLight> x2v_traffic_light =
nullptr;
150 obu_interface_->GetV2xTrafficLightFromObu(&x2v_traffic_light);
151 os_interface_->SendV2xObuTrafficLightToOs(x2v_traffic_light);
152 auto os_light = std::make_shared<OSLight>();
153 std::string junction_id =
"";
155 std::lock_guard<std::mutex> lg(lock_hdmap_junction_id_);
156 junction_id = hdmap_junction_id_;
158 bool res_success_ProcTrafficlight = internal_->ProcTrafficlight(
159 hdmap_, x2v_traffic_light.get(), junction_id, u_turn_,
160 FLAGS_traffic_light_distance, FLAGS_check_time, &os_light);
161 if (!res_success_ProcTrafficlight) {
165 os_interface_->SendV2xTrafficLightToOs(os_light);
167 std::lock_guard<std::mutex> lock(lock_last_os_light_);
169 last_os_light_ = os_light;
173 const ::apollo::common::PointENU &p2) {
174 double x = p1.x() - p2.x();
175 double y = p1.y() - p2.y();
176 return std::sqrt(x * x + y * y);
179void V2xProxy::OnV2xCarStatusTimer() {
182 std::make_shared<::apollo::localization::LocalizationEstimate>();
183 os_interface_->GetLocalizationFromOs(localization);
184 if (
nullptr == localization) {
187 std::set<std::string> rsu_whitelist;
189 std::lock_guard<std::mutex> lg(rsu_list_mutex_);
190 rsu_whitelist.insert(rsu_list_.cbegin(), rsu_list_.cend());
193 car_position.set_x(localization->pose().position().x());
194 car_position.set_y(localization->pose().position().y());
195 std::shared_ptr<::apollo::v2x::CarStatus> v2x_car_status =
nullptr;
196 double heading = 0.0;
197 std::string res_junction_id =
"";
199 hdmap_, *localization, rsu_whitelist, FLAGS_traffic_light_distance,
200 FLAGS_heading_difference, &v2x_car_status, &res_junction_id, &heading);
202 std::lock_guard<std::mutex> lg(lock_hdmap_junction_id_);
203 hdmap_junction_id_ = res_junction_id;
205 if (!ret_get_rsu_info) {
209 if (!init_heading_) {
211 init_heading_ =
true;
213 if (std::fabs(heading_ - heading) > 1.0) {
216 obu_interface_->SendCarStatusToObu(v2x_car_status);
uint64_t ToMicrosecond() const
convert time to microsecond (us).
V2xProxy(std::shared_ptr<::apollo::hdmap::HDMap > hdmap=nullptr)
bool GetRsuListFromFile(const std::string &filename, std::set< std::string > *whitelist)
std::string BaseMapFile()
get base map file path from flags.
bool GetRsuInfo(const std::shared_ptr<::apollo::hdmap::HDMap > &hdmap, const OSLocation &os_location, const std::set< std::string > &rsu_whitelist, double distance, double max_heading_difference, std::shared_ptr<::apollo::v2x::CarStatus > *v2x_car_status, std::string *out_junction_id, double *out_heading)
void UniqueOslight(OSLight *os_light)
double cal_distance(const ::apollo::common::PointENU &p1, const ::apollo::common::PointENU &p2)
uint32_t period
The period of the timer, unit is ms max: 512 * 64 min: 1
bool oneshot
True: perform the callback only after the first timing cycle False: perform the callback every timed ...
std::function< void()> callback
The task that the timer needs to perform
The gflags used by v2x proxy module