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-2226] audit GPIO servo code #2283

Merged
merged 31 commits into from
Apr 27, 2023

Conversation

penguinland
Copy link
Member

Except for a few commits that added and removed debugging info along with other changes, my hope is that each commit is self-contained and this should be easy to review commit-by-commit if it's confusing all at once.

Important changes:

  • If the frequency is not specified in the config, we've always used the current frequency of the pin. However, if the pin's frequency is currently 0, we now default to a sane value (300 Hz, chosen to be slightly slower than the default maximum of 400 Hz) instead!
  • If the frequency is so fast that we cannot move all the way to the max position (because it would require holding the signal high for longer than the period of the PWM), lower the frequency so that we could spend the maximum time high and the minimum time low.

Unimportant changes:

  • Don't capitalize the S in microseconds
  • Rename min and max to minDeg and maxDeg, to contrast with minUs and maxUs
  • Add more comments!
  • Comments: sentences start with capital letters and end with periods. PWM is capitalized.

Tried with 2 different servo motors (a TowerPro SG-5010 and a Bilda 2000-0025-0503) at my desk. They both work fine when plugged into a Jetson Orin AGX, and also both work fine when plugged into a raspberry pi. I tried plugging them into a PCA9685, but suspect I need to give it an extra power source to drive the motors: I could see the PWM signal change on the oscilloscope, but couldn't get either motor to move.

@penguinland penguinland requested a review from npmenard April 25, 2023 22:32
@viambot viambot added the safe to test This pull request is marked safe to test from a trusted zone label Apr 25, 2023
// before going high afterwards. Let's stay low for at least minUs microseconds, and make sure
// the frequency is slow enough that we can do this.
if maxFrequency := 1e6 / (minUs + maxUs); frequency > maxFrequency {
logger.Warnf("servo frequency (%f.1) is above maximum (%f.1), setting to max instead",
Copy link
Member

Choose a reason for hiding this comment

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

cool :) does the calculated frequency gets floored in this case? also why do minUs+maxUs if at most we should turn on the PWM for maxUs?

Copy link
Member Author

Choose a reason for hiding this comment

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

If I set the GPIO pin to high (duty cycle is 100%), it cuts power to the motor entirely. I infer that the servo needs some amount of time with the PWM signal low, so it can be confident it knows how long it was high. What's the minimum time it can be low? I dunno; probably the same as the minimum it can be high, so the period should be at least minUs+maxUs. but I just made all that up, because I don't actually know how servos work.

Copy link
Member Author

Choose a reason for hiding this comment

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

The amount of time the signal needs to spend low is the "dead band width," and the motors I've seen so far have it in the 1-10 microsecond range. My defaulting to 500 microseconds is super overkill. I'll change this to go faster.

Copy link
Member

Choose a reason for hiding this comment

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

make sense i'll defer to you to select the best value but would suggest 100us to be on the safe side :P

Copy link
Member Author

Choose a reason for hiding this comment

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

100 seems exceptionally slow, but I bumped it up to 50. You're right that 10 was probably too fast for a global maximum.

@npmenard
Copy link
Member

LGTM with a couple of comments, would be great to make sure the PCA board works. About the behavior does the driver find a resolution for the Orin board? if so what does it looks like? Since the search function assume hardware PWM i want to make sure the it doesn't have a weird behavior there.
Lastly did you test it using the app.viam.com?

@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 Apr 26, 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 Apr 26, 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 Apr 26, 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 Apr 26, 2023
@penguinland
Copy link
Member Author

would be great to make sure the PCA board works.

It outputs the right signal, according to the oscilloscope. but I haven't gotten the motors to move, which makes me suspect that either it's doing it at the wrong voltage, or the wrong amperage. Both of those feel outside the scope of software: I could figure out how to hook up an external power supply to the PCA board, or something else like that, but I don't see how it could possibly affect this PR.

does the driver find a resolution for the Orin board? if so what does it looks like? Since the search function assume hardware PWM i want to make sure the it doesn't have a weird behavior there.

The Orin sets the resolution to 65535, both for hardware PWM and software PWM. Software PWM makes the motor wiggle around a whole lot, even at 50 Hz, because it's still total garbage. Hardware PWM works great.

Lastly did you test it using the app.viam.com?

Yes, the tests on both the pi and the orin were done through app.viam.com.

@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 Apr 27, 2023
@github-actions
Copy link
Contributor

Code Coverage

Package Line Rate Delta Health
go.viam.com/rdk/components/arm 64% 0.00%
go.viam.com/rdk/components/arm/fake 29% 0.00%
go.viam.com/rdk/components/arm/universalrobots 41% 0.00%
go.viam.com/rdk/components/arm/wrapper 21% 0.00%
go.viam.com/rdk/components/arm/xarm 23% 0.00%
go.viam.com/rdk/components/arm/yahboom 6% 0.00%
go.viam.com/rdk/components/audioinput 43% 0.00%
go.viam.com/rdk/components/base 41% 0.00%
go.viam.com/rdk/components/base/agilex 63% 0.00%
go.viam.com/rdk/components/base/boat 40% 0.00%
go.viam.com/rdk/components/base/fake 52% 0.00%
go.viam.com/rdk/components/base/wheeled 75% 0.00%
go.viam.com/rdk/components/board 60% 0.00%
go.viam.com/rdk/components/board/fake 40% 0.00%
go.viam.com/rdk/components/board/genericlinux 20% 0.00%
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 57% 0.00%
go.viam.com/rdk/components/camera/align 58% 0.00%
go.viam.com/rdk/components/camera/fake 74% 0.00%
go.viam.com/rdk/components/camera/ffmpeg 82% +1.49%
go.viam.com/rdk/components/camera/rtsp 46% +0.88%
go.viam.com/rdk/components/camera/transformpipeline 77% 0.00%
go.viam.com/rdk/components/camera/videosource 34% 0.00%
go.viam.com/rdk/components/encoder 57% 0.00%
go.viam.com/rdk/components/encoder/ams 64% 0.00%
go.viam.com/rdk/components/encoder/fake 83% 0.00%
go.viam.com/rdk/components/encoder/incremental 80% 0.00%
go.viam.com/rdk/components/encoder/single 86% 0.00%
go.viam.com/rdk/components/gantry 56% 0.00%
go.viam.com/rdk/components/gantry/multiaxis 87% 0.00%
go.viam.com/rdk/components/gantry/oneaxis 87% 0.00%
go.viam.com/rdk/components/generic 79% 0.00%
go.viam.com/rdk/components/gripper 69% 0.00%
go.viam.com/rdk/components/input 88% 0.00%
go.viam.com/rdk/components/input/fake 94% +1.49%
go.viam.com/rdk/components/input/gpio 85% 0.00%
go.viam.com/rdk/components/motor 71% 0.00%
go.viam.com/rdk/components/motor/dimensionengineering 65% 0.00%
go.viam.com/rdk/components/motor/dmc4000 70% 0.00%
go.viam.com/rdk/components/motor/fake 53% 0.00%
go.viam.com/rdk/components/motor/gpio 57% -0.20%
go.viam.com/rdk/components/motor/gpiostepper 51% -0.62%
go.viam.com/rdk/components/motor/tmcstepper 64% 0.00%
go.viam.com/rdk/components/motor/ulnstepper 53% 0.00%
go.viam.com/rdk/components/movementsensor 76% 0.00%
go.viam.com/rdk/components/movementsensor/adxl345 66% 0.00%
go.viam.com/rdk/components/movementsensor/cameramono 41% 0.00%
go.viam.com/rdk/components/movementsensor/gpsnmea 51% 0.00%
go.viam.com/rdk/components/movementsensor/gpsrtk 28% -5.18%
go.viam.com/rdk/components/movementsensor/mpu6050 84% 0.00%
go.viam.com/rdk/components/posetracker 71% 0.00%
go.viam.com/rdk/components/sensor 52% 0.00%
go.viam.com/rdk/components/sensor/ultrasonic 43% 0.00%
go.viam.com/rdk/components/servo 62% 0.00%
go.viam.com/rdk/components/servo/gpio 72% +0.09%
go.viam.com/rdk/config 79% 0.00%
go.viam.com/rdk/control 57% 0.00%
go.viam.com/rdk/data 77% 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/internal/cloud 100% 0.00%
go.viam.com/rdk/ml 67% 0.00%
go.viam.com/rdk/ml/inference 71% 0.00%
go.viam.com/rdk/module 76% 0.00%
go.viam.com/rdk/module/modmanager 80% 0.00%
go.viam.com/rdk/motionplan 71% +0.43%
go.viam.com/rdk/operation 82% 0.00%
go.viam.com/rdk/pointcloud 69% 0.00%
go.viam.com/rdk/protoutils 49% 0.00%
go.viam.com/rdk/referenceframe 72% 0.00%
go.viam.com/rdk/resource 75% 0.00%
go.viam.com/rdk/rimage 77% 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 86% 0.00%
go.viam.com/rdk/robot/client 82% 0.00%
go.viam.com/rdk/robot/framesystem 67% 0.00%
go.viam.com/rdk/robot/impl 82% 0.00%
go.viam.com/rdk/robot/packages 80% 0.00%
go.viam.com/rdk/robot/server 53% 0.00%
go.viam.com/rdk/robot/web 64% 0.00%
go.viam.com/rdk/robot/web/stream 87% 0.00%
go.viam.com/rdk/services/baseremotecontrol 50% 0.00%
go.viam.com/rdk/services/baseremotecontrol/builtin 82% 0.00%
go.viam.com/rdk/services/datamanager 65% 0.00%
go.viam.com/rdk/services/datamanager/builtin 85% -0.49%
go.viam.com/rdk/services/datamanager/datacapture 73% 0.00%
go.viam.com/rdk/services/datamanager/datasync 0% 0.00%
go.viam.com/rdk/services/mlmodel 83% 0.00%
go.viam.com/rdk/services/mlmodel/tflitecpu 81% 0.00%
go.viam.com/rdk/services/motion 51% 0.00%
go.viam.com/rdk/services/motion/builtin 85% 0.00%
go.viam.com/rdk/services/navigation 53% 0.00%
go.viam.com/rdk/services/sensors 81% 0.00%
go.viam.com/rdk/services/sensors/builtin 95% 0.00%
go.viam.com/rdk/services/shell 11% 0.00%
go.viam.com/rdk/services/slam 93% 0.00%
go.viam.com/rdk/services/slam/builtin 75% 0.00%
go.viam.com/rdk/services/slam/fake 90% 0.00%
go.viam.com/rdk/services/slam/slam_copy/config 97% 0.00%
go.viam.com/rdk/services/slam/slam_copy/dataprocess 71% 0.00%
go.viam.com/rdk/services/slam/slam_copy/utils 100% 0.00%
go.viam.com/rdk/services/vision 78% 0.00%
go.viam.com/rdk/services/vision/builtin 72% 0.00%
go.viam.com/rdk/session 97% 0.00%
go.viam.com/rdk/spatialmath 84% 0.00%
go.viam.com/rdk/utils 71% -0.14%
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 26% 0.00%
Summary 66% (22391 / 34000) -0.12%

@penguinland penguinland merged commit 54b5c5b into viamrobotics:main Apr 27, 2023
@penguinland penguinland deleted the servo_refactor branch April 27, 2023 16:52
bazile-clyde pushed a commit to bazile-clyde/rdk that referenced this pull request Jan 5, 2024
Important changes:
- If the frequency is not specified in the config, we've always used the current frequency of the pin. However, if the pin's frequency is currently 0, we now default to a sane value (300 Hz) instead!
- If the frequency is so fast that we cannot move all the way to the max position (because it would require holding the signal high for longer than the period of the PWM), lower the frequency so that we could spend the maximum time high and the minimum time low. 

Unimportant changes:
- Don't capitalize the S in microseconds
- Rename `min` and `max` to `minDeg` and `maxDeg`, to contrast with `minUs` and `maxUs`
- Add more comments!
- Comments: sentences start with capital letters and end with periods. PWM is capitalized.

Tried with 2 different servo motors (a TowerPro  SG-5010 and a Bilda 2000-0025-0503) at my desk. They both work fine when plugged into a Jetson Orin AGX, and also both work fine when plugged into a raspberry pi. I tried plugging them into a PCA9685, but suspect I need to give it an extra power source to drive the motors: I could see the PWM signal change on the oscilloscope, but couldn't get either motor to move.
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants