[割草机]-任何人都可以通过Internet控制的割草机

你有时间吗 你能割我的草坪吗?


机器人割草机膝盖发展的简要历史。您可以通过Internet在世界任何地方对其进行管理。梦想过像漫游车或月球漫游车的操作员吗?只需访问mowmylawn.ru网站,您就可以控制我院子里的割草机!




背景知识


割草机的整个故事始于2015年夏天,我在GT上发表的第一篇文章就是关于我从车库里出售割草机的经验。

电视



之后,Robomow代表建议使用其平台进行进一步开发。这非常方便,因为有关硬件和机械的所有问题都需要特殊的技能,并且会花费大量时间。

我真的很想组织一场机器人割草机比赛事实证明,这不是一件容易的事。注册了15个以上的团队,但最终只有3个参与者显示了进度。

罗曼·萨科维奇(Roman Sakovich),明斯克(白俄罗斯),“贝尔默”
: . , .

: . Raspberrry Pi — . , , . Nucleo stm32 — . , , .

: RTK, . .

: GPS/GLONASS. . . .



特维尔Feofanov I.A.


, , . , . , , — ( , ).

尼古拉·米龙尼科夫(Nikolay Mironnikov),新西伯利亚



在斯科尔科沃举行比赛的所有努力都是徒劳的。最后,事实证明,斯科尔科沃的机器人竞赛没有免费的草坪。所有可能的赞助商都不想在前景不明的情况下搞砸新竞争。我什至没有收到给市政组织的信的答复。结果,我们组织来自不同城市的4名参赛者的比赛前景很模糊。尽管事实证明该比赛是国际比赛,但取消比赛还是比较方便的,因为这并不遗憾。

Robocower2016。ROS和乐趣


我学习ROS并为机器人割草机编写启动器,我使用Kinect和SLAM,只有在视觉里程表上,机器人才能构建地图并绘制路线。 Kinect在阳光明媚的天气下效果不佳。使用ROS,您将在一个夜晚制作出“ Hello World!”,然后进入黑暗。我从来没有找到关于初学者如何制作机器人的常规指南,而不仅仅是写主题。有没有人想知道为什么俄罗斯联邦在ROS社区地图上没有一个点?我开了一个VK小组


在业余时间,他将两个伺服器,一个超声波传感器和一个Arduino拧紧在他的“主力马”上。一个简单的桦木绕行和停止测试通过了!然后深渊,让这个东西通过您的网站很危险!她甚至无法像你知道的机器人那样踢。


事实证明,机器人-在大多数人的理解中,尤其是在服务机器人方面,事情非常无聊。是的,我知道机器人真空吸尘器和猫之间的友谊。我从波士顿动力公司,达帕公司和俄罗斯作战机器人的化身中了解到超级创造物,这更像是机器人,而不是其中某种算法与现实世界互动的盒子。

在对我女儿的理解中,机器人至少是变压器,而不是我花费时间的垃圾。我做出了一个艰难的决定,“暂时”用机器人割草机在蓝牙控制器上制作了一个玩具。



管理工作与吹雪机相同原来很有趣!特别是对于爸爸。

吹雪机视频




进一步-更多!我对不是通过蓝牙而是通过遥测通过互联网实施控制的想法很感兴趣。无聊,新鲜而刻薄的想法!

但是,如果允许任何互联网用户控制我的割草机怎么办?您是否知道这样的主意很难摆脱?只是... 接受挑战!

割草机







Raspberry pi,USB集线器,wifi适配器,网络摄像头被巧妙地添加到魔术盒中。
从铁的有趣观点。我没有适合引擎的驱动程序。通常,将用于场效应晶体管的H桥或用于继电器的(硬核)用作驱动器。我选择一个更严格的选项,因为可以使用的是继电器。



通常的连接方案意味着每个引擎有4个键,即8对2台正在运行的引擎。



考虑到可以使用继电器的常开状态以及不需要单独设置电动机的事实,您可以为两个运行中的电动机仅做5个继电器。

除了机器人本身之外,还在房屋上安装了摄像机,摄像机的频率为3帧/秒。将站点的概述照片上传到Internet上的ftp服务器,以更好地定位。但是随后简单地替换为ivideon的解决方案。

程序


和以前一样,Arduino在串行端口上收到一条字符消息,指示必须采取的措施。同样,为了进行测试和调试,从覆盆子接收的代码也是通过蓝牙发送的,您可以在终端模式下连接手机并从手机上的服务器接收数据。

素描Arduino
int m1=2;
int m1b=3;
int m2=4;
int m2b=5;
int mk=6;
int pis=7;


char a,b;

void setup()  
{
Serial.begin(9600);
Serial1.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  while (!Serial1) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  Serial.println("Start");

 pinMode(statpin, OUTPUT);
 pinMode(m1, OUTPUT);
 pinMode(m1b, OUTPUT);
 pinMode(m2, OUTPUT);
 pinMode(m2b, OUTPUT);
 pinMode(mk, OUTPUT);
 pinMode(pis, OUTPUT);

analogWrite(pis,  1000);
delay(100);
analogWrite(pis,  700);
delay(200);
analogWrite(pis,  300);
delay(300);
analogWrite(pis,  1000);
delay(100);
analogWrite(pis,  100);
digitalWrite(pis,  HIGH);
 digitalWrite(statpin, LOW);
digitalWrite(m1, LOW);
digitalWrite(m1b,  LOW);
digitalWrite(m2, LOW);
digitalWrite(m2b,  LOW);
digitalWrite(mk,  LOW);
digitalWrite(pis,  HIGH);

}

void loop() // run over and over
{

  if (Serial.available()){
     a=Serial.read();
     Serial1.println(a);

    if(a=='B'){
digitalWrite(m1, HIGH);
digitalWrite(m1b,  LOW);
digitalWrite(m2, HIGH);
digitalWrite(m2b,  LOW);
    }
    if(a=='F'){
digitalWrite(m1, HIGH);
digitalWrite(m1b, HIGH);
digitalWrite(m2, HIGH);
digitalWrite(m2b,  HIGH);
    }
    if(a=='R'){
digitalWrite(m1, HIGH);
digitalWrite(m1b, LOW);
digitalWrite(m2, HIGH);
digitalWrite(m2b,  HIGH);
    }
    if(a=='L'){
digitalWrite(m1, HIGH);
digitalWrite(m1b, HIGH);
digitalWrite(m2, HIGH);
digitalWrite(m2b,  LOW);
    }

       if(a=='S'){
digitalWrite(m1, LOW);
digitalWrite(m1b, LOW);
digitalWrite(m2, LOW);
digitalWrite(m2b,  LOW);
    }

       if(a=='W'){
digitalWrite(mk, HIGH);
    }  
       if(a=='w'){
digitalWrite(mk, LOW);
    }   

       if(a=='V'){
digitalWrite(pis, LOW);
    }  
       if(a=='v'){
digitalWrite(pis, 700);
    }   
  
    }else{
      
    }
  
}




树莓派上有两个Python脚本。使用opencv的脚本之一是从流动站上安装的网络摄像头捕获视频,然后通过ftp将其上传到服务器。同样,具有一定比例的可能性,照片和列表中的随机消息也会上传到Twitter帐户

第一个脚本
import numpy as np
import sys
import pygame
import pygame.camera
from pygame.locals import *
from twython import Twython
from random import random
import ftplib


pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0",(550,400))
cam.start()

CONSUMER_KEY = '-------MBZDT1PwibFeIcSp'
CONSUMER_SECRET = '-----------------1ZGHgBRz6aEr4YhUVuO84CuEV'
ACCESS_KEY = '-----------------4MCjSkny9Y6rJj5I32ulXctISQF'
ACCESS_SECRET = '------------------------cDadRY3He5Kv6CXVuqy2Dh'
api = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)
api.verify_credentials()

host = "-.--.---.196"
ftp_user = "ftp_user"
ftp_password = "ftp_password"
con = ftplib.FTP(host, ftp_user, ftp_password)
con.cwd("/mowmylawn.ru/webcam")

a={0:' !   !',1:'  .   !',2:'     ...    ',3:'      ?',4:',   !',5:'  ,        :)) !',6:', ... !',7:' ,     .',8:'  :  -  ',9:'  —  ,    ...',10:'    :    ?',11:'  ',11:'-,   ',12:' -  ,         .',13:'—     ! — ,    !',14:',   ! ...:(((!',15:'  ? robogazon.ru',16:' ,    !'}

def twit():
    image = cam.get_image()
    pygame.image.save(image,'webcam.jpg')
    photo = open('webcam.jpg','rb')
    b = random() * (len(a)-1)
    b = int(round(b,0))
    #api.upload_media(media=photo)
    #api.update_status(status=a[b])
    api.update_status_with_media(media=photo, status=a[b])

def ftpimg():
    image = cam.get_image()
    pygame.image.save(image,'webcam.jpg')
    photo = open('webcam.jpg','rb')
    send = con.storbinary("STOR "+ 'webcam.jpg', photo)

while 1 :
    ftpimg()
    b = random() * (500)
    b = int(round(b,0))
    if b==107:
        twit()

con.close



第二个脚本通过http接收当前要在服务器上执行的命令,并通过串行将该命令发送到arduino。
  • “ S”-停止
  • “ F”-继续
  • “ B”-返回
  • “ L”-左侧
  • “ R”-右侧
  • “ W”-启用割草引擎
  • “ W”-关闭割草机
  • “ V”-打开信号
  • “ V”-关闭信号


第二脚本
import serial,time
import urllib3

http = urllib3.PoolManager()


ser = serial.Serial("/dev/ttyUSB0",9600)
ser.writelines("S");

olddata=0
countolddata=0
while 1 :
    r = http.request('GET', 'http://mowmylawn.ru/1.php')
    
    if r.data!=olddata:
        olddata=r.data
        countolddata=0
    else:
        countolddata+=1
    
    if countolddata>20:
        ser.writelines("S")
    else:
        ser.writelines(r.data)

ser.close()
con.close



网络服务


我上传了一个页面进行引导。页面上有两个.jpg文件,它们在下载时会更新。有许多因素会影响控制和遥测的延迟,这是您的连接速度,服务器上的通道以及我所在位置的通道。

更新代码.jpg
<script>
setInterval(function(){
var im1='http://mowmylawn.ru/webcam/webcam.jpg?s='+Math.random();
var im2='http://kosmos-podolsk.ru/webc1.jpg?s='+Math.random();
var tmpImg = new Image() ;
    tmpImg.src = im1 ;
    tmpImg.onload = function() {
         $("#w1dd").attr('src',im1 );
    } ;

    tmpImg.src = im2 ;
    tmpImg.onload = function() {
         $("#w2dd").attr('src',im2 );
    } ;	

}, 200);
</script>



我设法达到的最大刷新率:
  • 流动站上的摄像头为4 Hz;
  • 房屋上的摄像头为3 Hz。

Mysql数据库由2个表组成,第一个表包含键/值对,这是机械手的命令。第二个表是用户。
当您进入站点队列时,将发送一个ajax获取请求以添加用户,带有时间戳标记,您的IP和所生成控制键的记录将输入数据库。

只有一个人可以同时控制割草机(我除外)-这是时间戳最小的用户。当轮到您开始控制割草机时-将管理开始的时间戳记输入数据库,每个数据库都有60秒的时间进行控制...



每次您指向控制按钮时,都会通过命令和您的控制键发送一个ajax获取请求,并检查当前时间与您启动“游戏”时间之间的时差,如果时差超过60秒,游戏将为您结束,您的记录从基地移走后,您可以再次排队,“游戏”进入下一个玩家。

宣传影片




然后我认为有必要用英语拍摄...然后奥斯塔普(Ostap)受了伤。








我在reddit上的第一篇文章。尝试管理mowmylawn.ru。如果队列过多或影响效率,请谅解。

PS:请记住,您可以参加一个联合项目,为冲击运动KickBrick开发健身追踪器团队正在等你!

UPD:我遇到了三个问题,其中两个已经解决。
1)演习过于活跃时,〜27V推进发动机的电源电缆已断开,其中一台发动机没有前进。
2)显然,由于使用同一根电线,wi-fi适配器烧坏了
3)大量具有GT和reddit的用户首先导致超过1000个用户的队列,然后服务器崩溃。优化就是我们的一切!

UPD:我不得不更换arduino并清理队列。你可以试试看

UPD:

Source: https://habr.com/ru/post/zh-CN397391/


All Articles