ROME 2 Lab5

Committer:
oehlemar
Date:
Tue Apr 28 13:59:27 2020 +0000
Revision:
0:893a1e710078
Child:
1:5201940a41c1
initial publish

Who changed what in which revision?

UserRevisionLine numberNew contents of line
oehlemar 0:893a1e710078 1 /*
oehlemar 0:893a1e710078 2 * LIDAR.cpp
oehlemar 0:893a1e710078 3 * Copyright (c) 2020, ZHAW
oehlemar 0:893a1e710078 4 * All rights reserved.
oehlemar 0:893a1e710078 5 */
oehlemar 0:893a1e710078 6
oehlemar 0:893a1e710078 7 #include <cmath>
oehlemar 0:893a1e710078 8 #include "LIDAR.h"
oehlemar 0:893a1e710078 9
oehlemar 0:893a1e710078 10 using namespace std;
oehlemar 0:893a1e710078 11
oehlemar 0:893a1e710078 12 const float LIDAR::DISTANCE_THRESHOLD = 0.01f; // threshold for measured distance, given in [m]
oehlemar 0:893a1e710078 13 const float LIDAR::DEFAULT_DISTANCE = 10.0f; // default distance > range of sensor, given in [m]
oehlemar 0:893a1e710078 14 const float LIDAR::M_PI = 3.1415926535897932f; // the mathematical constant PI
oehlemar 0:893a1e710078 15 const float LIDAR::DISTANCES[] = {10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 1.702465271f, 1.699141254f, 1.69632544f, 1.692140952f, 1.689068974f, 1.68018005f, 1.676267878f, 1.666183663f, 1.671424841f, 1.66193261f, 1.655635528f, 1.653413439f, 1.653517463f, 1.657246512f, 1.655132925f, 1.650946698f, 1.65257254f, 1.66468045f, 1.23646674f, 1.236336928f, 1.251003597f, 1.353653575f, 1.322500662f, 1.304577326f, 1.299988461f, 1.314887448f, 1.320968206f, 1.320374568f, 1.251579003f, 1.235510016f, 1.233241663f, 1.243382483f, 1.314194811f, 1.318788838f, 1.438384163f, 1.419872177f, 1.368804223f, 1.347354445f, 1.342721118f, 1.354318279f, 1.366872708f, 1.369305298f, 1.383822604f, 1.508895291f, 1.493255504f, 1.475824515f, 1.435599178f, 1.445460826f, 1.462035909f, 1.654100964f, 1.644884494f, 1.707480307f, 1.701130213f, 1.660187941f, 1.634974006f, 1.61723344f, 1.620856564f, 1.798737613f, 1.779742116f, 1.77366344f, 1.77661504f, 1.777926039f, 1.920203375f, 1.935389367f, 2.291142292f, 2.328650253f, 2.363611643f, 2.448420103f, 2.487483266f, 2.57330313f, 2.545476969f, 2.040235771f, 2.028301999f, 2.014f, 1.98730823f, 1.972207393f, 1.955661781f, 1.944761168f, 1.923351242f, 1.909502815f, 1.903193369f, 1.875251983f, 1.874046424f, 1.857301806f, 1.845873235f, 1.837153505f, 1.817614371f, 1.803495495f, 1.796232168f, 1.784177401f, 1.781868963f, 1.775984797f, 1.764001134f, 1.761087448f, 1.753326267f, 1.75371748f, 1.745729933f, 1.742740658f, 1.737636613f, 1.741089889f, 1.735240617f, 1.735295076f, 1.728695462f, 1.720377865f, 1.657877257f, 1.727796574f, 1.734111011f, 1.729579429f, 1.736116356f, 1.743193908f, 1.745805545f, 1.750349965f, 1.750429662f, 1.754628166f, 1.760757223f, 1.766661541f, 1.766717012f, 1.776524697f, 1.161069335f, 1.148512081f, 1.14054373f, 1.135753494f, 1.134139321f, 1.147087617f, 1.168199041f, 1.17903223f, 1.18040205f, 1.183327934f, 1.147416228f, 1.210927331f, 1.217378331f, 1.203945597f, 1.227244067f, 1.237879235f, 0.547902364f, 0.544882556f, 0.548745843f, 0.548314691f, 0.553859188f, 0.558237405f, 0.562782374f, 0.572875205f, 0.577382023f, 0.587456381f, 0.593270596f, 0.595157122f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 10.0f, 1.826932128f, 1.764292776f, 1.757409742f, 1.728041956f, 1.704264064f, 1.688f, 1.679250428f, 1.66501051f, 1.644250589f, 1.634979205f, 1.626211548f, 1.608795823f, 1.589880499f, 1.58137788f, 1.575325998f, 1.560708173f, 1.550516043f, 1.54374253f, 1.532342651f, 1.520213472f, 1.512674783f, 1.507533416f, 1.497487229f, 1.494217186f, 1.48919072f, 1.232154617f, 1.358305194f, 1.313616382f, 1.260025397f, 1.133025154f, 1.117565658f, 1.100202254f, 1.100181803f, 1.169824773f, 1.168748476f, 1.164819729f, 1.220040983f, 1.203097669f, 1.200735191f, 1.189294329f, 1.186247866f, 1.195532517f, 1.229603188f, 1.472497538f, 1.474618595f, 1.479985473f, 1.480043918f, 1.484135439f, 1.490767923f, 1.496454476f, 1.501894803f, 1.511313667f, 1.516939682f, 1.525908582f, 1.535359893f, 1.544518695f, 1.549271119f, 1.555904881f, 1.575204114f, 1.580785248f, 0.959320593f, 0.920540059f, 0.905058009f, 0.900680298f, 0.898481497f, 0.902731965f, 0.918059911f, 1.718295085f, 1.721370675f, 1.735719159f, 1.763130455f, 1.775434595f, 1.817423726f, 1.836723441f, 1.847665825f, 1.884798663f, 1.897461462f, 1.83701742f, 1.811276898f, 1.759177649f, 1.740189932f, 1.702600364f, 1.687345845f, 1.637890411f, 1.604450373f, 1.589151031f, 1.55510289f, 1.544042098f, 1.516327801f, 1.502226681f, 1.479634076f, 1.483579792f, 1.518056982f, 1.568964308f, 1.602244675f, 1.663f, 1.700264685f, 1.771085543f, 1.812491379f, 1.888618543f, 1.937385093f, 2.032088827f, 2.089617429f, 2.205471605f, 2.275026373f, 2.345580738f, 2.499928999f, 2.581471286f, 2.784285366f, 2.885689519f, 2.858447306f, 2.850508025f, 2.832713364f, 2.828422882f, 2.812354352f, 2.808188206f, 2.789411407f, 2.789161343f, 2.77675368f, 2.765194568f, 1.967565247f, 1.958f, 2.397585661f, 2.75211991f, 2.743884108f, 2.743676366f, 2.746035688f, 2.735854528f, 10.0f, 10.0f, 10.0f, 2.76492206f, 2.761207888f, 2.762739582f, 2.766510618f, 2.788146338f, 2.786430153f, 2.801847426f, 2.811054073f, 2.691653024f, 2.664378352f, 2.401709391f, 2.204667775f, 2.12351713f, 2.141373625f, 2.14578121f, 2.165700349f, 2.171425799f, 2.185005721f, 2.197850768f, 2.21938122f, 2.229375025f, 2.23809964f, 2.265003532f, 2.644680132f, 2.54522003f, 2.527676008f, 2.480120158f, 2.52638279f, 2.386449455f, 2.36217802f, 2.291129198f, 2.094351451f, 2.007193314f, 2.009421807f, 2.047382719f, 2.035974951f, 1.865168089f, 1.820468346f, 1.800660157f, 1.80447721f, 1.836480329f, 1.730293906f, 1.678679541f, 1.66250203f, 1.677434052f, 1.719175675f, 1.720679226f, 1.622129465f, 1.618845576f, 1.634181141f, 10.0f, 10.0f, 10.0f, 10.0f};
oehlemar 0:893a1e710078 16
oehlemar 0:893a1e710078 17 /**
oehlemar 0:893a1e710078 18 * Creates a LIDAR object.
oehlemar 0:893a1e710078 19 * @param serial a reference to a serial interface to communicate with the laser scanner.
oehlemar 0:893a1e710078 20 */
oehlemar 0:893a1e710078 21 LIDAR::LIDAR(RawSerial& serial) : serial(serial) {
oehlemar 0:893a1e710078 22
oehlemar 0:893a1e710078 23 // initialize serial interface
oehlemar 0:893a1e710078 24
oehlemar 0:893a1e710078 25 serial.baud(115200);
oehlemar 0:893a1e710078 26 serial.format(8, SerialBase::None, 1);
oehlemar 0:893a1e710078 27
oehlemar 0:893a1e710078 28 // initialize local values
oehlemar 0:893a1e710078 29
oehlemar 0:893a1e710078 30 headerCounter = 0;
oehlemar 0:893a1e710078 31 dataCounter = 0;
oehlemar 0:893a1e710078 32
oehlemar 0:893a1e710078 33 for (unsigned short i = 0; i < 360; i++) distances[i] = DEFAULT_DISTANCE;
oehlemar 0:893a1e710078 34
oehlemar 0:893a1e710078 35 simulation = true;
oehlemar 0:893a1e710078 36
oehlemar 0:893a1e710078 37 // start serial interrupt
oehlemar 0:893a1e710078 38
oehlemar 0:893a1e710078 39 serial.attach(callback(this, &LIDAR::receive), RawSerial::RxIrq);
oehlemar 0:893a1e710078 40
oehlemar 0:893a1e710078 41 // start the continuous operation of the LIDAR
oehlemar 0:893a1e710078 42
oehlemar 0:893a1e710078 43 serial.putc(START_FLAG);
oehlemar 0:893a1e710078 44 serial.putc(SCAN);
oehlemar 0:893a1e710078 45 }
oehlemar 0:893a1e710078 46
oehlemar 0:893a1e710078 47 /**
oehlemar 0:893a1e710078 48 * Stops the lidar and deletes this object.
oehlemar 0:893a1e710078 49 */
oehlemar 0:893a1e710078 50 LIDAR::~LIDAR() {
oehlemar 0:893a1e710078 51
oehlemar 0:893a1e710078 52 // stop the LIDAR
oehlemar 0:893a1e710078 53
oehlemar 0:893a1e710078 54 serial.putc(START_FLAG);
oehlemar 0:893a1e710078 55 serial.putc(STOP);
oehlemar 0:893a1e710078 56 }
oehlemar 0:893a1e710078 57
oehlemar 0:893a1e710078 58 /**
oehlemar 0:893a1e710078 59 * Get a list of points of a full 360 degree scan.
oehlemar 0:893a1e710078 60 * @return a deque vector of 360 point objects.
oehlemar 0:893a1e710078 61 */
oehlemar 0:893a1e710078 62 deque<Point> LIDAR::getScan() {
oehlemar 0:893a1e710078 63
oehlemar 0:893a1e710078 64 deque<Point> scan;
oehlemar 0:893a1e710078 65
oehlemar 0:893a1e710078 66 for (unsigned short i = 0; i < 360; i++) {
oehlemar 0:893a1e710078 67
oehlemar 0:893a1e710078 68 if (simulation) {
oehlemar 0:893a1e710078 69
oehlemar 0:893a1e710078 70 // use simulated distances, because LIDAR is not available
oehlemar 0:893a1e710078 71
oehlemar 0:893a1e710078 72 scan.push_back(Point(DISTANCES[i]-0.002f*(rand()%10), (float)i*M_PI/180.0f));
oehlemar 0:893a1e710078 73
oehlemar 0:893a1e710078 74 } else {
oehlemar 0:893a1e710078 75
oehlemar 0:893a1e710078 76 // use latest measurements from actual LIDAR
oehlemar 0:893a1e710078 77
oehlemar 0:893a1e710078 78 scan.push_back(Point(distances[i], (float)i*M_PI/180.0f));
oehlemar 0:893a1e710078 79 }
oehlemar 0:893a1e710078 80 }
oehlemar 0:893a1e710078 81
oehlemar 0:893a1e710078 82 return scan;
oehlemar 0:893a1e710078 83 }
oehlemar 0:893a1e710078 84
oehlemar 0:893a1e710078 85 /**
oehlemar 0:893a1e710078 86 * Get a list of points which are part of beacons.
oehlemar 0:893a1e710078 87 * @return a deque vector of points that are beacons.
oehlemar 0:893a1e710078 88 */
oehlemar 0:893a1e710078 89 deque<Point> LIDAR::getBeacons() {
oehlemar 0:893a1e710078 90
oehlemar 0:893a1e710078 91 // get a list of all points of a scan
oehlemar 0:893a1e710078 92
oehlemar 0:893a1e710078 93 deque<Point> scan = getScan();
oehlemar 0:893a1e710078 94
oehlemar 0:893a1e710078 95 // create a list of points of beacons
oehlemar 0:893a1e710078 96
oehlemar 0:893a1e710078 97 deque<Point> beacons;
oehlemar 0:893a1e710078 98
oehlemar 0:893a1e710078 99 // bitte implementieren!
oehlemar 0:893a1e710078 100 for (unsigned short i = 0; i < 358; i++) {
oehlemar 0:893a1e710078 101
oehlemar 0:893a1e710078 102 if ((DISTANCES[i] < 1) && ((((DISTANCES[i+1]-DISTANCES[i])<0.1)&&(DISTANCES[i+2]-DISTANCES[i+1])<0.1))) { //||((DISTANCES[i+1]-DISTANCES[i])>0.5))
oehlemar 0:893a1e710078 103
oehlemar 0:893a1e710078 104 beacons.push_back(Point(distances[i], (float)i*M_PI/180.0f));
oehlemar 0:893a1e710078 105
oehlemar 0:893a1e710078 106 }
oehlemar 0:893a1e710078 107
oehlemar 0:893a1e710078 108 }
oehlemar 0:893a1e710078 109
oehlemar 0:893a1e710078 110 return beacons;
oehlemar 0:893a1e710078 111 }
oehlemar 0:893a1e710078 112
oehlemar 0:893a1e710078 113 /**
oehlemar 0:893a1e710078 114 * This method is called by the serial interrupt service routine.
oehlemar 0:893a1e710078 115 * It handles the reception of measurements from the LIDAR.
oehlemar 0:893a1e710078 116 */
oehlemar 0:893a1e710078 117 void LIDAR::receive() {
oehlemar 0:893a1e710078 118
oehlemar 0:893a1e710078 119 // read received characters while input buffer is full
oehlemar 0:893a1e710078 120
oehlemar 0:893a1e710078 121 if (serial.readable()) {
oehlemar 0:893a1e710078 122
oehlemar 0:893a1e710078 123 // read single character from serial interface
oehlemar 0:893a1e710078 124
oehlemar 0:893a1e710078 125 char c = serial.getc();
oehlemar 0:893a1e710078 126
oehlemar 0:893a1e710078 127 // add this character to the header or to the data buffer
oehlemar 0:893a1e710078 128
oehlemar 0:893a1e710078 129 if (headerCounter < HEADER_SIZE) {
oehlemar 0:893a1e710078 130 headerCounter++;
oehlemar 0:893a1e710078 131 } else {
oehlemar 0:893a1e710078 132 if (dataCounter < DATA_SIZE) {
oehlemar 0:893a1e710078 133 data[dataCounter] = c;
oehlemar 0:893a1e710078 134 dataCounter++;
oehlemar 0:893a1e710078 135 }
oehlemar 0:893a1e710078 136 if (dataCounter >= DATA_SIZE) {
oehlemar 0:893a1e710078 137
oehlemar 0:893a1e710078 138 // data buffer is full, process measurement
oehlemar 0:893a1e710078 139
oehlemar 0:893a1e710078 140 char quality = data[0] >> 2;
oehlemar 0:893a1e710078 141 short angle = 360-(((unsigned short)data[1] | ((unsigned short)data[2] << 8)) >> 1)/64;
oehlemar 0:893a1e710078 142 float distance = (float)((unsigned short)data[3] | ((unsigned short)data[4] << 8))/4000.0f;
oehlemar 0:893a1e710078 143
oehlemar 0:893a1e710078 144 if ((quality < QUALITY_THRESHOLD) || (distance < DISTANCE_THRESHOLD)) distance = DEFAULT_DISTANCE;
oehlemar 0:893a1e710078 145
oehlemar 0:893a1e710078 146 // store distance in [m] into array of full scan
oehlemar 0:893a1e710078 147
oehlemar 0:893a1e710078 148 while (angle < 0) angle += 360;
oehlemar 0:893a1e710078 149 while (angle >= 360) angle -= 360;
oehlemar 0:893a1e710078 150 distances[angle] = distance;
oehlemar 0:893a1e710078 151
oehlemar 0:893a1e710078 152 // reset data counter and simulation flag
oehlemar 0:893a1e710078 153
oehlemar 0:893a1e710078 154 dataCounter = 0;
oehlemar 0:893a1e710078 155 simulation = false;
oehlemar 0:893a1e710078 156 }
oehlemar 0:893a1e710078 157 }
oehlemar 0:893a1e710078 158 }
oehlemar 0:893a1e710078 159 }
oehlemar 0:893a1e710078 160