Skip to content

Pecking Test Computer

kevinyu edited this page Dec 15, 2020 · 37 revisions

We are transitioning to running all pecking test boxes in 125 on one computer (Dell Optiplex 5080 Small form factor). Most things will be similar to the old setup. We will be using the Behringer UMC404HD audio interface for audio in/out.

TODOs

Getting everything running

  1. Set up insync data syncing with Google Drive
  2. Acquire audio adapters for UMC404HD playback outputs (1/4" or RCA -> banana plugs?)
  3. Test that the pecking test data notebook works
  4. Configure audio input via UMC404HD (both alsa config and python?)
  5. Turn off (on the router) the virtual server for notebook and find a better way to serve the notebook remotely

Improvements

  1. Set PATH and PYTHONPATH correctly (and set PYTHONPATH per code base)
  2. Mount remote drive zdrive (under whose/which credentials?)
  3. Desktop shortcuts to launch webcams
  4. Get a new USB pci card that is compatible with Ubuntu 20.04 (linux kernel 5.4)
  5. Timestamp and Trial info overlay on webcam feeds
  6. Periodic uploads to zdrive

OS

  • hostname: plump
  • user: fet
  • pw: finchfinchfin

Upgraded from Ubuntu 18.04 to 20.04

USBs

The Optiplex 5080 has 9 usb ports built in (4 USB 3.2 on back, 2 USB2.0 on back, 3 USB3.2 on front, and 1 USB-C on front). However, we require at least 10 USB ports: 4 webcams, 4 arduinos, 1 audio interface, and 1 usb hub with connected keyboard and mouse. In theory, we could connect arduinos to usb hubs as well, but I would keep the webcams and audio interface on their own usbs, since hubs typically split the bandwidth of the port.

I got a startech usb pci expansion card but unfortunately it seems to only be compatible with older versions of linux. So we need to replace it. Until we do, I'll use a usb hub for the keyboard, mouse, and 2 arduinos.

Installed software

  • python3.9 sudo apt install python3.9-dev

  • git sudo apt install git

  • portaudio sudo apt install portaudio19-dev (needed for pecking test pyaudio)

  • nodejs and npm sudo apt install nodejs npm (needed only for jupyterlab extensions)

  • vlc (installed from .deb file)

  • slack

  • nettools sudo apt install nettools

  • libxcb-xinerama0 (this was needed for multiple mics test gui to work)

Setting up webcams

When devices udev gives them a file descriptor in /dev. For webcam devices, they are mapped to /dev/video0, /dev/video1, etc. The order is not consistent, so we want to recognize which webcam corresponds to which box and assign it to a static path /dev/video_box2, etc.

To do this, you can interrogate the device attributes with udevadm /dev/video{idx}. For the webcams, we can see that each device has a serial number. You can figure out which serial number then corresponds to each box, and add a udev rule that identifies the device by serial number (ATTRS{serial}==), and then assigns that device to a symlink (SYMLINK+=video_box{box}).

Here are the udev rules

# /etc/udev/rules.d/webcam.rules
SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{serial}=="2F611FC0", ATTR{index}=="0", ATTR{name}=="HD Webcam C525", SYMLINK+="video_box2"
SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{serial}=="62C94890", ATTR{name}=="UVC Camera (046d:081b)", ATTR{index}=="0", SYMLINK+="video_box3"
SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{serial}=="E8322CA0", ATTR{name}=="HD Webcam C525", ATTR{index}=="0", SYMLINK+="video_box5"
SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{serial}=="0E622C20", ATTR{name}=="HD Webcam C525", ATTR{index}=="0"SYMLINK+="video_box6"

I wrote a script to launch streams of all 4 webcams over http with VLC. The script in ~/code/webcam_viewer/run.py launches 4 instances of VLC streaming to Ports 8082, 8083, 8085, and 8086. They are accessible on localhost:8082/box2.ogg etc. Opening the file ~/code/webcam_viewer/index.html in the browser shows all 4 in a grid. But there is some latency and some problems with autoplaying and keeping the stream live in the browser, so maybe there's a better way. Worst case we just use 4 instances of the VLC viewer, but it would be nice to get it into a grid view.

Setting up audio interface

The UMC404HD interface has 4 playback outputs. In surround sound they correspond to front left, front right, rear left, rear right, and are numbered 1, 2, 3, and 4 respectively. To output to these channels we typically would output 4-channel surround sound, but we want individual control over each output.

I modified ~/.asoundrc to create a virtual device "split", locating the audio interface device with hw surround40:u192K. This seems to identify the audio interface reliably, so a udev rule to find the audio device doesn't seem to be necessary at the moment. Then it creates virtual devices speaker2, speaker3, speaker5 and speaker6 for each channel.

pcm.split {
  type dmix
  ipc_key 2048
  slave {
    pcm "surround40:U192k"
    channels 4
  }
}

pcm.speaker2 {
  type plug
  slave.pcm "split"
  ttable.0.0 1
}

pcm.speaker3 {
  type plug
  slave.pcm "split"
  ttable.0.1 1
}

pcm.speaker5 {
  type plug
  slave.pcm "split"
  ttable.0.2 1
}

pcm.speaker6 {
  type plug
  slave.pcm "split"
  ttable.0.3 1
}

pcm_slave.umc_in {
  pcm "hw:U192k"
  rate 48000
  format S32_LE
  channels 4
}

pcm.mic2 {
  type plug
  slave.pcm {
    type dsnoop
    ipc_key 1232
    slave umc_in
    bindings.0 0
  }
}

pcm.mic3 {
  type plug
  slave.pcm {
    type dsnoop
    ipc_key 1232
    slave umc_in
    bindings.0 1
  }
}

pcm.mic5 {
  type plug
  slave.pcm {
    type dsnoop
    ipc_key 1232
    slave umc_in
    bindings.0 2
  }
}

pcm.mic6 {
  type plug
  slave.pcm {
    type dsnoop
    ipc_key 1232
    slave umc_in
    bindings.0 3
  }
}

The second half of this is my first attempt to split the microphone channels. When using the multiple mics test recording there is a weird lag... I don't know if that is reflected in the recorded audio data yet.

  • We also want to prevent this interface from ever becoming the default audio output of the system (we dont want the birds hearing random error sounds or notifications).

To do this pactl list short sinks

Edit /etc/pulse/default.pa, comment out all lines with switch in them.

#load-module module-switch-on-port-available
#load-module module-switch-on-connect

We also added a Startup Application called "Set default audio". Check it to see what the command does.

Setting up arduinos

Like the webcams, the arduino devices are by default mapped to /dev/ttyACM0, /dev/ttyACM1, etc but the order is not always consistent. We create rules in /etc/udev/rules.d/arduino.rules to detect Arduino's with the known serial numbers to their boxes using symlinks /dev/ttyArduino_Box5, etc.

# /etc/udev/rules.d/arduino.rules
### Box 2:
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{manufacturer}=="Arduino (www.arduino.cc)", ATTRS{serial}=="95232343733351909201", SYMLINK+="ttyArduino_box2"

### Box 3:
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{manufacturer}=="Arduino (www.arduino.cc)", ATTRS{serial}=="95232343733351403182", SYMLINK+="ttyArduino_box3"

# Box 5:
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{manufacturer}=="Arduino (www.arduino.cc)", ATTRS{serial}=="9523234373335140A011", SYMLINK+="ttyArduino_box5"

# Box 6:
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{manufacturer}=="Arduino (www.arduino.cc)", ATTRS{serial}=="952323437333518041A1", SYMLINK+="ttyArduino_box6"

Setting up 4TB storage drive

We ordered the computer to come with a 4TB HDD. I formatted as exFAT. However, the drive must be mounted to read/write from it. To set it up to automatically mount the drive (to /data) when you start the computer, you can make the mountpoint with sudo mkdir /data, give the fet user ownership of it with sudo chown -R fet:fet /data, find the UUID of the drive with sudo blkid, and then edit /etc/fstab with a line that tells fstab to automount the drive.

Relevant line in /etc/fstab

UUID=305ddbf7-485f-4aef-81aa-c196a600a785 /data ext4 auto,nosuid,nodev,x-gvfs-show 0 0

Set up remote access

The computer is connected to our wireless network 123E.

To give the computer a fixed ip address on the network, go to the router admin page at 192.168.0.1, Setup > Network Settings > Add DHCP reservation and map this computer plump -> 192.168.0.100 (this could be anything).

Setting up ssh

sudo apt install ssh && sudo service sshd start

Go to router config at 192.168.0.1, go to advanced > virtual server, and map private port 22 to public port 65456.

Setting up Google Drive Syncing

TODO: incloud

Downloading code

  • Cloned theunissenlab/pyoperant to /home/fet/code/pyoperant

  • Cloned theunissenlab/pecking_analysis to /home/fet/code/pecking_analysis

  • Created separate environments for each with python3.9 -m venv env

  • Copied scripts/pecking_test from chubbyninja to /home/fet/scripts/pecking_test

  • Modifying scripts/pecking_test to have a debug_audio command

  • Add ~/scripts to PATH and ~/code to PYTHONPATH in ~/.bashrc

Setting up jupyter notebook

In the pecking_analysis environment (cd ~/code/pecking_analysis && source env/bin/activate), install dependencies (pip install -r requirements.txt) and then run a notebook with jupyter notebook --ip 0.0.0.0 --port 8888. Or jupyter lab --ip 0.0.0.0 --port 8888.

TODO: connect to notebook remotely through ssh? dont want to have a notebook publicly accessible

Contents

General

Calendars and scheduling
Lab funds and purchases
Advising, Social Justice, Sexual Harassment, and Real World Shit * Support Resources

Dry lab

Getting connected to the lab network
Data storage and access
Computing
Working Remotely
Other Services

Wet lab

Animal Care

Husbandry, who to call, recordkeeping
Bird care links

Behavior

Pecking Test (NAF 125)
Field Station

Surgeries, Histology, Imaging, Waste

Certifications, protocols, techniques, and recipes
Instructions for individual pieces of equipment

Electrophysiology

Instructions
Hardware, software, and techniques for ephys

Calcium imaging

* Ca imaging Notes

fMRI

Data Collection
Data Analysis

Theory

Modulations

STRFs

Other




Old pages:

Wetlab


Pages in progress:

Clone this wiki locally