What's new
This wouldn't be too bad, though, since you're really only using the live feed to position yourself for a static photo (from what I can tell).
I vaguely remember playing vs 4 other people and during gameplay, whenever I was near another non AI player, their cart would show their face from the camera at their cab. I can't recall if this as GP1 or GP2. AI players would have the toons image in place of the camera.
 
I vaguely remember playing vs 4 other people and during gameplay, whenever I was near another non AI player, their cart would show their face from the camera at their cab. I can't recall if this as GP1 or GP2. AI players would have the toons image in place of the camera.
You're thinking it was a real-time stream of the player and not just the static image they took when they started? It's very possible, but I I'm not set up to see that in my tests, so there may be some stuff I'm just unware of.
 
I played the game at Dave and busters a while back and i noticed it was only a static image whenever you got close to a human opponent, not a live stream. Unfortunately we don’t have a D&B in my city so I cant double check.
 
You're thinking it was a real-time stream of the player and not just the static image they took when they started? It's very possible, but I I'm not set up to see that in my tests, so there may be some stuff I'm just unware of.
I'm not certain at all it was a live stream, i just remember it back in 2013 when i first played it. I will have to check it out again but I think the cabs near me (D&B and Round1) were all replaced with GP DX.
I just remember there being a significance between the "standard" stream and the HD stream that you are seeing. Nevertheless, the image on one cab is shared across all cabs during multiplayer battles. What I DO recall, the nearby players' images would pop up as you are near and go away the further in distance you are from that person.

I played the game at Dave and busters a while back and i noticed it was only a static image whenever you got close to a human opponent, not a live stream. Unfortunately we don’t have a D&B in my city so I cant double check.
Do you remember if it was GP1 or GP2? Now i'm even more curious.
 
I think it was Mario Kart GP DX. Which is the 3rd game in the series. I don’t know if this helps. But basically after the character select screen it gave you a template to choose from then it snapped a picture of you with or with the template if you chose one. Then whenever you get close to an opponent their picture would pop up. There wasn’t a live video feed.
 
I ran some updates on my RPi in an attempt to get quicker and better low light images, and now my script that was successfully running seems to be posting unusable jpegs. I'm not sure why it changed, but it's like now when the browser or Mario kart access the image, it's often not working. My browser will complain that there's an error with the image and MK just won't show anything until it gets a valid image. If I spam the refresh button, I can sometimes get a valid image in my browser.

It's as if now when the file is being accessed with the script (which is quite frequently) it locks it from being accessed by anything over http. Previously I was not encountering this.
 
Maybe it's a bit logical that writing and reading a file simultanously will cause issues. A solution could be to have 2 images and present the older one over http when the newer one is written. At that moment, you can switch images and overwrite the unused one.
 
In fact : if you try to read a file while it's written down, the file will be incomplete and so seems corrupted.
 
Maybe it's a bit logical that writing and reading a file simultanously will cause issues. A solution could be to have 2 images and present the older one over http when the newer one is written. At that moment, you can switch images and overwrite the unused one.
I'm not sure I have much control over it. Depending on timing, the game could be accessing the image at any point it's being written.

I did start writing to a temp file, and copy that over the file that is read afterwards and it seems to behave better. I don't know how I wasn't running into this before, though.

I'll consider this issue solved.

I did get the framerate up to something I think is comparable to the stock camera.

Now I'm still trying to get good low light images. I think I will have to sacrifice the framerate in order to do it. It must be that the picamera I have just isn't as good as the stock one for low light, and I would imagine the use case for this camera is a low light environment.
 
Ok - I might be back to preferring a webcam over the picamera, but I will have to do more tests to see if I can get similar performance from the picamera.

Using my better of 2 webcams, I made use of mjpeg-streamer to set up a live stream of the webcam, and this comes with a static capture. I then scripted something to copy this over to ip/img.jpg and the quality and refresh rate are phenomenal!
 
Last edited:
I did get the Pi camera working with mjpeg-streamer, but it's definitely not as good as the webcam I'm using, and I'm back to running into frequently unusable jpegs being posted, which basically kills the framerate of the camera in-game. It's just a difference in one line of code, so I can probably put together instructions that would include either option.

I'm thinking the webcam is going to be the way to go because they're easier to mount, can make use of an easy-to-acquire USB extension cable if installing in a cab some distance away from the RPi, and have the potential for better image quality and low light performance. In my testing scenario, the pi camera on the short ribbon cable was just annoying. There appear to be up to 2 meter extension ribbon cables for this, but I'm not interested in going down the pi camera path anymore and dealing with its shortcomings.

There may be more expensive, better quality pi cameras than the one I bought, but I'm not investing any more into them.

The webcam I've been having great results with is the Logitech C615 which is overkill for this application. The images for Mario Kart need to be 320x240, so a 1080p webcam is not needed. However, I don't want to invest a ton of money into testing other webcam options, so I'm not sure what to suggest for a cost-effective and good quality option. This camera is currently listed at close to $40 on amazon and I see it was $30 when I originally purchased it. I would think if you could find a well-reviewed cheap webcam that you can confirm works with RPi and has good low light performance, it would probably be good for this.

Octoprint uses the same streamer, and this page lists reported working webcams for RPi with this streamer.

I'm not sure if I want to get much more complex with this by adding in GPIO inputs and dynamically changing the IP according to the JVS I/O. It's kind of cool, but that will require me to wire this up to my I/O. Assuming I assign the same player number to a given cabinet, I can just set up the RPi to be the expected IP for the given player and not worry about changing it.

@obcd, I am interested in any input you have on migrating most of this to a ram disk. I do have the stills that I'm serving stored in a ram disk, but whatever else the OS and other processes are doing is unchanged, so I'm not sure what to look out for with regards to SD writes. I assume there are some processes generating logs. I'm pretty sure apache is. I honestly don't know what the mjpeg-streamer is doing and whether or not it's streaming to RAM (not sure performance would be great if it had to write to SD).
 
Last edited:
I've managed to get this solution down to an even simpler setup!

mjpg_streamer has its own webserver and you can specify the port when running the program, so it's easy to set it up to port 80, which is what Mario Kart needs.

mjpg_streamer requires that you pull it from git and compile it directly on you RPi to get it installed. One of the options you can set makes the program serve up a still if you access something like ip/cam.jpg. I figured out where this name is specified in the source code and am able to get mjpg_streamer to serve up ip/img.jpg directly! (Edit: I forked the mjpg_streamer repository into one with the edits needed for Mario Kart, so no complex edits or commands are needed to make it work - directions in the next post.)

I believe this is going to be the cleanest method of making sure the image is updated as quickly as possible while avoiding conflicts with reading/writing the file at the same time (I assume mjpg_streamer has some accommodations for avoiding these conflicts).

I have also figured out how to mount the file system as read only, while assigning a couple of directories as ram disks, so I think the concerns about SD corruption are minimized, if not eliminated.

I'll try to document the steps soon. They shouldn't be too complicated.
 
Last edited:
DIY directions:

Things you need:
Raspberry Pi 3 B+ (that's what I'm using - could maybe be another version)
Micro SD Card (not sure on minimum size - mine is 32GB and way more than enough)
5v Power Supply (I use a 2.5A Canakit one)
Webcam or Pi Camera (I'm using a Logitech C615)

Download a linux distro for RPi. I used this one:
http://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2018-04-19/

Load it onto the SD card. Once it's loaded, mount the card in your computer and write a file to the root folder and name it "ssh". In Windows you can just right-click, create new, text file and it will create a file called New Text Document.txt. Just rename it to "ssh" with no file extension. This will enable SSH. If you're setting up wifi (I didn't), you may need to keep the card in your PC and follow some directions to edit a file on the SD card now.

Put the SD card into the RPi, plug up a monitor if you can, wire up a connection to your router so that the RPi will have an internet connection (alternatively look up directions on setting up wifi), and power up the RPi. It will go through some automatic setup steps and will eventually result in a login prompt. A few lines above that it will say what its IP is. You can load up your favorite SSH program and use that IP to SSH into the RPi.

Credentials are usually: pi/raspberry

Now that you're logged in, you can copy/paste the commands from these directions:

Code:
sudo apt-get update
sudo apt-get install build-essential libjpeg8-dev imagemagick libv4l-dev cmake git -y

#get mjpg_streamer repository and compile it
cd /tmp
git clone https://github.com/winteriscomingpinball/mjpg-streamer.git
cd mjpg-streamer/mjpg-streamer-experimental
make
sudo make install

#edit crontab to set up and run mjpg_streamer at reboot (if it makes you choose an editor, it should default to nano and you can just hit enter)
sudo crontab -e
#add these lines to the bottom of the file:
#change IP per player cabinet #: 1=.104, 2=.105, 3=.106, 4=.107
@reboot sudo ifconfig eth0 192.168.29.105
#if using USB webcam uncomment the next line
#@reboot sudo /usr/local/bin/mjpg_streamer -i "input_uvc.so -r 320x240 -d /dev/video0 -f 30 -q 80" -o "output_http.so -p 80 -w /usr/local/share/mjpg-streamer/www"
#if using pi camera uncomment the next line
#@reboot sudo /usr/local/bin/mjpg_streamer -i "input_raspicam.so --width 320 --height 240 -d /dev/video0 -fps 30 -quality 80" -o "output_http.so -p 80 -w /usr/local/share/mjpg-streamer/www"
#CTRL+X to close crontab file and save it - pay attention to prompts

#set file system to be read only
sudo nano /etc/fstab
#change line 3 to this (note that this line may be different depending on the distro - find the line that has /ext4 and change it to have ro for read-only
PARTUUID=5c58623a-02  /ext4    defaults,noatime,ro  0       1
#add these lines to the bottom:
tmpfs   /var/log        tmpfs   nodev,nosuid    0       0
tmpfs   /var/tmp        tmpfs   nodev,nosuid    0       0
tmpfs   /tmp        tmpfs   nodev,nosuid    0   0
#CTRL+X to close file and save it - pay attention to prompts

#if using pi camera enable it
sudo raspi-config
#enable camera

#reboot after configuring
sudo reboot

#If you need to remount as rw:
sudo mount -o remount,rw /dev/mmcblk0p2 /
If everything went successfully, your RPi will now set the IP to the desired address and run mjpg_streamer on boot. Now just plug a network cable in and put it on the same switch/hub as Mario Kart, make sure to set the PCB ID # in Mario Kart settings to correspond with the IP you set up on the RPi, and the camera should be working in game.

Good luck!
 
Last edited:
I was just looking at resource usage for mjpg_streamer running this way, and it's super low. The highest I saw it go was 1.3% CPU usage, with a webcam. I fully expect that this could run along side netbooting and the card reader script. I haven't yet tried running the card reader script on the RPi myself, but others have reported success. I would imagine it's not too resource intensive either.
 
FYI for anyone with spare cards around, I was able to get this running on a 2GB micro SD card using the directions above.
 
Any success stories with the DIY camera?

I put together a temporary setup the other day to play with a camera in one of my WMMT cabs. My two-year-old daughter loved it. She just wanted it to keep taking her picture instead of playing the game. :P
 
Ok - I have it all compiled - I can see the mjpg stream - what URL does Mario Kart actually hit? And it seems like it's harcoded to 192.168.29.104|105|106|107 for the camera? Once I get my triforce back I can start testing fully.

I had to change the port on the regular webserver (for the cardemu) since I am guessing mariokart only looks at a fixed ip/port.
 
I see - ipaddres/img.jpg.

Works like a charm - anyway to have it bind to just one ip address? I didn't see it in the --help. Right now it binds to everything. Would be nice for it to bind to just one ip address, and I can have apache just bind to wireless.
 
Back
Top