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

ElectroHydraulicPTO Motor Mode #99

Merged
merged 50 commits into from
Nov 21, 2022
Merged

ElectroHydraulicPTO Motor Mode #99

merged 50 commits into from
Nov 21, 2022

Conversation

andermi
Copy link
Collaborator

@andermi andermi commented Oct 6, 2022

WIP

  • make solver more robust
  • possibly combine rpm, pressure with electronics in solver
  • try computing Jacobian explicitly to use in solver
  • try smoothing interpolation with higher order splines
  • incorporate motor mode to drive piston with user commanded winding current and bias current
  • possibly add better battery model (or make a new branch)

@hamilton8415 I resurrected motor mode and made this draft PR so we could discuss things as we work out of this same branch

andermi added 11 commits August 23, 2022 17:49
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
@andermi andermi requested a review from hamilton8415 October 6, 2022 00:54

// solver.solve will use functor `df` function to obtain Jacobian instead of
// computing numerically
const int solver_info = solver.solve(this->dataPtr->x);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I set this to solve rather than solveNumericalDiff so it would use ElectroHydraulicSoln::df from our functor

Comment on lines 112 to 116
fjac(0, 0) = 1 - J_eff_v[0U] * SecondsPerMinute * this->Q / this->HydMotorDisp; // df0/dx0
fjac(0, 1) = -J_eff_v[1U] * SecondsPerMinute * this->Q / this->HydMotorDisp; // df0/dx1
fjac(1, 0) =
(-J_eff_m[0U] * T - eff_m * dTdx0) / (this->HydMotorDisp / (2.0 * M_PI)); // df1/dx0
fjac(1, 1) = 1 - J_eff_m[1U] * T / (this->HydMotorDisp / (2.0 * M_PI)); // df1/dx1
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

check my math?

@andermi
Copy link
Collaborator Author

andermi commented Oct 6, 2022

@andermi
Copy link
Collaborator Author

andermi commented Oct 6, 2022

check the comparison to the test machine:
ros2 launch buoy_tests experiment_comparison_select.launch.py manual:=true

@hamilton8415
Copy link
Collaborator

Very good, thanks for resurrecting this branch, I was looking into how to bring it up to date and you beat me to it (big surprise). One item perhaps to add to the todo list is a battery model improvement, which may or may not get itself tangled up in the solver. Currently the model used uses a constant EMF value, and an improvement would be a coloumb counter that would drive this Vemf up and down as the battery charges and discharges. The internal resistance of the battery may also be dependent upon the state of charge. I think this is orthogonal to the other work so maybe should be done in a second branch after this is done if it's not related to the solver, we will see. In any event, not a required simulation feature, but would be a nice touch. :)

Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
hamilton8415 and others added 5 commits October 11, 2022 21:38
…they are applied, depending now on which motor/pump quadrant the hydraulic motor is operating.
Signed-off-by: Michael Anderson <anderson@mbari.org>
Signed-off-by: Michael Anderson <anderson@mbari.org>
andermi and others added 5 commits November 1, 2022 11:35
…ckage

Signed-off-by: Michael Anderson <anderson@mbari.org>
package.  still need to modify code to reference these files.
occasionally not-converging, need to had error handling for this still.
@mjcarroll mjcarroll marked this pull request as ready for review November 14, 2022 19:50
@mjcarroll mjcarroll changed the base branch from main to mjcarroll/hydrodynamic_coeffs November 14, 2022 21:03
Signed-off-by: Michael Carroll <michael@openrobotics.org>
Base automatically changed from mjcarroll/hydrodynamic_coeffs to main November 14, 2022 21:44
@andermi
Copy link
Collaborator Author

andermi commented Nov 14, 2022

@hamilton8415, I just pushed updates to new tests and new launch files for manual vs ci

@hamilton8415
Copy link
Collaborator

@andermi @mjcarroll: I completed the linter work and checked the functionality of motormode in terms of the entire model and simulation, and of course also the tests related to the electro-hydraulic PTO. There are some CI errors, some output below. I'm hoping one of you could look into what's going in there as it's a bit out of my depth. I believe andermi did these originally. Thanks! Looking forward to getting this off the plate and onward with some smaller pull-requests. :)

2022-11-15T03:22:39.4222419Z The following tests FAILED:
2022-11-15T03:22:39.4224100Z 30 - launch_sc_commands_ros_feedback.launch.py (Failed)
2022-11-15T03:22:39.4225675Z 34 - launch_sc_pump_ros_feedback_py.launch.py (Failed)
2022-11-15T03:22:39.5858009Z Errors while running CTest
2022-11-15T03:22:39.5889542Z --- stderr: buoy_tests
2022-11-15T03:22:39.5891090Z Errors while running CTest

@andermi
Copy link
Collaborator Author

andermi commented Nov 15, 2022

Somehow I guess I did miss your comment here! Looking into it now.

Signed-off-by: Michael Anderson <anderson@mbari.org>
@andermi
Copy link
Collaborator Author

andermi commented Nov 15, 2022

I think we are good to go after a review

.gitignore Outdated
Comment on lines 7 to 13
splinter/include
splinter/lib
splinter/splinter
splinter/assets
splinter/CREDITS.md
splinter/docs
splinter/README_SPLINTER.md
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

could delete splinter reference here

double x = prismaticJointVelComp->Data().at(0);
this->dataPtr->functor.I_Wind.RamPosition = 40.0; // TODO(hamilton8415) x * 39.4;
double PistonPos = prismaticJointVelComp->Data().at(0);
this->dataPtr->functor.I_Wind.RamPosition = 40; // 2.03 - PistonPos * 39.4;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@hamilton8415, with this like it is, I don't think it's using your ascii art in WindingCurrentTarget like you planned.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, that's right. At the moment I've been leaving that feature disabled as it's a bit second order designed to protect the physical hardware, but it's harder to break metal things in simulation. It complicates the interpretation of how the PTO model is performing so while I do test those features in "WindingCurrentTarget.hpp", I've been thinking to let things settle in a simpler case before they're put into use...

Comment on lines 311 to 314
std::cout << "=================================" << std::endl;
std::cout << "Warning: Numericals solver in ElectroHydraulicPTO did not converge" << std::endl;
std::cout << "solver info: [" << solver_info << "]" << std::endl;
std::cout << "=================================" << std::endl;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

perhaps change std::cout to igndbg?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would use std::stringstream to append it all together and send it to igndbg all at once in that case.

std::stringstream ss;
ss << "foo\n";
ss << "bar\n";
igndbg << ss.str();

double tau_c = 0.1; // N-m
double k_v = .06 / 1000; // N-m/RPM
double k_th = 20;
return fabs((tau_c * tanh(2 * M_PI * N / 60 / k_th) + k_v * N / 1000) * N);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I get nervous about integer literals in division

Comment on lines 196 to 212
#if 0
int df(const VectorXd & x, MatrixXd & fjac)
{
const int n = x.size();
assert(fjac.rows() == n);
assert(fjac.cols() == n);
for (int k = 0; k < n; k++) {
for (int j = 0; j < n; j++) {
fjac(k, j) = 0.;
}
fjac(k, k) = 3. - 4. * x[k];
if (k) {fjac(k, k - 1) = -1.;}
if (k != n - 1) {fjac(k, k + 1) = -2.;}
}
return 0;
}
#endif
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ok to remove this section?

0.9400, 0.9390, 0.9380, 0.9370, 0.9360, 0.9370, 0.9360, 0.9350,
0.9320, 0.9300, 0.9200, 0.9100, 0.9000, 0.8400};
#endif
#if 0
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ok to remove section?

};
#if 1
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ok to make permanent?

Comment on lines 258 to 312
struct EffV
{
EffV() = default;

std::vector<double> df(const double & rpm, const double & pressure) const
{
double sech_ = 1.0 / cosh(2e-6 * (rpm + 55.0) * (pressure - 5000.0));

// rpm
double dfdx0 = 2.667e-11 * (pressure - 74268.6) * (pressure - 5000.0) * sech_ * sech_;

// pressure
double dfdx1 = 1.333e-5 * tanh(2e-6 * (rpm + 55.0) * (pressure - 5000.0)) +
2.667e-11 * (rpm + 55.0) * (pressure - 74268.6) * sech_ * sech_;

return std::vector<double>{dfdx0, dfdx1};
}

double operator()(const double & rpm, const double & pressure) const
{
return std::max(
0.5,
(-1.333e-5 * pressure + 0.99) * tanh((-2e-6 * pressure + 0.01) * (rpm + 55.0)));
}
};


struct EffM
{
EffM() = default;

std::vector<double> df(const double & rpm, const double & pressure) const
{
double sech_ = 1.0 / cosh(8e-8 * (rpm - 37500.0) * (pressure + 34.0));

// rpm
double dfdx0 = (4.2664e-13 * rpm - 7.84e-8) * (pressure + 34.0) * sech_ * sech_ -
5.333e-6 * tanh((-8e-8 * rpm + 0.003) * (pressure + 34.0));

// pressure
double dfdx1 = 4.2664e-13 * (rpm - 183761.0) * (rpm - 37500.0) * sech_ * sech_;

return std::vector<double>{dfdx0, dfdx1};
}

double operator()(const double & rpm, const double & pressure) const
{
if (pressure <= 10.0) {
return (2.5871e-14 * rpm + 7.9528e-9) * exp((-3.9e-6 * rpm + 1.25742) * pressure) + 0.1;
}
return std::max(
0.1,
(-5.333e-6 * rpm + 0.98) * tanh((-8e-8 * rpm + 0.003) * (pressure + 34.0)));
}
};
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it's ok to remove these as we aren't doing 2D interpolation anymore

Comment on lines 88 to 104
/*
double df(const double & N) const
{
if (current_override_) {
J_I = 0.0;
} else {
J_I = this->DefaultDamping.evalJacobian(fabs(N));
J_I *= this->ScaleFactor;

if (N > 0.0) {
J_I *= -this->RetractFactor;
}
}

return J_I;
}
*/
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

delete

Comment on lines +51 to +59
def find_proc(ld):
entities = ld.\
_IncludeLaunchDescription__launch_description_source.\
_LaunchDescriptionSource__launch_description.\
_LaunchDescription__entities
for entity in entities:
if type(entity) is Node:
if type(entity._Action__condition) is UnlessCondition:
return entity
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@mjcarroll, I wish there was a better way to do this... (used on line 78)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Whoa, what is this trying to do exactly?



namespace buoy_gazebo
{
class ElectroHydraulicPTOPrivate
{
public:
/// \brief Piston joint entity
static constexpr double RPM_TO_RAD_PER_SEC{2.0 * M_PI / 60.0};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we move all of the constants to a common header?

// ~50GPM/600psi ~= .33472 in^3/psi -> Relief valve flow
// above setpoint, From SUN RPECLAN data sheet
const double ReliefValveFlowPerPSI = 50.0 / 600.0;
const double ReliefValveFlowPerPSI = 30.0 / 600.0;
const double CubicInchesPerGallon = 231.0;
Copy link
Collaborator

Choose a reason for hiding this comment

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

More constants that we can put somewhere common?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks Michael, I can make those adjustments. Not entirely sure how high up to put the constants header file, presumably package wide, i'll look to see what makes sense. Also, I'll leave the "entities" question to andermi

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think Constants.hpp in the buoy_utils folder would be reasonable and package wide.

@hamilton8415
Copy link
Collaborator

Hi All, I've implemented most of the above suggestions and it's passing CI. For the constants, as discussed I made a header file in buoy_utils but only put physical constants in there that are useful in a variety of places, unit conversions and similar. For the constants specific to the ElectroHydraulicPTO, I left those in the class definitions as static constexpr. There may be some sense in time to pull the constants out that define the exact behavior of this PTO into a header file in ElectroHydraulicPTO, but didn't go for that level of surgery at this time, instead figuring we need to get this merged in. Thanks for all the help and suggestions, have a great weekend...

@andermi
Copy link
Collaborator Author

andermi commented Nov 20, 2022

LGTM. If @mjcarroll approves, I'll merge.

@mjcarroll mjcarroll merged commit d6c0e2e into main Nov 21, 2022
@mjcarroll mjcarroll deleted the hamilton8415/motormode branch November 21, 2022 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants