mjs513 / libuavcan-Teensy-3.x

UAVcan for Teensy 3.x using Teensyduino/Arduino IDE
5 stars 3 forks source link

equipment::actuator::Command #4

Open flybrianfly opened 2 years ago

flybrianfly commented 2 years ago

Hey Mike,

I'm noticing an issue publishing message equipment::actuator::Command. Example code is:

#include "Arduino.h"
#include "uavcan.h"
#include "uavcan/uavcan_teensy/uavcan_teensy.hpp"
#include "uavcan/transport/can_acceptance_filter_configurator.hpp"
#include "uavcan/dsdlc/equipment/actuator/Command.hpp"

/* Defines needed for restart */
#define RESTART_ADDR       0xE000ED0C
#define READ_RESTART()     (*(volatile uint32_t *)RESTART_ADDR)
#define WRITE_RESTART(val) ((*(volatile uint32_t *)RESTART_ADDR) = (val))

/* Node constants */
static constexpr uint32_t NODE_ID = 102;
static constexpr uint8_t SW_VER = 1;
static constexpr uint8_t HW_VER = 1;
static const char* NODE_NAME = "TEST";
static const uint32_t NODE_MEM = 8192;  // size of node memory

/* System clock and CAN driver */
ISystemClock *clock = &uavcan_teensy::SystemClock::instance();
ICanDriver *can;

/* Node and publisher */
Node<NODE_MEM> *node;
Publisher<equipment::actuator::Command> *pub;

/* Data message */
equipment::actuator::Command msg;

/* Fake airspeed data */
float airspeed_ms = 0;

/* Function to restart Teensy, inherits from UAVCAN */
class : public IRestartRequestHandler {
  bool handleRestartRequest(NodeID request_source) override {
    Serial.println("Got a remote restart request!");
    WRITE_RESTART(0x5FA0004);
    return true;
  }
} restart_request_handler;

void setup() {
  /* Serial to print feedback */
  Serial.begin(115200);
  while (!Serial) {}
  Serial.println("Demo started");
  /* Init CAN transceivers - this is HW config dependent */
  pinMode(26, OUTPUT);
  pinMode(27, OUTPUT);
  digitalWriteFast(26, LOW);
  digitalWriteFast(27, LOW);
  /* Init CAN driver */
  uavcan_teensy::IfaceParams iface_param[] = {
    /* Config CAN0 */
    {
      .bitrate=1000000,               // bit rate of can bus
      .tx_buff_size=64,               // TX ring buffer size
      .rx_buff_size=64,               // RX ring buffer size
      .use_alt_tx_pin = false,        // use alternative TX pin
      .use_alt_rx_pin = false,        // use alternative RX pin
      .dis_all_RX_by_default = false  // disables all RX mailboxes
    }
  };
  uavcan_teensy::CanDriver::instance().init(iface_param);
  can = &uavcan_teensy::CanDriver::instance();
  /* Init Node */
  node = new Node<NODE_MEM>(*can, *clock);
  protocol::SoftwareVersion sw_ver;
  protocol::HardwareVersion hw_ver;
  sw_ver.major = SW_VER;
  sw_ver.minor = 0;
  hw_ver.major = HW_VER;
  hw_ver.minor = 0;
  node->setNodeID(NODE_ID);
  node->setName(NODE_NAME);
  node->setSoftwareVersion(sw_ver);
  node->setHardwareVersion(hw_ver);
  node->setRestartRequestHandler(&restart_request_handler);
  if (node->start() < 0) {
    Serial.println("ERROR starting node");
    while (1) {}
  }
  Serial.println("Node initialized");
  /* Init publisher */
  pub = new Publisher<equipment::actuator::Command>(*node);
  if (pub->init() < 0) {
    Serial.println("ERROR initializing publisher");
    while (1) {}
  }
  Serial.println("Publisher initialized");
  /* CAN acceptance filters */
  configureCanAcceptanceFilters(*node);
  /* Set Node mode to operational */
  node->setModeOperational();
  Serial.println("Setup complete");
}

void loop() {}

And pub->init() returns less than 0 for me. The interesting thing is that if I use the equipment::air_data::TrueAirspeed message, I don't have any issues, so it appears to be specific to the equipment::actuator::Command message. I don't have enough insight yet to tell whether it's an issue with the Teensy implementation or a larger DroneCAN issue. I am seeing the same problem with my version of the Teensy DroneCAN library also, but thought it would be easier to debug on yours, since your CAN bus library is much simpler.

flybrianfly commented 2 years ago

So far, I've figured out that it's because equipment::actuator::Command does not have a default data type ID, so it's not registered with the uavcan data type registry. Why it doesn't have an ID, I haven't figured out yet.

flybrianfly commented 2 years ago

I just confirmed that the newest DSDL and compiler also generate this message without a default data type ID and raised the issue with DroneCAN.

mjs513 commented 2 years ago

Hi Brian

As you said in the DroneCAN issue think you are going to need use the arraycommand for publishing actuator commands. Did a search and finally found what I was looking for. Check out what Ardupilot's AP_UAVCAN is doing for acutators:https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_UAVCAN/AP_UAVCAN.cpp.

For publisher is around https://github.com/ArduPilot/ardupilot/blob/bda280bcf158f0740bc65d07c94a55fe21365627/libraries/AP_UAVCAN/AP_UAVCAN.cpp#L339

Have to admit, I did try a few of them like for gimbals, gnss etc but never that one.

Ok now to look at your example

flybrianfly commented 2 years ago

After I posted the issue to the DroneCAN repo, I tried ArrayCommand and that certainly works, once I figured out how to use the ArrayModeDynamic type. I think we're right, that you are only supposed to use the ArrayCommand.