17 using std::placeholders::_1;
22 log(
"Starting ControllerNode...");
24 galaxis::ros::create_subscription(
this,
27 galaxis::ros::create_subscription(
this,
31 galaxis::ros::create_subscription(
this,
40 rclcpp::QoS qosParamsR = get_qos_profile(QOS_RELIABLE);
47 rclcpp::QoS qosParams = get_qos_profile(QOS_BEST_EFFORT);
73 float horizonStepSize = 0.5f;
74 int errorAccuracyStepsPerHorizon = 4;
76 float errorIncreaseForFirstHorizon = 4;
79 std::string configPath =
"settings/onstartup_controller.json";
81 json& settingsJson = (*settingsJsonSPtr)[
"settings"];
107 if(settingsJson[
"publish_map_trajectory_merged_debug_msg"] ==
true) {
110 galaxis::ros::TOPIC_AP_DATA_IMAGE_DEBUG,
130 bool apOffline =
false;
133 log_warning(
"Stopping car. No Polynom update within 400ms! (Is the AP online?)");
138 auto msgUPtr = std::make_unique<ControlMotionType>();
140 msgUPtr->set_motor_current = 0;
142 msgUPtr->set_servo_rear = 0;
147 auto set_start_ParkingNode_result = this->set_parameter(rclcpp::Parameter(
"CarOS.start_ParkingNode", 1));
148 if (!set_start_ParkingNode_result.successful) {
149 RCLCPP_ERROR(this->get_logger(),
"Failed to set CarOS.start_ParkingNode: %s", set_start_ParkingNode_result.reason.c_str());
151 log_warning(
"Real World: In parking mode. Controller Node is in idle mode.");
168 auto lightUPtr = std::make_unique<std_msgs::msg::UInt8>();
189 auto set_start_ParkingNode_result = this->set_parameter(rclcpp::Parameter(
"CarOS.start_ParkingNode", 1));
190 if (!set_start_ParkingNode_result.successful) {
191 RCLCPP_ERROR(this->get_logger(),
"Failed to set CarOS.start_ParkingNode: %s", set_start_ParkingNode_result.reason.c_str());
193 log_warning(
"Simulation: In parking mode. Controller Node is in idle mode.");
200 std::this_thread::sleep_for(std::chrono::milliseconds(2));
206 log(
"[SKIP] PathPolynom is nullptr. Skip sending Debug Message.");
212 DebugControllerType::UniquePtr debugMessage = std::make_unique<DebugControllerType>();
222 for(
auto const pose: *firstPoseSeries) {
224 vec.x = pose->position[0];
225 vec.y = pose->position[1];
226 debugMessage->carpose_series.push_back(vec);
229 for(
auto const pose: *secondPoseSeries) {
231 vec.x = pose->position[0];
232 vec.y = pose->position[1];
233 debugMessage->carpose_series.push_back(vec);
237 log(
"[PUBLISH] DebugController message.");
241 log(
"[SKIP] PathPolynom mutexed. Skip sending Debug Message.");
245 log(
"[SKIP] Control mutexed. Skip sending Debug Message.");
250 auto message = std::make_unique<SimulationVehicleControlType>();
254 message->reset =
false;
303 log(
"#New Measurements arrived.");
309 log_warning(
"ControllerNode::on_measurement_callback: MeasurementsPtr mutexed. Could not update Measurements");
314 log(
"#New Pathpolynom received.");
320 static_cast<float>(msg->c[0]),
321 static_cast<float>(msg->c[1]),
322 static_cast<float>(msg->c[2]),
323 static_cast<float>(msg->c[3])
344 assert(msg !=
nullptr);
347 log(
"[PUBLISH] ControlValues\n - ERPM: ", msg->set_motor_erpm,
"\n - Motor Current: ", msg->set_motor_current,
"\n - Servo Front: ",
348 static_cast<int>(msg->set_servo_front),
"\n - Servo Back: ",
static_cast<int>(msg->set_servo_rear),
"\n - Brakes: ", msg->set_brakes,
"\n");
365 log(
"[on_map_debug_image_callback] Skip sending Map-Trajectory-Debug-Image. Reason: NO Subscriber on the corresponding topic.");
369 std::shared_ptr<sensor_msgs::msg::Image> imageMsg = std::make_shared<sensor_msgs::msg::Image>();
371 imageMsg->header.stamp = msg->header.stamp;
372 imageMsg->width = msg->width;
373 imageMsg->height = msg->height;
374 imageMsg->encoding = msg->encoding;
375 imageMsg->is_bigendian = msg->is_bigendian;
376 imageMsg->step = msg->step;
378 imageMsg->data = msg->data;
390 float trajectoryPointPositionX = 0.f;
391 float trajectoryPointPositionY = 0.f;
392 for(
int i = 0; i < 2; ++i) {
393 for(
auto const& pose : *poseSeries) {
394 trajectoryPointPositionX = - pose->position[1] * 100;
399 for(
int y = -radiusCM; y <= radiusCM; y++) {
400 for(
int x = -radiusCM; x <= radiusCM; x++) {
401 if(x*x+y*y <= radiusCM*radiusCM) {
402 int imageX = trajectoryPointPositionX + x + imageMsg->width / 2;
403 int imageY = imageMsg->height - trajectoryPointPositionY + y;
404 int index = imageY * imageMsg->step + imageX * 3;
407 if (imageX < 0 || imageY < 0 || imageX >= imageMsg->width || imageY >= imageMsg->height) {
411 if(index >= 0 && index + 2 <=
static_cast<int>(imageMsg->data.size())) {
412 imageMsg->data[index] = 255;
413 imageMsg->data[index + 1] = 242;
414 imageMsg->data[index + 2] = 167;
428 log(
"[DEBUG] [PUBLISH] Map-Trajectory-Debug-Image");
432 log(
"[ControllerNode] NEW PARAMETERS");
434 rcl_interfaces::msg::SetParametersResult result;
435 result.successful =
true;
438 for (
const auto ¶m: parameters) {
439 if (param.get_name() ==
"settings.horizon_step_time_sec") {
440 if(check_parameter<double>(param, result, 0.1, 2.0)) {
444 else if (param.get_name() ==
"settings.error_accuracy_steps_per_horizon") {
445 if(check_parameter<int>(param, result, 5, 100)) {
449 else if (param.get_name() ==
"settings.error_factor_first_horizon") {
450 if(check_parameter<double>(param, result, -5.0, 5.0)) {
454 else if (param.get_name() ==
"settings.max_decreased_velocity_for_steering") {
455 if(check_parameter<double>(param, result, 0.3)) {
459 else if (param.get_name() ==
"settings.velocity_rolling_average_factor_to_new_velocity") {
460 if(check_parameter<double>(param, result, 0.000001, 1)) {
465 else if (param.get_name() ==
"CarOS.stop_ControllerNode") {
466 if(check_parameter<int>(param, result, 0)) {
470 else if (param.get_name() ==
"CarOS.start_ParkingNode") {
471 if(check_parameter<int>(param, result, 0)) {
477 else if (param.get_name() ==
"controlmetrics.cross_angle_error_weight") {
478 if(check_parameter<double>(param, result, 0)) {
482 else if (param.get_name() ==
"controlmetrics.cross_line_marking_error_weight") {
483 if(check_parameter<double>(param, result, 0)) {
488 result.successful =
false;
489 result.reason +=
"[" + param.get_name() +
"] UNKNOWN param or NOT IMPLEMENTED; ";
493 if(result.successful ==
false) {
494 log_warning(
"[AutopilotNode] Failed to set some parameters. Reasons: ", result.reason);