From 64bd1b57ba38c4bd842c716930726e72bac72c3d Mon Sep 17 00:00:00 2001 From: sokul_13 Date: Sun, 14 May 2023 23:17:25 -0700 Subject: [PATCH] committing v5 and v6 ( final code used in demo) Our prototype succeeded and got the top award from project invent, the "moonshot" award, for the most novel and impactful idea for the pacific region of the competition. We got 500 dollars of initial VC funding as our award. --- fileresize.py => v4/fileresize.py | 32 +- main.py => v4/main.py | 76 +- newparse.py => v4/newparse.py | 70 +- parsefile.py => v4/parsefile.py | 72 +- {code => v5}/main-haptic.py | 0 {code => v5}/start.sh | 0 v6 (final prototype v1)/project/command.txt | 1000 +++++++++++++++++ .../project/main-haptic.py | 162 +++ .../project/main-robo-haptic.py | 197 ++++ v6 (final prototype v1)/project/mp3/Bus.mp3 | Bin 0 -> 6628 bytes v6 (final prototype v1)/project/mp3/Chair.mp3 | Bin 0 -> 6314 bytes v6 (final prototype v1)/project/mp3/Door.mp3 | Bin 0 -> 6001 bytes .../project/mp3/config.json | 12 + .../project/mp3/person.mp3 | Bin 0 -> 6941 bytes .../project/mp3/welcome.mp3 | Bin 0 -> 12427 bytes .../project/roboflow_config.json | 12 + v6 (final prototype v1)/project/start.sh | 9 + .../project/startdocker.sh | 9 + v6 (final prototype v1)/project/startrobo.sh | 12 + 19 files changed, 1538 insertions(+), 125 deletions(-) rename fileresize.py => v4/fileresize.py (97%) rename main.py => v4/main.py (95%) rename newparse.py => v4/newparse.py (97%) rename parsefile.py => v4/parsefile.py (96%) rename {code => v5}/main-haptic.py (100%) rename {code => v5}/start.sh (100%) create mode 100644 v6 (final prototype v1)/project/command.txt create mode 100644 v6 (final prototype v1)/project/main-haptic.py create mode 100644 v6 (final prototype v1)/project/main-robo-haptic.py create mode 100644 v6 (final prototype v1)/project/mp3/Bus.mp3 create mode 100644 v6 (final prototype v1)/project/mp3/Chair.mp3 create mode 100644 v6 (final prototype v1)/project/mp3/Door.mp3 create mode 100644 v6 (final prototype v1)/project/mp3/config.json create mode 100644 v6 (final prototype v1)/project/mp3/person.mp3 create mode 100644 v6 (final prototype v1)/project/mp3/welcome.mp3 create mode 100644 v6 (final prototype v1)/project/roboflow_config.json create mode 100644 v6 (final prototype v1)/project/start.sh create mode 100644 v6 (final prototype v1)/project/startdocker.sh create mode 100644 v6 (final prototype v1)/project/startrobo.sh diff --git a/fileresize.py b/v4/fileresize.py similarity index 97% rename from fileresize.py rename to v4/fileresize.py index 3630cfc..84421fc 100644 --- a/fileresize.py +++ b/v4/fileresize.py @@ -1,16 +1,16 @@ -from PIL import Image -import os -import argparse - -def rescale_images (directory,size): - for img in os.listdir(directory): - im = Image.open(directory+img) - im_resized = im.resize(size, Image.ANTIALIAS) - im_resized.save(directory+img) - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Rescale Images") - parser.add_argument('-d', '--directory', type=str, required=True, help='Dir') - parser.add_argument('-s', '--size', type=int,nargs=2, required=True, metavar=int) - args = parser.parse_args() - rescale_images(args.directory, args.size) +from PIL import Image +import os +import argparse + +def rescale_images (directory,size): + for img in os.listdir(directory): + im = Image.open(directory+img) + im_resized = im.resize(size, Image.ANTIALIAS) + im_resized.save(directory+img) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Rescale Images") + parser.add_argument('-d', '--directory', type=str, required=True, help='Dir') + parser.add_argument('-s', '--size', type=int,nargs=2, required=True, metavar=int) + args = parser.parse_args() + rescale_images(args.directory, args.size) diff --git a/main.py b/v4/main.py similarity index 95% rename from main.py rename to v4/main.py index f6aa81b..24b60f5 100644 --- a/main.py +++ b/v4/main.py @@ -1,38 +1,38 @@ - -import pyttsx3 -from gpiozero import Button -from gpiozero import Buzzer -from time import sleep - -button = Button(11) -motor1 = Buzzer(12) -motor2 = Buzzer(13) -motor3 = Buzzer(16) -text_speech = pyttsx3.init() -all = 0 -bathroom = 1 -chair = 2 -door = 3 -counter = 0 -mode = counter%4 - - - -#while True: -# if button.is_pressed: -# if (mode == all): -# text_speech.say("all") -# text_speech.runAndWait() -## elif(mode == bathroom): -# text_speech.say("bathroom") -# text_speech.runAndWait() -# elif(mode == chair): -# text_speech.say("chair") -# text_speech.runAndWait() -# elif(mode == door): -# text_speech.say("door") -# text_speech.runAndWait() -# counter += 1 -# else: -# print(".") -# sleep(1) + +import pyttsx3 +from gpiozero import Button +from gpiozero import Buzzer +from time import sleep + +button = Button(11) +motor1 = Buzzer(12) +motor2 = Buzzer(13) +motor3 = Buzzer(16) +text_speech = pyttsx3.init() +all = 0 +bathroom = 1 +chair = 2 +door = 3 +counter = 0 +mode = counter%4 + + + +#while True: +# if button.is_pressed: +# if (mode == all): +# text_speech.say("all") +# text_speech.runAndWait() +## elif(mode == bathroom): +# text_speech.say("bathroom") +# text_speech.runAndWait() +# elif(mode == chair): +# text_speech.say("chair") +# text_speech.runAndWait() +# elif(mode == door): +# text_speech.say("door") +# text_speech.runAndWait() +# counter += 1 +# else: +# print(".") +# sleep(1) diff --git a/newparse.py b/v4/newparse.py similarity index 97% rename from newparse.py rename to v4/newparse.py index e130734..9979fc5 100644 --- a/newparse.py +++ b/v4/newparse.py @@ -1,36 +1,36 @@ -#from tensorflow.keras import Sequential -#from tensorflow.keras.layers import Flatten, Dense, Conv2D, MaxPooling2D, Dropout -import numpy as np -import pandas as pd -import cv2 -import random -from pathlib import Path -from tqdm import tqdm -#from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array -from keras.utils import to_categorical -import numpy as np -#from sklearn.mode_selection import train_test_split -import os - - -labels = [] -ds_dir = "C:/Users/Soham Kulkarni/OneDrive/Documents/GitHub/vechtor/v4/doorimages/" - -image_size = 224 # Define the image size here - -def create_dataset(category, label, dataset): - for img in tqdm(category): - image_path = os.path.join(ds_dir, img) - try: - image = cv2.imread(image_path,cv2.IMREAD_COLOR) - image = cv2.resize(image,(image_size, image_size)) - except: - continue - dataset.append([np.array(image),np.array(label)]) - random.shuffle(dataset) - return dataset -trash = "C:/Users/Soham Kulkarni/OneDrive/Documents/GitHub/vechtor/v4/trash/" -door = "C:/Users/Soham Kulkarni/OneDrive/Documents/GitHub/vechtor/v4/doortestimages/" -dataset = [] -dataset = create_dataset(trash, 1, dataset) +#from tensorflow.keras import Sequential +#from tensorflow.keras.layers import Flatten, Dense, Conv2D, MaxPooling2D, Dropout +import numpy as np +import pandas as pd +import cv2 +import random +from pathlib import Path +from tqdm import tqdm +#from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array +from keras.utils import to_categorical +import numpy as np +#from sklearn.mode_selection import train_test_split +import os + + +labels = [] +ds_dir = "C:/Users/Soham Kulkarni/OneDrive/Documents/GitHub/vechtor/v4/doorimages/" + +image_size = 224 # Define the image size here + +def create_dataset(category, label, dataset): + for img in tqdm(category): + image_path = os.path.join(ds_dir, img) + try: + image = cv2.imread(image_path,cv2.IMREAD_COLOR) + image = cv2.resize(image,(image_size, image_size)) + except: + continue + dataset.append([np.array(image),np.array(label)]) + random.shuffle(dataset) + return dataset +trash = "C:/Users/Soham Kulkarni/OneDrive/Documents/GitHub/vechtor/v4/trash/" +door = "C:/Users/Soham Kulkarni/OneDrive/Documents/GitHub/vechtor/v4/doortestimages/" +dataset = [] +dataset = create_dataset(trash, 1, dataset) dataset = create_dataset(door, 2, dataset) \ No newline at end of file diff --git a/parsefile.py b/v4/parsefile.py similarity index 96% rename from parsefile.py rename to v4/parsefile.py index 2f8849e..7fa9674 100644 --- a/parsefile.py +++ b/v4/parsefile.py @@ -1,37 +1,37 @@ -import matplotlib.pyplot as plt -import matplotlib.image as mpimg -import os - - -def save_image(like_value, photo, img): - filename = "C:/Users/Soham Kulkarni/OneDrive/Documents/GitHub/vechtor/v4/" - - # body like - if like_value == 's': - print('doorimages') - filename += "doortestimages/" + photo - plt.imsave(filename, img) - - # body dislike - if like_value == 'd': - print('notdoor') - filename += 'trash/' + photo - plt.imsave(filename, img) - -def main(): - base_path = "C:/Users/Soham Kulkarni/OneDrive/Documents/GitHub/vechtor/v4/doorimages/" - for photo in os.listdir(base_path): - photo_path = base_path + photo - img = mpimg.imread(photo_path) - plt.imshow(img) - plt.show() - - like_value = input() - - # save pic to new folder and delete it from 'to_label' folder - save_image(like_value, photo, img) - os.remove(photo_path) - - -if __name__ == "__main__": +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +import os + + +def save_image(like_value, photo, img): + filename = "C:/Users/Soham Kulkarni/OneDrive/Documents/GitHub/vechtor/v4/" + + # body like + if like_value == 's': + print('doorimages') + filename += "doortestimages/" + photo + plt.imsave(filename, img) + + # body dislike + if like_value == 'd': + print('notdoor') + filename += 'trash/' + photo + plt.imsave(filename, img) + +def main(): + base_path = "C:/Users/Soham Kulkarni/OneDrive/Documents/GitHub/vechtor/v4/doorimages/" + for photo in os.listdir(base_path): + photo_path = base_path + photo + img = mpimg.imread(photo_path) + plt.imshow(img) + plt.show() + + like_value = input() + + # save pic to new folder and delete it from 'to_label' folder + save_image(like_value, photo, img) + os.remove(photo_path) + + +if __name__ == "__main__": main() \ No newline at end of file diff --git a/code/main-haptic.py b/v5/main-haptic.py similarity index 100% rename from code/main-haptic.py rename to v5/main-haptic.py diff --git a/code/start.sh b/v5/start.sh similarity index 100% rename from code/start.sh rename to v5/start.sh diff --git a/v6 (final prototype v1)/project/command.txt b/v6 (final prototype v1)/project/command.txt new file mode 100644 index 0000000..483a160 --- /dev/null +++ b/v6 (final prototype v1)/project/command.txt @@ -0,0 +1,1000 @@ + 446 vi ./.local/share/Trash/files/miniforge3/etc/profile.d/conda.sh + 447 vi .bashrc + 448 ls -ltr ./project/vechtor/v2/start.sh + 449 ./project/vechtor/v2/start.sh + 450 chomd 777 ./project/vechtor/v2/start.sh + 451 chmod 777 ./project/vechtor/v2/start.sh + 452 ls -ltr ./project/vechtor/v2/start.sh + 453 ./project/vechtor/v2/start.sh + 454 clear + 455 ./project/vechtor/v2/start.sh + 456 c;lear + 457 clear + 458 pwd + 459 vi .bashrc + 460 cd projects + 461 l + 462 ls + 463 cd project + 464 ! source + 465 source ./env/bin/activate + 466 python3 main-haptic.py + 467 cd vechtor/v2/ + 468 python main-haptic.py + 469 source ./env/bin/activate + 470 cd project/ + 471 source ./env/bin/activate + 472 clear + 473 python3 vechtor/v2/main-haptic.py + 474 clear + 475 python3 vechtor/v2/main-haptic.py + 476 clear + 477 python3 vechtor/v2/main-haptic.py + 478 clear + 479 python3 vechtor/v2/main-haptic.py + 480 clear + 481 python3 vechtor/v2/main-haptic.py + 482 clear + 483 python3 vechtor/v2/main-haptic.py + 484 clear + 485 python3 vechtor/v2/main-haptic.py + 486 clear + 487 python3 vechtor/v2/main-haptic.py + 488 clear + 489 python3 vechtor/v2/main-haptic.py + 490 clear + 491 python3 vechtor/v2/main-haptic.py + 492 clear + 493 python3 vechtor/v2/main-haptic.py + 494 clear + 495 vi .bashrc + 496 ls + 497 ls -la + 498 pwd + 499 whoami + 500 df -h + 501 curl -sS https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/i2samp.sh | bash + 502 speaker-test -c2 + 503 speaker-test -c2 --test=wav -w /usr/share/sounds/alsa/Front_Center.wav + 504 sudo reboot + 505 curl -sS https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/i2samp.sh | bash + 506 speaker-test -c2 --test=wav -w /usr/share/sounds/alsa/Front_Center.wav + 507 sudo reboot + 508 pip install gTT + 509 pip install gTTS + 510 clear + 511 cd project/ + 512 source ./env/bin/activate + 513 pip install gTTS + 514 clear + 515 python3 ./vechtor/v2/testsound.py + 516 rm -rf /home/pi/project/soham.mp3 + 517 clear + 518 python3 ./vechtor/v2/testsound.py + 519 clear + 520 python3 ./vechtor/v2/testsound.py + 521 clear + 522 python3 vechtor/v2/main-haptic.py + 523 clear + 524 python3 vechtor/v2/main-haptic.py + 525 clear + 526 python3 vechtor/v2/main-haptic.py + 527 clear + 528 python3 vechtor/v2/main-haptic.py + 529 cd /media/pi/SOKUL13_USB/ + 530 ls -ltr + 531 mpg321 welcome.p4a + 532 mpg321 + 533 cp bus.m4a bus.mp3 + 534 vf /media/pi/SOKUL13_USB/ + 535 cd /media/pi/SOKUL13_USB/ + 536 mpg321 ls -ltr + 537 sudo apt upate + 538 sudo apt update + 539 sudo apt install omxplayer + 540 sudo apt install mplayer + 541 clear + 542 sudo apt uninstall mplaye + 543 mpg123 + 544 cd project/ + 545 mpg123 + 546 cd / + 547 sudo . -name mpg123* + 548 sudo find . -name mpg123* + 549 clear + 550 sudo apt install mpd + 551 df -h + 552 history | grep curl + 553 cd proc/ + 554 cd .. + 555 pwd + 556 cd + 557 cd project/ + 558 source ./env/bin/activate + 559 speaker-test -c2 --test=mp3 -w /home/pi/project/vechtor/v2/mp3/welcome.mp3 + 560 mpg123 /home/pi/project/vechtor/v2/mp3/welcome.mp3 + 561 mpg123 /home/pi/project/vechtor/v2/mp3/bus.mp3 + 562 mpg123 /home/pi/project/vechtor/v2/mp3/chair.mp3 + 563 mpg123 /home/pi/project/vechtor/v2/mp3/person.mp3 + 564 mpg123 /home/pi/project/vechtor/v2/mp3/welcome.mp3 + 565 python3 ./vechtor/v2/testsound.py + 566 cd project/ + 567 source ./env/bin/activate + 568 mpg123 /home/pi/project/vechtor/v2/mp3/welcome.mp3 + 569 python3 ./vechtor/v2/testsound.py + 570 python3 + 571 cd project/ + 572 source ./env/bin/activate + 573 python3 ./vechtor/v2/testsound.py + 574 python3 ./vechtor/v2/main-haptic.py + 575 clear + 576 python3 ./vechtor/v2/main-haptic.py + 577 clear + 578 python3 ./vechtor/v2/main-haptic.py + 579 clear + 580 python3 ./vechtor/v2/main-haptic.py + 581 clear + 582 python3 ./vechtor/v2/main-haptic.py + 583 exit + 584 sudo apt-get update + 585 sudo apt-get install mpg123 + 586 mpg123 + 587 clear + 588 vi .bashrc + 589 cd project/ + 590 tail -f ./logs/vechtor.log + 591 clear + 592 tail -f ./logs/vechtor.log + 593 clear + 594 vi .bashrc + 595 cd .. + 596 clear + 597 vi .bashrc + 598 ps -ef |grep python + 599 ps -ef |grep haptic + 600 clear + 601 vi .bashrc + 602 cd project/ + 603 tail -f ./logs/vechtor.log + 604 ps -ef | grep haptic + 605 kill -9 5400 + 606 clear + 607 tail -f ./logs/vechtor.log + 608 rm -rf ./logs/vechtor.log + 609 clear + 610 ps -ef | grep haptic + 611 kill -9 5536 + 612 tail -f ./project/logs/vechtor.log + 613 vi /etc/rc.local + 614 sudo vi /etc/rc.local + 615 cat /etc/rc.local + 616 sudo vi /etc/rc.local + 617 clear + 618 ps -ef + 619 ps -ef | grep start + 620 kill -9 3675 + 621 ps -ef | grep start + 622 ps -ef | grep haptic + 623 kill -9 3758 + 624 cd mpro + 625 cd project/ + 626 source ./env/bin/activate + 627 python3 ./vechtor/v2/main-haptic.py + 628 clear + 629 python3 ./vechtor/v2/main-haptic.py + 630 clear + 631 python3 ./vechtor/v2/main-haptic.py + 632 pinout + 633 mkdir logs + 634 python3 ./vechtor/v2/main-haptic.py + 635 clear + 636 python3 ./vechtor/v2/main-haptic.py + 637 ls -lrt logs/ + 638 view logs/vechtor.log + 639 rm -rf logs/vechtor.log + 640 python3 ./vechtor/v2/main-haptic.py + 641 clear + 642 rm -rf logs/vechtor.log + 643 cd .. + 644 vi .bashrc + 645 cat /etc/rc.local + 646 export GPIOZERO_PIN_FACTORY=rpigpio + 647 rm -rf /home/pi/project/logs/vechtor.log + 648 /home/pi/project/vechtor/v2/start.sh > /home/pi/project/logs/vechtor.log 1>&2 & + 649 kill -9 5663 + 650 ps -ef | grep haptic + 651 kill -9 5667 + 652 ps -ef | grep haptic + 653 clear + 654 vi .bashrc + 655 ps -ef | grep haptic + 656 tail -f ./project/logs/vechtor.log + 657 ps -ef | grep haptic + 658 kill -9 580 + 659 sudo kill -9 580 + 660 ps -ef | grep haptic + 661 tail -f ./project/logs/vechtor.log + 662 history | grep nano + 663 history | grep sudo + 664 history | grep rc + 665 cat /etc/rc.local + 666 sudo nano /etc/rc.local + 667 /home/pi/project/vechtor/v2/start.sh > /home/pi/project/logs/vechtor.log 1>&2 & + 668 sudo nano /etc/rc.local + 669 ps -ef | grep haptic + 670 clear + 671 tail -3 .bashrc + 672 rm -rf ./project/logs + 673 mkdir ./project/logs + 674 cd project + 675 source ./env/bin/activate + 676 ps -ef | grep haptic + 677 kill -9 1956 + 678 ps -ef | grep haptic + 679 tail -f .logs + 680 tail -f./logs/v + 681 tail -f ./logs/vechtor.log + 682 ps -ef | grep haptic + 683 kill -9 2009 + 684 ps -ef | grep haptic + 685 kill -9 2124 + 686 ps -ef | grep haptic + 687 clear + 688 history + 689 sudo vi /etc/rc.local + 690 cat /etc/rc.local + 691 wq + 692 sudo reboot now + 693 tail -f project/logs/vechtor.log + 694 sudo reboot now + 695 ps -ef | grep haptic + 696 kill -9 589 + 697 sudo kill -9 589 + 698 clear + 699 ls -ltr + 700 cd project/ + 701 cd logs/ + 702 l s-ltr + 703 ls -ltr + 704 view vechtor.log + 705 clear + 706 sudo reboot now + 707 ps -ef | grep haptic + 708 cd project/logs/ + 709 ls -lt + 710 ls -ltr + 711 tail -f vechtor.log + 712 ls -ltr + 713 ps -ef | grep haptic + 714 cat /etc/rc.local + 715 ps -ef | grep haptic + 716 cd project/ + 717 source ./env/bin/activate + 718 python3 ./vechtor/v2/main-haptic.py + 719 rm -rf ./logs/vechtor.log + 720 python3 ./vechtor/v2/main-haptic.py + 721 clear + 722 sudo reboot now + 723 cd project/logs/ + 724 tail -f vechtor.log + 725 ps -ef | grep haptic + 726 kill -9 581 + 727 ps -ef | grep haptic + 728 sudo ps -ef | grep haptic + 729 sudo kill -9 581 + 730 ps -ef | grep haptic + 731 clear + 732 ls + 733 rm -rf vechtor.log + 734 sudo reboot now + 735 cd project/logs/ + 736 tail -f vechtor.log + 737 sudo reboot now + 738 which tf + 739 which tensorflow + 740 rm -rf vechtor.log + 741 ps -ef | grep haptic + 742 sudo kill -9 565 + 743 ps -ef | grep haptic + 744 cd /project + 745 cd /home/project + 746 cd /home/pi + 747 cd /home + 748 cd pi + 749 pwd + 750 cd project/ + 751 source ./env/bin/activate + 752 which tensorflow + 753 python3 + 754 sudo shutdown now + 755 df -h + 756 pwd + 757 cd + 758 cd / + 759 sudo du -hs * | sort -rh | head -10 + 760 top + 761 netstat -an + 762 clear + 763 sudo du -hs * | sort -rh | head -10 + 764 cd home/ + 765 sudo du -hs * | sort -rh | head -10 + 766 cd pi/ + 767 sudo du -hs * | sort -rh | head -10 + 768 pwd + 769 sud + 770 ps -ef | grep pdf + 771 kill -9 3142 + 772 kill -9 2845 + 773 ps -ef | grep pdf + 774 clear + 775 pwdsudo + 776 cd project/ + 777 source ./env/bin/activate + 778 pip install roboflow + 779 clear + 780 python3 ./vechtor/v2/main-robo.py + 781 clear + 782 python3 ./vechtor/v2/main-robo.py + 783 curl http://localhost:9001 + 784 curl http://localhost:9001/server + 785 curl http://localhost:9001 + 786 python3 ./vechtor/v2/main-robo.py + 787 curl http://localhost:9001 + 788 clear + 789 python3 ./vechtor/v2/main-robo.py + 790 clear + 791 python3 ./vechtor/v2/main-robo.py + 792 clear + 793 python3 ./vechtor/v2/main-robo.py + 794 clear + 795 python3 ./vechtor/v2/main-robo.py + 796 clear + 797 python3 ./vechtor/v2/main-robo.py + 798 python3 ./vechtor/v2/main-robo-haptic.py + 799 sudo rm -rf ./logs/vechtor.log + 800 python3 ./vechtor/v2/main-robo-haptic.py + 801 clear + 802 python3 ./vechtor/v2/main-robo-haptic.py + 803 tail -20 ./logs/vechtor.log + 804 clear + 805 tail -20 ./logs/vechtor.log + 806 clear + 807 rm ./logs/vechtor.log + 808 clear + 809 tail -20 ./logs/vechtor.log + 810 clear + 811 python3 ./vechtor/v2/main-robo-haptic.py + 812 exit + 813 ps -ef | grep haptc + 814 ps -ef | grep haptic + 815 sudo kill -9 568 + 816 ps -ef | grep haptic + 817 clear + 818 cd project/ + 819 source ./env/bin/activate + 820 curl -fsSl https://get.docker.com -o get-docker.sh + 821 sudo sh get-docker.sh + 822 sudo apt-get update + 823 sudo sh get-docker.sh --fix-missing + 824 sudo docker pull roboflow/inference-server:cpu + 825 sudo docker run --net=host roboflow/inference-server:cpu + 826 clear + 827 sudo docker run --net=host roboflow/inference-server:cpu + 828 ps -ef | grep haptic + 829 sudo kill -9 584 + 830 ps -ef | grep haptic + 831 sudo vi /etc/rc.local + 832 tail -10 /etc/rc.local + 833 clear + 834 sudo shutdown now + 835 history + 836 tail -10 /etc/rc.local + 837 cd log + 838 cd project/logs/ + 839 ls -ltr + 840 sudo rm -rf vechtor.log + 841 clear + 842 cd .. + 843 ./vechtor/v2/start.sh + 844 cd logs/ + 845 tail -f vechtor.log + 846 tail -15 vechtor.log + 847 view vechtor.log + 848 tail -15 vechtor.log + 849 ps -ef | grep haptic + 850 clear + 851 ps -ef | grep haptic + 852 kill -9 1905 + 853 clear + 854 tail -1 /home/pi/project/logs/docker.log | grep "inference-server is ready to receive traffic" + 855 tail -1 /home/pi/project/logs/docker.log + 856 tail -2 /home/pi/project/logs/docker.log + 857 tail -2 /home/pi/project/logs/docker.log | grep "inference-server is ready to receive traffic" + 858 rm -rf vechtor.log + 859 cd .. + 860 clear + 861 ./vechtor/v2/start.sh + 862 kill -9 3098 + 863 kill -9 3096 + 864 ps -ef | grep docker + 865 sudo kill -9 2097 + 866 sudo kill -9 3097 + 867 ps -ef | grep docker + 868 sudo kill -9 3327 + 869 ps -ef | grep docker + 870 clear + 871 ./vechtor/v2/start.sh + 872 sudo kill -9 4050 + 873 ./vechtor/v2/start.sh + 874 tail -1 /home/pi/project/logs/docker.log | grep "ready to receive traffic + 875 tail -1 /home/pi/project/logs/docker.log | grep "ready to receive traffic" + 876 ./vechtor/v2/start.sh + 877 tail -1 /home/pi/project/logs/docker.log | grep "ready to receive traffic" + 878 ./vechtor/v2/start.sh + 879 tail -f ./logs/vechtor.log + 880 ps -ef | grep docker + 881 ps -ef | grep haptic + 882 kill -9 4615 + 883 ps -ef | grep haptic + 884 clear + 885 cd project/logs/ + 886 ls- ltr + 887 ls -ltr + 888 tail -f docker.log + 889 ps -ef | grep haptic + 890 ps -ef | grep docker + 891 kill -9 1904 + 892 ps -ef | grep docker + 893 kill -9 1907 + 894 sudo kill -9 1907 + 895 clear + 896 ps -ef | grep docker + 897 kill -9 618 + 898 sudo kill -9 618 + 899 clear + 900 ps -ef | grep docker + 901 clear + 902 l s-ltr + 903 ls -ltr + 904 tail -f 10 docker.log + 905 clear + 906 ls -ltr + 907 clear + 908 ls -ltr + 909 tail -f docker.log + 910 clear + 911 tail -f docker.log + 912 clear + 913 ls -ltr + 914 la -lre + 915 ls -ltr + 916 tail -f docker.log + 917 sudo docker stop --net=host roboflow/inference-server:cpu + 918 sudo docker stop --net=host + 919 tail -f ./project/logs/docker.log + 920 ps -ef | grep haptic + 921 kill -9 6190 + 922 ps -ef | grep haptic + 923 clear + 924 ps -ef | grep docker + 925 sudo docker stop + 926 sudo docker stop --net=host + 927 sudo docker stop roboflow/inference-server:cpu + 928 sudo docker ls + 929 sudo docker list-container + 930 sudo docker --help + 931 sudo docker container ls + 932 sudo docker container stop roboflow/inference-server:cpu + 933 sudo docker --stop roboflow/inference-server:cpu + 934 sudo docker container ls + 935 sudo docker container stop fd50dc5793cd + 936 sudo docker container ls + 937 clear + 938 tail -f ./project/logs/docker.log + 939 source ./env/bin/activate + 940 cd project/ + 941 source ./env/bin/activate + 942 python3 ./vechtor/v2/main-robo-haptic.py + 943 clear + 944 ls -ltr + 945 ./vechtor/v2/start.sh + 946 kill -9 6805 + 947 clear + 948 chmod +x ./vechtor/v2/startrobo.sh + 949 clear + 950 ls -ltr ./vechtor/v2/start* + 951 chmod 777 ./vechtor/v2/startrobo.sh + 952 clear + 953 exit + 954 cd project/logs/ + 955 tail -f vechtor.log + 956 ps -ef | grep haptic + 957 kill -9 6987 + 958 ps -ef | grep haptic + 959 clear + 960 ./project/vechtor/v2/startrobo.sh + 961 clear + 962 sudo vi /etc/rc.local + 963 sudo reboot now + 964 ps -ef | grep haptic + 965 ps -ef | grep docker + 966 kill -9 4054 + 967 sudo kill -9 4054 + 968 ps -ef | grep docker + 969 sudo kill -9 3430 + 970 clear + 971 ./project/vechtor/v2/start.sh + 972 tail -f ./project/logs/vechtor.log + 973 clear + 974 ls -ltr + 975 cd log + 976 ls -ltr + 977 cd logs + 978 ls -ltr + 979 cd project/logs/ + 980 ls -ltr + 981 tail -f vechtor.log + 982 ls -ltr + 983 clear + 984 ls -ltr + 985 tail -f docker.log + 986 ls- ltr + 987 ls -ltr ../vechtor/v2/start* + 988 clear + 989 ls -ltr + 990 sudo rm -rf *.log + 991 ls -ltr + 992 cd ./project/logs/ + 993 ls -lt + 994 ls -ltr + 995 tail -f docker.log + 996 tail -f vechtor.log + 997 ps -ef | grep haptic + 998 ls -lt + 999 ls -ltr + 1000 rm -rf * + 1001 clear + 1002 ls -ltr + 1003 sudo tail -10 /etc/rc.local + 1004 sudo reboot now + 1005 cd project/ + 1006 cd logs/ + 1007 ls -ltr + 1008 tail -f vechtor.log + 1009 tail -10 docker.log + 1010 tail -f vechtor.log + 1011 ls -ltr + 1012 ps -ef | grep haptic + 1013 ps -ef | grep robo + 1014 rm -rf vechtor.log + 1015 ls -ltr + 1016 sudo vi /etc/rc.local + 1017 sudo docker container ls + 1018 sudo docker container stop 796dcff80f6c + 1019 sudo docker container ls + 1020 clear + 1021 ls -ltr + 1022 rm -rf docker.log + 1023 clear + 1024 sudo reboot now + 1025 xs project/logs/ + 1026 ls -ltr + 1027 cd project/logs/ + 1028 ls -ltr + 1029 cat startup.log + 1030 cat docker.log + 1031 clear + 1032 ps -ef | grep haptic + 1033 cat startup.log + 1034 ps -ef | grep 1010 + 1035 clear + 1036 ls -ltr + 1037 cd .. + 1038 ./project/vechtor/v2/startrobo.sh + 1039 cd project/ + 1040 cd logs/ + 1041 ls -ltr + 1042 tail -f vechtor.log + 1043 ls -ltr + 1044 ps -ef | grep vechtor + 1045 ps -ef | grep haptic + 1046 kill -9 1811 + 1047 ps -ef | grep haptic + 1048 clear + 1049 ls -ltr + 1050 cat startup.log + 1051 clea + 1052 clear + 1053 rm -rf vechtor.log + 1054 ls -ltr + 1055 cat /etc/rc.local + 1056 clear + 1057 ls -ltr + 1058 sudo reboot now + 1059 cd project/logs/ + 1060 ls -ltr + 1061 ps -ef | grep haptic + 1062 ls -ltr /var/log/ + 1063 tail -15 /var/log/boot.log + 1064 sudo tail -15 /var/log/boot.log + 1065 tail -15 /var/log/boot.log + 1066 ls -ltr /var/log/ + 1067 ps -ef | grep docker + 1068 cat startup.log + 1069 ps -ef | grep 875 + 1070 sudo /etc/rc.local + 1071 sudo vi /etc/rc.local + 1072 clear + 1073 ls -ltr + 1074 tail -f vechtor.log + 1075 clear + 1076 ls -ltr + 1077 sudo rm -rf *.log + 1078 sudo /etc/rc.local + 1079 ps -ef | grep haptic + 1080 clear + 1081 ls -ltr + 1082 rm -rf docker.log + 1083 ls -ltr + 1084 /etc/rc.local + 1085 ls -ltr + 1086 tail -f vechtor.log + 1087 cd project/log + 1088 cd project/logs/ + 1089 ls -ltr + 1090 view vechtor.log + 1091 view docker.log + 1092 ps -ef | grep haptic + 1093 kill -9 1927 + 1094 sudo kill -9 1927 + 1095 ps -ef | grep haptic + 1096 view docker.log + 1097 sudo vi /etc/rc.local + 1098 chmod 777 ../vechtor/v2/startdocker.sh + 1099 clear + 1100 sudo vi /etc/rc.local + 1101 sudo docker container ls + 1102 sudo docker container stop 1883f3a73ed3 + 1103 sudo docker container stop a9b8d4ee4045 + 1104 sudo docker container ls + 1105 clear + 1106 sudo vi /etc/rc.local + 1107 sudo docker container ls + 1108 sudo docker container stop b355fa04e64c + 1109 sudo docker container ls + 1110 clear + 1111 sudo docker container ls + 1112 clear + 1113 ls -ltr + 1114 tail pf docker.log + 1115 sudo docker container ls + 1116 sudo docker container stop b355fa04e64c + 1117 sudo docker container ls + 1118 sudo docker container stop dcfeab2d728b + 1119 ps -ef | grep haptic + 1120 ps -ef | grep docker + 1121 clear + 1122 sudo reboot now + 1123 cd project/logs/ + 1124 ls -ltr + 1125 cat vechtor.log + 1126 ls -ltr + 1127 tail f- docker.log + 1128 ls -ltr + 1129 ls -ltr + 1130 tail -f vechtor.log + 1131 clear + 1132 ls -ltr + 1133 tail -f docker.log + 1134 cat vechtor.log + 1135 ls -ltr + 1136 rm -rf * + 1137 l s-ltr + 1138 ls -ltr + 1139 ps -ef | grep haptic + 1140 sudo vi /etc/rc.local + 1141 sudo reboot now + 1142 ls -ltr project/logs/ + 1143 cat project/logs/doc + 1144 cat project/logs/docker.log + 1145 cat project/logs/vechtor.log + 1146 cd project/logs/ + 1147 ls -ltr + 1148 cat vechtor.log + 1149 cat docker.log + 1150 ps -ef | grep haptic + 1151 sudo vi /etc/rc.local + 1152 clear + 1153 ls -ltr + 1154 rm vechtor.log + 1155 ls -ltr + 1156 ../vechtor/v2/startrobo.sh + 1157 ls -ltr + 1158 ../vechtor/v2/startrobo.sh + 1159 tail -f vechtor.log + 1160 clear + 1161 tail -f vechtor.log + 1162 ps -ef | grep haptic + 1163 kill -9 2026 + 1164 ps -ef | grep haptic + 1165 clear + 1166 ps -ef | grep haptic + 1167 ../vechtor/v2/startrobo.sh + 1168 ps -ef | grep haptic + 1169 kill -9 2090 + 1170 kill -9 2106 + 1171 ps -ef | grep haptic + 1172 clear + 1173 ../vechtor/v2/startrobo.sh + 1174 ls -lt + 1175 ls -ltr + 1176 tail -f vechtor.log + 1177 ps -ef | grep haptic + 1178 kill -9 2125 + 1179 cat /etc/c.loc + 1180 cat /etc/rc.local + 1181 sudo /etc/rc.local + 1182 sudo reboot now + 1183 cd project/logs/ + 1184 ls- ltr + 1185 ls -ltr + 1186 cat vechtor.log + 1187 ls -ltr + 1188 cat docker.log + 1189 clear + 1190 ps -ef | grep haptic + 1191 sudo vi /etc/rc.local + 1192 ps -ef | grep haptic + 1193 cat vechtor.log + 1194 ps -ef | grep 752 + 1195 sudo vi /etc/rc.local + 1196 cd project/logs/ + 1197 ls -ltr + 1198 sudo docker container ls + 1199 sudo docker container stop 1c63123b31ea + 1200 sudo /etc/rc.local + 1201 kill -9 2585 + 1202 sudo kill -9 2585 + 1203 cat /etc/rc.local + 1204 exit + 1205 cd project/ + 1206 cd logs/ + 1207 ls -ltr + 1208 cat vechtor.log + 1209 ls -ltr + 1210 tail -f vechtor.log + 1211 ls -ltr + 1212 ps -ef | grep haptic + 1213 ls -ltr + 1214 tail -f vechtor.log + 1215 cleear + 1216 clear + 1217 ls -ltr + 1218 sudo rm -rf * + 1219 ls -ltr + 1220 sudo reboot now + 1221 cd project/logs/ + 1222 ls -lr + 1223 ls -ltr + 1224 cat startup.log + 1225 cat docker.log + 1226 clear + 1227 cat startup.log + 1228 ls -ltr + 1229 sudo vi /etc/rc.local + 1230 sudo /etc/rc.local + 1231 sudo kill -9 2810 + 1232 ls -lr + 1233 ls- ltr + 1234 ls -ltr + 1235 clear + 1236 history | grep docker + 1237 ~1198 + 1238 sudo docker container ls + 1239 udo docker container stop 0c5c950acd9e + 1240 sudo docker container stop 0c5c950acd9e + 1241 ls -ltr + 1242 cd project/logs/ + 1243 ls -ltr + 1244 tail -10 docker.log + 1245 clear + 1246 rm -rf * + 1247 ls -ltr + 1248 cat docker.log + 1249 ls -ltr + 1250 cat docker.log + 1251 ls -ltr + 1252 tail -f vechtor.log + 1253 ls -ltr + 1254 clear + 1255 rm -rf * + 1256 ls -ltr + 1257 clear + 1258 ps -ef | grep haptic + 1259 sudo reboot now + 1260 cd / + 1261 sudo find . -name config.json + 1262 echo $HOME + 1263 cat $HOME/.config/roboflow/config.json + 1264 pwd + 1265 cd + 1266 pwd + 1267 cd .config/ + 1268 ls -ltr + 1269 cd + 1270 sudo find . -name roboflow + 1271 ls -ltr ./project/env/lib/python3.9/site-packages/roboflow + 1272 cd ./project/env/lib/python3.9/site-packages/roboflow + 1273 ls -ltr + 1274 cat config.py + 1275 clear + 1276 cd + 1277 clear + 1278 cd project/ + 1279 ls -ltr + 1280 cd /media/pi/SOKUL13_USB/ + 1281 ls -ltr + 1282 cp config.json /home/pi/project/vechtor/v2/ + 1283 cd /.config + 1284 pwd + 1285 cd / + 1286 pwd + 1287 cd /home/.config + 1288 cd + 1289 pwd + 1290 cd .config + 1291 cd roboflow + 1292 mkdir roboflow + 1293 cd roboflow + 1294 cp /home/pi/project/vechtor/v2/rboflow_config + 1295 cp /home/pi/project/vechtor/v2/rboflow_config.json config.json + 1296 cp /home/pi/project/vechtor/v2/rboflow_config config.json + 1297 cp /home/pi/project/vechtor/v2/roboflow_config config.json + 1298 cp /home/pi/project/vechtor/v2/roboflow_config.json config.json + 1299 ls + 1300 echo $HOME + 1301 cd /home/root + 1302 cd /home/ + 1303 ls + 1304 ls /home/pi/.config/roboflow/config.json + 1305 cd project/logs/ + 1306 ls -ltr + 1307 ps -ef | grep haptic + 1308 ls -ltr + 1309 sudo cat /etc/rc.local + 1310 ls -ltr + 1311 ps -ef | grep robo + 1312 ls -ltr + 1313 cat /var/log/syslog + 1314 grep haptic /var/log/syslog + 1315 cat /var/log/syslog | grep haptic + 1316 view /var/log/syslog + 1317 tail -100 /var/log/syslog + 1318 view /var/log/syslog + 1319 sudo reboot now + 1320 cd project/ + 1321 cd logs/ + 1322 ls -ltr + 1323 cat startup.log + 1324 cat /etc/rc.local + 1325 ls -ltr + 1326 view docker.log + 1327 cp ../vechtor/v2/roboflow_config.json ~/.config/roboflow/config.json + 1328 cat ~/.config/roboflow/config.json + 1329 cp ../vechtor/v2/roboflow_config.json ~/.config/roboflow/config.json + 1330 cat ~/.config/roboflow/config.json + 1331 sudo /etc/rc.local + 1332 cd project/logs/ + 1333 ls -ltr + 1334 view /var/log/syslog + 1335 grep haptic /var/log/syslog + 1336 sudo truncate /var/log/syslog + 1337 trucate --help + 1338 truncate --help + 1339 ls -ltr /var/log/syslog* + 1340 rm -rf /var/log/syslog.* + 1341 sudo rm -rf /var/log/syslog.* + 1342 sudo truncate /var/log/syslog + 1343 view /var/log/syslog + 1344 tail -50 /var/log/syslog + 1345 clear + 1346 pwd + 1347 sudo docker container ls + 1348 sudo docker container stop 0a8063eb9801 + 1349 sudo /etc/rc.local + 1350 cd + 1351 view .config/roboflow/config.json + 1352 clear + 1353 sudo docker container ls + 1354 sudo docker container stop [200~ "ANNOTATION_FORMAT": "ANNOTATION_FORMAT", + 1355 sudo docker container 759d7d01886f + 1356 sudo docker container stop 759d7d01886f + 1357 sudo docker container ls + 1358 view /var/log/syslog + 1359 tail -50 /var/log/syslog + 1360 clar + 1361 clear + 1362 cd project/logs + 1363 ls + 1364 tail -f vechtor.log + 1365 sudo reboot now + 1366 ps -ef | grep haptic + 1367 sudo kill -9 875 + 1368 tail -50 project/logs/vechtor.log + 1369 sudo docker container ls + 1370 sudo docker container stop 69e1abe373af + 1371 sudo reboot now + 1372 ps -ef | grep haptic + 1373 sudo docker container ls + 1374 ps -ef | grep haptic + 1375 tail -50 project/logs/vechtor.log + 1376 sudo docker container ls + 1377 sudo docker container stop 37046be1214f + 1378 tail -100 /var/log/syslog + 1379 sudo truncate /var/log/syslog + 1380 sudo truncate /var/log/syslog --help + 1381 sudo truncate /var/log/syslog --all + 1382 sudo truncate /var/log/syslog --help + 1383 sudo reboot now + 1384 sudo docker container ls + 1385 tail -100 /var/log/syslog + 1386 ps -ef | grep haptic + 1387 tail -100 /var/log/syslog + 1388 ps -ef | grep haptic + 1389 cd project/log + 1390 cd project/logs + 1391 ls -ltr + 1392 date + 1393 tail -10 docker.log + 1394 tail -20 vechtor.log + 1395 cat startup.log + 1396 history grep | sys log + 1397 history grep | sys.log + 1398 history grep | syslog + 1399 history | syslog + 1400 history | grep syslog + 1401 tail -100 /var/log/syslog + 1402 tail -100 /var/log/syslog | more + 1403 history | grep docker + 1404 sudo docker container ls + 1405 sudo docker container stop a43d64300af1 + 1406 sudo docker container ls + 1407 clear + 1408 sudo /etc/rc.local + 1409 ls -ltr + 1410 sudo rm -rf *.log + 1411 ls -ltr + 1412 ls -ltr + 1413 cat /etc/rc.local + 1414 cd project/ + 1415 cd logs/ + 1416 ls -ltr + 1417 tail -10 docker.log + 1418 tail -20 vechtor.log + 1419 tail -f vechtor.log + 1420 ps -ef | grep haptic + 1421 sudo kill -9 2434 + 1422 ps -ef | grep haptic + 1423 clear + 1424 sudo reboot now + 1425 clear + 1426 cd project/logs/ + 1427 ls- ltr + 1428 ls -ltr + 1429 sudo rm -rf *.log + 1430 ls -ltr + 1431 sudo reboot now + 1432 cd project/logs/ + 1433 tail -f vechtor.log + 1434 ps -ef | grep haptic + 1435 sudo kill -9 904 + 1436 ps -ef | grep haptic + 1437 clear + 1438 history | grep docker + 1439 sudo docker container ls + 1440 sudo docker container stop 425f9f7002d4 + 1441 sudo docker container ls + 1442 sudo docker container stop 052c4d4643a9 + 1443 ps -ef | grep haptic + 1444 history + 1445 history > command.txt diff --git a/v6 (final prototype v1)/project/main-haptic.py b/v6 (final prototype v1)/project/main-haptic.py new file mode 100644 index 0000000..8cddd6d --- /dev/null +++ b/v6 (final prototype v1)/project/main-haptic.py @@ -0,0 +1,162 @@ +import cv2 +import numpy as np +from gpiozero import Device, PWMOutputDevice, Button +from time import sleep +import threading +import os +import logging + +#init log +logging.basicConfig(filename='/home/pi/project/logs/vechtor.log',format='%(asctime)s %(message)s', filemode='w') +logger = logging.getLogger() +logger.setLevel(logging.DEBUG) + +#This script detects following objects +vClassNames = ['person','bus','chair'] +classCount = len(vClassNames) + +#Counter for button clicks +buttonClickCount=0 +button = Button(17) + +#Video init +thres = 0.45 # Threshold to detect object +nms_threshold = 0.2 +cam = cv2.VideoCapture(0) +cam.set(3,640) +cam.set(4,480) + +#Init coco class names +classNames = [] +classFile = r'/home/pi/project/vechtor/v2/coco.names.txt' +with open(classFile,'rt') as f: + classNames = f.read().rstrip('\n').split('\n') + logger.debug(classNames) + +#Coco setup +configPath = r'/home/pi/project/vechtor/v2/ssd_mobilenet_v3_large_coco_2020_01_14.pbtxt' +weightsPath = r'/home/pi/project/vechtor/v2/frozen_inference_graph.pb' +net = cv2.dnn_DetectionModel(weightsPath,configPath) +net.setInputSize(320,320) +net.setInputScale(1.0/ 127.5) +net.setInputMean((127.5, 127.5, 127.5)) +net.setInputSwapRB(True) + +#Initilize motors +motorLeft = PWMOutputDevice(23) +motorRight = PWMOutputDevice(24) +motorPower= 0.5 +motorStopPower = 0.0 +sleepTimer=2 + +#Function to draw rectangle around the image +def drawRectangle(img,box,classId,confidence): + cv2.rectangle(img,box,color=(0,255,0),thickness=2) + cv2.putText(img,classNames[classId-1],(box[0]+10,box[1]+30), + cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2) + cv2.putText(img,str(round(confidence*100,2)),(box[0]+200,box[1]+30), + cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2) + return + +#Thread will call following fuction to count button clicks +def registerButtonClicked(): + while True: + logger.info('Button Clicked Start ---------------------------') + global buttonClickCount + button.wait_for_press() + buttonClickCount = (buttonClickCount + 1)% classCount + logger.info('Button Clicked count set to detect :%s' ,vClassNames[buttonClickCount]) + logger.info('Button Clicked End ---------------------------') + sleep(sleepTimer) + return + +#Button Click thread init +logger.info('Starting Button thread *******************************') +buttonThread = threading.Thread(target=registerButtonClicked, name='ButtonClick') +buttonThread.start() + +lastCount=-1 +soundCmd="mpg123 /home/pi/project/vechtor/v2/mp3/" +logger.info('-------------- Cap Initilization complete --------------') +#os.system(soundCmd +'welcome.mp3') +welcomePlayed=False + +#main thread +while True: + success,img = cam.read() + if welcomePlayed != True : + welcomePlayed=True + os.system(soundCmd +'welcome.mp3') + + logger.debug('Reading new image *******************************') + #Uncomment below to see the webcam feed + #cv2.imshow('Imagetest',img) + classIds, confs, bbox = net.detect(img,confThreshold=thres) + #print(classIds,bbox) + + #Identify if user clicked button and play object name ]) + if lastCount != buttonClickCount: + mp3Name = vClassNames[buttonClickCount] + '.mp3' + logger.info('-------------playing mp3 %s' ,soundCmd+mp3Name) + os.system(soundCmd + mp3Name) + lastCount = buttonClickCount + + motorLeft.value =0.0 + motorRight.value =0.0 + + if len(classIds) == 0: + logger.info('Did not detect any object *******************************') + else: + for classId, confidence,box in zip(classIds.flatten(),confs.flatten(),bbox): + if classId < len(classIds): + motorLeft.value =0.0 + motorRight.value =0.0 + logger.info('Found class %s in camera',classNames[classId-1]) + logger.debug('ButtonClickCount=%d ', buttonClickCount) + logger.debug('Should detect %s', vClassNames[buttonClickCount]) + + #If person found then activate the motor based on if person is in left or right + if ( (buttonClickCount == 1) or (buttonClickCount == 2) or (buttonClickCount ==0)): + if classNames[classId -1] == vClassNames[buttonClickCount]: + logger.info(' %s detected at x cordinate %f', vClassNames[buttonClickCount] , box[0]) + #Open Cv box prints (startX,startY,endX,endY) + midX = (box[0]+box[2]) / 2 + + drawRectangle(img,box,classId,confidence) + #Uncomment below to see the rectangle drawn + #cv2.imshow("Output",img) + if midX < 120.0: + logger.info(' %s detected at left ', vClassNames[buttonClickCount]) + motorLeft.value =motorPower + motorRight.value=motorStopPower + #os.system(soundCmd + vClassNames[buttonClickCount] + '_left.mp3') + buttonClickCount + sleep(sleepTimer) + motorLeft.value =motorStopPower + elif midX > 210.0: + logger.info(' %s detected at right ', vClassNames[buttonClickCount]) + motorRight.value=motorPower + motorLeft.value =motorStopPower + #os.system(soundCmd + vClassNames[buttonClickCount] + '_right.mp3') + sleep(sleepTimer) + motorRight.value =motorStopPower + else: + logger.info(' %s detected at center ', vClassNames[buttonClickCount]) + motorLeft.value =motorPower + motorRight.value =motorPower + #os.system(soundCmd + vClassNames[buttonClickCount] + '_center.mp3') + sleep(sleepTimer) + motorRight.value =motorStopPower + motorLeft.value =motorStopPower + else: + logger.info(' %s was not detected ', vClassNames[buttonClickCount]) + + k=cv2.waitKey(1) + + if k != -1: + break; + +buttonThread.join() +cam.release() +logger.info('-----------------------End-------------------') +cv2.destroyAllWindows() diff --git a/v6 (final prototype v1)/project/main-robo-haptic.py b/v6 (final prototype v1)/project/main-robo-haptic.py new file mode 100644 index 0000000..27474bd --- /dev/null +++ b/v6 (final prototype v1)/project/main-robo-haptic.py @@ -0,0 +1,197 @@ +import cv2 +import numpy as np +from gpiozero import Device, PWMOutputDevice, Button +from time import sleep +import threading +import os +import logging +from roboflow import Roboflow + +#init log +logging.basicConfig(filename='/home/pi/project/logs/vechtor.log',format='%(asctime)s %(message)s', filemode='w') +logger = logging.getLogger() +logger.setLevel(logging.DEBUG) +logger.info("log setup done") + +rf=Roboflow(api_key="esXiQyyY9AGa6JY8zL1W") +project = rf.workspace("vechtor").project("vechtor-plkjm") + +#This script detects following objects +vClassNames = ['Chair','Door','Bus'] +classCount = len(vClassNames) + +#Counter for button clicks +buttonClickCount=0 +button = Button(17) + +#Video init +thres = 0.45 # Threshold to detect object +nms_threshold = 0.2 +cam = cv2.VideoCapture(0) +cam.set(3,640) +cam.set(4,480) + +#Initilize motors +motorLeft = PWMOutputDevice(23) +motorRight = PWMOutputDevice(24) +motorPower= 0.5 +motorStopPower = 0.0 +sleepTimer=2 + +#roboflow variables setup +def initRoboflow(): + #Check if docker container started otherwise wait + logger.info(" Checking docker log..") + dlog = open("/home/pi/project/logs/docker.log", "r") + logger.info(" Docker logfile opened..") + logLine = dlog.readline() + while True: + if "inference-server is ready to receive traffic." in logLine : + logger.info(" Docker container started..") + break; + else: + logger.debug(" Docker log line %s ",logLine) + logger.info(" Docker container not started so sleeping ....") + sleep(10) + logLine = dlog.readline() + + dlog.close() + logger.info(" Docker container has started so starting vechtor process ..") + #roboflow setup + global model + model = project.version(1,local="http://localhost:9001/").model + +#Function to draw rectangle around the image +def drawRfRectangle(img,spt, ept,className,confidence): + cv2.rectangle(img,spt, ept, color=(0,255,0),thickness=2) + cv2.putText(img,className,(spt[0]+10,spt[1]+30), + cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2) + cv2.putText(img,str(round(confidence*100,2)),(spt[0]+200,spt[1]+30), + cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2) + return + +#Thread will call following fuction to count button clicks +def registerButtonClicked(): + while True: + logger.info('Button Clicked Start ---------------------------') + global buttonClickCount + button.wait_for_press() + buttonClickCount = (buttonClickCount + 1)% classCount + logger.info('Button Clicked count set to detect :%s' ,vClassNames[buttonClickCount]) + logger.info('Button Clicked End ---------------------------') + sleep(sleepTimer) + return + +#Button Click thread init +logger.info('Starting Button thread *******************************') +buttonThread = threading.Thread(target=registerButtonClicked, name='ButtonClick') +buttonThread.start() + +lastCount=-1 +soundCmd="mpg123 /home/pi/project/vechtor/v2/mp3/" +#os.system(soundCmd +'welcome.mp3') +welcomePlayed=False + +#main thread +while True: + if welcomePlayed != True : + initRoboflow() + welcomePlayed=True + os.system(soundCmd +'welcome.mp3') + logger.info('-------------- Cap Initilization complete --------------') + + success,img = cam.read() + motorLeft.value =0.0 + motorRight.value =0.0 + #Identify if user clicked button and play object name ]) + if lastCount != buttonClickCount: + mp3Name = vClassNames[buttonClickCount] + '.mp3' + logger.info('-------------playing mp3 %s' ,soundCmd+mp3Name) + os.system(soundCmd + mp3Name) + lastCount = buttonClickCount + + logger.debug('Should detect %s', vClassNames[buttonClickCount]) + + if success==False : + logger.info('Did not detect any object *******************************') + else: + logger.debug('Reading new image *******************************') + height, width,channels = img.shape + + result = model.predict(img) + #cv2.imshow('Imagetest',img) + preds =result.json() + predictions = preds["predictions"] + + for prediction in predictions: + object_class = prediction["class"] + #logger.info('***** INDIVIDUAL prediction results---') + + if vClassNames[buttonClickCount] == object_class: + motorLeft.value =0.0 + motorRight.value =0.0 + logger.info('Found class %s in camera',object_class) + logger.debug('ButtonClickCount=%d ', buttonClickCount) + logger.debug('Should detect %s', vClassNames[buttonClickCount]) + confidence = prediction["confidence"] + x = prediction["x"] + y = prediction["y"] + w = prediction["width"] + h = prediction["height"] + + logger.info('Found class in camera %s',object_class) + logger.info('Confidence =%d ',confidence) + logger.info('x =%d ',x) + logger.info('y =%d ',y) + logger.info('width =%d ',w) + logger.info('height=%d ',h) + start_point = (int(x-width/2),int(y-height/2)) + end_point = (int(x+width/2), int(y+height/2)) + #Uncomment below to see the rectangle drawn + if ( (buttonClickCount == 1) or (buttonClickCount == 2) or (buttonClickCount ==0)): + logger.info(' %s detected at x cordinate %f', vClassNames[buttonClickCount] , x) + #Open Cv box prints (startX,startY,endX,endY) + midX = (x+w) / 2 + + #TODO Need to write function to draw rectangle + #Uncomment below to see the rectangle drawn + #logger.info('Drawing rectangle.') + #drawRfRectangle(img,start_point, end_point, object_class, confidence) + #cv2.imshow("Output",img) + if x < 120.0: + logger.info(' %s detected at left ', vClassNames[buttonClickCount]) + motorLeft.value =motorPower + motorRight.value=motorStopPower + #os.system(soundCmd + vClassNames[buttonClickCount] + '_left.mp3') + buttonClickCount + sleep(sleepTimer) + motorLeft.value =motorStopPower + elif x > 210.0: + logger.info(' %s detected at right ', vClassNames[buttonClickCount]) + motorRight.value=motorPower + motorLeft.value =motorStopPower + #os.system(soundCmd + vClassNames[buttonClickCount] + '_right.mp3') + sleep(sleepTimer) + motorRight.value =motorStopPower + else: + logger.info(' %s detected at center ', vClassNames[buttonClickCount]) + motorLeft.value =motorPower + motorRight.value =motorPower + #os.system(soundCmd + vClassNames[buttonClickCount] + '_center.mp3') + sleep(sleepTimer) + motorRight.value =motorStopPower + motorLeft.value =motorStopPower + else: + logger.info(' %s was not detected ', vClassNames[buttonClickCount]) + + k=cv2.waitKey(1) + + if k != -1: + break; + + +buttonThread.join() +cam.release() +logger.info('-----------------------End-------------------') +cv2.destroyAllWindows() + diff --git a/v6 (final prototype v1)/project/mp3/Bus.mp3 b/v6 (final prototype v1)/project/mp3/Bus.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..f32e6773cd34a3022effa10199f390caac3cee77 GIT binary patch literal 6628 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 KKJ5Sc|Nj9jBKBMW literal 0 HcmV?d00001 diff --git a/v6 (final prototype v1)/project/mp3/Chair.mp3 b/v6 (final prototype v1)/project/mp3/Chair.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..2517bf038bb815ec01c6455c6b0103bb5c34ca6c GIT binary patch literal 6314 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≫gd`U)fNemTHHM_%P1&spUii!`}5Q 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 liT;*Xl~$AId)cF}`+saNaQvXw=N /home/pi/project/logs/docker.log & +dockerPid="$!" +echo "Docker process started $dockerPid" diff --git a/v6 (final prototype v1)/project/startrobo.sh b/v6 (final prototype v1)/project/startrobo.sh new file mode 100644 index 0000000..1e58dd5 --- /dev/null +++ b/v6 (final prototype v1)/project/startrobo.sh @@ -0,0 +1,12 @@ +#! /bin/bash +source /home/pi/project/env/bin/activate +cd /home/pi/project/vechtor/v2/ +echo $HOME +export HOME="/home/pi" + +#start vechtor +sudo rm -rf /home/pi/project/logs/vechtor.log +echo "Vechtor process starting.." +python3 main-robo-haptic.py & +pid="$!" +echo "Vechtor process started $pid"