Skip to content

Add Residual Weighting/Scaling #8

@nickmccleery

Description

@nickmccleery

At present, our solver assumes that all residuals have comparable scale, which isn't the case.

Different types of constraints produce residuals with different units and magnitudes. For example:

  • A distance constraint produces a residual in length units (e.g., millimeters). An error of 10.0 could be significant or minor depending on the part's scale.
  • An angle constraint produces a residual in radians. The error is naturally bounded (e.g., $[-\pi, +\pi]$), and a value of 0.1 is a chunky deviation (~5.7 degrees).
  • A coincidence constraint is a distance constraint where the target is zero in both X and Y.

This could cause the solver to ~prioritise the wrong thing, trying to chase down a length error ahead of an angle error that might actually be more significant in the user's use case.

It's not yet clear me if we should be scaling angles or lengths or both. Radians are a nice dimensionless unit, but I guess most constraints will relate to lengths. Some ideas are:

  • We could try something like normalising length errors - 'how big is this residual on line length relative to the length of the line itself' - but that will be bad when we want to set the distance between things.
    • We could use a 'characteristic length', as is pretty common in fluid problems and so on. This could allow you to say that if you're drawing a ship, you don't care much about a hundred microns of error, but if you're drawing a piston, you very much do care about 100 microns of error.
  • The sketchflat paper reports some fudge factor applied to angles only, and the units in use there are microns and radians.

I also like the idea of associating an acceptable solve tolerance with different units of measure, but unclear how to bake that idea into a weighting of residuals such that the solver sees each with the same importance we do. Perhaps we could just scale the residual directly by our tolerance, e.g.:

tol_length = 0.001 # 1 micron
tol_angle = 0.0001 # 0.005°

Then you'd scale a length residual like r_scaled = r / tol_length and an angle residual like r_scaled = r / tol_angle.

As with my other braindump tickets, I'll try and build something in numpy land and see what works.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions