Skip to content

Instantly share code, notes, and snippets.

@jackersson
Last active July 1, 2020 07:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jackersson/b1fd3aedc0fe59b7968576c5a2f67fe6 to your computer and use it in GitHub Desktop.
Save jackersson/b1fd3aedc0fe59b7968576c5a2f67fe6 to your computer and use it in GitHub Desktop.
Raspberry Ubuntu Installation

Imager installation

wget https://downloads.raspberrypi.org/imager/imager_amd64.deb
sudo dpkg -i imager_amd64.deb

Using command line

sudo apt install xz-utils
unxz ubuntu-18.04.4-preinstalled-server-armhf+raspi3.img.xz
lsblk -p  # findout SD card /dev/mmcblk0

# format FAT32
sudo mkfs.vfat -F32 -v /dev/mmcblk0 

# Record image
dd bs=4M if=ubuntu-18.04.4-preinstalled-server-armhf+raspi3.img of=/dev/mmcblk0 conv=fsync status=progress
sync

2. Ubuntu Server ARM images (Download Section)

  • On SD card there is going to be mounted: /system-boot and /writable partitions
3.1 Make able to boot
# Add next lines to /system-boot/usercfg.txt
kernel=vmlinuz
initramfs initrd.img followkernel
3.3 [SSH configure]
# in /system-boot
touch ssh

5. Use SSH to connect to PI

ssh ubuntu@<Raspberry Pi’s IP address>

6. Setup

sudo add-apt-repository ppa:ubuntu-pi-flavour-makers/ppa
sudo apt update

sudo apt upgrade
sudo apt install rpi.gpio-common \
  python-rpi.gpio \
  python3-rpi.gpio \
  u-boot-rpi \
  linux-firmware-raspi2 \
  linux-image-raspi2 \
  raspi-config \
  libraspberrypi-bin \
  raspberrypi-sys-mods
  
  • config.txt located /boot/firmware/config.txt
  • Note: changes only in /boot/firmware/config.txt will affect RPI
  • Note: use official config.txt to enable/disable features or setup parameters.

Enable Camera

sudo raspi-config

Interfacing Options -> Camera -> Enable

sudo reboot now
Check config
start_x=1
gpu_mem=128

Night Mode

add to config.txt -> disable_camera_led=1

sudo reboot now

Check camera

# On PI
raspivid -l -t 0 -w 640 -h 480 -ss 1000 -fps 60 --codec MJPEG -o tcp://<Pi IP Address>:5000

# On PC
gst-launch-1.0 tcpclientsrc host=<Pi IP Address> port=5000 ! jpegdec ! videoconvert ! autovideosink

ROS Install

  • Note: use installation without desktop related packages
# ROS-Base: (Bare Bones)
sudo apt install ros-*-ros-base

Catkin WS

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/


sudo apt install python3-pip
pip3 install catkin_pkg

catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3
source devel/setup.bash

Troubleshoot

Check compatible cameras

vcgencmd get_camera

/var/lib/dpkg/lock

  • ‘E: Could not get lock /var/lib/dpkg/lock’ Error in Ubuntu Linux Solution
  • Solution: Wait for system to update.
sudo fsck -fy /dev/mmcblk0

Mount/Unmount

mount | grep /dev/mmc
sudo umount /dev/mmcblk0p1

SSH Reconfigure

  • Note: When first launch wait until ssh keys properly configured
sudo apt install openssh-server
sudo systemctl status ssh
sudo systemctl enable ssh

sudo dpkg-reconfigure openssh-server
sudo ufw allow ssh

References

#!/usr/bin/env python
import time
import RPi.GPIO as GPIO
# Use GPIO numbering
GPIO.setmode(GPIO.BCM)
# Set GPIO for camera LED
# Use 5 for Model A/B and 32 for Model B+
CAMLED = 5
# Set GPIO to output
GPIO.setup(CAMLED, GPIO.OUT, initial=False)
# Five iterations with half a second
# between on and off
GPIO.output(CAMLED, False) # On
sudo apt-get -y --no-install-recommends install \
git \
cmake \
autoconf \
automake \
libtool \
gstreamer-1.0 \
gstreamer1.0-dev \
libgstreamer1.0-0 \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
gstreamer1.0-libav \
gstreamer1.0-doc \
gstreamer1.0-tools \
gstreamer1.0-x \
gstreamer1.0-alsa \
gstreamer1.0-gl \
gstreamer1.0-gtk3 \
gstreamer1.0-qt5 \
gstreamer1.0-pulseaudio \
python-gst-1.0 \
libgirepository1.0-dev \
libgstreamer-plugins-base1.0-dev \
libcairo2-dev \
gir1.2-gstreamer-1.0 \
python3-gi \
python-gi-dev
#!/usr/bin/env python3
import time
import struct
import rospy
import numpy as np
from sensor_msgs.msg import Imu
from tf.transformations import quaternion_about_axis
import smbus2 as smbus
import math
imu_pub = None
IMU_FRAME = None
# Register
MPU9250_RA_PWR_MGMT_1 = 0x6B
MPU9250_RA_PWR_MGMT_2 = 0x6C
def read_byte(reg):
return bus.read_byte_data(address, reg)
def read_word(reg):
h = bus.read_byte_data(address, reg)
l = bus.read_byte_data(address, reg+1)
value = (h << 8) + l
return value
def read_word_2c(reg):
val = read_word(reg)
if (val >= 0x8000):
return -((65535 - val) + 1)
else:
return val
def dist(a,b):
return math.sqrt((a*a)+(b*b))
def get_y_rotation(x,y,z):
radians = math.atan2(x, dist(y,z))
return -math.degrees(radians)
def get_x_rotation(x,y,z):
radians = math.atan2(y, dist(x,z))
return math.degrees(radians)
MPU9250_ADDRESS_AD0_LOW = 0x68 # address pin low (GND), default for InvenSense evaluation board
MPU9250_ADDRESS_AD0_HIGH = 0x69 # address pin high (VCC)
MPU9250_DEFAULT_ADDRESS = MPU9250_ADDRESS_AD0_LOW
bus = smbus.SMBus(1) # bus = smbus.SMBus(0) fuer Revision 1
address = MPU9250_DEFAULT_ADDRESS # via i2cdetect
bus.write_byte_data(address, MPU9250_RA_PWR_MGMT_1, 0)
# Consts from: https://github.com/linorobot/linorobot/tree/master/teensy/firmware/lib/imu
# Code from: https://github.com/OSUrobotics/mpu_6050_driver/blob/master/scripts/imu_node.py
# http://www.sureshjoshi.com/embedded/invensense-imus-what-to-know/
# https://stackoverflow.com/questions/19161872/meaning-of-lsb-unit-and-unit-lsb
# MPU9250 https://www.invensense.com/wp-content/uploads/2015/02/MPU-9150-Datasheet.pdf
G_TO_ACCEL = 9.81
MGAUSS_TO_UTESLA = 0.1
UTESLA_TO_TESLA = 0.000001
ACCEL_SCALE = 1.0 / 16384 # * G_TO_ACCEL # m/s^2
GYRO_SCALE = math.radians(1.0 / 131) # rad/s
GYRO_SCALE = 1.0 / 131 # rad/s
MAG_SCALE = 0.6 # uT/LSB
# accelerometer
MPU9250_RA_ACCEL_XOUT = 0x3B
MPU9250_RA_ACCEL_YOUT = 0x3D
MPU9250_RA_ACCEL_ZOUT = 0x3F
# gyro
MPU9250_RA_GYRO_XOUT = 0x43
MPU9250_RA_GYRO_YOUT = 0x45
MPU9250_RA_GYRO_ZOUT = 0x47
# magnetometer
MPU9150_RA_MAG_ADDRESS = 0x0C
MPU9150_RA_MAG_XOUT = 0x04
MPU9150_RA_MAG_YOUT = 0x06
MPU9150_RA_MAG_ZOUT = 0x08
# temperature
MPU9250_RA_TEMP_OUT = 0x41
def publish_imu(timer_event):
imu_msg = Imu()
imu_msg.header.frame_id = "map"
# Read the acceleration vals
# LSB/g (least significant bit per g)
accel_x = read_word_2c(MPU9250_RA_ACCEL_XOUT) * ACCEL_SCALE
accel_y = read_word_2c(MPU9250_RA_ACCEL_YOUT) * ACCEL_SCALE
accel_z = read_word_2c(MPU9250_RA_ACCEL_ZOUT) * ACCEL_SCALE
# Calculate a quaternion representing the orientation
accel = accel_x, accel_y, accel_z
ref = np.array([0, 0, 1])
acceln = accel / (np.linalg.norm(accel) + 1e-10)
axis = np.cross(acceln, ref)
angle = np.arccos(np.dot(acceln, ref))
orientation = quaternion_about_axis(angle, axis)
# Read the gyro vals
# 16-bit signed integer container for X, Y, Z -axis rotation
gyro_x = read_word_2c(MPU9250_RA_GYRO_XOUT) * GYRO_SCALE # rad/s
gyro_y = read_word_2c(MPU9250_RA_GYRO_YOUT) * GYRO_SCALE
gyro_z = read_word_2c(MPU9250_RA_GYRO_ZOUT) * GYRO_SCALE
print([gyro_x, gyro_y, gyro_z])
# Get current internal temperature
# Temperature reading in 16-bit 2's complement format
# celsius degrees
temperature = read_word_2c(MPU9250_RA_TEMP_OUT)
# TODO: Magnetometer
# https://github.com/linorobot/linorobot/blob/master/teensy/firmware/lib/imu/MPU9250.cpp#L1840
# Load up the IMU message
o = imu_msg.orientation
o.x, o.y, o.z, o.w = orientation
imu_msg.linear_acceleration.x = accel_x
imu_msg.linear_acceleration.y = accel_y
imu_msg.linear_acceleration.z = accel_z
imu_msg.angular_velocity.x = gyro_x
imu_msg.angular_velocity.y = gyro_y
imu_msg.angular_velocity.z = gyro_z
imu_msg.header.stamp = rospy.Time.now()
imu_pub.publish(imu_msg)
if __name__ == '__main__':
rospy.init_node('imu_node')
frequency = rospy.get_param('~frequency', 50) # Hz
IMU_FRAME = rospy.get_param('~imu_frame', 'imu_link') #
imu_pub = rospy.Publisher('imu/data_raw', Imu, queue_size=16)
imu_timer = rospy.Timer(rospy.Duration(1.0 / frequency), publish_imu)
rospy.spin()
Header header
string child_frame_id
uint32 id
geometry_msgs/PoseWithCovariance pose

On Robot Machine (RPI)

nano ~/.bashrc

Put the following text :

  • Replace "Local IP address" with IP Address (use ifconfig), ex: 192.168.0.103
source /home/ubuntu/catkin_ws/devel/setup.bash

# ROBOT Machine Configuration
# The localhost IP address = IP address for the Master Node
export ROS_MASTER_URI=http://localhost:11311
# The IP address for the Master Node
export ROS_HOSTNAME=<Local IP address>
export ROS_IP=<Local IP address>

echo "ROS_HOSTNAME: "$ROS_HOSTNAME
echo "ROS_IP: "$ROS_IP
echo "ROS_MASSTER_URI: "$ROS_MASTER_URI
  • Save and close
source ~/.bashrc

On Remote Machine

nano ~/.bashrc

Put the following text:

  • Local IP Address (ifconfig), ex: 192.168.0.106
  • Robot IP Address should be the same as in previos section ROS_IP
export ROS_IP=<Local IP Address>
export ROS_HOSTNAME=<Local IP Address>
export ROS_MASTER_URI=http://<Robot IP Address>:11311

echo "ROS_HOSTNAME: "$ROS_HOSTNAME
echo "ROS_IP: "$ROS_IP
echo "ROS_MASTER_URI: "$ROS_MASTER_URI
  • Save and close
source ~/.bashrc

0. Use precompiled image from next guide

  • download
  • login: ubuntu, password: raspberry
  • change your network params in /etc/netplan/50-cloud-init.yaml
  • put in raspberry and use

1. Download Image from ubuntu-server-download-page

  • Ubuntu Server 18.04
  • Rasbperry 4
  • 32-bit

2. Prepare SD card

Imager installation

wget https://downloads.raspberrypi.org/imager/imager_amd64.deb
sudo dpkg -i imager_amd64.deb

Using command line

sudo apt install xz-utils
unxz ubuntu-18.04.4-preinstalled-server-armhf+raspi3.img.xz
lsblk -p  # findout SD card /dev/mmcblk0

# format FAT32
sudo mkfs.vfat -F32 -v /dev/mmcblk0 

# Record image
dd bs=4M if=ubuntu-18.04.4-preinstalled-server-armhf+raspi3.img of=/dev/mmcblk0 conv=fsync status=progress
sync

SSH configure

# in /system-boot
touch ssh

Configure usrconfig.txt

  • Overclock Raspberry Pi 2.0ghz
over_voltage=4
arm_freq=2000
gpu_freq=650

3. Launch RPI

  • During the first launch wait for 3-5 minutes to setup everything via Internet Connection
  • Reboot and during the Second launch do next steps

Use SSH to connect to PI

ssh ubuntu@<Raspberry Pi’s IP address>

4. Prepare RPI

sudo apt update
sudo apt upgrade 
sudo reboot now


sudo add-apt-repository ppa:ubuntu-pi-flavour-makers/ppa  
sudo add-apt-repository ppa:ubuntu-raspi2/ppa
sudo apt update

sudo apt-get -y --no-install-recommends install \
  libraspberrypi-bin \
  libraspberrypi-dev \
  rpi.gpio-common \
  python-rpi.gpio \
  python3-rpi.gpio \
  raspi-config \
  raspberrypi-sys-mods\
  python3-pip \
  python-pip
  
sudo ln -s /usr /opt/vc

pip install -U wheel pip setuptools
pip3 install -U wheel pip setuptools
sudo groupadd -f --system gpio
sudo groupadd -f --system i2c
sudo groupadd -f --system input
sudo groupadd -f --system spi

sudo usermod -a -G gpio,i2c,input,spi ubuntu
  • config.txt located /boot/firmware/config.txt
  • Note: changes only in /boot/firmware/config.txt will affect RPI
  • Note: use official config.txt to enable/disable features or setup parameters.

Enable camera

sudo raspi-config

Interfacing Options -> Camera -> Enable

sudo reboot now

Check config

start_x=1
gpu_mem=128

Enable camera night-vision

/boot/firmware/config.txt
disable_camera_led=1

Test

raspivid -l -t 0 -w 640 -h 480 -ss 10000 -fps 60 --codec MJPEG -o tcp://<RPI IP Address>:5000
gst-launch-1.0 tcpclientsrc host=<RPI IP Address> port=5000 ! jpegdec ! videoconvert  !  gtksink

Enable I2C (IMU)

/boot/firmware/config.txt
dtparam=spi=on

Install Gstreamer

sudo apt-get -y --no-install-recommends install \
    git \
    cmake \
    autoconf \
    automake \
    libtool \
    gstreamer-1.0 \
    gstreamer1.0-dev \
    libgstreamer1.0-0 \
    gstreamer1.0-plugins-base \
    gstreamer1.0-plugins-good \
    gstreamer1.0-plugins-bad \
    gstreamer1.0-plugins-ugly \
    gstreamer1.0-libav \
    gstreamer1.0-doc \
    gstreamer1.0-tools \
    gstreamer1.0-x \
    gstreamer1.0-alsa \
    gstreamer1.0-gl \
    gstreamer1.0-gtk3 \
    gstreamer1.0-qt5 \
    gstreamer1.0-pulseaudio \
    python-gst-1.0 \
    libgirepository1.0-dev \
    libgstreamer-plugins-base1.0-dev \
    libcairo2-dev \
    gir1.2-gstreamer-1.0 \
    python3-gi \
    python-gi-dev

Install gstrpicamsrc

sudo apt-get install -y ninja-build

git clone https://github.com/thaytan/gst-rpicamsrc
cd gst-rpicamsrc

pip3 install --user meson
mkdir build
~/.local/bin/meson --prefix=/usr build
ninja -C build -v
cd build
sudo ninja install

Test



gst-launch-1.0 rpicamsrc preview=false ! "image/jpeg,width=320,height=240,framerate=30/1" ! tcpserversink host=<RPI IP Address> port=5000
gst-launch-1.0 tcpclientsrc host=<RPI IP Address> port=5000 ! jpegdec ! videoconvert  !  gtksink

Note

  • if rpicamsrc is not visible use:
export GST_PLUGIN_PATH=$GST_PLUGIN_PATH:/usr/local/lib/arm-linux-gnueabihf/gstreamer-1.0/

Install OpenCV

sudo apt-get update && sudo apt-get upgrade

sudo apt-get -y --no-install-recommends install \
  build-essential \
  cmake \
  unzip \
  pkg-config \
  python3-dev \
  python-dev \
  libjpeg-dev \
  libpng-dev \
  libtiff-dev \
  libavcodec-dev \
  libswscale-dev \
  libavformat-dev \
  libv4l-dev \
  v4l-utils \
  libxvidcore-dev \
  libx264-dev \
  libtbb2 \
  libtbb-dev \
  libdc1394-22-dev \
  libopenblas-dev \
  libatlas-base-dev \
  libblas-dev \
  liblapack-dev \
  gfortran \
  gcc-arm* \
  protobuf-compiler
  

mkdir ~/libs
cd libs 

wget -O opencv.zip https://github.com/opencv/opencv/archive/4.3.0.zip
wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.3.0.zip

unzip opencv.zip
unzip opencv_contrib.zip
mv opencv-4.3.0/ opencv/
mv opencv_contrib-4.3.0/ opencv_contrib/

pip3 install numpy

cd opencv
mkdir build
cd build/
export PYTHON=/usr/bin/python3
cmake -D CMAKE_BUILD_TYPE=RELEASE \
  -D CMAKE_INSTALL_PREFIX=/usr/local \
  -D OPENCV_EXTRA_MODULES_PATH=~/libs/opencv_contrib/modules \
  -D ENABLE_NEON=ON \
  -D ENABLE_VFPV3=ON \
  -D BUILD_TESTS=OFF \
  -D INSTALL_PYTHON_EXAMPLES=OFF \
  -D OPENCV_ENABLE_NONFREE=ON \
  -D CMAKE_SHARED_LINKER_FLAGS=-latomic \
  -D BUILD_EXAMPLES=OFF \
  -DWITH_GTK=OFF \
  BUILD_opencv_python3=TRUE \
  BUILD_opencv_python2=TRUE ..

make -j4

sudo make install
sudo ldconfig

Install ROS-melodic


sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654


sudo apt update
sudo apt install ros-melodic-ros-base

echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc

sudo apt-get -y --no-install-recommends install \
  python-rosdep \
  python-rosinstall \
  python-rosinstall-generator \
  python-wstool \
  build-essential

sudo rosdep init
rosdep update

sudo apt-get -y --no-install-recommends install \
  ros-melodic-ros-base \
  ros-melodic-controller-manager \
  ros-melodic-ros-control \
  ros-melodic-ros-tutorials \
  ros-melodic-angles

pip3 install catkin_pkg empy

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment