<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://rsewiki.electro.dtu.dk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jca</id>
	<title>Rsewiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://rsewiki.electro.dtu.dk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jca"/>
	<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Special:Contributions/Jca"/>
	<updated>2026-04-09T03:15:33Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Ricbot&amp;diff=8700</id>
		<title>Ricbot</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Ricbot&amp;diff=8700"/>
		<updated>2026-03-24T08:27:24Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Library and examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Ricbot, a wheeled sensor platform == &lt;br /&gt;
&lt;br /&gt;
Ricbot is intended for fast deployment to areas of interest.&lt;br /&gt;
&lt;br /&gt;
Main features:&lt;br /&gt;
* Reused motors and wheels from an old &amp;quot;Elector Wheelie&amp;quot; platform&lt;br /&gt;
* Designed to fit into a normal car for deployment, i.e can be disassembled to no more than 55cm in height.&lt;br /&gt;
* No more than 25-30 kg, requiring 1 or 2 persons to load or unload.&lt;br /&gt;
* Wheel-odometry recording (and timestamped)&lt;br /&gt;
* Camera image recording (and timestamped), the intention is Realsense D435.&lt;br /&gt;
* Maybe GNSS recording too.&lt;br /&gt;
* Manual remote control.&lt;br /&gt;
&lt;br /&gt;
Tentative layout:&lt;br /&gt;
&lt;br /&gt;
[[file: ricbot_on-shape.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
Length is 1m, free height 25cm, width 65cm.&lt;br /&gt;
&lt;br /&gt;
== Installation notes ==&lt;br /&gt;
&lt;br /&gt;
=== Camera position ===&lt;br /&gt;
&lt;br /&gt;
[[file: ric-camera-position.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
Forward-looking camera: Intel RealSense D455, FOV 87 x 58 deg, range 0.6 to 6m.&lt;br /&gt;
&lt;br /&gt;
Down-looking camera: Intel RealSense D435, FOV: 87 x 58 deg, range 0.3 to 3m.&lt;br /&gt;
&lt;br /&gt;
=== Cabling ===&lt;br /&gt;
&lt;br /&gt;
[[file: ric_cabling.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
DRI0042: https://wiki.dfrobot.com/15A_Single_DC_Motor_Driver_SKU__DRI0042&lt;br /&gt;
&lt;br /&gt;
Regbot 6.3: [[Regbot hardware board]]&lt;br /&gt;
&lt;br /&gt;
[[RICBOT Power on-off board]] PCB&lt;br /&gt;
&lt;br /&gt;
==== DRI0042 to Regbot 4-pin PWM ====&lt;br /&gt;
&lt;br /&gt;
 DRI              Regbot PWM    Software&lt;br /&gt;
 7 GND   (black)  1 GND         --&lt;br /&gt;
 4 PWM   (red)    2 in1         PIN_xxxx_DIR&lt;br /&gt;
 5 IN1   (white)  3 in2         PIN_xxxx_PWM&lt;br /&gt;
 6 IN2   (yellow) 4 fault       PIN_xxxx_FAULT&lt;br /&gt;
 3 5V out &lt;br /&gt;
&lt;br /&gt;
 DRI0042 control values&lt;br /&gt;
 IN1 	IN2 	PWM 	OUT1, OUT2 Motor Behavior&lt;br /&gt;
 0 	0 	x 	Stop&lt;br /&gt;
 1 	1 	x 	Vacant (relax)&lt;br /&gt;
 1 	0 	1 	Forward 100%&lt;br /&gt;
 0 	1 	1 	Reverse 100%&lt;br /&gt;
 1 	0 	PWM 	Forward at PWM speed&lt;br /&gt;
 0 	1 	PWM 	Reverse at PWM speed&lt;br /&gt;
&lt;br /&gt;
==== Power control ====&lt;br /&gt;
&lt;br /&gt;
 Pin        IDC10-pin      Software       Function&lt;br /&gt;
 1 (black)  1              --             GND&lt;br /&gt;
 2 (red)    3              LS_1  (pin 27) power off (when low)  -- pt not working (wrong mod on power board)&lt;br /&gt;
 3 (white)  4              LS_0  (A6)     battery voltage  (39k/4.7k)&lt;br /&gt;
 4 (yellow) 6              LS_4  (pin 26) Alive LED&lt;br /&gt;
&lt;br /&gt;
=== Intel RealSense ===&lt;br /&gt;
&lt;br /&gt;
Install &lt;br /&gt;
 sudo apt-get install automake libtool libusb-1.0-0-dev libx11-dev xorg-dev libglu1-mesa-dev&lt;br /&gt;
 sudo apt install libssl-dev&lt;br /&gt;
&lt;br /&gt;
There is a script to download and compile, e.g. on Raspberry Pi here:&lt;br /&gt;
https://github.com/realsenseai/librealsense/blob/master/doc/libuvc_installation.md&lt;br /&gt;
&lt;br /&gt;
To install pyrealsense2 at the same time as librealsense, line 46 of the &#039;libuvc_installation.sh&#039; build script should be changed from this:&lt;br /&gt;
 cmake ../ -DFORCE_LIBUVC=true -DCMAKE_BUILD_TYPE=release&lt;br /&gt;
to this:&lt;br /&gt;
 cmake ../ -DFORCE_LIBUVC=true -DCMAKE_BUILD_TYPE=release -DBUILD_PYTHON_BINDINGS:bool=true&lt;br /&gt;
From MartyG-RealSense on a pose here: https://github.com/realsenseai/librealsense/issues/13373&lt;br /&gt;
&lt;br /&gt;
==== Library and examples ====&lt;br /&gt;
&lt;br /&gt;
This is an alternative to the script above.&lt;br /&gt;
&lt;br /&gt;
 cd ~/git&lt;br /&gt;
 git clone https://github.com/IntelRealSense/librealsense.git&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake ..&lt;br /&gt;
 make -j3&lt;br /&gt;
 sudo make install&lt;br /&gt;
&lt;br /&gt;
Copy udev rules to udev&lt;br /&gt;
&lt;br /&gt;
 cd ~/git/librealsense/config/99-realsense*.rules /etc/udev/rules.d/&lt;br /&gt;
 udevadm control --reload-rules&lt;br /&gt;
&lt;br /&gt;
All example commands start with rs-, e.g.:&lt;br /&gt;
 rs-capture&lt;br /&gt;
 rs-pointcloud&lt;br /&gt;
&lt;br /&gt;
=== Teensy interface ===&lt;br /&gt;
&lt;br /&gt;
The Teensy interface implements a bridge to MQTT, a motor controller (velocity and turn rate), and a remote control.&lt;br /&gt;
&lt;br /&gt;
The configuration is in&lt;br /&gt;
 /home/local/svn/teensy_interface/build/robot.ini&lt;br /&gt;
&lt;br /&gt;
See also [[Robobot teensy interface]].&lt;br /&gt;
&lt;br /&gt;
=== Start at boot ===&lt;br /&gt;
&lt;br /&gt;
See the similar start setup in [[https://rsewiki.electro.dtu.dk/index.php?title=Enable_autostart#Autostart]].&lt;br /&gt;
&lt;br /&gt;
Comment out (or delete) the start of the camera streamer (not compatible with RealSense 3D cam)&lt;br /&gt;
&lt;br /&gt;
=== Install software on Raspberry Pi ===&lt;br /&gt;
&lt;br /&gt;
Perform the same installation as [[Robobot install on Raspberry]], except for the serial port configuration (which should not be needed).&lt;br /&gt;
&lt;br /&gt;
=== Teensy software ===&lt;br /&gt;
&lt;br /&gt;
This is the Regbot software, configured to match the Ricbot.&lt;br /&gt;
&lt;br /&gt;
See more details here [[Regbot firmware]].&lt;br /&gt;
&lt;br /&gt;
=== Intel Librealsense ===&lt;br /&gt;
&lt;br /&gt;
Installing support for Intel librealsense.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install libssl-dev&lt;br /&gt;
 sudo apt-get install freeglut3-dev&lt;br /&gt;
 sudo apt-get install xorg-dev&lt;br /&gt;
 cd git&lt;br /&gt;
 git clone https://github.com/IntelRealSense/librealsense.git&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake ..&lt;br /&gt;
&lt;br /&gt;
I also needed to install libusb-1.0-0-dev&lt;br /&gt;
 sudo apt install libusb-1.0-0-dev&lt;br /&gt;
This path was not included in the CMakeLists.txt, so I added this line at the beginning of the CMakeLists.txt:&lt;br /&gt;
&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 nano CMakeLists.txt&lt;br /&gt;
add&lt;br /&gt;
 include_directories( /usr/include/libusb-1.0/ )&lt;br /&gt;
like here:&lt;br /&gt;
 cmake_minimum_required(VERSION 3.10)&lt;br /&gt;
 &lt;br /&gt;
 set( LRS_TARGET realsense2 )&lt;br /&gt;
 project( ${LRS_TARGET} LANGUAGES CXX C )&lt;br /&gt;
 &lt;br /&gt;
 # Allow librealsense2 and all of the nested project to include the main repo folder&lt;br /&gt;
 set(REPO_ROOT ${CMAKE_CURRENT_SOURCE_DIR})&lt;br /&gt;
 include_directories(${REPO_ROOT})&lt;br /&gt;
 &#039;&#039;&#039;include_directories( /usr/include/libusb-1.0/ )&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 include(CMake/lrs_options.cmake)&lt;br /&gt;
 include(CMake/connectivity_check.cmake)&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== ROS2 ==&lt;br /&gt;
&lt;br /&gt;
From https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html&lt;br /&gt;
&lt;br /&gt;
Install &lt;br /&gt;
 export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F &amp;quot;tag_name&amp;quot; | awk -F\&amp;quot; &#039;{print $4}&#039;)&lt;br /&gt;
&lt;br /&gt;
 curl -L -o /tmp/ros2-apt-source.deb &amp;quot;https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release &amp;amp;&amp;amp; echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 sudo dpkg -i /tmp/ros2-apt-source.deb&lt;br /&gt;
&lt;br /&gt;
 sudo apt update &amp;amp;&amp;amp; sudo apt install ros-dev-tools&lt;br /&gt;
&lt;br /&gt;
Install full ROS2 Jazzy&lt;br /&gt;
&lt;br /&gt;
 sudo apt install ros-jazzy-desktop&lt;br /&gt;
&lt;br /&gt;
Start in this ROS2 environment, now and in new terminals:&lt;br /&gt;
 source /opt/ros/jazzy/setup.bash&lt;br /&gt;
 echo &amp;quot;source /opt/ros/jazzy/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
 export ROS_DOMAIN_ID=0&lt;br /&gt;
 echo &amp;quot;export ROS_DOMAIN_ID=0&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
Install ROS QT GUI stuff&lt;br /&gt;
 sudo apt install &#039;~nros-jazzy-rqt*&#039;&lt;br /&gt;
&lt;br /&gt;
=== Create workspace ===&lt;br /&gt;
&lt;br /&gt;
From https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/Colcon-Tutorial.html &lt;br /&gt;
&lt;br /&gt;
Install colcon&lt;br /&gt;
 sudo apt install python3-colcon-common-extensions&lt;br /&gt;
&lt;br /&gt;
Create workspace directory&lt;br /&gt;
 mkdir -p ~/ros2_ws/src&lt;br /&gt;
 cd ~/ros2_ws&lt;br /&gt;
&lt;br /&gt;
From within this directory clone (any) standard package&lt;br /&gt;
&lt;br /&gt;
e.g. tutorial examples&lt;br /&gt;
 git clone https://github.com/ros2/examples src/examples -b jazzy&lt;br /&gt;
&lt;br /&gt;
Build the examples; this is memory and CPU-hungry, so the option &#039;&#039;--executor sequential&#039;&#039; may come in handy, especially on a Raspberry Pi, but it will take significantly longer.&lt;br /&gt;
 colcon build --symlink-install --executor sequential&lt;br /&gt;
&lt;br /&gt;
Allow use of colcon_cd&lt;br /&gt;
 echo &amp;quot;source /usr/share/colcon_cd/function/colcon_cd.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
 echo &amp;quot;export _colcon_cd_root=/opt/ros/jazzy/&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
To use the &#039;&#039;mixin&#039;&#039; shortcut for some colcon options, add:&lt;br /&gt;
 colcon mixin add default https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml&lt;br /&gt;
 colcon mixin update default&lt;br /&gt;
&lt;br /&gt;
=== MQTT client ===&lt;br /&gt;
&lt;br /&gt;
The un-modified &#039;&#039;mqtt_client&#039;&#039; package can act as a bridge between the &#039;&#039;teensy_interface&#039;&#039; and the ROS domain.&lt;br /&gt;
&lt;br /&gt;
From MQTT to ROS, the translation is using the primitive ROS type &#039;&#039;string&#039;&#039; for the parameters of the &#039;&#039;teensy_interface&#039;&#039; messages. &lt;br /&gt;
The MQTT topic name is translated to ROS topic names as specified in the parameter file below.&lt;br /&gt;
&lt;br /&gt;
From ROS to Teensy, the message should be published on a topic that matches the desired destination.&lt;br /&gt;
Topics for command messages to the &#039;&#039;teensy_interface&#039;&#039;:&lt;br /&gt;
* MQTT topic ricbot/cmd/T0 for the Teensy, the message is the string to send to the Teensy.&lt;br /&gt;
* MQTT topic ricbot/cmd/shutdown to schedule a shutdown of the RICBOT (power off), something like 20 seconds after the message.&lt;br /&gt;
* MQTT topic ricbot/cmd/ti for messages to the teensy_interface, the message is a string.&lt;br /&gt;
&lt;br /&gt;
==== Install ====&lt;br /&gt;
&lt;br /&gt;
The robot&#039;s interface is via MQTT. Install the MQTT ROS client&lt;br /&gt;
 sudo apt install ros-jazzy-mqtt-client&lt;br /&gt;
&lt;br /&gt;
Or directly as source&lt;br /&gt;
 cd src&lt;br /&gt;
 git clone https://github.com/ika-rwth-aachen/mqtt_client&lt;br /&gt;
 &lt;br /&gt;
Compile:&lt;br /&gt;
 cd ~/ros2_ws&lt;br /&gt;
 colcon build&lt;br /&gt;
&lt;br /&gt;
==== Run MQTT_client ====&lt;br /&gt;
&lt;br /&gt;
To start the &#039;&#039;mqtt_client&#039;&#039;:&lt;br /&gt;
 cd ros2_ws/src/mqtt_client/mqtt_client/config&lt;br /&gt;
 ros2 launch mqtt_client standalone.launch.xml params_file:=&amp;quot;params.teensy.yaml&amp;quot;&lt;br /&gt;
The parameter file should be extended with more &#039;&#039;mqtt2ros&#039;&#039; topics as needed.&lt;br /&gt;
&lt;br /&gt;
This will launch the un-modified &#039;&#039;mqtt_client&#039;&#039; node with specific bridge parameters as specified in &#039;&#039;params.teensy.yaml&#039;&#039;:&lt;br /&gt;
 /**/*:&lt;br /&gt;
  ros__parameters:&lt;br /&gt;
    broker:&lt;br /&gt;
      host: localhost&lt;br /&gt;
      port: 1883&lt;br /&gt;
      tls:&lt;br /&gt;
        enabled: false&lt;br /&gt;
    client:&lt;br /&gt;
      id: ros&lt;br /&gt;
      clean_session: true&lt;br /&gt;
      keep_alive_interval: 20.0&lt;br /&gt;
    bridge:&lt;br /&gt;
      ros2mqtt:&lt;br /&gt;
        ros_topics: &lt;br /&gt;
          - /teensy/cmd/T0&lt;br /&gt;
          - /teensy/cmd/shutdown&lt;br /&gt;
          - /teensy/cmd/ti&lt;br /&gt;
        /teensy/cmd/T0:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/T0&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
        /teensy/cmd/shutdown:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/shutdown&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
        /teensy/cmd/ti:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/ti&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
      mqtt2ros:&lt;br /&gt;
        # Needs to be expanded to relevant topics&lt;br /&gt;
        mqtt_topics: &lt;br /&gt;
          - ricbot/data/T0/info&lt;br /&gt;
          - ricbot/data/T0/hbt&lt;br /&gt;
        ricbot/data/T0/info:&lt;br /&gt;
          ros_topic: /teensy/T0/info&lt;br /&gt;
          primitive: true&lt;br /&gt;
        ricbot/data/T0/hbt:&lt;br /&gt;
          ros_topic: /teensy/T0/hbt&lt;br /&gt;
          primitive: true&lt;br /&gt;
&lt;br /&gt;
=== Test interface ===&lt;br /&gt;
&lt;br /&gt;
Start the &#039;&#039;teensy_interface&#039;&#039; with the right ini-file:&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -z ricbot.ini&lt;br /&gt;
&lt;br /&gt;
This should respond with something like:&lt;br /&gt;
 $ ./teensy_interface -z ricbot.ini&lt;br /&gt;
 # UService:: created directory log_20260118_083120.745/&lt;br /&gt;
 # UMqtt:: connection to MQTT broker on tcp://localhost:1883 established&lt;br /&gt;
 # UMqttIn:: connection to MQTT broker on tcp://localhost:1883 established&lt;br /&gt;
 # STeensy:: opening to USB /dev/ttyACM0&lt;br /&gt;
 # SRobot:: (t0) found IP 0: eno1 192.168.2.157&lt;br /&gt;
 # STeensy:: just connected &lt;br /&gt;
 # UService:: setup of Teensy 0 modules finished OK.&lt;br /&gt;
 # Type quit to stop, or &#039;h&#039; for help&lt;br /&gt;
&lt;br /&gt;
Start the &#039;&#039;mqtt_client&#039;&#039; in ROS&lt;br /&gt;
 cd ~/svn/ricbot/ros_config&lt;br /&gt;
 ros2 launch mqtt_client standalone.launch.xml params_file:=&amp;quot;params.teensy.yaml&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== From MQTT to ROS ====&lt;br /&gt;
&lt;br /&gt;
There should now be &#039;&#039;hbt&#039;&#039; (heartbeat) message on the ROS side:&lt;br /&gt;
 ros2 topic echo /teensy/T0/hbt&lt;br /&gt;
&lt;br /&gt;
This should give something like:&lt;br /&gt;
 data: &#039;1768722645.7425 1738.4885 93 1748 4.85 0 9 18.1 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
 data: &#039;1768722646.2426 1738.9885 93 1748 4.85 0 9 18.0 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
 data: &#039;1768722646.7431 1739.4885 93 1748 4.85 0 9 18.0 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
&lt;br /&gt;
The data is: timestamp (host), timestamp Teensy, Teensy ID, version, battery voltage, ... (the rest depend on the platform).&lt;br /&gt;
&lt;br /&gt;
==== From ROS to MQTT ====&lt;br /&gt;
&lt;br /&gt;
e.g. make the robot drive with velocity 0.25m/s and turn 0.1 rad/s CCV, followed by stop:&lt;br /&gt;
&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/ti std_msgs/String &#039;data: rc 0.25 0.1&#039;&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/ti std_msgs/String &#039;data: rc 0 0&#039;&lt;br /&gt;
&lt;br /&gt;
Or send a request to publish gyro data every 12ms:&lt;br /&gt;
&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/T0 std_msgs/String &#039;data: sub gyro 12&#039;&lt;br /&gt;
&lt;br /&gt;
== (RIC_pkg) HW sensor translate package ==&lt;br /&gt;
&lt;br /&gt;
Create the package in the workspace.&lt;br /&gt;
&lt;br /&gt;
 cd ~/ros2_ws/src&lt;br /&gt;
 ros2 pkg create --build-type ament_cmake --license MIT --node-name ric_node ric_pkg&lt;br /&gt;
&lt;br /&gt;
Add dependencies to other packages to CMakeLists.txt.&lt;br /&gt;
Add to the list of &#039;&#039;find_package&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 find_package(rclcpp REQUIRED)&lt;br /&gt;
 find_package(std_msgs REQUIRED)&lt;br /&gt;
 find_package(nav_msgs REQUIRED)&lt;br /&gt;
 find_package(sensor_msgs REQUIRED)&lt;br /&gt;
 find_package(geometry_msgs REQUIRED)&lt;br /&gt;
&lt;br /&gt;
Make target dependencies available in the include path (and elsewhere as needed).&lt;br /&gt;
&lt;br /&gt;
Add this after the &#039;&#039;add_executable&#039;&#039;&lt;br /&gt;
 ament_target_dependencies(talker rclcpp std_msgs nav_msgs sensor_msgs geometry_msgs)&lt;br /&gt;
&lt;br /&gt;
To the package description &#039;&#039;package.xml&#039;&#039; add dependencies:&lt;br /&gt;
&lt;br /&gt;
Add just after the &#039;&#039;buildtool_depend&#039;&#039; section:&lt;br /&gt;
 &amp;lt;depend&amp;gt;rclcpp&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;std_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;nav_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;sensor_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;geometry_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RIC_node code ===&lt;br /&gt;
&lt;br /&gt;
The code in &#039;&#039;ris_node.cpp&#039;&#039; is pt this (not functional yet):&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;cstdio&amp;gt;&lt;br /&gt;
 #include &amp;lt;chrono&amp;gt;&lt;br /&gt;
 #include &amp;lt;memory&amp;gt;&lt;br /&gt;
 #include &amp;lt;string&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;rclcpp/rclcpp.hpp&amp;quot;&lt;br /&gt;
 #include &amp;quot;std_msgs/msg/string.hpp&amp;quot;&lt;br /&gt;
 #include &amp;quot;std_msgs/msg/int32.hpp&amp;quot;&lt;br /&gt;
 #include &amp;lt;nav_msgs/msg/odometry.hpp&amp;gt;&lt;br /&gt;
 #include &amp;quot;geometry_msgs/msg/twist.hpp&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 class RIC_translator : public rclcpp::Node&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
  RIC_translator()&lt;br /&gt;
  : Node(&amp;quot;minimal_publisher&amp;quot;), count(0)&lt;br /&gt;
  {&lt;br /&gt;
    publisher_ = this-&amp;gt;create_publisher&amp;lt;std_msgs::msg::String&amp;gt;(&amp;quot;/ric/hbt&amp;quot;, 10);&lt;br /&gt;
    //&lt;br /&gt;
    // Heartbeat&lt;br /&gt;
    auto topic_callback =&lt;br /&gt;
    [this](std_msgs::msg::String::UniquePtr msg) -&amp;gt; void {&lt;br /&gt;
      // RCLCPP_INFO(this-&amp;gt;get_logger(), &amp;quot;I heard: hbt &#039;%s&#039;&amp;quot;, msg-&amp;gt;data.c_str());&lt;br /&gt;
      // strncpy(hbtParams, msg-&amp;gt;data.c_str(), 100);&lt;br /&gt;
      printHbt(msg-&amp;gt;data.c_str());&lt;br /&gt;
    };&lt;br /&gt;
    subsHbt =&lt;br /&gt;
    this-&amp;gt;create_subscription&amp;lt;std_msgs::msg::String&amp;gt;(&amp;quot;/teensy/T0/hbt&amp;quot;, 10, topic_callback);&lt;br /&gt;
  }&lt;br /&gt;
 private:&lt;br /&gt;
  rclcpp::TimerBase::SharedPtr timer_;&lt;br /&gt;
  rclcpp::Publisher&amp;lt;std_msgs::msg::String&amp;gt;::SharedPtr publisher_;&lt;br /&gt;
  rclcpp::Publisher&amp;lt;std_msgs::msg::Int32&amp;gt;::SharedPtr odo_;&lt;br /&gt;
  size_t count;&lt;br /&gt;
  //&lt;br /&gt;
  char hbtParams[100] = &amp;quot;&amp;quot;;&lt;br /&gt;
  rclcpp::Subscription&amp;lt;std_msgs::msg::String&amp;gt;::SharedPtr subsHbt;&lt;br /&gt;
  void printHbt(const char * msg)&lt;br /&gt;
  {&lt;br /&gt;
    printf(&amp;quot;# %lu got hbt %s&amp;quot;, count, msg);&lt;br /&gt;
    snprintf(hbtParams, 100, &amp;quot;Hello RIC %lu %s&amp;quot;, count++, msg);&lt;br /&gt;
    auto message = std_msgs::msg::String();&lt;br /&gt;
    message.set__data(hbtParams);&lt;br /&gt;
    this-&amp;gt;publisher_-&amp;gt;publish(message);&lt;br /&gt;
  }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char ** argv)&lt;br /&gt;
 {&lt;br /&gt;
  rclcpp::init(argc, argv);&lt;br /&gt;
  rclcpp::spin(std::make_shared&amp;lt;RIC_translator&amp;gt;());&lt;br /&gt;
  rclcpp::shutdown();&lt;br /&gt;
  return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Run RIC_node ===&lt;br /&gt;
&lt;br /&gt;
Compile (from workspace)&lt;br /&gt;
 colcon build --packages-select ric_pkg&lt;br /&gt;
 &lt;br /&gt;
Then add it to the path&lt;br /&gt;
 source install/setup.bash&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
 ros2 run ric_pkg ric_node&lt;br /&gt;
&lt;br /&gt;
If the &#039;&#039;teensy_interface&#039;&#039; and the &#039;&#039;mqtt-client&#039;&#039; are also running, then (with the code above), it should print something like this on the console.&lt;br /&gt;
 # 0 got hbt 1769340959.8623 13504.9463 105 1033 15.65 4 8 8.9 0.27 0&lt;br /&gt;
 # 1 got hbt 1769340960.3625 13505.4463 105 1033 15.65 4 8 8.8 0.28 0&lt;br /&gt;
 # 2 got hbt 1769340960.8626 13505.9453 105 1033 15.65 4 8 8.8 0.27 0&lt;br /&gt;
 # 3 got hbt 1769340961.3622 13506.4463 105 1033 15.65 4 8 8.9 0.28 0&lt;br /&gt;
 # 4 got hbt 1769340961.8625 13506.9463 105 1033 15.65 4 8 8.9 0.25 0&lt;br /&gt;
 # 5 got hbt 1769340962.3631 13507.4453 105 1033 15.66 4 8 8.9 0.26 0&lt;br /&gt;
 # 6 got hbt 1769340962.8624 13507.9463 105 1033 15.63 4 8 8.8 0.26 0&lt;br /&gt;
&lt;br /&gt;
=== Ros2 relevant messages ===&lt;br /&gt;
&lt;br /&gt;
One of the messages are probably &#039;&#039;twist&#039;&#039;:&lt;br /&gt;
 ros2 interface show geometry_msgs/msg/Twist&lt;br /&gt;
 # This expresses velocity in free space broken into its linear and angular parts.&lt;br /&gt;
 Vector3  linear&lt;br /&gt;
        float64 x&lt;br /&gt;
        float64 y&lt;br /&gt;
        float64 z&lt;br /&gt;
 Vector3  angular&lt;br /&gt;
        float64 x&lt;br /&gt;
        float64 y&lt;br /&gt;
        float64 z&lt;br /&gt;
&lt;br /&gt;
=== Where from here ===&lt;br /&gt;
&lt;br /&gt;
Search for tutorials in https://docs.ros.org/en/jazzy/&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Ricbot&amp;diff=8699</id>
		<title>Ricbot</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Ricbot&amp;diff=8699"/>
		<updated>2026-03-24T08:26:43Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Intel RealSense */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Ricbot, a wheeled sensor platform == &lt;br /&gt;
&lt;br /&gt;
Ricbot is intended for fast deployment to areas of interest.&lt;br /&gt;
&lt;br /&gt;
Main features:&lt;br /&gt;
* Reused motors and wheels from an old &amp;quot;Elector Wheelie&amp;quot; platform&lt;br /&gt;
* Designed to fit into a normal car for deployment, i.e can be disassembled to no more than 55cm in height.&lt;br /&gt;
* No more than 25-30 kg, requiring 1 or 2 persons to load or unload.&lt;br /&gt;
* Wheel-odometry recording (and timestamped)&lt;br /&gt;
* Camera image recording (and timestamped), the intention is Realsense D435.&lt;br /&gt;
* Maybe GNSS recording too.&lt;br /&gt;
* Manual remote control.&lt;br /&gt;
&lt;br /&gt;
Tentative layout:&lt;br /&gt;
&lt;br /&gt;
[[file: ricbot_on-shape.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
Length is 1m, free height 25cm, width 65cm.&lt;br /&gt;
&lt;br /&gt;
== Installation notes ==&lt;br /&gt;
&lt;br /&gt;
=== Camera position ===&lt;br /&gt;
&lt;br /&gt;
[[file: ric-camera-position.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
Forward-looking camera: Intel RealSense D455, FOV 87 x 58 deg, range 0.6 to 6m.&lt;br /&gt;
&lt;br /&gt;
Down-looking camera: Intel RealSense D435, FOV: 87 x 58 deg, range 0.3 to 3m.&lt;br /&gt;
&lt;br /&gt;
=== Cabling ===&lt;br /&gt;
&lt;br /&gt;
[[file: ric_cabling.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
DRI0042: https://wiki.dfrobot.com/15A_Single_DC_Motor_Driver_SKU__DRI0042&lt;br /&gt;
&lt;br /&gt;
Regbot 6.3: [[Regbot hardware board]]&lt;br /&gt;
&lt;br /&gt;
[[RICBOT Power on-off board]] PCB&lt;br /&gt;
&lt;br /&gt;
==== DRI0042 to Regbot 4-pin PWM ====&lt;br /&gt;
&lt;br /&gt;
 DRI              Regbot PWM    Software&lt;br /&gt;
 7 GND   (black)  1 GND         --&lt;br /&gt;
 4 PWM   (red)    2 in1         PIN_xxxx_DIR&lt;br /&gt;
 5 IN1   (white)  3 in2         PIN_xxxx_PWM&lt;br /&gt;
 6 IN2   (yellow) 4 fault       PIN_xxxx_FAULT&lt;br /&gt;
 3 5V out &lt;br /&gt;
&lt;br /&gt;
 DRI0042 control values&lt;br /&gt;
 IN1 	IN2 	PWM 	OUT1, OUT2 Motor Behavior&lt;br /&gt;
 0 	0 	x 	Stop&lt;br /&gt;
 1 	1 	x 	Vacant (relax)&lt;br /&gt;
 1 	0 	1 	Forward 100%&lt;br /&gt;
 0 	1 	1 	Reverse 100%&lt;br /&gt;
 1 	0 	PWM 	Forward at PWM speed&lt;br /&gt;
 0 	1 	PWM 	Reverse at PWM speed&lt;br /&gt;
&lt;br /&gt;
==== Power control ====&lt;br /&gt;
&lt;br /&gt;
 Pin        IDC10-pin      Software       Function&lt;br /&gt;
 1 (black)  1              --             GND&lt;br /&gt;
 2 (red)    3              LS_1  (pin 27) power off (when low)  -- pt not working (wrong mod on power board)&lt;br /&gt;
 3 (white)  4              LS_0  (A6)     battery voltage  (39k/4.7k)&lt;br /&gt;
 4 (yellow) 6              LS_4  (pin 26) Alive LED&lt;br /&gt;
&lt;br /&gt;
=== Intel RealSense ===&lt;br /&gt;
&lt;br /&gt;
Install &lt;br /&gt;
 sudo apt-get install automake libtool libusb-1.0-0-dev libx11-dev xorg-dev libglu1-mesa-dev&lt;br /&gt;
 sudo apt install libssl-dev&lt;br /&gt;
&lt;br /&gt;
There is a script to download and compile, e.g. on Raspberry Pi here:&lt;br /&gt;
https://github.com/realsenseai/librealsense/blob/master/doc/libuvc_installation.md&lt;br /&gt;
&lt;br /&gt;
To install pyrealsense2 at the same time as librealsense, line 46 of the &#039;libuvc_installation.sh&#039; build script should be changed from this:&lt;br /&gt;
 cmake ../ -DFORCE_LIBUVC=true -DCMAKE_BUILD_TYPE=release&lt;br /&gt;
to this:&lt;br /&gt;
 cmake ../ -DFORCE_LIBUVC=true -DCMAKE_BUILD_TYPE=release -DBUILD_PYTHON_BINDINGS:bool=true&lt;br /&gt;
From MartyG-RealSense on a pose here: https://github.com/realsenseai/librealsense/issues/13373&lt;br /&gt;
&lt;br /&gt;
==== Library and examples ====&lt;br /&gt;
&lt;br /&gt;
 cd ~/git&lt;br /&gt;
 git clone https://github.com/IntelRealSense/librealsense.git&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake ..&lt;br /&gt;
 make -j3&lt;br /&gt;
 sudo make install&lt;br /&gt;
&lt;br /&gt;
Copy udev rules to udev&lt;br /&gt;
&lt;br /&gt;
 cd ~/git/librealsense/config/99-realsense*.rules /etc/udev/rules.d/&lt;br /&gt;
 udevadm control --reload-rules&lt;br /&gt;
&lt;br /&gt;
All example commands start with rs-, e.g.:&lt;br /&gt;
 rs-capture&lt;br /&gt;
 rs-pointcloud&lt;br /&gt;
&lt;br /&gt;
=== Teensy interface ===&lt;br /&gt;
&lt;br /&gt;
The Teensy interface implements a bridge to MQTT, a motor controller (velocity and turn rate), and a remote control.&lt;br /&gt;
&lt;br /&gt;
The configuration is in&lt;br /&gt;
 /home/local/svn/teensy_interface/build/robot.ini&lt;br /&gt;
&lt;br /&gt;
See also [[Robobot teensy interface]].&lt;br /&gt;
&lt;br /&gt;
=== Start at boot ===&lt;br /&gt;
&lt;br /&gt;
See the similar start setup in [[https://rsewiki.electro.dtu.dk/index.php?title=Enable_autostart#Autostart]].&lt;br /&gt;
&lt;br /&gt;
Comment out (or delete) the start of the camera streamer (not compatible with RealSense 3D cam)&lt;br /&gt;
&lt;br /&gt;
=== Install software on Raspberry Pi ===&lt;br /&gt;
&lt;br /&gt;
Perform the same installation as [[Robobot install on Raspberry]], except for the serial port configuration (which should not be needed).&lt;br /&gt;
&lt;br /&gt;
=== Teensy software ===&lt;br /&gt;
&lt;br /&gt;
This is the Regbot software, configured to match the Ricbot.&lt;br /&gt;
&lt;br /&gt;
See more details here [[Regbot firmware]].&lt;br /&gt;
&lt;br /&gt;
=== Intel Librealsense ===&lt;br /&gt;
&lt;br /&gt;
Installing support for Intel librealsense.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install libssl-dev&lt;br /&gt;
 sudo apt-get install freeglut3-dev&lt;br /&gt;
 sudo apt-get install xorg-dev&lt;br /&gt;
 cd git&lt;br /&gt;
 git clone https://github.com/IntelRealSense/librealsense.git&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake ..&lt;br /&gt;
&lt;br /&gt;
I also needed to install libusb-1.0-0-dev&lt;br /&gt;
 sudo apt install libusb-1.0-0-dev&lt;br /&gt;
This path was not included in the CMakeLists.txt, so I added this line at the beginning of the CMakeLists.txt:&lt;br /&gt;
&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 nano CMakeLists.txt&lt;br /&gt;
add&lt;br /&gt;
 include_directories( /usr/include/libusb-1.0/ )&lt;br /&gt;
like here:&lt;br /&gt;
 cmake_minimum_required(VERSION 3.10)&lt;br /&gt;
 &lt;br /&gt;
 set( LRS_TARGET realsense2 )&lt;br /&gt;
 project( ${LRS_TARGET} LANGUAGES CXX C )&lt;br /&gt;
 &lt;br /&gt;
 # Allow librealsense2 and all of the nested project to include the main repo folder&lt;br /&gt;
 set(REPO_ROOT ${CMAKE_CURRENT_SOURCE_DIR})&lt;br /&gt;
 include_directories(${REPO_ROOT})&lt;br /&gt;
 &#039;&#039;&#039;include_directories( /usr/include/libusb-1.0/ )&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 include(CMake/lrs_options.cmake)&lt;br /&gt;
 include(CMake/connectivity_check.cmake)&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== ROS2 ==&lt;br /&gt;
&lt;br /&gt;
From https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html&lt;br /&gt;
&lt;br /&gt;
Install &lt;br /&gt;
 export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F &amp;quot;tag_name&amp;quot; | awk -F\&amp;quot; &#039;{print $4}&#039;)&lt;br /&gt;
&lt;br /&gt;
 curl -L -o /tmp/ros2-apt-source.deb &amp;quot;https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release &amp;amp;&amp;amp; echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 sudo dpkg -i /tmp/ros2-apt-source.deb&lt;br /&gt;
&lt;br /&gt;
 sudo apt update &amp;amp;&amp;amp; sudo apt install ros-dev-tools&lt;br /&gt;
&lt;br /&gt;
Install full ROS2 Jazzy&lt;br /&gt;
&lt;br /&gt;
 sudo apt install ros-jazzy-desktop&lt;br /&gt;
&lt;br /&gt;
Start in this ROS2 environment, now and in new terminals:&lt;br /&gt;
 source /opt/ros/jazzy/setup.bash&lt;br /&gt;
 echo &amp;quot;source /opt/ros/jazzy/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
 export ROS_DOMAIN_ID=0&lt;br /&gt;
 echo &amp;quot;export ROS_DOMAIN_ID=0&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
Install ROS QT GUI stuff&lt;br /&gt;
 sudo apt install &#039;~nros-jazzy-rqt*&#039;&lt;br /&gt;
&lt;br /&gt;
=== Create workspace ===&lt;br /&gt;
&lt;br /&gt;
From https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/Colcon-Tutorial.html &lt;br /&gt;
&lt;br /&gt;
Install colcon&lt;br /&gt;
 sudo apt install python3-colcon-common-extensions&lt;br /&gt;
&lt;br /&gt;
Create workspace directory&lt;br /&gt;
 mkdir -p ~/ros2_ws/src&lt;br /&gt;
 cd ~/ros2_ws&lt;br /&gt;
&lt;br /&gt;
From within this directory clone (any) standard package&lt;br /&gt;
&lt;br /&gt;
e.g. tutorial examples&lt;br /&gt;
 git clone https://github.com/ros2/examples src/examples -b jazzy&lt;br /&gt;
&lt;br /&gt;
Build the examples; this is memory and CPU-hungry, so the option &#039;&#039;--executor sequential&#039;&#039; may come in handy, especially on a Raspberry Pi, but it will take significantly longer.&lt;br /&gt;
 colcon build --symlink-install --executor sequential&lt;br /&gt;
&lt;br /&gt;
Allow use of colcon_cd&lt;br /&gt;
 echo &amp;quot;source /usr/share/colcon_cd/function/colcon_cd.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
 echo &amp;quot;export _colcon_cd_root=/opt/ros/jazzy/&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
To use the &#039;&#039;mixin&#039;&#039; shortcut for some colcon options, add:&lt;br /&gt;
 colcon mixin add default https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml&lt;br /&gt;
 colcon mixin update default&lt;br /&gt;
&lt;br /&gt;
=== MQTT client ===&lt;br /&gt;
&lt;br /&gt;
The un-modified &#039;&#039;mqtt_client&#039;&#039; package can act as a bridge between the &#039;&#039;teensy_interface&#039;&#039; and the ROS domain.&lt;br /&gt;
&lt;br /&gt;
From MQTT to ROS, the translation is using the primitive ROS type &#039;&#039;string&#039;&#039; for the parameters of the &#039;&#039;teensy_interface&#039;&#039; messages. &lt;br /&gt;
The MQTT topic name is translated to ROS topic names as specified in the parameter file below.&lt;br /&gt;
&lt;br /&gt;
From ROS to Teensy, the message should be published on a topic that matches the desired destination.&lt;br /&gt;
Topics for command messages to the &#039;&#039;teensy_interface&#039;&#039;:&lt;br /&gt;
* MQTT topic ricbot/cmd/T0 for the Teensy, the message is the string to send to the Teensy.&lt;br /&gt;
* MQTT topic ricbot/cmd/shutdown to schedule a shutdown of the RICBOT (power off), something like 20 seconds after the message.&lt;br /&gt;
* MQTT topic ricbot/cmd/ti for messages to the teensy_interface, the message is a string.&lt;br /&gt;
&lt;br /&gt;
==== Install ====&lt;br /&gt;
&lt;br /&gt;
The robot&#039;s interface is via MQTT. Install the MQTT ROS client&lt;br /&gt;
 sudo apt install ros-jazzy-mqtt-client&lt;br /&gt;
&lt;br /&gt;
Or directly as source&lt;br /&gt;
 cd src&lt;br /&gt;
 git clone https://github.com/ika-rwth-aachen/mqtt_client&lt;br /&gt;
 &lt;br /&gt;
Compile:&lt;br /&gt;
 cd ~/ros2_ws&lt;br /&gt;
 colcon build&lt;br /&gt;
&lt;br /&gt;
==== Run MQTT_client ====&lt;br /&gt;
&lt;br /&gt;
To start the &#039;&#039;mqtt_client&#039;&#039;:&lt;br /&gt;
 cd ros2_ws/src/mqtt_client/mqtt_client/config&lt;br /&gt;
 ros2 launch mqtt_client standalone.launch.xml params_file:=&amp;quot;params.teensy.yaml&amp;quot;&lt;br /&gt;
The parameter file should be extended with more &#039;&#039;mqtt2ros&#039;&#039; topics as needed.&lt;br /&gt;
&lt;br /&gt;
This will launch the un-modified &#039;&#039;mqtt_client&#039;&#039; node with specific bridge parameters as specified in &#039;&#039;params.teensy.yaml&#039;&#039;:&lt;br /&gt;
 /**/*:&lt;br /&gt;
  ros__parameters:&lt;br /&gt;
    broker:&lt;br /&gt;
      host: localhost&lt;br /&gt;
      port: 1883&lt;br /&gt;
      tls:&lt;br /&gt;
        enabled: false&lt;br /&gt;
    client:&lt;br /&gt;
      id: ros&lt;br /&gt;
      clean_session: true&lt;br /&gt;
      keep_alive_interval: 20.0&lt;br /&gt;
    bridge:&lt;br /&gt;
      ros2mqtt:&lt;br /&gt;
        ros_topics: &lt;br /&gt;
          - /teensy/cmd/T0&lt;br /&gt;
          - /teensy/cmd/shutdown&lt;br /&gt;
          - /teensy/cmd/ti&lt;br /&gt;
        /teensy/cmd/T0:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/T0&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
        /teensy/cmd/shutdown:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/shutdown&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
        /teensy/cmd/ti:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/ti&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
      mqtt2ros:&lt;br /&gt;
        # Needs to be expanded to relevant topics&lt;br /&gt;
        mqtt_topics: &lt;br /&gt;
          - ricbot/data/T0/info&lt;br /&gt;
          - ricbot/data/T0/hbt&lt;br /&gt;
        ricbot/data/T0/info:&lt;br /&gt;
          ros_topic: /teensy/T0/info&lt;br /&gt;
          primitive: true&lt;br /&gt;
        ricbot/data/T0/hbt:&lt;br /&gt;
          ros_topic: /teensy/T0/hbt&lt;br /&gt;
          primitive: true&lt;br /&gt;
&lt;br /&gt;
=== Test interface ===&lt;br /&gt;
&lt;br /&gt;
Start the &#039;&#039;teensy_interface&#039;&#039; with the right ini-file:&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -z ricbot.ini&lt;br /&gt;
&lt;br /&gt;
This should respond with something like:&lt;br /&gt;
 $ ./teensy_interface -z ricbot.ini&lt;br /&gt;
 # UService:: created directory log_20260118_083120.745/&lt;br /&gt;
 # UMqtt:: connection to MQTT broker on tcp://localhost:1883 established&lt;br /&gt;
 # UMqttIn:: connection to MQTT broker on tcp://localhost:1883 established&lt;br /&gt;
 # STeensy:: opening to USB /dev/ttyACM0&lt;br /&gt;
 # SRobot:: (t0) found IP 0: eno1 192.168.2.157&lt;br /&gt;
 # STeensy:: just connected &lt;br /&gt;
 # UService:: setup of Teensy 0 modules finished OK.&lt;br /&gt;
 # Type quit to stop, or &#039;h&#039; for help&lt;br /&gt;
&lt;br /&gt;
Start the &#039;&#039;mqtt_client&#039;&#039; in ROS&lt;br /&gt;
 cd ~/svn/ricbot/ros_config&lt;br /&gt;
 ros2 launch mqtt_client standalone.launch.xml params_file:=&amp;quot;params.teensy.yaml&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== From MQTT to ROS ====&lt;br /&gt;
&lt;br /&gt;
There should now be &#039;&#039;hbt&#039;&#039; (heartbeat) message on the ROS side:&lt;br /&gt;
 ros2 topic echo /teensy/T0/hbt&lt;br /&gt;
&lt;br /&gt;
This should give something like:&lt;br /&gt;
 data: &#039;1768722645.7425 1738.4885 93 1748 4.85 0 9 18.1 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
 data: &#039;1768722646.2426 1738.9885 93 1748 4.85 0 9 18.0 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
 data: &#039;1768722646.7431 1739.4885 93 1748 4.85 0 9 18.0 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
&lt;br /&gt;
The data is: timestamp (host), timestamp Teensy, Teensy ID, version, battery voltage, ... (the rest depend on the platform).&lt;br /&gt;
&lt;br /&gt;
==== From ROS to MQTT ====&lt;br /&gt;
&lt;br /&gt;
e.g. make the robot drive with velocity 0.25m/s and turn 0.1 rad/s CCV, followed by stop:&lt;br /&gt;
&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/ti std_msgs/String &#039;data: rc 0.25 0.1&#039;&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/ti std_msgs/String &#039;data: rc 0 0&#039;&lt;br /&gt;
&lt;br /&gt;
Or send a request to publish gyro data every 12ms:&lt;br /&gt;
&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/T0 std_msgs/String &#039;data: sub gyro 12&#039;&lt;br /&gt;
&lt;br /&gt;
== (RIC_pkg) HW sensor translate package ==&lt;br /&gt;
&lt;br /&gt;
Create the package in the workspace.&lt;br /&gt;
&lt;br /&gt;
 cd ~/ros2_ws/src&lt;br /&gt;
 ros2 pkg create --build-type ament_cmake --license MIT --node-name ric_node ric_pkg&lt;br /&gt;
&lt;br /&gt;
Add dependencies to other packages to CMakeLists.txt.&lt;br /&gt;
Add to the list of &#039;&#039;find_package&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 find_package(rclcpp REQUIRED)&lt;br /&gt;
 find_package(std_msgs REQUIRED)&lt;br /&gt;
 find_package(nav_msgs REQUIRED)&lt;br /&gt;
 find_package(sensor_msgs REQUIRED)&lt;br /&gt;
 find_package(geometry_msgs REQUIRED)&lt;br /&gt;
&lt;br /&gt;
Make target dependencies available in the include path (and elsewhere as needed).&lt;br /&gt;
&lt;br /&gt;
Add this after the &#039;&#039;add_executable&#039;&#039;&lt;br /&gt;
 ament_target_dependencies(talker rclcpp std_msgs nav_msgs sensor_msgs geometry_msgs)&lt;br /&gt;
&lt;br /&gt;
To the package description &#039;&#039;package.xml&#039;&#039; add dependencies:&lt;br /&gt;
&lt;br /&gt;
Add just after the &#039;&#039;buildtool_depend&#039;&#039; section:&lt;br /&gt;
 &amp;lt;depend&amp;gt;rclcpp&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;std_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;nav_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;sensor_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;geometry_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RIC_node code ===&lt;br /&gt;
&lt;br /&gt;
The code in &#039;&#039;ris_node.cpp&#039;&#039; is pt this (not functional yet):&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;cstdio&amp;gt;&lt;br /&gt;
 #include &amp;lt;chrono&amp;gt;&lt;br /&gt;
 #include &amp;lt;memory&amp;gt;&lt;br /&gt;
 #include &amp;lt;string&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;rclcpp/rclcpp.hpp&amp;quot;&lt;br /&gt;
 #include &amp;quot;std_msgs/msg/string.hpp&amp;quot;&lt;br /&gt;
 #include &amp;quot;std_msgs/msg/int32.hpp&amp;quot;&lt;br /&gt;
 #include &amp;lt;nav_msgs/msg/odometry.hpp&amp;gt;&lt;br /&gt;
 #include &amp;quot;geometry_msgs/msg/twist.hpp&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 class RIC_translator : public rclcpp::Node&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
  RIC_translator()&lt;br /&gt;
  : Node(&amp;quot;minimal_publisher&amp;quot;), count(0)&lt;br /&gt;
  {&lt;br /&gt;
    publisher_ = this-&amp;gt;create_publisher&amp;lt;std_msgs::msg::String&amp;gt;(&amp;quot;/ric/hbt&amp;quot;, 10);&lt;br /&gt;
    //&lt;br /&gt;
    // Heartbeat&lt;br /&gt;
    auto topic_callback =&lt;br /&gt;
    [this](std_msgs::msg::String::UniquePtr msg) -&amp;gt; void {&lt;br /&gt;
      // RCLCPP_INFO(this-&amp;gt;get_logger(), &amp;quot;I heard: hbt &#039;%s&#039;&amp;quot;, msg-&amp;gt;data.c_str());&lt;br /&gt;
      // strncpy(hbtParams, msg-&amp;gt;data.c_str(), 100);&lt;br /&gt;
      printHbt(msg-&amp;gt;data.c_str());&lt;br /&gt;
    };&lt;br /&gt;
    subsHbt =&lt;br /&gt;
    this-&amp;gt;create_subscription&amp;lt;std_msgs::msg::String&amp;gt;(&amp;quot;/teensy/T0/hbt&amp;quot;, 10, topic_callback);&lt;br /&gt;
  }&lt;br /&gt;
 private:&lt;br /&gt;
  rclcpp::TimerBase::SharedPtr timer_;&lt;br /&gt;
  rclcpp::Publisher&amp;lt;std_msgs::msg::String&amp;gt;::SharedPtr publisher_;&lt;br /&gt;
  rclcpp::Publisher&amp;lt;std_msgs::msg::Int32&amp;gt;::SharedPtr odo_;&lt;br /&gt;
  size_t count;&lt;br /&gt;
  //&lt;br /&gt;
  char hbtParams[100] = &amp;quot;&amp;quot;;&lt;br /&gt;
  rclcpp::Subscription&amp;lt;std_msgs::msg::String&amp;gt;::SharedPtr subsHbt;&lt;br /&gt;
  void printHbt(const char * msg)&lt;br /&gt;
  {&lt;br /&gt;
    printf(&amp;quot;# %lu got hbt %s&amp;quot;, count, msg);&lt;br /&gt;
    snprintf(hbtParams, 100, &amp;quot;Hello RIC %lu %s&amp;quot;, count++, msg);&lt;br /&gt;
    auto message = std_msgs::msg::String();&lt;br /&gt;
    message.set__data(hbtParams);&lt;br /&gt;
    this-&amp;gt;publisher_-&amp;gt;publish(message);&lt;br /&gt;
  }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char ** argv)&lt;br /&gt;
 {&lt;br /&gt;
  rclcpp::init(argc, argv);&lt;br /&gt;
  rclcpp::spin(std::make_shared&amp;lt;RIC_translator&amp;gt;());&lt;br /&gt;
  rclcpp::shutdown();&lt;br /&gt;
  return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Run RIC_node ===&lt;br /&gt;
&lt;br /&gt;
Compile (from workspace)&lt;br /&gt;
 colcon build --packages-select ric_pkg&lt;br /&gt;
 &lt;br /&gt;
Then add it to the path&lt;br /&gt;
 source install/setup.bash&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
 ros2 run ric_pkg ric_node&lt;br /&gt;
&lt;br /&gt;
If the &#039;&#039;teensy_interface&#039;&#039; and the &#039;&#039;mqtt-client&#039;&#039; are also running, then (with the code above), it should print something like this on the console.&lt;br /&gt;
 # 0 got hbt 1769340959.8623 13504.9463 105 1033 15.65 4 8 8.9 0.27 0&lt;br /&gt;
 # 1 got hbt 1769340960.3625 13505.4463 105 1033 15.65 4 8 8.8 0.28 0&lt;br /&gt;
 # 2 got hbt 1769340960.8626 13505.9453 105 1033 15.65 4 8 8.8 0.27 0&lt;br /&gt;
 # 3 got hbt 1769340961.3622 13506.4463 105 1033 15.65 4 8 8.9 0.28 0&lt;br /&gt;
 # 4 got hbt 1769340961.8625 13506.9463 105 1033 15.65 4 8 8.9 0.25 0&lt;br /&gt;
 # 5 got hbt 1769340962.3631 13507.4453 105 1033 15.66 4 8 8.9 0.26 0&lt;br /&gt;
 # 6 got hbt 1769340962.8624 13507.9463 105 1033 15.63 4 8 8.8 0.26 0&lt;br /&gt;
&lt;br /&gt;
=== Ros2 relevant messages ===&lt;br /&gt;
&lt;br /&gt;
One of the messages are probably &#039;&#039;twist&#039;&#039;:&lt;br /&gt;
 ros2 interface show geometry_msgs/msg/Twist&lt;br /&gt;
 # This expresses velocity in free space broken into its linear and angular parts.&lt;br /&gt;
 Vector3  linear&lt;br /&gt;
        float64 x&lt;br /&gt;
        float64 y&lt;br /&gt;
        float64 z&lt;br /&gt;
 Vector3  angular&lt;br /&gt;
        float64 x&lt;br /&gt;
        float64 y&lt;br /&gt;
        float64 z&lt;br /&gt;
&lt;br /&gt;
=== Where from here ===&lt;br /&gt;
&lt;br /&gt;
Search for tutorials in https://docs.ros.org/en/jazzy/&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Ricbot&amp;diff=8698</id>
		<title>Ricbot</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Ricbot&amp;diff=8698"/>
		<updated>2026-03-24T08:21:07Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Intel RealSense */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Ricbot, a wheeled sensor platform == &lt;br /&gt;
&lt;br /&gt;
Ricbot is intended for fast deployment to areas of interest.&lt;br /&gt;
&lt;br /&gt;
Main features:&lt;br /&gt;
* Reused motors and wheels from an old &amp;quot;Elector Wheelie&amp;quot; platform&lt;br /&gt;
* Designed to fit into a normal car for deployment, i.e can be disassembled to no more than 55cm in height.&lt;br /&gt;
* No more than 25-30 kg, requiring 1 or 2 persons to load or unload.&lt;br /&gt;
* Wheel-odometry recording (and timestamped)&lt;br /&gt;
* Camera image recording (and timestamped), the intention is Realsense D435.&lt;br /&gt;
* Maybe GNSS recording too.&lt;br /&gt;
* Manual remote control.&lt;br /&gt;
&lt;br /&gt;
Tentative layout:&lt;br /&gt;
&lt;br /&gt;
[[file: ricbot_on-shape.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
Length is 1m, free height 25cm, width 65cm.&lt;br /&gt;
&lt;br /&gt;
== Installation notes ==&lt;br /&gt;
&lt;br /&gt;
=== Camera position ===&lt;br /&gt;
&lt;br /&gt;
[[file: ric-camera-position.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
Forward-looking camera: Intel RealSense D455, FOV 87 x 58 deg, range 0.6 to 6m.&lt;br /&gt;
&lt;br /&gt;
Down-looking camera: Intel RealSense D435, FOV: 87 x 58 deg, range 0.3 to 3m.&lt;br /&gt;
&lt;br /&gt;
=== Cabling ===&lt;br /&gt;
&lt;br /&gt;
[[file: ric_cabling.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
DRI0042: https://wiki.dfrobot.com/15A_Single_DC_Motor_Driver_SKU__DRI0042&lt;br /&gt;
&lt;br /&gt;
Regbot 6.3: [[Regbot hardware board]]&lt;br /&gt;
&lt;br /&gt;
[[RICBOT Power on-off board]] PCB&lt;br /&gt;
&lt;br /&gt;
==== DRI0042 to Regbot 4-pin PWM ====&lt;br /&gt;
&lt;br /&gt;
 DRI              Regbot PWM    Software&lt;br /&gt;
 7 GND   (black)  1 GND         --&lt;br /&gt;
 4 PWM   (red)    2 in1         PIN_xxxx_DIR&lt;br /&gt;
 5 IN1   (white)  3 in2         PIN_xxxx_PWM&lt;br /&gt;
 6 IN2   (yellow) 4 fault       PIN_xxxx_FAULT&lt;br /&gt;
 3 5V out &lt;br /&gt;
&lt;br /&gt;
 DRI0042 control values&lt;br /&gt;
 IN1 	IN2 	PWM 	OUT1, OUT2 Motor Behavior&lt;br /&gt;
 0 	0 	x 	Stop&lt;br /&gt;
 1 	1 	x 	Vacant (relax)&lt;br /&gt;
 1 	0 	1 	Forward 100%&lt;br /&gt;
 0 	1 	1 	Reverse 100%&lt;br /&gt;
 1 	0 	PWM 	Forward at PWM speed&lt;br /&gt;
 0 	1 	PWM 	Reverse at PWM speed&lt;br /&gt;
&lt;br /&gt;
==== Power control ====&lt;br /&gt;
&lt;br /&gt;
 Pin        IDC10-pin      Software       Function&lt;br /&gt;
 1 (black)  1              --             GND&lt;br /&gt;
 2 (red)    3              LS_1  (pin 27) power off (when low)  -- pt not working (wrong mod on power board)&lt;br /&gt;
 3 (white)  4              LS_0  (A6)     battery voltage  (39k/4.7k)&lt;br /&gt;
 4 (yellow) 6              LS_4  (pin 26) Alive LED&lt;br /&gt;
&lt;br /&gt;
=== Intel RealSense ===&lt;br /&gt;
&lt;br /&gt;
Install &lt;br /&gt;
 sudo apt-get install automake libtool libusb-1.0-0-dev libx11-dev xorg-dev libglu1-mesa-dev&lt;br /&gt;
 sudo apt install libssl-dev&lt;br /&gt;
&lt;br /&gt;
There is a script to download and compile, e.g. on Raspberry Pi here:&lt;br /&gt;
https://github.com/realsenseai/librealsense/blob/master/doc/libuvc_installation.md&lt;br /&gt;
&lt;br /&gt;
==== Library and examples ====&lt;br /&gt;
&lt;br /&gt;
 cd ~/git&lt;br /&gt;
 git clone https://github.com/IntelRealSense/librealsense.git&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake ..&lt;br /&gt;
 make -j3&lt;br /&gt;
 sudo make install&lt;br /&gt;
&lt;br /&gt;
Copy udev rules to udev&lt;br /&gt;
&lt;br /&gt;
 cd ~/git/librealsense/config/99-realsense*.rules /etc/udev/rules.d/&lt;br /&gt;
 udevadm control --reload-rules&lt;br /&gt;
&lt;br /&gt;
All example commands start with rs-, e.g.:&lt;br /&gt;
 rs-capture&lt;br /&gt;
 rs-pointcloud&lt;br /&gt;
&lt;br /&gt;
=== Teensy interface ===&lt;br /&gt;
&lt;br /&gt;
The Teensy interface implements a bridge to MQTT, a motor controller (velocity and turn rate), and a remote control.&lt;br /&gt;
&lt;br /&gt;
The configuration is in&lt;br /&gt;
 /home/local/svn/teensy_interface/build/robot.ini&lt;br /&gt;
&lt;br /&gt;
See also [[Robobot teensy interface]].&lt;br /&gt;
&lt;br /&gt;
=== Start at boot ===&lt;br /&gt;
&lt;br /&gt;
See the similar start setup in [[https://rsewiki.electro.dtu.dk/index.php?title=Enable_autostart#Autostart]].&lt;br /&gt;
&lt;br /&gt;
Comment out (or delete) the start of the camera streamer (not compatible with RealSense 3D cam)&lt;br /&gt;
&lt;br /&gt;
=== Install software on Raspberry Pi ===&lt;br /&gt;
&lt;br /&gt;
Perform the same installation as [[Robobot install on Raspberry]], except for the serial port configuration (which should not be needed).&lt;br /&gt;
&lt;br /&gt;
=== Teensy software ===&lt;br /&gt;
&lt;br /&gt;
This is the Regbot software, configured to match the Ricbot.&lt;br /&gt;
&lt;br /&gt;
See more details here [[Regbot firmware]].&lt;br /&gt;
&lt;br /&gt;
=== Intel Librealsense ===&lt;br /&gt;
&lt;br /&gt;
Installing support for Intel librealsense.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install libssl-dev&lt;br /&gt;
 sudo apt-get install freeglut3-dev&lt;br /&gt;
 sudo apt-get install xorg-dev&lt;br /&gt;
 cd git&lt;br /&gt;
 git clone https://github.com/IntelRealSense/librealsense.git&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake ..&lt;br /&gt;
&lt;br /&gt;
I also needed to install libusb-1.0-0-dev&lt;br /&gt;
 sudo apt install libusb-1.0-0-dev&lt;br /&gt;
This path was not included in the CMakeLists.txt, so I added this line at the beginning of the CMakeLists.txt:&lt;br /&gt;
&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 nano CMakeLists.txt&lt;br /&gt;
add&lt;br /&gt;
 include_directories( /usr/include/libusb-1.0/ )&lt;br /&gt;
like here:&lt;br /&gt;
 cmake_minimum_required(VERSION 3.10)&lt;br /&gt;
 &lt;br /&gt;
 set( LRS_TARGET realsense2 )&lt;br /&gt;
 project( ${LRS_TARGET} LANGUAGES CXX C )&lt;br /&gt;
 &lt;br /&gt;
 # Allow librealsense2 and all of the nested project to include the main repo folder&lt;br /&gt;
 set(REPO_ROOT ${CMAKE_CURRENT_SOURCE_DIR})&lt;br /&gt;
 include_directories(${REPO_ROOT})&lt;br /&gt;
 &#039;&#039;&#039;include_directories( /usr/include/libusb-1.0/ )&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 include(CMake/lrs_options.cmake)&lt;br /&gt;
 include(CMake/connectivity_check.cmake)&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== ROS2 ==&lt;br /&gt;
&lt;br /&gt;
From https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html&lt;br /&gt;
&lt;br /&gt;
Install &lt;br /&gt;
 export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F &amp;quot;tag_name&amp;quot; | awk -F\&amp;quot; &#039;{print $4}&#039;)&lt;br /&gt;
&lt;br /&gt;
 curl -L -o /tmp/ros2-apt-source.deb &amp;quot;https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release &amp;amp;&amp;amp; echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 sudo dpkg -i /tmp/ros2-apt-source.deb&lt;br /&gt;
&lt;br /&gt;
 sudo apt update &amp;amp;&amp;amp; sudo apt install ros-dev-tools&lt;br /&gt;
&lt;br /&gt;
Install full ROS2 Jazzy&lt;br /&gt;
&lt;br /&gt;
 sudo apt install ros-jazzy-desktop&lt;br /&gt;
&lt;br /&gt;
Start in this ROS2 environment, now and in new terminals:&lt;br /&gt;
 source /opt/ros/jazzy/setup.bash&lt;br /&gt;
 echo &amp;quot;source /opt/ros/jazzy/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
 export ROS_DOMAIN_ID=0&lt;br /&gt;
 echo &amp;quot;export ROS_DOMAIN_ID=0&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
Install ROS QT GUI stuff&lt;br /&gt;
 sudo apt install &#039;~nros-jazzy-rqt*&#039;&lt;br /&gt;
&lt;br /&gt;
=== Create workspace ===&lt;br /&gt;
&lt;br /&gt;
From https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/Colcon-Tutorial.html &lt;br /&gt;
&lt;br /&gt;
Install colcon&lt;br /&gt;
 sudo apt install python3-colcon-common-extensions&lt;br /&gt;
&lt;br /&gt;
Create workspace directory&lt;br /&gt;
 mkdir -p ~/ros2_ws/src&lt;br /&gt;
 cd ~/ros2_ws&lt;br /&gt;
&lt;br /&gt;
From within this directory clone (any) standard package&lt;br /&gt;
&lt;br /&gt;
e.g. tutorial examples&lt;br /&gt;
 git clone https://github.com/ros2/examples src/examples -b jazzy&lt;br /&gt;
&lt;br /&gt;
Build the examples; this is memory and CPU-hungry, so the option &#039;&#039;--executor sequential&#039;&#039; may come in handy, especially on a Raspberry Pi, but it will take significantly longer.&lt;br /&gt;
 colcon build --symlink-install --executor sequential&lt;br /&gt;
&lt;br /&gt;
Allow use of colcon_cd&lt;br /&gt;
 echo &amp;quot;source /usr/share/colcon_cd/function/colcon_cd.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
 echo &amp;quot;export _colcon_cd_root=/opt/ros/jazzy/&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
To use the &#039;&#039;mixin&#039;&#039; shortcut for some colcon options, add:&lt;br /&gt;
 colcon mixin add default https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml&lt;br /&gt;
 colcon mixin update default&lt;br /&gt;
&lt;br /&gt;
=== MQTT client ===&lt;br /&gt;
&lt;br /&gt;
The un-modified &#039;&#039;mqtt_client&#039;&#039; package can act as a bridge between the &#039;&#039;teensy_interface&#039;&#039; and the ROS domain.&lt;br /&gt;
&lt;br /&gt;
From MQTT to ROS, the translation is using the primitive ROS type &#039;&#039;string&#039;&#039; for the parameters of the &#039;&#039;teensy_interface&#039;&#039; messages. &lt;br /&gt;
The MQTT topic name is translated to ROS topic names as specified in the parameter file below.&lt;br /&gt;
&lt;br /&gt;
From ROS to Teensy, the message should be published on a topic that matches the desired destination.&lt;br /&gt;
Topics for command messages to the &#039;&#039;teensy_interface&#039;&#039;:&lt;br /&gt;
* MQTT topic ricbot/cmd/T0 for the Teensy, the message is the string to send to the Teensy.&lt;br /&gt;
* MQTT topic ricbot/cmd/shutdown to schedule a shutdown of the RICBOT (power off), something like 20 seconds after the message.&lt;br /&gt;
* MQTT topic ricbot/cmd/ti for messages to the teensy_interface, the message is a string.&lt;br /&gt;
&lt;br /&gt;
==== Install ====&lt;br /&gt;
&lt;br /&gt;
The robot&#039;s interface is via MQTT. Install the MQTT ROS client&lt;br /&gt;
 sudo apt install ros-jazzy-mqtt-client&lt;br /&gt;
&lt;br /&gt;
Or directly as source&lt;br /&gt;
 cd src&lt;br /&gt;
 git clone https://github.com/ika-rwth-aachen/mqtt_client&lt;br /&gt;
 &lt;br /&gt;
Compile:&lt;br /&gt;
 cd ~/ros2_ws&lt;br /&gt;
 colcon build&lt;br /&gt;
&lt;br /&gt;
==== Run MQTT_client ====&lt;br /&gt;
&lt;br /&gt;
To start the &#039;&#039;mqtt_client&#039;&#039;:&lt;br /&gt;
 cd ros2_ws/src/mqtt_client/mqtt_client/config&lt;br /&gt;
 ros2 launch mqtt_client standalone.launch.xml params_file:=&amp;quot;params.teensy.yaml&amp;quot;&lt;br /&gt;
The parameter file should be extended with more &#039;&#039;mqtt2ros&#039;&#039; topics as needed.&lt;br /&gt;
&lt;br /&gt;
This will launch the un-modified &#039;&#039;mqtt_client&#039;&#039; node with specific bridge parameters as specified in &#039;&#039;params.teensy.yaml&#039;&#039;:&lt;br /&gt;
 /**/*:&lt;br /&gt;
  ros__parameters:&lt;br /&gt;
    broker:&lt;br /&gt;
      host: localhost&lt;br /&gt;
      port: 1883&lt;br /&gt;
      tls:&lt;br /&gt;
        enabled: false&lt;br /&gt;
    client:&lt;br /&gt;
      id: ros&lt;br /&gt;
      clean_session: true&lt;br /&gt;
      keep_alive_interval: 20.0&lt;br /&gt;
    bridge:&lt;br /&gt;
      ros2mqtt:&lt;br /&gt;
        ros_topics: &lt;br /&gt;
          - /teensy/cmd/T0&lt;br /&gt;
          - /teensy/cmd/shutdown&lt;br /&gt;
          - /teensy/cmd/ti&lt;br /&gt;
        /teensy/cmd/T0:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/T0&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
        /teensy/cmd/shutdown:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/shutdown&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
        /teensy/cmd/ti:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/ti&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
      mqtt2ros:&lt;br /&gt;
        # Needs to be expanded to relevant topics&lt;br /&gt;
        mqtt_topics: &lt;br /&gt;
          - ricbot/data/T0/info&lt;br /&gt;
          - ricbot/data/T0/hbt&lt;br /&gt;
        ricbot/data/T0/info:&lt;br /&gt;
          ros_topic: /teensy/T0/info&lt;br /&gt;
          primitive: true&lt;br /&gt;
        ricbot/data/T0/hbt:&lt;br /&gt;
          ros_topic: /teensy/T0/hbt&lt;br /&gt;
          primitive: true&lt;br /&gt;
&lt;br /&gt;
=== Test interface ===&lt;br /&gt;
&lt;br /&gt;
Start the &#039;&#039;teensy_interface&#039;&#039; with the right ini-file:&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -z ricbot.ini&lt;br /&gt;
&lt;br /&gt;
This should respond with something like:&lt;br /&gt;
 $ ./teensy_interface -z ricbot.ini&lt;br /&gt;
 # UService:: created directory log_20260118_083120.745/&lt;br /&gt;
 # UMqtt:: connection to MQTT broker on tcp://localhost:1883 established&lt;br /&gt;
 # UMqttIn:: connection to MQTT broker on tcp://localhost:1883 established&lt;br /&gt;
 # STeensy:: opening to USB /dev/ttyACM0&lt;br /&gt;
 # SRobot:: (t0) found IP 0: eno1 192.168.2.157&lt;br /&gt;
 # STeensy:: just connected &lt;br /&gt;
 # UService:: setup of Teensy 0 modules finished OK.&lt;br /&gt;
 # Type quit to stop, or &#039;h&#039; for help&lt;br /&gt;
&lt;br /&gt;
Start the &#039;&#039;mqtt_client&#039;&#039; in ROS&lt;br /&gt;
 cd ~/svn/ricbot/ros_config&lt;br /&gt;
 ros2 launch mqtt_client standalone.launch.xml params_file:=&amp;quot;params.teensy.yaml&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== From MQTT to ROS ====&lt;br /&gt;
&lt;br /&gt;
There should now be &#039;&#039;hbt&#039;&#039; (heartbeat) message on the ROS side:&lt;br /&gt;
 ros2 topic echo /teensy/T0/hbt&lt;br /&gt;
&lt;br /&gt;
This should give something like:&lt;br /&gt;
 data: &#039;1768722645.7425 1738.4885 93 1748 4.85 0 9 18.1 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
 data: &#039;1768722646.2426 1738.9885 93 1748 4.85 0 9 18.0 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
 data: &#039;1768722646.7431 1739.4885 93 1748 4.85 0 9 18.0 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
&lt;br /&gt;
The data is: timestamp (host), timestamp Teensy, Teensy ID, version, battery voltage, ... (the rest depend on the platform).&lt;br /&gt;
&lt;br /&gt;
==== From ROS to MQTT ====&lt;br /&gt;
&lt;br /&gt;
e.g. make the robot drive with velocity 0.25m/s and turn 0.1 rad/s CCV, followed by stop:&lt;br /&gt;
&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/ti std_msgs/String &#039;data: rc 0.25 0.1&#039;&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/ti std_msgs/String &#039;data: rc 0 0&#039;&lt;br /&gt;
&lt;br /&gt;
Or send a request to publish gyro data every 12ms:&lt;br /&gt;
&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/T0 std_msgs/String &#039;data: sub gyro 12&#039;&lt;br /&gt;
&lt;br /&gt;
== (RIC_pkg) HW sensor translate package ==&lt;br /&gt;
&lt;br /&gt;
Create the package in the workspace.&lt;br /&gt;
&lt;br /&gt;
 cd ~/ros2_ws/src&lt;br /&gt;
 ros2 pkg create --build-type ament_cmake --license MIT --node-name ric_node ric_pkg&lt;br /&gt;
&lt;br /&gt;
Add dependencies to other packages to CMakeLists.txt.&lt;br /&gt;
Add to the list of &#039;&#039;find_package&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 find_package(rclcpp REQUIRED)&lt;br /&gt;
 find_package(std_msgs REQUIRED)&lt;br /&gt;
 find_package(nav_msgs REQUIRED)&lt;br /&gt;
 find_package(sensor_msgs REQUIRED)&lt;br /&gt;
 find_package(geometry_msgs REQUIRED)&lt;br /&gt;
&lt;br /&gt;
Make target dependencies available in the include path (and elsewhere as needed).&lt;br /&gt;
&lt;br /&gt;
Add this after the &#039;&#039;add_executable&#039;&#039;&lt;br /&gt;
 ament_target_dependencies(talker rclcpp std_msgs nav_msgs sensor_msgs geometry_msgs)&lt;br /&gt;
&lt;br /&gt;
To the package description &#039;&#039;package.xml&#039;&#039; add dependencies:&lt;br /&gt;
&lt;br /&gt;
Add just after the &#039;&#039;buildtool_depend&#039;&#039; section:&lt;br /&gt;
 &amp;lt;depend&amp;gt;rclcpp&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;std_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;nav_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;sensor_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;geometry_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RIC_node code ===&lt;br /&gt;
&lt;br /&gt;
The code in &#039;&#039;ris_node.cpp&#039;&#039; is pt this (not functional yet):&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;cstdio&amp;gt;&lt;br /&gt;
 #include &amp;lt;chrono&amp;gt;&lt;br /&gt;
 #include &amp;lt;memory&amp;gt;&lt;br /&gt;
 #include &amp;lt;string&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;rclcpp/rclcpp.hpp&amp;quot;&lt;br /&gt;
 #include &amp;quot;std_msgs/msg/string.hpp&amp;quot;&lt;br /&gt;
 #include &amp;quot;std_msgs/msg/int32.hpp&amp;quot;&lt;br /&gt;
 #include &amp;lt;nav_msgs/msg/odometry.hpp&amp;gt;&lt;br /&gt;
 #include &amp;quot;geometry_msgs/msg/twist.hpp&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 class RIC_translator : public rclcpp::Node&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
  RIC_translator()&lt;br /&gt;
  : Node(&amp;quot;minimal_publisher&amp;quot;), count(0)&lt;br /&gt;
  {&lt;br /&gt;
    publisher_ = this-&amp;gt;create_publisher&amp;lt;std_msgs::msg::String&amp;gt;(&amp;quot;/ric/hbt&amp;quot;, 10);&lt;br /&gt;
    //&lt;br /&gt;
    // Heartbeat&lt;br /&gt;
    auto topic_callback =&lt;br /&gt;
    [this](std_msgs::msg::String::UniquePtr msg) -&amp;gt; void {&lt;br /&gt;
      // RCLCPP_INFO(this-&amp;gt;get_logger(), &amp;quot;I heard: hbt &#039;%s&#039;&amp;quot;, msg-&amp;gt;data.c_str());&lt;br /&gt;
      // strncpy(hbtParams, msg-&amp;gt;data.c_str(), 100);&lt;br /&gt;
      printHbt(msg-&amp;gt;data.c_str());&lt;br /&gt;
    };&lt;br /&gt;
    subsHbt =&lt;br /&gt;
    this-&amp;gt;create_subscription&amp;lt;std_msgs::msg::String&amp;gt;(&amp;quot;/teensy/T0/hbt&amp;quot;, 10, topic_callback);&lt;br /&gt;
  }&lt;br /&gt;
 private:&lt;br /&gt;
  rclcpp::TimerBase::SharedPtr timer_;&lt;br /&gt;
  rclcpp::Publisher&amp;lt;std_msgs::msg::String&amp;gt;::SharedPtr publisher_;&lt;br /&gt;
  rclcpp::Publisher&amp;lt;std_msgs::msg::Int32&amp;gt;::SharedPtr odo_;&lt;br /&gt;
  size_t count;&lt;br /&gt;
  //&lt;br /&gt;
  char hbtParams[100] = &amp;quot;&amp;quot;;&lt;br /&gt;
  rclcpp::Subscription&amp;lt;std_msgs::msg::String&amp;gt;::SharedPtr subsHbt;&lt;br /&gt;
  void printHbt(const char * msg)&lt;br /&gt;
  {&lt;br /&gt;
    printf(&amp;quot;# %lu got hbt %s&amp;quot;, count, msg);&lt;br /&gt;
    snprintf(hbtParams, 100, &amp;quot;Hello RIC %lu %s&amp;quot;, count++, msg);&lt;br /&gt;
    auto message = std_msgs::msg::String();&lt;br /&gt;
    message.set__data(hbtParams);&lt;br /&gt;
    this-&amp;gt;publisher_-&amp;gt;publish(message);&lt;br /&gt;
  }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char ** argv)&lt;br /&gt;
 {&lt;br /&gt;
  rclcpp::init(argc, argv);&lt;br /&gt;
  rclcpp::spin(std::make_shared&amp;lt;RIC_translator&amp;gt;());&lt;br /&gt;
  rclcpp::shutdown();&lt;br /&gt;
  return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Run RIC_node ===&lt;br /&gt;
&lt;br /&gt;
Compile (from workspace)&lt;br /&gt;
 colcon build --packages-select ric_pkg&lt;br /&gt;
 &lt;br /&gt;
Then add it to the path&lt;br /&gt;
 source install/setup.bash&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
 ros2 run ric_pkg ric_node&lt;br /&gt;
&lt;br /&gt;
If the &#039;&#039;teensy_interface&#039;&#039; and the &#039;&#039;mqtt-client&#039;&#039; are also running, then (with the code above), it should print something like this on the console.&lt;br /&gt;
 # 0 got hbt 1769340959.8623 13504.9463 105 1033 15.65 4 8 8.9 0.27 0&lt;br /&gt;
 # 1 got hbt 1769340960.3625 13505.4463 105 1033 15.65 4 8 8.8 0.28 0&lt;br /&gt;
 # 2 got hbt 1769340960.8626 13505.9453 105 1033 15.65 4 8 8.8 0.27 0&lt;br /&gt;
 # 3 got hbt 1769340961.3622 13506.4463 105 1033 15.65 4 8 8.9 0.28 0&lt;br /&gt;
 # 4 got hbt 1769340961.8625 13506.9463 105 1033 15.65 4 8 8.9 0.25 0&lt;br /&gt;
 # 5 got hbt 1769340962.3631 13507.4453 105 1033 15.66 4 8 8.9 0.26 0&lt;br /&gt;
 # 6 got hbt 1769340962.8624 13507.9463 105 1033 15.63 4 8 8.8 0.26 0&lt;br /&gt;
&lt;br /&gt;
=== Ros2 relevant messages ===&lt;br /&gt;
&lt;br /&gt;
One of the messages are probably &#039;&#039;twist&#039;&#039;:&lt;br /&gt;
 ros2 interface show geometry_msgs/msg/Twist&lt;br /&gt;
 # This expresses velocity in free space broken into its linear and angular parts.&lt;br /&gt;
 Vector3  linear&lt;br /&gt;
        float64 x&lt;br /&gt;
        float64 y&lt;br /&gt;
        float64 z&lt;br /&gt;
 Vector3  angular&lt;br /&gt;
        float64 x&lt;br /&gt;
        float64 y&lt;br /&gt;
        float64 z&lt;br /&gt;
&lt;br /&gt;
=== Where from here ===&lt;br /&gt;
&lt;br /&gt;
Search for tutorials in https://docs.ros.org/en/jazzy/&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_install_on_Raspberry&amp;diff=8697</id>
		<title>Robobot install on Raspberry</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_install_on_Raspberry&amp;diff=8697"/>
		<updated>2026-03-18T10:17:34Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Additional packages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot B]]&lt;br /&gt;
&lt;br /&gt;
== Raspberry installation notes ==&lt;br /&gt;
&lt;br /&gt;
Raspberry Pi recommended 64-bit OS is &#039;&#039;Debian GNU/Linux 13 (trixie)&#039;&#039; (2025)&lt;br /&gt;
&lt;br /&gt;
[[Raspberry base install]]&lt;br /&gt;
&lt;br /&gt;
Alternatively, if ROS2 is needed, install Ubuntu (but a bit more complicated)&lt;br /&gt;
&lt;br /&gt;
=== Install Raspberry on blank SD-card ===&lt;br /&gt;
&lt;br /&gt;
Use Raspberry Pi Imager &lt;br /&gt;
(download from https://www.raspberrypi.com/software/)&lt;br /&gt;
&lt;br /&gt;
 rpi-imager&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Select operating system&#039;&#039;&#039; &#039;Raspberry Pi OS (64bit)&#039; and &#039;&#039;&#039;storage&#039;&#039;&#039;, an empty SD-flash of at least 16GB.&lt;br /&gt;
&lt;br /&gt;
Next&lt;br /&gt;
&lt;br /&gt;
Edit settings: set: &lt;br /&gt;
&lt;br /&gt;
* Hostname (e.g. robobot)&lt;br /&gt;
* Username (local) and password (remember to spell the password correctly).&lt;br /&gt;
* SSID (DTUdevice), and associated password&lt;br /&gt;
* Time zone (Europe/Copenhagen)&lt;br /&gt;
* Danish keyboard&lt;br /&gt;
* In &#039;&#039;Services&#039;&#039;, enable SSH.&lt;br /&gt;
&lt;br /&gt;
Then yes, yes.&lt;br /&gt;
&lt;br /&gt;
When finished, mount the SD into the Raspberry Pi&lt;br /&gt;
&lt;br /&gt;
=== Get in contact with Raspberry ===&lt;br /&gt;
&lt;br /&gt;
If everything is configured as above, you just need to determine the IP.&lt;br /&gt;
On a Linux computer, you can find the Raspberry Pi&#039;s IP address using (if on the same local network):&lt;br /&gt;
&lt;br /&gt;
 sudo apt install net-tools nmap&lt;br /&gt;
 nmap -sP 192.168.2.0/24&lt;br /&gt;
&lt;br /&gt;
else&lt;br /&gt;
&lt;br /&gt;
You need a screen and keyboard.&lt;br /&gt;
&lt;br /&gt;
Log on to the Raspberry Pi&lt;br /&gt;
&lt;br /&gt;
 $ ifconfig&lt;br /&gt;
 eth0: flags=4099&amp;lt;UP,BROADCAST,MULTICAST&amp;gt;  mtu 1500&lt;br /&gt;
   ...&lt;br /&gt;
 lo: flags=73&amp;lt;UP,LOOPBACK,RUNNING&amp;gt;  mtu 65536&lt;br /&gt;
   ...&lt;br /&gt;
 wlan0: flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt;  mtu 1500&lt;br /&gt;
        inet 10.197.217.175  netmask 255.255.252.0  broadcast 10.197.219.255&lt;br /&gt;
        inet6 fe80::f620:b431:69cc:44f4  prefixlen 64  scopeid 0x20&amp;lt;link&amp;gt;&lt;br /&gt;
        ether dc:a6:32:f4:0e:a4  txqueuelen 1000  (Ethernet)&lt;br /&gt;
        RX packets 486  bytes 41505 (40.5 KiB)&lt;br /&gt;
        RX errors 0  dropped 0  overruns 0  frame 0&lt;br /&gt;
        TX packets 421  bytes 43403 (42.3 KiB)&lt;br /&gt;
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In this case, the IP4 (inet) is 10.197.217.175.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t get an IP address, the Wi-Fi may not be set correctly (see the [[Network setup]]).&lt;br /&gt;
&lt;br /&gt;
===Additional packages===&lt;br /&gt;
&lt;br /&gt;
Install the following packages:&lt;br /&gt;
 libreadline-dev&lt;br /&gt;
 libopencv-dev&lt;br /&gt;
 libgpiod-dev&lt;br /&gt;
 gpiod&lt;br /&gt;
 cmake&lt;br /&gt;
 subversion&lt;br /&gt;
 aptitude&lt;br /&gt;
 telnet&lt;br /&gt;
 ntp       (better to use timesyncd)&lt;br /&gt;
 ntpdate   (       --              )&lt;br /&gt;
 nmap&lt;br /&gt;
 lsof&lt;br /&gt;
 net-tools&lt;br /&gt;
 libpaho-mqtt-dev &lt;br /&gt;
 libpaho-mqttpp-dev (if not available, then not needed)&lt;br /&gt;
 python3-paho-mqtt&lt;br /&gt;
 python3-opencv&lt;br /&gt;
 python3-setproctitle&lt;br /&gt;
 mosquito&lt;br /&gt;
 mosquitto-dev &lt;br /&gt;
 mosquitto-clients&lt;br /&gt;
 libusb-dev&lt;br /&gt;
 libcli11-dev    (maybe not available)&lt;br /&gt;
 libssl-dev&lt;br /&gt;
 sudo apt install libreadline-dev libopencv-dev libgpiod-dev gpiod cmake subversion aptitude telnet nmap lsof python3-paho-mqtt libpaho-mqtt-dev python3-opencv python3-setproctitle mosquitto mosquitto-dev mosquitto-clients libusb-dev libcli11-dev net-tools libssl-dev&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
and, if libcli11-dev is not available&lt;br /&gt;
&lt;br /&gt;
Install command line interface library (if not found by &#039;apt install libcli11-dev&#039;)&lt;br /&gt;
 cd&lt;br /&gt;
 cd git&lt;br /&gt;
 git clone https://github.com/CLIUtils/CLI11.git&lt;br /&gt;
&lt;br /&gt;
The library is &#039;header-only&#039;, and the makefile for Raspberry looks in ~/git/CLI11 for the file, so no need to build.&lt;br /&gt;
&lt;br /&gt;
==== Ubuntu additional ====&lt;br /&gt;
&lt;br /&gt;
Install also:&lt;br /&gt;
 build-essential&lt;br /&gt;
 net-tools&lt;br /&gt;
 openssh-server&lt;br /&gt;
 grub-mkconfig  (not found)&lt;br /&gt;
 git&lt;br /&gt;
 sudo apt install net-tools openssh-server git build-essential&lt;br /&gt;
&lt;br /&gt;
The ssh server needs to be enabled&lt;br /&gt;
 sudo systemctl enable ssh&lt;br /&gt;
 sudo systemctl start ssh&lt;br /&gt;
&lt;br /&gt;
The grub-mkconfig command can be used to update the startup behaviour, e.g., to terminal-only.&lt;br /&gt;
Edit the /etc/default/grub, make the changes, and then update the boot&lt;br /&gt;
 sudo grub-mkconfig -o /boot/grub/grub.cfg&lt;br /&gt;
but not found&lt;br /&gt;
&lt;br /&gt;
=== Configure Mosquitto ===&lt;br /&gt;
&lt;br /&gt;
At installation, the Mosquitto server does not allow remote access.&lt;br /&gt;
&lt;br /&gt;
A complete configuration file can be found here: https://github.com/eclipse-mosquitto/mosquitto/tree/master&lt;br /&gt;
&lt;br /&gt;
Only two options are needed, so we make a set of local options:&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/mosquitto/conf.d/robobot.conf&lt;br /&gt;
&lt;br /&gt;
Insert these lines (insert from clipboard is Ctrl+Shift+v in nano)&lt;br /&gt;
 listener 1883&lt;br /&gt;
 allow_anonymous true&lt;br /&gt;
&lt;br /&gt;
Save and restart mosquito&lt;br /&gt;
&lt;br /&gt;
 sudo service mosquitto restart&lt;br /&gt;
&lt;br /&gt;
More details here [[MQTT_and_Mosquitto]]&lt;br /&gt;
&lt;br /&gt;
=== Configure serial port /dev/ttyACM0 ===&lt;br /&gt;
&lt;br /&gt;
At times, a serial port echoes what is received. This creates an endless loop, as the Teensy sends a reply, if something is not understood.&lt;br /&gt;
This is a configuration of the port; see the settings using stty:&lt;br /&gt;
&lt;br /&gt;
 stty -a -F /dev/ttyACM0&lt;br /&gt;
  &#039;&#039;speed 9600 baud; rows 0; columns 0; line = 0;&lt;br /&gt;
  &#039;&#039;intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = &amp;lt;undef&amp;gt;; eol2 = &amp;lt;undef&amp;gt;; swtch = &amp;lt;undef&amp;gt;; start = ^Q;&lt;br /&gt;
  &#039;&#039;stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;&lt;br /&gt;
  &#039;&#039;-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts&lt;br /&gt;
  &#039;&#039;-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8&lt;br /&gt;
  &#039;&#039;-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0&lt;br /&gt;
  &#039;&#039;-isig -icanon iexten &#039;&#039;&#039;-echo&#039;&#039;&#039; -echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Especially &#039;&#039;echo&#039;&#039; (last line) must have a &#039;-&#039; in front. However, other types of handshake, such as &#039;ixoff&#039;, should be disabled as well.&lt;br /&gt;
This can all be set by:&lt;br /&gt;
&lt;br /&gt;
 stty -F /dev/ttyACM0 raw -echo -echoe&lt;br /&gt;
&lt;br /&gt;
When installing the &#039;&#039;udev&#039;&#039; rule for Teensy devices, then the above command is executed when a Teensy device is detected.&lt;br /&gt;
See [[Arduino_and_Teensy_libraries#Add_Teensy_board_support]].&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;udev&#039;&#039; rule is included in &#039;&#039;robobot/setup&#039;&#039; directory as &#039;&#039;00-teensy.rules&#039;&#039;, is should be copied to /etc/udev&lt;br /&gt;
 sudo cp ~/svn/robobot/setup/00-teensy.rules /etc/udev/rules.d/&lt;br /&gt;
The file contains&lt;br /&gt;
&lt;br /&gt;
 # UDEV Rules for Teensy boards, http://www.pjrc.com/teensy/&lt;br /&gt;
 #&lt;br /&gt;
 # The latest version of this file may be found at:&lt;br /&gt;
 #   http://www.pjrc.com/teensy/00-teensy.rules&lt;br /&gt;
 #&lt;br /&gt;
 # This file must be placed at:&lt;br /&gt;
 #&lt;br /&gt;
 # /etc/udev/rules.d/00-teensy.rules    (preferred location)&lt;br /&gt;
 #   or&lt;br /&gt;
 # /lib/udev/rules.d/00-teensy.rules    (req&#039;d on some broken systems)&lt;br /&gt;
 #&lt;br /&gt;
 # To install, type this command in a terminal:&lt;br /&gt;
 #   sudo cp 00-teensy.rules /etc/udev/rules.d/00-teensy.rules&lt;br /&gt;
 #&lt;br /&gt;
 # After this file is installed, physically unplug and reconnect Teensy.&lt;br /&gt;
 #&lt;br /&gt;
 ATTRS{idVendor}==&amp;quot;16c0&amp;quot;, ATTRS{idProduct}==&amp;quot;04*&amp;quot;, ENV{ID_MM_DEVICE_IGNORE}=&amp;quot;1&amp;quot;, ENV{ID_MM_PORT_IGNORE}=&amp;quot;1&amp;quot;&lt;br /&gt;
 ATTRS{idVendor}==&amp;quot;16c0&amp;quot;, ATTRS{idProduct}==&amp;quot;04[789a]*&amp;quot;, ENV{MTP_NO_PROBE}=&amp;quot;1&amp;quot;&lt;br /&gt;
 KERNEL==&amp;quot;ttyACM*&amp;quot;, ATTRS{idVendor}==&amp;quot;16c0&amp;quot;, ATTRS{idProduct}==&amp;quot;04*&amp;quot;, MODE:=&amp;quot;0666&amp;quot;, RUN:=&amp;quot;/bin/stty -F /dev/%k raw -echo&amp;quot;&lt;br /&gt;
 KERNEL==&amp;quot;hidraw*&amp;quot;, ATTRS{idVendor}==&amp;quot;16c0&amp;quot;, ATTRS{idProduct}==&amp;quot;04*&amp;quot;, MODE:=&amp;quot;0666&amp;quot;&lt;br /&gt;
 SUBSYSTEMS==&amp;quot;usb&amp;quot;, ATTRS{idVendor}==&amp;quot;16c0&amp;quot;, ATTRS{idProduct}==&amp;quot;04*&amp;quot;, MODE:=&amp;quot;0666&amp;quot;&lt;br /&gt;
 KERNEL==&amp;quot;hidraw*&amp;quot;, ATTRS{idVendor}==&amp;quot;1fc9&amp;quot;, ATTRS{idProduct}==&amp;quot;013*&amp;quot;, MODE:=&amp;quot;0666&amp;quot;&lt;br /&gt;
 SUBSYSTEMS==&amp;quot;usb&amp;quot;, ATTRS{idVendor}==&amp;quot;1fc9&amp;quot;, ATTRS{idProduct}==&amp;quot;013*&amp;quot;, MODE:=&amp;quot;0666&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #&lt;br /&gt;
 # If you share your Linux system with other users, or just don&#039;t like the&lt;br /&gt;
 # idea of write permission for everybody, you can replace MODE:=&amp;quot;0666&amp;quot; with&lt;br /&gt;
 # OWNER:=&amp;quot;yourusername&amp;quot; to create the device owned by you, or with&lt;br /&gt;
 # GROUP:=&amp;quot;somegroupname&amp;quot; and manage access using standard Unix groups.&lt;br /&gt;
 #&lt;br /&gt;
 # ModemManager tends to interfere with USB Serial devices like Teensy.&lt;br /&gt;
 # Problems manifest as the Arduino Serial Monitor missing some incoming&lt;br /&gt;
 # data, and &amp;quot;Unable to open /dev/ttyACM0 for reboot request&amp;quot; when&lt;br /&gt;
 # uploading. If you experience these problems, disable or remove&lt;br /&gt;
 # ModemManager from your system. If you must use a modem, perhaps&lt;br /&gt;
 # try disabling the &amp;quot;MM_FILTER_RULE_TTY_ACM_INTERFACE&amp;quot; ModemManager&lt;br /&gt;
 # rule. Changing ModemManager&#039;s filter policy from &amp;quot;strict&amp;quot; to &amp;quot;default&amp;quot;&lt;br /&gt;
 # may also help. But if you don&#039;t use a modem, completely removing&lt;br /&gt;
 # the troublesome ModemManager is the most effective solution.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8696</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8696"/>
		<updated>2026-03-12T13:26:27Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Testing calibration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92 or 68)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
==== Set configuration ====&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This message is typicalle send from the Python script &#039;&#039;spose.py&#039;&#039; around line 92:&lt;br /&gt;
 service.send(&amp;quot;robobot/cmd/T0&amp;quot;, &amp;quot;confw 0.074 0.074 19 92 0.23&amp;quot;)&lt;br /&gt;
Note: Some of the motors have a different encoder with 68 ticks per revolution (TPR), rather than the 92 in this example.&lt;br /&gt;
&lt;br /&gt;
==== Get configuration ====&lt;br /&gt;
&lt;br /&gt;
The configuration values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
==== Testing calibration ====&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;br /&gt;
&lt;br /&gt;
In Python, there are start options to test the odometry calibration. To drive 1m forward:&lt;br /&gt;
&lt;br /&gt;
 python3 mqtt-client.py -m&lt;br /&gt;
&lt;br /&gt;
and for the turn calibration (turn 180 degrees):&lt;br /&gt;
&lt;br /&gt;
 python3 mqtt-client.py -p&lt;br /&gt;
&lt;br /&gt;
The robot may make a small overshoot in both distance and the turn, so check the logfile to see what the robot thinks; this should match the actual measured drive.&lt;br /&gt;
&lt;br /&gt;
The Python log file is named &#039;&#039;logfile.txt&#039;&#039; in the &#039;&#039;svn/robobot/mqtt_python&#039;&#039; directory.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;teensy_interface&#039;&#039; also creates a logfile named &#039;&#039;log_y0_pose.txt&#039;&#039; in the &#039;&#039;svn/robobot/teensy_interface/build&#039;&#039; directory.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8695</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8695"/>
		<updated>2026-03-12T13:21:22Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Testing calibration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92 or 68)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
==== Set configuration ====&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This message is typicalle send from the Python script &#039;&#039;spose.py&#039;&#039; around line 92:&lt;br /&gt;
 service.send(&amp;quot;robobot/cmd/T0&amp;quot;, &amp;quot;confw 0.074 0.074 19 92 0.23&amp;quot;)&lt;br /&gt;
Note: Some of the motors have a different encoder with 68 ticks per revolution (TPR), rather than the 92 in this example.&lt;br /&gt;
&lt;br /&gt;
==== Get configuration ====&lt;br /&gt;
&lt;br /&gt;
The configuration values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
==== Testing calibration ====&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;br /&gt;
&lt;br /&gt;
In Python, there are start options to test the odometry calibration. To drive 1m forward:&lt;br /&gt;
&lt;br /&gt;
 python3 mqtt-client.py -m&lt;br /&gt;
&lt;br /&gt;
and for the turn calibration (turn 180 degrees):&lt;br /&gt;
&lt;br /&gt;
 python3 mqtt-client.py -p&lt;br /&gt;
&lt;br /&gt;
The robot may make a small overshoot in both distance and the turn, so check the logfile to see what the robot thinks; this should match the actual measured drive.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8694</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8694"/>
		<updated>2026-03-12T13:18:06Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Testing calibration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92 or 68)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
==== Set configuration ====&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This message is typicalle send from the Python script &#039;&#039;spose.py&#039;&#039; around line 92:&lt;br /&gt;
 service.send(&amp;quot;robobot/cmd/T0&amp;quot;, &amp;quot;confw 0.074 0.074 19 92 0.23&amp;quot;)&lt;br /&gt;
Note: Some of the motors have a different encoder with 68 ticks per revolution (TPR), rather than the 92 in this example.&lt;br /&gt;
&lt;br /&gt;
==== Get configuration ====&lt;br /&gt;
&lt;br /&gt;
The configuration values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
==== Testing calibration ====&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;br /&gt;
&lt;br /&gt;
In Python, there are start options to test the odometry calibration. To drive 1m forward:&lt;br /&gt;
&lt;br /&gt;
 python3 mqtt-client.py -m&lt;br /&gt;
&lt;br /&gt;
and for the turn calibration (turn 180 degrees):&lt;br /&gt;
&lt;br /&gt;
 python3 mqtt-client.py -p&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8693</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8693"/>
		<updated>2026-03-12T13:15:01Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Calibrate odometry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92 or 68)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
==== Set configuration ====&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This message is typicalle send from the Python script &#039;&#039;spose.py&#039;&#039; around line 92:&lt;br /&gt;
 service.send(&amp;quot;robobot/cmd/T0&amp;quot;, &amp;quot;confw 0.074 0.074 19 92 0.23&amp;quot;)&lt;br /&gt;
Note: Some of the motors have a different encoder with 68 ticks per revolution (TPR), rather than the 92 in this example.&lt;br /&gt;
&lt;br /&gt;
==== Get configuration ====&lt;br /&gt;
&lt;br /&gt;
The configuration values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
==== Testing calibration ====&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8692</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8692"/>
		<updated>2026-03-12T13:14:44Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Calibrate odometry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92 or 68)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
==== set configuration ====&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This message is typicalle send from the Python script &#039;&#039;spose.py&#039;&#039; around line 92:&lt;br /&gt;
 service.send(&amp;quot;robobot/cmd/T0&amp;quot;, &amp;quot;confw 0.074 0.074 19 92 0.23&amp;quot;)&lt;br /&gt;
Note: Some of the motors have a different encoder with 68 ticks per revolution (TPR), rather than the 92 in this example.&lt;br /&gt;
&lt;br /&gt;
==== get configuration ====&lt;br /&gt;
&lt;br /&gt;
The configuration values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
==== testing calibration ====&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8691</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8691"/>
		<updated>2026-03-12T13:13:40Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Calibrate odometry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92 or 68)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This message is typicalle send from the Python script &#039;&#039;spose.py&#039;&#039; around line 92:&lt;br /&gt;
 service.send(&amp;quot;robobot/cmd/T0&amp;quot;, &amp;quot;confw 0.074 0.074 19 92 0.23&amp;quot;)&lt;br /&gt;
Note: Some of the motors have a different encoder with 68 ticks per revolution (TPR), rather than the 92 in this example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8690</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8690"/>
		<updated>2026-03-12T13:13:26Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Calibrate odometry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92 or 68)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This message is typicalle send from the Python script &#039;&#039;&#039;spose.py&#039;&#039;&#039; around line 92:&lt;br /&gt;
 service.send(&amp;quot;robobot/cmd/T0&amp;quot;, &amp;quot;confw 0.074 0.074 19 92 0.23&amp;quot;)&lt;br /&gt;
Note: Some of the motors have a different encoder with 68 ticks per revolution (TPR), rather than the 92 in this example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8689</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8689"/>
		<updated>2026-03-12T13:12:05Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Calibrate odometry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This message is typicalle send from the Python script &#039;&#039;&#039;spose.py&#039;&#039;&#039; around line 92:&lt;br /&gt;
 service.send(&amp;quot;robobot/cmd/T0&amp;quot;,&amp;quot;confw 0.074 0.074 19 92 0.23&amp;quot;)&lt;br /&gt;
Note that some of the motors have a different encoder with 68 ticks per revolution (TPR), rather than the 92 in this example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8688</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8688"/>
		<updated>2026-03-12T13:07:43Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Calibrate odometry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8687</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8687"/>
		<updated>2026-03-12T13:07:35Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Calibrate odometry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;-- In the 2026 version, odometry is calculated by the teensy_interface,&lt;br /&gt;
So these values need to go into the file&lt;br /&gt;
 svn/robobot/teensy_interface/build/robot.ini&lt;br /&gt;
in the [mixer] section.&lt;br /&gt;
Remember that this file is overwritten when the teensy_interface stops (e.g. at reboot). The overwriting can be avoided by changing &#039;saveconfig = true&#039; to &#039;saveconfig = false&#039; in the [ini] section. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8686</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8686"/>
		<updated>2026-03-12T13:07:25Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Calibrate odometry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;--! In the 2026 version, odometry is calculated by the teensy_interface,&lt;br /&gt;
So these values need to go into the file&lt;br /&gt;
 svn/robobot/teensy_interface/build/robot.ini&lt;br /&gt;
in the [mixer] section.&lt;br /&gt;
Remember that this file is overwritten when the teensy_interface stops (e.g. at reboot). The overwriting can be avoided by changing &#039;saveconfig = true&#039; to &#039;saveconfig = false&#039; in the [ini] section. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8685</id>
		<title>Robobot calibration</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_calibration&amp;diff=8685"/>
		<updated>2026-03-06T14:03:56Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Calibrate odometry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sending commands to the Teensy board using MQTT ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Line sensor ==&lt;br /&gt;
&lt;br /&gt;
[[file:line-sensor-firmware-blocks.png | 500px ]]&lt;br /&gt;
&lt;br /&gt;
The line sensor blinks the LED illumination and subtracts the non-illuminated from the illuminated.&lt;br /&gt;
&lt;br /&gt;
These (raw) values are then normalized relative to a calibrated expected white value.&lt;br /&gt;
&lt;br /&gt;
The normalized value is between 0 (black - no reflection) and 1000 (calibrated white reflection).&lt;br /&gt;
&lt;br /&gt;
=== Start calibration ===&lt;br /&gt;
&lt;br /&gt;
Place the sensor at the expected distance over a white surface with the expected reflectance (i.e. white tape).&lt;br /&gt;
&lt;br /&gt;
Send the command, e.g. &#039;&#039;licw 100&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;licw 100&amp;quot;&lt;br /&gt;
where 100 means average over 100 samples.&lt;br /&gt;
&lt;br /&gt;
Once finished, save the values in the Teensy flash by &#039;&#039;eew&#039;&#039;:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Get normalized data ===&lt;br /&gt;
&lt;br /&gt;
Subscribe to data from the Teensy using the command&lt;br /&gt;
 sub livn 7&lt;br /&gt;
 Or using MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;sub livn 7&amp;quot;&lt;br /&gt;
where 7 means update every 7 ms. This could be as low as 1, but the traffic load may give communication bottlenecks, resulting in delay or lost messages. The communication limit is approximately 4000 messages per second (each below 64 characters).&lt;br /&gt;
&lt;br /&gt;
== Distance sensor calibration ==&lt;br /&gt;
&lt;br /&gt;
The distance sensor needs calibration.&lt;br /&gt;
&lt;br /&gt;
[[file:distance_sensor_firmware_block.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The sensor is calibrated with two sensor values, 13 cm and 50 cm.&lt;br /&gt;
&lt;br /&gt;
The datasheet states that the analogue voltage out of the sensor is something like:&lt;br /&gt;
&lt;br /&gt;
[[file:ir-sensor-voltage-2025.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
It can be seen that distances below 5cm can give the same voltage as most other distances.&lt;br /&gt;
&lt;br /&gt;
The easiest way is to have console access directly to the Teensy.&lt;br /&gt;
Connect to the robot using, e.g., Putty to get two command lines on the Robot&#039;s Raspberry.&lt;br /&gt;
Or a serial console if the Teensy is connected directly to a PC.&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 13 cm ====&lt;br /&gt;
&lt;br /&gt;
Subscribe to sensor data and calibration values every 300ms:&lt;br /&gt;
&lt;br /&gt;
Send this message to the Teensy&lt;br /&gt;
 sub ir 300&lt;br /&gt;
 Using MQTT this is:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: sub ir 300&lt;br /&gt;
&lt;br /&gt;
Watch the message (either using cat or MQTT)&lt;br /&gt;
 cat /dev/ttyACM0&lt;br /&gt;
 Using MQTT, subscribe to&lt;br /&gt;
 topic: robobot/drive/T0/ir&lt;br /&gt;
Should get this &lt;br /&gt;
&lt;br /&gt;
 ir 0.124 0.137 15698 14219 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15660 14220 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.124 0.137 15666 14207 15000 4600 15000 4100 1&lt;br /&gt;
or using MQTT&lt;br /&gt;
 robobot/drive/T0/ir 1740853405.7074 0.124 0.137 15698 14219 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.0078 0.124 0.137 15660 14220 15000 4600 15000 4100 1 &lt;br /&gt;
 robobot/drive/T0/ir 1740853406.3075 0.124 0.137 15666 14207 15000 4600 15000 4100 1 &lt;br /&gt;
&lt;br /&gt;
Obstacles are here at 13 cm for both sensors. The first two values show the distance, which is close to 13 cm here. The raw (filtered) values are approximately 15660 and 14210, respectively. This is relatively close to the already-calibrated value of 15000.&lt;br /&gt;
&lt;br /&gt;
The last value &#039;&#039;1&#039;&#039; shows that the sensor is on; if not, then send the on command:&lt;br /&gt;
&lt;br /&gt;
 iron 1&lt;br /&gt;
 Using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: iron 1&lt;br /&gt;
&lt;br /&gt;
==== Sensor values 50 cm ====&lt;br /&gt;
&lt;br /&gt;
The 50cm values could be &lt;br /&gt;
&lt;br /&gt;
 ir 0.496 0.426 4633 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.500 0.426 4600 4770 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.426 4628 4764 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.494 0.426 4641 4762 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.498 0.426 4616 4761 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.496 0.427 4627 4759 15000 4600 15000 4100 1&lt;br /&gt;
 ir 0.481 0.427 4741 4756 15000 4600 15000 4100 1&lt;br /&gt;
&lt;br /&gt;
The value seems fine for sensor 1 (default side-mounted); it is a bit off for the other sensor.&lt;br /&gt;
&lt;br /&gt;
==== Implement calibration ====&lt;br /&gt;
&lt;br /&gt;
To implement the new calibration values, use (in this case). &lt;br /&gt;
* Help text is: &#039;&#039;irc A1 B1 A2 B2 V Set calibration values A=13cm value, B=50cm (sensor 1 and 2) V=1 in on&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 irc 15660 4600 14210 4760 1&lt;br /&gt;
 or MQTT, publish:&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;irc 15660 4600 14210 4760 1&amp;quot;&lt;br /&gt;
Then save to the Teensy flash:&lt;br /&gt;
 eew&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message &amp;quot;eew&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values at 50cm now look like:&lt;br /&gt;
&lt;br /&gt;
 ir 0.501 0.501 4590 4756 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.491 0.498 4669 4770 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.498 0.501 4619 4754 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.499 0.499 4610 4765 15660 4600 14210 4760 1&lt;br /&gt;
 ir 0.493 0.501 4654 4755 15660 4600 14210 4760 1&lt;br /&gt;
&lt;br /&gt;
After this calibration, the actual values should be within 3-5 cm in the 10cm to 50cm range.&lt;br /&gt;
&lt;br /&gt;
==== Reflections ====&lt;br /&gt;
&lt;br /&gt;
If the sensor looks into a reflecting surface, then this may disturb the reading.&lt;br /&gt;
&lt;br /&gt;
==== Back to normal ====&lt;br /&gt;
&lt;br /&gt;
The teensy_interface was terminated, and further, the CRC was disabled.&lt;br /&gt;
&lt;br /&gt;
Turn on CRC:&lt;br /&gt;
&lt;br /&gt;
 echo &amp;quot;i 0&amp;quot; &amp;gt;/dev/ttyACM0&lt;br /&gt;
&lt;br /&gt;
Restart the teensy_interface, or maybe better, reboot the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
&lt;br /&gt;
alternatively, restart&lt;br /&gt;
&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -l&lt;br /&gt;
&lt;br /&gt;
But the restarted process will be terminated sometime after you terminate the command line access.&lt;br /&gt;
&lt;br /&gt;
== Calibrate odometry ==&lt;br /&gt;
&lt;br /&gt;
Robot wheel configuration requires:&lt;br /&gt;
* Wheel radius (around 7.5cm)&lt;br /&gt;
* Gear ratio (19:1)&lt;br /&gt;
* Encoder ticks per revolution (92)&lt;br /&gt;
* Distance between wheels (around 23cm)&lt;br /&gt;
&lt;br /&gt;
In the 2026 version, odometry is calculated by the teensy_interface,&lt;br /&gt;
So these values need to go into the file&lt;br /&gt;
 svn/robobot/teensy_interface/build/robot.ini&lt;br /&gt;
in the [mixer] section.&lt;br /&gt;
Remember that this file is overwritten when the teensy_interface stops (e.g. at reboot). The overwriting can be avoided by changing &#039;saveconfig = true&#039; to &#039;saveconfig = false&#039; in the [ini] section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
These values are sent to the &#039;&#039;teensy_firmware_8&#039;&#039; as &#039;&#039;confw rl rr gear TPR wb&#039;&#039;, e.g.:&lt;br /&gt;
 confw 0.0750 0.0750 19 92 0.234&lt;br /&gt;
 or using MQTT&lt;br /&gt;
 topic: robobot/cmd/T0&lt;br /&gt;
 message: &amp;quot;confw 0.0750 0.0750 19 92 0.234&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The values can be queried with a &#039;&#039;configi&#039;&#039; command, which returns, e.g.:&lt;br /&gt;
 conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
 or, if subscribed from MQTT&lt;br /&gt;
 topic: robobot/drive/T0&lt;br /&gt;
 message: conf 0.0750 0.0750 19.000 92 0.2340 0.0020 0&lt;br /&gt;
The last &#039;&#039;0.0020&#039;&#039; is the system sample time, here 2ms. The last &#039;&#039;0&#039;&#039; is for motortest only.&lt;br /&gt;
&lt;br /&gt;
The simple method is:&lt;br /&gt;
* Order the robot to drive 1m, check how long the robot thinks it has driven, e.g. 1.02m, then compare with reality, and adjust the wheel radius as relevant.&lt;br /&gt;
* Order the robot to turn, e.g. 180 degrees, compare with reality and adjust the distance between driving wheels as needed.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=File:Power_switch_v2_pcb.png&amp;diff=8684</id>
		<title>File:Power switch v2 pcb.png</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=File:Power_switch_v2_pcb.png&amp;diff=8684"/>
		<updated>2026-03-01T18:46:35Z</updated>

		<summary type="html">&lt;p&gt;Jca: PCB&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
PCB&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=File:Power_switch_v2_circuit.png&amp;diff=8683</id>
		<title>File:Power switch v2 circuit.png</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=File:Power_switch_v2_circuit.png&amp;diff=8683"/>
		<updated>2026-03-01T18:46:13Z</updated>

		<summary type="html">&lt;p&gt;Jca: Circuit diagram&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Circuit diagram&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=RICBOT_Power_on-off_board&amp;diff=8682</id>
		<title>RICBOT Power on-off board</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=RICBOT_Power_on-off_board&amp;diff=8682"/>
		<updated>2026-03-01T18:45:41Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Power distribution */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Ricbot]]&lt;br /&gt;
&lt;br /&gt;
== Power distribution ==&lt;br /&gt;
&lt;br /&gt;
PCB&lt;br /&gt;
&lt;br /&gt;
[[file: power_switch_v2_circuit.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
[[file: power_switch_v2_pcb.png | 500px]]&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=RICBOT_Power_on-off_board&amp;diff=8681</id>
		<title>RICBOT Power on-off board</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=RICBOT_Power_on-off_board&amp;diff=8681"/>
		<updated>2026-03-01T18:41:31Z</updated>

		<summary type="html">&lt;p&gt;Jca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Ricbot]]&lt;br /&gt;
&lt;br /&gt;
== Power distribution ==&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=RICBOT_Power_on-off_board&amp;diff=8680</id>
		<title>RICBOT Power on-off board</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=RICBOT_Power_on-off_board&amp;diff=8680"/>
		<updated>2026-03-01T18:41:00Z</updated>

		<summary type="html">&lt;p&gt;Jca: Created page with &amp;quot;Back to RICBOT  == Power distribution ==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[RICBOT]]&lt;br /&gt;
&lt;br /&gt;
== Power distribution ==&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Ricbot&amp;diff=8679</id>
		<title>Ricbot</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Ricbot&amp;diff=8679"/>
		<updated>2026-03-01T18:40:36Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Cabling */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Ricbot, a wheeled sensor platform == &lt;br /&gt;
&lt;br /&gt;
Ricbot is intended for fast deployment to areas of interest.&lt;br /&gt;
&lt;br /&gt;
Main features:&lt;br /&gt;
* Reused motors and wheels from an old &amp;quot;Elector Wheelie&amp;quot; platform&lt;br /&gt;
* Designed to fit into a normal car for deployment, i.e can be disassembled to no more than 55cm in height.&lt;br /&gt;
* No more than 25-30 kg, requiring 1 or 2 persons to load or unload.&lt;br /&gt;
* Wheel-odometry recording (and timestamped)&lt;br /&gt;
* Camera image recording (and timestamped), the intention is Realsense D435.&lt;br /&gt;
* Maybe GNSS recording too.&lt;br /&gt;
* Manual remote control.&lt;br /&gt;
&lt;br /&gt;
Tentative layout:&lt;br /&gt;
&lt;br /&gt;
[[file: ricbot_on-shape.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
Length is 1m, free height 25cm, width 65cm.&lt;br /&gt;
&lt;br /&gt;
== Installation notes ==&lt;br /&gt;
&lt;br /&gt;
=== Camera position ===&lt;br /&gt;
&lt;br /&gt;
[[file: ric-camera-position.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
Forward-looking camera: Intel RealSense D455, FOV 87 x 58 deg, range 0.6 to 6m.&lt;br /&gt;
&lt;br /&gt;
Down-looking camera: Intel RealSense D435, FOV: 87 x 58 deg, range 0.3 to 3m.&lt;br /&gt;
&lt;br /&gt;
=== Cabling ===&lt;br /&gt;
&lt;br /&gt;
[[file: ric_cabling.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
DRI0042: https://wiki.dfrobot.com/15A_Single_DC_Motor_Driver_SKU__DRI0042&lt;br /&gt;
&lt;br /&gt;
Regbot 6.3: [[Regbot hardware board]]&lt;br /&gt;
&lt;br /&gt;
[[RICBOT Power on-off board]] PCB&lt;br /&gt;
&lt;br /&gt;
==== DRI0042 to Regbot 4-pin PWM ====&lt;br /&gt;
&lt;br /&gt;
 DRI              Regbot PWM    Software&lt;br /&gt;
 7 GND   (black)  1 GND         --&lt;br /&gt;
 4 PWM   (red)    2 in1         PIN_xxxx_DIR&lt;br /&gt;
 5 IN1   (white)  3 in2         PIN_xxxx_PWM&lt;br /&gt;
 6 IN2   (yellow) 4 fault       PIN_xxxx_FAULT&lt;br /&gt;
 3 5V out &lt;br /&gt;
&lt;br /&gt;
 DRI0042 control values&lt;br /&gt;
 IN1 	IN2 	PWM 	OUT1, OUT2 Motor Behavior&lt;br /&gt;
 0 	0 	x 	Stop&lt;br /&gt;
 1 	1 	x 	Vacant (relax)&lt;br /&gt;
 1 	0 	1 	Forward 100%&lt;br /&gt;
 0 	1 	1 	Reverse 100%&lt;br /&gt;
 1 	0 	PWM 	Forward at PWM speed&lt;br /&gt;
 0 	1 	PWM 	Reverse at PWM speed&lt;br /&gt;
&lt;br /&gt;
==== Power control ====&lt;br /&gt;
&lt;br /&gt;
 Pin        IDC10-pin      Software       Function&lt;br /&gt;
 1 (black)  1              --             GND&lt;br /&gt;
 2 (red)    3              LS_1  (pin 27) power off (when low)  -- pt not working (wrong mod on power board)&lt;br /&gt;
 3 (white)  4              LS_0  (A6)     battery voltage  (39k/4.7k)&lt;br /&gt;
 4 (yellow) 6              LS_4  (pin 26) Alive LED&lt;br /&gt;
&lt;br /&gt;
=== Intel RealSense ===&lt;br /&gt;
&lt;br /&gt;
Install &lt;br /&gt;
 sudo apt-get install automake libtool libusb-1.0-0-dev libx11-dev xorg-dev libglu1-mesa-dev&lt;br /&gt;
 sudo apt install libssl-dev&lt;br /&gt;
&lt;br /&gt;
==== Library and examples ====&lt;br /&gt;
&lt;br /&gt;
 cd ~/git&lt;br /&gt;
 git clone https://github.com/IntelRealSense/librealsense.git&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake ..&lt;br /&gt;
 make -j3&lt;br /&gt;
 sudo make install&lt;br /&gt;
&lt;br /&gt;
Copy udev rules to udev&lt;br /&gt;
&lt;br /&gt;
 cd ~/git/librealsense/config/99-realsense*.rules /etc/udev/rules.d/&lt;br /&gt;
 udevadm control --reload-rules&lt;br /&gt;
&lt;br /&gt;
All example commands start with rs-, e.g.:&lt;br /&gt;
 rs-capture&lt;br /&gt;
 rs-pointcloud&lt;br /&gt;
&lt;br /&gt;
=== Teensy interface ===&lt;br /&gt;
&lt;br /&gt;
The Teensy interface implements a bridge to MQTT, a motor controller (velocity and turn rate), and a remote control.&lt;br /&gt;
&lt;br /&gt;
The configuration is in&lt;br /&gt;
 /home/local/svn/teensy_interface/build/robot.ini&lt;br /&gt;
&lt;br /&gt;
See also [[Robobot teensy interface]].&lt;br /&gt;
&lt;br /&gt;
=== Start at boot ===&lt;br /&gt;
&lt;br /&gt;
See the similar start setup in [[https://rsewiki.electro.dtu.dk/index.php?title=Enable_autostart#Autostart]].&lt;br /&gt;
&lt;br /&gt;
Comment out (or delete) the start of the camera streamer (not compatible with RealSense 3D cam)&lt;br /&gt;
&lt;br /&gt;
=== Install software on Raspberry Pi ===&lt;br /&gt;
&lt;br /&gt;
Perform the same installation as [[Robobot install on Raspberry]], except for the serial port configuration (which should not be needed).&lt;br /&gt;
&lt;br /&gt;
=== Teensy software ===&lt;br /&gt;
&lt;br /&gt;
This is the Regbot software, configured to match the Ricbot.&lt;br /&gt;
&lt;br /&gt;
See more details here [[Regbot firmware]].&lt;br /&gt;
&lt;br /&gt;
=== Intel Librealsense ===&lt;br /&gt;
&lt;br /&gt;
Installing support for Intel librealsense.&lt;br /&gt;
&lt;br /&gt;
 sudo apt install libssl-dev&lt;br /&gt;
 sudo apt-get install freeglut3-dev&lt;br /&gt;
 sudo apt-get install xorg-dev&lt;br /&gt;
 cd git&lt;br /&gt;
 git clone https://github.com/IntelRealSense/librealsense.git&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 mkdir build&lt;br /&gt;
 cd build&lt;br /&gt;
 cmake ..&lt;br /&gt;
&lt;br /&gt;
I also needed to install libusb-1.0-0-dev&lt;br /&gt;
 sudo apt install libusb-1.0-0-dev&lt;br /&gt;
This path was not included in the CMakeLists.txt, so I added this line at the beginning of the CMakeLists.txt:&lt;br /&gt;
&lt;br /&gt;
 cd librealsense&lt;br /&gt;
 nano CMakeLists.txt&lt;br /&gt;
add&lt;br /&gt;
 include_directories( /usr/include/libusb-1.0/ )&lt;br /&gt;
like here:&lt;br /&gt;
 cmake_minimum_required(VERSION 3.10)&lt;br /&gt;
 &lt;br /&gt;
 set( LRS_TARGET realsense2 )&lt;br /&gt;
 project( ${LRS_TARGET} LANGUAGES CXX C )&lt;br /&gt;
 &lt;br /&gt;
 # Allow librealsense2 and all of the nested project to include the main repo folder&lt;br /&gt;
 set(REPO_ROOT ${CMAKE_CURRENT_SOURCE_DIR})&lt;br /&gt;
 include_directories(${REPO_ROOT})&lt;br /&gt;
 &#039;&#039;&#039;include_directories( /usr/include/libusb-1.0/ )&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 include(CMake/lrs_options.cmake)&lt;br /&gt;
 include(CMake/connectivity_check.cmake)&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
== ROS2 ==&lt;br /&gt;
&lt;br /&gt;
From https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html&lt;br /&gt;
&lt;br /&gt;
Install &lt;br /&gt;
 export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F &amp;quot;tag_name&amp;quot; | awk -F\&amp;quot; &#039;{print $4}&#039;)&lt;br /&gt;
&lt;br /&gt;
 curl -L -o /tmp/ros2-apt-source.deb &amp;quot;https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release &amp;amp;&amp;amp; echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 sudo dpkg -i /tmp/ros2-apt-source.deb&lt;br /&gt;
&lt;br /&gt;
 sudo apt update &amp;amp;&amp;amp; sudo apt install ros-dev-tools&lt;br /&gt;
&lt;br /&gt;
Install full ROS2 Jazzy&lt;br /&gt;
&lt;br /&gt;
 sudo apt install ros-jazzy-desktop&lt;br /&gt;
&lt;br /&gt;
Start in this ROS2 environment, now and in new terminals:&lt;br /&gt;
 source /opt/ros/jazzy/setup.bash&lt;br /&gt;
 echo &amp;quot;source /opt/ros/jazzy/setup.bash&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
 export ROS_DOMAIN_ID=0&lt;br /&gt;
 echo &amp;quot;export ROS_DOMAIN_ID=0&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
Install ROS QT GUI stuff&lt;br /&gt;
 sudo apt install &#039;~nros-jazzy-rqt*&#039;&lt;br /&gt;
&lt;br /&gt;
=== Create workspace ===&lt;br /&gt;
&lt;br /&gt;
From https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/Colcon-Tutorial.html &lt;br /&gt;
&lt;br /&gt;
Install colcon&lt;br /&gt;
 sudo apt install python3-colcon-common-extensions&lt;br /&gt;
&lt;br /&gt;
Create workspace directory&lt;br /&gt;
 mkdir -p ~/ros2_ws/src&lt;br /&gt;
 cd ~/ros2_ws&lt;br /&gt;
&lt;br /&gt;
From within this directory clone (any) standard package&lt;br /&gt;
&lt;br /&gt;
e.g. tutorial examples&lt;br /&gt;
 git clone https://github.com/ros2/examples src/examples -b jazzy&lt;br /&gt;
&lt;br /&gt;
Build the examples; this is memory and CPU-hungry, so the option &#039;&#039;--executor sequential&#039;&#039; may come in handy, especially on a Raspberry Pi, but it will take significantly longer.&lt;br /&gt;
 colcon build --symlink-install --executor sequential&lt;br /&gt;
&lt;br /&gt;
Allow use of colcon_cd&lt;br /&gt;
 echo &amp;quot;source /usr/share/colcon_cd/function/colcon_cd.sh&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
 echo &amp;quot;export _colcon_cd_root=/opt/ros/jazzy/&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
To use the &#039;&#039;mixin&#039;&#039; shortcut for some colcon options, add:&lt;br /&gt;
 colcon mixin add default https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml&lt;br /&gt;
 colcon mixin update default&lt;br /&gt;
&lt;br /&gt;
=== MQTT client ===&lt;br /&gt;
&lt;br /&gt;
The un-modified &#039;&#039;mqtt_client&#039;&#039; package can act as a bridge between the &#039;&#039;teensy_interface&#039;&#039; and the ROS domain.&lt;br /&gt;
&lt;br /&gt;
From MQTT to ROS, the translation is using the primitive ROS type &#039;&#039;string&#039;&#039; for the parameters of the &#039;&#039;teensy_interface&#039;&#039; messages. &lt;br /&gt;
The MQTT topic name is translated to ROS topic names as specified in the parameter file below.&lt;br /&gt;
&lt;br /&gt;
From ROS to Teensy, the message should be published on a topic that matches the desired destination.&lt;br /&gt;
Topics for command messages to the &#039;&#039;teensy_interface&#039;&#039;:&lt;br /&gt;
* MQTT topic ricbot/cmd/T0 for the Teensy, the message is the string to send to the Teensy.&lt;br /&gt;
* MQTT topic ricbot/cmd/shutdown to schedule a shutdown of the RICBOT (power off), something like 20 seconds after the message.&lt;br /&gt;
* MQTT topic ricbot/cmd/ti for messages to the teensy_interface, the message is a string.&lt;br /&gt;
&lt;br /&gt;
==== Install ====&lt;br /&gt;
&lt;br /&gt;
The robot&#039;s interface is via MQTT. Install the MQTT ROS client&lt;br /&gt;
 sudo apt install ros-jazzy-mqtt-client&lt;br /&gt;
&lt;br /&gt;
Or directly as source&lt;br /&gt;
 cd src&lt;br /&gt;
 git clone https://github.com/ika-rwth-aachen/mqtt_client&lt;br /&gt;
 &lt;br /&gt;
Compile:&lt;br /&gt;
 cd ~/ros2_ws&lt;br /&gt;
 colcon build&lt;br /&gt;
&lt;br /&gt;
==== Run MQTT_client ====&lt;br /&gt;
&lt;br /&gt;
To start the &#039;&#039;mqtt_client&#039;&#039;:&lt;br /&gt;
 cd ros2_ws/src/mqtt_client/mqtt_client/config&lt;br /&gt;
 ros2 launch mqtt_client standalone.launch.xml params_file:=&amp;quot;params.teensy.yaml&amp;quot;&lt;br /&gt;
The parameter file should be extended with more &#039;&#039;mqtt2ros&#039;&#039; topics as needed.&lt;br /&gt;
&lt;br /&gt;
This will launch the un-modified &#039;&#039;mqtt_client&#039;&#039; node with specific bridge parameters as specified in &#039;&#039;params.teensy.yaml&#039;&#039;:&lt;br /&gt;
 /**/*:&lt;br /&gt;
  ros__parameters:&lt;br /&gt;
    broker:&lt;br /&gt;
      host: localhost&lt;br /&gt;
      port: 1883&lt;br /&gt;
      tls:&lt;br /&gt;
        enabled: false&lt;br /&gt;
    client:&lt;br /&gt;
      id: ros&lt;br /&gt;
      clean_session: true&lt;br /&gt;
      keep_alive_interval: 20.0&lt;br /&gt;
    bridge:&lt;br /&gt;
      ros2mqtt:&lt;br /&gt;
        ros_topics: &lt;br /&gt;
          - /teensy/cmd/T0&lt;br /&gt;
          - /teensy/cmd/shutdown&lt;br /&gt;
          - /teensy/cmd/ti&lt;br /&gt;
        /teensy/cmd/T0:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/T0&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
        /teensy/cmd/shutdown:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/shutdown&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
        /teensy/cmd/ti:&lt;br /&gt;
          mqtt_topic: ricbot/cmd/ti&lt;br /&gt;
          primitive: true&lt;br /&gt;
          inject_timestamp: false&lt;br /&gt;
      mqtt2ros:&lt;br /&gt;
        # Needs to be expanded to relevant topics&lt;br /&gt;
        mqtt_topics: &lt;br /&gt;
          - ricbot/data/T0/info&lt;br /&gt;
          - ricbot/data/T0/hbt&lt;br /&gt;
        ricbot/data/T0/info:&lt;br /&gt;
          ros_topic: /teensy/T0/info&lt;br /&gt;
          primitive: true&lt;br /&gt;
        ricbot/data/T0/hbt:&lt;br /&gt;
          ros_topic: /teensy/T0/hbt&lt;br /&gt;
          primitive: true&lt;br /&gt;
&lt;br /&gt;
=== Test interface ===&lt;br /&gt;
&lt;br /&gt;
Start the &#039;&#039;teensy_interface&#039;&#039; with the right ini-file:&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build&lt;br /&gt;
 ./teensy_interface -z ricbot.ini&lt;br /&gt;
&lt;br /&gt;
This should respond with something like:&lt;br /&gt;
 $ ./teensy_interface -z ricbot.ini&lt;br /&gt;
 # UService:: created directory log_20260118_083120.745/&lt;br /&gt;
 # UMqtt:: connection to MQTT broker on tcp://localhost:1883 established&lt;br /&gt;
 # UMqttIn:: connection to MQTT broker on tcp://localhost:1883 established&lt;br /&gt;
 # STeensy:: opening to USB /dev/ttyACM0&lt;br /&gt;
 # SRobot:: (t0) found IP 0: eno1 192.168.2.157&lt;br /&gt;
 # STeensy:: just connected &lt;br /&gt;
 # UService:: setup of Teensy 0 modules finished OK.&lt;br /&gt;
 # Type quit to stop, or &#039;h&#039; for help&lt;br /&gt;
&lt;br /&gt;
Start the &#039;&#039;mqtt_client&#039;&#039; in ROS&lt;br /&gt;
 cd ~/svn/ricbot/ros_config&lt;br /&gt;
 ros2 launch mqtt_client standalone.launch.xml params_file:=&amp;quot;params.teensy.yaml&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== From MQTT to ROS ====&lt;br /&gt;
&lt;br /&gt;
There should now be &#039;&#039;hbt&#039;&#039; (heartbeat) message on the ROS side:&lt;br /&gt;
 ros2 topic echo /teensy/T0/hbt&lt;br /&gt;
&lt;br /&gt;
This should give something like:&lt;br /&gt;
 data: &#039;1768722645.7425 1738.4885 93 1748 4.85 0 9 18.1 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
 data: &#039;1768722646.2426 1738.9885 93 1748 4.85 0 9 18.0 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
 data: &#039;1768722646.7431 1739.4885 93 1748 4.85 0 9 18.0 0 0&lt;br /&gt;
   &#039;&lt;br /&gt;
 ---&lt;br /&gt;
&lt;br /&gt;
The data is: timestamp (host), timestamp Teensy, Teensy ID, version, battery voltage, ... (the rest depend on the platform).&lt;br /&gt;
&lt;br /&gt;
==== From ROS to MQTT ====&lt;br /&gt;
&lt;br /&gt;
e.g. make the robot drive with velocity 0.25m/s and turn 0.1 rad/s CCV, followed by stop:&lt;br /&gt;
&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/ti std_msgs/String &#039;data: rc 0.25 0.1&#039;&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/ti std_msgs/String &#039;data: rc 0 0&#039;&lt;br /&gt;
&lt;br /&gt;
Or send a request to publish gyro data every 12ms:&lt;br /&gt;
&lt;br /&gt;
 ros2 topic pub /ricbot/cmd/T0 std_msgs/String &#039;data: sub gyro 12&#039;&lt;br /&gt;
&lt;br /&gt;
== (RIC_pkg) HW sensor translate package ==&lt;br /&gt;
&lt;br /&gt;
Create the package in the workspace.&lt;br /&gt;
&lt;br /&gt;
 cd ~/ros2_ws/src&lt;br /&gt;
 ros2 pkg create --build-type ament_cmake --license MIT --node-name ric_node ric_pkg&lt;br /&gt;
&lt;br /&gt;
Add dependencies to other packages to CMakeLists.txt.&lt;br /&gt;
Add to the list of &#039;&#039;find_package&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 find_package(rclcpp REQUIRED)&lt;br /&gt;
 find_package(std_msgs REQUIRED)&lt;br /&gt;
 find_package(nav_msgs REQUIRED)&lt;br /&gt;
 find_package(sensor_msgs REQUIRED)&lt;br /&gt;
 find_package(geometry_msgs REQUIRED)&lt;br /&gt;
&lt;br /&gt;
Make target dependencies available in the include path (and elsewhere as needed).&lt;br /&gt;
&lt;br /&gt;
Add this after the &#039;&#039;add_executable&#039;&#039;&lt;br /&gt;
 ament_target_dependencies(talker rclcpp std_msgs nav_msgs sensor_msgs geometry_msgs)&lt;br /&gt;
&lt;br /&gt;
To the package description &#039;&#039;package.xml&#039;&#039; add dependencies:&lt;br /&gt;
&lt;br /&gt;
Add just after the &#039;&#039;buildtool_depend&#039;&#039; section:&lt;br /&gt;
 &amp;lt;depend&amp;gt;rclcpp&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;std_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;nav_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;sensor_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
 &amp;lt;depend&amp;gt;geometry_msgs&amp;lt;/depend&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RIC_node code ===&lt;br /&gt;
&lt;br /&gt;
The code in &#039;&#039;ris_node.cpp&#039;&#039; is pt this (not functional yet):&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;cstdio&amp;gt;&lt;br /&gt;
 #include &amp;lt;chrono&amp;gt;&lt;br /&gt;
 #include &amp;lt;memory&amp;gt;&lt;br /&gt;
 #include &amp;lt;string&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
 #include &amp;quot;rclcpp/rclcpp.hpp&amp;quot;&lt;br /&gt;
 #include &amp;quot;std_msgs/msg/string.hpp&amp;quot;&lt;br /&gt;
 #include &amp;quot;std_msgs/msg/int32.hpp&amp;quot;&lt;br /&gt;
 #include &amp;lt;nav_msgs/msg/odometry.hpp&amp;gt;&lt;br /&gt;
 #include &amp;quot;geometry_msgs/msg/twist.hpp&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 class RIC_translator : public rclcpp::Node&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
  RIC_translator()&lt;br /&gt;
  : Node(&amp;quot;minimal_publisher&amp;quot;), count(0)&lt;br /&gt;
  {&lt;br /&gt;
    publisher_ = this-&amp;gt;create_publisher&amp;lt;std_msgs::msg::String&amp;gt;(&amp;quot;/ric/hbt&amp;quot;, 10);&lt;br /&gt;
    //&lt;br /&gt;
    // Heartbeat&lt;br /&gt;
    auto topic_callback =&lt;br /&gt;
    [this](std_msgs::msg::String::UniquePtr msg) -&amp;gt; void {&lt;br /&gt;
      // RCLCPP_INFO(this-&amp;gt;get_logger(), &amp;quot;I heard: hbt &#039;%s&#039;&amp;quot;, msg-&amp;gt;data.c_str());&lt;br /&gt;
      // strncpy(hbtParams, msg-&amp;gt;data.c_str(), 100);&lt;br /&gt;
      printHbt(msg-&amp;gt;data.c_str());&lt;br /&gt;
    };&lt;br /&gt;
    subsHbt =&lt;br /&gt;
    this-&amp;gt;create_subscription&amp;lt;std_msgs::msg::String&amp;gt;(&amp;quot;/teensy/T0/hbt&amp;quot;, 10, topic_callback);&lt;br /&gt;
  }&lt;br /&gt;
 private:&lt;br /&gt;
  rclcpp::TimerBase::SharedPtr timer_;&lt;br /&gt;
  rclcpp::Publisher&amp;lt;std_msgs::msg::String&amp;gt;::SharedPtr publisher_;&lt;br /&gt;
  rclcpp::Publisher&amp;lt;std_msgs::msg::Int32&amp;gt;::SharedPtr odo_;&lt;br /&gt;
  size_t count;&lt;br /&gt;
  //&lt;br /&gt;
  char hbtParams[100] = &amp;quot;&amp;quot;;&lt;br /&gt;
  rclcpp::Subscription&amp;lt;std_msgs::msg::String&amp;gt;::SharedPtr subsHbt;&lt;br /&gt;
  void printHbt(const char * msg)&lt;br /&gt;
  {&lt;br /&gt;
    printf(&amp;quot;# %lu got hbt %s&amp;quot;, count, msg);&lt;br /&gt;
    snprintf(hbtParams, 100, &amp;quot;Hello RIC %lu %s&amp;quot;, count++, msg);&lt;br /&gt;
    auto message = std_msgs::msg::String();&lt;br /&gt;
    message.set__data(hbtParams);&lt;br /&gt;
    this-&amp;gt;publisher_-&amp;gt;publish(message);&lt;br /&gt;
  }&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char ** argv)&lt;br /&gt;
 {&lt;br /&gt;
  rclcpp::init(argc, argv);&lt;br /&gt;
  rclcpp::spin(std::make_shared&amp;lt;RIC_translator&amp;gt;());&lt;br /&gt;
  rclcpp::shutdown();&lt;br /&gt;
  return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Run RIC_node ===&lt;br /&gt;
&lt;br /&gt;
Compile (from workspace)&lt;br /&gt;
 colcon build --packages-select ric_pkg&lt;br /&gt;
 &lt;br /&gt;
Then add it to the path&lt;br /&gt;
 source install/setup.bash&lt;br /&gt;
&lt;br /&gt;
and run&lt;br /&gt;
 ros2 run ric_pkg ric_node&lt;br /&gt;
&lt;br /&gt;
If the &#039;&#039;teensy_interface&#039;&#039; and the &#039;&#039;mqtt-client&#039;&#039; are also running, then (with the code above), it should print something like this on the console.&lt;br /&gt;
 # 0 got hbt 1769340959.8623 13504.9463 105 1033 15.65 4 8 8.9 0.27 0&lt;br /&gt;
 # 1 got hbt 1769340960.3625 13505.4463 105 1033 15.65 4 8 8.8 0.28 0&lt;br /&gt;
 # 2 got hbt 1769340960.8626 13505.9453 105 1033 15.65 4 8 8.8 0.27 0&lt;br /&gt;
 # 3 got hbt 1769340961.3622 13506.4463 105 1033 15.65 4 8 8.9 0.28 0&lt;br /&gt;
 # 4 got hbt 1769340961.8625 13506.9463 105 1033 15.65 4 8 8.9 0.25 0&lt;br /&gt;
 # 5 got hbt 1769340962.3631 13507.4453 105 1033 15.66 4 8 8.9 0.26 0&lt;br /&gt;
 # 6 got hbt 1769340962.8624 13507.9463 105 1033 15.63 4 8 8.8 0.26 0&lt;br /&gt;
&lt;br /&gt;
=== Ros2 relevant messages ===&lt;br /&gt;
&lt;br /&gt;
One of the messages are probably &#039;&#039;twist&#039;&#039;:&lt;br /&gt;
 ros2 interface show geometry_msgs/msg/Twist&lt;br /&gt;
 # This expresses velocity in free space broken into its linear and angular parts.&lt;br /&gt;
 Vector3  linear&lt;br /&gt;
        float64 x&lt;br /&gt;
        float64 y&lt;br /&gt;
        float64 z&lt;br /&gt;
 Vector3  angular&lt;br /&gt;
        float64 x&lt;br /&gt;
        float64 y&lt;br /&gt;
        float64 z&lt;br /&gt;
&lt;br /&gt;
=== Where from here ===&lt;br /&gt;
&lt;br /&gt;
Search for tutorials in https://docs.ros.org/en/jazzy/&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robot_dashboard&amp;diff=8678</id>
		<title>Robot dashboard</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robot_dashboard&amp;diff=8678"/>
		<updated>2026-02-25T09:37:23Z</updated>

		<summary type="html">&lt;p&gt;Jca: Created page with &amp;quot;   == Introduction ==  This is intro.  * bullit list   then it is code   500px  Figur 1&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro.&lt;br /&gt;
&lt;br /&gt;
* bullit list&lt;br /&gt;
&lt;br /&gt;
 then it is code&lt;br /&gt;
&lt;br /&gt;
[[file: billede.png | 500px]]&lt;br /&gt;
&lt;br /&gt;
Figur 1&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Main_Page&amp;diff=8677</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Main_Page&amp;diff=8677"/>
		<updated>2026-02-25T09:35:15Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Robots */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the wiki pages of the Robot Systems Engineering (RSE) group in Automation and Control at DTU Electrical Engineering.&lt;br /&gt;
&lt;br /&gt;
These pages will contain updated information on RSE projects and other issues related to robotics research.&lt;br /&gt;
&lt;br /&gt;
= Facilities =&lt;br /&gt;
&lt;br /&gt;
* [[ASTA|Autonomous System Testing Arena (ASTA)]]&lt;br /&gt;
&lt;br /&gt;
* [[ASTA motion capture|Motion capture (Optitrack)]]&lt;br /&gt;
&lt;br /&gt;
* [[uASTA|μASTA]]&lt;br /&gt;
&lt;br /&gt;
* [[Lipo Safety | Lipo safety]]&lt;br /&gt;
&lt;br /&gt;
* [[Workshop]]&lt;br /&gt;
&lt;br /&gt;
= Robots =&lt;br /&gt;
&lt;br /&gt;
[[SMR]] (Small Mobile Robot)&lt;br /&gt;
&lt;br /&gt;
[[UR5]] (Universal Robot UR5 Arm)&lt;br /&gt;
&lt;br /&gt;
[[UR10]] (Universal Robot UR10 Arm)&lt;br /&gt;
&lt;br /&gt;
[[Fieldrobot]] (Fieldrobot)&lt;br /&gt;
&lt;br /&gt;
[[iRobot ATRV-Jr]]&lt;br /&gt;
&lt;br /&gt;
[[TerrainHopper]]&lt;br /&gt;
&lt;br /&gt;
[[regbot | Regbot]] (small robot intended as control-1 exercise)&lt;br /&gt;
&lt;br /&gt;
[[Basebot]] is the base version of Regbot for digital control exercises.&lt;br /&gt;
&lt;br /&gt;
[[robobot B | Robobot]] A small 4-wheel robot for DTU Robocup.&lt;br /&gt;
&lt;br /&gt;
[[SimServer]] Stage-based multi-robot simulator&lt;br /&gt;
&lt;br /&gt;
[[Fejemis]] autonomous cleaning&lt;br /&gt;
&lt;br /&gt;
[[Capra]] P5&lt;br /&gt;
&lt;br /&gt;
[[Scorpi]] crane robot.&lt;br /&gt;
&lt;br /&gt;
[[Lanciers]] demo robots.&lt;br /&gt;
&lt;br /&gt;
[[Ricbot]] Wheeled sensor platform for weed detection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other projects===&lt;br /&gt;
&lt;br /&gt;
[[Robot dashboard]] - igangværende projekt.&lt;br /&gt;
&lt;br /&gt;
[[Weather monitor]], also including the GNSS &#039;weather&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Claas axion]] (Semi-autonomous heavy tractor)&lt;br /&gt;
&lt;br /&gt;
[[Mini40 force/torque sensor]]&lt;br /&gt;
&lt;br /&gt;
[[Robotiq gripper]]&lt;br /&gt;
&lt;br /&gt;
[[Visual Tracking on Pixhawk]] (Position estimation of Pixhawk flight controller with external camera)&lt;br /&gt;
&lt;br /&gt;
[[3D localization]] based on sensor network&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- [[Magnetic Navigation]] sensor --&amp;gt;&lt;br /&gt;
&amp;lt;!-- [[robocup]] --&amp;gt;&lt;br /&gt;
[[inspection robot]] (4/6-legged robot)&lt;br /&gt;
&amp;lt;!-- [[3D printer]] Zortrax M300 --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Mobotware =&lt;br /&gt;
&lt;br /&gt;
(Mobile Robot software)&lt;br /&gt;
&lt;br /&gt;
* [[AU Robot Servers]] (AURS) includes servers for soft real-time processing, e.g.: camera and laser scanner processing.&lt;br /&gt;
&lt;br /&gt;
* [[RHD]] (Robot Hardware Daemon) is the hardware abstraction layer, with interface to real-time sensors and actuators.&lt;br /&gt;
&lt;br /&gt;
* MRC - see SMR below - is the real-time movement control (and mission control using the SMR-CL language)&lt;br /&gt;
&lt;br /&gt;
[[Version and download]]&lt;br /&gt;
&lt;br /&gt;
[[Automated test setup]]&lt;br /&gt;
&lt;br /&gt;
= Linux system considerations =&lt;br /&gt;
&lt;br /&gt;
[[Switchtool]] - Shift Mobotware version - earlier, newer or the one locally on the robots&lt;br /&gt;
&lt;br /&gt;
[[Rules for udev on RTAI]] (How to use udev rules to get correct modes for RTAI fifos and Comedi devices)&lt;br /&gt;
&lt;br /&gt;
[[Naming networkinterfaces using udev]]&lt;br /&gt;
&lt;br /&gt;
[[Setting permissions for various devices using udev]]&lt;br /&gt;
&lt;br /&gt;
[[Authenticating Linux clients against MS Active Directory]]&lt;br /&gt;
&lt;br /&gt;
[[Using GDB for coredump]]&lt;br /&gt;
&lt;br /&gt;
====Older pages====&lt;br /&gt;
&lt;br /&gt;
These pages are no longer relevant.&lt;br /&gt;
&lt;br /&gt;
[[Labyrinth]] (Labyrinth game)&lt;br /&gt;
&lt;br /&gt;
[[Drone control]] drone base control &lt;br /&gt;
&lt;br /&gt;
[[DTU running path dataset]]&lt;br /&gt;
&lt;br /&gt;
[[flexbot]] design work to get a flexible stair climbing robot&lt;br /&gt;
&lt;br /&gt;
[[Ubuntu 32-bit or 64-bit]]&lt;br /&gt;
&lt;br /&gt;
[[Slackware OpenCV package install]]&lt;br /&gt;
&lt;br /&gt;
[[Slackware packages in robot image]]&lt;br /&gt;
&lt;br /&gt;
[[MMR]] (Medium Mobile Robot)&lt;br /&gt;
&lt;br /&gt;
[[HAKO]] (KU Life tractor, now in Hohenheim University Germany)&lt;br /&gt;
&lt;br /&gt;
[[hexakopter]] (notes for six-rotor helicopter including the pixhawk autopilot)&lt;br /&gt;
&lt;br /&gt;
= Controllab =&lt;br /&gt;
&lt;br /&gt;
[[Platform list]] (List of computers used for various control set-ups)&lt;br /&gt;
&lt;br /&gt;
[[Realtime testing]] (Description of small test procedures to verify RTAI realtime operation)&lt;br /&gt;
&lt;br /&gt;
[http://aut.elektro.dtu.dk/staff/sh/rsewiki/matlabrtai_intro.pdf Introduction to Matlab RTW and RTAI] (Guide for usage of RTAILab with Matlab RTW and Simulink)&lt;br /&gt;
&lt;br /&gt;
= How-to documentation =&lt;br /&gt;
&lt;br /&gt;
====installation====&lt;br /&gt;
&lt;br /&gt;
[[NTP howto]] time-sync 2 computers&lt;br /&gt;
&lt;br /&gt;
Using the [[RSE SVN]] repository&lt;br /&gt;
&lt;br /&gt;
[[Flash disk cloning]] - to repair robot boot disk image&lt;br /&gt;
&lt;br /&gt;
[[Install on (K)UBUNTU]] - for test and development on PC or laptop&lt;br /&gt;
&lt;br /&gt;
[[Install on raspberry]] - install Mobotware on raspbian (NOOBS) or a Debian based Linux on Beagle-bone.&lt;br /&gt;
&lt;br /&gt;
[[Install Universal Robots simulator on lab PC]]&lt;br /&gt;
&lt;br /&gt;
[[Remote Development of Mobotware Using Eclipse]]&lt;br /&gt;
&lt;br /&gt;
[[Set hostnames from dhcp-server with dhclient on *buntu systems]]&lt;br /&gt;
&lt;br /&gt;
[[Notes on compiling augclient]] - GUI interface for Mobotware used fx. in AGCO project&lt;br /&gt;
&lt;br /&gt;
====utility pages====&lt;br /&gt;
&lt;br /&gt;
[[Convert a .tex document to openoffice]]&lt;br /&gt;
&lt;br /&gt;
[[Access DTU campus network using VPN from Linux]]&lt;br /&gt;
&lt;br /&gt;
[[disable display manager on boot]] (and thereby the graphic user interface)&lt;br /&gt;
&lt;br /&gt;
[[How to make a animation from separate images]]&lt;br /&gt;
&lt;br /&gt;
[[Citrix access to DTU files and Windows Apps]]  (Using Citrix Receiver, preferred way from 2015+)&lt;br /&gt;
&lt;br /&gt;
[[Latex]] where to put document class files in ubuntu installation&lt;br /&gt;
&lt;br /&gt;
[[file export]] testpage for export of files&lt;br /&gt;
&lt;br /&gt;
====older pages====&lt;br /&gt;
&lt;br /&gt;
[[RoboCup]] - bl.a. scoreboard - not maintained&lt;br /&gt;
&lt;br /&gt;
[[AU software license considerations]]&lt;br /&gt;
&lt;br /&gt;
[[Robot GUI (MARG)]] - (no longer maintained)&lt;br /&gt;
&lt;br /&gt;
[[Install GUI-less UBUNTU]] - new boot disk image for robots&lt;br /&gt;
&lt;br /&gt;
= Demonstrations =&lt;br /&gt;
&lt;br /&gt;
[[PLC controlled traffic light]]&lt;br /&gt;
&lt;br /&gt;
[[Machine shop in 326]]&lt;br /&gt;
&lt;br /&gt;
[[Inverted pendulum]]&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Network_setup&amp;diff=8676</id>
		<title>Network setup</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Network_setup&amp;diff=8676"/>
		<updated>2026-02-10T08:48:10Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Using static IP and DNS server on Raspberry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot B]]&lt;br /&gt;
&lt;br /&gt;
==WiFi network==&lt;br /&gt;
&lt;br /&gt;
If you are at DTU and the small display shows an IP, then all is fine. Otherwise read further down.&lt;br /&gt;
&lt;br /&gt;
====Network Manager====&lt;br /&gt;
&lt;br /&gt;
The NetworkManager uses device UUID as part of the Wi-Fi network setup. This means that (sometimes) an SD card can not be moved from one robot to another with a functional Wi-Fi connection.&lt;br /&gt;
&lt;br /&gt;
After 20 seconds, an attempt to solve this is activated using the commands below (the code is found in svn/robobot/setup/rename_host.bash - last half).&lt;br /&gt;
&lt;br /&gt;
Use the last line to setup manually - or the GUI, if available.&lt;br /&gt;
&lt;br /&gt;
See the current network settings&lt;br /&gt;
 nmcli dev show&lt;br /&gt;
Network manager connection with UUID&lt;br /&gt;
 nmcli connection&lt;br /&gt;
List available wifi access points&lt;br /&gt;
 nmcli dev wifi&lt;br /&gt;
&lt;br /&gt;
==== Connect to DTUdevice net ====&lt;br /&gt;
&lt;br /&gt;
You can establish a new connection from the command line&lt;br /&gt;
 sudo nmcli device wifi connect DTUdevice password &amp;lt;password&amp;gt; ifname wlan0 ipv6.method &amp;quot;disabled&amp;quot;&lt;br /&gt;
This should create a new system-connection file with a usable UUID.&lt;br /&gt;
IPv6 is disabled because many of the IPv6 MACs appear to be the same (we cloned the SD card), and this will blacklist the connection for MAC address theft.&lt;br /&gt;
&lt;br /&gt;
There is a terminal-based user interface to edit a connection. First list connections:&lt;br /&gt;
 $ nmcli con show&lt;br /&gt;
 eg: NAME            UUID                                  TYPE      DEVICE &lt;br /&gt;
 preconfigured       e07a0ae8-028b-4d65-806c-ec63f435df44  wifi      wlan0  &lt;br /&gt;
 lo                  2737bad6-956f-4668-99e0-4697f4ec30a7  loopback  lo &lt;br /&gt;
Find the NAME of the connection to edit, e.g. &#039;preconfigured&#039;&lt;br /&gt;
 sudo nmtui edit &amp;quot;preconfigured&amp;quot;&lt;br /&gt;
Then edit as desired.&lt;br /&gt;
&lt;br /&gt;
Reload Network Manager to read this.&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection reload&lt;br /&gt;
&lt;br /&gt;
or restart the NetworkManager&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl restart NetworkManager.service&lt;br /&gt;
&lt;br /&gt;
==== Home network connection ====&lt;br /&gt;
&lt;br /&gt;
If you know the SSID and password, you can prepare the robot for another (home) network.&lt;br /&gt;
Use this command (replacing &amp;lt;SSID&amp;gt; and &amp;lt;password&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli device wifi connect &amp;lt;SSID&amp;gt; password &amp;lt;password&amp;gt; ifname wlan0&lt;br /&gt;
&lt;br /&gt;
If you have no network contact, then use a local link (cable) or attach a screen and keyboard.&lt;br /&gt;
&lt;br /&gt;
== Cable connection ==&lt;br /&gt;
&lt;br /&gt;
==== Using static IP and DNS server on Raspberry ====&lt;br /&gt;
&lt;br /&gt;
Assign a static IP for the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add con-name eth0-manual ifname eth0 type ethernet ip4 192.168.7.7/24 ipv6.method disabled&lt;br /&gt;
&lt;br /&gt;
The Raspberry&#039;s IP address is 192.168.7.7 when a cable is connected. The Network Manager may need to be reloaded.&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli con reload&lt;br /&gt;
&lt;br /&gt;
Your PC on the other end then needs to be assigned a static (manual) IP address in the same network, e.g., 192.168.7.22.&lt;br /&gt;
&lt;br /&gt;
The response time on the cable is much faster than over wifi. Typically less than 0.5ms on cable and often more than 5ms on wifi. Try ping from your PC:&lt;br /&gt;
&lt;br /&gt;
 ping 192.168.7.7&lt;br /&gt;
&lt;br /&gt;
==== Alternative ====&lt;br /&gt;
&lt;br /&gt;
I found this method (Google AI) to use DHCP with higher priority, and then static IP if DHCP fails&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add type ethernet con-name &amp;quot;Wired-DHCP&amp;quot; ifname eth0 ipv4.method auto autoconnect yes connect.autoconnect-priority 1&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add type ethernet con-name &amp;quot;Robobot-Static7&amp;quot; ifname eth0 ipv4.method manual ipv4.addresses 192.168.7.7/24 ipv4.gateway 192.168.7.1 ipv4.dns 8.8.8.8 autoconnect yes connect.autoconnect-priority 0&lt;br /&gt;
&lt;br /&gt;
This creates 2 entries in /etc/NetworkManager/system-connections (on a default Raspberry Pi 64 Bit OS using Network Manager)&lt;br /&gt;
&lt;br /&gt;
/etc/NetworkManager/system-connections/Wired-DHCP.nmconnection&lt;br /&gt;
&lt;br /&gt;
 [connection]&lt;br /&gt;
 id=Wired-DHCP&lt;br /&gt;
 uuid=339844b1-cee4-4a43-a3f1-a5de05f3cb70&lt;br /&gt;
 type=ethernet&lt;br /&gt;
 autoconnect-priority=1&lt;br /&gt;
 interface-name=eth0&lt;br /&gt;
 &lt;br /&gt;
 [ethernet]&lt;br /&gt;
 &lt;br /&gt;
 [ipv4]&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [ipv6]&lt;br /&gt;
 addr-gen-mode=default&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [proxy]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note! the UUID should be different&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
/etc/NetworkManager/system-connections/Robobot-Static7.nmconnection&lt;br /&gt;
&lt;br /&gt;
 [connection]&lt;br /&gt;
 id=Robobot-Static7&lt;br /&gt;
 uuid=2a91ef05-3666-4293-a793-330c3b49cdd4&lt;br /&gt;
 type=ethernet&lt;br /&gt;
 interface-name=eth0&lt;br /&gt;
 &lt;br /&gt;
 [ethernet] &lt;br /&gt;
 &lt;br /&gt;
 [ipv4]&lt;br /&gt;
 address1=192.168.7.7/24,192.168.7.1&lt;br /&gt;
 dns=8.8.8.8;&lt;br /&gt;
 method=manual&lt;br /&gt;
 &lt;br /&gt;
 [ipv6]&lt;br /&gt;
 addr-gen-mode=default&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [proxy]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note2! To default to static IP can take 2-4 minutes after detecting the cable! (at least 2 times 60 second timeout is needed)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On your laptop you can do the same, but probably more efficient, set to manual IP v4.&lt;br /&gt;
This can be done using your GUI tools, or on Linux:&lt;br /&gt;
&lt;br /&gt;
 sudo ip eth0 192.168.7.22&lt;br /&gt;
&lt;br /&gt;
Note! &#039;&#039;eth0&#039;&#039; may be different, as modern hardware often has a more complex name, as &#039;&#039;eno1&#039;&#039; or &#039;&#039;enp108s0&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note2! If the robot has 192.168.7.7, then you should use something else for your laptop, e.g. 192.168.7.22.&lt;br /&gt;
&lt;br /&gt;
Then ssh to the robot&lt;br /&gt;
&lt;br /&gt;
 ssh local@192.168.7.7&lt;br /&gt;
&lt;br /&gt;
==== Install DNS server on Raspberry ====&lt;br /&gt;
&lt;br /&gt;
This section may be deprecated, use the alternative method above with fallback to static IP.&lt;br /&gt;
&lt;br /&gt;
Allow the connected PC to get an IP automatically; install DNSMASQ&lt;br /&gt;
&lt;br /&gt;
 sudo apt install dnsmasq&lt;br /&gt;
&lt;br /&gt;
Configure the use by editing /etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
Uncomment and change two lines. It is to be used on ETH0 only and in the IP range 192.168.7.50 to 192.168.7.99.&lt;br /&gt;
&lt;br /&gt;
 # DNS requests only on&lt;br /&gt;
 # specified interface&lt;br /&gt;
 interface=eth0&lt;br /&gt;
 # range of addresses available for lease and optionally&lt;br /&gt;
 # a lease time&lt;br /&gt;
 dhcp-range=192.168.7.50,192.168.7.99,255.255.255.0,12h&lt;br /&gt;
&lt;br /&gt;
Restart the dnsmasq&lt;br /&gt;
&lt;br /&gt;
 sudo service dnsmasq restart&lt;br /&gt;
&lt;br /&gt;
To see the status of the dnsmasq service use:&lt;br /&gt;
&lt;br /&gt;
 journalctl -b0 -u dnsmasq.service&lt;br /&gt;
&lt;br /&gt;
After this, when you plug in a cable to a PC, then, after some seconds, both the robot and the PC should have an IP in the range 192.168.7.x. And the robot should display the new IP 192.168.7.7.&lt;br /&gt;
&lt;br /&gt;
You can now access the robot using &lt;br /&gt;
 ssh local@192.168.7.7&lt;br /&gt;
&lt;br /&gt;
==== Local link ====&lt;br /&gt;
&lt;br /&gt;
Note: This method failed in most cases&lt;br /&gt;
&lt;br /&gt;
If wifi is too slow or unavailable, a local link using a network cable could be the solution.&lt;br /&gt;
&lt;br /&gt;
Many PCs will assign a local link IP like 168.254.x.x, and the Robot will do the same. The robot IP will be displayed on the small display but may be obscured if a Wi-Fi IP is available.&lt;br /&gt;
&lt;br /&gt;
To prepare this behaviour, log in to the Raspberry using wifi (or attach a screen and keyboard) and make a preferred local-link cabled connection:&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli con mod &amp;quot;Wired connection 1&amp;quot; ipv4.method link-local ipv6.method disabled&lt;br /&gt;
&lt;br /&gt;
This should then be the behaviour after a reboot. &amp;quot;Wired connection 1&amp;quot; needs to be spelt this way; see the valid names using:&lt;br /&gt;
&lt;br /&gt;
 nmcli connection&lt;br /&gt;
&lt;br /&gt;
Reload Network manager&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection reload&lt;br /&gt;
&lt;br /&gt;
== Check IP and SSID ==&lt;br /&gt;
&lt;br /&gt;
When the Pi has rebooted, connect to it using SSH once again. Check that the Pi is connected to WiFi&lt;br /&gt;
 ifconfig&lt;br /&gt;
Under &#039;&#039;&#039;wlan0&#039;&#039;&#039; confirm that the Pi has received an IP (inet addr) and note down the first three sections of the IP - they are most likely &#039;&#039;&#039;10.197.21x.xxx&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To see which SSID you are connected to, use&lt;br /&gt;
 iwconfig&lt;br /&gt;
or &lt;br /&gt;
 nmcli -o&lt;br /&gt;
&lt;br /&gt;
The MAC address (&#039;HWaddr&#039; or &#039;ether&#039;) of the Pi should also be noted down - this probably starts with &#039;&#039;&#039;B8:27:EB:xx:xx:xx&#039;&#039;&#039; make sure to get all of it.&lt;br /&gt;
&lt;br /&gt;
===Find IP of robot (Linux)===&lt;br /&gt;
&lt;br /&gt;
In case the Pi gets a new IP address after reboot, you can search for it using the MAC address and &#039;&#039;&#039;nmap&#039;&#039;&#039;. If &#039;&#039;&#039;nmap&#039;&#039;&#039; is not installed, start by installing it&lt;br /&gt;
 sudo apt-get install nmap&lt;br /&gt;
To search for the Pi using the MAC address in terminal type&lt;br /&gt;
 nmap -sP 10.197.218.0/20 | awk &#039;/^Nmap/{ip=$NF}/B8:27:EB:23:A0:F5/{print ip}&#039;&lt;br /&gt;
where &#039;&#039;&#039;10.197.218&#039;&#039;&#039; is the first three sections of the IP you noted down, 20 is the number of fixed bits (out of 32), and &#039;&#039;&#039;B8:27:EB:23:A0:F5&#039;&#039;&#039; is the MAC address of the Pi. This should return the IP of the Pi.&lt;br /&gt;
&lt;br /&gt;
NB! the MAC can hold letters, they should probably be capital.&lt;br /&gt;
&lt;br /&gt;
==== If you don&#039;t know the IP address====&lt;br /&gt;
&lt;br /&gt;
Use the first part to get a list of active IPs on the net:&lt;br /&gt;
  nmap -sP 10.197.218.0/24&lt;br /&gt;
&lt;br /&gt;
The robot&#039;s name should be included in the list, but the network may take a while to detect it.&lt;br /&gt;
&lt;br /&gt;
== NTP ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Depreciated&#039;&#039;&#039;. The Raspberry default time sync now works, also at DTU.&lt;br /&gt;
&lt;br /&gt;
Network Time Protocol is used to keep clocks in sync.&lt;br /&gt;
Raspberry Pi will start with the date and time of the last proper shutdown, and a few seconds after the network is up, it will sync the clock using NTP.&lt;br /&gt;
&lt;br /&gt;
NTP need to be installed, i.e. &#039;sudo apt install ntp&#039; if not done already.&lt;br /&gt;
&lt;br /&gt;
At DTU, most clock sources are blocked; the clock source needs to be configured.&lt;br /&gt;
&lt;br /&gt;
At DTU, edit /etc/NTP.conf or /etc/ntpsec/ntp.conf and add ntp.ait.du.dk to the top of the server pool list.&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/ntpsec/ntp.conf&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 # Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board&lt;br /&gt;
 # on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for&lt;br /&gt;
 # more information.&lt;br /&gt;
 pool ntp.ait.dtu.dk&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Sync time (if on DTU net)&lt;br /&gt;
&lt;br /&gt;
 sudo ntpdate -u ntp.ait.dtu.dk&lt;br /&gt;
&lt;br /&gt;
Should work in and around DTU - see also [[NTP howto]] for more details.&lt;br /&gt;
&lt;br /&gt;
You can also check the status of the ntp service:&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl status ntp.service&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Network_setup&amp;diff=8675</id>
		<title>Network setup</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Network_setup&amp;diff=8675"/>
		<updated>2026-02-10T08:46:18Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Cable connection */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot B]]&lt;br /&gt;
&lt;br /&gt;
==WiFi network==&lt;br /&gt;
&lt;br /&gt;
If you are at DTU and the small display shows an IP, then all is fine. Otherwise read further down.&lt;br /&gt;
&lt;br /&gt;
====Network Manager====&lt;br /&gt;
&lt;br /&gt;
The NetworkManager uses device UUID as part of the Wi-Fi network setup. This means that (sometimes) an SD card can not be moved from one robot to another with a functional Wi-Fi connection.&lt;br /&gt;
&lt;br /&gt;
After 20 seconds, an attempt to solve this is activated using the commands below (the code is found in svn/robobot/setup/rename_host.bash - last half).&lt;br /&gt;
&lt;br /&gt;
Use the last line to setup manually - or the GUI, if available.&lt;br /&gt;
&lt;br /&gt;
See the current network settings&lt;br /&gt;
 nmcli dev show&lt;br /&gt;
Network manager connection with UUID&lt;br /&gt;
 nmcli connection&lt;br /&gt;
List available wifi access points&lt;br /&gt;
 nmcli dev wifi&lt;br /&gt;
&lt;br /&gt;
==== Connect to DTUdevice net ====&lt;br /&gt;
&lt;br /&gt;
You can establish a new connection from the command line&lt;br /&gt;
 sudo nmcli device wifi connect DTUdevice password &amp;lt;password&amp;gt; ifname wlan0 ipv6.method &amp;quot;disabled&amp;quot;&lt;br /&gt;
This should create a new system-connection file with a usable UUID.&lt;br /&gt;
IPv6 is disabled because many of the IPv6 MACs appear to be the same (we cloned the SD card), and this will blacklist the connection for MAC address theft.&lt;br /&gt;
&lt;br /&gt;
There is a terminal-based user interface to edit a connection. First list connections:&lt;br /&gt;
 $ nmcli con show&lt;br /&gt;
 eg: NAME            UUID                                  TYPE      DEVICE &lt;br /&gt;
 preconfigured       e07a0ae8-028b-4d65-806c-ec63f435df44  wifi      wlan0  &lt;br /&gt;
 lo                  2737bad6-956f-4668-99e0-4697f4ec30a7  loopback  lo &lt;br /&gt;
Find the NAME of the connection to edit, e.g. &#039;preconfigured&#039;&lt;br /&gt;
 sudo nmtui edit &amp;quot;preconfigured&amp;quot;&lt;br /&gt;
Then edit as desired.&lt;br /&gt;
&lt;br /&gt;
Reload Network Manager to read this.&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection reload&lt;br /&gt;
&lt;br /&gt;
or restart the NetworkManager&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl restart NetworkManager.service&lt;br /&gt;
&lt;br /&gt;
==== Home network connection ====&lt;br /&gt;
&lt;br /&gt;
If you know the SSID and password, you can prepare the robot for another (home) network.&lt;br /&gt;
Use this command (replacing &amp;lt;SSID&amp;gt; and &amp;lt;password&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli device wifi connect &amp;lt;SSID&amp;gt; password &amp;lt;password&amp;gt; ifname wlan0&lt;br /&gt;
&lt;br /&gt;
If you have no network contact, then use a local link (cable) or attach a screen and keyboard.&lt;br /&gt;
&lt;br /&gt;
== Cable connection ==&lt;br /&gt;
&lt;br /&gt;
==== Using static IP and DNS server on Raspberry ====&lt;br /&gt;
&lt;br /&gt;
Assign a static IP for the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add con-name eth0-manual ifname eth0 type ethernet ip4 192.168.7.7/24 ipv6.method disabled&lt;br /&gt;
&lt;br /&gt;
The Raspberry&#039;s IP address is 192.168.7.7 when a cable is connected. The Network Manager may need to be reloaded.&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli con reload&lt;br /&gt;
&lt;br /&gt;
Your PC on the other end then needs to be assigned a static (manual) IP address in the same network, e.g., 192.168.7.8.&lt;br /&gt;
&lt;br /&gt;
The response time on the cable is much faster than over wifi. Typically less than 0.5ms on cable and often more than 5ms on wifi. Try ping from your PC:&lt;br /&gt;
&lt;br /&gt;
 ping 192.168.7.7&lt;br /&gt;
&lt;br /&gt;
==== Alternative ====&lt;br /&gt;
&lt;br /&gt;
I found this method (Google AI) to use DHCP with higher priority, and then static IP if DHCP fails&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add type ethernet con-name &amp;quot;Wired-DHCP&amp;quot; ifname eth0 ipv4.method auto autoconnect yes connect.autoconnect-priority 1&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add type ethernet con-name &amp;quot;Robobot-Static7&amp;quot; ifname eth0 ipv4.method manual ipv4.addresses 192.168.7.7/24 ipv4.gateway 192.168.7.1 ipv4.dns 8.8.8.8 autoconnect yes connect.autoconnect-priority 0&lt;br /&gt;
&lt;br /&gt;
This creates 2 entries in /etc/NetworkManager/system-connections (on a default Raspberry Pi 64 Bit OS using Network Manager)&lt;br /&gt;
&lt;br /&gt;
/etc/NetworkManager/system-connections/Wired-DHCP.nmconnection&lt;br /&gt;
&lt;br /&gt;
 [connection]&lt;br /&gt;
 id=Wired-DHCP&lt;br /&gt;
 uuid=339844b1-cee4-4a43-a3f1-a5de05f3cb70&lt;br /&gt;
 type=ethernet&lt;br /&gt;
 autoconnect-priority=1&lt;br /&gt;
 interface-name=eth0&lt;br /&gt;
 &lt;br /&gt;
 [ethernet]&lt;br /&gt;
 &lt;br /&gt;
 [ipv4]&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [ipv6]&lt;br /&gt;
 addr-gen-mode=default&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [proxy]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note! the UUID should be different&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
/etc/NetworkManager/system-connections/Robobot-Static7.nmconnection&lt;br /&gt;
&lt;br /&gt;
 [connection]&lt;br /&gt;
 id=Robobot-Static7&lt;br /&gt;
 uuid=2a91ef05-3666-4293-a793-330c3b49cdd4&lt;br /&gt;
 type=ethernet&lt;br /&gt;
 interface-name=eth0&lt;br /&gt;
 &lt;br /&gt;
 [ethernet] &lt;br /&gt;
 &lt;br /&gt;
 [ipv4]&lt;br /&gt;
 address1=192.168.7.7/24,192.168.7.1&lt;br /&gt;
 dns=8.8.8.8;&lt;br /&gt;
 method=manual&lt;br /&gt;
 &lt;br /&gt;
 [ipv6]&lt;br /&gt;
 addr-gen-mode=default&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [proxy]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note2! To default to static IP can take 2-4 minutes after detecting the cable! (at least 2 times 60 second timeout is needed)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On your laptop you can do the same, but probably more efficient, set to manual IP v4.&lt;br /&gt;
This can be done using your GUI tools, or on Linux:&lt;br /&gt;
&lt;br /&gt;
 sudo ip eth0 192.168.7.22&lt;br /&gt;
&lt;br /&gt;
Note! &#039;&#039;eth0&#039;&#039; may be different, as modern hardware often has a more complex name, as &#039;&#039;eno1&#039;&#039; or &#039;&#039;enp108s0&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note2! If the robot has 192.168.7.7, then you should use something else for your laptop, e.g. 192.168.7.22.&lt;br /&gt;
&lt;br /&gt;
Then ssh to the robot&lt;br /&gt;
&lt;br /&gt;
 ssh local@192.168.7.7&lt;br /&gt;
&lt;br /&gt;
==== Install DNS server on Raspberry ====&lt;br /&gt;
&lt;br /&gt;
This section may be deprecated, use the alternative method above with fallback to static IP.&lt;br /&gt;
&lt;br /&gt;
Allow the connected PC to get an IP automatically; install DNSMASQ&lt;br /&gt;
&lt;br /&gt;
 sudo apt install dnsmasq&lt;br /&gt;
&lt;br /&gt;
Configure the use by editing /etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
Uncomment and change two lines. It is to be used on ETH0 only and in the IP range 192.168.7.50 to 192.168.7.99.&lt;br /&gt;
&lt;br /&gt;
 # DNS requests only on&lt;br /&gt;
 # specified interface&lt;br /&gt;
 interface=eth0&lt;br /&gt;
 # range of addresses available for lease and optionally&lt;br /&gt;
 # a lease time&lt;br /&gt;
 dhcp-range=192.168.7.50,192.168.7.99,255.255.255.0,12h&lt;br /&gt;
&lt;br /&gt;
Restart the dnsmasq&lt;br /&gt;
&lt;br /&gt;
 sudo service dnsmasq restart&lt;br /&gt;
&lt;br /&gt;
To see the status of the dnsmasq service use:&lt;br /&gt;
&lt;br /&gt;
 journalctl -b0 -u dnsmasq.service&lt;br /&gt;
&lt;br /&gt;
After this, when you plug in a cable to a PC, then, after some seconds, both the robot and the PC should have an IP in the range 192.168.7.x. And the robot should display the new IP 192.168.7.7.&lt;br /&gt;
&lt;br /&gt;
You can now access the robot using &lt;br /&gt;
 ssh local@192.168.7.7&lt;br /&gt;
&lt;br /&gt;
==== Local link ====&lt;br /&gt;
&lt;br /&gt;
Note: This method failed in most cases&lt;br /&gt;
&lt;br /&gt;
If wifi is too slow or unavailable, a local link using a network cable could be the solution.&lt;br /&gt;
&lt;br /&gt;
Many PCs will assign a local link IP like 168.254.x.x, and the Robot will do the same. The robot IP will be displayed on the small display but may be obscured if a Wi-Fi IP is available.&lt;br /&gt;
&lt;br /&gt;
To prepare this behaviour, log in to the Raspberry using wifi (or attach a screen and keyboard) and make a preferred local-link cabled connection:&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli con mod &amp;quot;Wired connection 1&amp;quot; ipv4.method link-local ipv6.method disabled&lt;br /&gt;
&lt;br /&gt;
This should then be the behaviour after a reboot. &amp;quot;Wired connection 1&amp;quot; needs to be spelt this way; see the valid names using:&lt;br /&gt;
&lt;br /&gt;
 nmcli connection&lt;br /&gt;
&lt;br /&gt;
Reload Network manager&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection reload&lt;br /&gt;
&lt;br /&gt;
== Check IP and SSID ==&lt;br /&gt;
&lt;br /&gt;
When the Pi has rebooted, connect to it using SSH once again. Check that the Pi is connected to WiFi&lt;br /&gt;
 ifconfig&lt;br /&gt;
Under &#039;&#039;&#039;wlan0&#039;&#039;&#039; confirm that the Pi has received an IP (inet addr) and note down the first three sections of the IP - they are most likely &#039;&#039;&#039;10.197.21x.xxx&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To see which SSID you are connected to, use&lt;br /&gt;
 iwconfig&lt;br /&gt;
or &lt;br /&gt;
 nmcli -o&lt;br /&gt;
&lt;br /&gt;
The MAC address (&#039;HWaddr&#039; or &#039;ether&#039;) of the Pi should also be noted down - this probably starts with &#039;&#039;&#039;B8:27:EB:xx:xx:xx&#039;&#039;&#039; make sure to get all of it.&lt;br /&gt;
&lt;br /&gt;
===Find IP of robot (Linux)===&lt;br /&gt;
&lt;br /&gt;
In case the Pi gets a new IP address after reboot, you can search for it using the MAC address and &#039;&#039;&#039;nmap&#039;&#039;&#039;. If &#039;&#039;&#039;nmap&#039;&#039;&#039; is not installed, start by installing it&lt;br /&gt;
 sudo apt-get install nmap&lt;br /&gt;
To search for the Pi using the MAC address in terminal type&lt;br /&gt;
 nmap -sP 10.197.218.0/20 | awk &#039;/^Nmap/{ip=$NF}/B8:27:EB:23:A0:F5/{print ip}&#039;&lt;br /&gt;
where &#039;&#039;&#039;10.197.218&#039;&#039;&#039; is the first three sections of the IP you noted down, 20 is the number of fixed bits (out of 32), and &#039;&#039;&#039;B8:27:EB:23:A0:F5&#039;&#039;&#039; is the MAC address of the Pi. This should return the IP of the Pi.&lt;br /&gt;
&lt;br /&gt;
NB! the MAC can hold letters, they should probably be capital.&lt;br /&gt;
&lt;br /&gt;
==== If you don&#039;t know the IP address====&lt;br /&gt;
&lt;br /&gt;
Use the first part to get a list of active IPs on the net:&lt;br /&gt;
  nmap -sP 10.197.218.0/24&lt;br /&gt;
&lt;br /&gt;
The robot&#039;s name should be included in the list, but the network may take a while to detect it.&lt;br /&gt;
&lt;br /&gt;
== NTP ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Depreciated&#039;&#039;&#039;. The Raspberry default time sync now works, also at DTU.&lt;br /&gt;
&lt;br /&gt;
Network Time Protocol is used to keep clocks in sync.&lt;br /&gt;
Raspberry Pi will start with the date and time of the last proper shutdown, and a few seconds after the network is up, it will sync the clock using NTP.&lt;br /&gt;
&lt;br /&gt;
NTP need to be installed, i.e. &#039;sudo apt install ntp&#039; if not done already.&lt;br /&gt;
&lt;br /&gt;
At DTU, most clock sources are blocked; the clock source needs to be configured.&lt;br /&gt;
&lt;br /&gt;
At DTU, edit /etc/NTP.conf or /etc/ntpsec/ntp.conf and add ntp.ait.du.dk to the top of the server pool list.&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/ntpsec/ntp.conf&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 # Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board&lt;br /&gt;
 # on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for&lt;br /&gt;
 # more information.&lt;br /&gt;
 pool ntp.ait.dtu.dk&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Sync time (if on DTU net)&lt;br /&gt;
&lt;br /&gt;
 sudo ntpdate -u ntp.ait.dtu.dk&lt;br /&gt;
&lt;br /&gt;
Should work in and around DTU - see also [[NTP howto]] for more details.&lt;br /&gt;
&lt;br /&gt;
You can also check the status of the ntp service:&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl status ntp.service&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Network_setup&amp;diff=8674</id>
		<title>Network setup</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Network_setup&amp;diff=8674"/>
		<updated>2026-02-10T08:45:13Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Cable connection */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot B]]&lt;br /&gt;
&lt;br /&gt;
==WiFi network==&lt;br /&gt;
&lt;br /&gt;
If you are at DTU and the small display shows an IP, then all is fine. Otherwise read further down.&lt;br /&gt;
&lt;br /&gt;
====Network Manager====&lt;br /&gt;
&lt;br /&gt;
The NetworkManager uses device UUID as part of the Wi-Fi network setup. This means that (sometimes) an SD card can not be moved from one robot to another with a functional Wi-Fi connection.&lt;br /&gt;
&lt;br /&gt;
After 20 seconds, an attempt to solve this is activated using the commands below (the code is found in svn/robobot/setup/rename_host.bash - last half).&lt;br /&gt;
&lt;br /&gt;
Use the last line to setup manually - or the GUI, if available.&lt;br /&gt;
&lt;br /&gt;
See the current network settings&lt;br /&gt;
 nmcli dev show&lt;br /&gt;
Network manager connection with UUID&lt;br /&gt;
 nmcli connection&lt;br /&gt;
List available wifi access points&lt;br /&gt;
 nmcli dev wifi&lt;br /&gt;
&lt;br /&gt;
==== Connect to DTUdevice net ====&lt;br /&gt;
&lt;br /&gt;
You can establish a new connection from the command line&lt;br /&gt;
 sudo nmcli device wifi connect DTUdevice password &amp;lt;password&amp;gt; ifname wlan0 ipv6.method &amp;quot;disabled&amp;quot;&lt;br /&gt;
This should create a new system-connection file with a usable UUID.&lt;br /&gt;
IPv6 is disabled because many of the IPv6 MACs appear to be the same (we cloned the SD card), and this will blacklist the connection for MAC address theft.&lt;br /&gt;
&lt;br /&gt;
There is a terminal-based user interface to edit a connection. First list connections:&lt;br /&gt;
 $ nmcli con show&lt;br /&gt;
 eg: NAME            UUID                                  TYPE      DEVICE &lt;br /&gt;
 preconfigured       e07a0ae8-028b-4d65-806c-ec63f435df44  wifi      wlan0  &lt;br /&gt;
 lo                  2737bad6-956f-4668-99e0-4697f4ec30a7  loopback  lo &lt;br /&gt;
Find the NAME of the connection to edit, e.g. &#039;preconfigured&#039;&lt;br /&gt;
 sudo nmtui edit &amp;quot;preconfigured&amp;quot;&lt;br /&gt;
Then edit as desired.&lt;br /&gt;
&lt;br /&gt;
Reload Network Manager to read this.&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection reload&lt;br /&gt;
&lt;br /&gt;
or restart the NetworkManager&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl restart NetworkManager.service&lt;br /&gt;
&lt;br /&gt;
==== Home network connection ====&lt;br /&gt;
&lt;br /&gt;
If you know the SSID and password, you can prepare the robot for another (home) network.&lt;br /&gt;
Use this command (replacing &amp;lt;SSID&amp;gt; and &amp;lt;password&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli device wifi connect &amp;lt;SSID&amp;gt; password &amp;lt;password&amp;gt; ifname wlan0&lt;br /&gt;
&lt;br /&gt;
If you have no network contact, then use a local link (cable) or attach a screen and keyboard.&lt;br /&gt;
&lt;br /&gt;
== Cable connection ==&lt;br /&gt;
&lt;br /&gt;
==== Using static IP and DNS server on Raspberry ====&lt;br /&gt;
&lt;br /&gt;
Assign a static IP for the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add con-name eth0-manual ifname eth0 type ethernet ip4 192.168.7.7/24 ipv6.method disabled&lt;br /&gt;
&lt;br /&gt;
The Raspberry&#039;s IP address is 192.168.7.7 when a cable is connected. The Network Manager may need to be reloaded.&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli con reload&lt;br /&gt;
&lt;br /&gt;
Your PC on the other end then needs to be assigned a static (manual) IP address in the same network, e.g., 192.168.7.8.&lt;br /&gt;
&lt;br /&gt;
The response time on the cable is much faster than over wifi. Typically less than 0.5ms on cable and often more than 5ms on wifi.&lt;br /&gt;
&lt;br /&gt;
==== Alternative ====&lt;br /&gt;
&lt;br /&gt;
I found this method (Google AI) to use DHCP with higher priority, and then static IP if DHCP fails&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add type ethernet con-name &amp;quot;Wired-DHCP&amp;quot; ifname eth0 ipv4.method auto autoconnect yes connect.autoconnect-priority 1&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add type ethernet con-name &amp;quot;Robobot-Static7&amp;quot; ifname eth0 ipv4.method manual ipv4.addresses 192.168.7.7/24 ipv4.gateway 192.168.7.1 ipv4.dns 8.8.8.8 autoconnect yes connect.autoconnect-priority 0&lt;br /&gt;
&lt;br /&gt;
This creates 2 entries in /etc/NetworkManager/system-connections (on a default Raspberry Pi 64 Bit OS using Network Manager)&lt;br /&gt;
&lt;br /&gt;
/etc/NetworkManager/system-connections/Wired-DHCP.nmconnection&lt;br /&gt;
&lt;br /&gt;
 [connection]&lt;br /&gt;
 id=Wired-DHCP&lt;br /&gt;
 uuid=339844b1-cee4-4a43-a3f1-a5de05f3cb70&lt;br /&gt;
 type=ethernet&lt;br /&gt;
 autoconnect-priority=1&lt;br /&gt;
 interface-name=eth0&lt;br /&gt;
 &lt;br /&gt;
 [ethernet]&lt;br /&gt;
 &lt;br /&gt;
 [ipv4]&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [ipv6]&lt;br /&gt;
 addr-gen-mode=default&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [proxy]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note! the UUID should be different&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
/etc/NetworkManager/system-connections/Robobot-Static7.nmconnection&lt;br /&gt;
&lt;br /&gt;
 [connection]&lt;br /&gt;
 id=Robobot-Static7&lt;br /&gt;
 uuid=2a91ef05-3666-4293-a793-330c3b49cdd4&lt;br /&gt;
 type=ethernet&lt;br /&gt;
 interface-name=eth0&lt;br /&gt;
 &lt;br /&gt;
 [ethernet] &lt;br /&gt;
 &lt;br /&gt;
 [ipv4]&lt;br /&gt;
 address1=192.168.7.7/24,192.168.7.1&lt;br /&gt;
 dns=8.8.8.8;&lt;br /&gt;
 method=manual&lt;br /&gt;
 &lt;br /&gt;
 [ipv6]&lt;br /&gt;
 addr-gen-mode=default&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [proxy]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note2! To default to static IP can take 2-4 minutes after detecting the cable! (at least 2 times 60 second timeout is needed)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On your laptop you can do the same, but probably more efficient, set to manual IP v4.&lt;br /&gt;
This can be done using your GUI tools, or on Linux:&lt;br /&gt;
&lt;br /&gt;
 sudo ip eth0 192.168.7.22&lt;br /&gt;
&lt;br /&gt;
Note! &#039;&#039;eth0&#039;&#039; may be different, as modern hardware often has a more complex name, as &#039;&#039;eno1&#039;&#039; or &#039;&#039;enp108s0&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note2! If the robot has 192.168.7.7, then you should use something else for your laptop, e.g. 192.168.7.22.&lt;br /&gt;
&lt;br /&gt;
Then ssh to the robot&lt;br /&gt;
&lt;br /&gt;
 ssh local@192.168.7.7&lt;br /&gt;
&lt;br /&gt;
==== Install DNS server on Raspberry ====&lt;br /&gt;
&lt;br /&gt;
This section may be deprecated, use the alternative method above with fallback to static IP.&lt;br /&gt;
&lt;br /&gt;
Allow the connected PC to get an IP automatically; install DNSMASQ&lt;br /&gt;
&lt;br /&gt;
 sudo apt install dnsmasq&lt;br /&gt;
&lt;br /&gt;
Configure the use by editing /etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
Uncomment and change two lines. It is to be used on ETH0 only and in the IP range 192.168.7.50 to 192.168.7.99.&lt;br /&gt;
&lt;br /&gt;
 # DNS requests only on&lt;br /&gt;
 # specified interface&lt;br /&gt;
 interface=eth0&lt;br /&gt;
 # range of addresses available for lease and optionally&lt;br /&gt;
 # a lease time&lt;br /&gt;
 dhcp-range=192.168.7.50,192.168.7.99,255.255.255.0,12h&lt;br /&gt;
&lt;br /&gt;
Restart the dnsmasq&lt;br /&gt;
&lt;br /&gt;
 sudo service dnsmasq restart&lt;br /&gt;
&lt;br /&gt;
To see the status of the dnsmasq service use:&lt;br /&gt;
&lt;br /&gt;
 journalctl -b0 -u dnsmasq.service&lt;br /&gt;
&lt;br /&gt;
After this, when you plug in a cable to a PC, then, after some seconds, both the robot and the PC should have an IP in the range 192.168.7.x. And the robot should display the new IP 192.168.7.7.&lt;br /&gt;
&lt;br /&gt;
You can now access the robot using &lt;br /&gt;
 ssh local@192.168.7.7&lt;br /&gt;
&lt;br /&gt;
==== Local link ====&lt;br /&gt;
&lt;br /&gt;
Note: This method failed in most cases&lt;br /&gt;
&lt;br /&gt;
If wifi is too slow or unavailable, a local link using a network cable could be the solution.&lt;br /&gt;
&lt;br /&gt;
Many PCs will assign a local link IP like 168.254.x.x, and the Robot will do the same. The robot IP will be displayed on the small display but may be obscured if a Wi-Fi IP is available.&lt;br /&gt;
&lt;br /&gt;
To prepare this behaviour, log in to the Raspberry using wifi (or attach a screen and keyboard) and make a preferred local-link cabled connection:&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli con mod &amp;quot;Wired connection 1&amp;quot; ipv4.method link-local ipv6.method disabled&lt;br /&gt;
&lt;br /&gt;
This should then be the behaviour after a reboot. &amp;quot;Wired connection 1&amp;quot; needs to be spelt this way; see the valid names using:&lt;br /&gt;
&lt;br /&gt;
 nmcli connection&lt;br /&gt;
&lt;br /&gt;
Reload Network manager&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection reload&lt;br /&gt;
&lt;br /&gt;
== Check IP and SSID ==&lt;br /&gt;
&lt;br /&gt;
When the Pi has rebooted, connect to it using SSH once again. Check that the Pi is connected to WiFi&lt;br /&gt;
 ifconfig&lt;br /&gt;
Under &#039;&#039;&#039;wlan0&#039;&#039;&#039; confirm that the Pi has received an IP (inet addr) and note down the first three sections of the IP - they are most likely &#039;&#039;&#039;10.197.21x.xxx&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To see which SSID you are connected to, use&lt;br /&gt;
 iwconfig&lt;br /&gt;
or &lt;br /&gt;
 nmcli -o&lt;br /&gt;
&lt;br /&gt;
The MAC address (&#039;HWaddr&#039; or &#039;ether&#039;) of the Pi should also be noted down - this probably starts with &#039;&#039;&#039;B8:27:EB:xx:xx:xx&#039;&#039;&#039; make sure to get all of it.&lt;br /&gt;
&lt;br /&gt;
===Find IP of robot (Linux)===&lt;br /&gt;
&lt;br /&gt;
In case the Pi gets a new IP address after reboot, you can search for it using the MAC address and &#039;&#039;&#039;nmap&#039;&#039;&#039;. If &#039;&#039;&#039;nmap&#039;&#039;&#039; is not installed, start by installing it&lt;br /&gt;
 sudo apt-get install nmap&lt;br /&gt;
To search for the Pi using the MAC address in terminal type&lt;br /&gt;
 nmap -sP 10.197.218.0/20 | awk &#039;/^Nmap/{ip=$NF}/B8:27:EB:23:A0:F5/{print ip}&#039;&lt;br /&gt;
where &#039;&#039;&#039;10.197.218&#039;&#039;&#039; is the first three sections of the IP you noted down, 20 is the number of fixed bits (out of 32), and &#039;&#039;&#039;B8:27:EB:23:A0:F5&#039;&#039;&#039; is the MAC address of the Pi. This should return the IP of the Pi.&lt;br /&gt;
&lt;br /&gt;
NB! the MAC can hold letters, they should probably be capital.&lt;br /&gt;
&lt;br /&gt;
==== If you don&#039;t know the IP address====&lt;br /&gt;
&lt;br /&gt;
Use the first part to get a list of active IPs on the net:&lt;br /&gt;
  nmap -sP 10.197.218.0/24&lt;br /&gt;
&lt;br /&gt;
The robot&#039;s name should be included in the list, but the network may take a while to detect it.&lt;br /&gt;
&lt;br /&gt;
== NTP ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Depreciated&#039;&#039;&#039;. The Raspberry default time sync now works, also at DTU.&lt;br /&gt;
&lt;br /&gt;
Network Time Protocol is used to keep clocks in sync.&lt;br /&gt;
Raspberry Pi will start with the date and time of the last proper shutdown, and a few seconds after the network is up, it will sync the clock using NTP.&lt;br /&gt;
&lt;br /&gt;
NTP need to be installed, i.e. &#039;sudo apt install ntp&#039; if not done already.&lt;br /&gt;
&lt;br /&gt;
At DTU, most clock sources are blocked; the clock source needs to be configured.&lt;br /&gt;
&lt;br /&gt;
At DTU, edit /etc/NTP.conf or /etc/ntpsec/ntp.conf and add ntp.ait.du.dk to the top of the server pool list.&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/ntpsec/ntp.conf&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 # Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board&lt;br /&gt;
 # on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for&lt;br /&gt;
 # more information.&lt;br /&gt;
 pool ntp.ait.dtu.dk&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Sync time (if on DTU net)&lt;br /&gt;
&lt;br /&gt;
 sudo ntpdate -u ntp.ait.dtu.dk&lt;br /&gt;
&lt;br /&gt;
Should work in and around DTU - see also [[NTP howto]] for more details.&lt;br /&gt;
&lt;br /&gt;
You can also check the status of the ntp service:&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl status ntp.service&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Network_setup&amp;diff=8673</id>
		<title>Network setup</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Network_setup&amp;diff=8673"/>
		<updated>2026-02-10T08:43:23Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Cable connection */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot B]]&lt;br /&gt;
&lt;br /&gt;
==WiFi network==&lt;br /&gt;
&lt;br /&gt;
If you are at DTU and the small display shows an IP, then all is fine. Otherwise read further down.&lt;br /&gt;
&lt;br /&gt;
====Network Manager====&lt;br /&gt;
&lt;br /&gt;
The NetworkManager uses device UUID as part of the Wi-Fi network setup. This means that (sometimes) an SD card can not be moved from one robot to another with a functional Wi-Fi connection.&lt;br /&gt;
&lt;br /&gt;
After 20 seconds, an attempt to solve this is activated using the commands below (the code is found in svn/robobot/setup/rename_host.bash - last half).&lt;br /&gt;
&lt;br /&gt;
Use the last line to setup manually - or the GUI, if available.&lt;br /&gt;
&lt;br /&gt;
See the current network settings&lt;br /&gt;
 nmcli dev show&lt;br /&gt;
Network manager connection with UUID&lt;br /&gt;
 nmcli connection&lt;br /&gt;
List available wifi access points&lt;br /&gt;
 nmcli dev wifi&lt;br /&gt;
&lt;br /&gt;
==== Connect to DTUdevice net ====&lt;br /&gt;
&lt;br /&gt;
You can establish a new connection from the command line&lt;br /&gt;
 sudo nmcli device wifi connect DTUdevice password &amp;lt;password&amp;gt; ifname wlan0 ipv6.method &amp;quot;disabled&amp;quot;&lt;br /&gt;
This should create a new system-connection file with a usable UUID.&lt;br /&gt;
IPv6 is disabled because many of the IPv6 MACs appear to be the same (we cloned the SD card), and this will blacklist the connection for MAC address theft.&lt;br /&gt;
&lt;br /&gt;
There is a terminal-based user interface to edit a connection. First list connections:&lt;br /&gt;
 $ nmcli con show&lt;br /&gt;
 eg: NAME            UUID                                  TYPE      DEVICE &lt;br /&gt;
 preconfigured       e07a0ae8-028b-4d65-806c-ec63f435df44  wifi      wlan0  &lt;br /&gt;
 lo                  2737bad6-956f-4668-99e0-4697f4ec30a7  loopback  lo &lt;br /&gt;
Find the NAME of the connection to edit, e.g. &#039;preconfigured&#039;&lt;br /&gt;
 sudo nmtui edit &amp;quot;preconfigured&amp;quot;&lt;br /&gt;
Then edit as desired.&lt;br /&gt;
&lt;br /&gt;
Reload Network Manager to read this.&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection reload&lt;br /&gt;
&lt;br /&gt;
or restart the NetworkManager&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl restart NetworkManager.service&lt;br /&gt;
&lt;br /&gt;
==== Home network connection ====&lt;br /&gt;
&lt;br /&gt;
If you know the SSID and password, you can prepare the robot for another (home) network.&lt;br /&gt;
Use this command (replacing &amp;lt;SSID&amp;gt; and &amp;lt;password&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli device wifi connect &amp;lt;SSID&amp;gt; password &amp;lt;password&amp;gt; ifname wlan0&lt;br /&gt;
&lt;br /&gt;
If you have no network contact, then use a local link (cable) or attach a screen and keyboard.&lt;br /&gt;
&lt;br /&gt;
== Cable connection ==&lt;br /&gt;
&lt;br /&gt;
==== Using static IP and DNS server on Raspberry ====&lt;br /&gt;
&lt;br /&gt;
Assign a static IP for the Raspberry:&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add con-name eth0-manual ifname eth0 type ethernet ip4 192.168.7.7/24 ipv6.method disabled&lt;br /&gt;
&lt;br /&gt;
The Raspberry&#039;s IP address is 192.168.7.7 when a cable is connected. The Network Manager may need to be reloaded.&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli con reload&lt;br /&gt;
&lt;br /&gt;
Your PC on the other end then needs to be assigned a static (manual) IP address in the same network, e.g., 192.168.7.8.&lt;br /&gt;
&lt;br /&gt;
==== Alternative ====&lt;br /&gt;
&lt;br /&gt;
I found this method (Google AI) to use DHCP with higher priority, and then static IP if DHCP fails&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add type ethernet con-name &amp;quot;Wired-DHCP&amp;quot; ifname eth0 ipv4.method auto autoconnect yes connect.autoconnect-priority 1&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection add type ethernet con-name &amp;quot;Robobot-Static7&amp;quot; ifname eth0 ipv4.method manual ipv4.addresses 192.168.7.7/24 ipv4.gateway 192.168.7.1 ipv4.dns 8.8.8.8 autoconnect yes connect.autoconnect-priority 0&lt;br /&gt;
&lt;br /&gt;
This creates 2 entries in /etc/NetworkManager/system-connections (on a default Raspberry Pi 64 Bit OS using Network Manager)&lt;br /&gt;
&lt;br /&gt;
/etc/NetworkManager/system-connections/Wired-DHCP.nmconnection&lt;br /&gt;
&lt;br /&gt;
 [connection]&lt;br /&gt;
 id=Wired-DHCP&lt;br /&gt;
 uuid=339844b1-cee4-4a43-a3f1-a5de05f3cb70&lt;br /&gt;
 type=ethernet&lt;br /&gt;
 autoconnect-priority=1&lt;br /&gt;
 interface-name=eth0&lt;br /&gt;
 &lt;br /&gt;
 [ethernet]&lt;br /&gt;
 &lt;br /&gt;
 [ipv4]&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [ipv6]&lt;br /&gt;
 addr-gen-mode=default&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [proxy]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note! the UUID should be different&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
/etc/NetworkManager/system-connections/Robobot-Static7.nmconnection&lt;br /&gt;
&lt;br /&gt;
 [connection]&lt;br /&gt;
 id=Robobot-Static7&lt;br /&gt;
 uuid=2a91ef05-3666-4293-a793-330c3b49cdd4&lt;br /&gt;
 type=ethernet&lt;br /&gt;
 interface-name=eth0&lt;br /&gt;
 &lt;br /&gt;
 [ethernet] &lt;br /&gt;
 &lt;br /&gt;
 [ipv4]&lt;br /&gt;
 address1=192.168.7.7/24,192.168.7.1&lt;br /&gt;
 dns=8.8.8.8;&lt;br /&gt;
 method=manual&lt;br /&gt;
 &lt;br /&gt;
 [ipv6]&lt;br /&gt;
 addr-gen-mode=default&lt;br /&gt;
 method=auto&lt;br /&gt;
 &lt;br /&gt;
 [proxy]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note2! To default to static IP can take 2-4 minutes after detecting the cable! (at least 2 times 60 second timeout is needed)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
On your laptop you can do the same, but probably more efficient, set to manual IP v4.&lt;br /&gt;
This can be done using your GUI tools, or on Linux:&lt;br /&gt;
&lt;br /&gt;
 sudo ip eth0 192.168.7.22&lt;br /&gt;
&lt;br /&gt;
Note! &#039;&#039;eth0&#039;&#039; may be different, as modern hardware often has a more complex name, as &#039;&#039;eno1&#039;&#039; or &#039;&#039;enp108s0&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note2! If the robot has 192.168.7.7, then you should use something else for your laptop, e.g. 192.168.7.22.&lt;br /&gt;
&lt;br /&gt;
Then ssh to the robot&lt;br /&gt;
&lt;br /&gt;
 ssh local@192.168.7.7&lt;br /&gt;
&lt;br /&gt;
==== Install DNS server on Raspberry ====&lt;br /&gt;
&lt;br /&gt;
This section may be deprecated, use the alternative method above with fallback to static IP.&lt;br /&gt;
&lt;br /&gt;
Allow the connected PC to get an IP automatically; install DNSMASQ&lt;br /&gt;
&lt;br /&gt;
 sudo apt install dnsmasq&lt;br /&gt;
&lt;br /&gt;
Configure the use by editing /etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/dnsmasq.conf&lt;br /&gt;
&lt;br /&gt;
Uncomment and change two lines. It is to be used on ETH0 only and in the IP range 192.168.7.50 to 192.168.7.99.&lt;br /&gt;
&lt;br /&gt;
 # DNS requests only on&lt;br /&gt;
 # specified interface&lt;br /&gt;
 interface=eth0&lt;br /&gt;
 # range of addresses available for lease and optionally&lt;br /&gt;
 # a lease time&lt;br /&gt;
 dhcp-range=192.168.7.50,192.168.7.99,255.255.255.0,12h&lt;br /&gt;
&lt;br /&gt;
Restart the dnsmasq&lt;br /&gt;
&lt;br /&gt;
 sudo service dnsmasq restart&lt;br /&gt;
&lt;br /&gt;
To see the status of the dnsmasq service use:&lt;br /&gt;
&lt;br /&gt;
 journalctl -b0 -u dnsmasq.service&lt;br /&gt;
&lt;br /&gt;
After this, when you plug in a cable to a PC, then, after some seconds, both the robot and the PC should have an IP in the range 192.168.7.x. And the robot should display the new IP 192.168.7.7.&lt;br /&gt;
&lt;br /&gt;
You can now access the robot using &lt;br /&gt;
 ssh local@192.168.7.7&lt;br /&gt;
&lt;br /&gt;
==== Local link ====&lt;br /&gt;
&lt;br /&gt;
Note: This method failed in most cases&lt;br /&gt;
&lt;br /&gt;
If wifi is too slow or unavailable, a local link using a network cable could be the solution.&lt;br /&gt;
&lt;br /&gt;
Many PCs will assign a local link IP like 168.254.x.x, and the Robot will do the same. The robot IP will be displayed on the small display but may be obscured if a Wi-Fi IP is available.&lt;br /&gt;
&lt;br /&gt;
To prepare this behaviour, log in to the Raspberry using wifi (or attach a screen and keyboard) and make a preferred local-link cabled connection:&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli con mod &amp;quot;Wired connection 1&amp;quot; ipv4.method link-local ipv6.method disabled&lt;br /&gt;
&lt;br /&gt;
This should then be the behaviour after a reboot. &amp;quot;Wired connection 1&amp;quot; needs to be spelt this way; see the valid names using:&lt;br /&gt;
&lt;br /&gt;
 nmcli connection&lt;br /&gt;
&lt;br /&gt;
Reload Network manager&lt;br /&gt;
&lt;br /&gt;
 sudo nmcli connection reload&lt;br /&gt;
&lt;br /&gt;
== Check IP and SSID ==&lt;br /&gt;
&lt;br /&gt;
When the Pi has rebooted, connect to it using SSH once again. Check that the Pi is connected to WiFi&lt;br /&gt;
 ifconfig&lt;br /&gt;
Under &#039;&#039;&#039;wlan0&#039;&#039;&#039; confirm that the Pi has received an IP (inet addr) and note down the first three sections of the IP - they are most likely &#039;&#039;&#039;10.197.21x.xxx&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To see which SSID you are connected to, use&lt;br /&gt;
 iwconfig&lt;br /&gt;
or &lt;br /&gt;
 nmcli -o&lt;br /&gt;
&lt;br /&gt;
The MAC address (&#039;HWaddr&#039; or &#039;ether&#039;) of the Pi should also be noted down - this probably starts with &#039;&#039;&#039;B8:27:EB:xx:xx:xx&#039;&#039;&#039; make sure to get all of it.&lt;br /&gt;
&lt;br /&gt;
===Find IP of robot (Linux)===&lt;br /&gt;
&lt;br /&gt;
In case the Pi gets a new IP address after reboot, you can search for it using the MAC address and &#039;&#039;&#039;nmap&#039;&#039;&#039;. If &#039;&#039;&#039;nmap&#039;&#039;&#039; is not installed, start by installing it&lt;br /&gt;
 sudo apt-get install nmap&lt;br /&gt;
To search for the Pi using the MAC address in terminal type&lt;br /&gt;
 nmap -sP 10.197.218.0/20 | awk &#039;/^Nmap/{ip=$NF}/B8:27:EB:23:A0:F5/{print ip}&#039;&lt;br /&gt;
where &#039;&#039;&#039;10.197.218&#039;&#039;&#039; is the first three sections of the IP you noted down, 20 is the number of fixed bits (out of 32), and &#039;&#039;&#039;B8:27:EB:23:A0:F5&#039;&#039;&#039; is the MAC address of the Pi. This should return the IP of the Pi.&lt;br /&gt;
&lt;br /&gt;
NB! the MAC can hold letters, they should probably be capital.&lt;br /&gt;
&lt;br /&gt;
==== If you don&#039;t know the IP address====&lt;br /&gt;
&lt;br /&gt;
Use the first part to get a list of active IPs on the net:&lt;br /&gt;
  nmap -sP 10.197.218.0/24&lt;br /&gt;
&lt;br /&gt;
The robot&#039;s name should be included in the list, but the network may take a while to detect it.&lt;br /&gt;
&lt;br /&gt;
== NTP ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Depreciated&#039;&#039;&#039;. The Raspberry default time sync now works, also at DTU.&lt;br /&gt;
&lt;br /&gt;
Network Time Protocol is used to keep clocks in sync.&lt;br /&gt;
Raspberry Pi will start with the date and time of the last proper shutdown, and a few seconds after the network is up, it will sync the clock using NTP.&lt;br /&gt;
&lt;br /&gt;
NTP need to be installed, i.e. &#039;sudo apt install ntp&#039; if not done already.&lt;br /&gt;
&lt;br /&gt;
At DTU, most clock sources are blocked; the clock source needs to be configured.&lt;br /&gt;
&lt;br /&gt;
At DTU, edit /etc/NTP.conf or /etc/ntpsec/ntp.conf and add ntp.ait.du.dk to the top of the server pool list.&lt;br /&gt;
&lt;br /&gt;
 sudo nano /etc/ntpsec/ntp.conf&lt;br /&gt;
&lt;br /&gt;
 ...&lt;br /&gt;
 # Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board&lt;br /&gt;
 # on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for&lt;br /&gt;
 # more information.&lt;br /&gt;
 pool ntp.ait.dtu.dk&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Sync time (if on DTU net)&lt;br /&gt;
&lt;br /&gt;
 sudo ntpdate -u ntp.ait.dtu.dk&lt;br /&gt;
&lt;br /&gt;
Should work in and around DTU - see also [[NTP howto]] for more details.&lt;br /&gt;
&lt;br /&gt;
You can also check the status of the ntp service:&lt;br /&gt;
&lt;br /&gt;
 sudo systemctl status ntp.service&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_2&amp;diff=8672</id>
		<title>Robobot 2</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_2&amp;diff=8672"/>
		<updated>2026-02-01T16:17:37Z</updated>

		<summary type="html">&lt;p&gt;Jca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
==Network Access==&lt;br /&gt;
&lt;br /&gt;
[[file:O-led-display-ann.jpg | 400px]]&lt;br /&gt;
&lt;br /&gt;
=== Install Putty ===&lt;br /&gt;
&lt;br /&gt;
Putty is the recommended SSH client (see e.g. https://en.wikipedia.org/wiki/Comparison_of_SSH_clients). &lt;br /&gt;
&lt;br /&gt;
Install Putty and connect to the IP address on the small robot display.&lt;br /&gt;
&lt;br /&gt;
[[File:Putty_Screenshot.png|500px|Putty setup for SSH connection and IP]]&lt;br /&gt;
[[File:Putty_Screenshot_login_3.png|500px|Login with username &#039;&#039;local&#039;&#039; - password is found in the course &#039;&#039;resources&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
Once connected, you have a command line control of the Raspberry Pi.&lt;br /&gt;
&lt;br /&gt;
=== Alternative SSH connection ===&lt;br /&gt;
&lt;br /&gt;
Most PCs have a command line and a command line SSH-client version, try&lt;br /&gt;
&lt;br /&gt;
 ssh local@10.197.218.202&lt;br /&gt;
&lt;br /&gt;
See also the similar page [[Raspberry Pi directory structure for Robobot | Network access]].&lt;br /&gt;
&lt;br /&gt;
==== Fail to connect ====&lt;br /&gt;
&lt;br /&gt;
If the robot does not have an IP, consult [[Network_setup]] and maybe use the &#039;&#039;local link&#039;&#039; option.&lt;br /&gt;
&lt;br /&gt;
== Access to files on Raspberry ==&lt;br /&gt;
&lt;br /&gt;
All operating systems can be setup to access and modify files on Raspberry.&lt;br /&gt;
&lt;br /&gt;
=== Windows ===&lt;br /&gt;
&lt;br /&gt;
On a Windows computer &#039;&#039;WinScp&#039;&#039; is a satisfactory solution, but &amp;quot;RealFTP&amp;quot; may be cheaper:&lt;br /&gt;
&lt;br /&gt;
Connect using the above address (and port 22), you could get something like:&lt;br /&gt;
&lt;br /&gt;
[[File:RealFTP-screenshot.png | 500px | RealFTP (with Danish lead test)]]&lt;br /&gt;
&lt;br /&gt;
=== Linux (and Mac?) ===&lt;br /&gt;
&lt;br /&gt;
On Linux-based platforms, you could use SSHFS to mount a remote directory on your platform.&lt;br /&gt;
&lt;br /&gt;
In a terminal, create an empty directory (here jjj) and mount the remote directory:&lt;br /&gt;
&lt;br /&gt;
 mkdir jjj&lt;br /&gt;
 sshfs local@10.197.218.202: jjj&lt;br /&gt;
 password: &lt;br /&gt;
 cd jjj&lt;br /&gt;
 ls&lt;br /&gt;
 Documents  Downloads  git  mission_start.bash  Music  on_reboot.bash  rebootinfo.txt  svn  Video&lt;br /&gt;
&lt;br /&gt;
In the &#039;sshfs&#039; command, remember the &#039;:&#039; after the IP address.&lt;br /&gt;
&lt;br /&gt;
Remember to unmount&lt;br /&gt;
&lt;br /&gt;
 umount jjj&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_B&amp;diff=8671</id>
		<title>Robobot B</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_B&amp;diff=8671"/>
		<updated>2026-02-01T16:15:33Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Robobot is a robot platform for innovative applications, especially the annual DTU Robocup competition.&lt;br /&gt;
&lt;br /&gt;
=Robobot=&lt;br /&gt;
&lt;br /&gt;
[[File:robobot-in-blocks-2024.png | 600px]]&lt;br /&gt;
[[File:robobot-rev_8_frog.jpg | 400px]]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This section is intended for users.&lt;br /&gt;
&lt;br /&gt;
* Getting started&lt;br /&gt;
** [[Robobot 1 | Power on]], start and shut down&lt;br /&gt;
** [[Robobot 2 | Network access]] &lt;br /&gt;
** [[Robobot 2b | Software update]] &lt;br /&gt;
** [[Robobot 3 | Camera view]]&lt;br /&gt;
** [[Robobot 4 | Python control]]&lt;br /&gt;
** [[Robobot 5 | Firmware tools]]&lt;br /&gt;
* System description&lt;br /&gt;
** [[Robobot architecture | System overview]] and top-level blocks description.&lt;br /&gt;
** [[Robobot MQTT-client]]&lt;br /&gt;
** [[Robobot webcam server]]&lt;br /&gt;
** [[Robobot teensy interface]]&lt;br /&gt;
** [[Robobot teensy firmware]]&lt;br /&gt;
** [[Robobot MQTT topics]]&lt;br /&gt;
** [[Robobot calibration]]&lt;br /&gt;
* Further details&lt;br /&gt;
** Start button to start mission, see first part of [[Enable autostart]]&lt;br /&gt;
** [[Robobot and MATLAB]] use of logfiles.&lt;br /&gt;
** [[Raspberry Pi directory structure for Robobot | Network access]], file share and directory structure.&lt;br /&gt;
** [[Robobot hardware]] items. Motors, sensors, plastic and screws.&lt;br /&gt;
** [[Robobot circuits]], PCB and circuit diagrams&lt;br /&gt;
&lt;br /&gt;
==Developers notes==&lt;br /&gt;
&lt;br /&gt;
This section contains notes on robot installation.&lt;br /&gt;
&lt;br /&gt;
* [[Robobot install on Raspberry]] including all needed packages.&lt;br /&gt;
* DTU network and time setup: [[Network setup]]&lt;br /&gt;
* [[Robobot base software installation]] like teensy_interface&lt;br /&gt;
* [[Enable autostart]] and IP display as well as on_reboot script.&lt;br /&gt;
* [[Servo supply issue]] Especially the small servo X9MG.&lt;br /&gt;
&lt;br /&gt;
Arduino firmware - one of these:&lt;br /&gt;
* Installation of [[Arduino and Teensy libraries]] when using the Arduino IDE.&lt;br /&gt;
* Installation of [[Visual studio support | Visual Studio Code]] when working on a standard PC. There may be further help here [[Import code to Visual Studio]]&lt;br /&gt;
* installation of [[Arduino command line support | Command line support]] for use on the Raspberry Pi.&lt;br /&gt;
&lt;br /&gt;
Help and setup&lt;br /&gt;
* [[Help page Teensy_8]] from on-line command &#039;&#039;help&#039;&#039;.&lt;br /&gt;
* [[Robobot processor]] initialise setup of Teensy (factory reset)&lt;br /&gt;
* [[Robobot Raspberry strange error]] Unexplained error (January 2026, Trixie image, not cloned).&lt;br /&gt;
* [[Robobot packing list]].&lt;br /&gt;
* [[Robobot logfile cleanup]].&lt;br /&gt;
&lt;br /&gt;
Simulator (webots)&lt;br /&gt;
* https://github.com/WildWillyRobots/DtuRobocupWebots.git is a simulator for the DTU Robocup track for the 2025 track. Created by Jonas Sølvhøj.&lt;br /&gt;
&lt;br /&gt;
Older pages&lt;br /&gt;
&lt;br /&gt;
* Old [[robobot]] instructions are mostly deprecated&lt;br /&gt;
* Some architecture notes [[Robobot Teensy interface]].&lt;br /&gt;
* [[Robobot software description | Software description]] and examples.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8670</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8670"/>
		<updated>2026-02-01T16:13:33Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Run mission */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
&lt;br /&gt;
===Power on===&lt;br /&gt;
&lt;br /&gt;
Usually, the robot powers on, then the power switch is fully UP. Some switches have three positions.&lt;br /&gt;
If this fails, then the software-off may be active, then press the small &#039;&#039;&#039;Power ON&#039;&#039;&#039; button on the PCB (see image further down).&lt;br /&gt;
&lt;br /&gt;
When the Raspberry is booted, the LED band LED 14 will start blinking, but communication is not available for another 5-10 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:robobot_teensy_interfce_LED.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
===Run mission===&lt;br /&gt;
&lt;br /&gt;
By default, a mission is available to run 30cm, turn 90 degrees left, and then take 5 images while blinking an LED on the IO board.&lt;br /&gt;
&lt;br /&gt;
Press the green start button. It will take some 2-5 seconds for the Python script to load and start the mission.&lt;br /&gt;
&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and back ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:Start-buttons.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;Power on&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8669</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8669"/>
		<updated>2026-02-01T16:11:59Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Run mission */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
&lt;br /&gt;
===Power on===&lt;br /&gt;
&lt;br /&gt;
Usually, the robot powers on, then the power switch is fully UP. Some switches have three positions.&lt;br /&gt;
If this fails, then the software-off may be active, then press the small &#039;&#039;&#039;Power ON&#039;&#039;&#039; button on the PCB (see image further down).&lt;br /&gt;
&lt;br /&gt;
When the Raspberry is booted, the LED band LED 14 will start blinking, but communication is not available for another 5-10 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:robobot_teensy_interfce_LED.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
===Run mission===&lt;br /&gt;
&lt;br /&gt;
By default, a mission is available to run 30cm, turn 90 degrees left, and thereafter take 5 images (blinking an LED on the IO-board).&lt;br /&gt;
&lt;br /&gt;
Press the start button. It will take some 2-5 seconds for the Python script to load and start the mission.&lt;br /&gt;
&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and back ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:Start-buttons.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;Power on&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8668</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8668"/>
		<updated>2026-02-01T16:10:33Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Run mission */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
&lt;br /&gt;
===Power on===&lt;br /&gt;
&lt;br /&gt;
Usually, the robot powers on, then the power switch is fully UP. Some switches have three positions.&lt;br /&gt;
If this fails, then the software-off may be active, then press the small &#039;&#039;&#039;Power ON&#039;&#039;&#039; button on the PCB (see image further down).&lt;br /&gt;
&lt;br /&gt;
When the Raspberry is booted, the LED band LED 14 will start blinking, but communication is not available for another 5-10 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:robobot_teensy_interfce_LED.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
===Run mission===&lt;br /&gt;
&lt;br /&gt;
By default, a mission is available to run 30cm and turn 90 degrees left.&lt;br /&gt;
&lt;br /&gt;
Press the start button. It will take some 2-5 seconds for the Python script to load and start the mission.&lt;br /&gt;
&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and back ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:Start-buttons.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;Power on&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8667</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8667"/>
		<updated>2026-02-01T16:09:58Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Run mission */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
&lt;br /&gt;
===Power on===&lt;br /&gt;
&lt;br /&gt;
Usually, the robot powers on, then the power switch is fully UP. Some switches have three positions.&lt;br /&gt;
If this fails, then the software-off may be active, then press the small &#039;&#039;&#039;Power ON&#039;&#039;&#039; button on the PCB (see image further down).&lt;br /&gt;
&lt;br /&gt;
When the Raspberry is booted, the LED band LED 14 will start blinking, but communication is not available for another 5-10 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:robobot_teensy_interfce_LED.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
===Run mission===&lt;br /&gt;
&lt;br /&gt;
By default, a mission is available to run 30cm and turn 90 degrees left.&lt;br /&gt;
&lt;br /&gt;
Press the start button. It will take some 2-4 seconds for the Python script to load and start the mission.&lt;br /&gt;
&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and back ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:Start-buttons.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;Power on&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8666</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8666"/>
		<updated>2026-02-01T16:08:23Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Power on */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
&lt;br /&gt;
===Power on===&lt;br /&gt;
&lt;br /&gt;
Usually, the robot powers on, then the power switch is fully UP. Some switches have three positions.&lt;br /&gt;
If this fails, then the software-off may be active, then press the small &#039;&#039;&#039;Power ON&#039;&#039;&#039; button on the PCB (see image further down).&lt;br /&gt;
&lt;br /&gt;
When the Raspberry is booted, the LED band LED 14 will start blinking, but communication is not available for another 5-10 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:robobot_teensy_interfce_LED.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
===Run mission===&lt;br /&gt;
&lt;br /&gt;
By default, a mission is available to run 30cm and turn 90 degrees left.&lt;br /&gt;
&lt;br /&gt;
Press the start button&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and back ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:Start-buttons.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;Power on&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8665</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8665"/>
		<updated>2026-02-01T16:07:11Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Power on */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
&lt;br /&gt;
===Power on===&lt;br /&gt;
&lt;br /&gt;
Usually, the robot powers on, then the power switch is fully UP. Some switches have three positions.&lt;br /&gt;
If this fails, then the software-off may be active, then press the small &#039;&#039;&#039;power ON&#039;&#039;&#039; button on the PCB (see image further down).&lt;br /&gt;
&lt;br /&gt;
When the Raspberry is booted, the LED band LED 14 will start blinking, but communication is not available for another 5-10 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:robobot_teensy_interfce_LED.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
===Run mission===&lt;br /&gt;
&lt;br /&gt;
By default, a mission is available to run 30cm and turn 90 degrees left.&lt;br /&gt;
&lt;br /&gt;
Press the start button&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and back ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:Start-buttons.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;Power on&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=File:Robobot_teensy_interfce_LED.png&amp;diff=8664</id>
		<title>File:Robobot teensy interfce LED.png</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=File:Robobot_teensy_interfce_LED.png&amp;diff=8664"/>
		<updated>2026-02-01T16:04:48Z</updated>

		<summary type="html">&lt;p&gt;Jca: LED 14&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
LED 14&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8663</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8663"/>
		<updated>2026-02-01T16:04:17Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Robobot with Raspberry Pi */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
&lt;br /&gt;
===Power on===&lt;br /&gt;
&lt;br /&gt;
Usually, the robot powers on, then the power switch is fully UP. Some switches have three positions.&lt;br /&gt;
If this fails, then the software off may be active, then press the small &#039;&#039;&#039;power ON&#039;&#039;&#039; button on the PCB (see image further down).&lt;br /&gt;
&lt;br /&gt;
When the Raspberry is booted, the LED-band &lt;br /&gt;
&lt;br /&gt;
[[file:robobot_teensy_interfce_LED.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
===Run mission===&lt;br /&gt;
&lt;br /&gt;
By default, a mission is available to run 30cm and turn 90 degrees left.&lt;br /&gt;
&lt;br /&gt;
Press the start button&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and back ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:Start-buttons.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;Power on&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8662</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8662"/>
		<updated>2026-02-01T15:54:35Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* OFF and ON */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and back ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:Start-buttons.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;Power on&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8661</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8661"/>
		<updated>2026-02-01T15:52:39Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* OFF and ON */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:Start-buttons.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;Power on&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8660</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8660"/>
		<updated>2026-02-01T15:51:40Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* OFF and ON */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
[[file:Start-buttons.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;power&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_architecture&amp;diff=8659</id>
		<title>Robobot architecture</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_architecture&amp;diff=8659"/>
		<updated>2026-02-01T15:30:29Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Start buttons (and external power) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Display and LED-band ==&lt;br /&gt;
&lt;br /&gt;
=== O-LED display ===&lt;br /&gt;
&lt;br /&gt;
[[file:o-led-display-ann.jpg | 500 px]]&lt;br /&gt;
&lt;br /&gt;
The primary function of this display is the battery voltage. The AS encoder is not used by Robobot.&lt;br /&gt;
&lt;br /&gt;
=== LED-band ===&lt;br /&gt;
&lt;br /&gt;
[[file:led-band-annotated.jpg | 750px]]&lt;br /&gt;
&lt;br /&gt;
The Teensy maintains the LED band. Most LEDs show sensor values. The last 3 LEDs can be set by commands to the Teensy.&lt;br /&gt;
&lt;br /&gt;
== Hardware block overview ==&lt;br /&gt;
&lt;br /&gt;
[[File:robobot-in-blocks-2024.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
Figure 1. The main hardware building blocks.&lt;br /&gt;
&lt;br /&gt;
== Software building blocks ==&lt;br /&gt;
&lt;br /&gt;
[[File:robobot-function-blocks.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
Figure 2. The main software building blocks. &lt;br /&gt;
&lt;br /&gt;
The blocks marked with a blue dot are available in the repository as source code.&lt;br /&gt;
&lt;br /&gt;
==== Mission app====&lt;br /&gt;
The mission app block is the robot&#039;s top-level controller.&lt;br /&gt;
&lt;br /&gt;
It can subscribe to data streams from the Teensy interface and command the robot to perform actions (like forward and turn velocity).&lt;br /&gt;
It attaches to the camera video stream and connects to the IO board (e.g. the start and stop buttons.&lt;br /&gt;
&lt;br /&gt;
The mission app is in svn/robobot/mqtt_python; its main file is &#039;&#039;mqtt-client.py.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== Teensy interface ====&lt;br /&gt;
&lt;br /&gt;
The Teensy interface connects the Teensy USB interface and the MQTT protocol.&lt;br /&gt;
&lt;br /&gt;
The Teensy interface further has closed-loop control for forward velocity and implements turn-rate commands.&lt;br /&gt;
&lt;br /&gt;
The interface decodes many essential data types and allows these data streams to be logged.&lt;br /&gt;
The logged files are text-based and intended for Matlab for analysis and debugging.&lt;br /&gt;
See more details in [[Robobot teensy interface]].&lt;br /&gt;
&lt;br /&gt;
==== Mosquitto MQTT server ====&lt;br /&gt;
&lt;br /&gt;
This Mosquitto server is an open-source MQTT protocol server - see https://mosquitto.org/. &lt;br /&gt;
This server is running as a service.&lt;br /&gt;
&lt;br /&gt;
==== Camera streamer====&lt;br /&gt;
&lt;br /&gt;
The camera streamer is a small Python app that takes data from the camera and streams the video to socket port 7123.&lt;br /&gt;
This means that the stream is also available on Wi-Fi.&lt;br /&gt;
See [[Robobot webcam server]] for more details&lt;br /&gt;
&lt;br /&gt;
==== IP-disp ====&lt;br /&gt;
&lt;br /&gt;
IP_disp is a silent app that is started at reboot (by &#039;&#039;on_reboot.bash&#039;&#039;) and has two tasks:&lt;br /&gt;
* Detect the IP net address of the Raspberry and send it to the small display on the Teensy board (inactive if the Teensy_interface is running.)&lt;br /&gt;
* Detect if the &amp;quot;start&amp;quot; button is pressed, and start the mission app.&lt;br /&gt;
* Detect if the &amp;quot;start&amp;quot; button is pressed for more than 5 seconds to shut down the robot.&lt;br /&gt;
&lt;br /&gt;
==== Digital IO ====&lt;br /&gt;
&lt;br /&gt;
This is the board on top of the Robobot. It provides digital IO and a power supply for external devices.&lt;br /&gt;
&lt;br /&gt;
The IO is connected to the Raspberry PI pins GPIO06 (stop), 13 (start), 16, 19, 20, 21, and 26.&lt;br /&gt;
See details in [[Robobot circuits]].&lt;br /&gt;
&lt;br /&gt;
==== Teensy PCB ====&lt;br /&gt;
&lt;br /&gt;
The Teensy board is a baseboard used in the more straightforward &#039;Regbot&#039; robot.&lt;br /&gt;
This board has most of the hardware interfaces and offers all sensor data to be streamed in a publish-subscribe protocol.&lt;br /&gt;
All communication is based on clear text lines.&lt;br /&gt;
&lt;br /&gt;
The firmware is in &#039;&#039;svn/robobot/teensy_firmware_8&#039;&#039;, compiled with &#039;&#039;./compile&#039;&#039; and uploaded to the Teensy by &#039;&#039;./upload&#039;&#039;. NB! An upload will cut the battery power, so press the &#039;&#039;power&#039;&#039; switch during upload.&lt;br /&gt;
See details in [[Robobot circuits]].&lt;br /&gt;
&lt;br /&gt;
== Start buttons (and external power) ==&lt;br /&gt;
&lt;br /&gt;
[[file:start-buttons.png | 600px]]&lt;br /&gt;
&lt;br /&gt;
The two start buttons are quite different. &lt;br /&gt;
* The Arduino mission start will start the mission code in the Teensy. &lt;br /&gt;
* The IO Start button is read by &#039;&#039;ip_disp&#039;&#039; and starts the Python script mentioned in &#039;&#039;mission_start.bash&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Both buttons can shut down the robot when pressed for 5 seconds.&lt;br /&gt;
&lt;br /&gt;
The digital-io (except the start button) can only be used from the Python script.&lt;br /&gt;
&lt;br /&gt;
=== External power ===&lt;br /&gt;
&lt;br /&gt;
On the digital-io board, there are power pins available for 3V, 5V, and 12V. 12V is the battery voltage, which can vary from 10 to 16V.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_processor&amp;diff=8658</id>
		<title>Robobot processor</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_processor&amp;diff=8658"/>
		<updated>2026-02-01T15:12:03Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Fresh software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Reset of Teensy configuration ==&lt;br /&gt;
&lt;br /&gt;
Configuration commands to update or initialize a Robobot with version 8 PCB.&lt;br /&gt;
&lt;br /&gt;
=== Stop the Teensy user ===&lt;br /&gt;
&lt;br /&gt;
If the Raspberry is running, then stop the &#039;&#039;teensy_interface&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 pkill teensy_interfac&lt;br /&gt;
&lt;br /&gt;
The last &#039;e&#039; is missing; the process names are limited to 15 characters.&lt;br /&gt;
&lt;br /&gt;
=== Fresh software ===&lt;br /&gt;
&lt;br /&gt;
Upload the newly compiled software (from Raspberry or directly from a PC), e.g.&lt;br /&gt;
&lt;br /&gt;
 ./upload&lt;br /&gt;
 Teensy Loader, Command Line, Version 2.3&lt;br /&gt;
 Read &amp;quot;build/teensy_firmware_8.ino.hex&amp;quot;: 202752 bytes, 2.5% usage&lt;br /&gt;
 Waiting for Teensy device...&lt;br /&gt;
  (hint: press the reset button)&lt;br /&gt;
&lt;br /&gt;
Remember to hold the &#039;&#039;power on&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
Disable the CRC check to make the console printout look better (interactive flag). This also prevents the Teensy from stopping communicating due to a lack of activity (60 seconds).&lt;br /&gt;
&lt;br /&gt;
 i 1&lt;br /&gt;
&lt;br /&gt;
=== Fresh flash configuration ===&lt;br /&gt;
&lt;br /&gt;
If the flash configuration has changed, then use these commands.&lt;br /&gt;
&lt;br /&gt;
* Set robot number to &#039;&#039;invalid&#039;&#039; and save to flash:&lt;br /&gt;
 setidx 0&lt;br /&gt;
 eew&lt;br /&gt;
* Reboot the Teensy processor&lt;br /&gt;
 reboot&lt;br /&gt;
&lt;br /&gt;
=== Configure and calibrate ===&lt;br /&gt;
&lt;br /&gt;
* Set a valid robot number&lt;br /&gt;
 setidx &amp;lt;robot-number&amp;gt;&lt;br /&gt;
 sethw 8&lt;br /&gt;
 eew&lt;br /&gt;
&lt;br /&gt;
The robot should now show the new name.&lt;br /&gt;
&lt;br /&gt;
==== robot wheel configuration ====&lt;br /&gt;
&lt;br /&gt;
Defaults should be OK for Robobot (to view current configuration, use &#039;&#039;confi&#039;&#039;.)&lt;br /&gt;
 confw rl rr gear TPR wb&lt;br /&gt;
 confi 0.0750 0.0750 19 68 0.234&lt;br /&gt;
&lt;br /&gt;
==== Line sensor ====&lt;br /&gt;
Place the robot on white tape (all sensors)&lt;br /&gt;
 licw 100&lt;br /&gt;
Wait at least 100ms, then&lt;br /&gt;
 eew&lt;br /&gt;
&lt;br /&gt;
==== distance sensor ====&lt;br /&gt;
Values need to be found; use &#039;&#039;sub ir 200&#039;&#039; to see regular values (lists &#039;&#039;ir m m AD1 AD2&#039;&#039;).&lt;br /&gt;
 iron 1&lt;br /&gt;
 irc A13 A50 B13 B50 1&lt;br /&gt;
&lt;br /&gt;
Fair values&lt;br /&gt;
 irc 15000 5000 15000 5000&lt;br /&gt;
&lt;br /&gt;
==== gyro calibration ====&lt;br /&gt;
 gyroc&lt;br /&gt;
==== logger flags ====&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;lfli&#039;&#039; to see current flags.&lt;br /&gt;
 lfls 0 acc gyro 0 0 motv mota enc vel turnrate pose line dist batt timing 0 0&lt;br /&gt;
&lt;br /&gt;
Default is OK&lt;br /&gt;
&lt;br /&gt;
==== save to flash ====&lt;br /&gt;
 &lt;br /&gt;
Save to flash and turn off interactive mode.&lt;br /&gt;
 eew&lt;br /&gt;
 i 0&lt;br /&gt;
&lt;br /&gt;
=== Start the &#039;&#039;teensy_interface&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
Either reboot the Raspberry or start the interface manually.&lt;br /&gt;
&lt;br /&gt;
Reboot&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
Restart (with the no-logging option)&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build &lt;br /&gt;
 ./teensy_interface -l &amp;amp;&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_processor&amp;diff=8657</id>
		<title>Robobot processor</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_processor&amp;diff=8657"/>
		<updated>2026-02-01T15:11:45Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Fresh software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Reset of Teensy configuration ==&lt;br /&gt;
&lt;br /&gt;
Configuration commands to update or initialize a Robobot with version 8 PCB.&lt;br /&gt;
&lt;br /&gt;
=== Stop the Teensy user ===&lt;br /&gt;
&lt;br /&gt;
If the Raspberry is running, then stop the &#039;&#039;teensy_interface&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 pkill teensy_interfac&lt;br /&gt;
&lt;br /&gt;
The last &#039;e&#039; is missing; the process names are limited to 15 characters.&lt;br /&gt;
&lt;br /&gt;
=== Fresh software ===&lt;br /&gt;
&lt;br /&gt;
Upload the newly compiled software (from Raspberry or directly from a PC), e.g.&lt;br /&gt;
&lt;br /&gt;
 ./upload&lt;br /&gt;
 Teensy Loader, Command Line, Version 2.3&lt;br /&gt;
 Read &amp;quot;build/teensy_firmware_8.ino.hex&amp;quot;: 202752 bytes, 2.5% usage&lt;br /&gt;
 Waiting for Teensy device...&lt;br /&gt;
  (hint: press the reset button)&lt;br /&gt;
&lt;br /&gt;
Remember to hold the &#039;&#039;power&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
Disable the CRC check to make the console printout look better (interactive flag). This also prevents the Teensy from stopping communicating due to a lack of activity (60 seconds).&lt;br /&gt;
&lt;br /&gt;
 i 1&lt;br /&gt;
&lt;br /&gt;
=== Fresh flash configuration ===&lt;br /&gt;
&lt;br /&gt;
If the flash configuration has changed, then use these commands.&lt;br /&gt;
&lt;br /&gt;
* Set robot number to &#039;&#039;invalid&#039;&#039; and save to flash:&lt;br /&gt;
 setidx 0&lt;br /&gt;
 eew&lt;br /&gt;
* Reboot the Teensy processor&lt;br /&gt;
 reboot&lt;br /&gt;
&lt;br /&gt;
=== Configure and calibrate ===&lt;br /&gt;
&lt;br /&gt;
* Set a valid robot number&lt;br /&gt;
 setidx &amp;lt;robot-number&amp;gt;&lt;br /&gt;
 sethw 8&lt;br /&gt;
 eew&lt;br /&gt;
&lt;br /&gt;
The robot should now show the new name.&lt;br /&gt;
&lt;br /&gt;
==== robot wheel configuration ====&lt;br /&gt;
&lt;br /&gt;
Defaults should be OK for Robobot (to view current configuration, use &#039;&#039;confi&#039;&#039;.)&lt;br /&gt;
 confw rl rr gear TPR wb&lt;br /&gt;
 confi 0.0750 0.0750 19 68 0.234&lt;br /&gt;
&lt;br /&gt;
==== Line sensor ====&lt;br /&gt;
Place the robot on white tape (all sensors)&lt;br /&gt;
 licw 100&lt;br /&gt;
Wait at least 100ms, then&lt;br /&gt;
 eew&lt;br /&gt;
&lt;br /&gt;
==== distance sensor ====&lt;br /&gt;
Values need to be found; use &#039;&#039;sub ir 200&#039;&#039; to see regular values (lists &#039;&#039;ir m m AD1 AD2&#039;&#039;).&lt;br /&gt;
 iron 1&lt;br /&gt;
 irc A13 A50 B13 B50 1&lt;br /&gt;
&lt;br /&gt;
Fair values&lt;br /&gt;
 irc 15000 5000 15000 5000&lt;br /&gt;
&lt;br /&gt;
==== gyro calibration ====&lt;br /&gt;
 gyroc&lt;br /&gt;
==== logger flags ====&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;lfli&#039;&#039; to see current flags.&lt;br /&gt;
 lfls 0 acc gyro 0 0 motv mota enc vel turnrate pose line dist batt timing 0 0&lt;br /&gt;
&lt;br /&gt;
Default is OK&lt;br /&gt;
&lt;br /&gt;
==== save to flash ====&lt;br /&gt;
 &lt;br /&gt;
Save to flash and turn off interactive mode.&lt;br /&gt;
 eew&lt;br /&gt;
 i 0&lt;br /&gt;
&lt;br /&gt;
=== Start the &#039;&#039;teensy_interface&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
Either reboot the Raspberry or start the interface manually.&lt;br /&gt;
&lt;br /&gt;
Reboot&lt;br /&gt;
 sudo reboot now&lt;br /&gt;
Restart (with the no-logging option)&lt;br /&gt;
 cd ~/svn/robobot/teensy_interface/build &lt;br /&gt;
 ./teensy_interface -l &amp;amp;&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8656</id>
		<title>Robobot 1</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_1&amp;diff=8656"/>
		<updated>2026-02-01T15:10:20Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* OFF and ON */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Robobot with Raspberry Pi==&lt;br /&gt;
===Battery===&lt;br /&gt;
&lt;br /&gt;
The battery is an 11V 2.2 Ah 3-cell Lipo. Its power consumption (when not moving) is 0.3-0.5A, so it can sustain about 4 hours of use.&lt;br /&gt;
&lt;br /&gt;
Robobot will cut power when the battery voltage is below 10V to protect the battery.&lt;br /&gt;
&lt;br /&gt;
The Battery is (probably) charged to storage level (~40% of full capacity), so start by charging it.&lt;br /&gt;
&lt;br /&gt;
===Power supply===&lt;br /&gt;
&lt;br /&gt;
A 230V power supply, which supplies 15V and 6A, is available and intended for use during development.&lt;br /&gt;
&lt;br /&gt;
=== OFF and ON ===&lt;br /&gt;
&lt;br /&gt;
Preferably, turn the power off by holding the &#039;&#039;Start&#039;&#039; button for more than 5 seconds.&lt;br /&gt;
&lt;br /&gt;
[[file:PCB-off-and-on.png | 700px]]&lt;br /&gt;
&lt;br /&gt;
This will illuminate 3 LEDs in the LED band. These will gradually go off, and then the power will be cut.&lt;br /&gt;
&lt;br /&gt;
The Teensy display will show &#039;&#039;power off in XX seconds&#039;&#039; while waiting for the Raspberry to shut down. And usually 10 seconds longer, just in case.&lt;br /&gt;
&lt;br /&gt;
The Raspberry will be asked to &#039;&#039;shutdown&#039;&#039; during the wait time.&lt;br /&gt;
&lt;br /&gt;
To power on, press the &#039;&#039;power&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;power cut&#039;&#039; switch should not be used while the Raspberry is running.&lt;br /&gt;
It will usually be OK, but the disk may crash.&lt;br /&gt;
&lt;br /&gt;
===Raspberry Pi shutdown===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi can alternatively be shut down from the command line.&lt;br /&gt;
&lt;br /&gt;
Use the command&lt;br /&gt;
 sudo shutdown now&lt;br /&gt;
Then, wait about 30 seconds before cutting the power.&lt;br /&gt;
&lt;br /&gt;
This will ensure that all open files are closed correctly and that the system date and time are stored for the next boot.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_B&amp;diff=8655</id>
		<title>Robobot B</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_B&amp;diff=8655"/>
		<updated>2026-02-01T15:09:07Z</updated>

		<summary type="html">&lt;p&gt;Jca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Robobot is a robot platform for innovative applications, especially the annual DTU Robocup competition.&lt;br /&gt;
&lt;br /&gt;
=Robobot=&lt;br /&gt;
&lt;br /&gt;
[[File:robobot-in-blocks-2024.png | 600px]]&lt;br /&gt;
[[File:robobot-rev_8_frog.jpg | 400px]]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
This section is intended for users.&lt;br /&gt;
&lt;br /&gt;
* Getting started&lt;br /&gt;
** [[Robobot 1 | Battery power]] and shut down&lt;br /&gt;
** [[Robobot 2 | Network access]] &lt;br /&gt;
** [[Robobot 2b | Software update]] &lt;br /&gt;
** [[Robobot 3 | Camera view]]&lt;br /&gt;
** [[Robobot 4 | Python control]]&lt;br /&gt;
** [[Robobot 5 | Firmware tools]]&lt;br /&gt;
* System description&lt;br /&gt;
** [[Robobot architecture | System overview]] and top-level blocks description.&lt;br /&gt;
** [[Robobot MQTT-client]]&lt;br /&gt;
** [[Robobot webcam server]]&lt;br /&gt;
** [[Robobot teensy interface]]&lt;br /&gt;
** [[Robobot teensy firmware]]&lt;br /&gt;
** [[Robobot MQTT topics]]&lt;br /&gt;
** [[Robobot calibration]]&lt;br /&gt;
* Further details&lt;br /&gt;
** Start button to start mission, see first part of [[Enable autostart]]&lt;br /&gt;
** [[Robobot and MATLAB]] use of logfiles.&lt;br /&gt;
** [[Raspberry Pi directory structure for Robobot | Network access]], file share and directory structure.&lt;br /&gt;
** [[Robobot hardware]] items. Motors, sensors, plastic and screws.&lt;br /&gt;
** [[Robobot circuits]], PCB and circuit diagrams&lt;br /&gt;
&lt;br /&gt;
==Developers notes==&lt;br /&gt;
&lt;br /&gt;
This section contains notes on robot installation.&lt;br /&gt;
&lt;br /&gt;
* [[Robobot install on Raspberry]] including all needed packages.&lt;br /&gt;
* DTU network and time setup: [[Network setup]]&lt;br /&gt;
* [[Robobot base software installation]] like teensy_interface&lt;br /&gt;
* [[Enable autostart]] and IP display as well as on_reboot script.&lt;br /&gt;
* [[Servo supply issue]] Especially the small servo X9MG.&lt;br /&gt;
&lt;br /&gt;
Arduino firmware - one of these:&lt;br /&gt;
* Installation of [[Arduino and Teensy libraries]] when using the Arduino IDE.&lt;br /&gt;
* Installation of [[Visual studio support | Visual Studio Code]] when working on a standard PC. There may be further help here [[Import code to Visual Studio]]&lt;br /&gt;
* installation of [[Arduino command line support | Command line support]] for use on the Raspberry Pi.&lt;br /&gt;
&lt;br /&gt;
Help and setup&lt;br /&gt;
* [[Help page Teensy_8]] from on-line command &#039;&#039;help&#039;&#039;.&lt;br /&gt;
* [[Robobot processor]] initialise setup of Teensy (factory reset)&lt;br /&gt;
* [[Robobot Raspberry strange error]] Unexplained error (January 2026, Trixie image, not cloned).&lt;br /&gt;
* [[Robobot packing list]].&lt;br /&gt;
* [[Robobot logfile cleanup]].&lt;br /&gt;
&lt;br /&gt;
Simulator (webots)&lt;br /&gt;
* https://github.com/WildWillyRobots/DtuRobocupWebots.git is a simulator for the DTU Robocup track for the 2025 track. Created by Jonas Sølvhøj.&lt;br /&gt;
&lt;br /&gt;
Older pages&lt;br /&gt;
&lt;br /&gt;
* Old [[robobot]] instructions are mostly deprecated&lt;br /&gt;
* Some architecture notes [[Robobot Teensy interface]].&lt;br /&gt;
* [[Robobot software description | Software description]] and examples.&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_logfile_cleanup&amp;diff=8654</id>
		<title>Robobot logfile cleanup</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_logfile_cleanup&amp;diff=8654"/>
		<updated>2026-02-01T15:04:37Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Logfiles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Logfiles ==&lt;br /&gt;
&lt;br /&gt;
Many logfiles will accumulate over time.&lt;br /&gt;
&lt;br /&gt;
To clean up these files, there are two scripts in the setup directory.&lt;br /&gt;
&lt;br /&gt;
A total cleanup could be:&lt;br /&gt;
 cd ~/svn/robobot/setup&lt;br /&gt;
 ./clean_logfiles.bash&lt;br /&gt;
 sudo ./clean_logfiles_sudo.bash&lt;br /&gt;
&lt;br /&gt;
=== Files owned by &#039;&#039;local&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
This script removes all images from the mqtt_python directory and automatically generated log files.&lt;br /&gt;
&lt;br /&gt;
 clean_logfiles.bash:&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # clean logfiles before flash image&lt;br /&gt;
 # teensy_interface&lt;br /&gt;
 rm -r /home/local/svn/robobot/teensy_interface/build/log_20*&lt;br /&gt;
 rm /home/local/svn/robobot/teensy_interface/build/out_*.txt&lt;br /&gt;
 # mqtt_python&lt;br /&gt;
 rm /home/local/svn/robobot/mqtt_python/image*.jpg&lt;br /&gt;
 rm /home/local/svn/robobot/mqtt_python/log*.txt&lt;br /&gt;
 # log&lt;br /&gt;
 rm -r /home/local/svn/log/log_20*&lt;br /&gt;
 rm /home/local/svn/log/ip_disp.out&lt;br /&gt;
 rm /home/local/svn/log/log_*.txt&lt;br /&gt;
 rm /home/local/svn/log/rebootinfo.txt&lt;br /&gt;
 # these are owned by root&lt;br /&gt;
 # rm /home/local/svn/log/rename_info.txt&lt;br /&gt;
 # rm /home/local/svn/log/off_by*.txt&lt;br /&gt;
 echo &amp;quot;all clean (except svn/log/rename_info.txt and off_by*.txt that is owned by root)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Files owned by &#039;&#039;root&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
The host rename and off_by_mqtt run as user &#039;root&#039;, so the files are owned by &#039;root&#039;.&lt;br /&gt;
These need to be removed with the &#039;&#039;sudo&#039;&#039; command.&lt;br /&gt;
&lt;br /&gt;
 clean_logfiles_sudo.bash:&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # clean logfiles before flash image&lt;br /&gt;
 # these are owned by root&lt;br /&gt;
 rm /home/local/svn/log/rename_info.txt&lt;br /&gt;
 rm /home/local/svn/log/off_by*.txt&lt;br /&gt;
 echo &amp;quot;all root-logfiles clean&amp;quot;&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_logfile_cleanup&amp;diff=8653</id>
		<title>Robobot logfile cleanup</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_logfile_cleanup&amp;diff=8653"/>
		<updated>2026-02-01T15:03:45Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Files owned by root */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Logfiles ==&lt;br /&gt;
&lt;br /&gt;
Many logfiles will accumulate over time.&lt;br /&gt;
&lt;br /&gt;
To clean up these files, there are two scripts in the setup directory.&lt;br /&gt;
&lt;br /&gt;
A total cleanup could be:&lt;br /&gt;
 cd ~/svn/robobot/setup&lt;br /&gt;
 ./clean_&lt;br /&gt;
&lt;br /&gt;
=== Files owned by &#039;&#039;local&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
This script removes all images from the mqtt_python directory and automatically generated log files.&lt;br /&gt;
&lt;br /&gt;
 clean_logfiles.bash:&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # clean logfiles before flash image&lt;br /&gt;
 # teensy_interface&lt;br /&gt;
 rm -r /home/local/svn/robobot/teensy_interface/build/log_20*&lt;br /&gt;
 rm /home/local/svn/robobot/teensy_interface/build/out_*.txt&lt;br /&gt;
 # mqtt_python&lt;br /&gt;
 rm /home/local/svn/robobot/mqtt_python/image*.jpg&lt;br /&gt;
 rm /home/local/svn/robobot/mqtt_python/log*.txt&lt;br /&gt;
 # log&lt;br /&gt;
 rm -r /home/local/svn/log/log_20*&lt;br /&gt;
 rm /home/local/svn/log/ip_disp.out&lt;br /&gt;
 rm /home/local/svn/log/log_*.txt&lt;br /&gt;
 rm /home/local/svn/log/rebootinfo.txt&lt;br /&gt;
 # these are owned by root&lt;br /&gt;
 # rm /home/local/svn/log/rename_info.txt&lt;br /&gt;
 # rm /home/local/svn/log/off_by*.txt&lt;br /&gt;
 echo &amp;quot;all clean (except svn/log/rename_info.txt and off_by*.txt that is owned by root)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Files owned by &#039;&#039;root&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
The host rename and off_by_mqtt run as user &#039;root&#039;, so the files are owned by &#039;root&#039;.&lt;br /&gt;
These need to be removed with the &#039;&#039;sudo&#039;&#039; command.&lt;br /&gt;
&lt;br /&gt;
 clean_logfiles_sudo.bash:&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # clean logfiles before flash image&lt;br /&gt;
 # these are owned by root&lt;br /&gt;
 rm /home/local/svn/log/rename_info.txt&lt;br /&gt;
 rm /home/local/svn/log/off_by*.txt&lt;br /&gt;
 echo &amp;quot;all root-logfiles clean&amp;quot;&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_logfile_cleanup&amp;diff=8652</id>
		<title>Robobot logfile cleanup</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_logfile_cleanup&amp;diff=8652"/>
		<updated>2026-02-01T15:03:35Z</updated>

		<summary type="html">&lt;p&gt;Jca: /* Files owned by local */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Logfiles ==&lt;br /&gt;
&lt;br /&gt;
Many logfiles will accumulate over time.&lt;br /&gt;
&lt;br /&gt;
To clean up these files, there are two scripts in the setup directory.&lt;br /&gt;
&lt;br /&gt;
A total cleanup could be:&lt;br /&gt;
 cd ~/svn/robobot/setup&lt;br /&gt;
 ./clean_&lt;br /&gt;
&lt;br /&gt;
=== Files owned by &#039;&#039;local&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
This script removes all images from the mqtt_python directory and automatically generated log files.&lt;br /&gt;
&lt;br /&gt;
 clean_logfiles.bash:&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # clean logfiles before flash image&lt;br /&gt;
 # teensy_interface&lt;br /&gt;
 rm -r /home/local/svn/robobot/teensy_interface/build/log_20*&lt;br /&gt;
 rm /home/local/svn/robobot/teensy_interface/build/out_*.txt&lt;br /&gt;
 # mqtt_python&lt;br /&gt;
 rm /home/local/svn/robobot/mqtt_python/image*.jpg&lt;br /&gt;
 rm /home/local/svn/robobot/mqtt_python/log*.txt&lt;br /&gt;
 # log&lt;br /&gt;
 rm -r /home/local/svn/log/log_20*&lt;br /&gt;
 rm /home/local/svn/log/ip_disp.out&lt;br /&gt;
 rm /home/local/svn/log/log_*.txt&lt;br /&gt;
 rm /home/local/svn/log/rebootinfo.txt&lt;br /&gt;
 # these are owned by root&lt;br /&gt;
 # rm /home/local/svn/log/rename_info.txt&lt;br /&gt;
 # rm /home/local/svn/log/off_by*.txt&lt;br /&gt;
 echo &amp;quot;all clean (except svn/log/rename_info.txt and off_by*.txt that is owned by root)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Files owned by &#039;&#039;root&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
The host rename and off_by_mqtt run as user &#039;root&#039;, so the files are owned by &#039;root&#039;.&lt;br /&gt;
These need to be removed with the &#039;&#039;sudo&#039;&#039; command.&lt;br /&gt;
&lt;br /&gt;
clean_logfiles_sudo.bash:&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # clean logfiles before flash image&lt;br /&gt;
 # these are owned by root&lt;br /&gt;
 rm /home/local/svn/log/rename_info.txt&lt;br /&gt;
 rm /home/local/svn/log/off_by*.txt&lt;br /&gt;
 echo &amp;quot;all root-logfiles clean&amp;quot;&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
	<entry>
		<id>https://rsewiki.electro.dtu.dk/index.php?title=Robobot_logfile_cleanup&amp;diff=8651</id>
		<title>Robobot logfile cleanup</title>
		<link rel="alternate" type="text/html" href="https://rsewiki.electro.dtu.dk/index.php?title=Robobot_logfile_cleanup&amp;diff=8651"/>
		<updated>2026-02-01T15:03:23Z</updated>

		<summary type="html">&lt;p&gt;Jca: Created page with &amp;quot;Back to  Robobot  == Logfiles ==  Many logfiles will accumulate over time.  To clean up these files, there are two scripts in the setup directory.  A total cleanup could be:  cd ~/svn/robobot/setup  ./clean_  === Files owned by &amp;#039;&amp;#039;local&amp;#039;&amp;#039; ===  This script removes all images from the mqtt_python directory and automatically generated log files.  clean_logfiles.bash:  #!/bin/bash  # clean logfiles before flash image  # teensy_interface  rm -r /home/local/svn/r...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Back to [[Robobot_B | Robobot]]&lt;br /&gt;
&lt;br /&gt;
== Logfiles ==&lt;br /&gt;
&lt;br /&gt;
Many logfiles will accumulate over time.&lt;br /&gt;
&lt;br /&gt;
To clean up these files, there are two scripts in the setup directory.&lt;br /&gt;
&lt;br /&gt;
A total cleanup could be:&lt;br /&gt;
 cd ~/svn/robobot/setup&lt;br /&gt;
 ./clean_&lt;br /&gt;
&lt;br /&gt;
=== Files owned by &#039;&#039;local&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
This script removes all images from the mqtt_python directory and automatically generated log files.&lt;br /&gt;
&lt;br /&gt;
clean_logfiles.bash:&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # clean logfiles before flash image&lt;br /&gt;
 # teensy_interface&lt;br /&gt;
 rm -r /home/local/svn/robobot/teensy_interface/build/log_20*&lt;br /&gt;
 rm /home/local/svn/robobot/teensy_interface/build/out_*.txt&lt;br /&gt;
 # mqtt_python&lt;br /&gt;
 rm /home/local/svn/robobot/mqtt_python/image*.jpg&lt;br /&gt;
 rm /home/local/svn/robobot/mqtt_python/log*.txt&lt;br /&gt;
 # log&lt;br /&gt;
 rm -r /home/local/svn/log/log_20*&lt;br /&gt;
 rm /home/local/svn/log/ip_disp.out&lt;br /&gt;
 rm /home/local/svn/log/log_*.txt&lt;br /&gt;
 rm /home/local/svn/log/rebootinfo.txt&lt;br /&gt;
 # these are owned by root&lt;br /&gt;
 # rm /home/local/svn/log/rename_info.txt&lt;br /&gt;
 # rm /home/local/svn/log/off_by*.txt&lt;br /&gt;
 echo &amp;quot;all clean (except svn/log/rename_info.txt and off_by*.txt that is owned by root)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Files owned by &#039;&#039;root&#039;&#039; ===&lt;br /&gt;
&lt;br /&gt;
The host rename and off_by_mqtt run as user &#039;root&#039;, so the files are owned by &#039;root&#039;.&lt;br /&gt;
These need to be removed with the &#039;&#039;sudo&#039;&#039; command.&lt;br /&gt;
&lt;br /&gt;
clean_logfiles_sudo.bash:&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 # clean logfiles before flash image&lt;br /&gt;
 # these are owned by root&lt;br /&gt;
 rm /home/local/svn/log/rename_info.txt&lt;br /&gt;
 rm /home/local/svn/log/off_by*.txt&lt;br /&gt;
 echo &amp;quot;all root-logfiles clean&amp;quot;&lt;/div&gt;</summary>
		<author><name>Jca</name></author>
	</entry>
</feed>