Skip to main content

Featured

YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors review

 YOLO 버전이 v7 버전으로 논문이 발표되었다. papers with code에서 쉽게 확인할 수 있으며 이 논문은 모듈 최적화 기법 위주이다. CSPNet이라던지 RepVGG 같은 관련 네트워크들을 간단하게 공부하고 논문을 이해하는 것을 추천한다. 아래는 official github이며 ReadMe를 보면 쉽게 사용 방법을 알 수 있다. https://github.com/wongkinyiu/yolov7 또한 본 논문은 아래와 같다. Wang, Chien-Yao, Alexey Bochkovskiy, and Hong-Yuan Mark Liao. "YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors." arXiv preprint arXiv:2207.02696 (2022). 그렇다면 간략하게 논문에 대해 알아보도록 한다. - Abstract YOLOv7이 알려진 모든 detector들보다 정확도와 속도 면에서 성능을 능가하고 있다고 설명한다. 또한 이 네트워크를 오직 COCO 데이터셋으로만 훈련했다고 설명한다. 다른 네트워크들보다 확실히 좋은 성능을 내고 있다는 것으로 abstract에서 소개하고 있다. - Introduction  이 논문에서 제안한 real-time detector는 주로 mobile GPU나 GPU 장치를 지지할 수 있다는 것을 희망한다고 한 것을 보아 GPU가 필요하다는 것으로 이해하였다. 또한 이 논문에서 제안된 방법들의 개발 방향을 현재 real-time detector들의 개발 흐름과 다르다고 설명한다. 훈련 과정의 최적화에 집중했다고 한다. 그래서 중점적인 것이 정확도를 향상시키기 위한 훈련 cost를 강화화는 최적화된 모듈과 최적 기법이라고 설명한다.  논문의 제목에서 나오는데 제안된 모듈들과 최적 기법들을 trainable bag-of-freebies라고 칭한다. 최근에, model re-pa...

Toy Quad Rotor FCC Review 3 : STEVAL-FCU001V1 - I2C Setting

이 포스팅에서는 리뷰하고 있는 STEVEL-FCU001V1에서 I2C기능을 추가하는 방법에 대해 기술한다. 먼저 코드 링크와 파일 경로는 다음과 같다.

Code Link : 
 https://github.com/STMicroelectronics-CentralLabs/ST_Drone_FCU_F401

살펴볼 코드는 Official release with BLE Remocon이며 위치는 다음과 같다. 

File Path :
ST_Drone_FCU_F401-master\ST_Drone_FCU_F401-master\STM32 FW Project\Official release with BLE Remocon - 170318\Src

중점적으로 다뤄질 코드는 Src의 main.c, stm32f4xx_hal_msp.c이다. 해당 코드에서 간단히 코드를 추가하면 I2C를 사용할 수 있다.

그리고 중요한 부분이 있는데 다음 경로에 있는 .project 파일에 추가해 줄 것이 있다.

.project의 path는 다음과 같다.

File Path :
ST_Drone_FCU_F401-master\ST_Drone_FCU_F401-master\STM32 FW Project\Official release with BLE Remocon - 170318\SW4STM32\ToyDrone Configuration

이제 I2C를 살려보도록 하자,

I2C를 활성하기 위해서는 stm32f401의 핀의 역할을 잘 확인해보아야 하고 FCC 보드에 어떻게 porting 되어 있는지 확인이 필수적이다. 

아래의 그림 ST에서 제공하는 Document에서 찾을 수 있다. 링크는 다음과 같다.

Link : 
https://www.st.com/en/evaluation-tools/steval-fcu001v1.html#documentation

File Name : 
Getting started with the STEVAL-FCU001V1 flight controller unit evaluation board for mini drones - User manual

그럼 그림을 확인해보자,

Fig 1. STEVAL-FCU001V1 – circuit schematic (2 of 4)

User Manual에서는 위 그림과 같이 PB3와 PB10을 I2C로 사용하고 있다고 명시되어 있다.
하지만 코드상에는 활성화하지 않은 상태이다. 즉 회로적으로 연결을 되어있으므로 소프트웨어적으로 설정하는 코드를 작성하면어 문제 없을것이다.

결과적으로 PB3와 PB10을 각 I2C로 설정하되 PB3를 I2C의 SDA 그리고 PB10을 SCL로 설정하면 된다.

이제 이를 위한 코드를 추가해 보자, stm32f4xx_hal_msp.c로 가보자, 해당 파일의 코드를 보면 센서와의 통신, 모터 제어 신호를 위한 Timer 설정, 제어 주기를 위한 Timer 등등에 대한 핀 설정 함수들이 작성되어 있다(한번 Line-by-Line으로 확인해봐도 좋아요). 이 자체에서 "수정할 내용은 없고" I2C를 설정하는 코드를 "추가" 할 것이다. 아래 코드를 삽입하면 되는데 아무곳에 삽입해도 문제가 없지만 함수 HAL_UART_MspInit 아래 코드를 붙여넣기 하면 된다. 즉 함수 하나 넣는다 생각하면 된다.
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
 
  GPIO_InitTypeDef GPIO_InitStruct;
  if(hi2c->Instance==I2C2)
  {
  /* USER CODE BEGIN I2C2_MspInit 0 */
 
  /* USER CODE END I2C2_MspInit 0 */
 
    /**I2C2 GPIO Configuration
    PB10     ------> I2C2_SCL
    PB3      ------> I2C2_SDA
    */
    GPIO_InitStruct.Pin  = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin  = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_I2C2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    /* Peripheral clock enable */
    __I2C2_CLK_ENABLE();
  /* USER CODE BEGIN I2C2_MspInit 1 */
 
  /* USER CODE END I2C2_MspInit 1 */
  }
 
}
cs

그럼 stm32f4xx_hal_msp.c에서 볼일은 끝난 것이다.

다음으로 main.c에서 추가해야할 부분을 살펴보자, I2C 설정을 위해 I2C Handler를 생성해야만 한다(Line 24).
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "bluenrg_l2cap_aci.h"
#include "vl53l5cx_api.h"
/* USER CODE END Includes */
 
/* Private variables ---------------------------------------------------------*/
volatile uint32_t HCI_ProcessEvent=0;
uint8_t joydata[8= {0,0,0,0,0,0,0,0};
 
uint32_t uhCCR4_Val = 500;
uint32_t uhCCR1_Val = 5000;
 
 
ADC_HandleTypeDef hadc1;
 
SPI_HandleTypeDef hspi1;
SPI_HandleTypeDef hspi2;
 
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim4;
TIM_HandleTypeDef htim9;
 
UART_HandleTypeDef huart1;
 
I2C_HandleTypeDef hi2c2;//**추가된 부분 I2C Handler
...
...
...
cs

그리고 I2C를 상세하게 설정하기 위해 초기화 함수를 생성해주어야한다(Line 5).

1
2
3
4
5
6
7
8
9
10
11
12
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_I2C2_Init(void);//I2C 상세 설정을 위한 Initialization Function
//static void MX_SPI1_Init(void);
//static void MX_SPI2_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM4_Init(void);
static void MX_TIM9_Init(void);
static void MX_USART1_UART_Init(void);
 
cs

초기화 함수는 다음과 같은데, 이 함수는 main문 밑에 어딘가에 적절히 복사 붙여넣기 하면 된다. 필자는 MX_ADC1_Init 밑에 추가하였는데 이 함수 또한 main.c 코드의 밑 부분에 찾아보면 나온다(Line 31).
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/* ADC1 init function */
void MX_ADC1_Init(void)
{
 
  ADC_ChannelConfTypeDef sConfig;
 
    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
    */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION12b;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.EOCSelection = EOC_SINGLE_CONV;
  HAL_ADC_Init(&hadc1);
 
    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
    */
  sConfig.Channel = ADC_CHANNEL_9;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
 
}
 
/* I2C2 init function */ //MX_ADC1_Init밑에 이 코드를 추가하세요!
void MX_I2C2_Init(void)
{
  hi2c2.Instance = I2C2;
  hi2c2.Init.ClockSpeed = 400000;//SCL Clock Speed 400k[Hz]
//Clock speed는 센서마다 요구조건이 다르므로 확인하고 이를 바꾸면된다.
  hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c2.Init.OwnAddress1 = 0;
  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
  hi2c2.Mode = HAL_I2C_MODE_MASTER;
  hi2c2.Init.OwnAddress2 = 0;
  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
  HAL_I2C_Init(&hi2c2);
}
cs

이로서 코드는 설정이 끝났으며, ".project" 수정만 남았다. 수정을 위해 다음 path로 이동하자

path : 
ST_Drone_FCU_F401-master\ST_Drone_FCU_F401-master\STM32 FW Project\Official release with BLE Remocon - 170318\SW4STM32\ToyDrone Configuration

.project를  워드패드(추천)나 메모장으로 열어보자! 다음처럼

Fig 2. .project file open using WordPad

.project에서는 상위폴더에 있는 Src과 Inc에 포함되어있는 코드들을 Linking하는 코드들이 작성되어있다.

파일을 쭉 보다보면 stm32f4xx_hal_spi.c 도 있고 stm32f4xx_hal_tim.c도 있고 
stm32f4xx_hal_uart.c도 있을 것이다.

그렇다, 아니? 왜 i2c는 없는거야? 내가 여기 근처에 i2c를 추가하면 되겠지? 라는 생각이 들면된다. 이런 생각이 들었어도 어찌 추가해야하는 거지? 라는 생각이 들 수 있다.

uart도 있으니 i2c도 stm32f4xx_hal에 어딘가에 존재할 것이다. 그러면 stm32f4xx_hal_i2c.c를 추가하면 되는데... 어떻게 넣지?

uart나 spi도 다음과 같은 형식으로 써져있음을 알 수 있다.
    
1
2
3
4
5
6
7
</locationURI>
        </link>
        <link>
            <name>Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_uart.c</name>
            <type>1</type>
            <locationURI>
PARENT-2-PROJECT_LOC/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c
cs

그러면 i2c도 이런식으로 작성해서 넣어주면 되겠구나! 필자는 다음과 같이 uart 설정 윗부분에 추가하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.....
 
</locationURI>
        </link>
        <link>
            <name>Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_tim_ex.c</name>
            <type>1</type>
            <locationURI>
PARENT-2-PROJECT_LOC/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c
</locationURI>
        </link>
        <link>
            <name>Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_i2c.c</name>
            <type>1</type>
            <locationURI>
PARENT-2-PROJECT_LOC/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c</locationURI>
        </link>
        <link>
            <name>Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_uart.c</name>
            <type>1</type>
            <locationURI>
PARENT-2-PROJECT_LOC/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c
 
......
......
cs

이러면 I2C를 FCC에서 쓸 수 있게된것이다. 막혀있던 I2C 길이 열린것

추가 참고자료로 다음에 링크를 남긴다.

1. https://deepbluembedded.com/stm32-i2c-tutorial-hal-examples-slave-dma/

2. https://rs29.tistory.com/2

3. 
https://dkeemin.com/stm32f103-i2c-%EA%B8%B0%EC%B4%88%EC%84%A4%EC%A0%95-%EB%B0%8F-%EC%BD%94%EB%93%9C-%EC%A7%9C%EA%B8%B0/

4. https://mokhwasomssi.tistory.com/46

5.
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=eziya76&logNo=221486711330



































Comments