ros-drivers / rosserial

A ROS client library for small, embedded devices, such as Arduino. See: http://wiki.ros.org/rosserial
508 stars 527 forks source link

Teensy 4.1 NativeEthernet #532

Open drewhamiltonasdf opened 3 years ago

drewhamiltonasdf commented 3 years ago

I have been working all day trying to get this up and running the TCPHelloWorld example with a Teensy 4.1. I've swapped out the includes with includes and I just can't seem to get it working:

drew@drew-desktop:~/ros_ws$ rosrun rosserial_python serial_node.py tcp
[INFO] [1604807330.470733]: ROS Serial Python Node
[INFO] [1604807330.476709]: Fork_server is: False
[INFO] [1604807330.477776]: Waiting for socket connections on port 11411
[INFO] [1604807330.479025]: Waiting for socket connection
[INFO] [1604807330.481331]: Established a socket connection from 192.168.0.177 on port 8888
[INFO] [1604807330.482243]: calling startSerialClient
[INFO] [1604807332.586842]: Requesting topics...
[ERROR] [1604807860.185231]: Unable to sync with device; possible link problem or link software version mismatch such as hydro rosserial_python with groovy Arduino

I've tried installing this a) from binary b) from source c) using the Arduino Library manager to download rosserial and then patching in

Nothing seems to work. As far as I can tell the NativeEthernet library for Teensy 4.1 is 100% interoperable with the old Ethernet library that required a shield. I've had chatservers, Twitter clients, telnet etc etc. all running successfully on the Teensy, but I can't seem to get ROS to talk to it.

The Teensy seems to be pausing it's execution when the serial_node.py establishes the socket connection.

I should also mention that I am able to successfully establish a regular serial connection with USB between the Teensy and my PC using the HelloWorld example.

Any help would be greatly appreciated.

drewhamiltonasdf commented 3 years ago

I could not rest until I had this working. I managed to get it to work by re-implementing methods for init() and read() and write() in the INO. I now call

ros::NodeHandle_<NATIVE_hardware> nh;

This is one of those hair-tearing out moments in which the solution does not quite compute for me. This looks very similar to what I find in the ArduinoTcpHardware.h library. I'm not understanding why I have to override these functions.

class NATIVE_hardware {
  public:
    NATIVE_hardware() {};

    void init() {
        while(!client.connect(server, serverPort))
        {
          Serial.println("Attempting to connect [run serial_node on PC]...");
          delay(1000);
        }
    }

    int read() {
      if (client.available())
      {
          int c = client.read();
          return c;
      }
      return -1;
    }

    void write(uint8_t* data, int length) {
          for (int i = 0; i < length; i++) {
        client.write(data[i]);
      }
    }

    unsigned long time() {
      return millis();
    }
};
KelseyKim commented 2 years ago

Hi Drew, I know this is a year old issue, but I think I might be running into the same problem (same outputs and Teensy stops after establishing a socket connection). Would you mind sharing how you implemented the NATIVE_hardware class? Did you put all of that code in your main .ino script or in a header file separately? Thank you!

jetdillo commented 2 years ago

I'm also running into this. The fix appears unmerged into rosserial, although it looks like the code gets dropped into rosserial/rosserial_arduino/src/ros_lib/ArduinoTcpHardware.h

It would be helpful to get it merged in properly to save others the trouble of hacking in the fix themselves though.

mgosselin commented 1 year ago

I also ran into this issue. But thanks to this thread was able to get the TcpHelloWorld rosserial example working with the NativeEthernet library on a Teensy 4.1. The client.available() check is key, I wish the fix would get merged in, so myself and other users could benefit from it.