jamesmunns

Doing embedded stuff

Be nice, work hard. Build tools, tell stories. Start five year fights. Kein Ort für Nazis.


A list of all the other services I'm on around the internet


Posts with code highlighted with codehost by @wavebeem.


All posts licensed under CC-BY-SA 4.0, unless otherwise stated.


In my experience, there is only so much any one person can coherently keep in their mind. You might be able to keep a lot of detail about something small in your mind, or maybe a little bit of detail about a large group of things in your mind. The "size" varies by person, experience, excitement, life situations, and more. But honestly, the exact amount doesn't matter. At some point you will run into a problem that exceeds this size.

Unfortunately, relatively few "whole projects" fit into this kind of space. Especially when you have multiple "components" (e.g. mechanical, electrical, software, etc.), which span different contexts or knowledge domains.

A lot of the tools and concepts around systems engineering are meant to help you in exactly this sort of domain: problems that are too big for one brain.

I think I'm going to talk about three things I think about, which help me tackle big problems:

  • Thinking about "zoom levels" when thinking about a problem
  • Thinking about breaking things down into parts, or "sub-systems"
  • Thinking about how sub-systems interact with each other

Zoom Levels

"Zoom Levels" are the way I describe trying to group requirements or details of a system into similar levels of detail. I do this to help me frame my level of thinking, when trying to work on different parts of the system.

The "widest" zoom level

Say we wanted to think about our "whole system", which has a mechanical part, an electrical part, and a software part.

If I'm talking to someone who uses my whole system, I need to be able to keep a bit of detail about all three parts of my system. In this context, it probably doesn't matter what sorting algorithm I use for some data, or what the speed of my operational amplifiers are.

That doesn't mean that this information isn't useful or necessary to capture! But when I'm thinking at a "whole system" level, it would be prohibitive to keep all of these details in my brain at the same time.

I do probably want to know the high level, "system relevant" details of my project at this zoom level. I want to know what the acceptable voltage range for my input signals are (an electrical concern). I want to know how many software filters I can apply at the same time (a software concern).

Typically, these "high level requirements" will live in a document that is only relevant at this "zoom level". This document is usually called the "Systems Requirement Document", "Product Requirement Document", or a variety of different names.

Sometimes, either for specification, implementation, or troubleshooting reasons, we will need to zoom in.

A "narrower" zoom level

From here, we'll probably figure out how to "break up" our high level system into reasonable chunks. In the system described above, that probably will be into a set of requirements for the electrical system, the software system, and the mechanical system.

Again, these become our "go-to references" when we are working at these zoom levels. If I am working on the software itself, I should read the software requirements!

Figuring out how these "narrower" requirements map back to the "wider" requirements is a concept called traceability. We'll talk about this later, and it is a surprisingly useful concept/technique.

How many zoom levels do we need?

It depends! My general answer is: as many as are useful for you.

For simple projects, maybe you only need the top level system requirements. For complex projects, you might have two, three, or four levels.

I'd probably say two "major" zoom levels are probably a sweet spot: you have one place to talk about what the system as a whole does, and another place to discuss how the components work.

Using a car as a metaphor, your top level requirements would talk about how fast the car goes, how far it can go on one charge, or what kind of safety ratings it must meet. Your lower level requirements would talk about what the battery is rated for, the quantity and characteristics of the airbags, etc.

A car would probably keep "zooming in", to break up the components into their hardware/software/mechanical requirements, and more. But for many other projects, this step won't be necessary.

Breaking things into sub-systems

Honestly, this might be the one aspect most familiar to both software engineers, as well as folks from other engineering disciplines.

To solve a problem, you typically need to break it into parts.

But it's important to think about why we break down problems.

Some of this comes back to thinking about "zoom levels". When I am zoomed out at a higher level, the implementation details of a component shouldn't matter. I should only care about how it interacts with other components.

This encapsulation helps us by making the amount of context in our brains at one time lower: We only have to think about the different components and how they interact, WITHOUT thinking about how they work internally.

I'll have a lot to say later about how to architect your system to make it easier to make this ideal "real", but that's a story for another day.

Interactions between parts

Combining sub-systems is typically called integration.

Integration is typically where all the "fun" bugs come from. This happens for a lot of reasons:

  • If our implementation (e.g. code) doesn't match our model (e.g. requirements or architecture), then assumptions we made will end up being wrong
  • Integration requires bridging two or more "local contexts", which can also make "seeing problems" ahead of time much harder
  • Often integration requires combining the work of multiple people, and especially if the requirements aren't clear enough, you can find they held inconsistent understandings of how the pieces come together
  • Integration usually happens later in the project, which can be a problem if issues are found late. This often ends with the problems being "papered over", instead of the root issue fixed, which often causes more problems later.

Integration probably deserves its own post some other day, but the important take-aways here are:

You should spend a lot of time thinking about how sub-systems interact with each other.

Sometimes this means thinking ahead of time. Sometimes this means re-visiting these assumptions as you build the sub-systems, and making sure you didn't invalidate some "higher level assumption".

You should spend a lot of time making interactions between sub-systems as simple as possible.

The less going on, the less can go wrong.

Again, there are a lot of techniques for this, worth of a story on another day.

Summary

Systems Engineering shines when it helps you break problems down into chunks that can fit in your brain.

This means:

  • Breaking systems into sub-systems
  • Being explicit about how sub-systems interact

This post is made available under the CC-BY-SA 4.0 license.


You must log in to comment.

in reply to @jamesmunns's post: