Skip to content

Commit

Permalink
Settings changes (#133)
Browse files Browse the repository at this point in the history
- Re-arranged settings in the settings page and data/file
- Moved throttle from the gamepad to a settings page popup
- Made views resizable
- Migrated all ProviderConsumers to ReactiveWidgets
- Removed unused packages
- Bumped version
- Implemented Manual, Idle, and Autonomy modes
- Simplified drive code
- Added Android controls
- Added reset button for resizable views
  • Loading branch information
Levi-Lesches authored Feb 16, 2024
1 parent 30855cc commit dbd1d27
Show file tree
Hide file tree
Showing 39 changed files with 1,339 additions and 1,167 deletions.
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion flutter.compileSdkVersion
compileSdkVersion 34
ndkVersion flutter.ndkVersion

compileOptions {
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
19 changes: 0 additions & 19 deletions build.yaml

This file was deleted.

67 changes: 26 additions & 41 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
library app;

import "package:flutter/material.dart";
import "package:provider/provider.dart";

import "package:rover_dashboard/models.dart";
import "package:rover_dashboard/pages.dart";

/// The classic Binghamton green.
Expand All @@ -18,43 +15,31 @@ const binghamtonGreen = Color(0xff005943);
/// The main class for the app.
class RoverControlDashboard extends StatelessWidget {
@override
Widget build(BuildContext context) => MultiProvider(
providers: [
ChangeNotifierProvider.value(value: models),
ChangeNotifierProvider.value(value: models.video),
ChangeNotifierProvider.value(value: models.home),
ChangeNotifierProvider.value(value: models.rover),
ChangeNotifierProvider.value(value: models.serial),
ChangeNotifierProvider.value(value: models.settings),
],
child: Consumer<Models>(
builder: (context, models, _) => MaterialApp(
title: "Binghamton University Rover Team",
home: SplashPage(),
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: false,
colorScheme: const ColorScheme.light(
primary: binghamtonGreen,
secondary: binghamtonGreen,
),
appBarTheme: const AppBarTheme(
backgroundColor: binghamtonGreen,
// titleTextStyle: TextStyle(color: Colors.white),
foregroundColor: Colors.white,
),
),
darkTheme: ThemeData.from(
colorScheme: const ColorScheme.dark(
primary: binghamtonGreen,
secondary: binghamtonGreen,
),
),
routes: {
Routes.home: (_) => HomePage(),
Routes.settings: (_) => SettingsPage(),
},
),
),
Widget build(BuildContext context) => MaterialApp(
title: "Binghamton University Rover Team",
home: SplashPage(),
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: false,
colorScheme: const ColorScheme.light(
primary: binghamtonGreen,
secondary: binghamtonGreen,
),
appBarTheme: const AppBarTheme(
backgroundColor: binghamtonGreen,
// titleTextStyle: TextStyle(color: Colors.white),
foregroundColor: Colors.white,
),
),
darkTheme: ThemeData.from(
colorScheme: const ColorScheme.dark(
primary: binghamtonGreen,
secondary: binghamtonGreen,
),
),
routes: {
Routes.home: (_) => HomePage(),
Routes.settings: (_) => SettingsPage(),
},
);
}
3 changes: 1 addition & 2 deletions lib/data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/// The data library.
///
/// This library defines any data types needed by the rest of the app. While the dataclasses may
/// This library defines any data types needed by the rest of the app. While the data classes may
/// have methods, the logic within should be simple, and any broad logic that changes state should
/// happen in the models library.
///
Expand All @@ -21,7 +21,6 @@ export "src/data/metrics/mars.dart";
export "src/data/metrics/metrics.dart";
export "src/data/metrics/science.dart";

export "src/data/constants.dart";
export "src/data/modes.dart";
export "src/data/protobuf.dart";
export "src/data/science.dart";
Expand Down
1 change: 1 addition & 0 deletions lib/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export "src/models/view/builders/science_command.dart";
export "src/models/view/builders/builder.dart";
export "src/models/view/builders/color_builder.dart";
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";

Expand Down
22 changes: 0 additions & 22 deletions lib/src/data/constants.dart

This file was deleted.

119 changes: 58 additions & 61 deletions lib/src/data/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,6 @@ extension SettingsParser on Json {
}
}

/// Settings relating to video.
class VideoSettings {
/// How many frames to render per second.
///
/// This does not affect how many frames are sent by the rover per second.
final int fps;

/// A const constructor.
const VideoSettings({required this.fps});

/// Parses a [VideoSettings] from JSON.
VideoSettings.fromJson(Json? json) :
fps = (json?["fps"] ?? 60) as int;

/// Serializes these settings in JSON format.
Json toJson() => {
"fps": fps,
};
}

/// Settings relating to science.
class ScienceSettings {
/// How many frames to render per second.
Expand Down Expand Up @@ -140,16 +120,12 @@ class NetworkSettings {
/// the tank when it's being used.
final SocketInfo tankSocket;

/// The address and port of the Rover's GPS
final SocketInfo marsSocket;

/// Creates a new network settings object.
NetworkSettings({
required this.subsystemsSocket,
required this.videoSocket,
required this.autonomySocket,
required this.tankSocket,
required this.marsSocket,
required this.connectionTimeout,
});

Expand All @@ -159,7 +135,6 @@ class NetworkSettings {
videoSocket = json?.getSocket("videoSocket") ?? SocketInfo.raw("192.168.1.30", 8002),
autonomySocket = json?.getSocket("autonomySocket") ?? SocketInfo.raw("192.168.1.30", 8003),
tankSocket = json?.getSocket("tankSocket") ?? SocketInfo.raw("192.168.1.40", 8000),
marsSocket = json?.getSocket("marsSocket") ?? SocketInfo.raw("192.168.1.50", 8006),
connectionTimeout = json?["connectionTimeout"] ?? 5;

/// Serializes these settings to JSON.
Expand All @@ -168,34 +143,10 @@ class NetworkSettings {
"videoSocket": videoSocket.toJson(),
"autonomySocket": autonomySocket.toJson(),
"tankSocket": tankSocket.toJson(),
"marsSocket": marsSocket.toJson(),
"connectionTimeout": connectionTimeout,
};
}

/// Settings relating to autonomy.
class AutonomySettings {
/// 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 blockSize;

/// A const constructor.
const AutonomySettings({required this.blockSize});

/// Parses autonomy settings from a JSON map.
AutonomySettings.fromJson(Json? json) :
blockSize = json?["blockSize"] ?? 1.0;

/// Serializes these settings to JSON.
Json toJson() => {
"blockSize": blockSize,
};
}

/// Settings relating to easter eggs.
///
/// Implement these! Ask Levi for details.
Expand Down Expand Up @@ -223,14 +174,63 @@ class EasterEggsSettings {
};
}

/// Controls the way the Dashboard views split.
enum SplitMode {
/// Two views are split horizontally, one atop the other.
horizontal("Top and bottom"),
/// 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.
const SplitMode(this.humanName);
}

/// Settings related to the dashboard itself, not the rover.
class DashboardSettings {
/// How the Dashboard should split when only two views are present.
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;

/// A const constructor.
const DashboardSettings({
required this.splitMode,
required this.mapBlockSize,
required this.maxFps,
});

/// Parses Dashboard settings from JSON.
DashboardSettings.fromJson(Json? json) :
splitMode = SplitMode.values[json?["splitMode"] ?? SplitMode.horizontal.index],
mapBlockSize = json?["mapBlockSize"] ?? 1.0,
maxFps = (json?["maxFps"] ?? 60) as int;

/// Serializes these settings to JSON.
Json toJson() => {
"splitMode": splitMode.index,
"mapBlockSize": mapBlockSize,
"maxFps": maxFps,
};
}

/// 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 video display.
final VideoSettings video;

/// Settings for easter eggs.
///
/// Please, please, please -- do not remove these (Levi Lesches, '25).
Expand All @@ -242,35 +242,32 @@ class Settings {
/// Settings for the science analysis.
final ScienceSettings science;

/// Settings for the autonomy display.
final AutonomySettings autonomy;
/// Settings related to the dashboard itself.
final DashboardSettings dashboard;

/// A const constructor.
const Settings({
required this.network,
required this.video,
required this.easterEggs,
required this.science,
required this.arm,
required this.autonomy,
required this.dashboard,
});

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

/// Converts the data from the settings instance to Json.
Json toJson() => {
"autonomy": autonomy.toJson(),
"network": network.toJson(),
"video": video.toJson(),
"easterEggs": easterEggs.toJson(),
"science": science.toJson(),
"arm": arm.toJson(),
"dashboard": dashboard.toJson(),
};
}
2 changes: 1 addition & 1 deletion lib/src/models/data/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class HomeModel extends Model {
_messageTimer?.cancel(); // the new message might be cleared if the old one were about to
message = TaskbarMessage(severity: severity, text: text);
notifyListeners();
if (permanent) _hasError = true;
_hasError = permanent;
_messageTimer = Timer(const Duration(seconds: 3), clear);
}

Expand Down
9 changes: 3 additions & 6 deletions lib/src/models/data/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,15 @@ class SettingsModel extends Model {
/// The user's arm settings.
ArmSettings get arm => all.arm;

/// The user's video settings.
VideoSettings get video => all.video;

/// The user's science settings.
ScienceSettings get science => all.science;

/// The user's autonomy settings.
AutonomySettings get autonomy => all.autonomy;

/// The user's easter egg settings.
EasterEggsSettings get easterEggs => all.easterEggs;

/// The user's dashboard settings.
DashboardSettings get dashboard => all.dashboard;

@override
Future<void> init() async {
all = await services.files.readSettings();
Expand Down
Loading

0 comments on commit dbd1d27

Please sign in to comment.