allwpilib icon indicating copy to clipboard operation
allwpilib copied to clipboard

AsynchronousInterrupt "polarity" in simulation

Open briceonk opened this issue 5 months ago • 0 comments

Describe the question you have. While looking at the AsynchronousInterrupt class, I noticed that the boolean values passed into the callback don't seem to line up with the edge that actually triggered. The documentation (like this link) simply states that the booleans indicate which edge fired the interrupt. In both C++ and Java, it seems to be "active low", that is, it passes in false for the edge that triggered the interrupt. Just wanted to check if that was the expected behavior? Apologies in advance if this is documented elsewhere and I just missed it, am not using the DigitalInput simulation correctly, or am misinterpreting what this is supposed to look like. I tried to check all of the information I could find about it, including the source code and the SynchronousInterrupt documentation. I'm not very familiar with the lower-level HAL stuff though, unfortunately.

image

Describe the reason for your confusion. I'm unsure what the expected behavior should be. Just by reading the description, I thought the triggering edge might have been supposed to be true.

Is your question related to a problem? Please describe. I initially set up some code to play around with the interrupts and noticed that the initial logic I was using didn't work, because the boolean values were the opposite of what I thought was the "logical" (maybe?) setup. Of course, this is probably user error, hence the question :)

I had initially done something like:

void handleSensorInterrupt(Boolean rising, Boolean falling) {
    if (rising) {
        // ...
    }
}

Additional context Code that can reproduce this in simulation (on Linux and macOS, at least)

// RobotContainer.h
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

#pragma once

#include <frc2/command/CommandPtr.h>
#include <frc/AsynchronousInterrupt.h>
#include <frc/DigitalInput.h>

class RobotContainer {
 public:
  RobotContainer();

  frc2::CommandPtr GetAutonomousCommand();

 private:
  frc::DigitalInput testInput;
  frc::AsynchronousInterrupt testInterrupt;

  void ConfigureBindings();
  void ExampleInterruptHandler(bool rising, bool falling);
};

// RobotContainer.cpp
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

#include "RobotContainer.h"

#include <iostream>
#include <functional>
#include <frc2/command/Commands.h>

RobotContainer::RobotContainer() : testInput(0), testInterrupt(testInput, std::bind(&RobotContainer::ExampleInterruptHandler, this, std::placeholders::_1, std::placeholders::_2)) {
  ConfigureBindings();
  testInterrupt.SetInterruptEdges(false, true);
  testInterrupt.Enable();
}

void RobotContainer::ConfigureBindings() {}

frc2::CommandPtr RobotContainer::GetAutonomousCommand() {
  return frc2::cmd::Print("No autonomous command configured");
}

void RobotContainer::ExampleInterruptHandler(bool rising, bool falling) {
  std::cout << "Rising: " << rising << " Falling: " << falling << std::endl;
}

Example screenshot, showing the interrupt set up to fire on active low. Whenever the DIO input is changed from 1 to 0, the message is printed, but with the falling boolean set to be 0.

image

Of course, I see the same behavior if both edges or just the rising edge is set, where the triggered edge is passed in as 0.

Thank you! :)

briceonk avatar Mar 15 '24 06:03 briceonk