Tournament manager calls user_control() multiple times?

Hi, I’ve seen strange issues occasionally that only surface during competition. After reviewing code the only explanation seems to be that user_control() gets called more than once. I have not been able to reproduce this at our home field. I have tested both with the VEXNet field switch and the Smart Field Controller running on a regular brain suspecting its a debounce issue particularly with the DIP switches.

Today I got the opportunity to help setup tournament manager and got a repro immediately.

Here’s the start of my test user_control(), the exception triggered.


def user_control():
    global USER_STARTED
    if (USER_STARTED):
        raise RuntimeError("user_control called multiple times")
    USER_STARTED = True

    print("user control")
    # other stuff here

A 100msec delay at the start of user_control() seems take care of things. This was using the dedicated Smart Field Controllers and a Raspberry PI to connect to TM on a PC (all running latest FW / apps).

Thanks,
Nick

This is definitely not an isolated issue. A while back, I had problems getting LED strips to work as I was initialising them in op control. However, this only happened when using a field controller.

In a thread where I got advice, other people had similar issues and also suspected op control running multiple times with the field control.

Unfortunatly I don’t know why it happens, so your solution is probably the best. But I find with an issue like this its good to know when you aren’t the only one.

Hope this helps. :slight_smile:

I don’t know exactly when you are seeing this happen, but it’s pretty normal if the program is started before connecting to field control (or before the field is activated depending on how field control is setup) as the radio will jump to a competition channel causing radio disconnect and the V5 coming out of the disabled state.

@jpearman we ran through a match simulation by doing the 15sec autonomous and then into driver control which is when the exception triggered. I did plug the cable into the controller port before starting the program, but you’re right, I don’t know the exact cycling of the tournament code in relation to me starting the program.

OK, so that’s interesting what you’re saying. Very helpful. I will make sure everyone knows that if you get a red controller screen disconnect during match setup that’s an indication to restart the program.

I’ll get hold of a RPI so I can get the same setup going to test.

The test case that got me looking out for this was when the team was registering their controller callbacks right at the start of user_control(). The only explanation for the behavior they were seeing was that the callbacks were being registered twice and this seems to validate that.

Thanks,
Nick.

probably not the best idea.
do that on program start.

I’ll check if anything has changed re TM next week, I have not tested anything with TM for over a year. For user control to trigger twice, TM or field control (or the brain due to radio connection lost) would need to transition through disabled first.

I also need to check if it’s a Python issue, I’m usually testing with C++

Thanks - I’ll get the setup going here next week so I can test in a more controlled environment.

I was having the light issues with C++ on Pros, it seems pretty universal.

Any user function may run in any order, any number of times. Your code should be designed around this fact.

Common scenario:

  1. User starts program with controller UNPLUGGED from field control.
  2. Program starts, VEXos falls back to default competition flags when unplugged (DRIVER | ENABLED).
  3. Driver control starts.
  4. User plugs controller into field control.
  5. Field control places robot into (DISABLED | AUTONOMOUS).
  6. Robot is disabled until the match starts.
  7. Match starts, autonomous runs, disabled again, driver runs for the second time.

Simply starting your program before plugging into field control result in user_control()running twice. In reality, it can run any number of times. For example, a radio drop could potentially do weird things to user code, or TM may decide to re-run auto.

The only code guaranteed to run ONCE is main/initialize/pre_auton/etc…

Don’t register persistent callbacks or tasks, or expect any competition handler to run only a single time in a specific order.

See Competition code and user created tasks as well.

I ran some tests using latest TM and RasPi connected to the event brain. I’m not seeing anything unusual or unexpected, the previous post summarized everything pretty well.

Thanks all, we’ll adapt our code. But also says we need a full tournament setup to test our code. I guess you can simulate with VexNet Comp Switch but good to validate against the real thing.