This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revision | |||
| pt:examples:sensor:lidar [2015/12/17 18:17] – artica | pt:examples:sensor:lidar [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Lidar ====== | ||
| + | |||
| + | // | ||
| + | |||
| + | ===== Teoria ===== | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | O LIDAR (Light Detection and Ranging) é um sistema de detecção remoto óptico que pode medir a distância a um alvo, iluminando-o com luz. A tecnologia LIDAR é usada em robótica para percepção do ambiente, bem como classificação de objetos. A capacidade da tecnologia LIDAR para fornecer mapas de elevação 2D do terreno, distância de alta precisão ao solo, e a velocidade de aproximação pode permitir a aterragem segura de veículos tripulados ou robóticos com um elevado grau de precisão. | ||
| + | |||
| + | O Lidar consiste num transmissor que ilumina um alvo com um feixe de laser, e um receptor capaz de detectar a componente de luz que é essencialmente coaxial com o feixe transmitido. Os sensores do receptor calculam a distância com base no tempo necessário à luz para atinjir o alvo e regressar. Um mecanismo mecânico com um espelho varre o feixe de luz de forma a cobrir o local requerido num plano, ou mesmo a três dimensões, usando um espelho rotativo. | ||
| + | |||
| + | Uma maneira de medir o tempo de voo do feixe de luz é a utilização de um laser pulsado e, de seguida, medir directamente o tempo decorrido. Electrónica capaz de distinguir picossegundos é necessária em tais dispositivos e, por conseguinte, | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | Laser infravermelho colimado é utilizado para a medição de deslocamento de fase. Para superfícies, | ||
| + | |||
| + | |||
| + | [{{: | ||
| + | |||
| + | |||
| + | O sensor mede o deslocamento de fase entre os sinais transmitidos e reflectidos. A figura mostra como esta técnica pode ser usada para medir a distância. O comprimento de onda do sinal de modulação obedece à equação: | ||
| + | |||
| + | c = f ∙ τ | ||
| + | |||
| + | onde c é a velocidade da luz, f a frequência de modulação e τ o comprimento de onda de modulação conhecido. | ||
| + | |||
| + | A distância total D' abrangida pela luz emitida é: | ||
| + | |||
| + | D' = B + 2A = B + (θ * τ) / 2π | ||
| + | |||
| + | em que A é a distância medida. B é a distância à a unidade de medida de fase. A distância requerida D, entre o divisor de feixe e o alvo, é então dada por | ||
| + | |||
| + | D = τ * θ / 4π | ||
| + | |||
| + | onde θ é a diferença de fase medida electronicamente entre os feixes de luz reflectidos e transmitidos. | ||
| + | |||
| + | Pode ser mostrado que o intervalo é inversamente proporcional ao quadrado da amplitude do sinal recebido, afectando directamente a precisão do sensor. | ||
| + | |||
| + | |||
| + | ===== Prática ===== | ||
| + | [{{ : | ||
| + | |||
| + | Em robótica autónoma, bem como em robótica industrial, rangers a laser SICK são amplamente utilizados. O SICK LMS 200 pode ser facilmente acedido através de RS-232 ou RS-422, fornecendo medições de distância numa área de 180 graus até 80 metros de distância. Este LIDAR baseia-se no princípio de medição de tempo-de-voo (time-of-flight). A exemplo de um resultado de uma medição dum varrimento é mostrado na imagem à direita. | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | Para fazer a SICK operacional, | ||
| + | |||
| + | O SICK recebe comandos na forma de fluxos de bytes através da porta serial. Ao transmitir dados, envia de volta fluxos de bytes correspondentes às medições de distância com um determinado ângulo. | ||
| + | |||
| + | Para colectar dados do SICK, deve primeiro enviar-se uma cadeia de início para sinalizar ao sensor o inicio do envio de dados. Esta cadeia é: | ||
| + | |||
| + | Hexadecimal Form: | ||
| + | |||
| + | Decimal Form: | ||
| + | |||
| + | Se a seqüência de início é enviada com sucesso, o Lidar começará o streaming de dados através de RS232. Os dados de entrada de um varrimento são enviados sequencialmente à medida que o sensor varre 180°. Por exemplo, se o sensor está configurado para varrer 180° com resolução de 0,5° o primeiro ponto de dados que é enviado irá corresponder a 0°, o seguinte corresponderá a 0,5°, o que se segue para 1°, e assim por diante. Isto significa que existirão um total de 361 pontos de dados. Cada medição da distância é enviada sob a forma de dois bytes. O byte menos significativo é enviado em primeiro lugar seguido pelo byte mais significativo. Operando no modo métrico a unidade para as medições é em milímetros. | ||
| + | |||
| + | Finalmente, para parar o envio de dados do sensor uma sequência de paragem deve ser enviada. Esta sequência é: | ||
| + | |||
| + | Hexadecimal Form: | ||
| + | |||
| + | Decimal Form: | ||
| + | |||
| + | O exemplo seguinte mostra como iniciar o Lidar e obter a contagem do pacote. | ||
| + | |||
| + | <code c> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // Defining USART interface. | ||
| + | usart port = USART(0); | ||
| + | |||
| + | // Defining button pins. | ||
| + | pin button1 = PIN(C, 0); | ||
| + | pin button2 = PIN(C, 1); | ||
| + | |||
| + | // Initialize | ||
| + | static inline void init() | ||
| + | { | ||
| + | // Setting buttons pins as inputs. | ||
| + | pin_setup_input_with_pullup(button1); | ||
| + | pin_setup_input_with_pullup(button2); | ||
| + | |||
| + | // Set-up of the LCD. | ||
| + | lcd_gfx_init(); | ||
| + | // Cleaning the screen. | ||
| + | lcd_gfx_clear(); | ||
| + | // Switching on the background light. | ||
| + | lcd_gfx_backlight(true); | ||
| + | // Displaying the name of the program. | ||
| + | lcd_gfx_goto_char_xy(3, | ||
| + | lcd_gfx_write_string(" | ||
| + | |||
| + | // The set-up of the USART interface. | ||
| + | usart_init_async | ||
| + | ( | ||
| + | port, | ||
| + | USART_DATABITS_8, | ||
| + | USART_STOPBITS_ONE, | ||
| + | USART_PARITY_NONE, | ||
| + | USART_BAUDRATE_ASYNC(9600) | ||
| + | ); | ||
| + | } | ||
| + | |||
| + | // Main program | ||
| + | int main(void) | ||
| + | { | ||
| + | unsigned char new_value1, new_value2, old_value1 = 0, old_value2 = 0; | ||
| + | |||
| + | char c; | ||
| + | int i = 0; | ||
| + | int count = 0; | ||
| + | char text[16]; | ||
| + | |||
| + | // Initialize | ||
| + | init(); | ||
| + | |||
| + | // Endless cycle | ||
| + | while (1) | ||
| + | { | ||
| + | // Reads buttons states | ||
| + | new_value1 = pin_get_debounced_value(button1); | ||
| + | new_value2 = pin_get_debounced_value(button2); | ||
| + | |||
| + | // Button S1 is pressed. | ||
| + | if((!new_value1) && (old_value1)) | ||
| + | { | ||
| + | //Send "02 00 02 00 20 24 34 08" to start scanning. | ||
| + | |||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | } | ||
| + | |||
| + | // Button S2 is pressed. | ||
| + | if((!new_value2) && (old_value2)) | ||
| + | { | ||
| + | //Send "0x 02 00 02 00 20 25 35 08" to stop scanning. | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | usart_send_char(port, | ||
| + | } | ||
| + | |||
| + | // Remembers the last keys values. | ||
| + | old_value1 = new_value1; | ||
| + | old_value2 = new_value2; | ||
| + | |||
| + | // Try to read serial port | ||
| + | if (usart_try_read_char(port, | ||
| + | { | ||
| + | // Find a header "0x 02 81 D6 02 B0 69 41" | ||
| + | // Very basic package start search. | ||
| + | if(c == 0x02) i++; | ||
| + | if(c == 0x81) i++; | ||
| + | if(c == 0xD6) i++; | ||
| + | if(c == 0x02) i++; | ||
| + | if(c == 0xB0) i++; | ||
| + | if(c == 0x69) i++; | ||
| + | if(c == 0x41) i++; | ||
| + | |||
| + | //If there is an header | ||
| + | if(i >= 7) | ||
| + | { | ||
| + | // | ||
| + | count++; | ||
| + | |||
| + | // | ||
| + | lcd_gfx_goto_char_xy(0, | ||
| + | |||
| + | sprintf(text, | ||
| + | |||
| + | lcd_gfx_write_string(text); | ||
| + | |||
| + | i=0; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||