I've been studying MBSE for a few months and from my learning I have one question with regard to your statement, what drives your system design including programming; how do you validate the project?
This is actually a hard question to answer. In general, I’m driven by good software engineering practices. The key thing is to manage complexity. I tried writing more general information here, but none of it seemed really helpful or informative. “You need to keep high cohesion and low coupling...” blah blah blah
I’ll just give an example.
I work on processing lines made up of many individual machines. One thing I do here is create a framework to handle the machines interfacing with each other. Each machine plugs into the framework which acts as its interface to the processing line. It can write data into the framework and read data out of the framework. Any one machine does not deal directly with other machines.
So, as an example, we’ll look at a simplified version of the processing line speed reference. Each machine writes the maximum speed it can run into the framework (maybe it’s limited by motor size, or processing requirements, or the current state of the machine). The framework goes through all of the speeds, finds the lowest, and writes it back out to all of the machines. The machines receive this speed and limit themselves appropriately.
The code to loop through the line speeds is very simple. Find the lowest value.
The code to set a speed limit is very simple. Write the max speed.
The code to use the max line speed is also very simple.
Each individual piece is very simple and hard to mess up. It’s also easy to test each individual piece. Machines can be taken out, added, or replaced very easily without worrying about how it affects the system.
Usually, when I walk new programmers through creating programs this way, they’re amazed at the end because the end result is a complex system but it was made from all of these simple pieces.
The key idea here is that the complexity is not a function of the number of machines. And here I mean the complexity of writing and managing the code (space and time complexities here are linear). The code pieces are quite simple and you don’t have to hold very much in your head at any one time.
If your working on a particular machine program, you just worry about that machine. Not the line as a whole.
If you’re working on the framework, you don’t worry about specific machines. You’re dealing with abstract interfaces.
And now we have a system that’s better for a programmer to manage and change. But an electrician cannot look at it to see what’s going on. So, then you have to start dealing with how to get this information onto the HMI. Topic for another time.
Validation also becomes easier because the scope of your change is more limited. This is really, really important. The program has to written in a way to limit the scope of your changes.
This example is somewhat contrived, but it gets the idea across. Next steps are to break the machine out and manage that complexity. For example, you could have functions and sub functions within the machine, all writing to the their own framework interfaces and use reducers to collapse the data for top level use (...kind of sounds like a recursive data structure...). You can write domain specific code and swap out peripheral implementations (electric motor vs hydraulic motor, linear transducer vs encoder, etc) and on and on.
Safety related programming for safety functions is a little different. It’s more restrictive and has higher requirements of validation. But even here, I still use good practices and make abstractions to keep things as clean as possible.