Skip to content
This repository has been archived by the owner on Jul 1, 2018. It is now read-only.

Controller support for the config port #245

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
344 changes: 344 additions & 0 deletions angel-player/src/chrome/content/common_defs/radio_protocol_ng.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,344 @@
- name: uint8_t
repr: unsigned
kind: alien
size: 1
- name: uint16_t
repr: unsigned
kind: alien
size: 2
- name: uint32_t
repr: unsigned
kind: alien
size: 4
- name: uint64_t
repr: unsigned
kind: alien
size: 8

# Radio needs to transmit the following:

# Robot Host
# ---------------------------------------------------
# Telemetry →
# Control signals ←
# Code ←
# Bulk state →
# Debug <->
# Sensor probing <->



# NDL3 ports:
# NDL3_UBJSON_PORT
# Reliable, structured UBJSON data
# Usage:
# Debug
# NDL3_STRING_PORT
# Reliable, unstructured data
# Usage:
# stdout
# stdin?
# NDL3_CODE_PORT
# Reliable, structured binary data
# Usage:
# Code
# Bulk state?
# NDL3_CONFIG_PORT
# Reliable, structured binary data
# Usage:
# start/stop VM
# patch?
# device probing
# NDL3_FAST_PORT
# Unreliable, structured UBJSON data
# Usage:
# Telemetry
# Controls




# UBJSON (reliable) port:
# const TYPE_MEMOIZE_CLEAR 0x00
# const TYPE_MEMOIZE_STRING 0x01
- name: TYPE_MEMOIZE_CLEAR
kind: const
value: 0x00
- name: TYPE_MEMOIZE_STRING
kind: const
value: 0x01

# [
# 123, // type
# { // Only for TYPE_MEMOIZE_STRING
# 123: “str” // Memoize the string “str” with id 123
# …
# }
# ]

# String port:
# Raw, unencapsulated strings for stdin/stdout

# Code port:
# #define ID_SEND_CODE_BLOB 0x00
- name: ID_SEND_CODE_BLOB
kind: const
value: 0x00
# #define ID_GET_TRACE_BLOB 0x01
- name: ID_GET_TRACE_BLOB
kind: const
value: 0x01
- name: code_port
kind: struct
packed: true
slots:
- name: id
type: uint8_t
- name: len
type: uint32_t
- name: data
type: uint8_t[]
# struct code_port (packed) {
# uint8_t id
# uint32_t len
# uint8_t[] data
# }

# Config port:
# #define ID_START_VM
- name: ID_START_VM
kind: const
value: 0x00
# #define ID_STOP_VM
- name: ID_STOP_VM
kind: const
value: 0x01
# #define ID_LOAD_MAIN_THREAD 0x02
- name: ID_LOAD_MAIN_THREAD
kind: const
value: 0x02
# #define ID_CONTROL_UNFREEZE 0x10
- name: ID_CONTROL_UNFREEZE
kind: const
value: 0x10
# #define ID_CONTROL_STOP 0x11
- name: ID_CONTROL_STOP
kind: const
value: 0x11
# #define ID_CONTROL_UNPOWERED 0x12
- name: ID_CONTROL_UNPOWERED
kind: const
value: 0x12
# #define ID_CONTROL_SET_AUTON 0x13
- name: ID_CONTROL_SET_AUTON
kind: const
value: 0x13
# #define ID_CONTROL_SET_TELEOP 0x14
- name: ID_CONTROL_SET_TELEOP
kind: const
value: 0x14
# #define ID_DEVICE_GET_LIST 0x20
- name: ID_DEVICE_GET_LIST
kind: const
value: 0x20
# #define ID_DEVICE_READ_DESCRIPTOR 0x21
- name: ID_DEVICE_READ_DESCRIPTOR
kind: const
value: 0x21
# #define ID_DEVICE_ENABLE_BLINK 0x22
- name: ID_DEVICE_ENABLE_BLINK
kind: const
value: 0x22

- name: device_list_t
kind: struct
packed: true
slots:
- name: count
type: uint32_t
- name: dids
type: uint16_t[]

- name: device_read_descriptor_req_t
kind: struct
packed: true
slots:
- name: did
type: uint64_t
- name: start
type: uint16_t
- name: len
type: uint16_t

- name: LENGTH_AT_LEAST_ONE
kind: const
value: 0x01

- name: device_read_descriptor_resp_t
kind: struct
packed: true
slots:
- name: did
type: uint64_t
- name: data
type: uint8_t[LENGTH_AT_LEAST_ONE]

- name: device_blink_t
kind: struct
packed: true
slots:
- name: did
type: uint64_t
- name: blink_on
type: uint8_t

- name: config_port_data
kind: union
slots:
- name: device_list
type: device_list_t
- name: device_read_descriptor_req
type: device_read_descriptor_req_t
- name: device_read_descriptor_resp
type: device_read_descriptor_resp_t
- name: device_blink
type: device_blink_t
- name: nothing
type: uint8_t


- name: config_port
kind: struct
packed: true
slots:
- name: id
type: uint8_t
- name: data
type: config_port_data
# struct config_port (packed) {
# uint8_t id
# union {
# struct device_list {
# uint32_t count
# uint64_t[] dids
# }
# struct device_read_descriptor_req {
# uint64_t did
# uint16_t start
# uint16_t len
# }
# struct device_read_descriptor_resp {
# uint8_t[] data
# }
# struct device_blink {
# uint8_t blink_on
# uint64_t did
# }
# }
# }

# Fast port:
# const TYPE_JOY_DATA 0x00
# const TYPE_TELEM_DATA 0x01
- name: TYPE_JOY_DATA
kind: const
value: 0x00
- name: TYPE_TELEM_DATA
kind: const
value: 0x01

# [
# nnn, // type
# {
# 123: [1,0,1,…] // Telemetry or joystick, can be repeated
# } // 123 = memoized string
# // array = samples (for telemetry)
# // channel (for joystick)
# ]

















# More detailed brain dumps:

# Notes on UBJSON
# UBJSON is only available to Lua. Any state that needs to be available to C cannot be sent via UBJSON (easily). Any data from UBJSON can be condidered “untrusted” (not resistant against tampering from within studencode)
# String memoization
# The purpose of string memoization is to reduce the number of bytes that need to be sent repeatedly. For example, suppose there was a string “joy0-analog” that needed to be sent in every joystick packet. This takes up 11 bytes in every telemetry packet that conveys no additional information after the first time. String memoization solves this by having the host send a unique number and the string to the controller once at the beginning. The string will then be replaced by this number, which will usually take only 1 byte.
# The host can memoize strings sent to the controller. The controller can also send back a TYPE_MEMOIZE_STRING back to the host for e.g. telemetry. IDs may overlap between the two.
# TYPE_MEMOIZE_CLEAR clears both directions
# String port
# This port is directly mapped to stdio. No encapsulation
# printf() from robot appears here
# data written to this port should be made available via scanf, etc.
# Code/trace
# Code is always host-->robot
# Trace is always robot-->host
# Code is not run immediately. Running the code is controlled by the config port.
# How to trigger trace is TBD
# Config
# The majority of host “controlling” the robot happens here. This includes field control logic.
# VM state control
# The host can completely stop execution of any studentcode by sending a stop command. This tears down the VM and frees all of the associated state.
# Start will cause a VM to be created. Standard libraries will be loaded but no studentcode will be.
# Load main thread is used to load the studentcode. The studentcode must have been sent earlier using the code port.
# Replacing the studentcode should work. This needs to be worked out on the runtime dide. Loading studentcode when there is already a studentcode should tear down the student-controlled parts of the VM without rebooting the entire VM.
# Patching will be controlled here. Exact behavior TBD.
# Field control logic
# Field control logic is here (rather than e.g. a UBJSON port) so that it is impossible for students to cheat it.
# There are three stop/run states (unfreeze, stop, unpowered) because of corner-cases with e.g. servos. There are extensive notes on this elsewhere.
# Autonomous and teleop are needed by the C code to block access to the joystick (PiER never did this). It will also be exposed to Lua
# Smartdevice logic
# Smartdevices will be enumerated by the firmware at TBD time. The host can request a list of devices using the get list command. This will return a list of smart device UUIDs.
# The firmware will automatically handle bw allocation and most of the details of communicating with devices. The UI needs to handle human-readable descriptors and binding devices to meaningful names.
# The UI can get descriptions of the devices by reading the descriptor information. See smartdevice spec.
# In order to help identify devices that are already mounted on the robot, the UI can command the LED on the smartdevice to blink.
# Joystick
# Joystick packets contain a number of channels that each contain a number of values. Each individual value can be referred to as <channel name>-<value number>
# For the Xbox 360 joystick, there would be 2 channels: button, analog with 11 and 8 values
# Multiple joysticks can be sent in the same packet
# Telemetry
# Telemetry contains channels that can contain 1 or more samples
# Behavior very similar to joysticks
# Telemetry is batched up and sent at intervals













# Sample exchanges (PC <--> robot);
# config port: 0x01 → (stop VM, reset (almost) all state)
# config port: 0x20 → (get device list)
# config port: ← 0x20 0x01 0x00 0x00 0x00 0xAA 0xBB 0xCC 0xDD 0xEE 0xFF 0x00 0x01
# config port: 0x21 [0xAA … 0x01] 0x00 0x00 0x02 0x00 → (read descriptor length)
# config port: ← 0x21 0x55 0x00
# config port: 0x21 [0xAA … 0x01] 0x00 0x00 0x55 0x00 → (read entire descriptor)
# config port: ← 0x21 …
# config port: 0x00 → (start VM)
# code port: 0x00 0x23 0x01 0xXX 0xXX … → (buffer code)
# config port: 0x02 → (load code into main thread)
# ubjson reliable: [1, {0: “joy0-analog”, 1: “joy0-button”}] → (memoize string)
# config port: 0x10 → (unfreeze)
# ubjson fast: [0, 0: [1,1,0.5, …], 1: [true, false, …]] → (joystick)
# ...
8 changes: 8 additions & 0 deletions controller/inc/radio.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,18 @@

#include "inc/FreeRTOS.h"

#include "radio_protocol_ng.h" // NOLINT(build/include)


BaseType_t radioInit();

// Do not modify or release the data after calling these.
// The radio takes ownership of releasing the memeory.
void radioPushUbjson(const char *ubjson, size_t len);
void radioPushString(const char *str, size_t len);
void radioPushBulk(const code_port *data, size_t len);
void radioPushConfig(const config_port *data, size_t len);
void radioPushFast(const char *ubjson, size_t len);


#endif // INC_RADIO_H_
28 changes: 28 additions & 0 deletions controller/inc/radio_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Licensed to Pioneers in Engineering under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. Pioneers in Engineering licenses
// this file to you 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 INC_RADIO_CONFIG_H_
#define INC_RADIO_CONFIG_H_

#include "inc/FreeRTOS.h"
#include "inc/radio.h"
#include "inc/smartsensor/ssutil.h"
#include "radio_protocol_ng.h" // NOLINT(build/include)

BaseType_t radioConfigInit();
void receiveConfigPort(config_port *port, size_t len);
#endif // INC_RADIO_CONFIG_H_
Loading