Pecking Test Documentation - theunissenlab/lab-documentation GitHub Wiki
Software, hardware, and network configuration for Pecking test (NAF 125)
Table of Contents
- Pecking test code
- Sound input and output
- Webcams
- Computers and network
- Data syncing
- Arduino
Find our older documentation files (that much of this is based on) on Google Drive.
1 Pecking test code
Most commands are run on the two computers in 125 with the base command pecking_test
. See this for the full documentation.
The python code that runs the boxes is saved in our fork of the pyoperant repository (as of Nov 2020 the live-playback
branch, but hopefully to be updated to master soon). This code is cloned locally on both computers in 125. On the two computers in 125, this code is located at /home/fet/code/pyoperant
.
YAML File
/home/fet/code/pyoperant/pyoperant/tlab/pecking_test.yaml
The relevant lines of this config are:
local_tlab.py File
/home/fet/code/pyoperant/pyoperant/tlab/local_tlab.py
The relevant section of this file is
Jupyter notebook
/home/fet/code/pecking_analysis
?
PATH and PYTHONPATH
These should normally be already set (the relevant portions are set by /home/fet/.bash_path
). Check them with the following commands. The majority of the path doesn't matter, what is important is that it includes the portions.
echo $PATH
# needs to include /home/fet/bin
echo $PYTHONPATH
# needs to include /home/fet/python_path
Listing the contents of these relevant directories will show you why:
-
First,
ls -alh /home/fet/python_path
shows you that this directory has a symlink directly to/home/fet/code/pyoperant/pyoperant
, which is why you can import and run code for operating pecking boxes for shaping. -
Second,
ls -alh /home/fet/bin
includes the programspecking_test
, which is used each day to run the pecking test, andkeepalive
, which is used to continuously restart a program if it crashes.
2 Audio software and hardware
The audio software and hardware setup is the cause of many headaches. If we ever learn what it is doing, it should be documented here.
External USB soundcard
Pumpkin and chubbyninja now both have an external USB sound card Roccat Juke ("Juke") because the internal one appeared to die ("PCH"). We had to reconfigure the UDEV file to look for the new sound card. So the microphones and speaker outputs are connected to this usb dongle thing.
udev
This maps our new usb soundcards (the ROCCAT Juke) to the name "Analog". ATTRS{id}=="Juke"
would be ATTRS{id}=="PCH"
if we were using the built in soundcard.
# /etc/udev/rules.d/analog_audio.rules
KERNELS=="card[0-9]*", SUBSYSTEMS=="sound", ATTRS{id}=="Juke", ATTR{id}="Analog"
alsa
This configuration creates 3 virtual devices: (1) split
, which is a two channel device mirroring the device named "Analog" which we configured with udev, and (2) speaker0
and (3) speaker1
, which represent the left and right channels of split
. We can now play audio out of the left and right channels independently by playing sound to speaker0
and speaker1
, respectively. The python code references these virtual speakers, speaker0
and speaker1
. You might have to change the name of the device Analog if it does not match what you find out typing lsusb
and cat /proc/asound/cards
.
# /etc/asound.conf
pcm.split {
type dmix
ipc_key 2048
slave {
pcm "hw:Analog"
channels 2
}
}
pcm.speaker0 {
type plug
slave.pcm "split"
hint {
show on
description "Plays sound through the left channel only"
}
ttable.0.0 1
}
pcm.speaker1 {
type plug
slave.pcm "split"
hint {
show on
description "Plays sound through the right channel only"
}
ttable.0.1 1
Amplifier
Audio is run out of the headphone jack where it connects to an amplifier. The amplifier should be adjusted to provide the desired output sound level within its corresponding boxes (appropriate levels for song and call may be labeled on the dial). The left and right channels output from the amplifier are sent one to each box that the computer controls.
3 Webcams
Webcams are identified by their ID. The rules are indicated in webcam.rules and copied to /etc/udev/rules.d
on the computers (/etc/udev/rules.d/webcam.rules
). If one webcam was to be added, those files would need to be changed. And then you should check that the simulinks are correct under /dev: video_box# are indeed simulinks to the correct webcams!
mjpg_streamer
for webcams
This command will start up a webserver on the specified port that shows a simple html page with an embedded video stream. The html page and associated javascript can be edited to provide whatever we want (and should!)
Replace the first BOX=1
in the next command with the appropriate box number
BOX=1 && mjpg_streamer -i "/usr/local/lib/input_uvc.so -d $(readlink -e /dev/video_box$BOX)" -o "/usr/local/lib/output_http.so -p 808$BOX -w /usr/local/www" 2>/dev/null &
Then open a new tab in firefox and look at the camera at this url:
BOX=1 && firefox -new-tab http://192.168.0.102:808$BOX/stream_simple.html
or
BOX=1 && firefox -new-tab http://localhost:808$BOX/stream_simple.html
To remotely access the webcams via ssh
First your machine must be able to ssh the computers down in NWAF (see system folder notes). Then ssh chubbyninja behind the scene and make your port correspond to the one of chubbyninja using the following commands:
ssh -fN -L 8085:localhost:8085 -L 8086:localhost:8086 chubbyninja
Then same thing for pumpkin’s ports:
ssh -fN -L 8082:localhost:8082 -L 8083:localhost:8083 pumpkin
you can now go to your internet browser and visualize the webcam streaming using the following command where the ‘#’ sign is replace by the appropriate box number: 'http://localhost:808#/stream_simple.html'
4 Computers and Network
As of November 2020: The pecking test is set up in room NAF 125 in Boxes 2, 3, 5, and 6. There are 2 computers both Intel NUCs with nearly identical setup, each is responsible for the control of 2 boxes. (Product #BOXD34010WYKH1) and connected to the WiFi router set up in room 123E.
Host | Boxes | External IP | Local IP | SSH |
---|---|---|---|---|
chubbyninja | 5, 6 | 192.168.0.112 | 10.42.0.1 | ssh [email protected] -p 65454 |
pumpkin | 2, 3 | 192.168.0.102 | 10.42.0.23 | ssh [email protected] -p 65455 |
-
NWAF Network IP: 192.168.0.1
-
Incoming data is redirected by the router on chubbyninja (which acts as a virtual server, as the router itself cannot interpret incoming commands). Chubbyninja listens for incoming ssh connections on port 65454, which must be enabled in the file
/etc/sshd_config
. After adding the port the computer should listen to in this file, the ssh daemon must be restarted withsudo ssh service restart
. -
To ssh to the computers remotely, use
ssh [email protected] -p 65455
for pumpkin andssh [email protected] -p 65454
for chubbyninja. You can configure these in your own computer's ssh config file, which for windows would be in C:\Users\USERNAME.ssh\config:
Host pumpkin
HostName 169.229.251.200
Port 65455
User fet
Host chubbyninja
HostName 169.229.251.200
Port 65454
User fet
(old notes from Tyler). Here's an old description of the hardware from Tyler, and here is a similar description in google doc format which may be slightly more current.
5 Data syncing
The data saving system is set up in the following way. On each computer, the drive folder contain the Pecking_test folder which is synced using insync with the bdrive Pecking_test folder (account [email protected]). Only part of the content of Pecking_test under bdrive is synced with the local computers:
125_Computers
PythonConfig/scripts
PythonConfig/Commands
PythonConfig/Configuration
PythonConfig/Start Session Data Form.gdform
PythonConfig/Shaping Protocol Python Config.gddoc
PythonConfig/Pecking data.gdsheet
PythonConfig/Pecking data links.gddoc
PythonConfig/Fasting Data Form.gdform
PythonConfig/Session Data Form.gdform
PythonConfig/To-do list.gddoc
PythonConfig/Pyoperant additions.gddoc
PythonConfig/Run an experiment.gdform
PythonConfig/Rules to feed the birds!.gddoc
PythonConfig/Seed consumption experiment.gdform
Then each computer chubbyninja and pumpkin are synced with their respective data folder:
PythonConfig/experiment_chubbyninja
or PythonConfig/experiment_pumpkin
When birds are done running one experiment then their data folder is transferred to PythonConfig/Projects under the corresponding project folder.
All the Pecking_test folder is entirely synced also using insync with tdrive: /auto/tdrive/julie/drive/Pecking_test
including the Projects folder that contains all the data from the pecking test archived.
6 Arduino
The boxes are interfaced with using an Arduino Uno hooked up to each chamber. The Arduino outputs 3 digital signals to control the pecking button light, the feeder, and the main house light (I don't think this one works though...). It has 1 digital input from the pecking button. The functioning of the chamber and programmatic interface to it should be discussed elsewhere, but there are a few things that are needed to make things work on the computers.
- The Arduino software must be installed
- Can be done through
sudo apt-get install arduino
- Can be done through
- User must be added to the "dialout" group. This is done automatically when the Arduino software is run for the first time. You must log out and log back in before this takes effect.
- Again, udev will initialize the Arduinos in arbitrary order, so custom rules should be applied. These rules will create a symbolic link in /dev that points from a consistent and interpretable name like "ttyArduino_box2" to the randomly given name like "ttyACM1".
/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"
Here are some other notes, probably written by Tyler in the before times. I'm confident you'll be able to figure it out.
-
Initialize ArduinoInterface with device name and baud_rate
-
Config write with _config_write(channel) then write with _write_bool(channel, True)
-
Config read with _config_read(channel) then read with _read_bool(channel)
-
Accessing an output pin on two python terminals works well. Only issue is the config_write command causes it to go to OFF state (equivalent to calling _write_bool(channel, False))
To find a new arduino's serial number, run:
udevadm info --query=all --name=/dev/ttyACM0
and copy id_serial from there.