Apollo 10.0
自动驾驶开放平台
sim_control_with_model_base.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2019 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
20
21namespace apollo {
22namespace dreamview {
23
32using apollo::common::util::FillHeader;
38using Json = nlohmann::json;
39
46 : node_(cyber::CreateNode(node_name)),
47 gear_position_(0),
48 dt_(0.01),
49 map_service_(new MapService()) {
51}
52
54 // Setup control result data callback.
55 cyber::ReaderConfig control_cmd_reader_config;
56 control_cmd_reader_config.channel_name = FLAGS_control_command_topic;
57 control_cmd_reader_config.pending_queue_size =
58 FLAGS_reader_pending_queue_size;
60 FLAGS_prediction_topic,
61 [this](const std::shared_ptr<PredictionObstacles>& obstacles) {
62 this->OnPredictionObstacles(obstacles);
63 });
65 FLAGS_planning_command,
66 [this](const std::shared_ptr<PlanningCommand>& planning_command) {
67 this->OnPlanningCommand(planning_command);
68 });
70 control_cmd_reader_config,
71 [this](const std::shared_ptr<ControlCommand>& cmd) {
72 ADEBUG << "Received control data: run canbus callback.";
73 OnControlCommand(*cmd);
74 });
75 // Setup localization callback.
76 cyber::ReaderConfig localization_reader_config;
77 localization_reader_config.channel_name = FLAGS_localization_topic;
78 localization_reader_config.pending_queue_size =
79 FLAGS_reader_pending_queue_size;
81 localization_reader_config, nullptr);
82
84 node_->CreateWriter<LocalizationEstimate>(FLAGS_localization_topic);
85 chassis_writer_ = node_->CreateWriter<Chassis>(FLAGS_chassis_topic);
87 node_->CreateWriter<PredictionObstacles>(FLAGS_prediction_topic);
88
89 // Start timer to publish localization and chassis messages.
91 new cyber::Timer(kModelIntervalMs, [this]() { this->RunOnce(); }, false));
94 [this]() { this->PublishDummyPrediction(); }, false));
95}
96
98 // update gear location, 1 drive, -1 reverse, 0 for other states
100 gear_position_ = 1;
102 gear_position_ = -1;
103 } else {
104 gear_position_ = 0;
105 }
106 current_point_.set_gear_position(gear_position_);
107}
108
110 const std::shared_ptr<PredictionObstacles>& obstacles) {
111 std::lock_guard<std::mutex> lock(mutex_);
112 if (!enabled_) {
113 return;
114 }
116 obstacles->header().module_name() == "SimDMPrediction";
117}
118
120 std::lock_guard<std::mutex> lock(mutex_);
121 if (!enabled_) {
123 // todo: Compatible with scenario conf and default value
124 Json start_point_attr({});
125 // start_point_attr:from scenario conf json or default value.here dm is
126 // divided from scenario use default value
127 start_point_attr["start_velocity"] = 0.0;
128 start_point_attr["start_acceleration"] = 0.0;
129 start_point_attr["start_heading"] = std::numeric_limits<double>::max();
130 Init(true, start_point_attr);
131 sim_control_timer_->Start();
132 sim_prediction_timer_->Start();
133 enabled_ = true;
134 }
135}
136
137void SimControlWithModelBase::Start(double x, double y, double v, double a) {
138 std::lock_guard<std::mutex> lock(mutex_);
139 if (!enabled_) {
141 Json start_point_attr({});
142 start_point_attr["start_velocity"] = v;
143 start_point_attr["start_acceleration"] = a;
144 start_point_attr["start_heading"] = std::numeric_limits<double>::max();
145 start_point_attr["x"] = x;
146 start_point_attr["y"] = y;
147 Init(true, start_point_attr, true);
148 sim_control_timer_->Start();
149 sim_prediction_timer_->Start();
150 enabled_ = true;
151 }
152}
153
155 double heading) {
156 std::lock_guard<std::mutex> lock(mutex_);
157 SimCarStatus point;
158 point.set_x(x);
159 point.set_y(y);
160 // z use default 0
161 point.set_z(0);
162 point.set_theta(heading);
163 SetStartPoint(point);
165}
166
168 std::lock_guard<std::mutex> lock(mutex_);
169
170 if (enabled_) {
171 sim_control_timer_->Stop();
172 sim_prediction_timer_->Stop();
173 enabled_ = false;
174 }
175}
176
178 std::lock_guard<std::mutex> lock(mutex_);
180}
181
190
192 const ControlCommand& control_cmd) {
193 std::lock_guard<std::mutex> lock(mutex_);
194 if (!enabled_) {
195 return;
196 }
197 control_cmd_ = control_cmd;
199 (control_cmd_.throttle() >= 0.01 || control_cmd.brake() >= 0.01);
202}
203
205 const std::shared_ptr<PlanningCommand>& planning_command) {
206 std::lock_guard<std::mutex> lock(mutex_);
207 if (!enabled_) {
208 return;
209 }
210 // Avoid not sending prediction messages to planning after playing packets
211 // with obstacles
212 start_auto_ = true;
214 current_routing_header_ = planning_command->header();
215 AINFO << "planning_command: " << planning_command->DebugString();
219}
220
226
227void SimControlWithModelBase::InitStartPoint(nlohmann::json start_point_attr,
228 bool use_start_point_position) {
229 AINFO << "Init start point with position!";
230
231 start_velocity_ = start_point_attr["start_velocity"];
232 start_acceleration_ = start_point_attr["start_acceleration"];
233 start_heading_ = start_point_attr["start_heading"];
234 SimCarStatus point;
235 localization_reader_->Observe();
237 if (use_start_point_position) {
238 // add start point position for dynamic model
239 // new add feature to keep same with simcontrol
240 point.set_x(start_point_attr["x"]);
241 point.set_y(start_point_attr["y"]);
242 // z use default 0
243 point.set_z(0);
244 double theta = 0.0;
245 double s = 0.0;
246 map_service_->GetPoseWithRegardToLane(start_point_attr["x"],
247 start_point_attr["y"], &theta, &s);
248 point.set_theta(theta);
249 point.set_speed(start_velocity_);
250 point.set_acceleration_s(start_acceleration_);
251 } else {
252 if (!localization_reader_->Empty()) {
253 const auto& pose = localization_reader_->GetLatestObserved()->pose();
254 auto x = pose.position().x();
255 auto y = pose.position().y();
256 auto z = pose.position().z();
257 if (map_service_->PointIsValid(x, y)) {
258 point.set_x(x);
259 point.set_y(y);
260 point.set_z(z);
261 point.set_theta(pose.heading());
262 point.set_speed(
263 std::hypot(pose.linear_velocity().x(), pose.linear_velocity().y()));
264 // Calculates the dot product of acceleration and velocity. The sign
265 // of this projection indicates whether this is acceleration or
266 // deceleration.
267 double projection =
268 pose.linear_acceleration().x() * pose.linear_velocity().x() +
269 pose.linear_acceleration().y() * pose.linear_velocity().y();
270
271 // Calculates the magnitude of the acceleration. Negate the value if
272 // it is indeed a deceleration.
273 double magnitude = std::hypot(pose.linear_acceleration().x(),
274 pose.linear_acceleration().y());
275 point.set_acceleration_s(std::signbit(projection) ? -magnitude
276 : magnitude);
277 // Set init gear to neutral position
278 point.set_gear_position(0);
280 }
281 }
283 apollo::common::PointENU start_point;
284 if (!map_service_->GetStartPoint(&start_point)) {
285 AWARN << "Failed to get a dummy start point from map!";
286 return;
287 }
288 point.set_x(start_point.x());
289 point.set_y(start_point.y());
290 point.set_z(start_point.z());
291 double theta = 0.0;
292 double s = 0.0;
293 map_service_->GetPoseWithRegardToLane(start_point.x(), start_point.y(),
294 &theta, &s);
295 point.set_theta(theta);
296 point.set_speed(start_velocity_);
297 point.set_acceleration_s(start_acceleration_);
298 AINFO << "start point from map default point"
299 << " x: " << start_point.x() << " y: " << start_point.y();
300 }
301 }
302 SetStartPoint(point);
303}
304
310void SimControlWithModelBase::PublishChassis(const std::string model_name) {
311 auto chassis = std::make_shared<Chassis>();
312 apollo::common::util::FillHeader(model_name, chassis.get());
313
314 chassis->set_engine_started(true);
315 chassis->set_speed_mps(current_point_.speed());
316 chassis->set_odometer_m(current_point_.odometer());
317
318 if (FLAGS_enable_steering_latency) {
319 chassis->set_steering_percentage(filtered_control_cmd_.steering_target());
320 } else {
321 chassis->set_steering_percentage(control_cmd_.steering_target());
322 }
323 chassis->set_throttle_percentage(control_cmd_.throttle());
324 chassis->set_brake_percentage(control_cmd_.brake());
325 if (start_auto_) {
326 chassis->set_driving_mode(Chassis::COMPLETE_AUTO_DRIVE);
327 } else {
328 chassis->set_driving_mode(Chassis::COMPLETE_MANUAL);
329 }
330 chassis->set_gear_location(control_cmd_.gear_location());
331 chassis_writer_->Write(chassis);
332}
333
339 auto prediction = std::make_shared<PredictionObstacles>();
340 {
341 std::lock_guard<std::mutex> lock(mutex_);
343 return;
344 }
345 FillHeader("SimDMPrediction", prediction.get());
346 }
347 prediction_writer_->Write(prediction);
348}
349
351 const std::string model_name) {
352 auto localization = std::make_shared<LocalizationEstimate>();
353 FillHeader(model_name, localization.get());
354
355 auto* pose = localization->mutable_pose();
356
357 // Set position
358 pose->mutable_position()->set_x(current_point_.x());
359 pose->mutable_position()->set_y(current_point_.y());
360 pose->mutable_position()->set_z(0.0);
361 // Set orientation and heading
362 double cur_theta = current_point_.theta();
363
364 Eigen::Quaternion<double> cur_orientation =
365 HeadingToQuaternion<double>(cur_theta);
366 ADEBUG << "cur_theta" << cur_theta;
367 ADEBUG << "cur_orientation_w" << cur_orientation.w() << "cur_orientation_x"
368 << cur_orientation.x() << "cur_orientation_y" << cur_orientation.y()
369 << "cur_orientation_z" << cur_orientation.z();
370 pose->mutable_orientation()->set_qw(cur_orientation.w());
371 pose->mutable_orientation()->set_qx(cur_orientation.x());
372 pose->mutable_orientation()->set_qy(cur_orientation.y());
373 pose->mutable_orientation()->set_qz(cur_orientation.z());
374 pose->set_heading(cur_theta);
375
376 // Set linear_velocity
378 pose->mutable_linear_velocity()->set_x(std::cos(cur_theta) * -1.0 *
380 pose->mutable_linear_velocity()->set_y(std::sin(cur_theta) * -1.0 *
382 } else {
383 pose->mutable_linear_velocity()->set_x(std::cos(cur_theta) *
385 pose->mutable_linear_velocity()->set_y(std::sin(cur_theta) *
387 }
388
389 pose->mutable_linear_velocity()->set_z(0);
390
391 // Set angular_velocity in both map reference frame and vehicle reference
392 // frame
393 double cur_curvature = std::tan(control_cmd_.steering_target() *
397
398 pose->mutable_angular_velocity()->set_x(0);
399 pose->mutable_angular_velocity()->set_y(0);
400 pose->mutable_angular_velocity()->set_z(current_point_.speed() *
401 cur_curvature);
402
403 TransformToVRF(pose->angular_velocity(), pose->orientation(),
404 pose->mutable_angular_velocity_vrf());
405
406 // Set linear_acceleration in both map reference frame and vehicle reference
407 // frame
408 auto* linear_acceleration = pose->mutable_linear_acceleration();
409 linear_acceleration->set_x(std::cos(cur_theta) *
411 linear_acceleration->set_y(std::sin(cur_theta) *
413 linear_acceleration->set_z(0);
414
415 TransformToVRF(pose->linear_acceleration(), pose->orientation(),
416 pose->mutable_linear_acceleration_vrf());
417
418 localization_writer_->Write(localization);
419
420 adc_position_.set_x(pose->position().x());
421 adc_position_.set_y(pose->position().y());
422 adc_position_.set_z(pose->position().z());
423}
424
425} // namespace dreamview
426} // namespace apollo
Used to perform oneshot or periodic timing tasks
Definition timer.h:71
bool PointIsValid(const double x, const double y) const
bool GetStartPoint(apollo::common::PointENU *start_point) const
bool GetPoseWithRegardToLane(const double x, const double y, double *theta, double *s) const
void TransformToVRF(const apollo::common::Point3D &point_mrf, const apollo::common::Quaternion &orientation, apollo::common::Point3D *point_vrf)
std::unique_ptr< cyber::Timer > sim_control_timer_
std::unique_ptr< cyber::Timer > sim_prediction_timer_
virtual void RunOnce()=0
Main logic of the simulated control algorithm.
virtual void Init(bool set_start_point, nlohmann::json start_point_attr, bool use_start_point_position=false)=0
Initialization.
std::shared_ptr< cyber::Reader< apollo::planning::PlanningCommand > > planning_command_reader_
std::shared_ptr< cyber::Writer< apollo::localization::LocalizationEstimate > > localization_writer_
void PublishLocalization(const std::string model_name)
void OnControlCommand(const apollo::control::ControlCommand &control_command)
void Start() override
Starts the timer to publish simulated localization and chassis messages.
void ReSetPoinstion(double x, double y, double heading) override
Set vehicle position.
void OnPlanningCommand(const std::shared_ptr< apollo::planning::PlanningCommand > &planning_command)
void InitStartPoint(nlohmann::json start_point_attr, bool use_start_point_position=false)
SimControlWithModelBase(const std::string &node_name)
Construct a new Sim Control With Model Base object
std::shared_ptr< cyber::Reader< apollo::localization::LocalizationEstimate > > localization_reader_
void OnPredictionObstacles(const std::shared_ptr< apollo::prediction::PredictionObstacles > &obstacles)
std::shared_ptr< cyber::Reader< apollo::prediction::PredictionObstacles > > prediction_reader_
void PublishChassis(const std::string model_name)
pubish chassis info
std::shared_ptr< cyber::Writer< apollo::prediction::PredictionObstacles > > prediction_writer_
std::shared_ptr< cyber::Writer< apollo::canbus::Chassis > > chassis_writer_
std::shared_ptr< cyber::Reader< apollo::control::ControlCommand > > control_command_reader_
void Reset() override
Resets the internal state.
virtual void SetStartPoint(const ::apollo::sim_control::SimCarStatus &point)
#define ADEBUG
Definition log.h:41
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
nlohmann::json Json
SLPoint InterpolateUsingLinearApproximation(const SLPoint &p0, const SLPoint &p1, const double w)
Eigen::Quaternion< T > HeadingToQuaternion(T heading)
Definition quaternion.h:88
Eigen::Vector3d InverseQuaternionRotate(const Quaternion &orientation, const Eigen::Vector3d &rotated)
Definition quaternion.h:110
double QuaternionToHeading(const double qw, const double qx, const double qy, const double qz)
Definition quaternion.h:56
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Definition math_utils.cc:53
class register implement
Definition arena_queue.h:37
optional apollo::canbus::Chassis::GearPosition gear_location
uint32_t pending_queue_size
configuration for responding ChannelBuffer.