An object-oriented framework can be used to create safe, testable and tunable motion control systems.
Writing the software to handle motion control is a critical job on any real-time system design project. Safety is of the utmost importance. And, of course, it is also important that the code work precisely and allow for testing and performance tuning. An object-oriented framework can be used to create safe, testable and tunable motion control systems.
Developing firmware for motion control systems can be a tricky business. Strict accuracy and repeatability combine with user safety to present a challenging set of requirements. How do you go about designing motion control firmware to meet these requirements properly? And how can you ensure the resulting implementation is tunable and testable from the start? In using what are some key design methodologies and the beginnings of a framework for safe, testable and tunable motion control firmware, it is important to consider the design goals.
Safety concerns vary by the industry for which you write firmware. In such application areas as medical devices and aerospace systems, safety is the critical priority. How a system handles failures from a safety perspective might vary. For example, in a medical device that uses motion control, if there is a systematic failure, the system must fail in a manner that will keep the patient or user safe. This may simply be to invoke an electromechanical interlock and alert the operator. In other cases, a failure in the system may not be as simple as shutting down, and so the events that take place following a failure must be well defined.
The testability of a motion control system starts with good architecture, and the firmware plays a key role. Test engineers must have the ability to verify all software modules to ensure correct behavior. One of the most common mistakes is testing with only valid (i.e., in range) inputs. The real key to testing is subjecting the system and/or its various modules to invalid inputs and ensuring the system behaves correctly and safely under all possible conditions.
If a bug causes the software to request motion that requires infinite acceleration, does the firmware respond safely or does it instead try to perform the erroneous operation and hope for the best? For a safety-critical system, this can have devastating results, for example if a surgical robot receives an invalid position or velocity command.
Testable motion control systems should also provide means for tuning the motion control parameters. Tuning is necessary to ensure both precision and repeatability in movement outcomes, with such calibration generally motor-specific.
Infrastructure Planning
Reaching all of our design goals properly in the first implementation requires time to think and plan prior to the start of coding. At the same time, we also need to consider the tools we'll use to get the job done. Before getting into the always-interesting specific motion control algorithms and low-level hardware controls, we should first consider the software framework.
Infrastructure planning starts by thinking and using object-oriented analysis and design techniques. We have a great modeling tool at our disposal in Universal Modeling Language (UML) class diagrams and state charts. But we can begin, with or without UML, by identifying a few objects with limited and discrete sets of responsibilities. Used properly, objects also help avoid coupling between subsystems through encapsulation and good interface design.
To make our discussion concrete, consider the UML class diagram in Figure 1, which shows how to represent sensor and motor objects in an abstract way. We know there are many different types of sensors and motors. However, these objects do have common sets of features. In addition, there is a relationship between motors and their associated sensors. In the model shown, we do not directly incorporate sensor functionality with our motor implementation, but rather associate sensors with a motor instance. This object model immediately shows us extensibility and reuse using abstraction and class inheritance. The sensor and motor object model also sets us up for maintainability because we are avoiding putting all our functionality into a single object.
To reach our testability goals, we need to go a step further than this model by defining the public interface to each object. Once the interface is in place, white box tests can be developed to ensure proper functionality and the ability to handle invalid inputs.
We now have a set of objects in our framework for managing the motion control itself, but we mentioned earlier that infrastructure was one of the keys to success. Let's assume that our motors and sensors have the data we need, but how can we make it available, especially if we're running in an embedded system? This is where the classes in Figure 2 become part of our infrastructure.
Figure 2 presents a few different ideas. The first is the CDataComm class, which is a singleton object that provides a gateway to the outside world. The actual communication channel might be RS-232, USB, or Ethernet; it really doesn't matter from the system perspective. The CDataComm object manages requests for data and sends responses. There are more efficient mechanisms, but we are assuming a query/response communication model.
The next thing to notice is the CDataLogger object. CDataLogger is an instance of an active object (perhaps running in its own task) that maintains a list of CDataLoggerItem derived objects. CDataLoggerItem provides an interface for common methods but does not actually contain any real data. The derived class, in this case CBLDCMotorDataItem, contains the specific data we care about.
Using polymorphism, the data is formatted and obtained over our communication channel. As we manage/control the motor, we set and add CBLDCMotorDataItem data to our running list that is managed by the CDataLogger instance. As a side note, we would want to allocate our CBLDCMotorDataItem objects ahead of time and keep them in a memory pool to avoid dynamic memory allocation at runtime.
From the outside world, we access the list of data through our communication interface. This data becomes available for performing offline or near real-time analysis and/or display of data. The data could include position, velocity, current, or other data. It is completely up to the developer to define what data to provide. Of course, we can also imagine a lot of possibilities for other objects like CBLDCMotorDataItem that could be used for various purposes.
So what do we do with the data now that we have it available? That's really up to you, but we have used this data, combined with a small custom application, to provide live data displays or perform calculations. You could also do runtime calculations and graph the results to monitor your motion control behavior at runtime. The available tools for developing such test applications are varied, but could include Java, .NET, or LabVIEW, all of which have extensive support for communicating with your firmware. You could even go so far as to develop an entire testing infrastructure that matches your firmware infrastructure that would allow your testers to write a variety of test applications.
Event-Driven Software
The next level of design for the framework provides a means to ensure efficient and deterministic behavior. We recommend taking advantage of an event-driven, message-based framework to communicate among your objects.
An event-driven software architecture works well with an object-oriented design such as that above. It also helps to ensure efficient use of the CPU and ties into another valuable design methodology: state machines. Using an event-driven architecture combined with state machines utilizes run-to-completion semantics, which eliminate race conditions, and can ensure deterministic response times for critical system event handling. You can do this using RTOS mailboxes or message queues, or with a state-machine framework.
The use of state machines ensures predictable and discrete behavior based on a given system event. With UML state charts, you can provide industry standard diagrams that clearly define system behavior. Figure 3 shows an example of a simplified motion control state machine.
The advantage of implementing our behavior using the state machine versus a flowchart approach is that we don't need to check a bunch of flags using convoluted if/then/else spaghetti code. Additionally, the system only reacts to system events that matter based on the current system state. In this simplified example, there are only 11 possible states in which the axis can be at any given time. However, if we tried to manage the system with as few as, for example, 4 Boolean flags, then there are 16 possible system states. Each additional flag used to manage the state doubles the number of possible states, making unit and system maintainability, extensibility and testing difficult.
Verification
As mentioned, testing is critical when developing motion control firmware. In safety-critical systems, this is more formally referred to as verification. The verification process requires written detail and proof that the system has passed testing. The verification process usually involves formal test plans and procedures to be written, reviewed and approved.
During the development of the test plans and procedures, engineers need to devise tests that ensure their device meets the requirements. For the motion control case, this is usually done using an external measurement device. We're not suggesting we could eliminate external measurement, but our framework gives us another avenue for test.
By using the internally measured data provided through the communication interface, we have an additional means to test and troubleshoot the system. If internally measured data can be verified, the motion control system can be considered self-validating once you take into account the need for system calibration. This is a valuable outcome.
The foregoing is presented as a basis for developing a framework when designing motion control firmware. With a little forethought, planning and good design practices combined with realizing the need for development and test tools, an extensible code base can be developed for creating safe motion control firmware. This firmware will not only be reused for varying needs, but it can be properly tested and maintained into the future.
Related Barr Group Courses:
Firmware Defect Prevention for Safety-Critical Systems
Top 10 Ways to Design Safer Embedded Software
Best Practices for Designing Safe & Secure Embedded Systems
Best Practices for Designing Safe Embedded Systems
For a full list of Barr Group courses, go to our Course Catalog.