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

pybricks/parameters/pb_type_color: add distance method #217

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Novakasa
Copy link
Sponsor Contributor

@Novakasa Novakasa commented Nov 27, 2023

Exposing the new HCL-bicone color cost function (#104) makes it possible for users to create their own smarter color detection algorithms, for example by adding a hysteresis. This PR adds it as a color.distance(other_color) method to a Color instance. On movehub, this adds 84 bytes. The function name get_distance_to would have added 100 bytes.

Example use:

hsv = sensor.hsv()
if hsv.distance(Color.GREEN) < hsv.distance(Color.RED):
    print("green!")
else:
    print("red!")

Not sure if this would add less firmware size if it were just a module-level function, but to me it makes a bit more sense as a Color method.

exposes the pbio_color_get_bicone_squared_distance function used in the
sensor.color() method.
@coveralls
Copy link

Coverage Status

coverage: 56.535% (-0.06%) from 56.596%
when pulling 30e4df1 on Novakasa:expose-colordist
into a17fb1a on pybricks:master.

@Novakasa
Copy link
Sponsor Contributor Author

Not sure if we should call this distance() since it actually returns the squared cartesian distance in the HCL bicone mapping. Longer names cost firmware size though. If we document the method thoroughly, maybe distance is fine?

BTW, I'm keeping this as draft for now since I'm waiting to rebase this once version metadata reflects alpha release, then I'll also add changelog entry.

If we want to merge this, I'll also add a PR for the docs.

@laurensvalk
Copy link
Member

Can you add some end-user Python samples?

Is this primarily to map(color1, color2) --> cost, or would you eventually like to be able to pass a custom cost function to detectable_colors?

@Novakasa
Copy link
Sponsor Contributor Author

Novakasa commented Nov 30, 2023

This is simply intended to expose the function pbio_color_get_bicone_squared_distance(hsv_a, hsv_b) to the user.
I added a simple example of the proposed API to the first comment.

The purpose is to allow more specialized ways of deciding what color is measured depending on what the user needs.
For example, a kind of hysteresis might be implemented like this (edit: tested now, fixed indentation and typo):

# calibrate colors here
colors = [Color.GREEN, Color.RED, Color.BLUE]

current_color = colors[0]
new_color_threshold = 0.7  # only switch to new color, if (dist_to_new_col / dist_to_old_col) < 0.7

while True:  
    hsv = sensor.hsv()
    current_dist = hsv.distance(current_color)
    best_dist = current_dist
    best_color = None
    for color in colors:
        dist = hsv.distance(color)
        if dist < best_dist and dist < new_color_threshold*current_dist:
            best_color = color
            best_dist = dist
    if best_color is not None:
        current_color = best_color
        print("new color detected!", current_color)
        
    wait(100)

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