The SVL CabCam Project

As Silicon Valley Lines adapts to the current global pandemic, it has become clear we will not be meeting as a full club in person for some time. This has spurred our search for a solution to allow us to run operating sessions and have fun with trains as SVL is foremost a operating layout. We tried a few approaches but it quickly became apparent that we need to give remote operators a way to get immersed with running a train on the layout. We wanted to provide a view from the locomotive cab that is fast and responsive. Thus the SVL CabCam Project was born. In addition we provide layout overview cameras and/or views from key locations on the railroad.

This write-up is the result of a lot of trial and error, getting products fully running then realizing the end-to-end latency was so severe it wouldn’t be workable. It is intended as a general overview for hobbyists wishing to get a track-level view of their own layout, and provides technical instructions for replicating our approach.

A cab view camera is useful for more than remote operations during COVID. Local ops sessions can benefit from this as well.

Overview

We describe how to set up a small computer to stream cab view video from an HO locomotive. This allows remote operation of trains at local or remote layouts, optionally connecting it to video conferencing software like Google Meet or Zoom.

Goals

  1. Easy to set up and maintain.
  2. Easy to access the cab view via a URL or via conference software eg. Zoom or Meet.
  3. Distribute the setup to others for the betterment of the hobby.
  4. Provide a low latency video stream to enable remote control via Engine Driver/WiThrottle
  5. Keep the hardware within HO NMRA clearances.
  6. Use commonly available components and open-source software where possible.

Implementation

Hardware: We are using one Raspberry Pi Zero WH per CabCam car.

Camera: The Pi Zero Spy Camera works well for our purposes.

Software: The project uses Raspian Buster running MJPG Streamer on the CabCam car. This streams video from a URL on the local network. The video can be viewed locally or streamed to conference software via OBS and the OBS VirtualCam plugin.

Power: The Juiceb0x Zero is a “hat” for the Pi Zero. While the Pi Zero WH comes with the required header already installed, soldering is required to install header pins on the Juiceb0x Zero board.

Rolling Stock: The easiest approach is build a mounting sled out of styrene as shown below. With a little bit more work the setup can be installed inside a dummy engine, too.

IMG_20200710_191346

How To

This section describes the setup in more detail. Some familiarity with Raspberry Pi and respective software management is helpful.

1. Gathering the hardware

You will need:

2. Setting up the hardware

Connect the camera to the Pi Zero WH. Solder the header pins to the Juiceb0x Zero per the instructions that come with it and attach it to the Pi Zero WH. Connect the battery to the Juiceb0x Zero. Connect the USB charger to the Juiceb0x Zero to charge the battery.

Never connect power to the USB ports of the Pi Zero WH while the Juiceb0x Zero is attached. 

3. Burning the image and setting up the software

Download and install the Raspberry Pi Imager, formerly called NOOBS. 

Run the software and select Choose OS, then Raspberry Pi OS (Other) and select Raspberry Pi OS Lite.
Next Select your SD Card via Choose SD Card and hit Write. Once it is done writing, eject and reinsert the SD card into your computer.

4. WiFi Setup

Now we will configure wifi for your home or club network. With a text editor create (or edit) a file named wpa_supplicant.conf in the boot folder on the SD card. Paste the following text to this file.

country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
      ssid="NETWORK-NAME"
      psk="NETWORK-PASSWORD"
}

Change the country code to your two character country code per the  ISO 3166 alpha-2 country code. For many of us it will likely be US or GB. SSID refers to your wifi network name and PSK is your network’s password. Make the respective changes for your network and save the file.

To enable SSH access create an empty file called ssh in the boot folder on the SD card.

Eject and remove the SD card from your computer, insert it into the Pi, and power up the Pi by moving the small slider switch on the Juiceb0x Zero to On. The blue LED on the Juiceb0x Zero should light up, and you should see flashing green lights. Some cameras have LEDs on the connector strip, those should light up briefly as well. Give the Pi about two minutes to boot up. 

5. Logging in to the Pi

Find the IP address your Pi is using and log in using ssh as user pi.

The default password is raspberry.

On a Mac use Terminal. On Windows use PuTTY (you may have to download it)  and put in the IP of your Pi in the Hostname block. When you connect, the default username is pi and the password is raspberry.

On many networks the following also works:

ssh pi@raspberrypi.local

6. Configuring the Pi

Once on the Pi command line type

sudo raspi-config

to enter the configuration page for the Pi. First enter Change User Password and enter a new password if you want to secure the device. Next enter Network Options, select Hostname, and give your Pi a unique name like LayoutCabCam1 or similar. This is helpful to identify which Pi is which if your network supports hostnames. Next select Interfacing Options, select P1 Camera, and enable the camera interface. The last thing to do in the configurator is to expand the file system. Go to Advanced and select A1 Expand Filesystem. After that finishes, exit the configurator and allow the Pi to reboot. 

7. Configuring MJPG Streamer

Now we are going to configure the software to allow us to stream the cab POV. 

Log back into your Pi and run the following commands

sudo apt-get update
sudo apt-get upgrade

Follow this with

sudo apt-get install git 
sudo apt-get install cmake libjpeg8-dev -y
sudo apt-get install gcc g++ -y

This will take a while.

Run the following commands to clone and compile MJPG Streamer, this will also take some time. 

git clone https://github.com/jacksonliam/mjpg-streamer
cd mjpg-streamer/mjpg-streamer-experimental

make && sudo make install

Sit back for a bit and enjoy a drink.

Next run

mjpg_streamer -i "input_raspicam.so" -o "output_http.so"

to test the stream with the most basic settings. This should output some stuff on your terminal to let you know it is working. Point the browser on your computer  to http://IP:8080?action=stream (replace IP with the IP address for the Pi from earlier). If you see output from your camera you are ready to move on. In the terminal, hit Ctrl+C to close the stream.

The following command uses the parameters we set at SVL.

mjpg_streamer -i "input_raspicam.so -x 480 -y 360 -fps 10" \-o output_http.so

The Internet uplink bandwidth at SVL is quite limited. For cab control with remote operators we found that SD resolution is sufficient and limits bandwidth demand. We are using a frame rate of 10 images per second. The stream doesn’t get smoother turning this up. If your camera is upside down you may need to insert -rot 180 before -fps.

We want to turn on the stream at on startup. A small startup script will get us there.

Enter the following

sudo nano /home/pi/startcam.sh 

Enter the following in the text editor.

#!/bin/bash

mjpg_streamer \

-i "input_raspicam.so -x 480 -y 360 -rot 180 -fps 10" \
-o output_http.so

Hit CTRL+X to leave the editor, hit Y and  Enter to write the file to the SD card. 

Make this file executable with

sudo chmod a+x /home/pi/startcam.sh

To cause the camera stream to start whenever the Pi boots, edit the /etc/rc.local file. To do this run

sudo nano /etc/rc.local

and add /home/pi/startcam.sh close to the bottom of the file right above the exit 0 command. Exit the editor with CTRL+X Y Enter.

Reboot the Pi with sudo shutdown -r now. After reboot you should be able to see the stream in your browser at the URL you used above. After placing the camera on a flatcar, it should look something like this.

Put your CabCam car on the front of a train, and run the train while watching the video stream in the browser.

Bernhard wrote down some thoughts on camera placement and car choice on his blog.

9. What’s Next?

To stream the video to remote operators we use OBS with the VirtualCam plugin, configured with CabCam feeds. This is connected to Google Meet and can even stream to Youtube Live. Other video conferencing software like Zoom, Duo, Skype, etc. can be used, too. Remote operators join the video conference and use Engine Driver or WiThrottle to control trains via JMRI. We’ll cover that in a separate post.

Variations

Hardware: While we are using a Raspberry Pi Zero WH, any Pi with built-in Wifi will work.

Camera: Any compatible Raspberry Pi camera can be made to work. Possible options are the official Pi camera, the spy cameras, or other compatible cameras available from e.g. Adafruit.

Power: The Zero2Go board is an alternative to the Juiceb0xZero. However, the Zero2Go can’t charge the battery. In either case, do not power the Pi from the onboard USB while the power solution board is attached.

Some people had success with using a small form-factor USB power bank connected to a Pi Zero without additional hardware.

Revisions

Over time we have made corrections to these instructions, or fine tuned settings. Below is a list of important revisions.

  • Fixed a bug with double quotes in the startcam.sh example above.
  • Reduced video resolution from 640×480@15fps to 480×360@10fps to help with bandwidth usage in certain Wifi environments.
  • Various spelling and grammar corrections.

Socially Distanced Ops, June 2020

Screenshot from the camera control computer

Tonight was the ops session we have been planning for the last few weeks. Since we are in the middle of a global pandemic, we decided to severely limit on-site attendance, institute social distancing, wearing masks, and try out remote participation.

Instead of the usual 10 – 15 session participants in the layout room, we had only four: A yardmaster for Nowheres, and three engineers. Plus one member for taking care of cameras, Internet, and streaming stuff. We also had three club members joining us remotely as engineers, and a remote dispatcher.

Remote control of our web-based layout panels and locomotives on the layout is easily accomplished using a VPN application that connects remote devices to the club network. EngineDriver’s automatic discovery of JMRI’s Withrottle Server doesn’t work over the VPN connection. Instead, remote participants need to enter IP and port number of the computer running JMRI manually. In our case 192.168.8.10, port 12090. The control and dispatcher web panels are available at http://192.168.8.10:3000 over the VPN connection as well.

Upacking technology

Over the course of the afternoon we installed cameras in the layout room. We used Foscam X1 security cameras, as well as old Android phones with the IP Webcam app. All four cameras were streaming video into OBS.

The four cameras were set up to cover as much of the layout room as we could pull off. The intent was to give remote operators maximum visibility of the main line, so that they get to see the trains they are running.

We also streamed from OBS to Youtube Live for some time during the session. Using the Present from window Google Meet feature worked for the video stream, but resulted in unacceptable latency for remote participants. We will need to try this again with the OBS VirtualCam plugin.

The control stand

On the left is the FRS Radio / Meet gateway. This old Dell laptop runs Linux and has separate microphone and head set plugs, with microphones taped to computer and headset speakers. The laptop in the middle runs OBS and acts as the hub for all the video streams, including broadcasting to Meet and Youtube Live. The laptop on the right was the control for the Youtube Live stream.

This was another step towards restarting operations at Silicon Valley Lines. Operations sessions as we know them will not be possible for a while. Some remote participation component will be needed for the time being.

The club Internet connection has 24 MBit/s downlink and 5 MBit/s uplink. We found that throughput on the uplink was very variable, and stopped the Youtube Live stream halfway through the session after downgrading quality multiple times to free up more bandwidth for Google Meet. That definitely resulted in improved video and audio quality with less artifacts.

IP Webcam did not work reliably on some phones, while it worked just fine on another phone.

Finally, we need to build a more compelling remote engineer experience. While the camera setup we used allows for an ok overview of the layout room, it very much has a security camera feel to it. We will try to make it more reliable, but even then it’s at best nice as a novelty.

What we really want to do is to put the remote engineer in the middle of the action. If you can’t be there, maybe with technology we can provide an experience that is not possible when standing in the layout room.

Stay tuned.

Preparing for Socially Distanced Ops

Virtually bringing the membership to the club

Due to social distancing guidelines still in effect, Silicon Valley Lines canceled the May ops session originally scheduled for tonight. We discussed doing another remote ops session instead, and decided that this time we’d try to do a session from the club. Only two members went to the club. Everybody else joined over video conference from home.

This was to test both our ability to implement social distancing, as well as whether and how to incorporate remote operators into an operations scheme. Another goal tonight was to stress-test the club’s Internet connection with multiple video streams in a multi-user setting.

We set up various cameras to record the action from different angles. We also moved the cameras around to capture trains as they moved from yards over the layout to their destinations for switching.

We used Web cams connected to laptops, as well as Android phones to provide views of the layout for the stay-at-home audience

The verdict:
Over the course of the evening we ran only four trains, instead of the 25 trains we normally run.

We can support a remote dispatcher and give remote operators control of a train. We have the technology to do that.

However, our Internet uplink does not support multiple HD streams in parallel. The double-deck arrangement makes visual train control via cameras challenging for a remote operator. While detected sections on the layout work well, and are needed for signaling, not all blocks have detection for various reasons.

Keeping distance between operators in the layout room will be a requirement for a while

Even when the county’s strict shelter-in-place orders are lifted, we will need to continue some form of social distancing measures for the time being, including wearing masks. A well-attended ops session is a lot of fun with a lot of energy in the room. However, the health of club members and visitors is paramount. More discussions are needed to find a way to run an ops session at the club that is fun, but avoids crowding in the aisles, and minimizes health risks. Very likely this will include a remote engineer component, and we need to figure out how to make that fun and satisfying for everyone involved.

Model Railroading 101: DTC

A great introduction to operations with DTC featuring Silicon Valley Lines. John from TSG Multimedia attended one of our sessions last year and put together this great episode of Model Railroading 101. Enjoy!

If you enjoy operating a railroad in a relaxed club atmosphere, come and join us at one of our future operating sessions.

Virtual Club Life

When the COVID-19 Shelter-in-Place restrictions hit the SF Bay Area and pretty much everyone was required to stay home, we quickly realized that the club won’t be able to function as normal for a while. However, the club membership is still around, and we like to hang out with each other on Friday evenings working on the railroad.

Weekly Club Meeting

So we moved to the next best thing: hanging out together online, while working on the railroad, and kept meeting regularly. In some weeks we have a presentation, a tour of a member’s home layout, or other pre-planned program. Other weeks are more laid back, and members talk about model railroad news, explore local railroad resources together, work on projects and share results as the meeting is going on, etc.

At one of these meetings we started discussing that it might be fun to do a remote operating session. Start of with something simple: Set up a train on a home layout, write out a switch list, the layout owner runs the train, but the online group is acting as conductor and directs the moves the engineer is supposed to make. We decided to try it first with Bernhard’s Welztalbahn railroad.

Remote Ops on Bernhard’s Welztalbahn

It turns out, this was a very enjoyable experience, not only for the engineer, but for the group, too. Of course, some friendly banter and joking contributed to the fun, too.

In fact, we had so much fun, that we did it again this week on Bill’s San Arbo railroad, which also was a big success.

Remote Ops on Bill’s San Arbo Railroad

We are planning to do more such sessions in the future.

Even though we can’t be at the club for now, we are having fun.

Together.