Issues with shared resources in multiple states


#1

I’ve run into an issue before trying to control one specific motor from multiple states and I’m now having the same problem controlling a servo so I figured this same concept may apply to many different types of hardware…thus the new thread. For the motor I worked with nkrkv to make a new library and work some hacks to make it work and it did. For the servo I’m trying to do it myself using what I learned from the creating nodes in c++ documentation. I think I’m close but it is still a little buggy. The issue comes from having multiple states trying to control the same hardware and I’ve ended up with conflicting values and unpredictable results. My solution is to have each state attach the servo on “SET” and then detach the servo on “DONE”. I modified the standard servo hardware c++ code to have a pulse input for “ATTACH” and another for “DETACH”. I’ve uploaded a picture showing the stock servo code on the left and my modified version on the right.

This seems to work well for a program that has no feedback loops. The issue is when I try to implement a feedback loop using the “defer-pulse” node the program only runs one time and never repeats. In the 2nd picture the left main function works properly but the right one never repeats. The rightmost picture shows the structure of my “lookleft”, “lookright”, and “lookstraight” patches with the only difference being the number bound to the gate.

I’ve also attached the .xodball file.

sharedResourceServo.xodball (52.3 KB)

Please help me to understand why this program is not repeating and how to fix it.


#2

Hello, sorry for the reply delay. I’m pretty sure the problem is in code:

    if (isInputDirty<input_ATTACH>(ctx)) {
        if (port != state->configuredPort) {
        	state->servo.attach(port);
        	state->configuredPort = port;
        }
    }

It gives no chance to call servo.attach for the second time, when the second iteration begins. The inner if will always return false after the first call. I suggest dropping configuredPort check, and in your modification just look at ATTACH and DETACH signals. Try to remove configuredPort completely.

BTW, on the bottom right patch, I think the flip-flop is not required. You could link delay.ACT to gate-number.EN directly to achieve the equivalent result.


#3

Perfect. Works great now. Here’s the new code.

State* state = getState(ctx);

auto port = (int)getValue<input_PORT>(ctx);

if (isInputDirty<input_ATTACH>(ctx)) {
    state->servo.attach(port);
    state->configuredPort = port;
}

state->servo.write(getValue<input_VAL>(ctx) * 180);


if (isInputDirty<input_DETACH>(ctx)) {
   	state->servo.detach();
}