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

[RSDK-1008] Add GPIO support for Jetson Orin #1810

Merged
merged 26 commits into from
Feb 3, 2023

Conversation

penguinland
Copy link
Member

Tried on a Jetson Orin: both reading and writing both high and low values work great! Not yet tried on a rpi or BeagleBone, but I will do both of those before merging.

As Nicolas notes, it sucks to have 3 different implementations of GPIO stuff, and it would be wonderful to get down to a single approach that works everywhere. It's obvious why the pigpio approach doesn't work on a non-rpi board, and we've discussed why the periph.io approach doesn't work on the Orin. It would be neat to use the ioctl approach everywhere eventually, but that doesn't need to happen immediately.

I learned great things from https://blog.lxsang.me/post/id/33 about how to use ioctl, and from https://github.com/mkch/gpio for how to do this in Go.

I don't like how much duplication there is between ioctlPin.Set and ioctlPin.Get, but couldn't see an easy way to remove it: abstracting out a helper function to, say, open the device actually makes the code longer because you need to check the return value for errors, and the values to construct a gpioHandleRequest object are different enough that a helper function feels contrived to me.

I'm tagging Rand to review this PR because she knows good things from the BeagleBone, but part of me says Rand is already very busy and I ought to tag Gautham instead, because he's planning to look at the Jetson boards in the near future.

@viambot viambot added the safe to test This pull request is marked safe to test from a trusted zone label Jan 27, 2023
@edaniels edaniels self-requested a review January 27, 2023 04:59
Copy link
Contributor

@edaniels edaniels left a comment

Choose a reason for hiding this comment

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

Done with first pass. Main question is understanding why we didn't use a referenced library. Otherwise, this looks clean mod a refactor

components/board/commonsysfs/ioctl.go Outdated Show resolved Hide resolved
components/board/commonsysfs/ioctl.go Outdated Show resolved Hide resolved
components/board/commonsysfs/board.go Outdated Show resolved Hide resolved
components/board/commonsysfs/ioctl.go Outdated Show resolved Hide resolved
components/board/commonsysfs/ioctl.go Outdated Show resolved Hide resolved

// This helps implement the board.GPIOPin interface for ioctlPin.
func (pin *ioctlPin) SetPWM(ctx context.Context, dutyCyclePct float64, extra map[string]interface{}) error {
return errors.New("PWM stuff is not supported on ioctl pins yet")
Copy link
Contributor

Choose a reason for hiding this comment

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

will it be possible to support it in ioctl?

Copy link
Member Author

Choose a reason for hiding this comment

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

Eric and I discussed: the answer isn't very clear. By default, it doesn't seem like ioctl has PWM capabilities already built out, but there are folks online who have created such an interface (e.g., here's BeagleBone instructions). How hard would this be to generalize to other boards? I don't know. It's outside the scope of the current ticket/PR, and Eric's question was mere curiosity and not a blocker.

@stevebriskin stevebriskin self-requested a review January 27, 2023 22:20
@randhid randhid requested review from gvaradarajan and removed request for randhid January 30, 2023 15:48
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone viam-org Is part of the viamrobotics organization. "safe to test" and removed safe to test This pull request is marked safe to test from a trusted zone labels Jan 31, 2023
@penguinland
Copy link
Member Author

I'm gonna go resolve merge conflicts, but in the meantime I think I've addressed all of Eric's feedback. Things still work great on the Jetson Orin (GPIO can output low or high, or read low or high signals as input). I still want to test in further detail on a BeagleBone before merging because this does change all the boards formerly referred to as commonsysfs (now genericlinux). but I'm not expecting any surprises/trouble from that.

Copy link
Member

@gvaradarajan gvaradarajan left a comment

Choose a reason for hiding this comment

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

LGTM, I don't have any comments (except that I love the name change from commonsysfs to genericlinux). I'll approve once I manage to test the PR on hardware

@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 2, 2023
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 3, 2023
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 3, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2023

Code Coverage

Package Line Rate Delta Health
go.viam.com/rdk/components/arm 56% 0.00%
go.viam.com/rdk/components/arm/universalrobots 41% 0.00%
go.viam.com/rdk/components/arm/xarm 2% 0.00%
go.viam.com/rdk/components/arm/yahboom 7% 0.00%
go.viam.com/rdk/components/audioinput 55% 0.00%
go.viam.com/rdk/components/base 63% 0.00%
go.viam.com/rdk/components/base/agilex 62% 0.00%
go.viam.com/rdk/components/base/boat 41% 0.00%
go.viam.com/rdk/components/base/wheeled 76% 0.00%
go.viam.com/rdk/components/board 66% 0.00%
go.viam.com/rdk/components/board/arduino 10% 0.00%
go.viam.com/rdk/components/board/fake 38% 0.00%
go.viam.com/rdk/components/board/genericlinux 41% N/A
go.viam.com/rdk/components/board/numato 19% 0.00%
go.viam.com/rdk/components/board/pi 50% 0.00%
go.viam.com/rdk/components/camera 65% 0.00%
go.viam.com/rdk/components/camera/align 64% -0.48%
go.viam.com/rdk/components/camera/fake 64% 0.00%
go.viam.com/rdk/components/camera/ffmpeg 77% 0.00%
go.viam.com/rdk/components/camera/transformpipeline 78% -0.62%
go.viam.com/rdk/components/camera/videosource 46% 0.00%
go.viam.com/rdk/components/encoder 4% 0.00%
go.viam.com/rdk/components/encoder/fake 76% 0.00%
go.viam.com/rdk/components/gantry 60% 0.00%
go.viam.com/rdk/components/gantry/multiaxis 84% 0.00%
go.viam.com/rdk/components/gantry/oneaxis 86% 0.00%
go.viam.com/rdk/components/generic 83% 0.00%
go.viam.com/rdk/components/gripper 68% 0.00%
go.viam.com/rdk/components/input 87% 0.00%
go.viam.com/rdk/components/input/gpio 84% 0.00%
go.viam.com/rdk/components/motor 77% 0.00%
go.viam.com/rdk/components/motor/dimensionengineering 63% 0.00%
go.viam.com/rdk/components/motor/dmc4000 69% 0.00%
go.viam.com/rdk/components/motor/fake 57% 0.00%
go.viam.com/rdk/components/motor/gpio 64% 0.00%
go.viam.com/rdk/components/motor/gpiostepper 57% +0.59%
go.viam.com/rdk/components/motor/tmcstepper 62% 0.00%
go.viam.com/rdk/components/movementsensor 75% 0.00%
go.viam.com/rdk/components/movementsensor/cameramono 46% 0.00%
go.viam.com/rdk/components/movementsensor/gpsnmea 36% 0.00%
go.viam.com/rdk/components/movementsensor/gpsrtk 28% 0.00%
go.viam.com/rdk/components/posetracker 86% 0.00%
go.viam.com/rdk/components/sensor 86% 0.00%
go.viam.com/rdk/components/sensor/ultrasonic 26% 0.00%
go.viam.com/rdk/components/servo 68% 0.00%
go.viam.com/rdk/components/servo/gpio 71% 0.00%
go.viam.com/rdk/config 75% 0.00%
go.viam.com/rdk/control 57% 0.00%
go.viam.com/rdk/data 79% 0.00%
go.viam.com/rdk/examples/customresources/demos/complexmodule 0% 0.00%
go.viam.com/rdk/examples/customresources/demos/remoteserver 0% 0.00%
go.viam.com/rdk/grpc 25% 0.00%
go.viam.com/rdk/ml 67% 0.00%
go.viam.com/rdk/ml/inference 70% 0.00%
go.viam.com/rdk/module 64% 0.00%
go.viam.com/rdk/module/modmanager 79% 0.00%
go.viam.com/rdk/motionplan 69% -0.15%
go.viam.com/rdk/operation 82% 0.00%
go.viam.com/rdk/pointcloud 73% -0.08%
go.viam.com/rdk/protoutils 59% 0.00%
go.viam.com/rdk/referenceframe 72% 0.00%
go.viam.com/rdk/registry 89% 0.00%
go.viam.com/rdk/resource 84% 0.00%
go.viam.com/rdk/rimage 78% 0.00%
go.viam.com/rdk/rimage/depthadapter 94% 0.00%
go.viam.com/rdk/rimage/transform 75% 0.00%
go.viam.com/rdk/rimage/transform/cmd/extrinsic_calibration 67% 0.00%
go.viam.com/rdk/robot 85% -0.95%
go.viam.com/rdk/robot/client 81% 0.00%
go.viam.com/rdk/robot/framesystem 65% 0.00%
go.viam.com/rdk/robot/impl 80% 0.00%
go.viam.com/rdk/robot/server 55% -0.59%
go.viam.com/rdk/robot/web 61% 0.00%
go.viam.com/rdk/robot/web/stream 87% 0.00%
go.viam.com/rdk/services/armremotecontrol 71% 0.00%
go.viam.com/rdk/services/armremotecontrol/builtin 52% 0.00%
go.viam.com/rdk/services/baseremotecontrol 71% 0.00%
go.viam.com/rdk/services/baseremotecontrol/builtin 79% 0.00%
go.viam.com/rdk/services/datamanager 79% 0.00%
go.viam.com/rdk/services/datamanager/builtin 78% 0.00%
go.viam.com/rdk/services/datamanager/datacapture 70% 0.00%
go.viam.com/rdk/services/datamanager/datasync 0% 0.00%
go.viam.com/rdk/services/motion 63% 0.00%
go.viam.com/rdk/services/motion/builtin 88% 0.00%
go.viam.com/rdk/services/navigation 53% 0.00%
go.viam.com/rdk/services/sensors 77% 0.00%
go.viam.com/rdk/services/sensors/builtin 97% 0.00%
go.viam.com/rdk/services/shell 14% 0.00%
go.viam.com/rdk/services/slam 85% 0.00%
go.viam.com/rdk/services/slam/builtin 70% 0.00%
go.viam.com/rdk/services/vision 80% 0.00%
go.viam.com/rdk/services/vision/builtin 74% 0.00%
go.viam.com/rdk/session 97% 0.00%
go.viam.com/rdk/spatialmath 84% 0.00%
go.viam.com/rdk/subtype 92% 0.00%
go.viam.com/rdk/utils 72% +0.18%
go.viam.com/rdk/vision 26% 0.00%
go.viam.com/rdk/vision/chess 80% 0.00%
go.viam.com/rdk/vision/delaunay 87% 0.00%
go.viam.com/rdk/vision/keypoints 92% 0.00%
go.viam.com/rdk/vision/objectdetection 82% 0.00%
go.viam.com/rdk/vision/odometry 60% 0.00%
go.viam.com/rdk/vision/odometry/cmd 0% 0.00%
go.viam.com/rdk/vision/segmentation 49% 0.00%
go.viam.com/rdk/web/server 25% 0.00%
Summary 65% (21610 / 33053) -0.12%

@edaniels
Copy link
Contributor

edaniels commented Feb 3, 2023

General question: Are we comfortable with using centralized compatibility logic to get pin mapping? It feels like if we know the model name (e.g. jetson orin nx), we can give priority to the jetsonOrin pin mapping. The approach we're taking now is calling the model "jetson" and expecting it to get the right pin out. Not sure if how if or how we'd detect other board features that the board may support (e.g. gpu cores) if we continue with this approach. (Not a blocker, general question) CC @edaniels

I think for now it's okay but if we start seeing any more divergence in behavior that makes generalization harder. We can freeze this model and add jetson-* versions

Copy link
Contributor

@edaniels edaniels left a comment

Choose a reason for hiding this comment

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

LGTM!

@penguinland penguinland merged commit 7103d44 into viamrobotics:main Feb 3, 2023
@penguinland penguinland deleted the ioctl branch February 3, 2023 18:53
penguinland added a commit that referenced this pull request Feb 3, 2023
This is a follow-up to #1810. Data is taken from https://github.com/NVIDIA/jetson-gpio/blob/master/lib/python/Jetson/GPIO/gpio_pin_data.py#L53-L80. I can't test this out because the Jetson Orin NX hardware is not yet on the market (we have the higher-end Orin AGX, whose pin definitions are already in here and are different from the NX). but I'd sure expect that NVidia's github repo contains accurate data regarding NVidia's own hardware.
penguinland added a commit that referenced this pull request Feb 23, 2023
This is a follow-up to #1810. Thanks to Pete G for noticing the issue! 

We've been acquiring file descriptors for each GPIO pin, setting their direction to input/output, and if output, setting their value, and then closing the files again. It turns out that when you close the file, the value of the output is undetermined: the pin I tried last time (pin 40) keeps its most recent value, but pins like 37 and 32 float instead.

So, this PR holds the file descriptors open for the remainder of the program (once they're opened for the first time). That way, the GPIO pins keep the same output all the way until the next time you change one of them.
randhid pushed a commit to randhid/rdk that referenced this pull request Feb 25, 2023
Tried on a Jetson Orin: both reading and writing both high and low values work great! Also tried on a BeagleBone AI-64: GPIO behavior is unchanged.

As Nicolas notes, it sucks to have 3 different implementations of GPIO stuff, and it would be wonderful to get down to a single approach that works everywhere. It's obvious why the pigpio approach doesn't work on a non-rpi board, and we've discussed why the periph.io approach doesn't work on the Orin. It would be neat to use the ioctl approach everywhere eventually, but that doesn't need to happen immediately.

I learned great things from https://blog.lxsang.me/post/id/33 about how to use ioctl, and from https://github.com/mkch/gpio for how to do this in Go.

I don't like how much duplication there is between `ioctlPin.Set` and `ioctlPin.Get`, but couldn't see an easy way to remove it: abstracting out a helper function to, say, open the device actually makes the code longer because you need to check the return value for errors, and the values to construct a `gpioHandleRequest` object are different enough that a helper function feels contrived to me.
randhid pushed a commit to randhid/rdk that referenced this pull request Feb 25, 2023
This is a follow-up to viamrobotics#1810. Data is taken from https://github.com/NVIDIA/jetson-gpio/blob/master/lib/python/Jetson/GPIO/gpio_pin_data.py#L53-L80. I can't test this out because the Jetson Orin NX hardware is not yet on the market (we have the higher-end Orin AGX, whose pin definitions are already in here and are different from the NX). but I'd sure expect that NVidia's github repo contains accurate data regarding NVidia's own hardware.
randhid pushed a commit to randhid/rdk that referenced this pull request Feb 25, 2023
…s#1896)

This is a follow-up to viamrobotics#1810. Thanks to Pete G for noticing the issue! 

We've been acquiring file descriptors for each GPIO pin, setting their direction to input/output, and if output, setting their value, and then closing the files again. It turns out that when you close the file, the value of the output is undetermined: the pin I tried last time (pin 40) keeps its most recent value, but pins like 37 and 32 float instead.

So, this PR holds the file descriptors open for the remainder of the program (once they're opened for the first time). That way, the GPIO pins keep the same output all the way until the next time you change one of them.
biotinker pushed a commit to biotinker/robotcore that referenced this pull request Mar 16, 2023
Tried on a Jetson Orin: both reading and writing both high and low values work great! Also tried on a BeagleBone AI-64: GPIO behavior is unchanged.

As Nicolas notes, it sucks to have 3 different implementations of GPIO stuff, and it would be wonderful to get down to a single approach that works everywhere. It's obvious why the pigpio approach doesn't work on a non-rpi board, and we've discussed why the periph.io approach doesn't work on the Orin. It would be neat to use the ioctl approach everywhere eventually, but that doesn't need to happen immediately.

I learned great things from https://blog.lxsang.me/post/id/33 about how to use ioctl, and from https://github.com/mkch/gpio for how to do this in Go.

I don't like how much duplication there is between `ioctlPin.Set` and `ioctlPin.Get`, but couldn't see an easy way to remove it: abstracting out a helper function to, say, open the device actually makes the code longer because you need to check the return value for errors, and the values to construct a `gpioHandleRequest` object are different enough that a helper function feels contrived to me.
biotinker pushed a commit to biotinker/robotcore that referenced this pull request Mar 16, 2023
This is a follow-up to viamrobotics#1810. Data is taken from https://github.com/NVIDIA/jetson-gpio/blob/master/lib/python/Jetson/GPIO/gpio_pin_data.py#L53-L80. I can't test this out because the Jetson Orin NX hardware is not yet on the market (we have the higher-end Orin AGX, whose pin definitions are already in here and are different from the NX). but I'd sure expect that NVidia's github repo contains accurate data regarding NVidia's own hardware.
biotinker pushed a commit to biotinker/robotcore that referenced this pull request Mar 16, 2023
…s#1896)

This is a follow-up to viamrobotics#1810. Thanks to Pete G for noticing the issue! 

We've been acquiring file descriptors for each GPIO pin, setting their direction to input/output, and if output, setting their value, and then closing the files again. It turns out that when you close the file, the value of the output is undetermined: the pin I tried last time (pin 40) keeps its most recent value, but pins like 37 and 32 float instead.

So, this PR holds the file descriptors open for the remainder of the program (once they're opened for the first time). That way, the GPIO pins keep the same output all the way until the next time you change one of them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
safe to test This pull request is marked safe to test from a trusted zone viam-org Is part of the viamrobotics organization.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants