This page hosts the documentation of the SmartCGMS software architecture and all of its components.


When you predict future glucose level, typically you have all input signals at once. They may include current sensor reading, insulin delivery, meal ingestion info, etc. Each prediction exhibits an error. To correct future errors, you may desire to path the recent error back to the prediction input. In such a case, you need to establish a feedback.

Similarly, when controlling glucose level with an artificial pancreas, the insulin (and possibly glucagon) dosage computing algorithm needs the feedback to perform an efficient glucose-level control. Let us consider an in-silico experimental setup. Using the log-replay filter, we would replay a fixed schedule of multiple meal ingestions. The replay would go to directly to the discrete model filter, with a personalized in-silico patient model. This model provides simulated sensor readings and accepts insulin delivery. Therefore, we need to compute the actual insulin delivery after from the model output. Then, we pass the computed insulin delivery back to the model using a feedback mechanism.

When translating the developed pump-control algorithm to the practice, we would replace the patient model with a sensor-reading filter. Then, we would add pump-controlling filter between the algorithm filter and the feedback filter. Note that pump itself can decide to deliver insulin at a different rate than requested. Therefore, we need to transfer the effectively applied insulin delivery rate to algorithm-filter input. Therefore, we still need to establish the feedback as with any other control/regulatory system.


To establish the feedback link use the Signal Feedback filter. In this filter, configure the feedback name. Similarly, configure another feedback-receiving filter with the same feedback name. Note that only some filters (such as model filters) can act as feedback receivers. To act as a feedback receiver, the filter must implement the IFilter_Feedback_Receiver interface.

class IFilter_Feedback : public virtual scgms::IFilter {
        virtual HRESULT IfaceCalling Name(wchar_t** const name) = 0;

constexpr GUID IID_Filter_Feedback_Receiver = { 0xee9d9028, 0xb714, 0x4412, { 0x98, 0xd8, 0xe5, 0xf7, 0xe5, 0xf1, 0xcf, 0x7a } };
class IFilter_Feedback_Receiver : public virtual scgms::IFilter_Feedback {

constexpr GUID IID_Filter_Feedback_Sender = { 0x19d21259, 0x7358, 0x4533, { 0x8c, 0x18, 0x85, 0x65, 0x25, 0xc2, 0x35, 0x9 } };
class IFilter_Feedback_Sender : public scgms::IFilter_Feedback {
        virtual HRESULT IfaceCalling Sink(scgms::IFilter_Feedback_Receiver *receiver) = 0;

When instantiating the filter chain, SmartCGMS will automatically pair feedback sender and receiver, which shares the same name. The IFilter_Feedback_Sender allow multiple receivers to connect to a single sender. The Signal Feedback filter implements such functionality. IFilter_Feedback_Sender::Sink should register as many listeners as many times it get called with non-null pointer. There's no call for un-registering a listener on a purpose, because such a functionality would harm a static analysis when proving fail-aware properties of the resulting SmartCGMS configuration.

It makes sense to implement IFilter_Feedback_Receiver interface for filters, which somehow mimics or actually control an insulin pump. Such filter should accept the signal_Requested_Insulin_Basal_Rate and signal_Requested_Insulin_Bolus signals, process and discard them, while producing a respective signal_Delivered_Insulin_Bolus and signal_Delivered_Insulin_Basal_Rate signals. Note that insulin-pump motor-controller itself may set a different basal rate than the requested one and that insulin bolus may be translated to a temporarily altered insulin basal rate.


As was already stated above, the SmartCGMS will automatically establish the link. This only means, that the sender stores a list of receivers, which expect to receive events from the feedback during operation. The feedback link is a simple reference to an earlier filter, without any extension methods. The feedback sender invokes the Execute method of the receiver. It is not generally possible to distinguish events, that came from the previous filter, from events coming through the feedback link.

This implies, that the event, that triggered the feedback link, should not reach the same feedback sender again. Feedback sender is configured to forward events with specific signal GUID, so the common practice is to change the signal GUID while processing the event. A good example would be the one mentioned above - the feedback sender sends signal_Requested_Insulin_Basal_Rate to the pump filter (or model filter), and upon setting the basal rate to the internal controller, it changes the signal GUID to signal_Delivered_Insulin_Basal_Rate. This effectively avoids further recursive feedback invocation.

Feedback link

The above figure illustrates the operation of a feedback link. Note that red dashed line depicts an unwanted scenario, when the feedback-sended event reaches the same feedback sender again. That would cause possibly infinite recursion. The feedback sender filter implemented within the SmartCGMS tracks this recursion depth and when the same event loops more than 10 times (mMaximum_Stack_Depth), an error is returned.