Skip to content

feat: Ported robotic arm #2729

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

Open
wants to merge 5 commits into
base: flutter
Choose a base branch
from

Conversation

rahul31124
Copy link
Collaborator

@rahul31124 rahul31124 commented Jun 7, 2025

Fixes #2728

Changes

Added the Robotic arm screen and communication protocol.

Screenshots / Recordings

Ported_Robotic_Arm.webm

Checklist:

  • No hard coding: I have used resources from strings.xml, dimens.xml and colors.xml without hard coding any value.
  • No end of file edits: No modifications done at end of resource files strings.xml, dimens.xml or colors.xml.
  • Code reformatting: I have reformatted code and fixed indentation in every file included in this pull request.
  • No extra space: My code does not contain any extra lines or extra spaces than the ones that are necessary.

Summary by Sourcery

Port the Robotic Arm feature by adding a dedicated screen with interactive servo controls, a draggable timeline scheduler, and extend the ScienceLab communication protocol for four-servo support.

New Features:

  • Add Robotic Arm screen with real-time servo angle controls and input dialog.
  • Implement draggable timeline view for scheduling and playback of servo angles with play/pause/stop controls.

Enhancements:

  • Introduce servo4 method in ScienceLab for sending commands to four servos.
  • Extend navigation and routing to include the /roboticArm screen in the main app and instruments menu.
  • Add constants and localized strings for robotic arm labels, tooltips, and validations.

Build:

  • Add sleek_circular_slider dependency for ServoCard UI.

Copy link

sourcery-ai bot commented Jun 7, 2025

Reviewer's Guide

This pull request ports the Robotic Arm feature by adding a new multi-servo command in the communication layer, introducing a dedicated UI screen with servo controls and a timeline, updating string resources and dependencies, and wiring up navigation and routing.

Sequence Diagram for Robotic Arm Servo Control (servo4)

sequenceDiagram
    participant RAS as RoboticArmScreen
    participant SL as ScienceLab
    participant PH as mPacketHandler

    RAS->>SL: servo4(angle1, angle2, angle3, angle4)
    SL->>PH: sendByte(mCommandsProto.wavegen)
    SL->>PH: sendByte(mCommandsProto.sqr4)
    SL->>PH: sendInt(period)
    SL->>PH: sendInt(pulse1)
    SL->>PH: sendInt(0)
    SL->>PH: sendInt(pulse2)
    SL->>PH: sendInt(0)
    SL->>PH: sendInt(pulse3)
    SL->>PH: sendInt(0)
    SL->>PH: sendInt(pulse4)
    SL->>PH: sendByte(params)
    SL->>PH: getAcknowledgement()
    PH-->>SL: Acknowledgement
    SL-->>RAS: Completes
Loading

Sequence Diagram for Robotic Arm Timeline Playback

sequenceDiagram
    actor User
    participant RAS as RoboticArmScreen
    participant T as Timer
    participant SL as ScienceLab

    User->>RAS: Presses Play Button
    RAS->>RAS: togglePlayPause()
    activate RAS
    RAS->>T: Start Timer (1s interval)
    activate T
    loop For each timeline step
        T-->>RAS: Tick
        RAS->>RAS: Get currentAngles from timelineDegrees[timelinePosition]
        RAS->>SL: servo4(currentAngles[0], ..., currentAngles[3])
        activate SL
        SL-->>SL: Send commands to hardware
        deactivate SL
        RAS->>RAS: Update UI (scroll, timelinePosition++)
    end
    alt timelinePosition >= totalTimelineItems OR User presses Stop
        RAS->>T: Cancel Timer
        deactivate T
        RAS->>RAS: stopScrolling()
    end
    deactivate RAS
Loading

Class Diagram for Robotic Arm Components

classDiagram
    class ScienceLab {
        +servo4(angle1: double, angle2: double, angle3: double, angle4: double) Future~void~
    }

    class RoboticArmScreen {
        <<StatefulWidget>>
        +createState() _RoboticArmScreenState
    }

    class _RoboticArmScreenState {
        <<State>>
        -servoValues: List~double~
        -timelineScrollController: ScrollController
        -timelineTimer: Timer?
        -timelinePosition: int
        -isPlaying: bool
        -scienceLab: ScienceLab
        -timelineDegrees: List~List~double~~
        +initState()
        +dispose()
        -_sendAllServoCommands(servoValues: List~double~) void
        -_setLandscapeOrientation() void
        +togglePlayPause() void
        +stopScrolling(resetPosition: bool) void
        -_showAngleInputDialog(index: int) void
        +build(context: BuildContext) Widget
    }
    RoboticArmScreen --o _RoboticArmScreenState
    _RoboticArmScreenState ..> ScienceLab : uses
    _RoboticArmScreenState ..> ServoCard : uses
    _RoboticArmScreenState ..> TimelineScrollView : uses

    class ServoCard {
        <<StatelessWidget>>
        +value: double
        +onChanged: Function~double~
        +onTap: VoidCallback
        +label: String
        +servoId: int
        +build(context: BuildContext) Widget
    }
    ServoCard ..> SleekCircularSlider : uses

    class TimelineScrollView {
        <<StatelessWidget>>
        +scrollController: ScrollController
        +timelinePosition: int
        +scrollAmountPerTick: double
        +timelineDegrees: List~List~double~~
        +onUpdate: Function~int, int, double~
        +build(context: BuildContext) Widget
    }
    TimelineScrollView ..> DragTarget : uses

    class SleekCircularSlider {
        <<External Library>>
    }
    class DragTarget {
        <<Flutter Widget>>
    }
    class ScrollController {
        <<Flutter Class>>
    }
    class Timer {
        <<Dart Class>>
    }
Loading

File-Level Changes

Change Details Files
Implemented a new four-servo control API in the communication layer
  • Added servo4() method with pulse computation for four channels
  • Sent necessary wavegen, sqr4, period, pulse and params packets
  • Handled acknowledgements and error logging
lib/communication/science_lab.dart
Added string resources and external dependency for the robotic arm
  • Defined degree symbol, angle prompts, servo labels and UI text in constants
  • Inserted sleek_circular_slider dependency in pubspec.yaml
lib/constants.dart
pubspec.yaml
Updated navigation and routing to include the Robotic Arm screen
  • Imported and registered RoboticArmScreen route in main.dart
  • Added case handling in instruments_screen to navigate to /roboticArm
lib/main.dart
lib/view/instruments_screen.dart
Created RoboticArmScreen with servo controls and timeline playback
  • Built StatefulWidget with landscape orientation and connect logic
  • Implemented debounce logic for batch servo commands
  • Added play/pause/stop controls and timeline scrolling timer
lib/view/robotic_arm_screen.dart
Introduced ServoCard widget for individual servo interaction
  • Rendered circular slider with drag-and-drop capability
  • Displayed current angle and enabled angle input tapping
lib/view/widgets/servo_card.dart
Built TimelineScrollView for visualizing and editing servo sequences
  • Created horizontal scroll view with time markers and drag targets
  • Enabled per-cell drag acceptance and updated timeline state
lib/view/widgets/robotic_arm_timeline.dart

Assessment against linked issues

Issue Objective Addressed Explanation
#2728 Port the existing Robotic Arm screen to Flutter.
#2728 Implement the same UI as the existing Robotic Arm screen.
#2728 Implement the same functionality as the existing Robotic Arm screen.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@rahul31124 rahul31124 changed the title Ported robotic arm feat: Ported robotic arm Jun 7, 2025
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @rahul31124 - I've reviewed your changes and found some issues that need to be addressed.

Blocking issues:

  • Undefined constant 'cancel' used; define or import it (link)

General comments:

  • The servo4 method repeats the same pulse calculation and send logic for each angle—consider looping over the angles to reduce duplication and improve maintainability.
  • In instruments_screen, the switch case uses the literal 12 for launching the robotic arm—extract that into a named constant or enum to make the code clearer and less error-prone.
  • Route strings like '/roboticArm' are hard-coded in multiple places—centralize them into a constant to avoid mismatches and ease future updates.
Here's what I looked at during the review
  • 🔴 General issues: 1 blocking issue, 4 other issues
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link

github-actions bot commented Jun 7, 2025

@rahul31124
Copy link
Collaborator Author

Closed the previous PR due to wrong branch.

Copy link
Collaborator

@AsCress AsCress left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rahul31124 Quite some things to fix here. Let's go part by part.

@@ -0,0 +1,343 @@
import 'dart:async';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow the SOC principle. Widgets and functionality should be handled separately. Observe how the other instruments handle this: a separate layout file which contains the widgets, and a dedicated ChangeNotifierProvider for handling the functionality which is consumed by the layout widgets.

@marcnause
Copy link
Contributor

I tested with an older device with a small screen (at today's standards, https://en.wikipedia.org/wiki/Moto_X_Play) and I was able to control a servo. 👍

Just a little something I noticed: When I start the Robotic Arm screen, I get the warning in the screenshot below.

Screenshot_20250608-173907

In the log I found this exception:

exception.txt

Once I turned the screen of the device off an on again, the warning is gone.

Screenshot_20250608-173931

@rahul31124 rahul31124 closed this Jun 9, 2025
@rahul31124
Copy link
Collaborator Author

@marcnause,I guess it will be better to reduce the height of the time line abit and increase the servo controller height.

@rahul31124 rahul31124 reopened this Jun 9, 2025
@rahul31124
Copy link
Collaborator Author

@AsCress I've made the requested changes in the PR.

@AsCress
Copy link
Collaborator

AsCress commented Jun 10, 2025

@rahul31124 Have you addressed the above issue reported by @marcnause ?

@rahul31124
Copy link
Collaborator Author

@AsCress No, I will do it by tomorrow.

@rahul31124
Copy link
Collaborator Author

@AsCress I’ve resized the height and width and tested it on a Pixel 3 (5.5-inch screen). I didn’t encounter any exceptions for layout

@rahul31124 rahul31124 assigned rahul31124 and AsCress and unassigned rahul31124 and AsCress Jun 11, 2025
@rahul31124 rahul31124 added flutter Status: Review Required Requested reviews from peers and maintainers labels Jun 11, 2025
@mariobehling mariobehling requested a review from marcnause June 12, 2025 08:42
@AsCress
Copy link
Collaborator

AsCress commented Jun 13, 2025

@rahul31124 Ok. I'll test this and get back to you. Meanwhile, please resolve conflicts.

@rahul31124 rahul31124 force-pushed the robotic_arm branch 2 times, most recently from 0368ea8 to e4b6927 Compare June 14, 2025 06:07
@rahul31124
Copy link
Collaborator Author

@AsCress I’ve resolved the merge conflicts

@marcnause
Copy link
Contributor

@marcnause,I guess it will be better to reduce the height of the time line abit and increase the servo controller height.

@rahul31124 Thank you for the layout changes. Now Flutter does not complain about the width anymore but the height on my phone:

Screenshot_20250616-130815

This is the exception from the log: exception.txt

I know that my device is a little bit quirky...

Could you also please react to the sourcery-ai comments. If they don't make any sense, saying that is also a valid reaction. If you already did some changes which void the comments, please use the "resolve conversation" buttons to hide the commnets. This makes life a little bit easier for the reviewers.

@rahul31124
Copy link
Collaborator Author

Hello @marcnause, it would be better if you could share a video of the screen.

@marcnause
Copy link
Contributor

@rahul31124 Here is a video of the app in deubg mode on my phone.

screen-recording-20250617-110628_lU07Qcfd.mp4

I switched off the screen of the phone after the Robotic Arm screen was displayed. When I switched on the screen again, the layout fills the whole screen where it left a margin on the right before the screen was turned off. This may be a quirk of my phone, I saw a similar behavior with the old app too.

The warning is visible at the bottom of screen before and after I turned off the screen.

I think this is a minor issue which is probably limited to some older devices. If this blocks your progress, we can track this as a know issue in a separate ticket and come back to it later.

@rahul31124
Copy link
Collaborator Author

@marcnause,
Most likely, the issue is device-specific, as I’ve tested the Robotic Arm screen on 4–5 emulators and my personal phone and didn’t encounter this behavior.

I’ve also made improvements to the UI layout in the upcoming PR related to this issue: #2734, and I’ll include those changes in the next commit.

@marcnause
Copy link
Contributor

@marcnause, Most likely, the issue is device-specific

Since the device is my test device I will automatically keep an eye on it as the screen progresses and maybe it makes most sense if I try to fix it since I have access to the device and I can see the results of changes faster than you.

@AsCress
Copy link
Collaborator

AsCress commented Jun 20, 2025

@rahul31124 This would most certainly need layout building in a way that they are responsive, even on small screen sizes. In flutter, you can always create layouts which scale properly on all screen sizes, regardless of how small the screen is.
We can have a 1:1 on this if you'd like me to go through the general details on building such layouts and the components in this PR which cause a problem.
You can always take up those changes in a later PR though. If you want, I can merge this one now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flutter Status: Review Required Requested reviews from peers and maintainers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implementation of Robotic Arm Screen
3 participants