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-802] Add generic servo driver #1585

Merged
merged 8 commits into from
Nov 11, 2022
Merged

Conversation

npmenard
Copy link
Member

This is an implementation of a generic servo driver. This is supposed to work with any GPIO pins implementing PWM, to properly scale the movement of the servo we need to have an understanding of the underlying hardware resolution to do so we have a search function that estimate the underlying pwm timer resolution.

I have an holdPos attribute in the config (to mimick the pi implementation) in the pi implementation if set to false it would stop the pwm signal (servo torque to 0) after a certain time. I chose not to implement it since I can't think of a reasonable case where we would want to the servo torque to be 0. I am tempted to remove it altogether but would like other people's input !

@npmenard npmenard added the safe to test This pull request is marked safe to test from a trusted zone label Nov 10, 2022
@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 Nov 10, 2022
@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 Nov 10, 2022
@penguinland
Copy link
Member

penguinland commented Nov 10, 2022

I am tempted to remove [holdPos] altogether but would like other people's input

My instinct is that anything not actively in use or tested should be removed. If you don't plan to use that feature, it's dead code and might have bugs creep in over time, so get rid of it for now and we can add it back in if it becomes important in the future.

@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 Nov 10, 2022
@npmenard
Copy link
Member Author

I am tempted to remove [holdPos] altogether but would like other people's input

My instinct is that anything not actively in use or tested should be removed. If you don't plan to use that feature, it's dead code and might have bugs creep in over time, so get rid of it for now and we can add it back in if it becomes important in the future.

Agreed

Copy link
Member

@penguinland penguinland left a comment

Choose a reason for hiding this comment

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

Stopping for the day. I'm only halfway through the PR, but all my feedback is minor, and this code looks very good so far!

components/board/hat/pca9685/pca9685.go Outdated Show resolved Hide resolved
I2CAddress *int `json:"i2c_address"`
BoardName string `json:"board_name"`
I2CName string `json:"i2c_name"`
I2CAddress *int `json:"i2c_address"`
Copy link
Member

Choose a reason for hiding this comment

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

Mild curiosity: why is this a pointer-to-int instead of a mere int? Doesn't that open us up to shenanigans if someone modifies the value it points at? (The correct response is probably "Alan, that's off-topic for this PR and should be discussed at a later date instead of now.")

Copy link
Member Author

Choose a reason for hiding this comment

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

answered below

const (
minDeg float64 = 0.0
maxDeg float64 = 180.0
minWidthUs uint = 500 // absolute minimum width pwm width
Copy link
Member

Choose a reason for hiding this comment

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

Comment feels like it has too many "widths" in it. Would "absolute minimum PWM width" still make sense?

Copy link
Member Author

Choose a reason for hiding this comment

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

agreed

// MinDeg minimum angle the servo can reach, note this doesn't affect PWM calculation
MinDeg *float64 `json:"min_angle_deg,omitempty"`
// MaxDeg maximum angle the servo can reach, note this doesn't affect PWM calculation
MaxDeg *float64 `json:"max_angle_deg,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Same question here re: storing references to our data instead of our data itself. Why have a *float64 instead of a float64 itself? What happens if someone else changes our underlying data?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's a neat trick to avoid defining default value, for example if it wasn't a pointer and a user didn't reference this field it would be initialized to 0.0 by default. Now for minDeg it's fine but for max we have an issue :) Also we consume the config struct and never reference it again, and we can reasonably assume that nothing is going to change anything while we read it

components/servo/generic/servo.go Show resolved Hide resolved
period := 1.0 / float64(frequency) // dutyCycle in s
pwmWidthus := pct * period * 1000 * 1000
rSpan := maxDeg - minDeg // servo moves from 0 to 180 deg
lSpan := float64(maxUs - minUs) // pulse width between 1ms to 2ms to s
Copy link
Member

Choose a reason for hiding this comment

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

Same suggestions here re: comments not matching code and variable names being confusing. Maybe degRange and usRange instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

:+1

pwmWidthus = float64(minUs)
}
if pwmWidthus > float64(maxUs) {
pwmWidthus = float64(maxUs)
Copy link
Member

Choose a reason for hiding this comment

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

Mild preference for

pwmWidthus = math.max(pwmWidthus, minUs)
pwmWidthus = math.min(pwmWidthus, maxUs)

which I suspect is more idiomatic.

Copy link
Member Author

Choose a reason for hiding this comment

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

👍


angle := math.Round(minDeg + (pwmWidthus-float64(minUs))*scale)

return angle
Copy link
Member

Choose a reason for hiding this comment

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

Slight preference to just return on line 217, rather than define a variable there that just gets returned here. but I'm open to disagreement.

Copy link
Member Author

Choose a reason for hiding this comment

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

👍

return angle
}

// Attempt to find the PWM resolution assuming an hardware PWM
Copy link
Member

Choose a reason for hiding this comment

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

Typo: "assuming a hardware PWM"


// Attempt to find the PWM resolution assuming an hardware PWM
// Assumption :
// 1. 16,15,14,12,or 8 bit timer
Copy link
Member

Choose a reason for hiding this comment

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

I have no idea what this means. Was this line supposed to be removed before the PR went out? If not, put in more words to explain it better.

@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 Nov 11, 2022
@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 Nov 11, 2022
Copy link
Member

@randhid randhid left a comment

Choose a reason for hiding this comment

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

A few minor nitpicks here and there.

The 'pi' servo holdPos was added for hackweek where the servos were burning themselves out because they were not zeroed before being assembled with the yahbooms. It dictates a timeout to stop the servo from continuously trying to get to a position, it is not needed in generic servo at all. We can remove it at a later date, I don't think it's important now and it is kinder to those $1 servos. I'd just keep it in there until we need to break it.

components/servo/generic/servo.go Show resolved Hide resolved
components/servo/generic/servo.go Show resolved Hide resolved
components/servo/generic/servo.go Outdated Show resolved Hide resolved
components/servo/generic/servo.go Show resolved Hide resolved
components/servo/generic/servo.go Outdated Show resolved Hide resolved
components/servo/generic/servo.go Outdated Show resolved Hide resolved
components/servo/generic/servo.go Outdated Show resolved Hide resolved
components/board/hat/pca9685/pca9685.go Outdated Show resolved Hide resolved
@npmenard npmenard requested a review from randhid November 11, 2022 17:28
@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 Nov 11, 2022
@github-actions
Copy link
Contributor

Code Coverage

Package Line Rate Delta Health
go.viam.com/rdk/components/arm 59% 0.00%
go.viam.com/rdk/components/arm/universalrobots 12% 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.34%
go.viam.com/rdk/components/base 68% 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 69% 0.00%
go.viam.com/rdk/components/board/arduino 10% 0.00%
go.viam.com/rdk/components/board/commonsysfs 47% 0.00%
go.viam.com/rdk/components/board/fake 38% 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 66% 0.00%
go.viam.com/rdk/components/camera/fake 67% 0.00%
go.viam.com/rdk/components/camera/ffmpeg 77% +1.43%
go.viam.com/rdk/components/camera/transformpipeline 80% +0.41%
go.viam.com/rdk/components/camera/videosource 56% -0.17%
go.viam.com/rdk/components/encoder/fake 77% 0.00%
go.viam.com/rdk/components/gantry 68% 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 84% 0.00%
go.viam.com/rdk/components/gripper 81% 0.00%
go.viam.com/rdk/components/input 86% 0.00%
go.viam.com/rdk/components/input/gpio 83% 0.00%
go.viam.com/rdk/components/motor 82% 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 58% 0.00%
go.viam.com/rdk/components/motor/gpio 64% 0.00%
go.viam.com/rdk/components/motor/gpiostepper 57% 0.00%
go.viam.com/rdk/components/motor/tmcstepper 62% 0.00%
go.viam.com/rdk/components/movementsensor 76% 0.00%
go.viam.com/rdk/components/movementsensor/cameramono 40% 0.00%
go.viam.com/rdk/components/movementsensor/gpsnmea 37% 0.00%
go.viam.com/rdk/components/movementsensor/gpsrtk 28% 0.00%
go.viam.com/rdk/components/posetracker 87% 0.00%
go.viam.com/rdk/components/sensor 87% 0.00%
go.viam.com/rdk/components/sensor/ultrasonic 34% 0.00%
go.viam.com/rdk/components/servo 79% 0.00%
go.viam.com/rdk/components/servo/generic 71% N/A
go.viam.com/rdk/config 76% +0.08%
go.viam.com/rdk/control 57% 0.00%
go.viam.com/rdk/data 77% 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/motionplan 71% +2.34%
go.viam.com/rdk/operation 81% 0.00%
go.viam.com/rdk/pointcloud 71% 0.00%
go.viam.com/rdk/protoutils 62% 0.00%
go.viam.com/rdk/referenceframe 78% 0.00%
go.viam.com/rdk/registry 88% 0.00%
go.viam.com/rdk/resource 85% 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 73% 0.00%
go.viam.com/rdk/rimage/transform/cmd/extrinsic_calibration 67% 0.00%
go.viam.com/rdk/robot 93% 0.00%
go.viam.com/rdk/robot/client 81% 0.00%
go.viam.com/rdk/robot/framesystem 68% 0.00%
go.viam.com/rdk/robot/impl 79% +0.24%
go.viam.com/rdk/robot/server 59% +0.97%
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 75% 0.00%
go.viam.com/rdk/services/armremotecontrol/builtin 25% 0.00%
go.viam.com/rdk/services/baseremotecontrol 75% 0.00%
go.viam.com/rdk/services/baseremotecontrol/builtin 66% 0.00%
go.viam.com/rdk/services/datamanager 66% 0.00%
go.viam.com/rdk/services/datamanager/builtin 80% 0.00%
go.viam.com/rdk/services/datamanager/datacapture 21% 0.00%
go.viam.com/rdk/services/datamanager/datasync 72% 0.00%
go.viam.com/rdk/services/motion 68% 0.00%
go.viam.com/rdk/services/motion/builtin 89% 0.00%
go.viam.com/rdk/services/navigation 54% 0.00%
go.viam.com/rdk/services/sensors 78% 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 72% 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/spatialmath 85% 0.00%
go.viam.com/rdk/subtype 96% 0.00%
go.viam.com/rdk/utils 71% 0.00%
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% (19496 / 29430) +0.19%

@npmenard npmenard merged commit d4022a6 into viamrobotics:main Nov 11, 2022
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.

4 participants