This documentation explains how to set up the ADA Feeding System in the Robot Studio lab. We are adapting the Personal Robotics Lab’s setup to support a Gen3 robot.
Currently, following this guide will allow you to set up ADA Feeding on your system and run the simulation with a Jaco2 robot. For additional details, refer to the Work in Progress section.
Regarding Gen3 functionality, at this stage you can only control motion plans for the Gen3 robot within the ada_ros2 directory.
- The Robot Studio GitHub repo is linked here.
- These steps are edited from the original Personal Robotics Lab’s
ada_feedingsetup, which can be found here or within thePRsetupfolder. - Replace all instances of
YOUR_WORKSPACE_PATHwith your actual workspace directory. - If working from the shared directory, make sure you are sourcing the correct settings for Cyclone DDS. Follow Step 9 below.
- Installing Virtual Ubuntu 22.04
- Installing ROS2 Humble
- Clone pr-rosinstalls
- Install repositories
- Configure rosdep
- Install rosdep dependencies
- Install and fix non-rosdep dependencies
- Installing pyrealsense (for ARM users) – Build from Source
- Setup CycloneDDS
- Build your workspace
- Installing the webapp
- Running the Software
- Work in Progress Notes
- Troubleshooting
Ensure your environment runs Ubuntu 22.04, either natively or through WSL for Windows users.
lsb_release -awsl --install Ubuntu-22.04 ROS2 Humble is the middleware for robot communication and motion planning. These steps will configure your system locale, install ROS2 packages, and verify the installation.
Check whether ROS2 is installed (or follow the rest of the steps).
printenv ROS_DISTRO- Expected output for Humble:
humble - If Humble is already installed, skip to Verify ROS2 Works.
- If empty, ROS2 is not sourced yet.
- You can also check
/opt/ros/for any ROS distributions. - If none exist, continue with the installation steps below.
which python3- ROS2 Humble should use system Python:
/usr/bin/python3 - If it shows a conda/miniforge path, deactivate conda before proceeding:
conda deactivatelocale- Ensure UTF-8 is enabled (
en_US.UTF-8). - If not, run:
sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8
locale # verify settingssudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb"
sudo dpkg -i /tmp/ros2-apt-source.deb
sudo apt update
sudo apt upgrade
sudo apt install ros-humble-desktop
sudo apt install ros-humble-ros-base
sudo apt install ros-dev-tools
source /opt/ros/humble/setup.bashOpen two terminals:
Terminal 1:
source /opt/ros/humble/setup.bash
ros2 run demo_nodes_cpp talkerTerminal 2:
source /opt/ros/humble/setup.bash
ros2 run demo_nodes_py listener- The talker should publish messages, and the listener should print out:
I heard ...
Tip: Refer to the Troubleshooting section if you encounter any errors.
This will install the ada_feeding, ada_ros2, and other repositories required for the program.
cd ~
git clone https://github.com/studiorobot/pr-rosinstalls.gitReplace <https/ssh> with your preferred authentication method.
Note: You must have access rights to Robot Studio — see troubleshooting for help.
sudo apt install python3-wstool # if not already installed
cd YOUR_WORKSPACE_PATH # create a workspace/src for project
wstool init
wstool merge ~/pr-rosinstalls/ada-feeding.<https/ssh>.rosinstall
wstool upsudo apt install python3-rosdep # if not already installed
sudo rosdep init # only needed the first time using rosdeprosdep update
cd YOUR_WORKSPACE_PATH
rosdep install --from-paths src -y --ignore-src --as-root=pip:falsecd ~/YOUR_WORKSPACE_PATH/src/ada_feeding
python3 -m pip install -r requirements.txt- Upgrade
transforms3d(Ubuntu package is outdated):
python3 -m pip install transforms3d -U- Remove the duplicate matplotlib pip installation caused by installing scikit-spatial with pip (some accounts have required sudo access for this command, other have not. If you do not have sudo access and encounter this, contact a lab member who does):
python3 -m pip uninstall matplotlibpyrealsense2is not released for ARM systems. ARM users must build from source (see Step 8). You may need to add-DPYTHON_EXECUTABLE=/usr/bin/python3to thecmakecommand. When runningsudo make install, ensure the installation path is added to yourPYTHONPATH(usually/usr/local/lib).
sudo apt-get update && sudo apt-get dist-upgradeUse
dist-upgradeinstead ofupgradeif running an older Ubuntu version.
sudo apt-get install python3 python3-devgit clone https://github.com/IntelRealSense/librealsense.git
cd librealsensemkdir build
cd build
cmake ../ -DBUILD_PYTHON_BINDINGS:bool=true -DPYTHON_EXECUTABLE=$(which python3)
make -j4
sudo make installOptional CMake Flags:
- Build a self-contained (statically compiled) library:
-DBUILD_SHARED_LIBS=false
- Use a specific Python executable:
-DPYTHON_EXECUTABLE=[full path to desired python executable]
export PYTHONPATH=$PYTHONPATH:/usr/local/libIf the above doesn’t work:
export PYTHONPATH=$PYTHONPATH:/usr/local/lib/[python version]/pyrealsense2Copy the build output (librealsense2.so and pyrealsense2.so) next to your script.
Python 3 module filenames may include additional info, e.g.,
pyrealsense2.cpython-35m-arm-linux-gnueabihf.so
They recommend using CycloneDDS as your ROS2 midleware, with a custom configuration file that enables multicast on loopback and prioritizes loopback.
- Install CycloneDDS:
sudo apt install ros-humble-rmw-cyclonedds-cpp- Add the following lines to your
~/.bashrc:
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI=~/YOUR_WORKSPACE_PATH/src/ada_feeding/cyclonedds.xml- Create the
cyclonedds.xmlfile (not tracked by Robot Studio GitHub as it varies per environment):
cd ~/YOUR_WORKSPACE_PATH/src/ada_feeding/
nano cyclonedds.xml
sudo chown $USER:$USER cyclonedds.xml- Copy and paste the following into
cyclonedds.xml:
<?xml version="1.0" encoding="utf-8"?>
<CycloneDDS
xmlns="https://cdds.io/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://cdds.io/config https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/master/etc/cyclonedds.xsd"
>
<Domain Id="any">
<General>
<Interfaces>
<NetworkInterface name="lo" priority="default" multicast="true"/>
<NetworkInterface name="wlp0s20f3" priority="default" multicast="true"/>
</Interfaces>
</General>
</Domain>
</CycloneDDS>Notes:
- You may need to change the fallback interface if
lodoes not work. To do so, run ifconfig and either use the name of your ethernet network or WiFi network, depending on how your computer is connected to the internet.- After updating
cyclonedds.xml, rebuild your workspace from scratch.- IF YOU HAVE BOTH KINOVA KORTEX AND ADA SETUP: Adding the CYCLONEDDS_URI will cause DDS in Kortex files/program to fail so you must unset the URI when running Kortex API
unset CYCLONEDDS_URINote: At this stage, you should have multiple repositories cloned into your workspace. One of these repositories is ada_ros2.
- If you want to run the Gen2 simulation, switch to the
Jaco2branch of theada_ros2repo. - If you want to run the Gen3 simulation, use the
mainbranch instead.
Be aware that the ada_feeding setup is not fully compatible with Gen3 yet: the arm will appear in the system, but it won’t execute the full program because the Gen3 integration still needs updates.
Recommendation:
Start by building and testing everything on the Jaco2 branch (Gen2), confirm that it runs correctly, and then move on to Gen3 once you have a working baseline.
Note: Currently, communication with hardware is not set up. Therefore, the following command will only build the packages needed for simulation
cd ~/YOUR_WORKSPACE_PATH
colcon build --symlink-install --packages-skip KinovaExample ada_hardware
# Currently, hardware is not set up so do not build those packages
# Otherwise, use following command to build all
# colcon build --symlink-install - Install Node Version Manager [nvm] (https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script):
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash- Install and use NodeJS 21:
nvm install 21
nvm use 21If you have just installed nvm using the previous command, you will need to source your .bashrc or open a new terminal to run these commands
- (Only for users with sudo access; this should already be configured on PRL computers) Make Node available to all users, including root:
sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/node" "/usr/local/bin/node"
sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/npm" "/usr/local/bin/npm"
sudo ln -s "$NVM_DIR/versions/node/$(nvm version)/bin/npx" "/usr/local/bin/npx"- (Only for users with sudo access; this should already be configured on PRL computers) Install serve and pm2 globally. Root access is necessary for serve so it can access port 80.
sudo npm install -g serve
npm install -g pm2@latest- Install the web app dependencies. (Note: there will be some vulnerabilities in dependencies. This is okay, since access to the web app is shielded behind our secure router.)
cd ~/YOUR_WORKSPACE_PATH/src/feeding_web_interface/feedingwebapp
npm install --legacy-peer-deps
npx playwright install- (Optional; this should already be configured on PRL computers) To access the web app on a device other than the one hosting it, enable the desired port for HTTP access
sudo ufw enable
sudo ufw allow 80
sudo ufw allow 3000Currently, we are testing using Option B: Mock Robot as the real robot has not been configured to use yet. We use the convenience script start.py to launch the software. This script has several command-line arguments, which can be seen by passing the -h flag when running the script.
This option starts the web app and the real robot code, and can be used to test the entire system. This will by default start the web app on port 80, and requires sudo access. The robot's HDMI connection must be plugged into your computer, and your computer should be connected to the robot's router with an ethernet cable. NOTE: If not running on the production machine i.e., lovelace, it's recommended that you append the command line flag --dev to the start script. This will launch RVIZ, will not require the e-stop button to be plugged in, and will not require sudo access to launch the web app.
cd ~/YOUR_WORKSPACE_PATH
python3 src/ada_feeding/start.py-
In a browser, access
127.0.0.1(if on the same device serving the web app), or the IP address of the device hosting the web app (if on a different device connected to the same network, e.g. a cell phone connected to the LOVELACE_5g network). You should now be able to run the system! Note that upon startup, the watchdog is in a failing state until the e-stop is clicked exactly once, allowing the system to verify that it is connected and working. -
To close:
python3 src/ada_feeding/start.py -cThis option starts the web app, runs dummy nodes for perception, runs the real robot motion code, but runs a mock robot in MoveIt. This is useful for testing robot motion code in simulation before moving onto the real robot. This will start the web app on port 3000 and does not require sudo access.
For Gen2 Jaco Robot:
cd ~/YOUR_WORKSPACE_PATH
python3 src/ada_feeding/start.py --sim mock_jaco-
In a browser, access
127.0.0.1:3000(if on the same device serving the web app), or the IP address of the device hosting the web app at port3000(if on a different device connected to the same network). You should now be able to run the system! -
You should see the webapp and a simulation in RVIZ with the Jaco2 robot. You should be able to choose different actions through the webapp and see the execution in the simulation.
-
To close:
python3 src/ada_feeding/start.py --sim mock_jaco -cFor Gen3 Kortex Robot (Not functional yet):
cd ~/YOUR_WORKSPACE_PATH
python3 src/ada_feeding/start.py --sim mock_kortex-
In a browser, access 127.0.0.1:3000 (if on the same device serving the web app), or the IP address of the device hosting the web app at port 3000 (if on a different device connected to the same network). You should now be able to run the system!
-
Close with:
python3 src/ada_feeding/start.py --sim mock_kortex -cThis option starts the web app, and runs dummy nodes for all perception and robot motion code. This is useful to test the web app in isolation. This will start the web app on port 3000 and does not require sudo access.
cd ~/YOUR_WORKSPACE_PATH
python3 src/ada_feeding/start.py --sim dummy- In a browser, access 127.0.0.1:3000 (if on the same device serving the web app), or the IP address of the device hosting the web app at port 3000 (if on a different device connected to the same network). You should now be able to run the system!
- To close:
python3 src/ada_feeding/start.py --sim dummy -c- The feeding setup is currently functional for older Jaco 2 robots.
- Food acquisition is the only action not working, likely because there is no actual plate of food for the robot to acquire.
ada_ros2 is compatible with the Gen 3 Kortex robot. Its responsibilities include:
- Launching the robot and correlated sensors.
- Setting up the ROS 2 environment.
- Handling communication with the robot in both simulation and real hardware.
Within the ada_ros2 directory, you can test simulation using:
ros2 launch ada_moveit demo.launch.py sim:=mockThis works for Jaco2 robots.
To run the Gen 3 robot in simulation, temporarily switch the description files in ada_description:
-
Navigate to the
urdffolder. -
Rename files:
ada.xacro → ada.jaco2.txt ada.gen3.txt → ada.xacro -
In the
rvizfolder, rename:view_robot.rviz → view_robot.jaco2.txt view_robot.gen3.txt → view_robot.rviz
This swaps in the Gen 3 description while preserving Jaco2 files. Currently working on a way to do this without having to switch config files between Jaco2 vs Gen3. ** Not completely sure, but if you switch and build the respective branch in ada_ros2 (jaco2 vs gen3), you may not have to change the previous file names. Read through those files and confirm the correct robot is being sourced.
- Build the workspace:
colcon build- Navigate to
ada_ros2and source the setup script:
source ../install/setup.bash- Launch the Gen 3 simulation:
ros2 launch ada_moveit_kortex demo.launch.py sim:=mockThis will allow you to see ada_ros2 working with Gen 3 in simulation. You should be able to plan motions for the Gen 3 robot in RVIZ. The orientation of the fork and camera mount need to be fixed.
- A planning scene needs to be created that defines where and when the Gen 3 robot should move.
- This ensures coordinated operation with the feeding application.
- The Kortex API is installed in the repository.
- Write a
gen3.cppfile using the Kortex API to control the Gen 3 hardware.
The ADA Feeding system launches multiple isolated workspaces, called screens, to handle different components independently.
These include feeding logic, robot simulation, sensors, and the web interface. Each screen runs in its own terminal session, making it easier to manage and debug specific parts of the system.
To attach to a running screen and see real-time logs:
screen -r <screen_name>Replace <screen_name> with the component you want to monitor (e.g., feeding, robot_sim, sensors, web_interface).
- Attach to the desired screen:
screen -r <screen_name>- Start logging the session:
Ctrl-A H
This will save output to
screenlog.0in the current directory.
- To stop logging:
Ctrl-A H
- Rename and move the log file for later reference:
mv screenlog.0 ~/logs/<screen_name>_$(date).logCommon error:
Waiting for robot_description to be published on the robot_description topic
- Source the proper workspaces/repos before launching files.
- Check if ROS 2 nodes are communicating:
ros2 node list- If nodes/topics appear correctly, it’s not a ROS 2 DDS issue.
- Test minimal
talker/listenernodes. - On Linux, check firewall status:
sudo ufw status
sudo ufw allow 7400:7500/udp- Launch your file again.
Clear inactive screens:
screen -wipeExample: ModuleNotFoundError: No module named 'yourdfpy'
pip3 install yourdfpy- Check if you already have an SSH key:
ls ~/.sshLook for id_ed25519 / id_ed25519.pub or id_rsa / id_rsa.pub.
- If no SSH key exists, generate one:
ssh-keygen -t ed25519 -C "your_email@example.com"Hit Enter through all prompts unless you want a custom path/passphrase.
- Start the SSH agent:
eval "$(ssh-agent -s)"- Add your SSH key to the agent:
ssh-add ~/.ssh/id_ed25519- Copy your public key:
cat ~/.ssh/id_ed25519.pub- Add the key to GitHub:
- GitHub → Settings → SSH and GPG keys → New SSH key → Paste → Save
- Verify GitHub SSH access:
ssh -T git@github.comExpected output:
Hi <username>! You've successfully authenticated...
- Clone the repo using SSH:
git clone git@github.com:<user>/<repo>.git- Check Git installation:
git --version- Set global Git identity:
git config --global user.name "Your Name"
git config --global user.email "your_email@example.com"- Uninstall Conan 2.x:
python3 -m pip uninstall -y conan- Install Conan 1.x:
python3 -m pip install "conan<2.0" --user- Add Conan to PATH:
export PATH=$HOME/.local/bin:$PATH- Verify version:
conan --version- Detect system settings:
conan profile detect- Verify default profile exists:
conan profile list- Navigate to workspace:
cd ~/YOUR_WORKSPACE_PATH- Clean previous builds:
rm -rf build/ install/ log/- Rebuild all packages:
colcon build --symlink-install- Cause: Build took too much memory and crashed.
- Solution: Remove build logs and build with 1 parallel worker.
rm -rf build log install
colcon build --symlink-installIf sourcing older configs, reset MoveIt:
rm -rf ~/.moveitIf everything seems to load correctly but the web app never gets past “thinking” and simulation does not move, first verify that ROS2 and the action servers are actually responding.
-
From the
ada_feeding/ada_feedingdirectory, run the following tests (from the original PRL README):ros2 action send_goal /MoveAbovePlate ada_feeding_msgs/action/MoveTo "{}" --feedback ros2 action send_goal /AcquireFood ada_feeding_msgs/action/AcquireFood "{header: {stamp: {sec: 0, nanosec: 0}, frame_id: ''}, detected_food: {roi: {x_offset: 0, y_offset: 0, height: 0, width: 0, do_rectify: false}, mask: {header: {stamp: {sec: 0, nanosec: 0}, frame_id: ''}, format: '', data: []}, item_id: '', confidence: 0.0}}" --feedback ros2 action send_goal /MoveToRestingPosition ada_feeding_msgs/action/MoveTo "{}" --feedback ros2 action send_goal /MoveToStagingConfiguration ada_feeding_msgs/action/MoveTo "{}" --feedback ros2 action send_goal /MoveToMouth ada_feeding_msgs/action/MoveToMouth "{}" --feedback ros2 action send_goal /MoveFromMouth ada_feeding_msgs/action/MoveTo "{}" --feedback ros2 action send_goal /MoveToStowLocation ada_feeding_msgs/action/MoveTo "{}" --feedback
If these actions return feedback, then **MoveIt + ROS2 + simulation are working correctly**.
Next steps:
* If running the **Web App locally**, try clearing your browser cache:
* Open browser history
* Delete cached data
* Restart the program
This often resolves the web app getting stuck after successful ROS2 startup.
---