De softwarereis van een eiermachinebouwer
Het traditionele beeld van een machinebouwer is er een van een bedrijf dat bakbeesten maakt met veel staal, krachtmotoren en vetsmeringen. Dergelijke robuuste systemen bestaan nog steeds, maar we zien ook steeds meer machines vol met fijnmechanica en nanotechnologie, opgesteld in cleanrooms. De grote gemene deler: de aansturing gebeurt met software. Peter Neumann geeft een kijkje in de softwarekeuken van eiermachinespecialist Moba.
Bij Moba in Barneveld ontwikkelen en produceren we machines voor de eierindustrie. Grote kans dat wij het doosje eieren hebben gevuld dat bij jou in de koelkast staat.
Het vulproces begint in een pakstation, bij de grotere pluimveehouders in huis of anders in een verpakkingscentrum in de regio. Daar plaatst een van onze robotsystemen de eieren op een sorteermachine van ons. Die controleert ze akoestisch op breuken in de schaal, stelt optisch de vuilgraad vast, licht ze door met krachtige leds en constateert op basis van spectrale verschillen of er bloed- of vleesinsluitsels aanwezig zijn. Met een weegcel bepaalt het systeem het gewicht van de eieren. Vervolgens sorteren we ze volgens instelbare algoritmes uit in de verpakkingen. Die gaan via intelligente transportsystemen naar robotcellen, waar ze in dozen en/of op pallets worden geplaatst.
De aansturing van al deze transport- en meetsystemen doen we met software. Daarnaast is het belangrijk om te allen tijde te weten waar elk ei is in het traject. Ook deze traceerbaarheid realiseren we in software.

Pc-platform
Software deed zijn intrede bij Moba in de jaren tachtig. Als basis voor onze eiersorteermachines gebruikten we toen de E7/E19-processorkaarten van Siemens en voor de centrale aansturing besloten we daar de multitasking-omgeving Concurrent CP/M bovenop te zetten. In deze omgeving gingen we programma’s schrijven in assembly en C. De userinterface bouwden we in Turbo Pascal van Borland. Hiermee legden we de fundamenten voor onze latere platform- en toolingkeuzes.
Begin jaren negentig lanceerden we een nieuwe generatie eiersorteermachine, de Omnia. Met als besturingsplatform Dos, dat even daarvoor op de markt was gekomen. Voor de realtime communicatie met embedded systemen, bijvoorbeeld de systemen om tekst op eieren te printen, de inpaklijnen en de kwaliteitscontrolesystemen, hadden we gekozen voor de Can-bus vanwege de grote populariteit ervan in de auto-industrie.
Vele uitbreidingen en innovaties later vindt de Omnia vandaag de dag nog steeds zijn weg naar de markt. En nog steeds vormt een pc-platform de basis. Dos hebben we inmiddels ingeruild voor een Linux-distributie met realtimepatch, draaiend op een industriële pc. Alle software is volledig objectgeoriënteerd en geschreven in C++ (versie 11). Voor de realtime communicatie gebruiken we nog steeds de Can-bus, maar deze gaan we in fases vervangen door de open Ethernet Powerlink-bus, zodat er meer bandbreedte beschikbaar komt om data uit te wisselen.
Daarnaast zijn we aan de slag gegaan met webtechnologieën. De komst van smartphones, tablets en daarmee de vraag naar meer flexibiliteit rondom de machine heeft geleid tot de introductie van webgebaseerde, deviceonafhankelijke, goed schaalbare userinterfaces. De standaard Restful-api’s maken het eenvoudig om modules aan elkaar te knopen, maar toch een strakke scheiding te houden. Wij gebruiken Javascript, HTML5, CSS en daarbovenop het Aurelia-framework om state-of-the-art userinterfaces te bouwen, die via Rest integreren met onze C++11-besturingssoftware.

Breder scrumproces
Als wereldwijde marktleider in een snelgroeiende industrie is Moba de laatste jaren flink groter geworden, ook in software. Het softwareontwikkelteam is bijna verdubbeld, tot dertig mensen nu. Aanjagers zijn de uitbreiding van het productportfolio en de toenemende vraag vanuit de markt voor functionele uitbreidingen die we kunnen realiseren in software. Zo’n groei vraagt om aandacht voor de organisatie, aanpassingen en standaardisatie.
Onze r&d-organisatie is opgedeeld in productgroepen, die weer werken in multidisciplinaire teams. Zo zijn er onder meer groepen voor de detectiesystemen, voor de hoge- en lagecapaciteitsmachines, voor de logistiek, voor de robots en voor de loaders. Elke groep heeft een productverantwoordelijke, die er met het team voor zorgt dat ze niet alleen met een hoge kwaliteit en betrouwbaarheid, maar ook betaalbaar opleveren aan de klant.
Bij de ontwikkeling volgen we de Agile/Scrum-methodiek. Samen de complexiteit, risico’s en hoeveelheid werk inschatten is een echte meerwaarde gebleken in onze organisatie. Informatie delen, elkaars kennis aanvullen, maar ook de extra handjes binnen een team: het zorgt allemaal voor een meer gestroomlijnd ontwikkelproces.
Deze voordelen beperken zich niet tot de softwareontwikkeling. Met de inrichting van de productgroepen zijn de teams multidisciplinair geworden en zetten we het scrumproces ook breder in. Dit vraagt weliswaar om aandacht en begeleiding, maar we zien ook duidelijke meerwaarde bij de andere disciplines. Samen delen, samen ontwikkelen, samen reviewen: dat is de kracht van Scrum.
Technische schuld
Behalve verschillen hebben onze producten ook een aantal overeenkomsten. Bijvoorbeeld de manier waarop we motoren aansturen, of de opzet en componenten die we gebruiken voor een userinterface. Als we niets regelen, bedenkt en implementeert elke productgroep zijn eigen oplossing. Vandaar dat we ook een productgroep hebben specifiek voor integratie. Deze zorgt in samenspraak met de andere groepen voor generieke oplossingen, frameworks en daarmee voor het hergebruik van code.
Waar kleine teams op vrij natuurlijke wijze een ontwikkelomgeving kiezen, ontstaat er bij grotere teams meer variatie. Dat is niet efficiënt; iedereen gaat zijn eigen programma’s installeren, en softwaretools voor bijvoorbeeld archivering, review en statische codeanalyse sluiten lang niet altijd naadloos op elkaar aan. We hebben stappen gezet om de ontwikkelomgeving uit te rollen aan de hand van een centrale configuratie. Met één druk op de knop wordt een virtuele machine geïnstalleerd, inclusief een of twee ontwikkelomgevingen en de benodigde softwaretools. De configureerbaarheid geeft weinig onderhoud en toch flexibiliteit.
Hoe meer softwaremensen, hoe belangrijker het ook wordt om programmeerstandaarden te definiëren en te gebruiken. Deze beschrijven de manier waarop ontwikkelaars code dienen te schrijven, met als doel overzichtelijke en eenduidige code en een auteuronafhankelijke codeerstijl. De code wordt hierdoor leesbaar voor collega’s en beter te onderhouden. We hadden hier al langer standaarden voor, maar met de groei van het team en de intrede van nieuwe technologieën komen er aandachtspunten bij: programmeerstandaarden voor een specifieke taal, richtlijnen en best practices voor library’s, frameworks en applicaties.
Het is niet zo dat we elke twee jaar een heel nieuwe machine of module op de markt brengen. Veelal pakken we bestaande (sub)systemen op om ze aan te passen en/of uit te breiden. Het softwareontwerp hebben we ooit van scratch opgezet en de code hebben we geschreven volgens de principes die toen golden. Door de jaren heen hebben we hier extra functionaliteit aan toegevoegd met een aanpassing hier en een wijziging daar. Feitelijk hebben we hiermee een technische schuld opgebouwd. Deze zullen we een keer moeten inlossen. Dat betekent dat we delen van de software opnieuw moeten opzetten of moeten aanpassen – refactoren – zodat de basis stevig blijft en we de functionaliteit betrouwbaar en efficiënt kunnen wijzigen of uitbreiden.
Ook bij onze modules hebben we technische schuld. Door onderhoud juist te plannen, creëren we draagvlak voor maatregelen. Het kost namelijk geld en inspanning om de schuld in te lossen en op het eerste gezicht, aan de buitenkant, lijkt het als of er helemaal niets is gebeurd. Functioneel mogen er tijdens het refactoren dan misschien geen aanpassingen zijn gedaan, de basis is weer gezond en betrouwbaar, en toekomstige aanpassingen en uitbreidingen zijn veel efficiënter door te voeren.

Unittests
Jaarlijks schrijven onze softwareontwikkelaars ongeveer tweehonderdduizend regels code. Lang hebben we alles met de hand getest. Samen met collega’s van het Product Research Centre checkten de softwareontwikkelaars dan de bestaande en toegevoegde functionaliteit op een van de beschikbare testmachines. Een noodzakelijke, maar tijdrovende bezigheid. We hebben een aantal stappen gezet om eerder in het ontwikkelproces te weten of de bestaande functionaliteit niet is omgerold (regressietests) en of de toevoegingen voldoen aan de gestelde specificaties.
Op systeemniveau zetten we scenariotests in, deels geautomatiseerd en deels handmatig. Door in een testplan te beschrijven wat we willen testen, onder welke omstandigheden en wat de uitkomst moet zijn, bereiden we de test goed voor. Zo’n plan geeft extra inzicht en is later vele malen te hergebruiken. Daarnaast hebben we een tool die scenario’s kan aflopen. Met de tool kunnen we toetsenbord- en muisacties genereren en de resultaten verifiëren. Zo borgen we dat functionaliteit intact blijft. Met machines die 24/7 operationeel zijn, zijn de scenarioduurtests ook van belang om de performance van de applicaties te monitoren. Blijft de reactiesnelheid binnen de specificaties? Zijn er geheugenlekken die op termijn crashes kunnen veroorzaken?
Tijdens de softwareontwikkeling hebben machinebouwers vaak de behoefte om te testen op een fysiek systeem. Met simulatie is een echte efficiencyslag te maken. In plaats van staal op de vloer is er dan een virtuele machine of module om ontwikkelde code op te controleren. De Moba-library biedt de hiervoor benodigde voorzieningen, ook om zo’n virtuele machine in 3d zichtbaar te maken op een scherm. Een grote bijvangst is dat we de visualisatie van de machine ook kunnen inzetten bij onze klanten. Hiermee kunnen we hun het productieproces geheel in 3d tonen. Bij een van onze klanten doen we dit ook al.
Een laag dieper, in de code zelf, hebben we stappen gezet om de functionaliteit automatisch te kunnen testen. We programmeren in objecten, elk met zijn eigen taken en verantwoordelijkheid. Per object schrijven we daar tests tegenaan. Deze unittests voeren we ’s nachts uit op de bouwserver en de resultaten komen ’s ochtends beschikbaar in een dashboard. Doordat ontwikkelaars moeten nadenken over een unittest voor een object, leggen we tekortkomingen in het ontwerp in een vroeg stadium van het softwareontwikkelproces bloot.
Unittests zijn niet voor al onze software even bruikbaar. Nieuwe, in objecten ontwikkelde code leent zich er uitstekend voor, maar oudere code die meer procedureel van aard is, is minder geschikt. Met derden willen we gaan kijken wat hier de mogelijkheden zijn.
Hoger niveau
Softwareontwikkeling is heel dynamisch en divers. Het begint al bij de beschikbare technologieën: deze komen en gaan en het is de kunst om hierin de juiste keuzes te maken. We kunnen niet elk jaar overstappen op iets nieuws. Ook de werkwijze is onderhevig aan veranderingen. Met de introductie van unittests komt testgedreven ontwikkeling in beeld: eerst de tests maken en dan pas de softwarefunctionaliteit zelf.
Een volgende stap voor ons is modelgedreven ontwikkeling. Hierbij beschrijven we het gedrag van een systeem in een model, waaruit we automatisch de code generen en waarvan we mathematisch verifiëren of we alle mogelijke uitzonderingen in kaart hebben gebracht. De open eindjes komen in de praktijk pas heel laat boven water, vaak pas bij de klant. Met de modelgedreven aanpak, ondersteund door tooling, verwachten we dat onze software al veel robuuster en betrouwbaarder is voordat we ermee het veld in gaan. De eerste successen hebben we al na een paar weken mogen vieren.
Onze softwareontwikkelaars hebben een continue drive om de kwaliteit en efficiency van de code naar een hoger niveau te tillen. Voorstellen voor verbeteringen bespreken we in een regelmatig overleg. Daarnaast hebben we een lunch waar iedereen de gelegenheid heeft om zijn of haar enthousiasme te delen over softwareontwikkeling en andere technische onderwerpen. De goede ideeën en voorstellen werken we uit in kleine teams en pakken we vervolgens op binnen het ontwikkelteam.