diff --git a/lib/src/models/rover/controls/tank_drive.dart b/lib/src/models/rover/controls/tank_drive.dart index cb575b804..1acbce2eb 100644 --- a/lib/src/models/rover/controls/tank_drive.dart +++ b/lib/src/models/rover/controls/tank_drive.dart @@ -5,25 +5,46 @@ import "controls.dart"; /// The skid-steer drive controls. class DriveControls extends RoverControls { - @override - OperatingMode get mode => OperatingMode.drive; + /// Whether the left shoulder was pressed last tick. + bool leftShoulderFlag = false; - @override - List parseInputs(GamepadState state) => [ - DriveCommand(setLeft: true, left: state.normalLeftY), - DriveCommand(setRight: true, right: -1*state.normalRightY), - ]; + /// Whether the right shoulder was pressed last tick. + bool rightShoulderFlag = true; + + @override + OperatingMode get mode => OperatingMode.drive; + + /// The throttle the rover should be at. + double throttle = 0; + + @override + void updateState(GamepadState state) { + if (!leftShoulderFlag && state.leftShoulder) throttle -= 0.1; + leftShoulderFlag = state.leftShoulder; + if (!rightShoulderFlag && state.rightShoulder) throttle += 0.1; + rightShoulderFlag = state.rightShoulder; + throttle = throttle.clamp(0, 1); + } + + @override + List parseInputs(GamepadState state) => [ + DriveCommand(throttle: throttle, setThrottle: true), + DriveCommand(setLeft: true, left: state.normalLeftY), + DriveCommand(setRight: true, right: -1*state.normalRightY), + ]; @override List get onDispose => [ DriveCommand(setThrottle: true, throttle: 0), - DriveCommand(setLeft: true, left: 0), - DriveCommand(setRight: true, right: 0), + DriveCommand(setLeft: true, left: 0), + DriveCommand(setRight: true, right: 0), ]; - @override - Map get buttonMapping => { - "Left Throttle": "Left joystick (vertical)", - "Right Throttle": "Right joystick (vertical)", - }; + @override + Map get buttonMapping => { + "Left Throttle": "Left joystick (vertical)", + "Right Throttle": "Right joystick (vertical)", + "Increase throttle": "Right bumper (R1)", + "Decrease throttle": "Left bumper (L1)", + }; } diff --git a/lib/src/pages/settings.dart b/lib/src/pages/settings.dart index 5c7562d9b..6470bd458 100644 --- a/lib/src/pages/settings.dart +++ b/lib/src/pages/settings.dart @@ -1,4 +1,6 @@ // ignore_for_file: directives_ordering +import "dart:io"; + import "package:flutter/material.dart"; import "package:url_launcher/url_launcher.dart"; @@ -8,7 +10,7 @@ import "package:rover_dashboard/services.dart"; import "package:rover_dashboard/widgets.dart"; /// A widget to display all the settings in a [ValueBuilder]. -/// +/// /// Technically this class does not need to be used with [ValueBuilder], but it provides a heading /// and a list of children widgets to modify individual settings. class ValueEditor extends StatelessWidget { @@ -38,7 +40,7 @@ class ValueEditor extends StatelessWidget { ...children, ], ); -} +} /// The settings page. class SettingsPage extends ReactiveWidget { @@ -60,6 +62,33 @@ class SettingsPage extends ReactiveWidget { SocketEditor(name: "Autonomy socket", model: model.network.autonomySocket), SocketEditor(name: "Tank IP address", model: model.network.tankSocket, editPort: false), NumberEditor(name: "Heartbeats per second", model: model.network.connectionTimeout), + if (Platform.isWindows) ListTile( + title: const Text("Open Windows network settings"), + subtitle: const Text("You may need to change these if the rover will not connect"), + trailing: const Icon(Icons.lan_outlined), + onTap: () { + launchUrl(Uri.parse("ms-settings:network-ethernet")); + showDialog( + context: context, + builder: (context) => AlertDialog( + content: const Text( + "Click on IP Assignment, select Manual, then IPv4, then set:\n" + "\n- IP address: 192.168.1.10" + "\n- Subnet 255.255.255.0 (or Subnet length: 24)" + "\n- Gateway: 192.168.1.1" + "\n- Preferred DNS: 192.168.1.1" + ), + title: const Text("Set your IP settings"), + actions: [ + TextButton( + child: const Text("Ok"), + onPressed: () => Navigator.of(context).pop(), + ), + ], + ), + ); + }, + ), ], ), const Divider(), @@ -79,7 +108,7 @@ class SettingsPage extends ReactiveWidget { name: "Science settings", children: [ NumberEditor( - name: "Number of samples", + name: "Number of samples", model: model.science.numSamples, ), SwitchListTile( @@ -95,13 +124,13 @@ class SettingsPage extends ReactiveWidget { name: "Dashboard Settings", children: [ NumberEditor( - name: "Frames per second", + name: "Frames per second", subtitle: "This does not affect the rover's cameras. Useful for limiting the CPU of the dashboard", model: model.dashboard.fps, ), NumberEditor( - name: "Block size", - subtitle: "The precision of the GPS grid", + name: "Block size", + subtitle: "The precision of the GPS grid", model: model.dashboard.blockSize, ), SwitchListTile( @@ -192,15 +221,6 @@ class SettingsPage extends ReactiveWidget { ), const Divider(), Text("Misc", style: Theme.of(context).textTheme.titleLarge), - ListTile( - title: const Text("Adjust throttle"), - subtitle: const Text("Sets the max speed on the rover"), - trailing: const Icon(Icons.speed), - onTap: () => showDialog( - context: context, - builder: (_) => ThrottleEditor(), - ), - ), ListTile( title: const Text("Open session output"), subtitle: const Text("Opens all files created by this session"), @@ -245,11 +265,11 @@ class SettingsPage extends ReactiveWidget { ], ),), Row( - mainAxisAlignment: MainAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( onPressed: () => Navigator.of(context).pop(), - child: const Text("Cancel"), + child: const Text("Cancel"), ), const SizedBox(width: 4), ElevatedButton.icon( @@ -257,9 +277,9 @@ class SettingsPage extends ReactiveWidget { await model.save(); if (context.mounted) Navigator.of(context).pop(); }, - label: const Text("Save"), - icon: model.isLoading - ? const SizedBox(height: 24, width: 24, child: CircularProgressIndicator()) + label: const Text("Save"), + icon: model.isLoading + ? const SizedBox(height: 24, width: 24, child: CircularProgressIndicator()) : const Icon(Icons.save), ), const SizedBox(width: 4), diff --git a/lib/src/services/gamepad.dart b/lib/src/services/gamepad.dart index 71009a08c..147f0db34 100644 --- a/lib/src/services/gamepad.dart +++ b/lib/src/services/gamepad.dart @@ -139,7 +139,7 @@ class GamepadService extends Service { static const int numGamepads = 3; /// A list of all the [Gamepad]s the user has connected. - /// + /// /// Non-connected gamepads are represented with [MockGamepad]s, which has the nice benefit of /// automatically handling the case where the user is on a non-supported platform. final List gamepads = [