Compare commits
12 Commits
2b3e4129e8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 906e5c0610 | |||
| 9975e3f24c | |||
| 4dde6cf046 | |||
| 637dd9296f | |||
| 8faf1fb3af | |||
| fed22e5fd7 | |||
| eaad822677 | |||
| 63df753fa8 | |||
| 484dcf5843 | |||
| bbd0bd2004 | |||
| 385aa66ffc | |||
| 8a3336c994 |
@@ -6,9 +6,11 @@
|
|||||||
#include "stm32g431xx.h"
|
#include "stm32g431xx.h"
|
||||||
|
|
||||||
#define USART3_START_BYTE 0x59
|
#define USART3_START_BYTE 0x59
|
||||||
|
#define USART3_BUF_SIZE 64
|
||||||
#define USART3_FRAME_SIZE 9
|
#define USART3_FRAME_SIZE 9
|
||||||
#define LIDAR_MIN_DIST 0.01f
|
#define LIDAR_MIN_DIST 0.01f
|
||||||
#define LIDAR_MAX_DIST 40.0f
|
#define LIDAR_MAX_DIST 40.0f
|
||||||
|
#define TF02_I2C_ADDR 0x10
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -25,12 +27,24 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t distance; // meters
|
uint16_t distance; // cm
|
||||||
uint16_t strength;
|
uint16_t strength;
|
||||||
uint16_t temperature;
|
uint16_t temperature;
|
||||||
} lidar_data;
|
} lidar_data;
|
||||||
|
|
||||||
void lidar_init();
|
void lidar_init();
|
||||||
|
void lidar_tim7_init();
|
||||||
|
void TIM7_DAC_IRQHandler();
|
||||||
|
void USART3_IRQHandler();
|
||||||
void lidar_update(lidar_data* lidar);
|
void lidar_update(lidar_data* lidar);
|
||||||
|
|
||||||
|
uint8_t usart_available();
|
||||||
|
uint8_t usart_read();
|
||||||
|
|
||||||
|
void lidar_i2c2_init();
|
||||||
|
static void i2c2_wait_txis();
|
||||||
|
static void i2c2_wait_stop();
|
||||||
|
static int i2c2_write(uint8_t addr, uint8_t *data, uint8_t size);
|
||||||
|
void tf02_force_uart();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
#include "lidar.h"
|
#include "lidar.h"
|
||||||
|
|
||||||
volatile uint8_t usart3_index = 0;
|
volatile uint8_t usart3_rx_buf[USART3_BUF_SIZE];
|
||||||
volatile uint8_t usart3_checksum = 0;
|
static uint8_t usart3_rx_head = 0;
|
||||||
volatile uint8_t usart3_frame_ready = 0;
|
static uint8_t usart3_rx_tail = 0;
|
||||||
static lidar_data_buf buffer;
|
|
||||||
static uint8_t* buff_data = (uint8_t*)&buffer;
|
|
||||||
|
|
||||||
void lidar_init()
|
void lidar_init()
|
||||||
{
|
{
|
||||||
@@ -37,7 +35,7 @@ void lidar_init()
|
|||||||
USART3->BRR = 16000000UL / 115200UL;
|
USART3->BRR = 16000000UL / 115200UL;
|
||||||
|
|
||||||
// parity control disable
|
// parity control disable
|
||||||
USART3->CR1 &= ~(USART_CR1_PCE);
|
USART3->CR1 &= ~USART_CR1_PCE;
|
||||||
|
|
||||||
// word length 8 bit
|
// word length 8 bit
|
||||||
USART3->CR1 &= ~USART_CR1_M1 & ~USART_CR1_M0;
|
USART3->CR1 &= ~USART_CR1_M1 & ~USART_CR1_M0;
|
||||||
@@ -50,7 +48,7 @@ void lidar_init()
|
|||||||
USART3->CR1 |= USART_CR1_RE | USART_CR1_RXNEIE;
|
USART3->CR1 |= USART_CR1_RE | USART_CR1_RXNEIE;
|
||||||
|
|
||||||
// overrun disable
|
// overrun disable
|
||||||
USART3->CR3 |= USART_CR3_OVRDIS;
|
// USART3->CR3 |= USART_CR3_OVRDIS;
|
||||||
|
|
||||||
// USART3 enable
|
// USART3 enable
|
||||||
USART3->CR1 |= USART_CR1_UE;
|
USART3->CR1 |= USART_CR1_UE;
|
||||||
@@ -59,41 +57,158 @@ void lidar_init()
|
|||||||
NVIC_EnableIRQ(USART3_IRQn);
|
NVIC_EnableIRQ(USART3_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lidar_tim7_init()
|
||||||
|
{
|
||||||
|
RCC->APB1ENR1 |= RCC_APB1ENR1_TIM7EN;
|
||||||
|
|
||||||
|
TIM7->PSC = 16000 - 1; // 16 MHz / 16000 = 1000 Hz (1 ms)
|
||||||
|
TIM7->ARR = 10 - 1; // 10 ms
|
||||||
|
|
||||||
|
TIM7->DIER |= TIM_DIER_UIE; // interrupt enable
|
||||||
|
TIM7->CR1 |= TIM_CR1_CEN; // counter enable
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(TIM7_DAC_IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM7_DAC_IRQHandler()
|
||||||
|
{
|
||||||
|
if (TIM7->SR & TIM_SR_UIF)
|
||||||
|
{
|
||||||
|
TIM7->SR &= ~TIM_SR_UIF;
|
||||||
|
//lidar_update_flag = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void USART3_IRQHandler()
|
void USART3_IRQHandler()
|
||||||
{
|
{
|
||||||
if (USART3->ISR & USART_ISR_RXNE)
|
if (USART3->ISR & USART_ISR_RXNE)
|
||||||
{
|
{
|
||||||
uint8_t b = USART3->RDR;
|
usart3_rx_buf[usart3_rx_head] = USART3->RDR;
|
||||||
|
usart3_rx_head = (usart3_rx_head + 1) % USART3_BUF_SIZE;
|
||||||
if (usart3_index < 2)
|
|
||||||
{
|
|
||||||
if (b == USART3_START_BYTE)
|
|
||||||
buff_data[usart3_index++] = b;
|
|
||||||
}
|
|
||||||
else if (usart3_index < USART3_FRAME_SIZE)
|
|
||||||
buff_data[usart3_index++] = b;
|
|
||||||
|
|
||||||
if (usart3_index == USART3_FRAME_SIZE)
|
|
||||||
{
|
|
||||||
usart3_index = 0;
|
|
||||||
usart3_frame_ready = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t usart_available()
|
||||||
|
{
|
||||||
|
return usart3_rx_head != usart3_rx_tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t usart_read()
|
||||||
|
{
|
||||||
|
uint8_t data = usart3_rx_buf[usart3_rx_tail];
|
||||||
|
usart3_rx_tail = (usart3_rx_tail + 1) % USART3_BUF_SIZE;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
void lidar_update(lidar_data* lidar)
|
void lidar_update(lidar_data* lidar)
|
||||||
{
|
{
|
||||||
if (!usart3_frame_ready)
|
static uint8_t frame[USART3_FRAME_SIZE];
|
||||||
return;
|
static uint8_t index = 0;
|
||||||
|
|
||||||
usart3_frame_ready = 0;
|
while(usart_available())
|
||||||
|
{
|
||||||
|
uint8_t c = usart_read();
|
||||||
|
|
||||||
|
frame[index++] = c;
|
||||||
|
|
||||||
|
if (index == USART3_FRAME_SIZE)
|
||||||
|
{
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
for (uint8_t i = 0; i < USART3_FRAME_SIZE - 1; ++i) checksum += frame[i];
|
||||||
|
|
||||||
|
if (checksum == frame[USART3_FRAME_SIZE - 1])
|
||||||
|
{
|
||||||
|
lidar->distance = frame[2] | (frame[3] << 8);
|
||||||
|
lidar->strength = frame[4] | (frame[5] << 8);
|
||||||
|
lidar->temperature = frame[6] | (frame[7] << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lidar_i2c2_init()
|
||||||
|
{
|
||||||
|
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < USART3_FRAME_SIZE; ++i) usart3_checksum += buff_data[i];
|
GPIOA->MODER &= ~(3 << (8 * 2)) & ~(3 << (9 * 2));
|
||||||
|
GPIOA->MODER |= 2 << (8 * 2) | 2 << (9 * 2); // alt func mode
|
||||||
|
|
||||||
if (buffer.checksum != usart3_checksum)
|
GPIOA->AFR[1] &= ~(0xF << 0) & ~(0xF << 4);
|
||||||
return;
|
GPIOA->AFR[1] |= 4 << 0 | 4 << 4; // AF4
|
||||||
|
|
||||||
lidar->distance = buffer.distance_l | (buffer.distance_h << 8);
|
GPIOA->OTYPER |= 1 << 8 | 1 << 9; // open-drain
|
||||||
lidar->strength = buffer.strength_l | (buffer.strength_h << 8);
|
|
||||||
lidar->temperature = buffer.temp_l | (buffer.temp_h << 8);
|
GPIOA->PUPDR &= ~(3 << (8 * 2)) & ~(3 << (9 * 2));
|
||||||
}
|
GPIOA->PUPDR |= 1 << (8 * 2) | 1 << (9 * 2); // pull-up
|
||||||
|
|
||||||
|
RCC->APB1ENR1 |= RCC_APB1ENR1_I2C2EN; // enable I2C2
|
||||||
|
I2C2->TIMINGR = 0x00303D5B; // 400 kHz @ 16 MHz
|
||||||
|
I2C2->CR1 |= I2C_CR1_PE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c2_wait_txis()
|
||||||
|
{
|
||||||
|
while (!(I2C2->ISR & I2C_ISR_TXIS));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c2_wait_stop()
|
||||||
|
{
|
||||||
|
while (!(I2C2->ISR & I2C_ISR_STOPF));
|
||||||
|
I2C2->ICR |= I2C_ICR_STOPCF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int i2c2_write(uint8_t addr, uint8_t *data, uint8_t size)
|
||||||
|
{
|
||||||
|
while (I2C2->ISR & I2C_ISR_BUSY);
|
||||||
|
|
||||||
|
I2C2->CR2 = 0;
|
||||||
|
I2C2->CR2 |= (addr << 1); // 7-bit addr
|
||||||
|
I2C2->CR2 |= (size << 16); // bite count
|
||||||
|
I2C2->CR2 |= I2C_CR2_AUTOEND; // auto stop
|
||||||
|
I2C2->CR2 |= I2C_CR2_START; // start
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
i2c2_wait_txis();
|
||||||
|
I2C2->TXDR = data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c2_wait_stop();
|
||||||
|
|
||||||
|
// check NACK
|
||||||
|
if (I2C2->ISR & I2C_ISR_NACKF)
|
||||||
|
{
|
||||||
|
I2C2->ICR |= I2C_ICR_NACKCF;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tf02_force_uart()
|
||||||
|
{
|
||||||
|
uint8_t cmd_uart[] = {0x5A, 0x05, 0x0A, 0x00, 0x69};
|
||||||
|
uint8_t cmd_save[] = {0x5A, 0x04, 0x11, 0x6F};
|
||||||
|
|
||||||
|
// force UART command
|
||||||
|
if (!i2c2_write(TF02_I2C_ADDR, cmd_uart, sizeof(cmd_uart)))
|
||||||
|
{
|
||||||
|
// no ACK — lidar is not on i2c
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (volatile int i = 0; i < 100000; i++);
|
||||||
|
|
||||||
|
// save command
|
||||||
|
i2c2_write(TF02_I2C_ADDR, cmd_save, sizeof(cmd_save));
|
||||||
|
|
||||||
|
for (volatile int i = 0; i < 200000; i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
64
Source/INS/geometry/quaternion.c
Normal file
64
Source/INS/geometry/quaternion.c
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#include "quaternion.h"
|
||||||
|
|
||||||
|
Quaternion QuatConjugate(const Quaternion* q)
|
||||||
|
{
|
||||||
|
Quaternion res = {.x = -q->x, .y = -q->y, .z = -q->z, .w = q->w};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion QuatInvert(const Quaternion* q)
|
||||||
|
{
|
||||||
|
Quaternion res;
|
||||||
|
float nsq = q->x * q->x + q->y * q->y + q->z * q->z + q->w * q->w;
|
||||||
|
|
||||||
|
if (nsq > 1e-6f)
|
||||||
|
{
|
||||||
|
nsq = 1.0f / nsq;
|
||||||
|
|
||||||
|
res.x = q->x * nsq;
|
||||||
|
res.y = q->y * nsq;
|
||||||
|
res.z = q->z * nsq;
|
||||||
|
res.w = q->w * nsq;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *q;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion QuatNegate(const Quaternion* q)
|
||||||
|
{
|
||||||
|
Quaternion res = {.x = -q->x, .y = -q->y, .z = -q->z, .w = -q->w};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion QuatSum(const Quaternion* q1, const Quaternion* q2)
|
||||||
|
{
|
||||||
|
Quaternion res = {.x = q1->x + q2->x, .y = q1->y + q2->y, .z = q1->z + q2->z, .w = q1->w + q2->w};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion QuatDiff(const Quaternion* q1, const Quaternion* q2)
|
||||||
|
{
|
||||||
|
Quaternion res = {.x = q1->x - q2->x, .y = q1->y - q2->y, .z = q1->z - q2->z, .w = q1->w - q2->w};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion QuatConstProd(const Quaternion* q, const float value)
|
||||||
|
{
|
||||||
|
Quaternion res = {.x = q->x * value, .y = q->y * value, .z = q->z * value, .w = q->w * value};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion QuatProd(const Quaternion* q1, const Quaternion* q2)
|
||||||
|
{
|
||||||
|
Quaternion res = {
|
||||||
|
.x = q1->w * q2->x + q1->x * q2->w + q1->y * q2->z - q1->z * q2->y,
|
||||||
|
.y = q1->w * q2->y + q1->x * q2->z + q1->y * q2->w - q1->z * q2->x,
|
||||||
|
.z = q1->w * q2->z + q1->x * q2->y + q1->y * q2->x - q1->z * q2->w,
|
||||||
|
.w = q1->w * q2->w + q1->x * q2->x + q1->y * q2->y - q1->z * q2->z
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
30
Source/INS/geometry/quaternion.h
Normal file
30
Source/INS/geometry/quaternion.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef QUATERNION_H
|
||||||
|
#define QUATERNION_H
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float x, y, z, w;
|
||||||
|
} Quaternion;
|
||||||
|
|
||||||
|
Quaternion QuatNormalize(const Quaternion* q, const float gain);
|
||||||
|
Quaternion QuatConjugate(const Quaternion* q);
|
||||||
|
Quaternion QuatInvert(const Quaternion* q);
|
||||||
|
Quaternion QuatNegate(const Quaternion* q);
|
||||||
|
|
||||||
|
Quaternion QuatSum(const Quaternion* q1, const Quaternion* q2);
|
||||||
|
Quaternion QuatDiff(const Quaternion* q1, const Quaternion* q2);
|
||||||
|
Quaternion QuatConstProd(const Quaternion* q, const float value);
|
||||||
|
Quaternion QuatProd(const Quaternion* q1, const Quaternion* q2);
|
||||||
|
|
||||||
|
Vector3 QuatRotateAroundZ(const Vector3* vec, bool CCW);
|
||||||
|
Quaternion QuatCreateRollPitchYaw(const Vector3* RollPitchYawRad);
|
||||||
|
Quaternion QuatGetError(const Quaternion* current, const Quaternion* target, bool fastWay);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
138
Source/INS/geometry/vector.c
Normal file
138
Source/INS/geometry/vector.c
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
#include "vector.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
Vector2 normalizeV2(const Vector2* v, float gain)
|
||||||
|
{
|
||||||
|
float len = lengthV2(v);
|
||||||
|
Vector2 res = {.x = v->x / len, .y = v->y / len};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 normalizeV3(const Vector3* v, float gain)
|
||||||
|
{
|
||||||
|
float len = lengthV3(v);
|
||||||
|
Vector3 res = {.x = v->x / len, .y = v->y / len, .z = v->z};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 absV2(const Vector2* v)
|
||||||
|
{
|
||||||
|
Vector2 res = {.x = fabsf(v->x), .y = fabsf(v->y)};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 absV3(const Vector3* v)
|
||||||
|
{
|
||||||
|
Vector3 res = {.x = fabsf(v->x), .y = fabsf(v->y), .z = fabsf(v->z)};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
float lengthV2(const Vector2* v)
|
||||||
|
{
|
||||||
|
return sqrtf(v->x * v->x + v->y * v->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
float lengthV3(const Vector3* v)
|
||||||
|
{
|
||||||
|
return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
float lengthSquaredV2(const Vector2* v)
|
||||||
|
{
|
||||||
|
return v->x * v->x + v->y * v->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float lengthSquaredV3(const Vector3* v)
|
||||||
|
{
|
||||||
|
return v->x * v->x + v->y * v->y + v->z * v->z;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 limitV2(const Vector2* v, float min, float max)
|
||||||
|
{
|
||||||
|
Vector2 lim;
|
||||||
|
|
||||||
|
if (v->x < min) lim.x = min; else if (v->x > max) lim.x = max; else lim.x = v->x;
|
||||||
|
if (v->y < min) lim.y = min; else if (v->y > max) lim.y = max; else lim.y = v->y;
|
||||||
|
|
||||||
|
return lim;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 limitV3(const Vector3* v, float min, float max)
|
||||||
|
{
|
||||||
|
Vector3 lim;
|
||||||
|
|
||||||
|
if (v->x < min) lim.x = min; else if (v->x > max) lim.x = max; else lim.x = v->x;
|
||||||
|
if (v->y < min) lim.y = min; else if (v->y > max) lim.y = max; else lim.y = v->y;
|
||||||
|
if (v->z < min) lim.z = min; else if (v->z > max) lim.z = max; else lim.z = v->z;
|
||||||
|
|
||||||
|
return lim;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 powerV2(const Vector2* v, float pow)
|
||||||
|
{
|
||||||
|
Vector2 res = {.x = powf(v->x, pow), .y = powf(v->y, pow)};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 powerV3(const Vector3* v, float pow)
|
||||||
|
{
|
||||||
|
Vector3 res = {.x = powf(v->x, pow), .y = powf(v->y, pow), .z = powf(v->z, pow)};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 sumV2(const Vector2* v1, const Vector2* v2)
|
||||||
|
{
|
||||||
|
Vector2 res = {.x = v1->x + v2->x, .y = v1->y + v2->y};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 sumV3(const Vector3* v1, const Vector3* v2)
|
||||||
|
{
|
||||||
|
Vector3 res = {.x = v1->x + v2->x, .y = v1->y + v2->y, .z = v1->z + v2->z};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 diffV2(const Vector2* v1, const Vector2* v2)
|
||||||
|
{
|
||||||
|
Vector2 res = {.x = v1->x - v2->x, .y = v1->y - v2->y};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 diffV3(const Vector3* v1, const Vector3* v2)
|
||||||
|
{
|
||||||
|
Vector3 res = {.x = v1->x - v2->x, .y = v1->y - v2->y, .z = v1->z - v2->z};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 constProdV2(const Vector2* v, float value)
|
||||||
|
{
|
||||||
|
Vector2 res = {.x = v->x * value, .y = v->y * value};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 constProdV3(const Vector3* v, float value)
|
||||||
|
{
|
||||||
|
Vector3 res = {.x = v->x * value, .y = v->y * value, .z = v->z * value};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
float scalarProdV2(const Vector2* v1, const Vector2* v2)
|
||||||
|
{
|
||||||
|
float res = v1->x * v2->x + v1->y * v2->y;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
float scalarProdV3(const Vector3* v1, const Vector3* v2)
|
||||||
|
{
|
||||||
|
float res = v1->x * v2->x + v1->y * v2->y + v1->z * v2->z;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
50
Source/INS/geometry/vector.h
Normal file
50
Source/INS/geometry/vector.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef VECTOR_H
|
||||||
|
#define VECTOR_H
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float x, y;
|
||||||
|
} Vector2;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
} Vector3;
|
||||||
|
|
||||||
|
Vector2 normalizeV2(const Vector2* v, float gain);
|
||||||
|
Vector3 normalizeV3(const Vector3* v, float gain);
|
||||||
|
|
||||||
|
Vector2 absV2(const Vector2* v);
|
||||||
|
Vector3 absV3(const Vector3* v);
|
||||||
|
|
||||||
|
float lengthV2(const Vector2* v);
|
||||||
|
float lengthV3(const Vector3* v);
|
||||||
|
|
||||||
|
float lengthSquaredV2(const Vector2* v);
|
||||||
|
float lengthSquaredV3(const Vector3* v);
|
||||||
|
|
||||||
|
Vector2 limitV2(const Vector2* v, float min, float max);
|
||||||
|
Vector3 limitV3(const Vector3* v, float min, float max);
|
||||||
|
|
||||||
|
Vector2 powerV2(const Vector2* v, float pow);
|
||||||
|
Vector3 powerV3(const Vector3* v, float pow);
|
||||||
|
|
||||||
|
Vector2 sumV2(const Vector2* v1, const Vector2* v2);
|
||||||
|
Vector3 sumV3(const Vector3* v1, const Vector3* v2);
|
||||||
|
|
||||||
|
Vector2 diffV2(const Vector2* v1, const Vector2* v2);
|
||||||
|
Vector3 diffV3(const Vector3* v1, const Vector3* v2);
|
||||||
|
|
||||||
|
Vector2 constProdV2(const Vector2* v, float value);
|
||||||
|
Vector3 constProdV3(const Vector3* v, float value);
|
||||||
|
|
||||||
|
float scalarProdV2(const Vector2* v1, const Vector2* v2);
|
||||||
|
float scalarProdV3(const Vector3* v1, const Vector3* v2);
|
||||||
|
|
||||||
|
Vector2 vectorProdV2(const Vector2* v1, const Vector2* v2);
|
||||||
|
Vector3 vectorProdV3(const Vector3* v1, const Vector3* v2);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "radio_receiver.h"
|
#include "radio_receiver.h"
|
||||||
#include "motors.h"
|
#include "motors.h"
|
||||||
#include "pid.h"
|
#include "pid.h"
|
||||||
|
#include "lidar.h"
|
||||||
|
|
||||||
|
|
||||||
imu_scaled_t imu;
|
imu_scaled_t imu;
|
||||||
@@ -12,6 +13,7 @@ attitude_t attitude;
|
|||||||
rc_channels rx_chs_raw;
|
rc_channels rx_chs_raw;
|
||||||
rc_channels rx_chs_normalized;
|
rc_channels rx_chs_normalized;
|
||||||
control_channels_t ctrl_chs;
|
control_channels_t ctrl_chs;
|
||||||
|
lidar_data lidar;
|
||||||
|
|
||||||
void delay_ms(uint32_t ms);
|
void delay_ms(uint32_t ms);
|
||||||
|
|
||||||
@@ -19,7 +21,8 @@ int main(void)
|
|||||||
{
|
{
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
NVIC_SetPriority(TIM6_DAC_IRQn, 1);
|
NVIC_SetPriority(TIM6_DAC_IRQn, 2);
|
||||||
|
NVIC_SetPriority(USART3_IRQn, 1);
|
||||||
NVIC_SetPriority(LPUART1_IRQn, 0);
|
NVIC_SetPriority(LPUART1_IRQn, 0);
|
||||||
|
|
||||||
imu_pow_init();
|
imu_pow_init();
|
||||||
@@ -44,6 +47,8 @@ int main(void)
|
|||||||
|
|
||||||
attitude_pid_update(&ctrl_chs, &rx_chs_normalized, &attitude, &imu);
|
attitude_pid_update(&ctrl_chs, &rx_chs_normalized, &attitude, &imu);
|
||||||
|
|
||||||
|
lidar_update(&lidar);
|
||||||
|
|
||||||
if (rx_chs_normalized.rc_armed)
|
if (rx_chs_normalized.rc_armed)
|
||||||
{
|
{
|
||||||
motors_set_throttle_mix(rx_chs_normalized.rc_throttle, &ctrl_chs, rx_chs_normalized.rc_armed);
|
motors_set_throttle_mix(rx_chs_normalized.rc_throttle, &ctrl_chs, rx_chs_normalized.rc_armed);
|
||||||
|
|||||||
19
drone.ewp
19
drone.ewp
@@ -362,6 +362,7 @@
|
|||||||
<state>$PROJ_DIR$\Source\Core\Inc</state>
|
<state>$PROJ_DIR$\Source\Core\Inc</state>
|
||||||
<state>$PROJ_DIR$\Source\BSP\Inc</state>
|
<state>$PROJ_DIR$\Source\BSP\Inc</state>
|
||||||
<state>$PROJ_DIR$\Source\Control\Inc</state>
|
<state>$PROJ_DIR$\Source\Control\Inc</state>
|
||||||
|
<state>$PROJ_DIR$\Source\INS\geometry</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>CCStdIncCheck</name>
|
<name>CCStdIncCheck</name>
|
||||||
@@ -2367,6 +2368,24 @@
|
|||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
|
<group>
|
||||||
|
<name>INS</name>
|
||||||
|
<group>
|
||||||
|
<name>geometry</name>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\Source\INS\geometry\quaternion.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\Source\INS\geometry\quaternion.h</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\Source\INS\geometry\vector.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\Source\INS\geometry\vector.h</name>
|
||||||
|
</file>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
<file>
|
<file>
|
||||||
<name>$PROJ_DIR$\Source\main.c</name>
|
<name>$PROJ_DIR$\Source\main.c</name>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
18
drone.ewt
18
drone.ewt
@@ -3552,6 +3552,24 @@
|
|||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
|
<group>
|
||||||
|
<name>INS</name>
|
||||||
|
<group>
|
||||||
|
<name>geometry</name>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\Source\INS\geometry\quaternion.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\Source\INS\geometry\quaternion.h</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\Source\INS\geometry\vector.c</name>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<name>$PROJ_DIR$\Source\INS\geometry\vector.h</name>
|
||||||
|
</file>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
<file>
|
<file>
|
||||||
<name>$PROJ_DIR$\Source\main.c</name>
|
<name>$PROJ_DIR$\Source\main.c</name>
|
||||||
</file>
|
</file>
|
||||||
|
|||||||
Reference in New Issue
Block a user