-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rtl button #28
base: main
Are you sure you want to change the base?
Rtl button #28
Changes from all commits
a05c702
ad58ad3
cddf268
64742ea
35d9b1b
2bf2140
b7cc2e9
9250c3c
8aaa5ff
6034219
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import 'package:dart_mavlink/dialects/common.dart'; | ||
import 'package:dart_mavlink/mavlink.dart'; | ||
|
||
/// Constructs a MissionItem command to return to launch using MAV_CMD_NAV_RETURN_TO_LAUNCH (20). | ||
/// | ||
/// @sequence The sequence number for the MAVLink frame. | ||
/// @systemId The MAVLink system ID of the vehicle (normally "1"). | ||
/// @componentId The MAVLink component ID (normally "0"). | ||
/// @param1 Unused | ||
/// @param2 Unused | ||
/// @param3 Unused | ||
/// @param4 Unused | ||
/// @param5 Unused | ||
/// @param6 Unused | ||
/// @param7 Unused | ||
/// | ||
/// @return A MavlinkFrame representing the reutrn to launch command. | ||
|
||
MavlinkFrame returnToLaunch(int sequence, int systemID, int componentID) { | ||
var commandLong = CommandLong( | ||
targetSystem: systemID, | ||
targetComponent: componentID, | ||
command: mavCmdNavReturnToLaunch, | ||
confirmation: 0, | ||
param1: 0, | ||
param2: 0, | ||
param3: 0, | ||
param4: 0, | ||
param5: 0, | ||
param6: 0, | ||
param7: 0, | ||
); | ||
|
||
var frm = MavlinkFrame.v2(sequence, systemID, componentID, commandLong); | ||
|
||
return frm; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import 'package:imacs/command_constructors/return_to_launch_constructor.dart'; | ||
import 'package:imacs/modules/mavlink_communication.dart'; | ||
import 'dart:developer'; | ||
|
||
const String moduleName = "Return To Launch"; | ||
|
||
class ReturnToLaunch { | ||
final MavlinkCommunication comm; | ||
|
||
// Requires both the constructor (Mission Item) and comm | ||
ReturnToLaunch({required this.comm}); | ||
|
||
// Skips the queues and forces the drone to return | ||
Future returnNoQueue(int systemID, int componentID) async { | ||
try { | ||
if (comm.connectionType == MavlinkCommunicationType.tcp) { | ||
await comm.tcpSocketInitializationFlag.future; | ||
} | ||
var frame = returnToLaunch(comm.sequence, systemID, componentID); | ||
comm.sequence++; | ||
comm.write(frame); | ||
|
||
log('[$moduleName] Returning to Launch'); | ||
return true; | ||
} catch (e) { | ||
log('[$moduleName] Error occurred: $e'); | ||
return false; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:imacs/modules/return_to_launch.dart'; | ||
|
||
class ReturnToLaunchTemplate extends StatefulWidget { | ||
final ReturnToLaunch returnToLaunchCommand; | ||
final int systemID; | ||
final int componentID; | ||
|
||
// Needs the ReturnToLaunch object from the return_to_launch dart | ||
|
||
const ReturnToLaunchTemplate( | ||
{Key? key, | ||
required this.returnToLaunchCommand, | ||
required this.systemID, | ||
required this.componentID}) | ||
: super(key: key); | ||
|
||
@override | ||
ReturnToLaunchButton createState() => ReturnToLaunchButton(); | ||
} | ||
|
||
class ReturnToLaunchButton extends State<ReturnToLaunchTemplate> { | ||
String buttonLabel = "Return to Launch"; | ||
|
||
void updateButton() { | ||
setState(() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of updating the text of the button, I think it will be better to have a temporary SnackBar appear |
||
buttonLabel = "Sent"; // Triggers a rebuild | ||
}); | ||
} | ||
|
||
// Returns a button that tells the drone to return to launch | ||
@override | ||
Widget build(BuildContext context) { | ||
return ElevatedButton( | ||
onPressed: () async { | ||
bool result = await widget.returnToLaunchCommand | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason the text of you button is not changing is that this async code never finished executing. This is actually to be expected since part of the async code is the completer for TCP initialization, which will never complete unless connected to the drone. |
||
.returnNoQueue(widget.systemID, widget.componentID); | ||
if (true) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unnecessary if statement |
||
updateButton(); | ||
} | ||
}, | ||
child: Text(buttonLabel)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import 'package:dart_mavlink/dialects/common.dart'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lgtm! |
||
import 'package:dart_mavlink/mavlink.dart'; | ||
import 'package:imacs/command_constructors/return_to_launch_constructor.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
void main() { | ||
/// dialect: Selected MAVLink dialect | ||
/// sequence: The sequence number for the MAVLink frame. | ||
/// Each component counts up its send sequence. | ||
/// Allows to detect packet loss. | ||
/// systemId: The MAVLink system ID of the vehicle (normally "1"). | ||
/// componentId: The MAVLink component ID (normally "0"). | ||
var dialect = MavlinkDialectCommon(); | ||
const sequence = 0; | ||
const systemID = 1; | ||
const componentID = 0; | ||
|
||
test("Return To Launch", () { | ||
const createReturnToLaunchCommandNumber = mavCmdNavReturnToLaunch; | ||
|
||
var parser = MavlinkParser(dialect); | ||
parser.stream.listen((MavlinkFrame frm) { | ||
if (frm.message is MissionItem) { | ||
var mi = frm.message as MissionItem; | ||
expect(mi.command, equals(createReturnToLaunchCommandNumber)); | ||
} | ||
}); | ||
|
||
var returnToLaunchCommand = returnToLaunch(sequence, systemID, componentID); | ||
|
||
parser.parse(returnToLaunchCommand.serialize().buffer.asUint8List()); | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:imacs/modules/mavlink_communication.dart'; | ||
import 'package:imacs/modules/return_to_launch.dart'; | ||
import 'package:imacs/widgets/return_to_launch_widget.dart'; | ||
|
||
void main() { | ||
group("Return to Launch Widget", () { | ||
testWidgets("Return to Launch Button Generate", | ||
(WidgetTester tester) async { | ||
final mavlinkCommunication = MavlinkCommunication( | ||
MavlinkCommunicationType.tcp, '127.0.0.1', 14550); | ||
final ReturnToLaunch command = ReturnToLaunch(comm: mavlinkCommunication); | ||
|
||
// Tests to see if the button renders | ||
await tester.pumpWidget(MaterialApp( | ||
home: Scaffold( | ||
body: ReturnToLaunchTemplate( | ||
returnToLaunchCommand: command, | ||
systemID: 1, | ||
componentID: 0)))); | ||
|
||
// Waits for all frames and animations to settle | ||
await tester.pumpAndSettle(); | ||
expect(find.byType(ElevatedButton), findsOneWidget); | ||
expect(find.text("Return to Launch"), findsOneWidget); | ||
}); | ||
|
||
testWidgets("Button sends MavLink command", (WidgetTester tester) async { | ||
final mavlinkCommunication = MavlinkCommunication( | ||
MavlinkCommunicationType.tcp, '127.0.0.1', 14550); | ||
final ReturnToLaunch command = ReturnToLaunch(comm: mavlinkCommunication); | ||
|
||
// Tests to see if the button renders | ||
await tester.pumpWidget(MaterialApp( | ||
home: Scaffold( | ||
body: ReturnToLaunchTemplate( | ||
returnToLaunchCommand: command, | ||
systemID: 1, | ||
componentID: 0, | ||
key: UniqueKey())))); | ||
|
||
await tester.pumpAndSettle(); | ||
expect(find.byType(ElevatedButton), findsOneWidget); | ||
|
||
await tester.tap(find.byType(ElevatedButton)); | ||
await tester.pumpAndSettle(); | ||
debugPrint((tester | ||
.widget<ElevatedButton>(find.byType(ElevatedButton)) | ||
.child as Text) | ||
.data); | ||
expect(find.text("sent"), findsOneWidget); | ||
}); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make return type explicit
Future<bool>