Converts the IR sensors data into a line tracking value that determines the Octoliner board position relative to the line.
map-line
@/map-line
Converts the IR sensors data into a line tracking value that determines the Octoliner board position relative to the line.
CH0number
CH1number
CH2number
CH3number
CH4number
CH5number
CH6number
CH7number
LINEnumber
Last calculated line tracking value in the range [-1,1].
The 0 value shows that line is at the center position relative to the sensors. The -1 value corresponds to the extreme left position while the 1 to the extreme right.
To use the node in your project you should have the amperka/octoliner library installed. Use the “File → Add Library” menu item in XOD IDE if you don’t have it yet. See Using libraries for more info.
C++ implementation
struct State {
float line;
const uint8_t ADCResolution = 10;
};
// clang-format off
{{ GENERATED_CODE }}
// clang-format on
void evaluate(Context ctx) {
auto state = getState(ctx);
int16_t min = 32767;
int16_t max = 0;
int16_t binaryLine[8] =
{ getValue<input_CH0>(ctx) * pow(2,state->ADCResolution),
getValue<input_CH1>(ctx) * pow(2,state->ADCResolution),
getValue<input_CH2>(ctx) * pow(2,state->ADCResolution),
getValue<input_CH3>(ctx) * pow(2,state->ADCResolution),
getValue<input_CH4>(ctx) * pow(2,state->ADCResolution),
getValue<input_CH5>(ctx) * pow(2,state->ADCResolution),
getValue<input_CH6>(ctx) * pow(2,state->ADCResolution),
getValue<input_CH7>(ctx) * pow(2,state->ADCResolution)};
uint8_t pattern = 0b00000000;
for (uint8_t i = 0; i < 8; i++) {
if (binaryLine[i] < min)
min = binaryLine[i];
if (binaryLine[i] > max)
max = binaryLine[i];
}
// calculate border level
int16_t threshold = min + (max - min) / 2;
// create bit pattern
for (uint8_t i = 0; i < 8; i++) {
pattern = (pattern << 1) + ((binaryLine[i] < threshold) ? 0 : 1);
}
switch (pattern) {
case 0b00011000:
state->line = 0;
break;
case 0b00010000:
state->line = 0.25;
break;
case 0b00111000:
state->line = 0.25;
break;
case 0b00001000:
state->line = -0.25;
break;
case 0b00011100:
state->line = -0.25;
break;
case 0b00110000:
state->line = 0.375;
break;
case 0b00001100:
state->line = -0.375;
break;
case 0b00100000:
state->line = 0.5;
break;
case 0b01110000:
state->line = 0.5;
break;
case 0b00000100:
state->line = -0.5;
break;
case 0b00001110:
state->line = -0.5;
break;
case 0b01100000:
state->line = 0.625;
break;
case 0b11100000:
state->line = 0.625;
break;
case 0b00000110:
state->line = -0.625;
break;
case 0b00000111:
state->line = -0.625;
break;
case 0b01000000:
state->line = 0.75;
break;
case 0b11110000:
state->line = 0.75;
break;
case 0b00000010:
state->line = -0.75;
break;
case 0b00001111:
state->line = -0.75;
break;
case 0b11000000:
state->line = 0.875;
break;
case 0b00000011:
state->line = -0.875;
break;
case 0b10000000:
state->line = 1.0;
break;
case 0b00000001:
state->line = -1.0;
break;
default:
break; // for other patterns return previous value
}
emitValue<output_LINE>(ctx, state->line);
}