๐Ÿ“’
OpenRobot, Inc
  • Welcome
  • Quick Guide
    • Getting Started
    • VESC-Tool
    • Motor Setting
    • Basic Run
    • Additional Guide
  • Tutorials
    • Firmware download
    • Control with VESC driver
    • Control with Python
    • Control with CAN
    • VESCular6
    • VESCuino Shield
    • Control using Odroid SBC
  • Applications
    • 3D-Printed Actuator Modules
    • 2-Link Planar Robot
    • Omni-directional Mobile Platform
    • 6-DOF Manipulator
Powered by GitBook
On this page

Was this helpful?

  1. Tutorials

Control with VESC driver

We describe the VESC control method in ROS using the VESC driver developed by Michael T. Boulet at MIT.

PreviousFirmware downloadNextControl with Python

Last updated 4 years ago

Was this helpful?

1. Use Custom App

VESC๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Custom App์ด๋ผ๋Š” ๋ถ€๋ถ„์„ ๋งŒ๋“ค์–ด ์ด ๋ถ€๋ถ„์ด ์‚ฌ์šฉ์ž๊ฐ€ ์ถ”๊ฐ€์ ์œผ๋กœ ๊ฐœ๋ฐœํ•œ ํ”„๋กœ๊ทธ๋žจ์„ ์‰ฝ๊ฒŒ ํƒ‘์ œํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐฐ๋ คํ•˜์˜€๋‹ค. OpenRobot์—์„œ ๊ฐœ๋ฐœํ•œ Custom App์€ VESC ๊ธฐ๋ณธ ํŽŒ์›จ์–ด์˜ application ํด๋”์— openrobot ํด๋”์— ์ €์žฅํ•ด๋†“์•˜๋‹ค.

๊ธฐ๋ณธ Firmware์— app_custm.c ๋ผ๋Š” ํŒŒ์ผ์ด custom app์˜ ๊ธฐ๋ณธ ํ…œํ”Œ๋ฆฟ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๊ณณ์— ์žˆ๋Š” ํ”„๋กœ๊ทธ๋žจ ์˜ˆ์ œ๋งŒ์„ ๋ณด๊ณ ๋กœ์ฒ˜์Œ๋ถ€ ์ง์ ‘ custom app์„ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์€ ์‰ฌ์šด ์ผ์ด ์•„๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ VESC ํŽŒ์›จ์–ด์˜ ๋™์ž‘์›๋ฆฌ์— ๋Œ€ํ•ด ๋จผ์ € ์ดํ•ดํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

VESC์—๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ํ†ต์‹  ์ฑ„๋„๋“ค์ด ์žˆ๊ณ  ๋Œ€ํ‘œ์ ์œผ๋กœ UART, USB ํ†ต์‹ ์ด VESC์— ๋ช…๋ น์„ ๋‚ด๋ฆด ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” VESC์˜ ํ†ต์‹  Protocol์— ๋Œ€ํ•ด ๋จผ์ € ์„ค๋ช…ํ•˜๊ฒ ๋‹ค.

๋ณธ ๋‚ด์šฉ์€ ์•„๋ž˜ ํ™ˆํŽ˜์ด์ง€๋ฅผ ์ฐธ๊ณ ํ•˜์˜€๋‹ค.

1. VESC ํ†ต์‹  Protocol

VESC์˜ ํ†ต์‹  ํ”„๋กœํ† ์ฝœ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ํ•˜๊ณ  ์žˆ๋‹ค. ๋ฐ์ดํ„ฐ๋Š” Packet ๋‹จ์œ„๋กœ ์ „์†ก๋˜๋ฉฐ Packet์€ ์ „์†กํ•˜๊ณ ์ž ํ•˜๋Š” Data ์˜ ์‚ฌ์ด์ฆˆ์— ๋”ฐ๋ผ Short Packet ๊ณผ Long Packet์˜ ๋‘ ๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

  • Short Packet

1st Byte

2nd Byte

3rd ~ (n-3)th Byte

(n-2)th Byte

(n-1)th Byte

(n)th Byte

2

packet length

data

CRC High

CRC Low

3

Short Packet ์€ ์ฒซ๋ฒˆ์งธ Byte ์ˆซ์ž 2๋กœ ์‹œ์ž‘ํ•œ๋‹ค. ์ดํ›„ 2๋ฒˆ์งธ Byte์— packet์˜ ๊ธธ์ด ๊ฐ’์„ ๋„ฃ๋Š”๋‹ค. 3๋ฒˆ์งธ Byte๋ถ€ํ„ฐ๊ฐ€ ์‹ค์ œ ๋ฐ์ดํ„ฐ์ด๋ฉฐ ์ „์†กํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ์— ๋”ฐ๋ผ ์ด ๋ถ€๋ถ„์ด ์ฐจ์ง€ํ•˜๋Š” ํฌ๊ธฐ๋Š” ๋ฐ”๋€” ์ˆ˜ ์žˆ๋‹ค. ์ดํ›„ ๋งˆ์ง€๋ง‰์—์„œ 3๋ฒˆ์งธ์™€ 2๋ฒˆ์งธ์— CRC Check sum์„ ์œ„ํ•œ 2๊ฐœ์˜ Byte๊ฐ€ ์‚ฌ์šฉ๋˜๊ณ  ๋งˆ์ง€๋ง‰ Byte๋Š” Stop Byte๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ ์ˆซ์ž 3์„ ์‚ฌ์šฉํ•œ๋‹ค.

Short Packet ์€ Packet์˜ ํฌ๊ธฐ๋ฅผ ํ‘œํ˜„ํ•˜๋Š”๋ฐ 1Byte๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ 1Byte๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ์ˆซ์ž์˜ ํฌ๊ธฐ๋Š” 0~255๊นŒ์ง€์ด๋ฏ€๋กœ Short Packet์— ์‹ค๋ ค์„œ ์ „์†ก๋  ์ˆ˜ ์žˆ๋Š” ์‹ค์ œ data์˜ ํฌ๊ธฐ๋Š” 255 Byte๊ฐ€ ์ตœ๋Œ€๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. ์ด๋ ‡๊ฒŒ Short Packet์— ์ตœ๋Œ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์–ด์„œ ์ „์†กํ•˜๊ฒŒ ๋˜๋ฉด ์ „์ฒด packet์˜ ์‚ฌ์ด์ฆˆ๋Š” 1(์‹œ์ž‘) + 1(length) + 255(data) + 2(crc) + 1(stop) = 260 Byte๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ๋งˆ์ดํฌ๋กœํ”„๋กœ์„ธ์„œ์—์„œ int32, float๋“ฑ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ 4byte ๋ฐ์ดํ„ฐํ˜•์ด๋ฏ€๋กœ ๋‹จ์ˆœ ๊ณ„์‚ฐ์œผ๋กœ ์ƒ๊ฐํ•ด๋ณด๋ฉด 255 Byte๋Š” 63๊ฐœ์˜ float ๋ณ€์ˆ˜๋ฅผ ์ „์†กํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์‚ฌ์ด์ฆˆ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  • Long Packet

1st Byte

2nd Byte

3rd Byte

4th ~ (n-3)th Byte

(n-2)th Byte

(n-1)th Byte

(n)th Byte

3

packet

length High

packet

length Low

data

CRC High

CRC Low

3

Long Packet ์€ ์ฒซ๋ฒˆ์งธ Byte๊ฐ€ ์ˆซ์ž 3์œผ๋กœ ์‹œ์ž‘ํ•˜๊ณ  ์ด์–ด์„œ 2~3๋ฒˆ์งธ Byte๊ฐ€ packet length์— ํ•ด๋‹นํ•œ๋‹ค. Packet length์— 2Byte๋ฅผ ํ• ๋‹นํ•˜๋ฏ€๋กœ ์ตœ๋Œ€๋กœ ์ „์†ก๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ์˜ ์–‘์€ 65535 Byte๊ฐ€ ๋œ๋‹ค. ์ด๋Š” Short Packet์— ๋น„ํ•ด 257๋ฐฐ ๋” ํฐ ๋ฐ์ดํ„ฐ๋Ÿ‰์— ํ•ด๋‹นํ•œ๋‹ค. ์ดํ›„ Byte์—๋Š” Short Packet๊ณผ ๋™์ผํ•˜๊ฒŒ CRC์— 2Byte์™€ Stop Byte๋กœ ์ˆซ์ž 3์ด ์“ฐ์ธ๋‹ค.

2. VESC ํ†ต์‹  Interface

VESC์˜ ํ†ต์‹  ํ”„๋กœํ† ์ฝœ์— ๋Œ€ํ•ด์„œ๋Š” ์•ž์—์„œ ์ด์•ผ๊ธฐ ํ•˜์˜€์œผ๋ฉฐ ์ด ๋ถ€๋ถ„์—์„œ๋Š” VESC ํ†ต์‹ ์˜ Interface์— ๋Œ€ํ•ด ๋‹ค๋ฃฌ๋‹ค. VESC๋Š” ๋‹ค์–‘ํ•œ ํ†ต์‹ ๋ฐฉ์‹์„ ์ง€์›ํ•œ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ UART์™€ USB ๊ทธ๋ฆฌ๊ณ  CANํ†ต์‹ ์ด ์žˆ๋‹ค.

USB๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ VESC-Tool์„ ์ด์šฉํ•  ๋•Œ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ์ด๋Š” ํ†ต์‹ ๋ฐฉ์‹์ด๋ฉฐ ROS(Robot Operating System)์„ ์ด์šฉํ•˜์—ฌ VESC๋ฅผ ์‹ค์‹œ๊ฐ„ ์ œ์–ดํ•  ๋•Œ๋„ ์ฃผ๋กœ USB๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.

UART๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ USB-Serial Adapter๋ฅผ ์ด์šฉํ•˜๋ฉด USB๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ VESC-Tool์ด๋‚˜ ROS๋“ฑ์— ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ, UART๋Š” ๋ธ”๋ฃจํˆฌ์Šค ๋™๊ธ€(nRF51822)์„ ์—ฐ๊ฒฐํ•˜์—ฌ ๋ฌด์„ ์œผ๋กœ ์•ˆ๋“œ๋กœ์ด๋“œ์šฉ VESC-Tool์—์„œ VESC๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

CAN ํ†ต์‹ ์€ ๋‹ค์ˆ˜์˜ VESC๋ฅผ ์„œ๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ฉฐ ํ†ต์‹ ๋ฐ์ดํ„ฐ๋ฅผ Forwardingํ•˜์—ฌ ํ•˜๋‚˜์˜ VESC๋กœ ์ „๋‹ฌ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฅธ VESC๋กœ ์ „๋‹ฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

์ด๋ฐ–์—๋„ I2C ํ†ต์‹ ์„ ์ด์šฉํ•˜์—ฌ ๋ฌด์„  ์ œ์–ด๊ธฐ์ธ Nunchuk(๊ณผ๊ฑฐ ๋‹Œํ…๋„ Wii ๊ฒŒ์ž„ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์‚ฌ์šฉ๋จ)์„ ์ด์šฉํ•ด VESC๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. I2C ํ†ต์‹ ์€ IMU์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด๋“ค์ด๊ธฐ ์œ„ํ•ด์„œ๋„ ์‚ฌ์šฉ๋˜๋ฉฐ ํ˜„์žฌ VESCular์—๋Š” Bosch ์‚ฌ์˜ BMI160 IMU๊ฐ€ On-board์— ํƒ‘์žฌ๋˜์–ด Custom App์„ ์‚ฌ์šฉ์‹œ ๊ธฐ๋ณธ์ ์œผ๋กœ IMU ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฐ–์—๋„ SPI ํ†ต์‹ ์€ Magnetic Encoder์ธ AS5047p์™€ ์—ฐ๊ฒฐ์‹œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ํŠน์ดํ•œ ์ ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” Hardware SPI๊ฐ€ ์•„๋‹Œ Software SPI๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ(Firmware์—์„œ Hardware SPI๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ”๊ฟ€์ˆ˜๋Š” ์žˆ๋‹ค)์ด๊ณ  DRV8301(Mosfet Gate Driver)๊ณผ์˜ ํ†ต์‹ ๋„ Software SPI ํ†ต์‹ ์„ ์ด์šฉํ•œ๋‹ค.

Hardware SPI๋Š” PA4~PA7์— ํ• ๋‹น๋œ SPI1 ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด ํ•€๋“ค์€ UART ๋ฐ I2C ํ†ต์‹ ์œผ๋กœ๋„ Alternate ํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— PA4~PA7์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋Š” ํ†ต์‹  ๊ธฐ๋Šฅ์€ UART, I2C, SPI ์„ธ๊ฐ€์ง€ ํ†ต์‹ ์ค‘ ๋™์‹œ์— ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

OpenRobot App์—์„œ๋Š” Hardware SPI ํ†ต์‹ ์„ ์ด์šฉํ•˜์—ฌ Arduino์™€ ๊ณ ์† ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜์—ฌ VESC์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์‚ฌํ•ญ์„ ๋ชฐ๋ผ๋„ Arduino์—์„œ SPI ํ†ต์‹ ์„ ํ†ตํ•ด ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋„๋ก ํ”„๋กœ๊ทธ๋žจํ•˜์˜€๋‹ค. Hardware SPI ํ†ต์‹  ๊ธฐ๋Šฅ์€ OpenRobot App์˜ ๋…์ž์ ์ธ ๊ธฐ๋Šฅ์ด๋‹ค.

์•„๋ž˜ ํ‘œ์— VESC์˜ ํ†ต์‹  Interface๋ฅผ ๋ชจ๋‘ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

ํ†ต์‹ ์ฑ„๋„

์‚ฌ์šฉ

ํ†ต์‹ ์†

USB

VESC-Tool, ROS

๊ธฐ๋ณธ 115200bps, ์ตœ๋Œ€ 3000000bps

UART

VESC-Tool, ROS, Bluetooth

๊ธฐ๋ณธ 115200bps, ์ตœ๋Œ€ 921600bps

CAN

VESC to VESC

๊ธฐ๋ณธ 500Kbps, ์ตœ๋Œ€ 1Mbps

I2C (Software)

Nunchuk, IMU

๊ธฐ๋ณธ 1Mbit/sec, ์ตœ๋Œ€ 2Mbit/sec

SPI (Software)

DRV8301, AS5047p

Bit-banging (didn't measure yet)

SPI (Hardware)

Arduino (OpenRobot App Only)

๊ธฐ๋ณธ 4Mhz, ์ตœ๋Œ€ 8Mhz(Clock Speed)

VESC ๊ธฐ๋ณธ ํŽŒ์›จ์–ด์—์„œ๋Š” I2C ๋ฐ SPI ํ†ต์‹ ์„ Software ์ ์ธ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜์˜€๋Š”๋ฐ, ์ด๋Š” STM32F4x์—์„œ ์ œ๊ณตํ•˜๋Š” ํŠน์ • ํ•€๋งˆ๋‹ค ํ• ๋‹น๋œ ํ•˜๋“œ์›จ์–ด์ ์ธ ํ†ต์‹  Pin์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์ด ์•„๋‹Œ, ์ผ๋ฐ˜์ ์ธ digital IO๋ฅผ ์ด์šฉํ•˜์—ฌ ํ†ต์‹ ์„ ๊ตฌํ˜„ํ•œ ๊ฒƒ์œผ๋กœ ์•„๋‘์ด๋…ธ ์šฐ์˜ software serial ๊ณผ ์œ ์‚ฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ณด๋ฉด ๋œ๋‹ค.

์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•œ ๋ฐ๋Š” ์•„๋ฌด๋ž˜๋„ ๋ชจํ„ฐ ์ œ์–ด์— ์ข€๋” ํ•˜๋“œ์›จ์–ด ๋ฆฌ์†Œ์Šค๋ฅผ ๋” ํˆฌ์ž…ํ•˜๊ณ ์ž ํ•˜๋Š” ์˜๋„๊ฐ€ ๋ณด์ธ๋‹ค. Hardware ํ†ต์‹  ์ฑ„๋„์„ ์ด์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์•„๋ฌด๋ž˜๋„ ํ†ต์‹ ์‹œ Hardware ์ธํ„ฐ๋ŸฝํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ณ  ์ด ์ƒํ™ฉ์—์„œ ๋ชจํ„ฐ์ œ์–ด๋ฅผ ์œ„ํ•œ Interrupt ๋“ฑ๊ณผ ์ซ‘๋‚ ์ˆ˜ ์žˆ์–ด์„œ ํŽŒ์›จ์–ด๊ฐ€ ๋ฉˆ์ถฐ๋ฒ„๋ฆฌ๊ฑฐ๋‚˜ ๋ฆฌ์…‹๋˜๋Š” ๋ฌธ์ œ๋“ฑ์ด ๋ฐœ์ƒํ•  ์œ„ํ—˜์†Œ์ง€๊ฐ€ ์žˆ๋‹ค. ๋ฌผ๋ก  ํ”„๋กœ๊ทธ๋žจ์„ ์ž˜ ๋งŒ๋“ค๋ฉด ์ด๋Ÿฐ ์ƒํ™ฉ์„ ํ”ผํ•  ์ˆ˜๋Š” ์žˆ๊ฒ ์ง€๋งŒ, software ์ ์œผ๋กœ๋„ ์ถฉ๋ถ„ํžˆ ์›ํ™œํ•œ ํ†ต์‹  ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ๊ตณ์ด Hardware ๋ฐฉ์‹์„ ๊ฐˆ ํ•„์š”๋Š” ์—†๋‹ค.

๊ตณ์ด Hardware ํ†ต์‹  ๋ฐฉ์‹์„ ์จ์•ผํ•  ๋•Œ๋Š” ๊ณ ์†์˜ ํ†ต์‹ ์ด ์š”๊ตฌ๋  ๋•Œ์ด๋ฉฐ, VESCuino์˜ ๊ฒฝ์šฐ์—๋Š” Hardware SPIํ†ต์‹ ์„ ์ด์šฉํ•ด ์•„๋‘์ด๋…ธ Due์™€ ์ตœ๋Œ€ 8Mhz SPI Clock ์Šคํ”ผ๋“œ๋กœ ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•˜์—ฌ ๊ณ ์†์˜ ์‹ค์‹œ๊ฐ„ ์ œ์–ด(Low Latency)์— ์œ ๋ฆฌํ•˜๋‹ค.

3. VESC์˜ ํ†ต์‹  Software Architecture

์•ž์—์„œ ์–ธ๊ธ‰ํ•œ ๋‹ค์–‘ํ•œ ํ†ต์‹ ์ฑ„๋„์— ๋น„ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” software ๋ฃจํ‹ด์€ ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ์ด๋Š” ๋ชจ๋“  ํ†ต์‹  ์ฑ„๋„์—์„œ ๋“ค์–ด์˜ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ ์‹ค์ œ data๋งŒ ์ถ”์ถœํ•œ ํ›„ ์ด๋ฅผ ํ•ด์„ํ•˜๋Š” ๊ตฌ๋ฌธ์ด ํ•œ ๊ณณ์—์„œ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋„๋ก ์„ค๊ณ„ํ•ด๋†“์•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

VESC ํŽŒ์›จ์–ด์—์„œ๋Š” C์–ธ์–ด๋กœ ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ†ต์‹  ์ฑ„๋„๋งˆ๋‹ค ๋ฐ์ดํ„ฐ ํŒŒ์‹ฑ์„ ์œ„ํ•œ ํ•จ์ˆ˜๋ฅผ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋ฐ”๊ฟ”์ค„ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑ์ด ๋˜์–ด์žˆ๋‹ค. ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ผ๋Š” ๊ฒƒ์ด ์กฐ๊ธˆ ์ƒ์†Œํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ธ๋ฐ ์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • UART ํ†ต์‹ 

VESC-Tool์„ ์‹คํ–‰ํ•ด๋ณด๋ฉด ํฌ๊ฒŒ ๋‘๊ฐœ์˜ ํŒŒํŠธ๋กœ ๋‚˜๋‰˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ์•Œ์ˆ˜ ์žˆ๋Š”๋ฐ ๋ฐ”๋กœ Motor setting ๋ถ€๋ถ„๊ณผ App setting ๋ถ€๋ถ„ ๊ทธ๋ฆฌ๊ณ  Data Analysis ์ด๋‹ค. Motor setting์€ ๋ชจํ„ฐ์˜ Identification ๋ฐ ์ œ์–ดGain๋“ฑ์˜ ์„ธํŒ…๊ณผ ๊ด€๋ จ๋œ ๋ถ€๋ถ„์ด๊ณ  App setting์€ ์–ด๋– ํ•œ App์„ ์‹คํ–‰์‹œํ‚ฌ๊ฑด์ง€ ๊ทธ๋ฆฌ๊ณ  ํŠน์ • App ์ด ์‹คํ–‰์ค‘์ผ๋•Œ ์ด์— ๊ด€ํ•œ ์„ธํŒ…์— ๋Œ€ํ•œ ๋ถ€๋ถ„์ด๋‹ค. ์„ธํŒ…๊ณผ ๊ด€๋ จ๋œ ๋‘ ๋ถ€๋ถ„์€ ๊ฐ๊ธฐ ๋ถ„๋ฆฌ๋œ ์ €์žฅ์˜์—ญ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋…๋ฆฝ์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ์ €์žฅ์‹œํ‚ค๋„๋ก ๋˜์–ด์žˆ๋‹ค. ํ˜„์žฌ VESC-Tool์—์„œ ์„ ํƒ๊ฐ€๋Šฅํ•œ App์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค(VESC FW ver5.02 ๊ธฐ์ค€).

No App
PPM
ADC
UART
PPM and UART
ADC and UART
Nunchuk (I2C, Nyko Kama)
NRF
Custom User App
Balance
PAS
ADC and PAS

์•ž์—์„œ ์–ธ๊ธ‰ํ•œ ๋ฐ”์™€ ๊ฐ™์ด VESC์—์„œ ํ†ต์‹ ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ์ปค๋„ฅํ„ฐ๋Š” ์—ฌ๋Ÿฌ ํ†ต์‹ ์ด ํ†ตํ•ฉ๋˜์–ด ์žˆ์–ด ํ•œ๋ฒˆ์— ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜๋Š” ์—†๋‹ค. ๊ทธ๋ž˜์„œ ์œ„์™€ ๊ฐ™์ด App์„ ์„ ํƒํ•˜์—ฌ ํ†ต์‹ ํ•€์ด ์ „์›์ธ๊ฐ€ํ›„ ์ดˆ๊ธฐํ™”๋  ๋•Œ ์›ํ•˜๋Š” ํ†ต์‹ ํ•€์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ธํŒ…๋œ๋‹ค.

UARTํ†ต์‹ ์„ ์œ„ํ•ด์„œ๋Š” Tx, Rx (Tx๋Š” ์†ก์‹ , Rx๋Š” ์ˆ˜์‹ )๋ฅผ ์œ„ํ•œ Pin์ด ์š”๊ตฌ๋˜๋ฉฐ ์ด๋ฅผ ๋ฐ˜๋Œ€ํŽธ ํ†ต์‹ ์ธก๊ณผ ์•„๋ž˜์™€ ๊ฐ™์ด ์—ฐ๊ฒฐํ•˜๋ฉด UARTํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. UART ํ†ต์‹ ์€ ๋ฐ˜๋“œ์‹œ GND๋ฅผ ๋™์ผํ•˜๊ฒŒ ํ•ด์ค˜์•ผํ•˜๋ฏ€๋กœ ์‹ค์งˆ์ ์œผ๋กœ๋Š” 3๊ฐœ์˜ ์„ ์ด ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด์•ผ ํ•œ๋‹ค.

VESC ์ชฝ TX - ๋ฐ˜๋Œ€์ชฝ RX
VESC ์ชฝ RX - ๋ฐ˜๋Œ€์ชฝ TX
VESC ์ชฝ GND - ๋ฐ˜๋Œ€์ชฝ GND

UART ํ†ต์— ๊ด€ํ•ด์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์•„๋ž˜์˜ ํ”„๋กœ๊ทธ๋žจ์„ ์‚ดํŽด๋ณด์•„์•ผ ํ•œ๋‹ค.

app_uartcomm.c
packet.c
commands.c

์œ„ ํ”„๋กœ๊ทธ๋žจ์˜ ๊ตฌ์กฐ๋ฅผ ์ž˜ ์ดํ•ดํ•˜๋ฉด ์ „์ฒด์ ์ธ VESC์˜ ํ†ต์‹  ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ๋˜๋Š”๋ฐ, ์šฐ์„  app_uartcomm.c์—์„œ๋Š” app_uartcomm_start()ํ•จ์ˆ˜์—์„œ UART ํ†ต์‹ ์„ ์œ„ํ•œ Pin ์„ค์ •๊ณผ UART ํ†ต์‹ ์„ ์ฒ˜๋ฆฌํ•˜๋Š” Thread๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ด์ „์— packet_init ํ•จ์ˆ˜์—์„œ UART ํ†ต์‹ ์˜ ๋ฐ์ดํ„ฐ Packet์„ ์ฒ˜๋ฆฌํ•  ํ•จ์ˆ˜๋“ค์„ ์„ ํƒํ•ด์ฃผ ํ•จ์ˆ˜ํฌ์ธํ„ฐ๋ฅผ ์ง€์ •ํ•œ๋‹ค.

void app_uartcomm_start(void) {
  // UART ํ†ต์‹  Packet์„ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜ํฌ์ธํ„ฐ
	packet_init(send_packet, process_packet, PACKET_HANDLER);

	// UART ํ†ต์‹ ์ฒ˜๋ฆฌ Thread
	if (!thread_is_running) {
		chThdCreateStatic(packet_process_thread_wa, sizeof(packet_process_thread_wa),
				NORMALPRIO, packet_process_thread, NULL);
		thread_is_running = true;
	}
 
  // UART Pin ์„ค์ •๋ถ€
	sdStart(&HW_UART_DEV, &uart_cfg);
	palSetPadMode(HW_UART_TX_PORT, HW_UART_TX_PIN, PAL_MODE_ALTERNATE(HW_UART_GPIO_AF) |
			PAL_STM32_OSPEED_HIGHEST |
			PAL_STM32_PUDR_PULLUP);
	palSetPadMode(HW_UART_RX_PORT, HW_UART_RX_PIN, PAL_MODE_ALTERNATE(HW_UART_GPIO_AF) |
			PAL_STM32_OSPEED_HIGHEST |
			PAL_STM32_PUDR_PULLUP);

	uart_is_running = true;
}

๋ฐ”๋กœ ์ด packet_init ํ•จ์ˆ˜๊ฐ€ ๋งค์šฐ ์ค‘์š”ํ•œ๋‹ค. packet_init ํ•จ์ˆ˜์˜ ์›ํ˜•์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. packet.c์— ๊ฐ€๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋˜์–ด์žˆ๋‹ค. packet_init ํ•จ์ˆ˜์˜ ์ฒซ๋ฒˆ์งธ input์—๋Š” send_func(์†ก๋ฅผ ์œ„ํ•œ ํ•จ์ˆ˜)์˜ ํ•จ์ˆ˜ํฌ์ธํ„ฐ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ณ  ๋‘๋ฒˆ์งธ input์—๋Š” process_func(์ˆ˜์‹ ์„ ์œ„ํ•œ ํ•จ์ˆ˜)์˜ ํ•จ์ˆ˜ํฌ์ธํ„ฐ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

void packet_init(void (*s_func)(unsigned char *data, unsigned int len),
		void (*p_func)(unsigned char *data, unsigned int len), int handler_num) {
	memset(&m_handler_states[handler_num], 0, sizeof(PACKET_STATE_t));
	m_handler_states[handler_num].send_func = s_func;
	m_handler_states[handler_num].process_func = p_func;

๊ทธ๋Ÿผ ์•ž์—์„œ UART ํ†ต์‹ ์˜ ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ณด๋ฉด packet_init ํ•จ์ˆ˜์˜ ์ฒซ๋ฒˆ์งธ input์œผ๋กœ ์ง€์ •ํ•œ send_packet ํ•จ์ˆ˜์˜ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

static void send_packet(unsigned char *data, unsigned int len) {
	if (uart_is_running) {
		sdWrite(&HW_UART_DEV, data, len);
	}
}

send_packet ํ•จ์ˆ˜๋Š” app_uartcomm.c ํŒŒ์ผ์•ˆ์— ์žˆ์œผ๋ฉฐ ๋‹จ์ˆœ์ด data์™€ data์˜ ๊ธธ์ด(len)๋ฅผ ์•Œ๋ฉด ์ด๋ฅผ UART ํ†ต์‹ ์œผ๋กœ ์ „์†กํ•˜๋Š” ์ž„๋ฌด๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

packet_init ํ•จ์ˆ˜์˜ ๋‘๋ฒˆ์งธ input์ธ process_packet ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. process_packet ํ•จ์ˆ˜๋„ app_uartcomm.c ํŒŒ์ผ์•ˆ์— ์žˆ์œผ๋ฉฐ data์™€ data์˜ ๊ธธ์ด(len)์„ commands_process_packet ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๋„๋ก ๋˜์–ด์žˆ์œผ๋ฉฐ commands_process_packet ํ•จ์ˆ˜๋Š” commands.c ํŒŒ์ผ์— ์ž‘์„ฑ๋˜์–ด ์žˆ๋‹ค.

static void process_packet(unsigned char *data, unsigned int len) {
	commands_process_packet(data, len, app_uartcomm_send_packet);
}

์—ฌ๊ธฐ์„œ commands_process_packet ํ•จ์ˆ˜์˜ ์„ธ๋ฒˆ์งธ input์œผ๋กœ ์ง€์ •๋œ app_uartcomm_send_packet ํ•จ์ˆ˜๋Š” ์ผ๋ช… reply ํ•จ์ˆ˜๋กœ UARTํ†ต์‹ ์„ ํ†ตํ•ด ์—ฐ๊ฒฐ๋œ ์žฅ์น˜์—์„œ ์ „๋‹ฌํ•œ ๋ช…๋ น์— ๋Œ€ํ•œ ๋‹ต๋ณ€์„ ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์•ž์—์„œ send_packet ํ•จ์ˆ˜์™€ ๋‹ค๋ฅธ ์ ์€ send_packet ํ•จ์ˆ˜๋Š” VESC ์ธก์—์„œ ๋จผ์ € ๋ฐ์ดํ„ฐ Packet์„ ์ „์†กํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์ด๊ณ  app_uartcomm_send_packet ํ•จ์ˆ˜๋Š” UARTํ†ต์‹ ์œผ๋กœ ์—ฐ๊ฒฐ๋œ ๋ฐ˜๋Œ€์ชฝ ์žฅ์น˜์—์„œ ๋จผ์ € ๋ฐ์ดํ„ฐ Packet์ด ์ „์†ก๋˜์–ด ์ด์— ๋Œ€ํ•œ ๋‹ต๋ณ€์„ ์œ„ํ•œ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

๊ทธ๋Ÿผ ์‹ค์งˆ์ ์œผ๋กœ Data์˜ ํ๋ฆ„์ด ์–ด๋–ป๊ฒŒ ์ด๋ค„์ง€๋Š”์ง€ ์ข€ ๋” ์ž์„ธํ•˜๊ฒŒ ์•Œ์•„๋ณด์ž

http://vedder.se/2015/08/vesc-writing-custom-applications/
http://vedder.se/2015/10/communicating-with-the-vesc-using-uart/