-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration Guide
Comprehensive configuration guide for the Hyperloop UPV Control Station system, covering all aspects from basic setup to advanced customization.
This guide provides detailed instructions for configuring every aspect of the Control Station system, including backend services, frontend applications, network settings, and hardware integration.
System Configuration
โโโ Backend Configuration (config.toml)
โโโ ADJ Specifications (JSON files)
โโโ Network Configuration (IP, routing, VLANs)
โโโ Frontend Configuration (environment variables)
โโโ Hardware Configuration (boards, sensors)
โโโ Security Configuration (certificates, keys)
The primary configuration file is located at backend/cmd/config.toml
:
# =============================================================================
# Hyperloop UPV Control Station Configuration
# =============================================================================
# Network Configuration
[network]
# Your machine's IP address (must match ADJ specification)
backend_ip = "192.168.0.9"
backend_port = 8080
# Enable network propagation of faults
[transport]
# Propagate faults across the network
propagate_fault = true
# Network interface for packet capture
interface = "eth0" # Linux: eth0, macOS: en0, Windows: "Local Area Connection"
# TCP timeout settings
tcp_timeout = "30s"
tcp_keepalive = "10s"
# Board Configuration
[vehicle.boards]
# Enable/disable individual boards
VCU = true # Vehicle Control Unit
PCU = true # Propulsion Control Unit
TCU = true # Thermal Control Unit
LCU = true # Levitation Control Unit
BCU = true # Brake Control Unit
BLCU = true # Boot Loader Control Unit
BMSL = true # Battery Management System Left
BMSR = true # Battery Management System Right
OBCCU = true # On-Board Computer Control Unit
# ADJ (Board Specification) Configuration
[adj]
# Git branch to use for board specifications
# Leave blank to use local ADJ files
branch = "main"
# Automatically update ADJ from git
auto_update = true
# Test mode (use mock data instead of real hardware)
test = false
# ADJ repository URL (if using remote ADJ)
repository = "https://github.com/HyperloopUPV-H8/software-adj.git"
# Local path for ADJ files
local_path = "./adj"
# HTTP Server Configuration
[server.control-station]
# Server address and port
addr = "0.0.0.0:8080"
# API endpoints
endpoints.pod_data = "/api/pod-data"
endpoints.order_data = "/api/order-data"
endpoints.connections = "/ws"
endpoints.files = "/static"
# Static file serving
static_path = "../control-station/dist"
# CORS settings
cors.allowed_origins = ["http://localhost:5173", "http://localhost:3000"]
cors.allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
cors.allowed_headers = ["*"]
[server.ethernet-view]
# Ethernet view server configuration
addr = "0.0.0.0:8081"
# API endpoints
endpoints.pod_data = "/api/pod-data"
endpoints.order_data = "/api/order-data"
endpoints.connections = "/ws"
endpoints.files = "/static"
# Static file serving
static_path = "../ethernet-view/dist"
# Data Logging Configuration
[logging]
# Enable/disable different log types
enable_data_logger = true
enable_order_logger = true
enable_protection_logger = true
enable_state_logger = true
# Log file configuration
data_log_path = "./logs/data"
order_log_path = "./logs/orders"
protection_log_path = "./logs/protection"
state_log_path = "./logs/state"
# Log rotation settings
max_file_size = "100MB"
max_files = 30
compress_old_files = true
# CSV format settings
csv_delimiter = ","
csv_timestamp_format = "2006-01-02 15:04:05.000"
# WebSocket Configuration
[websocket]
# Maximum number of concurrent connections
max_connections = 100
# Message buffer size
buffer_size = 1024
# Ping/pong interval for connection health
ping_interval = "30s"
pong_timeout = "10s"
# Security Configuration
[security]
# Enable HTTPS (requires certificates)
enable_tls = false
cert_file = "./certs/server.crt"
key_file = "./certs/server.key"
# API rate limiting
rate_limit_enabled = true
rate_limit_requests = 100
rate_limit_window = "1m"
# Development Configuration
[development]
# Enable development mode features
debug_mode = false
hot_reload = false
verbose_logging = false
# Mock data for testing
use_mock_data = false
mock_data_interval = "100ms"
# Profiling
enable_profiling = false
profiling_port = 6060
# config.dev.toml
[adj]
test = true
use_mock_data = true
[development]
debug_mode = true
verbose_logging = true
enable_profiling = true
[websocket]
max_connections = 10
# config.prod.toml
[security]
enable_tls = true
rate_limit_enabled = true
[logging]
compress_old_files = true
max_files = 90
[websocket]
max_connections = 50
# config.test.toml
[adj]
test = true
branch = "test"
[network]
backend_port = 8081
[logging]
enable_data_logger = false
ADJ (Board Specification) files define the hardware configuration:
adj/
โโโ boards/
โ โโโ VCU/
โ โ โโโ board.json # Board definition
โ โ โโโ packets/
โ โ โ โโโ data.json # Data packet specifications
โ โ โ โโโ state.json # State packet specifications
โ โ โโโ orders/
โ โ โโโ brake.json # Brake command orders
โ โ โโโ emergency.json # Emergency orders
โ โโโ PCU/
โ โโโ TCU/
โ โโโ ...
โโโ measurements/
โ โโโ speed.json # Speed measurement definition
โ โโโ temperature.json # Temperature measurement definition
โ โโโ ...
โโโ info.json # Global configuration
{
"name": "VCU",
"id": 1,
"address": "192.168.1.101",
"description": "Vehicle Control Unit - Main vehicle coordination",
"version": "1.2.0",
"manufacturer": "Hyperloop UPV",
"communication": {
"protocol": "TCP",
"port": 8080,
"timeout": 5000,
"retries": 3
},
"capabilities": [
"sensor_data",
"motor_control",
"emergency_brake",
"status_reporting"
],
"packets": [
{
"id": 256,
"name": "speed_data",
"description": "Vehicle speed and acceleration data",
"frequency": 100,
"measurements": ["speed", "acceleration", "distance"]
},
{
"id": 257,
"name": "motor_status",
"description": "Motor controller status",
"frequency": 50,
"measurements": ["motor_rpm", "motor_current", "motor_temperature"]
}
],
"orders": [
{
"id": 512,
"name": "emergency_brake",
"description": "Emergency brake activation",
"priority": "critical",
"fields": [
{
"name": "brake_force",
"type": "float",
"range": [0.0, 100.0],
"unit": "percent"
}
]
},
{
"id": 513,
"name": "set_speed_limit",
"description": "Set maximum allowed speed",
"priority": "normal",
"fields": [
{
"name": "max_speed",
"type": "float",
"range": [0.0, 150.0],
"unit": "m/s"
}
]
}
]
}
// measurements/speed.json
{
"name": "speed",
"description": "Vehicle velocity measurement",
"unit": "m/s",
"type": "float",
"range": {
"min": 0.0,
"max": 150.0
},
"precision": 0.1,
"safety_limits": {
"warning": 100.0,
"critical": 120.0
},
"calibration": {
"offset": 0.0,
"scale": 1.0,
"formula": "raw * scale + offset"
},
"validation": {
"required": true,
"rate_limit": "10Hz",
"change_limit": "5.0/s"
}
}
// boards/VCU/packets/data.json
{
"id": 256,
"name": "vcu_data_packet",
"description": "Primary VCU data transmission",
"size": 64,
"frequency": 100,
"priority": "high",
"format": {
"header": {
"size": 8,
"fields": [
{"name": "packet_id", "size": 2, "type": "uint16"},
{"name": "timestamp", "size": 4, "type": "uint32"},
{"name": "sequence", "size": 2, "type": "uint16"}
]
},
"payload": {
"size": 48,
"measurements": [
{
"name": "speed",
"offset": 0,
"size": 4,
"type": "float32"
},
{
"name": "acceleration",
"offset": 4,
"size": 4,
"type": "float32"
},
{
"name": "motor_rpm",
"offset": 8,
"size": 4,
"type": "float32"
}
]
},
"checksum": {
"size": 8,
"algorithm": "CRC32"
}
}
}
Windows:
# Set static IP via PowerShell
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.0.9 -PrefixLength 24 -DefaultGateway 192.168.0.1
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 8.8.8.8,8.8.4.4
macOS:
# Set static IP via command line
sudo networksetup -setmanual "Ethernet" 192.168.0.9 255.255.255.0 192.168.0.1
sudo networksetup -setdnsservers "Ethernet" 8.8.8.8 8.8.4.4
Linux:
# Using netplan (Ubuntu 18.04+)
sudo tee /etc/netplan/01-hyperloop.yaml << EOF
network:
version: 2
ethernets:
enp0s3: # Replace with your interface name
dhcp4: false
addresses:
- 192.168.0.9/24
gateway4: 192.168.0.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
EOF
sudo netplan apply
# Detect network interfaces automatically
# Linux
ip link show | grep -E '^[0-9]+:' | awk -F': ' '{print $2}'
# macOS
networksetup -listallhardwareports
# Windows
Get-NetAdapter | Select-Object Name, InterfaceDescription
# Allow backend server
New-NetFirewallRule -DisplayName "Hyperloop Backend" -Direction Inbound -Port 8080 -Protocol TCP -Action Allow
New-NetFirewallRule -DisplayName "Hyperloop Ethernet View" -Direction Inbound -Port 8081 -Protocol TCP -Action Allow
# Allow WebSocket connections
New-NetFirewallRule -DisplayName "Hyperloop WebSocket" -Direction Inbound -Port 8080 -Protocol TCP -Action Allow
# Allow required ports
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8081 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 69 -j ACCEPT # TFTP
# Save rules
sudo iptables-save > /etc/iptables/rules.v4
# Create pf rule file
sudo tee /etc/pf.anchors/hyperloop << EOF
pass in proto tcp from any to any port 8080
pass in proto tcp from any to any port 8081
pass in proto udp from any to any port 69
EOF
# Load rules
sudo pfctl -f /etc/pf.anchors/hyperloop
# .env.development
VITE_API_BASE_URL=http://localhost:8080
VITE_WS_URL=ws://localhost:8080/ws
VITE_ENVIRONMENT=development
VITE_DEBUG_MODE=true
VITE_MOCK_DATA=false
# .env.production
VITE_API_BASE_URL=http://192.168.0.9:8080
VITE_WS_URL=ws://192.168.0.9:8080/ws
VITE_ENVIRONMENT=production
VITE_DEBUG_MODE=false
VITE_MOCK_DATA=false
# .env.test
VITE_API_BASE_URL=http://localhost:8081
VITE_WS_URL=ws://localhost:8081/ws
VITE_ENVIRONMENT=test
VITE_DEBUG_MODE=true
VITE_MOCK_DATA=true
# .env
VITE_API_BASE_URL=http://localhost:8081
VITE_WS_URL=ws://localhost:8081/ws
VITE_PACKET_CAPTURE_ENABLED=true
VITE_NETWORK_INTERFACE=eth0
VITE_CAPTURE_FILTER="host 192.168.1.0/24"
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig(({ command, mode }) => {
const isProduction = mode === 'production';
return {
plugins: [react()],
// Development server configuration
server: {
host: '0.0.0.0',
port: 5173,
strictPort: true,
hmr: {
port: 5174,
},
},
// Build configuration
build: {
outDir: 'dist',
sourcemap: !isProduction,
minify: isProduction ? 'esbuild' : false,
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
charts: ['chart.js', 'react-chartjs-2'],
},
},
},
},
// Path resolution
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@common': path.resolve(__dirname, '../common-front/lib'),
},
},
// Environment variable prefix
envPrefix: 'VITE_',
// CSS configuration
css: {
modules: {
localsConvention: 'camelCase',
},
preprocessorOptions: {
scss: {
additionalData: `@import "@common/styles/colors.scss";`,
},
},
},
};
});
# Generate self-signed certificate for development
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes \
-subj "/C=ES/ST=Valencia/L=Valencia/O=Hyperloop UPV/CN=192.168.0.9"
# Move certificates to proper location
mkdir -p backend/cmd/certs
mv server.key server.crt backend/cmd/certs/
# config.toml
[security]
enable_tls = true
cert_file = "./certs/server.crt"
key_file = "./certs/server.key"
# TLS settings
tls_min_version = "1.2"
tls_cipher_suites = [
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
]
# config.toml
[security.api_keys]
# API keys for different access levels
admin = "admin_key_here"
operator = "operator_key_here"
readonly = "readonly_key_here"
# Key requirements
require_api_key = true
key_header = "X-API-Key"
# config.toml
[server.control-station.cors]
allowed_origins = [
"http://localhost:5173",
"http://192.168.0.9:5173",
"https://control.hyperloop-upv.com"
]
allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
allowed_headers = ["*"]
allow_credentials = true
max_age = 86400
# config.toml
[boards.VCU]
enabled = true
ip_address = "192.168.1.101"
port = 8080
protocol = "TCP"
timeout = "5s"
retries = 3
[boards.PCU]
enabled = true
ip_address = "192.168.1.102"
port = 8080
protocol = "TCP"
timeout = "5s"
retries = 3
[boards.BLCU]
enabled = true
ip_address = "192.168.1.103"
port = 69 # TFTP
protocol = "UDP"
timeout = "30s"
retries = 1
// calibration.json
{
"sensors": {
"speed_sensor": {
"offset": 0.0,
"scale": 1.0,
"filter": {
"type": "moving_average",
"window_size": 10
}
},
"temperature_sensor": {
"offset": -2.5,
"scale": 1.02,
"filter": {
"type": "kalman",
"process_noise": 0.1,
"measurement_noise": 0.5
}
}
}
}
# config.toml
[load_balancing]
enabled = true
algorithm = "round_robin" # round_robin, least_connections, ip_hash
[[load_balancing.backends]]
address = "192.168.0.9:8080"
weight = 100
health_check = "/health"
[[load_balancing.backends]]
address = "192.168.0.10:8080"
weight = 100
health_check = "/health"
# config.toml
[caching]
enabled = true
type = "redis" # memory, redis, memcached
ttl = "5m"
[caching.redis]
address = "localhost:6379"
password = ""
database = 0
pool_size = 10
# config.toml
[monitoring]
enabled = true
metrics_port = 9090
health_check_interval = "30s"
[monitoring.prometheus]
enabled = true
path = "/metrics"
[monitoring.jaeger]
enabled = false
endpoint = "http://localhost:14268/api/traces"
#!/bin/bash
# validate-config.sh
echo "=== Configuration Validation ==="
# Check config.toml syntax
echo "Checking config.toml syntax..."
if ! toml-test backend/cmd/config.toml; then
echo "โ config.toml has syntax errors"
exit 1
fi
# Check ADJ files
echo "Checking ADJ files..."
for file in $(find backend/cmd/adj -name "*.json"); do
if ! python -m json.tool "$file" > /dev/null; then
echo "โ Invalid JSON in $file"
exit 1
fi
done
# Check network configuration
echo "Checking network configuration..."
if ! ping -c 1 192.168.0.1 > /dev/null; then
echo "โ ๏ธ Cannot reach gateway 192.168.0.1"
fi
# Check required ports
for port in 8080 8081; do
if netstat -tlnp | grep ":$port " > /dev/null; then
echo "โ ๏ธ Port $port is already in use"
fi
done
echo "โ
Configuration validation complete"
// config_validator.go
func ValidateConfiguration(cfg *Config) error {
// Validate network settings
if !isValidIP(cfg.Network.BackendIP) {
return fmt.Errorf("invalid backend IP: %s", cfg.Network.BackendIP)
}
// Validate port ranges
if cfg.Network.BackendPort < 1024 || cfg.Network.BackendPort > 65535 {
return fmt.Errorf("invalid backend port: %d", cfg.Network.BackendPort)
}
// Validate board configuration
for name, board := range cfg.Boards {
if !board.Enabled {
continue
}
if !isValidIP(board.IPAddress) {
return fmt.Errorf("invalid IP for board %s: %s", name, board.IPAddress)
}
}
return nil
}
- Installation Guide - System installation
- System Architecture - Architecture overview
- Development Environment Setup - Development setup
- Common Issues - Troubleshooting
โ๏ธ Configuration Complete!
Your Hyperloop UPV Control Station is now properly configured for optimal performance, security, and reliability. Remember to backup your configuration files and test thoroughly in a development environment before deploying to production.