DIY: A robot submarine to explore the waters of the Moscow River. Part 1

    This is a brief history of the creation of an underwater autonomous robot by a very middle manager. The current goal is to create an up-to-date map of the fairway of the Moscow River. When searching, there is no problem finding such a map , but its relevance raises the question. The river bed is constantly changing. Erosion of the riverbanks occurs and the channel map changes. These processes are especially noticeable, given the nutrition of the Moscow River snow (61%), ground (27%) and rain (12%). The ultimate goal is to create a multifunctional underwater robot for the study of the deep sea. The oceans covering 2/3 of the Earth’s surface has been studied only 5%. To create an autonomous robot, you need a simple “autopilot”.

    How to make an affordable and easy autopilot for DIY projects and sail on it along the Moscow River?





    The Moscow River is the main waterway of the city of Moscow, the length within the city is 80 km. The width of the river inside the city varies from 120 to 200 m, from the narrowest part near the Kremlin to the widest near Luzhniki. It is generally accepted that the river flow rate is 0.5 m / s. Quite favorable conditions for testing the robot.
    It might be more efficient and easier to make a boat, but the task of making an underwater robot seems a lot more interesting.

    Design


    Robot submarine to explore the waters of the Moscow River.

    The approximate arrangement of the elements I saw as follows.


    Installing the collector motor.


    Servo-drive steering.


    Servo-drive steering depth.


    As a joke, I can say that I'm preparing for the X-Prize competition .
    It remains to save $ 2000. :)

    The registration deadline is 30 June, 2016 (11:59 PM UTC / 4: 59 PM PST). The registration fee is $ 2,000.00 USD.



    The goal is to develop an autonomous underwater robot, not ROV . (Remotely operated underwater vehicle).

    The electronic part is not distinguished by the complexity and build quality of the
    Arduino nano + L293D + Bluetooth + 3 servo + Power bank (Special thanks to the online store that sold such for 3 cents). Separately connected to the Power bank smartphone Samsung Galaxy S3 to maintain charge. The smartphone communicates with Arduino via Bluetooth.


    Management Software


    “We are meeting our fate on the path that we have chosen to leave from it”
    Jean de Lafontaine


    I always tried to avoid programming on Android. When it became possible to develop even a lightweight application with the ability to get to know Android in action, I gave in.
    But the time has come! Indeed, stop wasting money on nameplates for Arduino. All you need is already in your old smartphones. At hand was the Samsung Galaxy S3 and a bit of magic.
    As a decent geek, I asked a question on the toaster . Maybe I asked hard. Perhaps a poorly worded question. And it seemed more likely this was not a question. But in response, I did not get what I expected.
    Yandex to me in the bay! All requests “Android GPS”, “Programming Android GPS” and so on gave answers that definitely did not work on Android Studio.
    What a relief for me was finding SL4A. It turns out you can prototype and program on Android using Python. They control, after all, even rockets .

    SL4A Python


    If you have an Android phone, but you have one. You're a geek, not a fan of sugary fruits.
    We select a program for recognizing QR codes .
    To use SL4A, you must install the application on your phone.

    The Python interpreter is here.

    Or QPython3

    It is possible to write programs on the phone, but you can’t call it a fun activity.
    There is a way out
    Source: http://habrahabr.ru/post/134184/
    Let's redirect all local traffic coming to port 9999 to the Android device (assume that the server is listening on port 46136):
    $ adb forward tcp: 9999 tcp: 46136 It
    remains to create an environment variable and the setup is finished:
    $ AP_PORT = 9999 It
    remains to add the android.py file to the Python library folder, and that’s it, now you can write applications on your computer, run them, and you can see the result right away on the phone. To run helloWorld on an Android device, now just enter in the Python interpreter:
    >>> import android
    >>> droid = android.Android ()
    >>> droid.makeToast (“Hello, world!”)

    In the first line, the android library is imported, then a droid object is created, using which the Android API is used. The last line displays the message “Hello, World!” On the device screen.
    Now is the time to take a closer look at the API that SL4A provides.


    Building a path. Point selection



    Using Yandex.maps or Google.maps, select points in the center of the river. This is an example route. For tests and setup I use a truncated version of the points.
    [55.671110, 37.686625], [55.668448, 37.675467], [55.660847, 37.671776], [55.654649, 37.671175]

    How to make an affordable and easy autopilot for DIY projects from an andoid phone and 70 lines of code?




    Autopilot code
    import math,android,time
    coordmas = [[55.671110, 37.686625],[55.668448, 37.675467],[55.660847, 37.671776],[55.654649, 37.671175]]
    droid = android.Android()
    droid.startSensingTimed(1,200)
    droid.startLocating(5000, 30)
    def getgps():
    	locs = droid.getLastKnownLocation()
    	gpspos = locs.result["gps"]
    	return gpspos
    def distazim(llat1,llong1,llat2,llong2):
    	rad=6372795
    	#врадианах
    	lat1=llat1*math.pi/180.
    	lat2=llat2*math.pi/180.
    	long1=llong1*math.pi/180.
    	long2=llong2*math.pi/180.
    	cl1=math.cos(lat1)
    	cl2=math.cos(lat2)
    	sl1=math.sin(lat1)
    	sl2=math.sin(lat2)
    	delta=long2-long1
    	cdelta=math.cos(delta)
    	sdelta=math.sin(delta)
    	y=math.sqrt(math.pow(cl2*sdelta,2)+math.pow(cl1*sl2-sl1*cl2*cdelta,2))
    	x=sl1*sl2+cl1*cl2*cdelta
    	ad=math.atan2(y,x)
    	dist=ad*rad
    	x=(cl1*sl2)-(sl1*cl2*cdelta)
    	y=sdelta*cl2
    	z=math.degrees(math.atan(-y/x))
    	if(x<0):
    		z=z+180.
    	z2=(z+180.)%360.-180.
    	z2=-math.radians(z2)
    	anglerad2=z2-((2*math.pi)*math.floor((z2/(2*math.pi))))
    	angledeg=(anglerad2*180.)/math.pi
    	return [dist,angledeg]
    def servoangle(azdiff):
    	if azdiff>10 or azdiff<-10:
    		deg=azdiff
    		if deg>90:
    			deg=90
    		if deg<-90:
    			deg=-90
    	return deg
    gpspos=getgps()
    oldlat = gpspos["latitude"]
    oldlon = gpspos["longitude"]
    for c in range(len(coordmas)):
    	#получение координат текцщей целевой точки
    	curcoord=coordmas[c]
    	targetlat=curcoord[0]
    	targetlon=curcoord[1]
    	darange=11;
    	while darange>10:
    		gpspos=getgps()
    		curlat = gpspos["latitude"]
    		curlon = gpspos["longitude"]
    		time.sleep(0.5)
    		da=distazim(curlat,curlon,targetlat,targetlon)
    		darange = da[0]
    		dazimut = round(da[1])
    		pol=droid.sensorsReadOrientation()
    		pol2=pol.result
    		turn = round(pol2[0])
    		turn = (-turn) *180/ 3.2
    		azdiff=turn-dazimut
    		deg=servoangle(azdiff)
    	oldlat = curlat
    	oldlon = curlon
    



    Code with comments
    import math,android,time
    #Массив координат
    coordmas = [[55.671110, 37.686625],[55.668448, 37.675467],[55.660847, 37.671776],[55.654649, 37.671175]]
    #Инициализация, запуск GPS, сенсоров
    droid = android.Android()
    droid.startSensingTimed(1,200)
    droid.startLocating(5000, 30)
    #Функции
    #GPS
    def getgps():
    	locs = droid.getLastKnownLocation()
    	gpspos = locs.result["gps"]
    	return gpspos
    #Функция определения расстояния и азимута между двумя GPS-точками
    def distazim(llat1,llong1,llat2,llong2):
    	rad=6372795
    	#врадианах
    	lat1=llat1*math.pi/180.
    	lat2=llat2*math.pi/180.
    	long1=llong1*math.pi/180.
    	long2=llong2*math.pi/180.
    	#косинусыисинусыширотиразницыдолгот
    	cl1=math.cos(lat1)
    	cl2=math.cos(lat2)
    	sl1=math.sin(lat1)
    	sl2=math.sin(lat2)
    	delta=long2-long1
    	cdelta=math.cos(delta)
    	sdelta=math.sin(delta)
    	#вычислениядлиныбольшогокруга
    	y=math.sqrt(math.pow(cl2*sdelta,2)+math.pow(cl1*sl2-sl1*cl2*cdelta,2))
    	x=sl1*sl2+cl1*cl2*cdelta
    	ad=math.atan2(y,x)
    	dist=ad*rad
    	#вычислениеначальногоазимута
    	x=(cl1*sl2)-(sl1*cl2*cdelta)
    	y=sdelta*cl2
    	z=math.degrees(math.atan(-y/x))
    	if(x<0):
    	z=z+180.
    	z2=(z+180.)%360.-180.
    	z2=-math.radians(z2)
    	anglerad2=z2-((2*math.pi)*math.floor((z2/(2*math.pi))))
    	angledeg=(anglerad2*180.)/math.pi
    	return [dist,angledeg]
    def servoangle(azdiff):
    	if azdiff>10 or azdiff<-10:
    		deg=azdiff
    		if deg>90:
    			deg=90
    		if deg<-90:
    			deg=-90
    	return deg
    #принятие текущего положения за старую точку
    gpspos=getgps()
    oldlat = gpspos["latitude"]
    oldlon = gpspos["longitude"]
    #Цикл
    for c in range(len(coordmas)):
    	#получение координат текцщей целевой точки
    	curcoord=coordmas[c]
    	targetlat=curcoord[0]
    	targetlon=curcoord[1]
    	#выполняем цикл пока расстояние больше 10 метров до след.точки
    	darange=11;
    	while darange>10:
    		#определение координат	
    		gpspos=getgps()
    		curlat = gpspos["latitude"]
    		curlon = gpspos["longitude"]
    		time.sleep(0.5)
    		#сравнение дальности и азимута до след. точки.
    		da=distazim(curlat,curlon,targetlat,targetlon)
    		darange = da[0]
    		dazimut = round(da[1])
    		#определяем угол телефона
    		pol=droid.sensorsReadOrientation()
    		pol2=pol.result
    		turn = round(pol2[0])
    		#[1.57=left, 0=stop, -1.57=right]
    		turn = (-turn) *180/ 3.2
    		#если угол точки отличается от угла телефона на 10 градусов готовим команду на поворот
    		azdiff=turn-dazimut
    		#готовим данные для угла поворота сервы руля
    		deg=servoangle(azdiff)
    		#отправляем по блютус угол поворота серво
    	#Меняем координаты старой точки, т.к. ожидается смена координат текущей цели
    	oldlat = curlat
    	oldlon = curlon
    



    Python For Android. Features I've been looking for for a long time
    Battery:
    droid.batteryStartMonitoring () - started working with the battery.
    droid.batteryStopMonitoring ()
    droid.batteryGetHealth () - returns the battery status (1-unknown, 2-good, 3 - overheating, 4 - dead, 5 - overload, 6 - unknown failure)
    droid.batteryGetStatus () - returns the battery status ( 1 - unknown, 2 - charging, 3 - discharging, 4 - not charging, 5 - maximum charge)
    droid.batteryGetTechnology ()
    droid.readBatteryData () - data about the battery.
    droid.batteryGetTemperature ()
    droid.batteryGetVoltage ()
    droid.batteryGetLevel ()

    Bluetooth:
    droid.checkBluetoothState () - checks if Bluetooth is turned on
    droid.toggleBluetoothState () - turns on if in brackets True and turns off if False
    droid.bluetoothAccept () - accepts a connection
    droid.bluetoothActiveConnections () - checks if there are any
    droid.bluetoothGetConnectedDeviceName ()
    connections droid.bluetoothMakeDiscoverable () - time interval in seconds
    droid.bluetoothStop ()

    Wi-Fi:
    droid.checkWifiState () - checks if Wi-Fi is on
    droid.toggleWifiState () - turns on if in brackets True and turns off if False
    droid.wifiStartScan ()
    droid.wifiGetScanResults ( )
    droid.wifiGetConnectionInfo ()

    Other settings:
    droid.checkAirplaneMode () - checks if the “Airplane” mode is on
    droid.checkRingerSilentMode () - checks whether the silent mode enabled
    droid.checkScreenOn () - if the screen is enabled
    droid.toggleRingerSilentMode () - includes a silent mode
    droid.toggleAirplaneMode ()
    droid.toggleVibrateMode ()

    Obtaining information about the settings:
    droid.getMaxMediaVolume ()
    droid .getMaxRingerVolume ()
    droid.getMediaVolume ()
    droid.getRingerVolume ()
    droid.getScreenBrightness ()
    droid.getScreenTimeout ()
    droid.getVibrateMode ()

    Setting:
    droid.setMediaVolume ()
    droid.setRingerVolume ()
    droid.setScreenBrightness ()
    droid.setScreenTimeOut ()


    In the plans:
    • Configure Bluetooth data sending to arduino.
    • Getting depth data from arduino. I will measure the depth with an ultrasonic sensor.
    • Sending data about the current position and depth measurements to the server.
    • Finalization of the design. The boat should be with zero buoyancy so that the depth can be changed by rudders. Perhaps the design of the submarine will have to go to the surface vehicle.
    • Test, test, test


    PS: Why did I decide to write a post before the launch of the robot? I want to find like-minded people. If you have a desire - do your robot. A great occasion to gather at the May holidays for an aqua ride on the Moscow River on robots! For all questions you can write to me VK . Please repost, maybe one of your friends will want to take part in the aqua marathon.

    Let me remind you: the
    contest of robotic lawnmowers will be held in Skolkovo on June 3. Everyone can try their hand at robotics. Following the results of the competition, we want to select a team for a startup. We will make the first Russian commercial robot mulcher. Valuable prizes and gifts for all participants.

    Also popular now: