I'm trying to communicate between an Ubuntu 22.04 computer running ROS2 Iron and a Teensy 4.1 over Ethernet, but am not having much luck. On the Ubuntu side, I have ROS2 installed and that's it.
On the Teensy side, I've found ros2arduino
and micro_ros_arduino
libraries, but am running into issues with both of them.
The micro_ros_arduino
library I can't get to build at all. It doesn't appear to be built into either the Arduino IDE or PlatformIO on VSCode.
On the Arduino IDE, I've tried adding it as a ZIP library, but I get Error: 13 INTERNAL: Library install failed: extracting archive: Not a supported archive: unknown
. On PlatformIO I can add the library through the HTTPS git clone URL, but when I try to build it, I get
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\teensy41\firmware.elf] Error 1
with absolutely no other errors. I know that error usually means something earlier failed, but there are no other errors in the build output.
The publisher_ethernet_udp example in the ros2arduino
library will build and run just fine, but I can't seem to get it to actually publish anything. When using the default Ethernet
library, it hangs at the while(Ethernet.linkStatus() != LinkON);
line forever. By switching to the QNEthernet
library and adding DHCP, I can connect to the local network, get through the ros2::init
, and start the spin, but nothing ever publishes. My guess is that it's failing to connect to the ROS2 instance on the Ubuntu machine, but I don't know what's missing to let it do so. I've tried setting the AGENT_IP
to the IP address of the Ubuntu machine (which I believe is the correct setting), as well as the IP of the Teensy and just some random IPs for kicks. I don't know what the AGENT_PORT
should be set to, but I've tried 11811
and the default 2018
. The ros2arduino
and QNEthernet
code is below:
main.cpp
#include <Arduino.h>
#include <ros2arduino.h>
#include <QNEthernet.h>
using namespace qindesign::network;
#define AGENT_IP "192.168.1.37"
#define AGENT_PORT 2018 //AGENT port number
#define PUBLISH_FREQUENCY 1 //hz
constexpr uint32_t kDHCPTimeout = 15'000; // 15 seconds
// UDP port.
EthernetUDP udp;
//this publishstring function never runs
void publishString(std_msgs::String* msg, void* arg) {
(void)(arg);
static int cnt = 0;
sprintf(msg->data, "Hello ros2arduino %d", cnt++);
Serial.println("Publishing");
}
//this section runs
class StringPub : public ros2::Node {
public:
StringPub()
: Node("ros2arduino_pub_node")
{
ros2::Publisher<std_msgs::String>* publisher_ = this->createPublisher<std_msgs::String>("arduino_chatter");
this->createWallFreq(PUBLISH_FREQUENCY, (ros2::CallbackFunc)publishString, nullptr, publisher_);
}
};
void setup() {
Serial.begin(115200);
delay(3000);
Serial.println("Starting");
uint8_t mac[6];
Ethernet.macAddress(mac);
Serial.printf("MAC = %02x:%02x:%02x:%02x:%02x:%02x\r\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.printf("Starting Ethernet with DHCP...\r\n");
if (!Ethernet.begin()) {
Serial.printf("Failed to start Ethernet\r\n");
return;
}
if (!Ethernet.waitForLocalIP(kDHCPTimeout)) {
Serial.printf("Failed to get IP address from DHCP\r\n");
return;
}
IPAddress ip = Ethernet.localIP();
Serial.printf(" Local IP = %u.%u.%u.%u\r\n", ip[0], ip[1], ip[2], ip[3]);
ip = Ethernet.subnetMask();
Serial.printf(" Subnet mask = %u.%u.%u.%u\r\n", ip[0], ip[1], ip[2], ip[3]);
ip = Ethernet.gatewayIP();
Serial.printf(" Gateway = %u.%u.%u.%u\r\n", ip[0], ip[1], ip[2], ip[3]);
ip = Ethernet.dnsServerIP();
Serial.printf(" DNS = %u.%u.%u.%u\r\n", ip[0], ip[1], ip[2], ip[3]);
ros2::init(&udp, AGENT_IP, AGENT_PORT);
Serial.println("ros init");
}
void loop() {
static StringPub StringNode;
ros2::spin(&StringNode);
}
platformio.ini
[env:teensy41]
platform = teensy
board = teensy41
framework = arduino
lib_deps =
robotis-git/ros2arduino@^0.2.1
https://github.com/ssilverman/QNEthernet.git
Any help or guidance would be appreciated.