Skip to content

Commit

Permalink
Merge branch 'main' into dashboard-logs
Browse files Browse the repository at this point in the history
  • Loading branch information
Levi-Lesches authored Oct 30, 2024
2 parents 35af40e + 3c8e4a5 commit 87f3b1d
Show file tree
Hide file tree
Showing 31 changed files with 589 additions and 249 deletions.
9 changes: 4 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Setup Java
uses: actions/setup-java@v1
with:
java-version: '12.x'
java-version: '17'

- name: Load certificate
run: |
Expand All @@ -45,15 +45,14 @@ jobs:
dart analyze
dart run msix:create
# Temporarily removed because Android builds are broken
# - name: Build APK
# run: flutter build apk
- name: Build APK
run: flutter build apk

- name: Create Release
uses: softprops/[email protected]
with:
# build/app/outputs/apk/release/app-release.apk
files: |
build/app/outputs/apk/release/app-release.apk
build/windows/x64/runner/Release/Dashboard.msix
name: ${{ github.ref_name }}
generate_release_notes: true
Expand Down
Binary file removed SDL3.dll
Binary file not shown.
27 changes: 11 additions & 16 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
Expand All @@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
Expand All @@ -21,21 +22,19 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
namespace "com.example.dashboard"

compileSdkVersion 34
ndkVersion flutter.ndkVersion

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '17'
}

sourceSets {
Expand All @@ -61,7 +60,3 @@ android {
flutter {
source '../..'
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
13 changes: 0 additions & 13 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
buildscript {
ext.kotlin_version = '1.8.21'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

allprojects {
repositories {
google()
Expand Down
4 changes: 3 additions & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
30 changes: 22 additions & 8 deletions android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
include ':app'
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()

def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}

def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.4.2" apply false
id "org.jetbrains.kotlin.android" version "1.8.10" apply false
}

include ":app"
Binary file added assets/Rocks_Minerals_Images/Augite.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions lib/data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ export "src/data/settings.dart";
export "src/data/socket.dart";
export "src/data/taskbar_message.dart";
export "src/data/utils.dart";
export "src/data/view_preset.dart";
2 changes: 2 additions & 0 deletions lib/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export "src/models/view/builders/settings_builder.dart";
export "src/models/view/builders/throttle.dart";
export "src/models/view/builders/timer_builder.dart";
export "src/models/view/builders/video_builder.dart";
export "src/models/view/builders/preset_builder.dart";


/// A wrapper model around all other data models used by the app.
///
Expand Down
62 changes: 35 additions & 27 deletions lib/src/data/settings.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import "package:flutter/material.dart";
import "package:rover_dashboard/data.dart";

import "socket.dart";

/// A collection of functions for parsing [Settings].
/// A collection of functions for parsing [Settings].
extension SettingsParser on Json {
/// Parses a [SocketInfo] that may not be present.
SocketInfo? getSocket(String key) {
Expand All @@ -15,7 +14,7 @@ extension SettingsParser on Json {
/// Settings relating to science.
class ScienceSettings {
/// How many frames to render per second.
///
///
/// This does not affect how many frames are sent by the rover per second.
final bool scrollableGraphs;

Expand All @@ -26,7 +25,7 @@ class ScienceSettings {
const ScienceSettings({required this.scrollableGraphs, required this.numSamples});

/// Parses a [ScienceSettings] from JSON.
ScienceSettings.fromJson(Json? json) :
ScienceSettings.fromJson(Json? json) :
numSamples = json?["numSamples"] ?? 3,
scrollableGraphs = json?["scrollableGraphs"] ?? false;

Expand Down Expand Up @@ -76,7 +75,7 @@ class ArmSettings {
});

/// Parses arm settings from a JSON map.
ArmSettings.fromJson(Json? json) :
ArmSettings.fromJson(Json? json) :
shoulder = json?["shoulder"] ?? 0.005,
elbow = json?["elbow"] ?? 0.005,
swivel = json?["swivel"] ?? 0.2,
Expand All @@ -102,8 +101,8 @@ class ArmSettings {
/// Settings related to network configuration.
class NetworkSettings {
/// The amount of time, in seconds, the dashboard should wait before determining it's
/// lost connection to the rover. For reference, the rover should be sending messages
/// at least once per second.
/// lost connection to the rover. For reference, the rover should be sending messages
/// at least once per second.
final double connectionTimeout;

/// The address and port of the subsystems program.
Expand All @@ -116,7 +115,7 @@ class NetworkSettings {
final SocketInfo autonomySocket;

/// The address of the tank. The port is ignored.
///
///
/// The Tank is a model rover that has all the same programs as the rover. This field does not
/// include port numbers because ports are specific to the program, and the tank will have many
/// programs running. Instead, the IP address of all the other programs should be swapped with
Expand All @@ -133,7 +132,7 @@ class NetworkSettings {
});

/// Parses network settings from a JSON map.
NetworkSettings.fromJson(Json? json) :
NetworkSettings.fromJson(Json? json) :
subsystemsSocket = json?.getSocket("subsystemsSocket") ?? SocketInfo.raw("192.168.1.20", 8001),
videoSocket = json?.getSocket("videoSocket") ?? SocketInfo.raw("192.168.1.30", 8002),
autonomySocket = json?.getSocket("autonomySocket") ?? SocketInfo.raw("192.168.1.30", 8003),
Expand All @@ -151,7 +150,7 @@ class NetworkSettings {
}

/// Settings relating to easter eggs.
///
///
/// Implement these! Ask Levi for details.
class EasterEggsSettings {
/// Whether to do a SEGA-like intro during boot.
Expand All @@ -161,7 +160,7 @@ class EasterEggsSettings {
/// Whether clippy should appear by log messages.
final bool enableClippy;
/// Whether to render Bad Apple in the Map page.
final bool badApple;
final bool badApple;

/// A const constructor.
const EasterEggsSettings({
Expand All @@ -172,7 +171,7 @@ class EasterEggsSettings {
});

/// Parses easter eggs settings from JSON.
EasterEggsSettings.fromJson(Json? json) :
EasterEggsSettings.fromJson(Json? json) :
segaIntro = json?["segaIntro"] ?? true,
segaSound = json?["segaSound"] ?? true,
enableClippy = json?["enableClippy"] ?? true,
Expand All @@ -191,9 +190,9 @@ class EasterEggsSettings {
enum SplitMode {
/// Two views are split horizontally, one atop the other.
horizontal("Top and bottom"),
/// Two views are split vertically, side-by-side.
/// Two views are split vertically, side-by-side.
vertical("Side by side");

/// The name to show in the UI.
final String humanName;
/// A const constructor.
Expand All @@ -216,37 +215,41 @@ class DashboardSettings {
final SplitMode splitMode;

/// The precision of the GPS grid.
///
///
/// Since GPS coordinates are decimal values, we divide by this value to get the index of the cell
/// each coordinate belongs to. Smaller sizes means more blocks, but we should be careful that the
/// blocks are big enough to the margin of error of our GPS. This value must be synced with the
/// value in the autonomy program, or else the UI will not be accurate to the rover's logic.
final double mapBlockSize;

/// How many frames to render per second.
///
///
/// This does not affect how many frames are sent by the rover per second.
final int maxFps;

/// The theme of the Dashboard.
/// The theme of the Dashboard.
final ThemeMode themeMode;

/// Whether to split cameras into their own controls.
///
/// Whether to split cameras into their own controls.
///
/// When this is disabled, some other modes, like arm or drive, may move the cameras.
/// When this is enabled, only the dedicated camera control mode can move the cameras.
final bool splitCameras;

/// Whether to default to tank drive controls.
///
///
/// Tank controls offer more custom control, but modern drive controls are more intuitive.
final bool preferTankControls;

/// Whether to have version checking on protobuf messages.
final bool versionChecking;

/// A list of ViewPresets
final List<ViewPreset> presets;

/// A const constructor.
const DashboardSettings({
required this.presets,
required this.splitMode,
required this.mapBlockSize,
required this.maxFps,
Expand All @@ -256,8 +259,12 @@ class DashboardSettings {
required this.versionChecking,
});

/// Parses Dashboard settings from JSON.
DashboardSettings.fromJson(Json? json) :
/// Parses settings from JSON.
DashboardSettings.fromJson(Json? json) :
presets = [
for (final presetJson in json?["presets"] ?? [])
ViewPreset.fromJson(presetJson),
],
splitMode = SplitMode.values[json?["splitMode"] ?? SplitMode.horizontal.index],
mapBlockSize = json?["mapBlockSize"] ?? 1.0,
maxFps = (json?["maxFps"] ?? 60) as int,
Expand All @@ -268,6 +275,7 @@ class DashboardSettings {

/// Serializes these settings to JSON.
Json toJson() => {
"presets" : presets,
"splitMode": splitMode.index,
"mapBlockSize": mapBlockSize,
"maxFps": maxFps,
Expand All @@ -278,13 +286,13 @@ class DashboardSettings {
};
}

/// Contains the settings for running the dashboard and the rover.
/// Contains the settings for running the dashboard and the rover.
class Settings {
/// Settings for the network, like IP addresses and ports.
final NetworkSettings network;

/// Settings for easter eggs.
///
///
/// Please, please, please -- do not remove these (Levi Lesches, '25).
final EasterEggsSettings easterEggs;

Expand All @@ -307,15 +315,15 @@ class Settings {
});

/// Initialize settings from Json.
Settings.fromJson(Json json) :
Settings.fromJson(Json json) :
network = NetworkSettings.fromJson(json["network"]),
easterEggs = EasterEggsSettings.fromJson(json["easterEggs"]),
science = ScienceSettings.fromJson(json["science"]),
arm = ArmSettings.fromJson(json["arm"]),
dashboard = DashboardSettings.fromJson(json["dashboard"]);

/// Converts the data from the settings instance to Json.
Json toJson() => {
Json toJson() => {
"network": network.toJson(),
"easterEggs": easterEggs.toJson(),
"science": science.toJson(),
Expand Down
Loading

0 comments on commit 87f3b1d

Please sign in to comment.