我实施D star lite怎么了?

时间:2019-07-19 00:17:55

标签: c++ c++11 motion-planning d-star

因此,我正在尝试在C ++中实现D star lite。该代码没有实现其含义,我相信G和RHS的更新没有以正确的方式进行。

我试图通过用范围为2的for循环替换主循环中的while循环来进行进一步探究,并注意到updateVertex()方法中RHS和G值中的杂散-2.14748e + 09并非如此达到所有期望值。请帮助我解决这个奇怪的问题。

    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <random>
    #include <limits>
    #include <cstdlib>
    #include <utility>
    #include <queue>

    class Node {
     public:
      /**
       * @var _x of type int stores the x coordinate of the node
       */
      int _x = 0;
      /**
       * @var _y of type int stores the y coordinate of the node
       */
      int _y = 0;
      /**
       * @var _key of type pair<double,double> stores the key values of the node
       */
      std::pair<double, double> _key = std::make_pair(0, 0);
      /**
       * default constructor
       */
      Node() {
      }
      /**
       * Constructor taking 2 parameters
       * @param x of type int used to initialize the value of the member _x
       * @param y of type int used to initialize the value of the member _y
       */
      Node(int x, int y)
          : _x(x),
            _y(y) {
      }
      /**
       * Constructor which takes a const Node reference as a parameter copies
       * the values of n in a new Node object
       * @param n is a reference of Node class object
       *
       */
      Node(const Node &n) {
        _x = n._x;
        _y = n._y;
        _key = n._key;
      }
      /**
       * @brief Sets the key value of the node
       *
       * @param k is a reference of a pair<double,double>
       * @return void
       */
      void setkey(std::pair<double, double> k) {
        _key = k;
      }
      /**
       * @brief Gets the value of the key
       * @return the key value of type pair<double,double>
       */
      std::pair<double, double> getkey() {
        return _key;
      }
      /**
       * @brief A friend to the class Node. Overloads the operator +,
       * used to add two const Node obejcts
       *
       * @param r a reference of the Node class object
       * @param l a reference of the Node class object
       * @return a const Node created by adding the _x and _y values of the parameters
       */
      const Node operator+(const Node &r) {
        return Node(this->_x + r._x, this->_y + r._y);
      }
      /**
       * @brief A friend to the class Node.Overloads the operator ==,  used to check if
       * the two const Node elements are the same
       *
       *
       * @param r a reference of the const Node class object
       * @param l a reference of the const Node class object
       * @return a bool value, true if the elements are equal false if different
       */
      bool operator==(const Node &r) {
        return ((this->_x == r._x) && (this->_y == r._y));
      }
      /**
       * @brief A friend to the class Node.Overloads the operator !=,  used to check if
       * the two const Node elements are different
       *
       * @param r a reference of the const Node class object
       * @param l a reference of the const Node class object
       * @return a bool value, true if the elements are not equal false if equal
       */
      bool operator!=(const Node &r) {
        return !(*this == r);
      }

      /**
       * @brief A friend to the class Node.Overloads the operator <,  used to compare the key value of the Node and key
       *
       * @param l a reference of the const Node class object
       * @param r is a key of type pair<double,double>
       * @return a bool value, true or false
       */
      friend bool operator<(const Node& l, const std::pair<double, double> r) {
        if (l._key.first < r.first) {
          return true;
        } else {
          if ((l._key.first == r.first) && (l._key.second < r.second))
            return true;
          else
            return false;
        }
      }
      /**
       * Destructor
       */
      ~Node() {
      }

    };

    /**
     * @brief      Structure compare used as the comparator in the PriorityQ making it a min priority queue
     */
    struct compare {
      bool operator()(const Node &l, const Node &r) {
        if (l._key.first < r._key.first) {
          return false;
        } else {
          if ((l._key.first == r._key.first) && (l._key.second < r._key.second))
            return false;
          else
            return true;
        }
      }
    };
    /**
     * @brief      Template Class inherits from priority queue
     */
    template<typename T>
    class PriorityQ : public std::priority_queue<T, std::vector<T>, compare> {
     public:
      /**
       * @brief A method used to remove a particular value from the queue
       *
       * @param value a const reference to the template T
       * @return bool true or false
       */
      bool remove(const T& value) {
        // finds if the desired value is present in the queue
        auto it = std::find(this->c.begin(), this->c.end(), value);
        if (it != this->c.end()) {
          // used to erase the element
          this->c.erase(it);
          // reorders the queue
          std::make_heap(this->c.begin(), this->c.end(), this->comp);
          return true;
        } else {
          return false;
        }
      }
      /**
       * @brief A method to find if an element is present in the queue
       *
       * @param value a const reference to the template T
       * @return the template T
       */
      T find(const T& value) {
        auto it = std::find(this->c.begin(), this->c.end(), value);
        return *it;
      }
    };

    class DSL {
     private:
      std::vector<std::vector<double>> g;
      std::vector<std::vector<double>> rhs;
      std::vector<std::vector<int>> cost;
      std::vector<std::vector<int>> map;
      int m, n;
      float dropout = 0.9;
      Node start;
      Node goal;
      int km = 0;

     public:

      PriorityQ<Node> U;

      DSL(int rows, int columns, Node s, Node gol) {
        m = rows;
        n = columns;
        start = s;
        goal = gol;
        g.resize(m,
                 std::vector<double>(n, std::numeric_limits<double>::infinity()));
        rhs.resize(m,
                   std::vector<double>(n, std::numeric_limits<double>::infinity()));
        cost.resize(m, std::vector<int>(n, 1));

        //generateMap();
        map = { {0, 0, 0, 0, 0, 0},
          { 0, 1, 0, 0, 0, 0},
          { 0, 1, 1, 0, 0, 0},
          { 0, 0, 1, 0, 0, 0},
          { 0, 1, 1, 0, 0, 0},
          { 0, 1, 1, 1, 0, 0}};
      }

      std::vector<std::vector<double>> getG() {
        return g;
      }

      std::vector<std::vector<int>> getCost() {
        return cost;
      }

      void setCost(Node node, double val) {
        cost[node._x][node._y] = val;
      }

      void setMap(Node node, double val) {
        map[node._x][node._y] = val;
      }
      void setkm(Node node) {
        km += heuristic(node);
      }

      std::vector<std::vector<int>> getMap() {
        return map;
      }

      std::vector<std::vector<int>> generateMap() {
        map.resize(m, std::vector<int>(n, 0));
        size_t size = m * n;
        std::random_device rd;
        std::mt19937 gen(rd());
        std::bernoulli_distribution dist(1 - dropout);  // bernoulli_distribution takes chance of true n constructor

        std::vector<int> temp(size);
        std::generate(temp.begin(), temp.end(), [&] {return dist(gen);});
        int i = 0;
        for (int x = 0; x < m; x++) {
          for (int y = 0; y < n; y++) {
            map[x][y] = temp[i];
            i++;
          }
        }
        return map;
      }

      void initialize() {
        rhs[goal._x][goal._y] = 0;
        auto key = calculateKey(goal);
        goal.setkey(key);
        U.push(goal);
      }

      std::pair<double, double> calculateKey(Node node) {
        double minVal =
        g[node._x][node._y] > rhs[node._x][node._y] ?
        rhs[node._x][node._y] : g[node._x][node._y];
        double key1 = minVal + heuristic(node) + km;
        double key2 = minVal;
        // make pair of key1 and key2
        return std::make_pair(key1, key2);
      }

      double heuristic(Node node) {
        return (abs(start._x - node._x) + abs(start._y - node._y));
      }

      std::vector<Node> getNeighbours(Node node) {
        std::vector < Node > neighbours;
        if (node._x - 1 >= 0) {
          neighbours.push_back(Node((node._x - 1),node._y));
        }
        if (node._x + 1 < m) {
          neighbours.push_back(Node((node._x + 1),node._y));
        }
        if (node._y - 1 >= 0) {
          neighbours.push_back(Node(node._x ,(node._y - 1)));
        }
        if (node._y + 1 < n) {
          neighbours.push_back(Node((node._x),(node._y + 1)));
        }
        return neighbours;
      }

      void updateVertex(Node node) {
        std::vector < Node > neighbours;
        if (node != goal) {
          neighbours = getNeighbours(node);
          std::vector<double> values;
          for (auto neighbour : neighbours) {
            values.push_back(
                g[neighbour._x][neighbour._y]
                + cost[neighbour._x][neighbour._y]);
          }
    //      for(auto val:values){
    //        std::cout<<val<<"\t";
    //      }
          rhs[node._x][node._y] = *std::min_element(values.begin(),
              values.end());
        }

        if (node == U.find(node)) {
          U.remove(node);  // if found removes the node u
        }
        if (g[node._y][node._x] != rhs[node._y][node._x]) {
          auto key = calculateKey(node);  // calculates the key of u
          node.setkey(key);// sets the key of u
          U.push(node);// pushes u to the priority queue
        }

      }

      void computeShortestPath() {
        while (U.top() < calculateKey(start)
            || (rhs[start._x][start._y] != g[start._x][start._y])) {
          Node u = U.top();  // top Node
          U.pop();// remove Node
          if (u < calculateKey(u)) {
            std::pair<double, double> knew = calculateKey(u);
            u.setkey(knew);
            U.push(u);

          } else if (g[u._x][u._y] > rhs[u._x][u._y]) {
            // sets the g value of the node equal to it's rhs value
            g[u._x][u._y] = rhs[u._x][u._y];
            std::vector < Node > neighbours = getNeighbours(u);
            for (auto &n : neighbours) {
              if (cost[n._x][n._y] == 1)
              // updates the inconsitent nodes
              updateVertex(n);
            }
          } else {
            // sets the g value to "infinity"
            g[u._x][u._y] = std::numeric_limits<double>::infinity();
            updateVertex(u);
            std::vector < Node > neighbours = getNeighbours(u);
            for (auto &n : neighbours) {
              // checks the cost of the node
              if (cost[n._x][n._y] == 1)
              // updates the neighbours of the node u
              updateVertex(n);
            }

          }
          //printG();
          //printRhs();
        }

      }

      void printMap() {
        for (size_t i = 0; i < map.size(); i++)
        {
          for (size_t j = 0; j < map[i].size(); j++)
          {
            std::cout << map[i][j];
          }
          std::cout<<std::endl;
        }

      }

      void printG() {
        std::cout<<"printing G"<<std::endl;
        for (size_t i = 0; i < g.size(); i++)
        {
          for (size_t j = 0; j < g[i].size(); j++)
          {
            std::cout << g[i][j]<<" ";
          }
          std::cout<<std::endl;
        }

      }

      void printRhs() {
        std::cout<<"printing RHS"<<std::endl;
        for (size_t i = 0; i < rhs.size(); i++)
        {
          for (size_t j = 0; j < rhs[i].size(); j++)
          {
            std::cout << rhs[i][j]<< " ";
          }
          std::cout<<std::endl;
        }

      }
    };

    int main() {
      std::vector<std::pair<double, double>> path;
      int m, n;
      m = 6;
      n = 6;
      Node start(0, 0);  // sets the start Node
      Node goal(5, 4);  // sets the goal Node
      DSL dsl(m, n, start, goal);
      std::cout << "Initial map" << std::endl;
      dsl.printMap();
      Node last = start;
      dsl.initialize();
      dsl.computeShortestPath();
      Node current;
      //while (start != goal) {
        for( auto i = 0 ; i < 2; i++){
        if (dsl.getG()[start._x][start._y]
            == std::numeric_limits<double>::infinity()) {
          std::cout << "There's no solution";
          break;
        }
        std::vector<Node> neighbours1 = dsl.getNeighbours(start);
        std::vector<double> costRange;  // used to store the costs of neighbours
        for (auto n : neighbours1) {
          costRange.push_back(dsl.getG()[n._x][n._y] + dsl.getCost()[n._x][n._y]);
        }
        size_t index = 0;
        for (size_t i = 0; i < costRange.size(); i++) {
          if (costRange[index] > costRange[i])
            // index of costRange with minimum value
            index = i;
        }
        // argmin of the neighbours of start
        Node nextStep = neighbours1[index];
        if (!dsl.getMap()[nextStep._x][nextStep._y]) {
          start = nextStep;
          current = start;
        } else {
          dsl.setkm(last);
          last = start;
          // set the value of nextStep to infinity
          dsl.setCost(nextStep, std::numeric_limits<double>::infinity());
          std::vector<Node> neighbours2 = dsl.getNeighbours(nextStep);
          for (auto n : neighbours2) {
            dsl.updateVertex(n);
          }
          dsl.computeShortestPath();
        }
        //
    //            path.push_back(std::make_pair(current._x, current._y));
    //            dsl.setMap(current,8);
    //            std::cout<<"Current position"<<std::endl;
    //            dsl.printMap();
        //break;
      }
      //std::cout<<"Final map"<<std::endl;
      //dsl.printMap();
      return 0;

    }

此外,由于未按预期进行更新,computeShortestPath()中的while循环不会以某种方式终止。 请用我的代码帮助我,任何帮助将不胜感激。非常感谢您阅读我的文章。请在编译时使用c ++ 11,可以使用来完成 g ++ -std = c ++ 11 test.cpp -o测试 其次是 ./test

    else if (g[u._x][u._y] > rhs[u._x][u._y]) {
                // sets the g value of the node equal to it's rhs value
                g[u._x][u._y] = rhs[u._x][u._y];
                std::vector < Node > neighbours = getNeighbours(u);
                for (auto &n : neighbours) {
                  if (cost[n._x][n._y] == 1)
                  // updates the inconsitent nodes
                  updateVertex(n);
                }

更新:我相信上面的代码块是代码出现错误的地方

0 个答案:

没有答案
相关问题