Skip to content
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

New Feature: Single Step Debugger Support #49

Open
gerth2 opened this issue Dec 22, 2023 · 4 comments
Open

New Feature: Single Step Debugger Support #49

gerth2 opened this issue Dec 22, 2023 · 4 comments
Labels
enhancement New feature or request

Comments

@gerth2
Copy link

gerth2 commented Dec 22, 2023

Problem description

Basic debug support through debugpy works well today with vsCode.

Documenting this here for potential future integration.

Overall design goal: single-click debugger activation that lets you walk code line by line on a development computer, while execution is happening on the RIO.

  1. Standard vsCode python extensions
  2. install debugpy on both the RIO and local desktop
  3. Add a vsCode task to start the robot in debug mode - for us, this involves dropping a blank file with a magic name in the RIO's filesystem, then restarting the robot code
  4. a small snippet of code in the robot main code to detect the "wait for debugger" file trigger and wait for a debug connection.

tasks.json:

        {
            "label": "PyFRC: _Activate Debug",
            "type": "shell",
            "windows": {
                "command": "ssh [email protected] -t 'chmod +x ./robotCommand; touch /home/lvuser/py/enableDebug; ./robotCommand || true; echo Waiting for robot program to start...; sleep 5' "
            },
            "linux": {
                "command": "ssh [email protected] -t 'chmod +x ./robotCommand; touch /home/lvuser/py/enableDebug; ./robotCommand || true; echo Waiting for robot program to start...; sleep 5' "
            },
            "group": {
                "kind": "build",
            },
            "presentation": {
                "reveal": "always",
                "panel": "dedicated",
                "clear": true,
                "focus": true,
                "showReuseMessage": false
            },
            "problemMatcher": [],
            "icon": {
                "id": "cloud-upload"
            }
        },

launch.json:

...
        {
            "name": "Debug RoboRIO",
            "type": "python",
            "request": "attach",
            "connect": {
                "host": "roboRIO-1736-frc.local",
                "port": 5678
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}",
                    "remoteRoot": "/home/lvuser/py"
                }
            ],
            "justMyCode": true,
            "preLaunchTask": "PyFRC: _Activate Debug"
        },
...

Robot Code:

if __name__ == '__main__':

    enableDebug = os.path.isfile("/home/lvuser/py/enableDebug")
    if(enableDebug):
        print("Starting Debug Support....")
        import debugpy 
        debugpy.listen(('0.0.0.0', 5678))
        debugpy.wait_for_client()

    wpilib.run(MyRobot)

The real trick is just to make sure the robot code gets restarted with the correct value for enableDebug - it does slow down execution noticeably, and isn't something I think you'd want all the time.

I've got no idea if there's a better way than a file (environment variables?), but that just seemed to be the most reliable way.

One nice thingabout using a file: if the code is simply redeployed, the file is wiped away, so the code goes back to "normal/non-debug" mode.

Hopefully helps? Other than the funkiness of the file itself, I'd highly recommend the rest.

Operating System

Windows

Installed Python Packages

N/A

Reproducible example code

N/A
@auscompgeek
Copy link
Member

you can deploy in debug mode already, no need for a complex ssh command

./robot.py deploy --debug

this can be detected with __debug__ e.g.

if __name__ == "__main__":
    if __debug__:
        try:
            import debugpy
        except ModuleNotFoundError:
            pass
        else:
            debugpy.listen(('0.0.0.0', 5678))

    wpilib.run(MyRobot)

@gerth2
Copy link
Author

gerth2 commented Dec 22, 2023

that is way better than magic files. One moment please...

@gerth2
Copy link
Author

gerth2 commented Dec 22, 2023

https://github.com/RobotCasserole1736/firstRoboPy/blob/chris_daves_dandy_debug_design/.vscode/tasks.json

https://github.com/RobotCasserole1736/firstRoboPy/blob/chris_daves_dandy_debug_design/robot.py#L117

Updated, works well.

Tasks is a bit more complex now, to keep a "single button" paradigm I had to chain together the deploy with --debug and a short pause to let the RIO get up and running before the host PC tries to connect (otherwise vscode was giving me a connection refused error)

Also, in the code stnippet, I added inspection to check that we were indeed running the code, not deploying or simulating. Otherwise, it's likely that debug is true, which will stall things out.

I do think it's valid for teams to want to be able to walk through robotInit(), so I included the debugpy.wait_for_client() call to facilitate that.

@auscompgeek
Copy link
Member

See also previous discussion: robotpy/robotpy-wpilib#99

@auscompgeek auscompgeek added the enhancement New feature or request label Jan 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Todo
Development

No branches or pull requests

2 participants