Revision 64cba697
| devices/DiWheelDrive/amiro_map.cpp | ||
|---|---|---|
| 26 | 26 | 
    }  | 
| 27 | 27 | 
     | 
| 28 | 28 | 
    this->nodeList[i].id = i;  | 
| 29 | 
    this->nodeList[i].left = global->testmap[i][0];  | 
|
| 30 | 
    this->nodeList[i].right = global->testmap[i][1];  | 
|
| 29 | 
        this->nodeList[i].edge.edge_id.left = global->testmap[i][0];
   | 
|
| 30 | 
        this->nodeList[i].edge.edge_id.right = global->testmap[i][1];
   | 
|
| 31 | 31 | 
    this->nodeList[i].flag = global->testmap[i][2];  | 
| 32 | 32 | 
    this->nodeCount++;  | 
| 33 | 33 | 
    }  | 
| 34 | 
    this->state.next = this->nodeList[this->state.current].right;  | 
|
| 34 | 
      this->state.next = this->nodeList[this->state.current].edge.edge_id.right;
   | 
|
| 35 | 35 | 
     | 
| 36 | 36 | 
    // TODO make validity check  | 
| 37 | 37 | 
     | 
| ... | ... | |
| 57 | 57 | 
    return;  | 
| 58 | 58 | 
      }else{
   | 
| 59 | 59 | 
    nodeList[id].visited = 1;  | 
| 60 | 
    visitNode(this->nodeList[id].left);  | 
|
| 61 | 
    visitNode(this->nodeList[id].right);  | 
|
| 60 | 
        visitNode(this->nodeList[id].edge.edge_id.left);
   | 
|
| 61 | 
        visitNode(this->nodeList[id].edge.edge_id.right);
   | 
|
| 62 | 62 | 
    }  | 
| 63 | 63 | 
    }  | 
| 64 | 64 | 
     | 
| ... | ... | |
| 71 | 71 | 
    // but we will go with it for now to initialize everything properly.  | 
| 72 | 72 | 
    uint8_t flag = 0;  | 
| 73 | 73 | 
    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();  | 
|
| 76 | 
     | 
|
| 77 | 74 | 
    // Check the wheel sensors  | 
| 78 | 75 | 
    bool left = global->linePID.BThresh >= WL;  | 
| 79 | 76 | 
    bool right = global->linePID.BThresh >= WR;  | 
| ... | ... | |
| 83 | 80 | 
    // TODO A dangerous case -> amiro could be lifted  | 
| 84 | 81 | 
    flag |= 255;  | 
| 85 | 82 | 
    }  | 
| 86 | 
      else if (left && !leftDetected) {
   | 
|
| 83 | 
      else if (left && !fxpDetected) { // Driving on the right edge
   | 
|
| 87 | 84 | 
    // The sensor on the left side of the Amiro is driving on black  | 
| 88 | 85 | 
    // To prevent continous fixpoint detection a point needs to be marked as currently detected  | 
| 89 | 86 | 
    // and released.  | 
| 90 | 
    leftDetected = true;  | 
|
| 91 | 
    copyPoint(¤tPos, &nodeList[state.next].pR);  | 
|
| 92 | 
    nodeList[state.next].visited |= 0x01;  | 
|
| 93 | 
    state.current = state.next;  | 
|
| 94 | 
    state.next = nodeList[state.current].right;  | 
|
| 95 | 
    state.strategy = 0x01;  | 
|
| 96 | 
    state.eLength = 0; // Reset length to get recalculated after fixpoint  | 
|
| 97 | 
    flag |= 0x1;  | 
|
| 87 | 
    state.strategy = 0x02;  | 
|
| 88 | 
    switchToNext(¤tPos);  | 
|
| 89 | 
    flag |= 0x2;  | 
|
| 98 | 90 | 
    }  | 
| 99 | 
      else if (right && !rightDetected) {
   | 
|
| 91 | 
      else if (right && !fxpDetected) { // Driving on the left edge
   | 
|
| 100 | 92 | 
    // Same as left only for the right sensor.  | 
| 101 | 
    rightDetected = true;  | 
|
| 102 | 
    copyPoint(¤tPos, &nodeList[state.next].pR);  | 
|
| 103 | 
    nodeList[state.next].visited |= 0x02;  | 
|
| 104 | 
    state.current = state.next;  | 
|
| 105 | 
    state.next = nodeList[state.current].left;  | 
|
| 106 | 
    state.strategy = 0x2;  | 
|
| 107 | 
    state.eLength = 0; // Reset length to get recalculated after fixpoint  | 
|
| 108 | 
    flag |= 0x2;  | 
|
| 93 | 
    state.strategy = 0x01;  | 
|
| 94 | 
    switchToNext(¤tPos);  | 
|
| 95 | 
    flag |= 0x1;  | 
|
| 109 | 96 | 
    }  | 
| 110 | 97 | 
      else if (!left && !right) {
   | 
| 111 | 98 | 
    // in case the fixpoint is not detected anymore  | 
| 112 | 
    leftDetected = false;  | 
|
| 113 | 
    rightDetected = false;  | 
|
| 99 | 
    fxpDetected = false;  | 
|
| 114 | 100 | 
    flag |= 0x4;  | 
| 115 | 101 | 
    }  | 
| 116 | 102 | 
     | 
| 103 | 
    // Update dist and edge length if possible  | 
|
| 104 | 
    calTravelState(¤tPos);  | 
|
| 117 | 105 | 
     | 
| 118 | 
    // update internal map_state  | 
|
| 119 | 
    // Update travel distance  | 
|
| 120 | 
    // check if the nodes of the specific strategy where visited  | 
|
| 121 | 
    if (state.strategy  | 
|
| 122 | 
          == nodeList[state.current].visited) {
   | 
|
| 123 | 
    flag |= 0x8;  | 
|
| 124 | 
    // only update distance if both nodes were visited  | 
|
| 125 | 
    // Calculate estimated length of the edge  | 
|
| 126 | 
        if (state.strategy == 0x01) {
   | 
|
| 127 | 
    // Amiro is driving on the right edge  | 
|
| 128 | 
    // only calculate edge length if the node is already vivited  | 
|
| 129 | 
          if ((state.eLength == 0) && (state.strategy == nodeList[state.current].visited)) {
   | 
|
| 130 | 
    state.eLength = calculateDist(&nodeList[state.next].pR,  | 
|
| 131 | 
    &nodeList[state.current].pR);  | 
|
| 132 | 
    }  | 
|
| 133 | 
    state.dist = calculateDist(&nodeList[state.current].pR, ¤tPos);  | 
|
| 134 | 
        } else {
   | 
|
| 135 | 
    // Driving on the left edge  | 
|
| 136 | 
    if ((state.eLength == 0) &&  | 
|
| 137 | 
              (state.strategy == nodeList[state.current].visited)) {
   | 
|
| 138 | 
    state.eLength = calculateDist(&nodeList[state.next].pR,  | 
|
| 139 | 
    &nodeList[state.current].pR);  | 
|
| 140 | 
    }  | 
|
| 141 | 
    state.dist = calculateDist(&nodeList[state.current].pL, ¤tPos);  | 
|
| 142 | 
     | 
|
| 143 | 
    }  | 
|
| 144 | 
    }  | 
|
| 145 | 106 | 
    return flag;  | 
| 146 | 107 | 
    }  | 
| 147 | 108 | 
     | 
| ... | ... | |
| 169 | 130 | 
    types::position currentPos = global->odometry.getPosition();  | 
| 170 | 131 | 
     | 
| 171 | 132 | 
    // Assign fixpoint if side sensor is black  | 
| 172 | 
      // Do not update if update was already applied the round before (leftDetected || rightDetected) == true
   | 
|
| 173 | 
      if ((left || right) && !(leftDetected || rightDetected)) {
   | 
|
| 133 | 
    // Do not update if update was already applied the round before (|| rightDetected) == true  | 
|
| 134 | 
      if ((left || right) && !fxpDetected) {
   | 
|
| 174 | 135 | 
    // Determine what strategy to use  | 
| 175 | 136 | 
    // assignFxp() will use strategy to assign the next point  | 
| 176 | 
        state.strategy = right ? 1 : 2;
   | 
|
| 137 | 
        state.strategy = left ? 1 : 2;
   | 
|
| 177 | 138 | 
     | 
| 178 | 139 | 
    // Check if next point is reachable  | 
| 179 | 140 | 
        if (state.next == 255){
   | 
| ... | ... | |
| 183 | 144 | 
     | 
| 184 | 145 | 
      }else if (!(left || right)) {
   | 
| 185 | 146 | 
    // TODO: do we need both?  | 
| 186 | 
        leftDetected = rightDetected = true;
   | 
|
| 147 | 
        fxpDetected = true;
   | 
|
| 187 | 148 | 
    }  | 
| 188 | 149 | 
    }  | 
| 189 | 150 | 
     | 
| 190 | 151 | 
    void AmiroMap::calTravelState(types::position *p1) {
   | 
| 191 | 152 | 
    // Calculate the moved distance from last detected fixpoint  | 
| 192 | 
    state.dist = calculateDist(p1, &nodeList[state.current].p.arr[state.strategy - 1]);  | 
|
| 193 | 
     | 
|
| 194 | 
    // Calculate elength if it is 0  | 
|
| 195 | 
    // and if the point of the next node was visited before  | 
|
| 196 | 
      if ((state.eLength == 0) && ((state.strategy & nodeList[state.next].visited) == 1)) {
   | 
|
| 197 | 
    state.eLength =  | 
|
| 153 | 
    // if current was visited  | 
|
| 154 | 
      if ((state.strategy & nodeList[state.current].visited) > 0) {
   | 
|
| 155 | 
    state.dist =  | 
|
| 198 | 156 | 
    calculateDist(p1, &nodeList[state.current].p.arr[state.strategy - 1]);  | 
| 199 | 157 | 
    }  | 
| 200 | 
    }  | 
|
| 158 | 
    // Calculate elength if it is 0  | 
|
| 159 | 
    // and if the point of the next node was visited before  | 
|
| 160 | 
    if ((state.eLength == 0) &&  | 
|
| 161 | 
            ((state.strategy & nodeList[state.next].visited) > 0)) {
   | 
|
| 162 | 
    state.eLength =  | 
|
| 163 | 
    calculateDist(&nodeList[state.current].p.arr[state.strategy - 1],  | 
|
| 164 | 
    &nodeList[state.next].p.arr[state.strategy - 1]);  | 
|
| 165 | 
    }  | 
|
| 166 | 
    }  | 
|
| 201 | 167 | 
     | 
| 202 | 168 | 
    void AmiroMap::checkMap() {
   | 
| 203 | 169 | 
    // The check will basically only consist in checking if all nodes  | 
| ... | ... | |
| 222 | 188 | 
    nodeList[state.next].visited |= state.strategy;  | 
| 223 | 189 | 
    }  | 
| 224 | 190 | 
     | 
| 225 | 
      leftDetected = true;
   | 
|
| 191 | 
      fxpDetected = true;
   | 
|
| 226 | 192 | 
    state.current = state.next;  | 
| 227 | 193 | 
    state.next = nodeList[state.current].edge.arr[state.strategy - 1];  | 
| 228 | 194 | 
    state.eLength = 0; // Reset length to get recalculated after fixpoint  | 
| devices/DiWheelDrive/amiro_map.hpp | ||
|---|---|---|
| 99 | 99 | 
    node nodeList[MAX_NODES];  | 
| 100 | 100 | 
    // If driving over fixpoint prevent continuous updating  | 
| 101 | 101 | 
    // True if left sensor is driving over black  | 
| 102 | 
    bool leftDetected = false;  | 
|
| 103 | 
    // True if right sensor is driving over black  | 
|
| 104 | 
    bool rightDetected = false;  | 
|
| 102 | 
    bool fxpDetected = false;  | 
|
| 105 | 103 | 
     | 
| 106 | 104 | 
    /**  | 
| 107 | 105 | 
    * Recursively search through all nodes in the node list and  | 
| devices/DiWheelDrive/userthread.cpp | ||
|---|---|---|
| 877 | 877 | 
    // No case should be true because neither was a node visited nor  | 
| 878 | 878 | 
    // was a fixpoint detected.  | 
| 879 | 879 | 
    // global.odometry  | 
| 880 | 
          global.testres[global.tcase] = (ret == 0x1)
   | 
|
| 881 | 
            && (map.get_state()->strategy == 0x01)
   | 
|
| 880 | 
          global.testres[global.tcase] = (ret == 0x2)
   | 
|
| 881 | 
            && (map.get_state()->strategy == 0x02)
   | 
|
| 882 | 882 | 
    && (map.get_state()->dist == 0)  | 
| 883 | 883 | 
    && (map.get_state()->current == 2);  | 
| 884 | 884 | 
     | 
| ... | ... | |
| 896 | 896 | 
    // No case should be true because neither was a node visited nor  | 
| 897 | 897 | 
    // was a fixpoint detected.  | 
| 898 | 898 | 
    global.testres[global.tcase] = (ret == 0x00)  | 
| 899 | 
            && (map.get_state()->strategy == 0x01);
   | 
|
| 899 | 
            && (map.get_state()->strategy == 0x02);
   | 
|
| 900 | 900 | 
    // && (map.get_state()->dist == 0);  | 
| 901 | 901 | 
     | 
| 902 | 902 | 
    global.odometry.setPosition(1.2, 0.0, 0.0);  | 
| ... | ... | |
| 910 | 910 | 
    // No case should be true because neither was a node visited nor  | 
| 911 | 911 | 
    // was a fixpoint detected.  | 
| 912 | 912 | 
    global.testres[global.tcase] =  | 
| 913 | 
    (ret == 0x04) && (map.get_state()->strategy == 0x01)  | 
|
| 914 | 
    && (map.get_state()->dist == 0);  | 
|
| 913 | 
    (ret == 0x04) && (map.get_state()->strategy == 0x02);  | 
|
| 915 | 914 | 
     | 
| 916 | 915 | 
    global.odometry.setPosition(.5, 0.0, 0.0);  | 
| 917 | 916 | 
    chprintf((BaseSequentialStream *)&global.sercanmux1,  | 
| ... | ... | |
| 928 | 927 | 
    // No case should be true because neither was a node visited nor  | 
| 929 | 928 | 
    // was a fixpoint detected.  | 
| 930 | 929 | 
    global.testres[global.tcase] =  | 
| 931 | 
            (ret == 9) &&
   | 
|
| 932 | 
            (map.get_state()->strategy == 1) &&
   | 
|
| 933 | 
    (map.get_state()->dist == 0) &&  | 
|
| 930 | 
            (ret == 2) &&
   | 
|
| 931 | 
            (map.get_state()->strategy == 2) &&
   | 
|
| 932 | 
            // (map.get_state()->dist == 0) &&
   | 
|
| 934 | 933 | 
    (map.get_state()->eLength == 50);  | 
| 935 | 934 | 
     | 
| 936 | 935 | 
    global.odometry.setPosition(.75, 0.0, 0.0);  | 
| ... | ... | |
| 948 | 947 | 
    // No case should be true because neither was a node visited nor  | 
| 949 | 948 | 
    // was a fixpoint detected.  | 
| 950 | 949 | 
    global.testres[global.tcase] =  | 
| 951 | 
    (ret == 12) && (map.get_state()->strategy == 1) &&  | 
|
| 952 | 
    (map.get_state()->dist == 50) && (map.get_state()->eLength == 50);  | 
|
| 950 | 
    (ret == 4) && (map.get_state()->strategy == 2) &&  | 
|
| 951 | 
    // (map.get_state()->dist == 50)  | 
|
| 952 | 
    (map.get_state()->eLength == 50);  | 
|
| 953 | 953 | 
     | 
| 954 | 954 | 
    int failed = 0;  | 
| 955 | 955 | 
    int passed = 0;  | 
| devices/DiWheelDrive/userthread.hpp | ||
|---|---|---|
| 62 | 62 | 
     | 
| 63 | 63 | 
    // Map Tracking Parameters  | 
| 64 | 64 | 
    // enable amiro map to continuously build internal map representation  | 
| 65 | 
    #define AMIRO_MAP_AUTO_TRACKING true
   | 
|
| 65 | 
    #define AMIRO_MAP_AUTO_TRACKING false
   | 
|
| 66 | 66 | 
     | 
| 67 | 67 | 
     | 
| 68 | 68 | 
     | 
| ... | ... | |
| 75 | 75 | 
    // Messages which can be received and trigger state changes  | 
| 76 | 76 | 
    public:  | 
| 77 | 77 | 
     | 
| 78 | 
    // States of user thread state machine  | 
|
| 79 | 
        // enum ut_states : int8_t {
   | 
|
| 80 | 
    // UT_IDLE = 0,  | 
|
| 81 | 
    // UT_FOLLOW_LINE = 1,  | 
|
| 82 | 
    // UT_DETECT_STATION = 2,  | 
|
| 83 | 
    // UT_REVERSE = 3,  | 
|
| 84 | 
    // UT_PUSH_BACK = 4,  | 
|
| 85 | 
    // UT_CHECK_POSITIONING = 5,  | 
|
| 86 | 
    // UT_CHECK_VOLTAGE = 6,  | 
|
| 87 | 
    // UT_CHARGING = 7,  | 
|
| 88 | 
    // UT_RELEASE = 8,  | 
|
| 89 | 
    // UT_RELEASE_TO_CORRECT = 9,  | 
|
| 90 | 
    // UT_CORRECT_POSITIONING = 10,  | 
|
| 91 | 
    // UT_TURN = 12,  | 
|
| 92 | 
    // UT_INACTIVE = 13,  | 
|
| 93 | 
    // UT_CALIBRATION = 14,  | 
|
| 94 | 
    // UT_CALIBRATION_CHECK = 15,  | 
|
| 95 | 
    // UT_DEVIATION_CORRECTION = 16,  | 
|
| 96 | 
    // UT_TEST_MAP_STATE = 17,  | 
|
| 97 | 
    // UT_TEST_MAP_AUTO_STATE = 18,  | 
|
| 98 | 
    // UT_DOCKING_ERROR = -1,  | 
|
| 99 | 
    // UT_REVERSE_TIMEOUT_ERROR = -2,  | 
|
| 100 | 
    // UT_CALIBRATION_ERROR = -3,  | 
|
| 101 | 
    // UT_WHITE_DETECTION_ERROR = -4,  | 
|
| 102 | 
    // UT_PROXY_DETECTION_ERROR = -5,  | 
|
| 103 | 
    // UT_NO_CHARGING_POWER_ERROR = -6,  | 
|
| 104 | 
    // UT_UNKNOWN_STATE_ERROR = -7  | 
|
| 105 | 
    // };  | 
|
| 106 | 
     | 
|
| 107 | 
        struct ut_counter {
   | 
|
| 108 | 
    int whiteCount = 0;  | 
|
| 109 | 
    int ringProxCount = 0;  | 
|
| 110 | 
    // int correctionCount = 0;  | 
|
| 111 | 
    int errorCount = 0;  | 
|
| 112 | 
    int stateCount = 0;  | 
|
| 113 | 
    int stepCount = 0;  | 
|
| 114 | 
    uint32_t stateTime = 0;  | 
|
| 78 | 
      struct ut_counter {
   | 
|
| 79 | 
    int whiteCount = 0;  | 
|
| 80 | 
    int ringProxCount = 0;  | 
|
| 81 | 
    // int correctionCount = 0;  | 
|
| 82 | 
    int errorCount = 0;  | 
|
| 83 | 
    int stateCount = 0;  | 
|
| 84 | 
    int stepCount = 0;  | 
|
| 85 | 
    uint32_t stateTime = 0;  | 
|
| 115 | 86 | 
    };  | 
| 116 | 87 | 
     | 
| 117 | 88 | 
      struct proxy_ctrl {
   | 
Also available in: Unified diff