-
Notifications
You must be signed in to change notification settings - Fork 24
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
Arm widget #131
Arm widget #131
Changes from 3 commits
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,168 @@ | ||
import 'package:collection/collection.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:viam_sdk/viam_sdk.dart'; | ||
import 'package:viam_sdk/widgets.dart'; | ||
|
||
/// A widget to control an [Arm]. | ||
class ViamArmWidget extends StatefulWidget { | ||
/// The [Arm] | ||
final Arm arm; | ||
|
||
const ViamArmWidget({ | ||
Key? key, | ||
required this.arm, | ||
}) : super(key: key); | ||
|
||
@override | ||
State<ViamArmWidget> createState() => _ViamArmWidgetState(); | ||
} | ||
|
||
enum _PoseField { x, y, z, theta, oX, oY, oZ } | ||
|
||
class _ViamArmWidgetState extends State<ViamArmWidget> { | ||
Pose endPosition = Pose(); | ||
List<double> jointPositions = []; | ||
|
||
Future<void> _getPositions() async { | ||
final ep = await widget.arm.endPosition(); | ||
final jp = await widget.arm.jointPositions(); | ||
setState(() { | ||
jointPositions = jp; | ||
endPosition = ep; | ||
}); | ||
} | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
_getPositions(); | ||
} | ||
|
||
Future<void> updateEndPosition(_PoseField field, double increment) async { | ||
final ep = endPosition; | ||
switch (field) { | ||
case _PoseField.x: | ||
ep.x += increment; | ||
case _PoseField.y: | ||
ep.y += increment; | ||
case _PoseField.z: | ||
ep.z += increment; | ||
case _PoseField.theta: | ||
ep.theta += increment; | ||
case _PoseField.oX: | ||
ep.oX += increment; | ||
case _PoseField.oY: | ||
ep.oY += increment; | ||
case _PoseField.oZ: | ||
ep.oZ += increment; | ||
} | ||
Comment on lines
+68
to
+85
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. ✨ love it, thank you! |
||
|
||
await widget.arm.moveToPosition(ep); | ||
await _getPositions(); | ||
} | ||
|
||
Future<void> updateJointPosition(int joint, double increment) async { | ||
final jp = jointPositions; | ||
jp[joint] += increment; | ||
await widget.arm.moveToJointPositions(jp); | ||
await _getPositions(); | ||
} | ||
|
||
TableRow _getEndPositionRow(_PoseField field) { | ||
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. Nice! Can we put this in it's own widget instead of a helper function? See here for a bit more of a deep dive on why. Basically it's more performant when the widget tree rebuilds. 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. @njooma and I spoke offline, I was mistaken and TableRow is not a |
||
double value; | ||
switch (field) { | ||
case _PoseField.x: | ||
value = endPosition.x; | ||
case _PoseField.y: | ||
value = endPosition.y; | ||
case _PoseField.z: | ||
value = endPosition.z; | ||
case _PoseField.theta: | ||
value = endPosition.theta; | ||
case _PoseField.oX: | ||
value = endPosition.oX; | ||
case _PoseField.oY: | ||
value = endPosition.oY; | ||
case _PoseField.oZ: | ||
value = endPosition.oZ; | ||
} | ||
|
||
return TableRow(children: [ | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2), | ||
child: Text('${field.name[0].toUpperCase()}${field.name.substring(1).toLowerCase()}', textAlign: TextAlign.end))), | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2), | ||
child: ViamButton(onPressed: () => updateEndPosition(field, -10), text: '--', size: ViamButtonSizeClass.small))), | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2), | ||
child: ViamButton(onPressed: () => updateEndPosition(field, -1), text: '-', size: ViamButtonSizeClass.small))), | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2), child: Text(value.toStringAsFixed(2), textAlign: TextAlign.center))), | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2), | ||
child: ViamButton(onPressed: () => updateEndPosition(field, 1), text: '+', size: ViamButtonSizeClass.small))), | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 1), | ||
child: ViamButton(onPressed: () => updateEndPosition(field, 10), text: '++', size: ViamButtonSizeClass.small))), | ||
]); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Column( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
crossAxisAlignment: CrossAxisAlignment.center, | ||
children: [ | ||
const Text('End Positions (mm)', style: TextStyle(fontWeight: FontWeight.bold)), | ||
Table( | ||
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. [minor] This Table is a BEEFY widget, can we break it out into its own widget? |
||
columnWidths: const {0: IntrinsicColumnWidth()}, | ||
defaultVerticalAlignment: TableCellVerticalAlignment.middle, | ||
children: _PoseField.values.map((e) => _getEndPositionRow(e)).toList(), | ||
), | ||
const SizedBox(height: 16), | ||
const Text('Joints (degrees)', style: TextStyle(fontWeight: FontWeight.bold)), | ||
Table( | ||
columnWidths: const {0: IntrinsicColumnWidth()}, | ||
defaultVerticalAlignment: TableCellVerticalAlignment.middle, | ||
children: jointPositions | ||
.mapIndexed((index, element) => TableRow(children: [ | ||
clintpurser marked this conversation as resolved.
Show resolved
Hide resolved
|
||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2), child: Text('Joint $index', textAlign: TextAlign.end))), | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2), | ||
child: | ||
ViamButton(onPressed: () => updateJointPosition(index, -10), text: '--', size: ViamButtonSizeClass.small))), | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2), | ||
child: | ||
ViamButton(onPressed: () => updateJointPosition(index, -1), text: '-', size: ViamButtonSizeClass.small))), | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2), | ||
child: Text(element.toStringAsFixed(2), textAlign: TextAlign.center))), | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2), | ||
child: ViamButton(onPressed: () => updateJointPosition(index, 1), text: '+', size: ViamButtonSizeClass.small))), | ||
TableCell( | ||
child: Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 1), | ||
child: | ||
ViamButton(onPressed: () => updateJointPosition(index, 10), text: '++', size: ViamButtonSizeClass.small))), | ||
])) | ||
.toList(), | ||
) | ||
], | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,8 +34,8 @@ class _ViamBaseWidgetState extends State<ViamBaseWidget> { | |
|
||
@override | ||
void initState() { | ||
camera = widget.cameras.firstOrNull; | ||
super.initState(); | ||
camera = widget.cameras.firstOrNull; | ||
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. [q] why move this after the super init state? Was it getting overwritten or something? 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. We've just been doing it wrong the entire time. From the documentation:
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. Similarly, you might see changes to
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. Cool; makes intuitive sense too that you want to do the inherited construction/destruction before the custom class construction/destruction. |
||
} | ||
|
||
Widget _buildCamera() { | ||
|
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.
Nice, good catch here; definitely agree with preferring native types where possible.