Skip to content

fix controller #3

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

Merged
merged 5 commits into from
Jul 1, 2022
Merged

fix controller #3

merged 5 commits into from
Jul 1, 2022

Conversation

tonynajjar
Copy link

@tonynajjar tonynajjar commented Jun 27, 2022

1- Fixes convert_trans_rot_vel_to_steering_angle formulat
2- Adds slowing down until steering angle target is reached
3- Adds extreme angles conditions

@tonynajjar
Copy link
Author

@jplapp I added the requirement for an approval to merge. Now that this repo will be very important, feel free to set the necessary PR requirements

Copy link
Collaborator

@jplapp jplapp left a comment

Choose a reason for hiding this comment

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

looks good, some comments on the math

// TODO: find the best function profile, e.g convex power functions
// TODO: Is there a better/more generic way to take into consideration motor velocity/acceleration limitations?
double alpha_delta = abs(alpha_write - steering_joint_[0].position_state.get().get_value());
Ws_write *= cos(alpha_delta/2);
Copy link
Collaborator

Choose a reason for hiding this comment

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

  • why devide it by 2?
  • you should limit this to positive value, otherwise it will be scaled in the negative direction, which will create unexpected results, e.g. sth like Ws_write *= max(0.01, cos(alpha_delta/2)); . We used 0.01 here, to have some wheel motion already so that flexisoft wakes up.

Copy link
Author

Choose a reason for hiding this comment

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

My goal was to find a function that for x between [0, pi] would give y between [0,1] to keep it as one mathematical function and not add more checks like max().

I found cos(x/2) to do the job.
image

alpha_delta is between [0, pi] given that alpha_write and alpha_read are normalized (above discussion)

Copy link
Collaborator

@jplapp jplapp Jun 27, 2022

Choose a reason for hiding this comment

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

ah, I see.
But with this scaling, if input is "turn right" (pi/2), and current angle is 45 degrees left (-pi/4), this would already give 38% (update: corrected) of the speed. In the previous implementation, the idea was to have 0% speed if angle is incorrect by more than 90 degrees

Copy link
Author

@tonynajjar tonynajjar Jun 27, 2022

Choose a reason for hiding this comment

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

We should probably add "last minute" checks in some places to make it safer but shouldn't make it too redundant if we are sure of our inputs' restrictions

Copy link
Author

@tonynajjar tonynajjar Jun 27, 2022

Choose a reason for hiding this comment

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

In the previous implementation, the idea was to have 0% speed if angle is incorrect by more than 90 degrees

I see, I missed this in the initial implementation, wasn't very explicit. I'll implement it as std::max(0.01, cos(alpha_delta)) then but we should do something about this 0.01 magic value for the generic controller. (and make it more explicit)
That's the profile then
image

Copy link
Author

@tonynajjar tonynajjar Jun 27, 2022

Choose a reason for hiding this comment

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

We can already make it more explicit. What do you think of:

  double scale;
  if (alpha_delta < M_PI_4) {
    scale = 1;
  } else if (alpha_delta > M_PI_2) {
    scale = 0;
  } else {
    scale = cos(alpha_delta);
  }
  Ws_write *= scale;

Replace M_PI_4 and M_PI_2 with whatever you'd like. I think that's a good example where explicit is better than implicit

P.S: The reason for the first condition is that there will always be a small error but at some point we want to run with full speed

Copy link
Collaborator

Choose a reason for hiding this comment

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

agree with all your points! I would use pi / 6 as the first threshold, but we'd need to give that a try in a real-world situation then to finetune.
Also, instead of scale=0 -> use that magic value scale=0.01

Copy link
Author

@tonynajjar tonynajjar Jun 27, 2022

Choose a reason for hiding this comment

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

Also, instead of scale=0 -> use that magic value scale=0.01

Will do.
Are you sure there is not a more direct way to keep flexisoft awake? e.g setting a certain bit

Copy link
Collaborator

Choose a reason for hiding this comment

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

currently, we use jetson_speed_cmd, that is in turn based on whether we have some command or not. This, in turn, is calculated based on whether we have some speed. Of course we could change this calculation to use some different input.

Flexisoft then runs some timer once this bit is false.
Speaking of this, I'm not sure if you set this bit anymore (it's set in can_bus_communicator).

// Increase power to make it more strict (i.e to make it slower when angle difference is big)
// TODO: find the best function profile, e.g convex power functions
// TODO: Is there a better/more generic way to take into consideration motor velocity/acceleration limitations?
double alpha_delta = abs(alpha_write - steering_joint_[0].position_state.get().get_value());
Copy link
Collaborator

Choose a reason for hiding this comment

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

when subtracting angles, always ensure that they are normalized, as e.g. an angle of 0 is equivalent to 2*PI. Can we assume that the input angles (so alpha_write and the steering joint state) are normalized?

Copy link
Author

@tonynajjar tonynajjar Jun 27, 2022

Choose a reason for hiding this comment

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

My assumption were that they are always normalized. alpha_write comes from process_twist_command's arctan which is between -pi/2 and pi/2. The read alpha comes from read() in the hardware interface which is scaled also between -pi/2 and pi/2.

Copy link
Collaborator

Choose a reason for hiding this comment

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

ok, good then

Tony Najjar added 2 commits June 27, 2022 12:15
@tonynajjar
Copy link
Author

I ran uncrustify on it, will need to find a way to run our pre-commits here also

Tony Najjar added 2 commits June 27, 2022 15:24
@tonynajjar tonynajjar requested a review from jplapp June 29, 2022 13:43
@tonynajjar
Copy link
Author

tonynajjar commented Jun 29, 2022

Anything left to do here from your side @jplapp?

@tonynajjar tonynajjar merged commit 60935bc into galactic Jul 1, 2022
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.

2 participants