Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:bcaa6d8df26d, committed 2022-03-03
- Comitter:
- htzer
- Date:
- Thu Mar 03 06:55:48 2022 +0000
- Commit message:
- YdlidarX4_gitlab
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/Buffer/MyBuffer.cpp Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,76 @@
+
+/**
+ * @file Buffer.cpp
+ * @brief Software Buffer - Templated Ring Buffer for most data types
+ * @author sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MyBuffer.h"
+
+template <class T>
+MyBuffer<T>::MyBuffer(uint32_t size)
+{
+ _buf = new T [size];
+ _size = size;
+ clear();
+
+ return;
+}
+
+template <class T>
+MyBuffer<T>::~MyBuffer()
+{
+ delete [] _buf;
+
+ return;
+}
+
+template <class T>
+uint32_t MyBuffer<T>::getSize()
+{
+ return this->_size;
+}
+
+template <class T>
+void MyBuffer<T>::clear(void)
+{
+ _wloc = 0;
+ _rloc = 0;
+ memset(_buf, 0, _size);
+
+ return;
+}
+
+template <class T>
+uint32_t MyBuffer<T>::peek(char c)
+{
+ return 1;
+}
+
+// make the linker aware of some possible types
+template class MyBuffer<uint8_t>;
+template class MyBuffer<int8_t>;
+template class MyBuffer<uint16_t>;
+template class MyBuffer<int16_t>;
+template class MyBuffer<uint32_t>;
+template class MyBuffer<int32_t>;
+template class MyBuffer<uint64_t>;
+template class MyBuffer<int64_t>;
+template class MyBuffer<char>;
+template class MyBuffer<wchar_t>;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/Buffer/MyBuffer.h Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,163 @@
+
+/**
+ * @file Buffer.h
+ * @brief Software Buffer - Templated Ring Buffer for most data types
+ * @author sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MYBUFFER_H
+#define MYBUFFER_H
+
+#include <stdint.h>
+#include <string.h>
+
+/** A templated software ring buffer
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "MyBuffer.h"
+ *
+ * MyBuffer <char> buf;
+ *
+ * int main()
+ * {
+ * buf = 'a';
+ * buf.put('b');
+ * char *head = buf.head();
+ * puts(head);
+ *
+ * char whats_in_there[2] = {0};
+ * int pos = 0;
+ *
+ * while(buf.available())
+ * {
+ * whats_in_there[pos++] = buf;
+ * }
+ * printf("%c %c\n", whats_in_there[0], whats_in_there[1]);
+ * buf.clear();
+ * error("done\n\n\n");
+ * }
+ * @endcode
+ */
+
+template <typename T>
+class MyBuffer
+{
+private:
+ T *_buf;
+ volatile uint32_t _wloc;
+ volatile uint32_t _rloc;
+ uint32_t _size;
+
+public:
+ /** Create a Buffer and allocate memory for it
+ * @param size The size of the buffer
+ */
+ MyBuffer(uint32_t size = 0x100);
+
+ /** Get the size of the ring buffer
+ * @return the size of the ring buffer
+ */
+ uint32_t getSize();
+
+ /** Destry a Buffer and release it's allocated memory
+ */
+ ~MyBuffer();
+
+ /** Add a data element into the buffer
+ * @param data Something to add to the buffer
+ */
+ void put(T data);
+
+ /** Remove a data element from the buffer
+ * @return Pull the oldest element from the buffer
+ */
+ T get(void);
+
+ /** Get the address to the head of the buffer
+ * @return The address of element 0 in the buffer
+ */
+ T *head(void);
+
+ /** Reset the buffer to 0. Useful if using head() to parse packeted data
+ */
+ void clear(void);
+
+ /** Determine if anything is readable in the buffer
+ * @return 1 if something can be read, 0 otherwise
+ */
+ uint32_t available(void);
+
+ /** Overloaded operator for writing to the buffer
+ * @param data Something to put in the buffer
+ * @return
+ */
+ MyBuffer &operator= (T data)
+ {
+ put(data);
+ return *this;
+ }
+
+ /** Overloaded operator for reading from the buffer
+ * @return Pull the oldest element from the buffer
+ */
+ operator int(void)
+ {
+ return get();
+ }
+
+ uint32_t peek(char c);
+
+};
+
+template <class T>
+inline void MyBuffer<T>::put(T data)
+{
+ _buf[_wloc++] = data;
+ _wloc %= (_size-1);
+
+ return;
+}
+
+template <class T>
+inline T MyBuffer<T>::get(void)
+{
+ T data_pos = _buf[_rloc++];
+ _rloc %= (_size-1);
+
+ return data_pos;
+}
+
+template <class T>
+inline T *MyBuffer<T>::head(void)
+{
+ T *data_pos = &_buf[0];
+
+ return data_pos;
+}
+
+template <class T>
+inline uint32_t MyBuffer<T>::available(void)
+{
+ return (_wloc == _rloc) ? 0 : 1;
+}
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/BufferedSerial.cpp Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,158 @@
+/**
+ * @file BufferedSerial.cpp
+ * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BufferedSerial.h"
+#include <stdarg.h>
+
+BufferedSerial::BufferedSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name)
+ : RawSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size))
+{
+ RawSerial::attach(this, &BufferedSerial::rxIrq, Serial::RxIrq);
+ this->_buf_size = buf_size;
+ this->_tx_multiple = tx_multiple;
+ return;
+}
+
+BufferedSerial::~BufferedSerial(void)
+{
+ RawSerial::attach(NULL, RawSerial::RxIrq);
+ RawSerial::attach(NULL, RawSerial::TxIrq);
+
+ return;
+}
+
+int BufferedSerial::readable(void)
+{
+ return _rxbuf.available(); // note: look if things are in the buffer
+}
+
+int BufferedSerial::writeable(void)
+{
+ return 1; // buffer allows overwriting by design, always true
+}
+
+int BufferedSerial::getc(void)
+{
+ return _rxbuf;
+}
+
+int BufferedSerial::putc(int c)
+{
+ _txbuf = (char)c;
+ BufferedSerial::prime();
+
+ return c;
+}
+
+int BufferedSerial::puts(const char *s)
+{
+ if (s != NULL) {
+ const char* ptr = s;
+
+ while(*(ptr) != 0) {
+ _txbuf = *(ptr++);
+ }
+ _txbuf = '\n'; // done per puts definition
+ BufferedSerial::prime();
+
+ return (ptr - s) + 1;
+ }
+ return 0;
+}
+
+int BufferedSerial::printf(const char* format, ...)
+{
+ char buffer[this->_buf_size];
+ memset(buffer,0,this->_buf_size);
+ int r = 0;
+
+ va_list arg;
+ va_start(arg, format);
+ r = vsprintf(buffer, format, arg);
+ // this may not hit the heap but should alert the user anyways
+ if(r > this->_buf_size) {
+ error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__,this->_buf_size,r);
+ va_end(arg);
+ return 0;
+ }
+ va_end(arg);
+ r = BufferedSerial::write(buffer, r);
+
+ return r;
+}
+
+ssize_t BufferedSerial::write(const void *s, size_t length)
+{
+ if (s != NULL && length > 0) {
+ const char* ptr = (const char*)s;
+ const char* end = ptr + length;
+
+ while (ptr != end) {
+ _txbuf = *(ptr++);
+ }
+ BufferedSerial::prime();
+
+ return ptr - (const char*)s;
+ }
+ return 0;
+}
+
+
+void BufferedSerial::rxIrq(void)
+{
+ // read from the peripheral and make sure something is available
+ if(serial_readable(&_serial)) {
+ _rxbuf = serial_getc(&_serial); // if so load them into a buffer
+ }
+
+ return;
+}
+
+void BufferedSerial::txIrq(void)
+{
+ // see if there is room in the hardware fifo and if something is in the software fifo
+ while(serial_writable(&_serial)) {
+ if(_txbuf.available()) {
+ serial_putc(&_serial, (int)_txbuf.get());
+ } else {
+ // disable the TX interrupt when there is nothing left to send
+ RawSerial::attach(NULL, RawSerial::TxIrq);
+ break;
+ }
+ }
+
+ return;
+}
+
+void BufferedSerial::prime(void)
+{
+ // if already busy then the irq will pick this up
+ if(serial_writable(&_serial)) {
+ RawSerial::attach(NULL, RawSerial::TxIrq); // make sure not to cause contention in the irq
+ BufferedSerial::txIrq(); // only write to hardware in one place
+ RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq);
+ }
+
+ return;
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/BufferedSerial.h Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,140 @@
+
+/**
+ * @file BufferedSerial.h
+ * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BUFFEREDSERIAL_H
+#define BUFFEREDSERIAL_H
+
+#include "mbed.h"
+#include "MyBuffer.h"
+
+/** A serial port (UART) for communication with other serial devices
+ *
+ * Can be used for Full Duplex communication, or Simplex by specifying
+ * one pin as NC (Not Connected)
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "BufferedSerial.h"
+ *
+ * BufferedSerial pc(USBTX, USBRX);
+ *
+ * int main()
+ * {
+ * while(1)
+ * {
+ * Timer s;
+ *
+ * s.start();
+ * pc.printf("Hello World - buffered\n");
+ * int buffered_time = s.read_us();
+ * wait(0.1f); // give time for the buffer to empty
+ *
+ * s.reset();
+ * printf("Hello World - blocking\n");
+ * int polled_time = s.read_us();
+ * s.stop();
+ * wait(0.1f); // give time for the buffer to empty
+ *
+ * pc.printf("printf buffered took %d us\n", buffered_time);
+ * pc.printf("printf blocking took %d us\n", polled_time);
+ * wait(0.5f);
+ * }
+ * }
+ * @endcode
+ */
+
+/**
+ * @class BufferedSerial
+ * @brief Software buffers and interrupt driven tx and rx for Serial
+ */
+class BufferedSerial : public RawSerial
+{
+private:
+ MyBuffer <char> _rxbuf;
+ MyBuffer <char> _txbuf;
+ uint32_t _buf_size;
+ uint32_t _tx_multiple;
+
+ void rxIrq(void);
+ void txIrq(void);
+ void prime(void);
+
+public:
+ /** Create a BufferedSerial port, connected to the specified transmit and receive pins
+ * @param tx Transmit pin
+ * @param rx Receive pin
+ * @param buf_size printf() buffer size
+ * @param tx_multiple amount of max printf() present in the internal ring buffer at one time
+ * @param name optional name
+ * @note Either tx or rx may be specified as NC if unused
+ */
+ BufferedSerial(PinName tx, PinName rx, uint32_t buf_size = 256, uint32_t tx_multiple = 4,const char* name=NULL);
+
+ /** Destroy a BufferedSerial port
+ */
+ virtual ~BufferedSerial(void);
+
+ /** Check on how many bytes are in the rx buffer
+ * @return 1 if something exists, 0 otherwise
+ */
+ virtual int readable(void);
+
+ /** Check to see if the tx buffer has room
+ * @return 1 always has room and can overwrite previous content if too small / slow
+ */
+ virtual int writeable(void);
+
+ /** Get a single byte from the BufferedSerial Port.
+ * Should check readable() before calling this.
+ * @return A byte that came in on the Serial Port
+ */
+ virtual int getc(void);
+
+ /** Write a single byte to the BufferedSerial Port.
+ * @param c The byte to write to the Serial Port
+ * @return The byte that was written to the Serial Port Buffer
+ */
+ virtual int putc(int c);
+
+ /** Write a string to the BufferedSerial Port. Must be NULL terminated
+ * @param s The string to write to the Serial Port
+ * @return The number of bytes written to the Serial Port Buffer
+ */
+ virtual int puts(const char *s);
+
+ /** Write a formatted string to the BufferedSerial Port.
+ * @param format The string + format specifiers to write to the Serial Port
+ * @return The number of bytes written to the Serial Port Buffer
+ */
+ virtual int printf(const char* format, ...);
+
+ /** Write data to the Buffered Serial Port
+ * @param s A pointer to data to send
+ * @param length The amount of data being pointed to
+ * @return The number of bytes written to the Serial Port Buffer
+ */
+ virtual ssize_t write(const void *s, std::size_t length);
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/YDLidarX4/YDLidarX4.cpp Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,123 @@
+#include "YDLidarX4.h"
+#include "mbed.h"
+
+
+YDLidarX4::YDLidarX4(PinName tx, PinName rx, PinName m_en, PinName ctl) : _lidar(tx, rx, 1024), _m_en(m_en), _m_ctl(ctl) {
+ _lidar.baud(LIDAR_BAUD);
+ _m_en = 1;
+ //M_EN가 high level이면 M_SCTR의 input voltage는 0V이며, 모터는 최대속도로 회전
+ _m_ctl.period(0.0001);
+ _m_ctl.write(0.85);
+ // PWM 주기는 10KHz, Duty cycle은 85%로 설정
+ softReset();
+}
+
+void YDLidarX4::softReset() {
+ sendCommand(CMD_RESET);
+ wait(0.1);
+ flush();
+ // 버퍼가 있는 스트림은 flush로 데이터를 목적지에 바로 보낸다.
+}
+
+
+void YDLidarX4::stopplease(){
+ sendCommand(0x65);
+ }
+/*
+
+감지모드 >> 이 명령어만 들어가면 먹통됨
+현재 코드가 막히고 있는 부분.
+
+>>해결
+
+*/
+int YDLidarX4::startSampling() {
+ softReset();
+ // 감지하기 전에 리셋한번 하고 들어간다
+ responseHeader header;
+ sendCommand(CMD_START);
+ getResponseHeader(&header);
+ return header.type == RESPONSE_HEADER_TYPE_START ? 1 : 0;
+}
+
+
+// 정지명령, 명령이 들어가긴 하지만 라이다가 멈추진 않음**샘플링만 멈춘다.
+
+// >> 해결
+void YDLidarX4::stopSampling() {
+ sendCommand(CMD_STOP);
+}
+
+void YDLidarX4::getResponseHeader(responseHeader* header) {
+ uint8_t *headerBuffer = (uint8_t*)(header);
+ uint8_t currentByte;
+ uint8_t receivePosition = 0;
+ while (receivePosition < sizeof(responseHeader)) {
+ if (_lidar.readable()) {
+ currentByte = _lidar.getc();
+ switch (receivePosition) {
+ case 0:
+ if (currentByte != RESPONSE_HEADER_BYTE_1) {
+ continue;
+ }
+ break;
+ case 1:
+ if (currentByte != RESPONSE_HEADER_BYTE_2) {
+ receivePosition = 0;
+ continue;
+ }
+ break;
+ }
+ headerBuffer[receivePosition++] = currentByte;
+ }
+ }
+}
+
+void YDLidarX4::getCloudHeader(cloudHeader* header) {
+ flush();
+ uint8_t *headerBuffer = (uint8_t*)(header);
+ uint8_t currentByte;
+ uint8_t receivePosition = 0;
+ while (receivePosition < sizeof(cloudHeader)) {
+ if (_lidar.readable()) {
+ currentByte = _lidar.getc();
+ switch (receivePosition) {
+ case 0:
+ if (currentByte != CLOUD_HEADER_BYTE_1) {
+ receivePosition = 0;
+ continue;
+ }
+ break;
+ case 1:
+ if (currentByte != CLOUD_HEADER_BYTE_2) {
+ receivePosition = 0;
+ continue;
+ }
+ break;
+ }
+ headerBuffer[receivePosition++] = currentByte;
+ }
+ }
+}
+
+void YDLidarX4::getCloudSamples(uint16_t* tab, uint8_t size) {
+ uint8_t *tabBuffer = (uint8_t*)(tab);
+ uint8_t receivePosition = 0;
+ while (receivePosition < size * sizeof(uint16_t)) {
+ if (_lidar.readable()) {
+ tabBuffer[receivePosition++] = _lidar.getc();
+ }
+ }
+}
+
+
+void YDLidarX4::sendCommand(uint8_t com) {
+ _lidar.putc(START_BYTE);
+ _lidar.putc(com);
+}
+
+void YDLidarX4::flush() {
+ while(_lidar.readable()) {
+ _lidar.getc();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/YDLidarX4/YDLidarX4.h Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,85 @@
+#ifndef YDLIDARX4_H
+#define YDLIDARX4_H
+
+#include "BufferedSerial.h"
+#include "mbed.h"
+
+#define LIDAR_BAUD 128000
+
+#define RESPONSE_HEADER_BYTE_1 0xA5
+#define RESPONSE_HEADER_BYTE_2 0x5A
+#define RESPONSE_HEADER_TYPE_START 0x81
+// Scan Command
+
+#define CLOUD_HEADER_BYTE_1 0xAA
+#define CLOUD_HEADER_BYTE_2 0x55
+// 2B in length, fixed at 0x55AA, low in front, high in back
+
+#define START_BYTE 0xA5
+#define CMD_START 0x60
+#define CMD_STOP 0x65
+#define CMD_RESET 0x80
+#define CMD_HEALTH 0x91
+// System Command
+
+struct responseHeader {
+ //응답 관련 헤더
+ uint8_t startByte1;
+ uint8_t startByte2;
+ //start sign, 16비트인데 2개로 나눠놓은듯
+ uint32_t length:30;
+ //length 30비트
+ uint32_t mode:2;
+ //mode 2비트
+ uint8_t type;
+ //타입코드, 개발자메뉴얼에 8비트라 명시
+} __attribute__((packed));
+
+
+struct cloudHeader {
+ //패킷
+ uint16_t ph;
+ // 패킷헤더
+ uint8_t ct;
+ // 패키지 타입
+ uint8_t lsn;
+ // 수신 정보량
+ uint16_t fsa;
+ // first
+ uint16_t lsa;
+ // last
+ uint16_t cs;
+ // check sum
+} __attribute__((packed));
+
+
+class YDLidarX4 {
+
+public:
+
+ YDLidarX4(PinName tx, PinName rx, PinName m_en, PinName ctl);
+
+ void stopplease();
+ //좀 멈추게 만들어본거
+ void softReset();
+ int startSampling();
+ void stopSampling();
+ // 단순명령어들, 따로 입력값이 없다.
+
+ void setRotationSpeed(float speed);
+ void getResponseHeader(responseHeader* header);
+ void getCloudHeader(cloudHeader* header);
+ void getCloudSamples(uint16_t* tab, uint8_t size);
+
+private :
+
+ void sendCommand(uint8_t com);
+ void flush();
+
+ BufferedSerial _lidar;
+ DigitalOut _m_en;
+ PwmOut _m_ctl;
+
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,217 @@
+#include "mbed.h"
+#include "BufferedSerial.h"
+#include "YDLidarX4.h"
+
+#define PC_TX USBTX
+#define PC_RX USBRX
+#define PC_BAUD 115200
+
+#define LIDAR_TX PA_9
+#define LIDAR_RX PA_10
+#define LIDAR_M_EN PB_5
+#define LIDAR_M_PWN PB_4
+#define LIDAR_DEV_EN PA_11
+
+#define ALPHA 0.70
+#define BETA 0.85
+//각도/거리보정 계수
+
+BufferedSerial pc(PC_TX, PC_RX, 512);
+YDLidarX4 lidar(LIDAR_TX, LIDAR_RX, LIDAR_M_EN, LIDAR_M_PWN);
+
+uint16_t samples[128];
+uint16_t trend[360];
+uint16_t datas[360];
+//samples와 trend는 각도보정에 쓰이는 거리값, datas는 sample과 trend에 의해 보정된 거리값
+
+bool isSampling = false;
+/*샘플링되었는가?*/
+
+void processInput() {
+ // Si il y a un message sur le port série
+ // 직렬포트에 메세지가 있는 경우
+ // pc로부터 명령어 받았을때 상황
+ if (pc.readable()) {
+ switch(pc.getc()) {
+ //메세지의 종류에 따른 분류
+ //여기까지 작동 확인
+ case 'G': { // Derniers points relevés
+ //최종점수? 아무튼 pc로부터 받은 값이 'G'일때
+ uint32_t sum = 0;
+ uint8_t sum_counter = 0;
+ uint8_t counter = 0;
+ uint8_t degree = 0;
+ //값들 초기화
+
+ // On envoit sur le port série la moyenne tous les 10 degrés
+ // 10도마다 직렬포트로 평균치를 보낸다.
+ for (uint16_t index = 0; index < 360; index++) {
+ // 이 if문은 datas 배열의 index에 해당하는 값을 sum 변수에 더한다.
+ if (datas[359 - index] != 0) {
+ //datas라는 배열의 우측 데이터부터 0이 아니라면
+ sum += datas[359 - index];
+ //sum이라는 변수는 datas 배열의 index에 해당하는 데이터를 더한다.
+ sum_counter += 1;
+ //sum이 몇번 더해졌는지 판별하기 위한 index?
+ }
+ if (++counter == 1) {
+ //***************************************************************************평균치 개수 여기서 조절
+ pc.printf("%d:", sum / sum_counter);
+ counter = 0;
+ sum = 0;
+ sum_counter = 0;
+ // counter가 10이면 sum을 10으로 나눈 평균치를 출력하고 모든 변수값 초기화.
+ // 0~9 평균 출력 및 초기화, 10~11 평균 출력 및 초기화,....
+ // counter == x 값 변경
+ }
+ }
+ pc.printf("\n");
+ break;
+ };
+ case 'I': { // Information d'identification
+ // 'I'일 경우 식별정보 pc로 출력. 아마 기기정보인듯
+ // 근데 아무 명령어가 없다?
+ pc.printf("CarteLidar\n");
+ break;
+ };
+ case 'R': { // soft reset du LIDAR
+ // 'R'일 경우 Lidar의 소프트 리셋
+ lidar.softReset();
+ pc.printf("softReset\n");
+ break;
+ };
+ case 'E': { // Démarrer le ranging
+ /*
+
+ ***************************************************************************'E' 입력시 감지 시작
+ isSampling을 True로 만들어주는게 끝이긴 하다
+
+ */
+ pc.printf("entering E ok\n");
+ if (lidar.startSampling()) {
+ isSampling = true;
+ //샘플링 시작 선언
+ pc.printf("1\n");
+ } else {
+ pc.printf("0\n");
+ }
+ break;
+ };
+ case 'D': { // Arrêter le ranging
+ //'D'입력시 감지 중지
+ lidar.stopSampling();
+ isSampling = false;
+ pc.printf("sampling stop\n");
+ break;
+
+ case 'O':{
+ lidar.stopplease();
+ pc.printf("stop ok\n");
+ break;
+ }
+ };
+ case 'S': { // Savoir si le lidar est entrain de fonctionner ou non
+ //'S'입력시 LIdar가 작동중인지 여부 확인.
+ //isSampling 변수를 통해 확인한다.
+ pc.printf(isSampling ? "State Sampling\n" : "State Stop\n");
+ }
+ }
+ }
+}
+
+void format_samples(uint8_t size) {
+ // Formate les distances obtenues suivant les indications du datasheet
+ //데이터시트 지시사항에 따라 얻은 거리를 측정한다
+ for (uint8_t index = 0; index < size; index++) {
+ samples[index] = samples[index] / 4.0;
+ }
+}
+
+double get_angle_correct(double distance) {
+ // Calcule la correction de l'angle suivant les indications du datasheet
+ //데이터시트 지시사항에 따라 얻은 각도보정
+ return distance == 0 ? 0 : atan(21.8 * (155.3 - distance) / (155.3 * distance)) * 57.2957795147;
+}
+
+uint16_t get_angle_formated(int16_t angle) {
+ // Permet d'obtenir un angle module 360
+ // 각도가 0도 미만 또는 360도 이상일때 보정
+ return angle < 0 ? angle + 360 : angle > 360 ? angle - 360 : angle;
+}
+
+int main() {
+ // Initialisation des communications UART
+ //UART 통신 초기화
+ pc.baud(PC_BAUD);
+
+ int angle;
+ int s;
+ int index;
+
+
+
+ // Boucle infinie
+ // 반복문
+
+ while (true) {
+ // Si le ranging est actif, on lit le prochain paquet
+ // 감지가 활성화된 경우 다음 패킷을 읽는다
+ if (isSampling) {
+ // 이 반복문은 isSampling이 활성화된 경우, 즉 감지 명령어 'E'가 들어온 경우에만 실행된다
+ cloudHeader header;
+ /*
+
+ pc.printf("cloudHeader\n");
+
+ */
+ // Récupération du paquet de points actuel
+ // 현재 포인트 패킷 복구
+ lidar.getCloudHeader(&header);
+ /*
+
+ pc.printf("getCloudHeader\n");
+
+ */
+ lidar.getCloudSamples(samples, header.lsn);
+ /*
+
+ pc.printf("getCloudSample\n");
+
+ */
+ // Si il y a au moins un point échantilloné
+ // 하나 이상의 샘플링 지점이 있는 경우
+ if (header.lsn > 1) {
+ // Formatage préliminaire des points
+ // 점의 예비 포맷
+ format_samples(header.lsn);
+ // Calcul des angles initiaux et finaux du paquet
+ //패킷의 초기 및 최종 각도 계산
+ double fsa = ((double)(header.fsa >> 1) / 64.0) + get_angle_correct(samples[0]);
+ double lsa = ((double)(header.lsa >> 1) / 64.0) + get_angle_correct(samples[header.lsn - 1]);
+ double dif = fsa < lsa ? (lsa - fsa) / ((double)header.lsn - 1.0) : (360.0 + lsa - fsa) / ((double)header.lsn - 1.0);
+ // Iteration sur chaque point du paquet
+ for (index = 0; index < header.lsn; index++) {
+ // Si la distance mesurée est positive
+ // 측정된 거리가 양수인 경우
+ if (samples[index] != 0) {
+ // Détermination de l'angle pour le point courant
+ //현재 지점에 대한 각도 결정
+ angle = get_angle_formated(((dif * (double)(index)) + fsa + get_angle_correct(samples[index])));
+ // Lissage à double exponentielle de la mesure
+ // 이중 지수 측정 평활화
+ s = ALPHA * (double)samples[index] + (1.0 - ALPHA) * ((double)datas[angle] + (double)trend[angle]);
+ trend[angle] = BETA * ((double)s - (double)datas[angle]) + (1.0 - BETA) * (double)trend[angle];
+ // Stockage du résultat
+ // 결과 저장
+ datas[angle] = s;
+ }
+ }
+ }
+ }
+ // On exécute les commandes reçues
+ // 수신된 명령을 실행
+ // comportMaster에서 내가 보낸 명령어는 while문 맨 끝에서 받게된다.
+ // while문의 코드는 감지명령이 있을때만 실행되는데 감지명령만 들어가면 먹통되는걸 보면 while문을 빠져나오지 못하는걸로 예상
+ processInput();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Mar 03 06:55:48 2022 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file