To have the best view of this document, download Typora, the best Markdown editor ever
PTE24 UART4_RX (BT) -> UiProtocol PTE25 UART4_TX (BT) -> UiProtocol
PTB10 UART3_RX (UART) -> Protocol PTB11 UART3_TX (UART) -> Protocol
PTB16 UART0_RX (GPIO1) -> OpenMV1 PTB17 UART0_TX (GPIO2) -> OpenMV1
PTD2 UART1_RX (SOUT) -> OpenMV2 PTD3 UART1_TX (SIN) -> OpenMV2
graph TD;
id1[Encoders and motors]
wheelbase-->|contains|id1
wheelbase-->|contains|protocol
wheelbase-->|contains|uiprotocol
protocol-->|contains|wheelbase
uiprotocol-->|contains|wheelbase
wheelbase-->|contains|scheduler
protocol-->|contains|bluetooth
uiprotocol-->|contains|bluetooth
scheduler-->|used by|bluetooth
bluetooth-->|extends|comm
Global Origin at top left corner of game field, unit mm (integer), x-axis right going, y axis down going. Global rotational angle defined by x-axis to y-axis direction, in radian(float)
//Package Anotations
HEAD = 0xAA,
END = 0xFF,
//Package Types
kACK = 0x00,
kRequestSetMotor = 0x01,
kRequestEncoder = 0x02,
kResponseEncoder = 0x03,
kRequestMove = 0x04,
kRequestSetMotorById = 0x05,
kRequestEncoderById = 0x06,
kResponseEncoderById = 0x07,
kRequestEncoders = 0x08,
kResponseEncoders = 0x09,
kFeedGlobalRotation = 0x0A,
kFeedGlobalTranslation = 0x0B,
kRequestSetServo = 0x0C,
kRequestAutoFeedEncoders = 0x0D,
kRequestAutoFeedEncodersById = 0x0E,
kFeedCorners = 0xA0,
kFeedLocalRotation = 0xA1,
kFeedLocalTranslation = 0xA2
|HEAD|LENGTH|PACKAGE_TYPE|PACKAGE_ID|DATA|...|CHECKSUM|END|
where:
HEAD = 0xAA
LENGTH = length of whole package including header and end
PACKAGE_TYPE = package Type, determine the function of package
PACKAGE_ID = unique id of package over a machine, for ACK packages
CHECKSUM = sum of all bytes in package mod 256
END = 0xFF
Master: the tempory camera17 coard
Slave: the tempory balance17 board
Super: the UI/ OpenMV/ other high level instances...
OpenMV
Ui
- the
sendPackageImmediatefunction send the package only once and will not take care the acknowledge - the
queuePackagefunction will keep sending the package until corresponding acknowledgement is received. It is done by pushing the package to a queue, peroidfunction will callsendPackageImmediatefunction for each package inside the queue, which should be done periodicallylistenfunction will parse the incoming bytes from RxbuildBufferPackageconvert byte array to packagepackageHandleris called when package is built.- If the package is not an acknowledgement package, it will send an acknowledgement package for that;
- if the package is an acknowledgement package, it will remove corresponding package from queue
int16_t motorpower (PWM)
<none>
Master -> Slave: kRequestSetMotor(Power)
Slave -> Master: kACK
Note over Slave: motor0 setpower
<none>
int32_t encoder_count (accumunative, from kResponseEncoder Type)
if calling await version will halt the master until recieve the count
Master->Slave: kRequestEncoder
Slave->Master: kACK
Note over Slave: get encoder0 count
Slave->Master: kResponseEncoder(count)
Master->Slave: kACK
int16_t x_speed (TBC)
int16_t y_speed (TBC)
<none>
Super->Master: kRequestMove(x,y)
Master->Super: kACK
Note over Master: Set Moter0, Motor1
Master->Slave: kRequestSetMotor(power)
Slave->Master: kACK
Note over Slave: Set Motor0
uin8_t id
<none>
Super->Master: kRequestSetMotorById(id, power)
Master->Super: kACK
Note over Master: if id<2: Set Motor by id
Note over Master: if id==2: request slave
Master-->Slave: kRequestSetMotor(power)
Slave-->Master: kACK
uint8_t id
int32_t count
Super->Master: kRequestEncoderById(id)
Master->Super: kACK
Note over Master: if id<2: Get Encoder
Note over Master: if id==2: Request Encoder
Master-->Slave: kRequestEncoder
Slave-->Master: kACK
Note over Slave: encoder0 get count
Slave-->Master: kResponseEncoder(count)
Master-->Slave: kACK
Master->Super: kResponseEncoderById(id, count)
Super->Master: kACK
none
int32_t encoder0_count, encoder1_count, encoder2_count
Super->Master: kRequestEncoders
Master->Super: kACK
Note over Master: Encoder0,1 Get Count
Master->Slave: kRequestEncoder
Slave->Master: kACK
Note over Slave: encoder0 get count
Slave->Master: kResponseEncoder(count)
Master->Slave: kACK
Master->Super: kResponseEncoders(count0, count1, count2)
Super->Master: kACK
float rotation angle
uint16_t lapse (time_spent_on_calculation)
uint16_t frame_id
none
Note over Super: new frame
Super->Master: kFeedGlobalRotation(angle,time)
Master->Super: kACK
int32_t x_translation, y_translation
uint16_t lapse (time_spent_on_calculation)
uint16_t frame_id
none
Note over Super: new frame
Super->Master: kFeedTranslation
Master->Super: kACK
uint16_t frame_id
uint8_t chunk_id (the buffer length should be limited below 100)
uint16_t[] x0, y0, x1, y1, ...
<none>
Note over OpenMV: on frame
OpenMV -> Ui: kFeedCorners(frame_id, chunk_id ...)
OpenMV -> Ui: kFeedCorners(frame_id, chunk_id ...)
Ui -> OpenMV: kACK
Ui -> OpenMV: kACK
uint16_t servo degree (PWM)
<none>
Master -> Slave: kRequestSetServo(Degree)
Slave -> Master: kACK
Note over Slave: servo0 set degree
float rotation angle
uint16_t lapse (time_spent_on_calculation)
uint16_t frame_id
none
Note over Super: new frame
Super->Master: kFeedLocalRotation(angle,time,frame_id)
Master->Super: kACK
uint16_t interval in ms for checking encoders, send when encoder value is changed, 0 for canceling the auto feed. If an auto feed is already started in the protocol, it will overwrite the original one
none
Ui->Master: kRequestAutoFeedEncoders(interval)
Master->Ui: kACK
Note over Master: (general behavior of this protocol)
Master->Slave: kRequestAutoFeedEncoders(interval)
Slave->Master: kACK
Note over Slave: For each interval encoder value changed
Slave->Master: kResponseEncoder(count)
Master->Slave: kACK
Title: general behavior
Any -> k60: kRequestAutoFeedEncoders(interval)
Note over k60: For every interval
Note over k60: If encoder[k] got changed
k60 -> Any: kResponseEncodersById(k,accunumate count)
Any->k60: kACK
int32_t x_translation, y_translation
uint16_t lapse (time_spent_on_calculation)
uint16_t frame_id
none
Note over OpenMV: new frame
OpenMV->Ui: kFeedLocalTranslation
Ui->OpenMV: kACK
uint8_t id
uint16_t interval in ms for checking encoders, send when encoder value is changed, 0 for canceling the auto feed. If an auto feed is already started in the protocol, it will overwrite the original one
none