Jeroen Hilgers is softwarearchitect bij Ellips. In die rol is hij betrokken bij de ontwikkeling van beeldbewerkingsalgoritmes en de omgeving waarin deze draaien. De dataflowomgeving is begonnen als een vrijdagmiddagproject van hem.

14 December 2011

Gebruikers van fruitsorteersystemen willen steeds meer niet-standaard functionaliteit. Daarom heeft de ontwikkelafdeling van het Eindhovense Ellips haar werkwijze veranderd en een dataflowomgeving ingevoerd. Jeroen Hilgers beschrijft de nieuwe aanpak en de resultaten.

Een paar jaar geleden kon Ellips als leverancier van sorteersystemen voor fruit nog volstaan met de meting van maat, gewicht en kleur. Tegenwoordig moeten we ook defecten als rotte plekjes, scheuren en hagelschade detecteren. Bovendien vragen gebruikers steeds vaker maatwerk. Zo wil een Noord-Duitse klant een bonkig soort appels kunnen verwerken, een klant in Zuid-Amerika schimmelinfecties kunnen opsporen op sinaasappels en een Australische klant zelfs abalones sorteren, een eetbare soort zeeslak.

Door het groeiende eisenpakket moet onze ontwikkelafdeling steeds complexere beeldbewerkingsalgoritmes leveren. Daarnaast moeten we steeds vaker klantspecifieke aanpassingen aanbrengen. Om aan deze behoeftes te voldoen, hebben we onze ontwikkelmethode veranderd: we hebben een zogeheten dataflowomgeving opgezet, waarin de focus niet langer ligt op het aaneenrijgen van C++-statements maar op het modelleren van gegevensstromen door het systeem.

Ellips_sorteermachine
De sorteermachine werpt een appel uit bij de juiste uitgang.

Natuurproducten

Onze klanten zijn machinebouwers over de hele wereld. Zij integreren onze software met bijbehorende hardware in hun sorteersystemen. Vervolgens verzorgen ze de installatie bij de eindklant, al dan niet met onze hulp. Vaak berust de werking van een sorteermachine op kettingen die bakjes of rollertjes voortbewegen. In elk bakje of op elk rollertje ligt een stuk fruit. Het systeem bepaalt telkens een aantal eigenschappen zoals gewicht, kleur en maat. Op grond daarvan kiest het voor iedere vrucht een uitgang. Wanneer deze wordt gepasseerd, werpt de machine het fruit af.

De rollertjes maken het mogelijk om de vrucht te draaien. Van links- en rechtsboven kijken we vervolgens naar het draaiende fruit. Daarbij gebruiken we twee sets van telkens één kleuren- en één nabij-infraroodcamera (Nir). Door met iedere set meerdere opnames te maken, krijgen we de vrucht rondom in beeld. Voor een appel levert dit 32 plaatjes op. Deze plaatjes zijn voorzien van aanvullende informatie, zoals de positie van de machine op het moment van de opname.

 advertorial 

Free webinar ‘Modernizing your code base with C++20’

As many production tool chains now adopt C++20 features, the potential this brings is unlocked. What advantages can recent versions offer to your code base? In this webinar we’ll look at the great improvements C++ has gone through and how features like concepts and ranges can transform your code. Register for video access.

De exacte configuratie varieert per systeem. Sommige machines gebruiken alleen Nir-opnames en geen kleur. Andere hebben slechts één set camera‘s recht boven de vrucht. Ook combinaties komen voor. In onze software resulteert dit in verschillende paden door de code. Verschillende vruchten vergen ook een verschillende aanpak. Zo hebben appels en kersen een steeltje dat buiten de contour van de vrucht steekt en grapefruits en sinaasappels niet. Dit geeft weer wat extra paden. Al deze paden vereisen de nodige instellingen voor een correcte werking, wat uitmondt in een complexe userinterface. Het moge duidelijk zijn dat de zeeslakken het geheel niet overzichtelijker maken.

Daarbij komt dat we met natuurproducten werken. Die zijn allemaal anders. Dit betekent dat we een algoritme op veel producten moeten uitproberen om een indruk te krijgen van de prestaties. Meestal geeft een dergelijke evaluatie een aantal probleemgevallen. De prestatie daarop verbeteren we vervolgens door het algoritme aan te passen. Daarna herhalen we de hele evaluatie om te controleren of de verbetering het gewenste resultaat heeft. Uiteraard gaan we hierbij ook na of we geen nieuwe probleemgevallen hebben geïntroduceerd.

Bevriende telers

Om dit ontwikkelproces te ondersteunen, hebben we een dataflowomgeving opgezet en daarin onze bestaande algoritmes beschikbaar gemaakt als bouwblokken. Deze hebben inputs waarop gegevens binnenkomen, bijvoorbeeld getallen, plaatjes, contouren of combinaties daarvan in zogeheten tupels. Hierop voeren de blokken een bewerking uit, waarna ze het resultaat aanbieden op hun outputs. Onderling worden de bouwstenen verbonden door netten die de data vervoeren. Op deze manier kunnen we complexe algoritmes tekenen als schema.

Ellips_camera_s
Camera‘s maken vanuit verschillende hoeken opnames van fruit op de machine.
Ellips_appel_rondom
Een volledige appel in Nir en kleur

Als testcase hebben we een schema ontwikkeld voor het sorteren van kersen. In de dataflowomgeving bleek dit veel betere resultaten te geven dan de bestaande implementatie. Dat wilden we natuurlijk graag testen in de praktijk. Daarom zijn we naar een van onze kersensorterende klanten gestapt. Omdat diens systeem is geïmplementeerd in C++, was het eerst zaak om het schema daarnaartoe om te schrijven. De meeste blokken zijn simpele wrappers om C++-code, dus daarin voorzagen we geen problemen. Wel verwachtten we tijdens de praktijktests ideeën op te doen voor verdere verbeteringen. Die wilden we eerst weer testen in de dataflowomgeving. De aanpassingen zouden we dan opnieuw met de hand moeten overzetten naar C++ voor het realtime systeem. Het zou veel handiger zijn als we het aangepaste schema gewoon naar de klant konden sturen.

We hebben toen gekeken naar de mogelijkheid om de schema-interpreter uit de dataflowomgeving te integreren in het realtime systeem. Binnen het bedrijf leverde dit wat weerstand op. De interpreter maakt intensief gebruik van dynamische geheugenallocatie. Dit zou het realtime gedrag in gevaar kunnen brengen en kunnen leiden tot onverwachte out of memory-errors in het veld. Ook zou de interpreter veel overhead opleveren. We besloten daarom om voorzichtig te gaan testen bij deze ene klant en de processorbelasting en het geheugengebruik nauwlettend in de gaten te houden. Deze test verliep niet geheel volgens plan. De klant was zo enthousiast over de betere sorteerresultaten dat hij bevriende telers met een Ellips-systeem belde, die weer contact opnamen met onze supportafdeling. Aan het eind van de dag hadden we vier systemen met een alfaversie in volle productie staan.

Behalve het sorteerresultaat hebben we ook het systeemgedrag geëvalueerd. Hieruit kwam naar voren dat het systeem minder geheugen gebruikt dan de vorige versie, waar de worstcaseallocatie zich nogal verspillend toonde. Met de juiste maatregelen bleek het dynamische geheugenbeheer bovendien het realtime gedrag niet te beïnvloeden. De schema-interpreter resulteerde wel in zo‘n vijftien procent extra processorbelasting. Dit is de prijs die we betalen voor de toegenomen flexibiliteit.

Specifieke schema‘s

Met de nieuwe methode ontwikkelen we complexere beeldbewerking in minder tijd. Voorheen moesten we voor iedere aanpassing een C++-project herbouwen en herstarten. De nieuwe omgeving laat toe om een schema on-the-fly aan te passen, waarna het effect meteen zichtbaar is. Een schema geeft ons ook veel meer dan in C++ inzicht in de beeldbewerking en de tussenresultaten. De tupelviewer is hierbij een krachtige tool om te analyseren wat er precies gebeurt tijdens de bewerking. Van ieder net in het schema kunnen we de inhoud bekijken.

Ellips_tupleviewer
De tupelviewer is een krachtige tool om te analyseren wat er precies gebeurt tijdens de beeldbewerking.
Ellips_schemafragment
Een voorbeeld van een schema dat een tupel bouwt. Op het net links komt een grijswaardeplaatje binnen. Eerst zoeken we hier een contour om een licht gebied. Van deze contour bereken we vervolgens een convex hull. Tenslotte maken we een tupel met het plaatje, de contour en de convex hull.

Voor speciale machineconfiguraties kunnen we specifieke schema‘s maken zonder de software voor de meer gangbare configuraties complexer te maken. De schema‘s zijn in het veld te laden, waardoor we snel kunnen reageren op bugs of verzoeken om extra gegevens uit te rekenen. Ieder schema dat we maken, heeft wel enig onderhoud nodig in de toekomst. Onze nieuwe ontwikkelomgeving maakt het gelukkig een stuk makkelijker om aanpassingen door te voeren dan voorheen.

Vlak na de zomer hebben we een nieuwe versie van ons systeem uitgebracht. Vanaf deze versie doen we het helemaal zonder de oude beeldbewerking en gebruiken we alleen nog maar schema‘s.