apollo planning tasks optimizers road_graph comparable_cost

1. 描述

在 dp path 的时候 node 间的 cost 主要分为3部分:路径平滑、避开静态障碍物、避开动态障碍物,使用ComparableCost 类描述。

该类除包含常规的 safety_cost(无碰)和 smoothness_cost(平滑)外,还含有 3 个 bool 型的成员变量,以表示是否碰撞、是否超出边界、是否超出车道线, 如下:

  static const size_t HAS_COLLISION = 0;
  static const size_t OUT_OF_BOUNDARY = 1;
  static const size_t OUT_OF_LANE = 2;
  std::array<bool, 3> cost_items = {{false, false, false}};

  // cost from distance to obstacles or boundaries
  double safety_cost = 0.0f;
  // cost from deviation from lane center, path curvature etc
  double smoothness_cost = 0.0f;

comparable_cost,源文件在这里

modules/planning/tasks/optimizers/road_graph/comparable_cost.h
modules/planning/tasks/optimizers/road_graph/comparable_cost.cc

2. 代码

看一下完整代码,和测试的例子

(这个直接就是源码中的,因为和其他的模块没有关联,不用修改,可以直接运行)

#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <memory>
#include <algorithm>
#include <cmath>
#include <array>

#include <gtest/gtest.h>

using namespace std;
#include <cmath>

namespace apollo {
namespace planning {

class ComparableCost {
 public:
  ComparableCost() = default;
  ComparableCost(const bool has_collision, const bool out_of_boundary,
                 const bool out_of_lane, const double safety_cost_,
                 const double smoothness_cost_)
      : safety_cost(safety_cost_), smoothness_cost(smoothness_cost_) {
    cost_items[HAS_COLLISION] = has_collision;
    cost_items[OUT_OF_BOUNDARY] = out_of_boundary;
    cost_items[OUT_OF_LANE] = out_of_lane;
  }
  ComparableCost(const ComparableCost &) = default;

  int CompareTo(const ComparableCost &other) const {
    for (size_t i = 0; i < cost_items.size(); ++i) {
      if (cost_items[i]) {
        if (other.cost_items[i]) {
          continue;
        } else {
          return 1;
        }
      } else {
        if (other.cost_items[i]) {
          return -1;
        } else {
          continue;
        }
      }
    }

    constexpr double kEpsilon = 1e-12;
    const double diff = safety_cost + smoothness_cost - other.safety_cost -
                       other.smoothness_cost;
    if (std::fabs(diff) < kEpsilon) {
      return 0;
    } else if (diff > 0) {
      return 1;
    } else {
      return -1;
    }
  }
  ComparableCost operator+(const ComparableCost &other) {
    ComparableCost lhs = *this;
    lhs += other;
    return lhs;
  }
  ComparableCost &operator+=(const ComparableCost &other) {
    for (size_t i = 0; i < cost_items.size(); ++i) {
      cost_items[i] = (cost_items[i] || other.cost_items[i]);
    }
    safety_cost += other.safety_cost;
    smoothness_cost += other.smoothness_cost;
    return *this;
  }
  bool operator>(const ComparableCost &other) const {
    return this->CompareTo(other) > 0;
  }
  bool operator>=(const ComparableCost &other) const {
    return this->CompareTo(other) >= 0;
  }
  bool operator<(const ComparableCost &other) const {
    return this->CompareTo(other) < 0;
  }
  bool operator<=(const ComparableCost &other) const {
    return this->CompareTo(other) <= 0;
  }
  /*
   * cost_items represents an array of factors that affect the cost,
   * The level is from most critical to less critical.
   * It includes:
   * (0) has_collision or out_of_boundary
   * (1) out_of_lane
   *
   * NOTICE: Items could have same critical levels
   */
  static const size_t HAS_COLLISION = 0;
  static const size_t OUT_OF_BOUNDARY = 1;
  static const size_t OUT_OF_LANE = 2;
  std::array<bool, 3> cost_items = {{false, false, false}};

  // cost from distance to obstacles or boundaries
  double safety_cost = 0.0f;
  // cost from deviation from lane center, path curvature etc
  double smoothness_cost = 0.0f;
};

}  // namespace planning
}  // namespace apollo

namespace apollo {
namespace planning {

TEST(ComparableCost, simple) {
  ComparableCost cc;
  EXPECT_FLOAT_EQ(cc.safety_cost, 0.0);
  EXPECT_FLOAT_EQ(cc.smoothness_cost, 0.0);
  EXPECT_FALSE(cc.cost_items[ComparableCost::HAS_COLLISION]);
  EXPECT_FALSE(cc.cost_items[ComparableCost::OUT_OF_BOUNDARY]);
  EXPECT_FALSE(cc.cost_items[ComparableCost::OUT_OF_LANE]);
}

TEST(ComparableCost, add_cost) {
  ComparableCost cc1(true, false, false, 10.12, 2.51);
  ComparableCost cc2(false, false, true, 6.1, 3.45);

  ComparableCost cc = cc1 + cc2;

  EXPECT_TRUE(cc.cost_items[ComparableCost::HAS_COLLISION]);
  EXPECT_FALSE(cc.cost_items[ComparableCost::OUT_OF_BOUNDARY]);
  EXPECT_TRUE(cc.cost_items[ComparableCost::OUT_OF_LANE]);
  EXPECT_FLOAT_EQ(cc.safety_cost, 16.22);
  EXPECT_FLOAT_EQ(cc.smoothness_cost, 5.96);

  EXPECT_TRUE(cc1 > cc2);

  cc1 += cc2;

  EXPECT_TRUE(cc1.cost_items[ComparableCost::HAS_COLLISION]);
  EXPECT_FALSE(cc1.cost_items[ComparableCost::OUT_OF_BOUNDARY]);
  EXPECT_TRUE(cc1.cost_items[ComparableCost::OUT_OF_LANE]);
  EXPECT_FLOAT_EQ(cc1.safety_cost, 16.22);
  EXPECT_FLOAT_EQ(cc1.smoothness_cost, 5.96);

  ComparableCost cc3(true, false, false, 10.12, 2.51);
  ComparableCost cc4(false, true, true, 6.1, 3.45);

  EXPECT_TRUE(cc3 > cc4);

  ComparableCost cc5(false, false, false, 10.12, 2.51);
  ComparableCost cc6(false, true, true, 6.1, 3.45);

  EXPECT_TRUE(cc5 < cc6);

  ComparableCost cc7 = cc5 + cc6;

  EXPECT_FALSE(cc7.cost_items[ComparableCost::HAS_COLLISION]);
  EXPECT_TRUE(cc7.cost_items[ComparableCost::OUT_OF_BOUNDARY]);
  EXPECT_TRUE(cc7.cost_items[ComparableCost::OUT_OF_LANE]);
  EXPECT_FLOAT_EQ(cc7.safety_cost, 16.22);
  EXPECT_FLOAT_EQ(cc7.smoothness_cost, 5.96);

  EXPECT_TRUE(cc5 < cc6);
}

TEST(ComparableCost, compare_to) {
  ComparableCost cc1(true, false, false, 10.12, 2.51);
  ComparableCost cc2(false, false, true, 6.1, 3.45);
  EXPECT_TRUE(cc1 > cc2);

  ComparableCost cc3(false, true, false, 10.12, 2.51);
  ComparableCost cc4(false, false, false, 6.1, 3.45);
  EXPECT_TRUE(cc3 > cc4);

  ComparableCost cc5(false, false, true, 10.12, 2.51);
  ComparableCost cc6(false, false, false, 6.1, 3.45);
  EXPECT_TRUE(cc5 > cc6);

  ComparableCost cc7(false, false, false, 10.12, 2.51);
  ComparableCost cc8(false, false, false, 6.1, 3.45);
  EXPECT_TRUE(cc7 > cc8);

  ComparableCost cc9(false, false, false, 0.12, 2.51);
  ComparableCost cc10(false, false, false, 6.1, 3.45);
  EXPECT_TRUE(cc9 < cc10);

  ComparableCost cc11(false, false, false, 0.1, 100.0);
  ComparableCost cc12(false, false, false, 6.1, 3.45);
  EXPECT_TRUE(cc11 < cc12);
}

}  // namespace planning
}  // namespace apollo

  • 结果:
/home/seivl/me/代码/规划/bbox_test/src/main.cpp:453: Failure
Value of: cc11 < cc12
  Actual: false
Expected: true
[  FAILED  ] ComparableCost.compare_to (0 ms)
[----------] 3 tests from ComparableCost (0 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 2 test suites ran. (0 ms total)
[  PASSED  ] 3 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] ComparableCost.compare_to

 1 FAILED TEST

3. 分析

很明显:

  • 先判断是否碰撞、是否超出边界、是否超出车道线,一旦有一个是 true, 直接选择另一个 node

  • 如果都没发生,那就比较两个 node 的 safety_cost 和 smoothness_cost 之和,选择小的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值