Голосовое управление освещением X10 из ROS. Часть 5. Будильник в ROS


В этих статьях — Часть1, Часть 2, Часть 3 и Часть 4 я рассматривал голосовое управление приборами X10 через ROS. Добавим к данной системе будильник с голосовым оповещением.

Задача ставилась следующая — для каждой записи будильника установить:

время срабатывания
количество повторений срабатывания и интервал
дни недели для данного будильника
действия по срабатыванию будильника, пока такие:
голосовое оповещение
запуск короткого музыкального файла (рингтона)
отправка команд для управления приборами x10

Скрипт node_x10_alarm_pub.py создает узел node_x10_alarm_events, который будет ожидать время срабатывания (либо повторного оповещения) будильников. Список будильников находится в двумерном массиве alarm_events

Для каждой записи, например

[«06:20″,3,5,[0,1,2,3,4],{1:»rington6.mp3;17»,2:»Подъём пора на работу, вставай Виктор Александрович «,4:»12»}],

06:20 — время срабатывания
3 — количество повторений
5 мин — интервал между повторениями
дни недели (0-4 — понедельник — пятница)

действия

1 — публикация в тему x10_alarm_mediaplayer (имя звукового файла) для запуска медиапроигрывателя
2 — публикация в тему x10_alarm_festival голосовое сообщение (запуск программы festival)
3 — получение текущего времени и публикация в тему x10_alarm_festival для голосового сообщения (запуск программы festival)
4 — публикация в тему x10_voicetotext посылка команды для приборов x10 в тему

Перед голосовым оповещением о текущем времени, время переводится в строковое сообщение а затем строка отправляется в тему x10_alarm_festival.

Запуск узла node_x10_alarm_pub.py

rosrun vp_x10_voice   node_x10_alarm_pub.py

Содержимое файла node_x10_alarm_pub.py

#!/usr/bin/env python
#-*-coding:utf-8 -*-

#
#  Ожидание событий будильника
#
#  и отправка команд в темы для
#  x10, festival(голос), медиаплейер(музыка),x10 (свет x10)
#

import roslib; roslib.load_manifest('vp_x10_voice')
import rospy
import subprocess
import shlex
import time
from datetime import datetime, timedelta

from std_msgs.msg import String
from std_msgs.msg import Int16


alarm_events=[
   ["06:30",2,5,[0,1,2,3,4,5,6],{1:"rington2.mp3;23",2:"Надо прогулять Графа "}],
   ["06:15",3,3,[0,1,2,3,4,5,6],{1:"rington6.mp3;17",2:"Подъём  пора на работу, вставай Виктор Александрович "},4:"12"],
   ["9:20",500,1,[0,1,2,3,4,5,6],{1:"rington6.mp3;19",3:"Время "}],
   ["18:30",2,5,[0,1,2,3,4,5,6],{1:"rington2.mp3;23",2:"Надо прогулять Графа "}],
   ["23:00",2,5,[0,1,2,3,4,5,6],{1:"rington2.mp3;23",2:"Надо прогулять Графа "}],
   ];
name_hours=[
           [{1,21},"час"],
           [{2,3,4,22,23},"часа"],
           [{5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20},"часов"],
          ]
name_minutes=[
           [{1,21,31,41,51},"минута"],
           [{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54},"минуты"],
           [{5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,25,26,27,28,29,30,35,36,37,38,39,40,45,46,47,48,49,50,55,56,57,58,59},"минут"],
          ]


def my_alarm():
    pub1 = rospy.Publisher('x10_alarm_mediaplayer',String)
    pub2 = rospy.Publisher('x10_alarm_festival', String)
    rospy.init_node('node_x10_alarm_events')

    d=datetime.today()
    dh=d.hour;dm=d.minute;
    while not rospy.is_shutdown():
      d=datetime.today()
      if(d.hour!=dh or d.minute!=dm):
        for element in alarm_events:
          for dt in range(element[1]):  # кол-во повторений element[1]
            alarm_time=element[0]
            dminutes=dt*element[2]      # промежуток повторения
            dd=timedelta(minutes=dminutes)
            d1=d-dd
            if(d.hour<10):
               this_time="0"+str(d.hour)
            else:
               this_time=str(d.hour)
            if(d.minute<10):
               this_time+=":0"+str(d.minute)
            else:
               this_time+=":"+str(d.minute)
            #this_time=str(d.hour)+":"+str(d.minute)
            cor_this_time=str(d1.hour)+":"+str(d1.minute)
            #rospy.loginfo(this_time)
            try:
              element[3].index(d.weekday())
              if (alarm_time==cor_this_time):
                rospy.loginfo("!!!!!!!!!!!!==="+alarm_time+"---"+this_time)
                for key in element[4]:
                   if key==1:
                     rington_file=element[4][key].split(";")[0];
                     pub1.publish(rington_file)
                     time.sleep(int(element[4][key].split(";")[1]))
                     rospy.loginfo("program 1 ")
                   elif key==2:
                     pub2.publish(element[4][key])
                     time.sleep(5)
                     rospy.loginfo("program 2 ")
                   elif key==3:
                     for ho in name_hours:
                       if d.hour in ho[0]:
                         strtime1= str(d.hour)+" "+ho[1]
                         break
                     if d.minute>0:
                       for mi in name_minutes:
                         if d.minute in mi[0]:
                            strtime2=" "+str(d.minute)+" "+mi[1]
                            break
                     strtime2=strtime2.replace("01","одна")
                     strtime2=strtime2.replace("21","двадцать одна")
                     strtime2=strtime2.replace("31","тридцать одна")
                     strtime2=strtime2.replace("41","сорок одна")
                     strtime2=strtime2.replace("51","пятьдесят одна")
                     strtime2=strtime2.replace("02","две")
                     strtime2=strtime2.replace("22","двадцать две")
                     strtime2=strtime2.replace("32","тридцать две")
                     strtime2=strtime2.replace("42","сорок две")
                     strtime2=strtime2.replace("52","пятьдесят две")
                     pub2.publish(element[4][key]+strtime1+strtime2)
                     time.sleep(5)
                     rospy.loginfo("program 3 ")
                   elif key==4:
                     pub4.publish(int(element[4][key]))
                     time.sleep(1)
                     rospy.loginfo("program 4 ")
                   else:
                     pass
            except ValueError:
              pass
        dh=d.hour;dm=d.minute;
      else:
        time.sleep(10)


if __name__ == '__main__':
    try:
        my_alarm()
    except rospy.ROSInterruptException: pass

Теперь создаем два узла subscriber — получателей сообщений из тем x10_alarm_festival и x10_alarm_mediaplayer.

Узел node_x10_alarm_mediaplayer получает сообщение String из темы nx10_alarm_mediaplayer и запускает программу проигрывания звуковых файлов. Я запускаю программу smplayer, можно любой проигрыватель.

Содержимое файла node_x10_mediaplayer_sub.py

#!/usr/bin/env python
#-*-coding:utf-8 -*-

#
#  Слушатель x10_mediaplayer
#
#  и запуск медиапроигрывателя
#
#

import roslib; roslib.load_manifest('vp_x10_voice')
import rospy
import subprocess
import shlex

from std_msgs.msg import String

PATH_RINGTONS="ros_pkgs/vp_x10_voice/nodes/ringtons/"

def controller(data):

    rington_file = data.data
    command1='smplayer "'
    command1+=PATH_RINGTONS+rington_file+'"'
    subprocess.Popen(command1,shell=True).communicate()
    rospy.loginfo(command1)


def listener():
   rospy.init_node('node_x10_alarm_mediaplayer')
   sub = rospy.Subscriber("x10_alarm_mediaplayer",String,controller)
   rospy.spin()

if __name__ == '__main__':
   listener()

Узел node_x10_alarm_festival получает сообщение String из темы x10_alarm_festival и запускает программу festival.

Содержимое файла node_x10_festival_sub.py

#!/usr/bin/env python
#-*-coding:utf-8 -*-

#
#  Слушатель x10_festival
#
#  и произношение голосом
#

import roslib; roslib.load_manifest('vp_x10_voice')
import rospy
import subprocess
import shlex

from std_msgs.msg import String

def controller(data):

    fraza = data.data
    #command1="festival -b '(begin (SayText "
    #command1+='"'+fraza+'"'
    #command1+="))'"
    command1='echo "'
    command1+=fraza+'"'
    command1+=" | festival --language russian --tts"
    subprocess.Popen(command1,shell=True).communicate()
    rospy.loginfo(command1)


def listener():
   rospy.init_node('node_x10_alarm_festival')
   sub = rospy.Subscriber("x10_alarm_festival",String,controller)
   rospy.spin()

if __name__ == '__main__':
   listener()

Для управления приборами X10 запускаем узел node_x10_texttocommand

rosrun vp_x10_voice node_x10_texttocommand.py

и посылаем в него номер сценария из массива arr_commands файла node_x10_texttocommand.py

Составляем список пробных будильников

Запускаем

1 терминал

roscore

2 терминал

rosrun vp_x10_voice   node_x10_alarm_pub.py

3 терминал

rosrun vp_x10_voice node_x10_festival_sub.py

4 терминал

rosrun vp_x10_voice node_x10_mediaplayer_sub.py

5 терминал

rosrun vp_x10_voice node_x10_texttocommand.py

Файлы проекта можно скачать в репозитории


Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Android Arduino Bluetooth CraftDuino DIY IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение