Wiznet makers

Benjamin

Published August 27, 2026 © MIT license (MIT)

156 UCC

11 WCC

24 VAR

0 Contests

0 Followers

2 Following

Original Link

Why Does a W5500 Ethernet Link Carry ROS 2 Drive Commands in the ULSTU Buggy?

ULSTU put a W5500 on the ESP32 board of its Ackermann teaching robot, so a Jetson AGX Xavier sends JSON-RPC drive commands and reads IMU data over wired UDP.

COMPONENTS Hardware components

WIZnet - W5500

x 1

Ethernet controller on the ULSTU low-level control board. Carries ROS 2 drive commands from a Jetson AGX Xavier to the ESP32 as JSON-RPC over UDP port 9090, and returns IMU samples on the same port. T


PROJECT DESCRIPTION

📌 An Ackermann Teaching Robot From Ulyanovsk State Technical University

Ulyanovsk State Technical University created the buggy-learn repository on GitHub on 2025-04-05, and the low-level control board of the robot inside it carries a WIZnet W5500 Ethernet controller. The GitHub organisation ulstu lists its location as Ulyanovsk, Russia and its contact address as fist@ulstu.ru. The repository is MIT licensed, copyright 2025 Ulyanovsk State Technical University, with commits from k.svyatov@ulstu.ru and the account ghub-ayrtom, the last of them on 2025-04-11.

Photograph of the ULSTU buggy robot, a black short-course radio-controlled car chassis with a scanning laser on an acrylic plate at the front, a red lithium battery, a black finned computer, and a grey Ethernet cable looping over the rear, standing on a laboratory floor in front of a cardboard building model The assembled robot. The scanning laser sits on the front plate, the onboard computer behind it, and a network cable loops over the rear deck. Photo: ULSTU, buggy-learn repository.

ULSTU describes buggy-learn as a platform for learning robotics from scratch, shipping 3D models, control libraries, a virtual proving ground, a map editor and circuit designs alongside the physical robot. The published progression diagram runs from block programming for school grades 4 to 9, through a ROS 2 simulator for grades 10 to 11, to ROS 2 on the real robot for engineering teams.

Why Ackermann Steering Changes the Software Stack

Most teaching robots, and most ready-made ROS packages, assume differential-drive or mecanum wheels that can spin in place. Real cars steer with Ackermann geometry, where the front wheels turn through slightly different angles and the vehicle cannot rotate about its own centre, which restricts the trajectories a planner may produce. ULSTU chose an Ackermann chassis so that lab work transfers to full-size driverless cars.

The base is a Traxxas Raptor Ford F-150 short-course radio-controlled model with the factory radio gear removed and replaced by a networked control kit, a Nvidia Jetson AGX Xavier and a Hokuyo laser rangefinder. That choice shows up in the code as ackermann_keyboard_teleop_node.py, a WASD keyboard node publishing ackermann_msgs/AckermannDrive on /cmd_ackermann with ROBOT_MAX_SPEED set to 8.0 cm/s and ROBOT_MAX_STEERING_ANGLE set to 30.0 degrees.

The Two Layers and the Board That Joins Them

Generated block diagram showing three groups. Actuators and sensors on the left hold a steering servo, a BTS7960 driver feeding the traction motor, and an IMU. The custom control board in the middle holds a W5500 highlighted in red above an ESP32, joined by SPI. The onboard computer on the right holds a Hokuyo laser on USB, a Jetson AGX Xavier, and a dashed Wi-Fi adapter on USB. Ethernet on UDP port 9090 joins the W5500 to the Jetson Generated technical diagram, redrawn in English from the block diagram published in the repository.

The upper layer of the ULSTU buggy is a Nvidia Jetson AGX Xavier running Ubuntu 20.04 and ROS 2 Foxy. The README explains that choice by the age of the hardware, noting the Xavier was released in 2018, and states the same instructions were tested on Ubuntu 22.04 with ROS 2 Humble. A Raspberry Pi or the cheaper Orange Pi can take the same role.

The lower layer is a board of the team's own design. The README lists an ESP32-family microcontroller, a W5500 Ethernet module, a MEMS inertial measurement unit, a 12 V to 5 V converter, and connectors for a BTS7960 transistor board and the steering servo. The perception sensor is a Hokuyo URG-04LX-UG01 single-plane lidar, which the README says can be swapped for equivalent Chinese units, with a camera as an optional addition.

Autonomy here means physical self-containment as well as software. The README states it plainly: "Все оборудование размещается непосредственно на роботе, что позволяет работать полностью автономно", meaning all the equipment sits directly on the robot so it can operate fully autonomously.

Close-up photograph of the ULSTU control board mounted on the robot, showing a blue W5500 Ethernet module with an RJ45 jack and a grey patch cable plugged into it, an ESP32 development board with a lit blue LED, a small green sensor module, green screw terminals and a black finned heatsink below The control board after installation, with the patch cable plugged into the blue W5500 module. Photo: ULSTU, buggy-learn repository.

⚙️ What the W5500 Does for This Robot

The README states the networking decision in one sentence: "В отличие от многих других роботов для обмена данными используется интерфейс Ethernet, реализованный при помощи W5500." In English, unlike many other robots, data exchange uses an Ethernet interface implemented with a W5500.

The README then lists three benefits of that Ethernet link: high operational stability, immunity to interference, and no need to occupy the microcomputer's Wi-Fi adapter or to have an external wireless network available. The root README adds the performance claim, that the ESP32 with its Ethernet module transmits control commands and odometry data "надежно и с низкими задержками", reliably and with low latency.

The published board artwork backs the README. A silkscreen block marked W5500 sits next to a ten-pad module header labelled 3V3, 5V, MISO, GND, MOSI, RST, CS, INT, CLK and GND, which is the standard SPI plus reset and interrupt pinout of an off-the-shelf W5500 module. The same artwork shows an ESP32 devkit footprint and, next to it, an MPU-6050 footprint whose pads read GND, SCL, SDA, XDA, XCL, AD0 and INT.

Two crops of the ULSTU board artwork side by side. The left crop shows green copper traces on black with red silkscreen reading W5500 and a header labelled CLK GND, CS INT, MOSI RST, MISO GND, 3V3 5V. The right crop shows a footprint marked ESP32 beside an MPU-6050 footprint with pads GND, SCL, SDA, XDA, XCL, AD0 and INT Edited repository image: two crops of the published board artwork, upscaled and captioned. The W5500 crop is rotated 180 degrees because that block is drawn upside down in the original.

How Drive Commands and IMU Data Share One Cable

Generated diagram in two lanes. The downlink lane runs from the /cmd_vel and /cmd_ackermann topics through robot_controller_node to the W5500 on the ESP32 board at 192.168.2.11 port 9090, carrying a JSON-RPC message with method set_control_values. The uplink lane runs from the same board over UDP to a socket bound on 0.0.0.0 port 9090 and out to the /imu topic Generated technical diagram. Endpoints and field names read from robot_controller_node.py in the repository.

The bridge between the two layers is a single Python node, buggy/urg_node2/urg_node2/scripts/robot_controller_node.py. It defines UDP_SERVER_IP = '192.168.2.11', UDP_SERVER_PORT = 9090 and RECV_BUFFER_SIZE = 1024, then subscribes to /cmd_vel and /cmd_ackermann and sends each command down as a JSON-RPC 2.0 datagram.

jsonrpc_message = {
    'jsonrpc': '2.0',
    'method': 'set_control_values',
    'params': [speed, steering_angle],
}

jsonrpc_message_str = json.dumps(jsonrpc_message)
self.__sock.sendto(jsonrpc_message_str.encode(), (UDP_SERVER_IP, UDP_SERVER_PORT))

Conversion from ROS 2 velocity commands happens in the same node. Nav2 publishes geometry_msgs/Twist on /cmd_vel, and the node multiplies linear.x by 17.5, multiplies angular.z by -500, then clamps the steering angle to plus or minus 30 degrees before sending. A watchdog in the receive thread stops the robot if no /cmd_vel message has arrived for more than three seconds, which matters on a vehicle whose throttle is held by a separate microcontroller.

The return path uses the same port in the opposite direction. A background thread binds 0.0.0.0 on port 9090, reads datagrams of up to 1024 bytes, parses each as JSON, and copies params[0] into a sensor_msgs/Imu message: the timestamp in seconds and nanoseconds, linear acceleration, angular velocity and orientation. That message is published on /imu, which is where the robot_localization package picks it up.

LinkInterfaceEndpoint or settingWhere it is stated
ESP32 to W5500SPITen-pad header: 3V3, 5V, MISO, GND, MOSI, RST, CS, INT, CLK, GNDBoard artwork ros2/docs/img/scheme_el.png
Control board to onboard computerEthernet, UDP192.168.2.11 port 9090, 1024 byte receive bufferrobot_controller_node.py
ESP32 to IMUI2CMPU-6050 footprint, SCL and SDA padsBoard artwork and block diagram
Onboard computer to lidarUSB or Ethernetip_port 10940, ip_address left blank in the shipped fileconfig/params_ether.yaml
Onboard computer to operator laptopUSB Wi-Fi adapterRemote desktop sessionBlock diagram and repository photographs

Mapping and Navigation on the Onboard Computer

One launch file, urg_node2.launch.py, starts the whole robot, and the README shows which entries to comment in or out for mapping, for localisation and for EKF fusion. The composed node list is the part a reader would otherwise have to assemble by hand:

  • urg_node2_node, the Hokuyo lifecycle driver publishing /scan
  • lidar_odometry_node, scan matching that publishes /odom and the odom transform
  • robot_state_publisher, fed by robot.urdf.xacro
  • robot_controller_node, the UDP bridge to the ESP32 board
  • ekf_filter_node from robot_localization, fusing lidar odometry with the IMU
  • async_slam_toolbox_node for mapping, or localization_slam_toolbox_node for pose tracking
  • rviz plus joint_state_publisher_gui for visualisation and wheel joints
  • a static transform publisher tying map to odom

Photograph of a laptop screen showing an RViz window with a partly built black and white occupancy map and red odometry arrows, with the buggy robot and cardboard building models visible on the floor behind the laptop A mapping run in progress. The red arrows are the robot odometry, and the physical test area sits behind the laptop. Photo: ULSTU, buggy-learn repository.

The lidar odometry node declares three tunable parameters, defaulting to 0.25 m for max_correspondence_distance, 0.005 for transformation_epsilon and 30 for maximum_iterations, and the README says they can be retuned for odometry quality or for lower compute cost. Mapping runs slam_toolbox in mapping mode, after which the operator saves and serialises the map from an RViz panel.

The repository ships five saved maps. The one nav2_params.yaml points at, real_map.pgm, is 97 by 83 pixels at 0.05 m per pixel, so that space is roughly 4.85 m by 4.15 m, an indoor room rather than a car park. Localisation can then use slam_toolbox in localization mode or AMCL from Nav2, whose parameter block in the README sets laser_max_range to 5.6 m, particles between 100 and 500, and 30 beams per update, all commented out in the shipped file.

Photograph of a monitor showing an RViz navigation view with a grey global costmap, cyan inflation circles around obstacles, a dark blue mapped wall, and a magenta planned path running from the robot footprint to a goal on the right Navigation with Nav2 on the built map. The cyan discs are inflated obstacles and the magenta line is the planned path. Photo: ULSTU, buggy-learn repository.

What Still Runs Over the Air

The wired link is not a claim that the robot is wireless-free. The block diagram in the repository shows a Wi-Fi adapter attached to the Jetson AGX Xavier over USB, and repository photographs show an operator laptop driving RViz through a remote desktop session to a host named nvidia-xavier. The split is the useful part: the real-time control loop and the IMU stream stay on the cable between the ESP32 board and the onboard computer, while the operator connection stays wireless.

Top-down photograph of the robot on a wooden floor, showing the Nvidia onboard computer with its finned case in the centre, a red lithium battery beside it, the custom control board with its blue Ethernet module at the left, and the Hokuyo scanning laser on an acrylic plate at the right The same robot from above. The onboard computer, battery and control board share the chassis deck. Photo: ULSTU, buggy-learn repository.

What the Repository Publishes and What It Does Not

The firmware for the ESP32 board is not in this repository. A listing of the 881 tracked files outside node_modules, checked on 2026-08-27, contains no ESP-IDF or Arduino project for the control board, so the register-level detail of how the W5500 is driven cannot be read here. What the repository does publish is the ROS 2 side, the board artwork and the wire protocol, which is enough to rebuild the link against any firmware.

A related repository from the same organisation shows the house pattern. ulstu/cad-self-driving, created on 2022-05-31 and last pushed on 2025-07-24, holds ESP32 control units for full-size vehicles whose sdkconfig files carry CONFIG_ETH_SPI_ETHERNET_W5500=y and whose Ethernet.cpp opens the SPI device at 36 MHz. That is a different vehicle programme, but it is the closest published reference for the low-level side.

Two smaller gaps are worth naming. The README describes the inertial sensor as a MEMS device from ST Microelectronics while the board artwork carries a GY-521 MPU-6050 footprint, so a rebuilder should trust the artwork. The board is published as a rendered image rather than schematic or Gerber sources, and no bill of materials or cost figure appears in the repository.

Related WIZnet Maker Projects

How to Bridge a ROS2 Jazzy Rover to Wired Ethernet with W5500 on ESP32? covers the same division of labour, an ESP32 handling motors and sensors below a ROS 2 host. The difference is the wire protocol, since SzufladaV2 carries its traffic over MQTT while the ULSTU buggy sends raw JSON-RPC datagrams and adds Ackermann steering limits.

How Did RoboMagellan Implement a UDP-Based Robot Motor Controller Using the RP2040 and W5500? is the closest match on the protocol side, a UDP command channel to a motor controller over a W5500. The difference is the microcontroller and the return path, since the ULSTU node reuses the same port to lift IMU samples into a ROS 2 topic.

PipeInspect: Wired Ethernet Control & Wi-Fi Video Streaming shows the same layering in a different machine, wired control with wireless payload traffic. The difference is what rides the wireless side, since PipeInspect streams camera video while the ULSTU buggy uses Wi-Fi only to reach the operator desktop.

❓ FAQ

Q. What does the ULSTU buggy use the W5500 for? The W5500 gives the ESP32 control board its Ethernet port, over which the Jetson AGX Xavier sends drive commands as JSON-RPC datagrams to 192.168.2.11 port 9090 and receives IMU samples on the same port.

Q. Why did ULSTU choose Ethernet for the control link? The README names three reasons: high operational stability, immunity to interference, and no need to occupy the onboard computer's Wi-Fi adapter or to provide an external wireless network. Wi-Fi is still used for the operator desktop.

Q. Is the ESP32 firmware published? No. A listing of the 881 tracked files on 2026-08-27 found no firmware project for the control board, so the SPI driver and pin assignment for the W5500 are not visible here.

Q. What ROS 2 version does the stack need? The instructions were written for ROS 2 Foxy on Ubuntu 20.04 because the Jetson AGX Xavier dates from 2018, and the README states the same steps were tested on Ubuntu 22.04 with ROS 2 Humble.

Q. Can this platform be rebuilt on cheaper hardware? The README names Raspberry Pi and Orange Pi as alternatives to the Jetson AGX Xavier, and says the Hokuyo URG-04LX-UG01 lidar can be replaced by equivalent units.

Documents
  • buggy-learn repository

    The platform repository from Ulyanovsk State Technical University. MIT licence, created 2025-04-05, last push 2025-04-11.

  • Robot build and run instructions

    Hardware description and the sentence stating that data exchange uses Ethernet implemented with a W5500, plus the ROS 2 build, mapping and navigation steps.

  • robot_controller_node.py

    The UDP bridge. Defines 192.168.2.11 port 9090, the JSON-RPC set_control_values message, the 30 degree steering clamp and the three second watchdog.

  • Control board artwork

    Board layout showing the W5500 silkscreen and its ten-pad SPI header next to the ESP32 and MPU-6050 footprints.

  • Control board mounted on the robot

    Photograph of the installed board with a patch cable plugged into the blue W5500 Ethernet module.

  • Nav2 parameter file

    Nav2 settings for the built map. The AMCL block ships commented out, and the README prints the same block with laser_max_range 5.6 m, 100 to 500 particles and 30 beams.

  • ULSTU on GitHub

    Organisation profile of Ulyanovsk State Technical University, listing Ulyanovsk, Russia and fist@ulstu.ru.

  • WIZnet W5500

    Datasheet and documentation for the Ethernet controller used on the control board.

Comments Write