Revision bdac5bec

View differences:

devices/DiWheelDrive/amiro_map.cpp
1 1
#include "amiro_map.hpp"
2 2

  
3
// #include <cstdint>
4
// #include <math.h>
5

  
6

  
7 3
uint8_t AmiroMap::initialize(){
8 4

  
9 5
  // Clear old values in case the map is initialized again
......
11 7
  this->state.next = 0;
12 8
  this->state.valid = false;
13 9
  this->nodeCount = 0;
10
  this->state.strategy = 0x1;
14 11

  
15 12
  // convert proto map to internal representation
16 13
  for (int i=0; i<MAX_NODES; i++){
......
32 29
    this->nodeList[i].flag = global->testmap[i][2];
33 30
    this->nodeCount++;
34 31
  }
32
  this->state.next = this->nodeList[this->state.current].right;
35 33

  
36 34
  // TODO make validity check
37 35

  
......
62 60
  }
63 61
}
64 62

  
65
void AmiroMap::update(LineFollowStrategy strategy) {
66
  // Each time at the end of the user thread state maschine, when the strategy
67
  // is changed or a fixpoint is detected, this method gets called.
68
  // The strategy change only has an effect on the fixpoint or in particular if
69
  // a fixpoint is detected.
63
uint8_t AmiroMap::update(uint16_t WL, uint16_t WR, LineFollowStrategy strategy) {
64
  // Called each time at the end of the user thread state machine
65
  // The bottom sensors will be checked for black ground which is interpreted as
66
  // filxpoint
70 67

  
71 68
  // set the strategy directly, actually there is no need to store that variable in the class
72 69
  // but we will go with it for now to initialize everything properly.
70
  uint8_t flag = 0;
73 71
  this->lfStrategy = strategy;
74
  uint16_t WL = global->vcnl4020[constants::DiWheelDrive::PROX_WHEEL_LEFT].getProximityScaledWoOffset();
75
  uint16_t WR = global->vcnl4020[constants::DiWheelDrive::PROX_WHEEL_RIGHT].getProximityScaledWoOffset();
72
  // uint16_t WL = global->vcnl4020[constants::DiWheelDrive::PROX_WHEEL_LEFT].getProximityScaledWoOffset();
73
  // uint16_t WR = global->vcnl4020[constants::DiWheelDrive::PROX_WHEEL_RIGHT].getProximityScaledWoOffset();
76 74

  
77 75
  // Check the wheel sensors
78 76
  bool left = global->linePID.BThresh >= WL;
......
81 79

  
82 80
  if (left && right) {
83 81
    // TODO A dangerous case -> amiro could be lifted
82
    flag |= 255;
84 83
  }
85 84
  else if (left && !leftDetected) {
86 85
    // The sensor on the left side of the Amiro is driving on black
......
97 96
    state.current = state.next;
98 97
    state.next = nodeList[state.current].right;
99 98
    state.strategy = 0x01;
99
    state.eLength = 0; // Reset length to get recalculated after fixpoint
100
    flag |= 0x1;
100 101
  }
101 102
  else if (right && !rightDetected) {
102 103
    // Same as left only for the right sensor.
......
110 111
    nodeList[state.next].visited |= 0x02;
111 112
    state.current = state.next;
112 113
    state.next = nodeList[state.current].left;
113
    state.strategy = 0x02;
114
    state.strategy = 0x2;
115
    state.eLength = 0; // Reset length to get recalculated after fixpoint
116
    flag |= 0x2;
114 117
  }
115 118
  else if (!left && !right) {
116 119
    // in case the fixpoint is not detected anymore
117 120
    leftDetected = false;
118 121
    rightDetected = false;
122
    flag |= 0x4;
119 123
  }
120 124

  
121 125

  
122 126
  // update internal map_state
123 127
  // Update travel distance
124 128
  // check if the nodes of the specific strategy where visited
125
  // if (state.strategy
126
  //     == (nodeList[state.current].visited & nodeList[state.next].visited)) {
127
  //   // only update distance if both nodes were visited
128
  //   if (state.strategy == 0x01) {
129
  //     // Amiro is driving on the right edge
130
  //     state.dist = (uint8_t) sqrt(
131
  //                                 pow(nodeList[state.next].pR.x - nodeList[state.current].pR.x, 2)
132
  //                                 + pow(nodeList[state.next].pR.y - nodeList[state.current].pR.y, 2));
133
  //   } else {
134
  //     // Driving on the left edge
135

  
136
  //   }
137
  // }
129
  if (state.strategy
130
      == (nodeList[state.current].visited & nodeList[state.next].visited)) {
131
    flag |= 0x8;
132
    // only update distance if both nodes were visited
133
    // Calculate estimated length of the edge
134
    if (state.strategy == 0x01) {
135
      // Amiro is driving on the right edge
136
      if (state.eLength == 0) {
137
        state.eLength = calculateDist(&nodeList[state.next].pR,
138
                                      &nodeList[state.current].pR);
139
      }
140
      state.dist = calculateDist(&nodeList[state.next].pR, &currentPos) * 100 /
141
                   state.eLength;
142
    } else {
143
      // Driving on the left edge
144
      if (state.eLength == 0) {
145
        state.eLength =
146
            calculateDist(&nodeList[state.next].pL, &nodeList[state.current].pL);
147
      }
148
      state.dist = calculateDist(&nodeList[state.next].pL, &currentPos) * 100 / state.eLength;
149

  
150
    }
151
  }
152
  return flag;
153
}
154

  
155
uint32_t AmiroMap::calculateDist(types::position *p1, types::position *p2) {
156
  return (uint32_t)  sqrt(pow(p2->x - p1->x, 2) +
157
              pow(p2->y - p1->y, 2));
138 158
}
devices/DiWheelDrive/amiro_map.hpp
6 6
#include <amiroosconf.h>
7 7
#include <ch.hpp>
8 8

  
9

  
9 10
namespace amiro {
10 11

  
11 12
  struct node {
......
27 28
    // Next node ID
28 29
    uint8_t next;
29 30
    //Traveled Distance between current and next in %
30
    uint8_t dist;
31
    uint32_t dist;
31 32
    // True if the current loaded map is valid
32 33
    bool valid;
34
    // Length of the currently traveled edge
35
    uint32_t eLength;
33 36
  };
34 37

  
35 38
class AmiroMap {
......
58 61
   *
59 62
   *
60 63
   */
61
  void update(LineFollowStrategy strategy);
64
  uint8_t update(uint16_t WL, uint16_t WR, LineFollowStrategy strategy);
62 65

  
63 66
private:
64 67
  Global *global;
......
83 86
   *
84 87
   */
85 88
  void visitNode(uint8_t id);
89

  
90
  /**
91
   *  Calculate the distance between two given points
92
   *
93
   *  @param p1 point 1
94
   *  @param p2 point 2
95
   *
96
   */
97
  uint32_t calculateDist(types::position *p1, types::position *p2);
86 98
  };
87 99
}; // namespace amiro
88 100

  
devices/DiWheelDrive/userthread.cpp
785 785
      // Test suit for amiro map
786 786

  
787 787

  
788
      setAttributes(global.testmap, 0, 1, 2, 1);
789
      setAttributes(global.testmap, 1, 2, 2, 0);
790
      setAttributes(global.testmap, 2, 1, 0, 0);
791
      setAttributes(global.testmap, 3, 0, 0, 0xff);
788

  
792 789
      // AmiroMap map = AmiroMap(&global);
793 790

  
794 791
      // --------------------------------------------------
795 792

  
796 793
      global.tcase = 0;
797
      map.initialize();
794
      // Set basic valid map configuration
795
      setAttributes(global.testmap, 0, 1, 2, 1);
796
      setAttributes(global.testmap, 1, 2, 2, 0);
797
      setAttributes(global.testmap, 2, 1, 0, 0);
798
      setAttributes(global.testmap, 3, 0, 0, 0xff);
799
      chprintf((BaseSequentialStream *)&global.sercanmux1, "Init Case: %d, res: %d\n",global.tcase, map.initialize());
798 800
      global.testres[global.tcase] = map.get_state()->valid;
799 801

  
800
        global.tcase++; // 1
802
      global.tcase++; // 1
803
      // Test map fail if first node is flagged with end
801 804
      setAttributes(global.testmap, 0, 1, 2, 0xff);
802 805
      map.initialize();
803 806
      global.testres[global.tcase] = !map.get_state()->valid;
804 807

  
805 808
      global.tcase++; // 2
809
      // Test if node 2 is set as start node
806 810
      setAttributes(global.testmap, 0, 1, 2, 0);
807 811
      setAttributes(global.testmap, 2, 1, 0, 1);
808 812
      map.initialize();
809 813
      global.testres[global.tcase] = map.get_state()->current == 2;
810 814

  
811 815
      global.tcase++; // 3
816
      // Test if non reachable nodes will trigger invalid map
812 817
      setAttributes(global.testmap, 3, 0, 0, 0);
813 818
      setAttributes(global.testmap, 4, 0, 0, 0xff);
814 819
      map.initialize();
815 820
      global.testres[global.tcase] = !map.get_state()->valid;
816 821

  
822
      global.tcase++; // 4
823
      // Test Reinitialization
824
      setAttributes(global.testmap, 0, 1, 2, 1);
825
      setAttributes(global.testmap, 1, 2, 2, 0);
826
      setAttributes(global.testmap, 2, 1, 0, 0);
827
      setAttributes(global.testmap, 3, 0, 0, 0xff);
828
      map.initialize();
829
      global.testres[global.tcase] = map.get_state()->valid;
830

  
831
      global.odometry.resetPosition();
832
      uint8_t ret = 0;
833
      global.tcase++; // 5
834
      // Test update under normal linefollowing without fixpoint
835
      ret = map.update(20000, 20000, LineFollowStrategy::EDGE_RIGHT);
836
      chprintf((BaseSequentialStream *)&global.sercanmux1,
837
               "Update test %d: Ret %d, cur %d, nex %d\n", global.tcase, ret,
838
               map.get_state()->current, map.get_state()->next);
839
      // No case should be true because neither was a node visited nor
840
      // was a fixpoint detected.
841
      global.testres[global.tcase] = (ret == 0x4);
842

  
843

  
844
      global.odometry.setPosition(1.0, 0.0, 0.0);
845
      global.tcase++; // 6
846
      // Fixpoint on left side
847
      ret = map.update(0, 20000, LineFollowStrategy::EDGE_RIGHT);
848
      chprintf((BaseSequentialStream *)&global.sercanmux1,
849
               "Update test %d: Ret %d, cur %d, nex %d\n", global.tcase, ret,
850
               map.get_state()->current, map.get_state()->next);
851
      // No case should be true because neither was a node visited nor
852
      // was a fixpoint detected.
853
      // global.odometry
854
      global.testres[global.tcase] = (ret == 0x1)
855
        && (map.get_state()->strategy == 0x01)
856
        && (map.get_state()->dist == 0)
857
        && (map.get_state()->current == 2);
858

  
859

  
860
      global.odometry.setPosition(1.5, 0.0, 0.0);
861
      global.tcase++; // 7
862
      // Fixpoint on left side, no update should appear because fixpoint already
863
      // marked
864
      ret = map.update(0, 20000, LineFollowStrategy::EDGE_RIGHT);
865
      chprintf((BaseSequentialStream *)&global.sercanmux1,
866
               "Update test %d: Ret %d, cur %d, nex %d\n", global.tcase, ret,
867
               map.get_state()->current, map.get_state()->next);
868
      // No case should be true because neither was a node visited nor
869
      // was a fixpoint detected.
870
      global.testres[global.tcase] = (ret == 0x00)
871
        && (map.get_state()->strategy == 0x01);
872
        // && (map.get_state()->dist == 0);
873

  
874

  
875

  
876

  
877

  
817 878
      int failed = 0;
818 879
      int passed = 0;
819 880
      for (int i = 0; i <= global.tcase; i++) {

Also available in: Unified diff