📜 ⬆️ ⬇️

Home Raspberry shooting gallery

Hi Habr.
I love small arms and shooting. However, at home it is a bad hobby. No, well, you can certainly buy trauma and ridge the apartment, but I think the home will not appreciate it. Not wanting to put up with this, I decided to realize my own, moderately safe home shooting range. If interested - welcome under cat.



Ideas on how to implement this have been in your head for a long time. Here are some rejected:
- phototransistor pistol + monitor screen. Highlighting half / quarter / one eighth /, etc. screen, check the response from the phototransistor and iteratively specify the part of the screen to which the gun is directed. The idea was rejected because of the low frequency of updating monitors and their inertia.
- pistol with phototransistor + screen of LED arrays. Already better, you can update the image on the diode array with a sufficient frequency. I even started soldering diode arrays, but I changed my mind in time.
- a pistol with a camera, several laser LEDs, forming marks on the wall, on which the camera determines its position. In principle, the idea was not bad. However, having estimated how the gun with a webcam bolted to it will look, it also refused it.
Well, the final idea - a static camera, looking at the wall and a gun with a laser. The idea is, the case for implementation.
Bought the first child pistol (Desert Eagle caliber 50). He threw out the insides, filed a file and set in it a laser diode, a button on the trigger and arduinina nano. No, you can of course put a capacitor in place of arduinin, so that he would switch the button from the power source to the diode and back, but this is not a flexible enough approach. Laser diode glued to cold welding. While it froze, carefully adjusted the included diode, combining it with the aiming bar.
Hidden text
Hidden text

Wrote the simplest sketch:
Hidden text
void setup() { pinMode(3, OUTPUT);//LED pinMode(2, INPUT);//Button to ground digitalWrite(2, true); } int t = 10000; bool PreButton = false; void loop() { bool Button = !digitalRead(2); if (PreButton == false && Button == true && t > 500) t = 0; if (t<5) digitalWrite(3, true); else digitalWrite(3, false); if (t<10000) t++; PreButton = Button; delay(1); } 

The gun "shoots" short pulses of 4ms (picked up during the setup process) with a maximum rate of fire of 2 shots per second.
Next, the case for the receiving party. I bought a simple webcam. Malinka was already in the bins. I connected the camera, sent it to the wall.
Hidden text

Next you need to put the necessary packages on the raspberry
 sudo apt-get install libv4l-0 libopencv-dev python-opencv 

It remains to write a Python script. This was my first python script, so I had to kill him for almost a day.
Hidden text
 #!/usr/bin/python import sys import cv2 import math import subprocess if __name__ == '__main__': #target in camera CenterX = 426.5 CenterY = 190.5 Radius = 40.0 width = 800 height = 640 capture = cv2.VideoCapture(0) capture.set(3, width); capture.set(4, height); image = cv2.imread("target.jpg", cv2.CV_LOAD_IMAGE_COLOR) target_x = float(image.shape[0])*0.5 target_y = float(image.shape[1])*0.5 target_Radius = min(target_x,target_y) target = image.copy() cv2.namedWindow("Result", 1) cv2.imshow("Result", target) ShotCount = int(); Scoore = 0; while 1: if cv2.waitKey(1) >= 0: break ret,frame = capture.read() grey_image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) ret,grey_image = cv2.threshold(grey_image, 245, 255, cv2.THRESH_BINARY) # grey_image = cv2.erode(grey_image, None, iterations = 1) # grey_image = cv2.dilate(grey_image, None, iterations = 1) (contour, _) = cv2.findContours(grey_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if contour: subprocess.Popen('aplay Shot.wav', shell = True) cntr = sorted(contour, key = cv2.contourArea, reverse = True)[0] (x,y), radius = cv2.minEnclosingCircle(cntr) center = (x, y) shot_x = (float(x) - CenterX)/Radius shot_y = (float(y) - CenterY)/Radius dist = math.sqrt(shot_x*shot_x+shot_y*shot_y) shot_x = target_x + shot_x*target_Radius shot_y = target_y + shot_y*target_Radius Shot = (int(shot_x), int(shot_y)) cv2.circle(target, Shot, 5, (60,60,255),10) cv2.circle(target, Shot, 10, (120,120,120),1) cv2.imshow("Result", target) #calibrate #print (center, dist) print ("Shots", ShotCount+1) if dist < 1.0: Scoore += 1 - dist ShotCount += 1 if ShotCount > 6: ShotCount = 0; Scoore = Scoore/7.0*100.0 print("You Scoore: ", Scoore) Scoore = 0 target = image.copy() cv2.waitKey(300) subprocess.Popen('aplay 924.wav', shell = True) cv2.waitKey(1000) cv2.waitKey(50) cv2.destroyAllWindows() 

A little bit of explanation. The script takes pictures from the camera and converts them into black and white. Then it cuts off everything that is darker 245. As practice has shown, the spot of a laser diode is detected very confidently even with a pulse length of only a couple of milliseconds. Next we find the contour of the spot and the minimum circle describing it. We draw hits on targets, we lose a sound. After seven “shots” we count the points (of which you can fill a maximum of 100).
Before shooting, you need to calibrate the position of the target in the chamber.
By the way "target":
Hidden text

My camera is three meters from the target. Uncomment the line #print (center, dist), shoot until we get exactly to the center. We look in the log position of the hit and write to the beginning of the script (CenterX, CenterY). Also there rule Radius to your target size.
The resolution of the camera with three meters is about two millimeters. If this seems a little, you can just move the camera.
Everything, we fall into the childhood we start fire training classes.

The process looks like this (litter for shabby wallpaper - I live in a rented apartment):
')


Sources to the project: github.com/DIMOSUS/Laser-shoting

Do not forget about security - you can only look at the laser, like in a telescope in the sun, twice ...
In the future, I would like to install a servomotor in the pistol, which will pull the load to simulate recoil. Well, print a normal target.

Source: https://habr.com/ru/post/248181/


All Articles