Skip to content

Commit

Permalink
Fix Log Messages Displaying (#181)
Browse files Browse the repository at this point in the history
* Show info messages from video
* Actually show the error for dashboard messages

---------

Co-authored-by: Levi Lesches <[email protected]>
  • Loading branch information
Gold872 and Levi-Lesches authored Nov 19, 2024
1 parent 14066ef commit 36af765
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 38 deletions.
50 changes: 32 additions & 18 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/// The entrypoint of the app.
///
/// These `library` declarations are not needed, the default name for a Dart library is simply the
/// The entrypoint of the app.
///
/// These `library` declarations are not needed, the default name for a Dart library is simply the
/// name of the file. However, DartDoc comments placed above a library declaration will show up on
/// the libraries page in the generated documentation.
///
///
/// This library's main purpose is to execute the app defined in the app library and is designed to
/// be as simple as possible.
/// be as simple as possible.
library main;

import "dart:async";
Expand All @@ -15,22 +15,36 @@ import "package:flutter/material.dart";
import "package:rover_dashboard/app.dart";
import "package:rover_dashboard/data.dart";
import "package:rover_dashboard/models.dart";
import "package:rover_dashboard/services.dart";

/// Network errors that can be fixed by a simple reset.
const networkErrors = {1234, 1231};

/// Converts an error and optional stack trace into a [BurtLog] and calls [LogsModel.handleLog].
void logError(Object error, StackTrace? stackTrace) => models.logs.handleLog(
BurtLog(
level: BurtLogLevel.critical,
title: "Dashboard Error. Click for details",
body: "$error\n$stackTrace",
device: Device.DASHBOARD,
),
);

void main() async {
runZonedGuarded(
() => runApp(RoverControlDashboard()),
(error, stack) async {
if (error is SocketException && networkErrors.contains(error.osError!.errorCode)) {
models.home.setMessage(severity: Severity.critical, text: "Network error, restart by clicking the network icon");
} else {
models.home.setMessage(severity: Severity.critical, text: "Dashboard error. See the logs");
await services.files.logError(error, stack);
Error.throwWithStackTrace(error, stack);
}
}
);
// Logs sync errors to the logs page
FlutterError.onError = (FlutterErrorDetails details) {
logError(details.exception, details.stack);
FlutterError.presentError(details); // do the regular error behavior
};
// Logs async errors to the logs page
runZonedGuarded(
() => runApp(RoverControlDashboard()),
(error, stackTrace) async {
if (error is SocketException && networkErrors.contains(error.osError!.errorCode)) {
models.home.setMessage(severity: Severity.critical, text: "Network error, restart by clicking the network icon");
} else {
logError(error, stackTrace);
Error.throwWithStackTrace(error, stackTrace); // do the regular error behavior
}
}
);
}
2 changes: 1 addition & 1 deletion lib/src/models/data/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class HomeModel extends Model {
if (_hasError && severity != Severity.critical) return; // Don't replace critical messages
_messageTimer?.cancel(); // the new message might be cleared if the old one were about to
message = TaskbarMessage(severity: severity, text: text);
if (logMessage) models.logs.handleLog(message!.burtLog);
if (logMessage) models.logs.handleLog(message!.burtLog, display: false);
notifyListeners();
_hasError = permanent;
_messageTimer = Timer(const Duration(seconds: 3), clear);
Expand Down
6 changes: 3 additions & 3 deletions lib/src/models/data/logs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class LogsModel extends Model {
};

/// Sends a log message to be shown in the footer.
void handleLog(BurtLog log) {
void handleLog(BurtLog log, {bool display = true}) {
// Save to disk and memory
saveToFileBuffer.add(log);
logsForDevice(log.device)?.addWithLimit(log);
Expand All @@ -79,12 +79,12 @@ class LogsModel extends Model {
notifyListeners();

// Show important messages to the footer.
if (log.device != Device.DASHBOARD) { // Prevents showing dashboard messages that have already been shown
if (display) { // Prevents showing dashboard messages that have already been shown
switch (log.level) {
case BurtLogLevel.critical: models.home.setMessage(severity: Severity.critical, text: log.title, permanent: true, logMessage: false);
case BurtLogLevel.warning: models.home.setMessage(severity: Severity.warning, text: log.title, logMessage: false);
case BurtLogLevel.error: models.home.setMessage(severity: Severity.error, text: log.title, logMessage: false);
case BurtLogLevel.info: // Info messages from other devices are not important enough to show here
case BurtLogLevel.info: models.home.setMessage(severity: Severity.info, text: "${log.device.humanName}: ${log.title}", logMessage: false);
case BurtLogLevel.debug:
case BurtLogLevel.trace:
case BurtLogLevel.BURT_LOG_LEVEL_UNDEFINED:
Expand Down
16 changes: 8 additions & 8 deletions lib/src/models/rover/controls/arm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class ArmControls extends RoverControls {
ArmSettings get settings => models.settings.arm;

/// The coordinates of the gripper.
///
///
/// The arm uses IK to move all the joints to stay at these coordinates.
Coordinates ik = Coordinates(x: 0.5, y: 0.5, z: 0.5);

Expand Down Expand Up @@ -38,15 +38,15 @@ class ArmControls extends RoverControls {
@override
List<Message> parseInputs(GamepadState state) => [
// Manual control
if (state.normalRightX.abs() > state.normalRightJoystickY.abs() && state.normalRightX != 0)
if (state.normalRightX.abs() > state.normalRightY.abs() && state.normalRightX != 0)
ArmCommand(swivel: MotorCommand(moveRadians: state.normalRightX * settings.swivel)),
if (state.normalRightJoystickY.abs() > state.normalRightX.abs() && state.normalRightJoystickY != 0)
ArmCommand(shoulder: MotorCommand(moveRadians: state.normalRightJoystickY * settings.shoulder)),
if (state.normalRightY.abs() > state.normalRightX.abs() && state.normalRightY != 0)
ArmCommand(shoulder: MotorCommand(moveRadians: state.normalRightY * settings.shoulder)),
if (state.normalLeftY != 0) ArmCommand(elbow: MotorCommand(moveRadians: state.normalLeftY * settings.elbow)),
// The bumpers should be pseudo-IK: Move the shoulder and elbow in sync.
if (state.normalShoulders != 0) ArmCommand(
shoulder: MotorCommand(moveRadians: state.normalShoulders * settings.shoulder * -1),
elbow: MotorCommand(moveRadians: state.normalShoulders * settings.elbow),
// The bumpers should be pseudo-IK: Move the shoulder and elbow in sync.
if (state.normalShoulder != 0) ArmCommand(
shoulder: MotorCommand(moveRadians: state.normalShoulder * settings.shoulder * -1),
elbow: MotorCommand(moveRadians: state.normalShoulder * settings.elbow),
),

// Gripper
Expand Down
6 changes: 5 additions & 1 deletion lib/src/pages/controllers/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class ControllerWidget extends ReusableReactiveWidget<Controller> {
required double y,
required Offset offsetOnImage,
required Size widgetSize,
// TODO(Levi-Lesches): Support thumbstick presses, https://github.com/Levi-Lesches/sdl_gamepad/issues/1
required bool? isPressed,
}) {
final scaleFactor = _getBackgroundFitWidth(widgetSize) / imageSize.width;

Expand All @@ -62,7 +64,7 @@ class ControllerWidget extends ReusableReactiveWidget<Controller> {
width: joystickRadius,
height: joystickRadius,
decoration: BoxDecoration(
color: gamepadColor,
color: (isPressed ?? false) ? gamepadColor : null,
borderRadius: BorderRadius.circular(10000),
),
),
Expand Down Expand Up @@ -161,12 +163,14 @@ class ControllerWidget extends ReusableReactiveWidget<Controller> {
y: -1 * (state?.normalLeftY ?? 0),
offsetOnImage: leftStick,
widgetSize: widgetSize,
isPressed: true,
),
_controllerJoystick(
x: state?.normalRightX ?? 0,
y: -1 * (state?.normalRightY ?? 0),
offsetOnImage: rightStick,
widgetSize: widgetSize,
isPressed: true,
),
],
),
Expand Down
8 changes: 1 addition & 7 deletions lib/src/services/files.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,15 +140,9 @@ class FilesService extends Service {
WrappedMessage.fromBuffer(base64.decode(line)),
];

/// Outputs error to log file
Future<void> logError(Object error, StackTrace stack) async{
if (!_isInit) return;
final file = loggingDir / "errors.log";
await file.writeAsString("${DateTime.now().timeStamp} $error $stack\n", mode: FileMode.writeOnlyAppend);
}

/// Outputs a log to its device's respective log file.
Future<void> logMessage(BurtLog log) async {
if (!_isInit) return;
final file = loggingDir / "${log.device.humanName}.log";
await file.writeAsString("${log.format()}\n", mode: FileMode.writeOnlyAppend);
}
Expand Down

0 comments on commit 36af765

Please sign in to comment.