В этой статье мастер расскажет нам как сделать виртуального помощника для компьютера и его физическую аватар. Аватар выполняет некоторые действия, когда с ним разговариваешь. Например, двигает руками и головой. В конце статьи можно посмотреть видео с демонстрацией работы и сборки устройства.
Инструменты и материалы:-Ардуино Нано;-Сервопривод SG90 – 3шт;-Ультразвуковой датчик HC-SR04;
-Лист ПВХ;
-Сервоколесо (для основания);
-Нож;
-Ножницы;
-Клеевой пистолет;
-Аэрозольная краска;
-Компьютер с ПО;
Шаг первый: принцип работы
Основной код или часть кода AI (искусственный интеллект) будет исполняться на компьютере. Это сделано потому, что компьютер поддерживает язык программирования python и имеет большую вычислительную мощность, чем маленький Arduino, а также, поскольку бот AI будет контролировать / автоматизировать некоторые задачи компьютера. Плата Arduino будет подключена к компьютеру с помощью USB-кабеля.
Идея состоит в том, чтобы запустить программу, которая будет выполнять преобразование речи в текст, обрабатывать текст, а также преобразовывать текст в речь. Т.е. робот будет слушать, понимать и отвечать. А также, его физическая копия, выполнять некоторые движения.
В качестве примера – если робот должен сказать ‘Hi/hello’, код Python отправит «h», а затем Arduino выполнит функцию hi ().
Шаг второй: печатная плата
Мастер разработал печатную плату, которую можно использовать для создания множества проектов. Она имеет слот для карт Micro SD, слот для модуля Bluetooth, внешний источник питания 5 В, и все это работает от Arduino Nano.
Печатную плату он заказал на специализированном сервисе, а пользователи могут скачать ее здесь.Шаг третий: схема и монтаж
Затем мастер собирает плату согласно схемы.Шаг четвертый: сборка бота
Для изготовления тела робота мастер использовал лист ПВХ, но можно использовать любой подходящий материал, например, картон.
Сначала он сделал туловище и установил в него плату и серводвигатели.Одна рука была сделана как гаечный ключ, в другую руку установил и приклеил штекер.
Дальше сделал голову и установил в нее ультразвуковой датчик.
Установил рычаги сервоприводов, собрал робота и покрасил в желтый цвет.
Шаг пятый: программирование
Сначала нужно загрузите Python с этого сайта.
Можно использовать любую версию Python, мастер использует Python3.7.1.
После установки Python нужно будет запустить некоторые команды из командной строки / терминала, чтобы установить библиотеки для распознавания речи, поддержки звука, преобразования текста в речь, автоматизации браузера, последовательной связи. Выполняем эти команды:
pip install speechrecognition pip install pyaudio pip install pyttsx3 pip install pywhatkit pip install pyserial
Затем загружает код.
author: ashraf minhaj mail: ashraf_minhaj@yahoo.com Last Edit: Nov 2020 License: Copyright (C) Ashraf Minhaj. General Public License (GPL3+) """ import speech_recognition as sr # voice recognition library import random # to choose random words from list import pyttsx3 # offline Text to Speech import datetime # to get date and time import webbrowser # to open and perform web tasks import serial # for serial communication import pywhatkit # for more web automation # Declare robot name (Wake-Up word) robot_name = 'jaundice' # random words list hi_words = ['hi', 'hello', 'yo baby', 'salam'] bye_words = ['bye', 'tata', 'hasta la vista'] r_u_there = ['are you there', 'you there'] # initilize things engine = pyttsx3.init() # init text to speech engine #voices = engine.getProperty('voices') #check for voices #engine.setProperty('voice', voices[1].id) # female voice listener = sr.Recognizer() # initialize speech recognition API # connect with NiNi motor driver board over serial communication try: port = serial.Serial("COM15", 9600) print("Phycial body, connected.") except: print("Unable to connect to my physical body") def listen(): """ listen to what user says""" try: with sr.Microphone() as source: # get input from mic print("Talk>>") voice = listener.listen(source) # listen from microphone command = listener.recognize_google(voice).lower() # use google API # all words lowercase- so that we can process easily #command = command.lower() print(command) # look for wake up word in the beginning if (command.split(' ')[0] == robot_name): # if wake up word found.... print("[wake-up word found]") process(command) # call process funtion to take action except: pass def process(words): """ process what user says and take actions """ print(words) # check if it received any command # break words in word_list = words.split(' ')[1:] # split by space and ignore the wake-up word if (len(word_list)==1): if (word_list[0] == robot_name): talk("How Can I help you?") #.write(b'l') return if word_list[0] == 'play': """if command for playing things, play from youtube""" talk("Okay boss, playing") extension = ' '.join(word_list[1:]) # search without the command word port.write(b'u') pywhatkit.playonyt(extension) port.write(b'l') return elif word_list[0] == 'search': """if command for google search""" port.write(b'u') talk("Okay boss, searching") port.write(b'l') extension = ' '.join(word_list[1:]) pywhatkit.search(extension) return if (word_list[0] == 'get') and (word_list[1] == 'info'): """if command for getting info""" port.write(b'u') talk("Okay, I am right on it") port.write(b'u') extension = ' '.join(word_list[2:]) # search without the command words inf = pywhatkit.info(extension) talk(inf) # read from result return elif word_list[0] == 'open': """if command for opening URLs""" port.write(b'l') talk("Opening, sir") url = f"http://{''.join(word_list[1:])}" # make the URL webbrowser.open(url) return elif word_list[0] == 'uppercut': port.write(b'U') elif word_list[0] == 'smash': port.write(b's') elif word_list[0] == 'punch': port.write(b'p') # now check for matches for word in word_list: if word in hi_words: """ if user says hi/hello greet him accordingly""" port.write(b'h') # send command to wave hand talk(random.choice(hi_words)) elif word in bye_words: """ if user says bye etc""" talk(random.choice(bye_words)) def talk(sentence): """ talk / respond to the user """ engine.say(sentence) engine.runAndWait() # run the app while True: listen() # runs listen one time
Дальше нужно запрограммировать Ардуино. Мастер использует Arduino.ide для программирования платы.
Как уже упоминалось ранее, программа Arduino ожидает последовательных данных. Если она получает какие-либо данные, она ищет сопоставление. Если данные совпадают с предопределенной командой, она выполняет команду.
Код можно скачать ниже.
/** JAUNDICE: AI Assistant robot with Arduino and Python ** * * author: ashraf minhaj * mail: ashraf_minhaj@yahoo.com * Last Edit: Nov 2020 * * License: Copyright (C) Ashraf Minhaj. * General Public License (GPL3+) */ #include<Servo.h> Servo head; Servo l_hand; Servo r_hand; // define sonar sensor's pins int trig = 4; int echo = 5; // received data byte val = ""; void setup() { // put your setup code here, to run once: head.attach(2); l_hand.attach(3); r_hand.attach(4); Serial.begin(9600); // for communicating via serial port with Python } void standby(){ // all motors to these positions head.write(90); int r_pos = 30; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); } void hi(){ // all motors to these positions head.write(90); int i = 0; for(i=30; i<= 170; i++){ r_hand.write(i); delay(5); } for(i=170; i>= 100; i--){ r_hand.write(i); delay(5); } for(i=100; i<= 170; i++){ r_hand.write(i); delay(5); } for(i=170; i>= 30; i--){ r_hand.write(i); delay(5); } standby(); } void hands_up(){ // do this on every command (nothing much just move hands a bit) //head.write(150); //delay(300); //head.write(90); int i = 0; for(i=30; i<= 170; i++){ int r_pos = i; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(5); } delay(600); for(i=170; i>= 30; i--){ int r_pos = i; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(5); } } void weight_lift(){ // lift weight using both hands int i = 0; for(i=30; i<= 170; i++){ int r_pos = i; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(5); } for(int count=0; count<=4; count++){ for(i=170; i>= 60; i--){ int r_pos = i; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(5); } for(i=60; i<= 170; i++){ int r_pos = i; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(5); } } for(i=170; i>= 30; i--){ int r_pos = i; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(5); } } void excited(){ return; } void look_left(){ // rotate hed to left head.write(180); } void confused(){ for(int count=0; count<=1; count++){ head.write(30); r_hand.write(170); delay(700); r_hand.write(30); head.write(120); l_hand.write(30); delay(700); l_hand.write(160); } standby(); } void double_punch(){ // do a punch int i = 0; for(i=30; i>= 0; i--){ int r_pos = i; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(5); } delay(2000); int r_pos = 80; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(500); standby(); } void r_upper_cut(){ // make right upper-cut int i = 0; for(i=30; i<= 170; i++){ int r_pos = i; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(5); } for(int count=0; count<=4; count++){ int i = 0; for(i=170; i>= 60; i--){ r_hand.write(i); delay(1); } for(i=60; i<= 170; i++){ r_hand.write(i); delay(1); } } standby(); delay(100); } void smash(){ // smash things int i = 0; for(i=30; i<= 170; i++){ int r_pos = i; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(5); } delay(2000); for(i=170; i>= 0; i--){ int r_pos = i; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(1); } delay(300); int r_pos = 180; int l_pos = map(r_pos, 0, 180, 180, 0); l_hand.write(l_pos); r_hand.write(r_pos); delay(1000); standby(); } void eye_detect(){ // do something if eye sensor detect motion return; } void loop() { // put your main code here, to run repeatedly: standby(); while(Serial.available() > 0) //look for serial data available or not { val = Serial.read(); //read the serial value if(val == 'h'){ // do hi hi(); } if(val == 'p'){ // do hi double_punch(); } if(val == 'u'){ hands_up(); delay(3000); } if(val == 'l'){ standby(); look_left(); delay(2000); } if(val == 'U'){ // uppercut r_upper_cut(); delay(2000); } if(val == 's'){ smash(); delay(2000); } } }
После выполнения всех этих шагов мастер подключает Arduino к компьютеру с помощью USB-кабеля, а затем запускает программу python. Еще нужно добавьте правильный порт Arduino в код Python.
