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

Fix the force-torque sensor update rate #1159

Merged
merged 3 commits into from
Nov 17, 2021
Merged

Conversation

mjcarroll
Copy link
Contributor

@mjcarroll mjcarroll commented Nov 2, 2021

🦟 Bug fix

Makes the force-torque sensor system properly respect the update_time parameter from the sensor's SDF.

Summary

This bug is introduced by calling ForceTorqueSensor::Update rather that Sensors::Update from the base class. This was causing all of the base class update logic to be skiped and the FT sensor would update every time.

To test, runt he example sensors world

ign gazebo ./src/ign-gazebo/examples/worlds/sensors.sdf    

And verify that the output rate of the f-t sensor is reasonable (10 hz, in this case):

ign topic -e -t /world/sensors/model/force_torque_demo/joint/joint_01/sensor/force_torque/forcetorque 

Note to maintainers: Remember to use Squash-Merge

@mjcarroll mjcarroll requested a review from chapulina as a code owner November 2, 2021 20:15
@github-actions github-actions bot added 🌱 garden Ignition Garden 🏯 fortress Ignition Fortress labels Nov 2, 2021
Copy link
Contributor

@chapulina chapulina left a comment

Choose a reason for hiding this comment

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

This bug is introduced by calling ForceTorqueSensor::Update rather that Sensors::Update from the base class.

I see the same pattern is used for other sensors, but with this pattern, how are we handling custom updates for each sensor type? That's why they override the parent Sensor::Update function, right?

Is there a problem in ign-sensors itself? I'd expect the overriding functions to call the parent function, i.e.

bool ForceTorqueSensor::Update(const std::chrono::steady_clock::duration &_now)
{
    Sensor::Update(_now);
...

@@ -137,7 +137,9 @@ void ForceTorque::PostUpdate(const UpdateInfo &_info,
for (auto &it : this->dataPtr->entitySensorMap)
{
// Update measurement time
it.second->Update(_info.simTime);
auto time = math::durationToSecNsec(_info.simTime);
Copy link
Contributor

Choose a reason for hiding this comment

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

I see the same pattern is used on other sensors, but is the conversion to sec/nsec and back necessary? Can't we just call Update(_info.simTime, false)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This may be vestigial from switching over how we handled time in Fortress. I can do a follow up to fix all of the locations where we are using this pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Similar to my comment on the main thread, I think we can do away with the time logic, but we still have to cast to the base class in order to get the Update function that we want to use here.

Our two options would be, neither of which are particularly pretty.

      it.second.get()->sensors::Sensor::Update(_info.simTime, false);
      static_cast<sensors::Sensor*>(it.second.get())->Update(_info.simTime, false);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated to my preferred call, but I'm open to suggestions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One other option would be to put using Sensor::Update(..., ...) in each of the derived classes.

Copy link
Contributor

@chapulina chapulina Nov 2, 2021

Choose a reason for hiding this comment

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

One other option would be to put using Sensor::Update(..., ...) in each of the derived classes.

I think that would be the right thing to do, but I understand it if it's out of the scope of this PR

Copy link
Contributor

Choose a reason for hiding this comment

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

One other option would be to put using Sensor::Update(..., ...) in each of the derived classes.

I was just looking into that, and what's currently happening is that this function:

public: bool Update(const std::chrono::steady_clock::duration &_now, const bool _force);

Calls this one:

public: virtual bool Update(const std::chrono::steady_clock::duration &_now) = 0;

So I think this PR is correct, calling the outermost function. We should do the same for all sensors. And we should rethink whether we want the 2nd function to be public at all; it seems to me that calling it is a mistake, because it only does a subset of what the other function does.

Copy link
Contributor

Choose a reason for hiding this comment

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

@mjcarroll
Copy link
Contributor Author

Ah, so I think I see the issue.

In Sensor, we have:

public: virtual bool Update(const std::chrono::steady_clock::duration &_now) = 0;
public: bool Update(const std::chrono::steady_clock::duration &_now, const bool _force);

Where the argument version calls the virtual version to be implemented by downstream users.

In our systems in ign-gazebo, we generally keep the pointer to the most-derived class, so we don't have access to Sensor::Update that contains the logic that we are most interested in.

@chapulina chapulina removed the 🌱 garden Ignition Garden label Nov 16, 2021
@chapulina
Copy link
Contributor

The approach here LGTM, we just need to fix the test:

  /github/workspace/test/integration/force_torque_system.cc:142: Failure
  Expected equality of these values:
    iters
      Which is: 1000
    wrenches.size()
      Which is: 31

Also add a sample configuration to the sensors world example

Signed-off-by: Michael Carroll <[email protected]>
Signed-off-by: Michael Carroll <[email protected]>
Signed-off-by: Michael Carroll <[email protected]>
@codecov
Copy link

codecov bot commented Nov 17, 2021

Codecov Report

Merging #1159 (a5e0c34) into ign-gazebo6 (ee90892) will increase coverage by 0.00%.
The diff coverage is 100.00%.

❗ Current head a5e0c34 differs from pull request most recent head 35a3e97. Consider uploading reports for the commit 35a3e97 to get more accurate results
Impacted file tree graph

@@             Coverage Diff              @@
##           ign-gazebo6    #1159   +/-   ##
============================================
  Coverage        61.92%   61.93%           
============================================
  Files              275      275           
  Lines            22457    22457           
============================================
+ Hits             13907    13908    +1     
+ Misses            8550     8549    -1     
Impacted Files Coverage Δ
src/systems/force_torque/ForceTorque.cc 73.72% <100.00%> (ø)
src/EntityComponentManager.cc 87.15% <0.00%> (+0.12%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ee90892...35a3e97. Read the comment docs.

@chapulina chapulina merged commit 96ed1ef into ign-gazebo6 Nov 17, 2021
@chapulina chapulina deleted the fix_ft_update branch November 17, 2021 19:48
WilliamLewww pushed a commit to WilliamLewww/ign-gazebo that referenced this pull request Dec 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏯 fortress Ignition Fortress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants