I am working on an automotive project that we are supposed to make more modular. I am a software specialist and I have very little knowledge of automotive hardware. I don't have any requirements or details about the project other than "making it more modular/portable" and "think in terms of software not hardware". By making it more modular they mean that they want to be able to pick any car and replace its conventional battery or pump with a different type without having to redesign the entire system.

So far the only thing I have come up with is to separate the system into two layers with the first layer having the general code that can be reused in all cars and the second layer has code specific to each component. Of course I don't have the actual source code. I think I am required to produce a general software architecture that they can use for implementing all their systems. I don't have any other idea at the moment.

Any help, direction or source of information is appreciated.

EDIT: I am working with a few electrical engineers and they have some idea about cars. So I am not alone. But still we are lost as they want a modular system and want us to think more in terms of software to save their costs.

  • "They want to be able to pick any car and replace its conventional battery or pump with a different type without having to redesign the entire system." -> That means standardized interfaces throughout. – ratchet freak Feb 19 '15 at 9:27
  • 3
    I do not think that without having a least some knowledge of the field you can design something. Speak to your roommates. Use their experience. You are not alone there ;) BTW, I really hate to use, for example, accounting software written by programmers, that, it seems, had absolutely no knowledge of the subject. – Vladislav Rastrusny Feb 19 '15 at 10:43
  • 3
    You probably need at least to become familiar with AUTOSAR and GENIVI – Basile Starynkevitch Feb 19 '15 at 11:43

I would start by looking at existing standards in this area, like ARINC 653 and (especially) AUTOSAR.

Both of those are real-time component-based systems where components communicate by passing messages. That's more complex, but ultimately far more flexible, that the straightforward approach of using the modularity features of a specific programming language.


I think that at the very least, they should tell you what are the minimal functions of each component. For instance, (I have no clue of car mechanics, so bear with the example), a pump might need to provide the following set of functions: CurrentPressure, MaximumOperatingPressure, MinimumOperatingPressure.

Assuming that all of the components can provide you with a similar set of API's, you could define a series of Interfaces, such as IPump, which would define the bare minimum functions a pump should provide.

This, in turn, would allow you to have some contracts against which you can write drivers, so that, regardless of make and model, you would always have the same set of functions available, where in each model then takes care to implement how are these values provided.

Your centralized code then, would only work in terms of these interfaces. So essentially, your code would not know, nor care for that matter, if you are working with Brand A Pump or Brand B Pump.

This proposal obviously assumes that there is a set of standards somewhere.

  • Agreed. Only subject matter experts can really create a taxonomy of components. Otherwise you end up having these sorts of problems as a novice of the subject matter: 1) two things look different but actually fill a similar gap, but you give them separate interfaces or 2) two things look the same but there are some subtleties which your interface glosses over when it shouldn't have. That being said, I think you can work with them to guide them through your thought processes of abstraction. – J Trana Feb 20 '15 at 5:27

I think they've asked you to do the impossible. We do something similar in our shop with industrial automation. We frequently purchase mechanical presses and we retrofit them with our own control system. We try very hard to make the user interface similar across all the presses, but internally they are sometimes similar and sometimes very different. One press is equipped with hydraulic overloads, one has strain gauge-style tonnage monitoring while another has piezo-electric style tonnage monitoring.

Even among systems that every press has, like a press lubrication pump, the way they work are all generally different.

How do we handle these differences without insanity? We don't. The software for each press is about 90% custom. We do have a "common library" of functions that we use across presses, such as an event logging system, but the events that are actually logged on each press are almost completely unique. The common library contains standard logic for interfacing with an analog input card that we use across all the presses.

Each press has a main motor, but electrically these all work subtly differently, so we have custom logic for each.

In your example, can you make it so that you can replace a pump with a different model without having to make software changes? I doubt it. In fact the important thing is that you anticipate the need to change something when they do that, and you think about where these changes will be made. Try to make it so these changes are limited to a single class or module. What does the rest of the system care about that pump? Does some other system need to know that pump is running before it can do its job? Then your interface needs a Pump.Running property. How you set that bit will probably have to change when they replace the pump, but at least the change should be localized. You know that you'll need to log problems to the car-wide error reporting system, so you probably need an error reporting interface, and you should assume your Pump module will need to be injected with a reference to that interface in the constructor or initialization code.


In the early days of automobiles many parts ere interchangeable either directly or with the aid of a hacksaw and file. It was quite common for the engine, chassis and coachwork to be made by completely different companies.

In the fifties and sixties it was considered cool to fit the best motercycle engine (e.g. Triumph Bonneville) into the best frame (e.g. Norton Commando) with perhaps the brakes and shocks from a completely different machine.

All the was possible because the engineering was fairly crude and parts were not made to high tolerances.

In a modern vehicle even relatively inexpensive cars have highly optimized designs. Take as an example gas flows (the piece of engineering that most affects power output); the design must incorporate the air filter, carburetor/fuel injection, inlet manifold, valves, cylinder, piston, exhaust manifold, exhaust headers, the silencer and catalytic converter. Changing any one of those components will affect the gas flow and hence the power output and fuel consumption(probably for the worse).

Its difficult to see how you could have a plug and play approach to component design in this scenario.


The way to modularise things (any things) is to have facades for each component. If you also use message-passing instead of directly-connected APIs you also have much more flexibility.

as an example: imagine we have 2 types of steering component - a wheel and 2 joysticks; and 2 types of movement components: wheels and tracks.

You can isolate each steering component to send a message describing the intention, eg a steering wheel rotated 10 degrees to the left means steer the vehicle to the left, so it can construct a message describing the intention and sends it to the movement component that turns this into either 10 degree turn for the wheels, or a slower speed for the left track. Now you see that you can send the same kind of message for the joysticks - right one pushed forward more than the left, translates into the same 'turn left by a bit' message.

Now you have a system that can interchange a steering wheel for twin joysticks, or tracks for wheels. Mix and match and don't care which you have! The same principle applies for everything else - the interface just needs to be designed independently from the components, decide what you need the vehicle to do without thinking of how the user will do it or the hardware will perform it.

Using a message passing architecture means you don't need to plug things together - everything plugs into a message bus, so your steering wheel would push the steering messages to the bus, and components that recognise steering message would pull them off. This helps when you have multiple ways to control the same system - eg radio volume buttons on the steering wheel and the dash and the rear passenger armrest - all simply send the same message to the message bus and it all just works.

Now for hardware you're much more limited simply because things have to be connected together. You're also limited by the interface they supply, eg a battery is a battery, and although it could be a lead-acid one, or a hydrogen fuel cell, it needs to have the exact same plugs and the same voltages coming out of it. In this case, standardised interfaces are needed and that limits you. eg While you can have an identically sized and shaped chassis with wheels or tank tracks that can be swapped out you will find the physical constraints will limit your options.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.