Συναντήσεις

Συναντήσεις 5 και 12/6/2019

Σε αυτές τις συναντήσεις ασχοληθήκαμε με βελτιώσεις στα αποχιονιστικά μας μηχανήματα, όσον αφορά το πρόγραμμα και την κατασκευή τους. Παράλληλα βελτιώσαμε και το πρόγραμμα για το χειριστήριο εικονικής πραγματικότητας. Πιο συγκεκριμένα:

Διασκορπιστής αλατιού στα αποχιονιστικά

Για τον καλύτερο διασκορπισμό του αλατιού που πέφτει από την αλατιέρα προσθέσαμε στο ένα όχημα μας έναν κινητήρα servo στον οποίο προσθέσαμε μια επιφάνεια από μακετόχαρτο. Ο κινητήρας θα γυρνάει συνέχεια δεξιά – αριστερά για να διασκορπίζει το αλάτι. Στο δεύτερο όχημα, τα παιδιά αποφάσισαν να αποφύγουν τη χρήση κινητήρα servo, δημιουργώντας μια μηχανική κατασκευή αποκλειστικά από μακετόχαρτο.

Επίσης επειδή το αλάτι πέφτει λίγο απότομα από τον κοχλία μήπως να σχεδιάσουμε ένα δοχείο και να το εκτυπώσουμε;

Ξεκινήστε με έναν κώνο
Γυρίστε τον ανάποδα
Διπλασιάστε τον
Μετατρέψτε τον 2ο κώνο σε τρύπα
Μειώστε λίγο (5 χιλιοστά) το πλάτος και το μήκος του 2ου κώνου και τοποθετήστε τον στην μέση του πρώτου
Προσθέστε έναν κενό κύλινδρο
Μειώστε το ύψος του και τοποθετήστε τον και αυτόν στο κέντρο
Προσθέστε έναν κύβο
Αλλάξτε το μέγεθος και την θέση του ώστε να είναι περίπου όπως στην εικόνα
Επιλέξτε όλα τα σχήματα και ομαδοποιήστε τα (Group)

Τώρα μπορείτε να κατεβάσετε το αρχείο stl και να το εκτυπώσετε.

Τοποθέτηση κινητήρα servo για τον διασκορπισμό του αλατιού από την αλατιέρα.

Προγραμματισμός αποχιονιστικών

Με βάση τον αλγόριθμο που φτιάξαμε σε προηγούμενη συνάντηση στο Scratch έπρεπε αλλάξουμε τις βασικές οδηγίες που έχουμε στο πρόγραμμα μας.

Αυτός είναι ο αλγόριθμος που φτιάξαμε την προηγούμενη φορά.

Πριν ξεκινήσουμε να κάνουμε το πρόγραμμα μας θα πρέπει αρχικά να βρούμε πόσα εκατοστά προχωράει το όχημα μας για ένα δευτερόλεπτο. Αυτό θα μας χρειαστεί για να υπολογίσουμε πόσες επαναλήψεις θα κάνει για να ολοκληρώσει το καθάρισμα όλης της αυλής. Ανοίξτε λοιπόν τα προγράμματα που έχουμε ήδη στον υπολογιστή και πηγαίνεται στην συνάρητηση setup που έχουμε τις οδηγίες. Εκεί γράψτε μόνο τις εξής εντολές:

void setup() {
    //Ορίζω τα pin που χρειάζονται να δηλωθούν ως input και output
  pinMode(pinS,OUTPUT);   //Ορίζουμε το pin του ηχείου ως έξοδο
  pinMode(pinL,OUTPUT);   //Ορίζουμε το pin του φωτός ως έξοδο
  pinMode(pinP, INPUT);   //Ορίζουμε το pin του αισθητήρα PIR ως είσοδο
  
  //Τώρα ξεκινάν οι οδηγίες μας
  start();
  driveMillis(1000);
}

Αφού φορτώσετε το πρόγραμμα στο μηχάνημα, σημειώστε με ένα μολύβι την αρχική και την τελική του θέση και μετρήστε την απόσταση που έκανε. Κρατήστε αυτό τον αριθμό γιατί θα μας χρειαστεί στο πρόγραμμα.

Τα αποτελέσματα που βρήκαν οι δυο ομάδες δοκιμών είναι: Για το όχημα Α 22 εκατοστά και για το όχημα Β 35 εκατοστά

Εμείς αυτό που πρέπει να κάνουμε τώρα είναι να έχουμε στο μυαλό μας τον παραπάνω αλγόριθμο και να γράψουμε τις σωστές εντολές μέσα στο πρόγραμμα μας στο Arduino. Τις οδηγίες μας θα τις γράψουμε μέσα στην void setup. Οι συναρτήσεις που έχουμε φτιάξει και θα μας χρειαστούν είναι:

  • start(); //Αρχικοποίηση
  • turnLeft(); //Στρίψε αριστερά
  • turnRight(); //Στρίψε δεξιά
  • drive(); //Προχώρα μπροστά μέχρι να βρεις τον τοίχο
  • driveMillis(m); //Προχώρα μπροστά για m χιλιοδευτερόλεπτα
  • cm = sonar.ping_cm(); //Βάζουμε στην μεταβλητή cm τα εκατοστά που βλέπει ο αισθητήρας υπερήχων

Επίσης θα χρειαστούμε τη συνάρτηση int(n) που παίρνει έναν δεκαδικό αριθμό n και τον μετατρέπει σε ακέραιο, ενώ θα πρέπει να χρησιμοποιήσουμε και μια δομή επανάληψης. Θα χρησιμοποιήσουμε την for που γράφεται όπως φαίνεται παρακάτω:

for (int i=1; i<=10; i++) {
  //Εδώ βάζουμε τις εντολές που θέλουμε να επαναλαμβάνονται πολλές φορές
}

Η παραπάνω επανάληψη εκτελείται 10 φορές, από το 1 ως το 10. Αν θέλω να εκτελεστεί 20 φορές τότε θα πρέπει να την αλλάξω ως εξής:

for (int i=1; i<=20; i++) {
  //Εδώ βάζουμε τις εντολές που θέλουμε να επαναλαμβάνονται πολλές φορές
}

Με βάση αυτές τις πληροφορίες λοιπόν πρέπει τώρα να φτιάξετε το πρόγραμμα!

Το πρόγραμμα που παρέδωσε η ομάδα για το όχημα Α έχει ως εξής:

//Τώρα ξεκινάν οι οδηγίες μας
  start();        
  turnLeft();
  cm = sonar.ping_cm();
  turnRight();
  for (int i=1; i<=cm/44; i++) {
    drive();
    delay(750);
    turnLeft();
    delay(750);
    driveMillis(1000);
    delay(750);
    turnLeft();
    delay(750);
    drive();
    delay(750);
    turnRight();
    delay(750);
    driveMillis(1000);
    delay(750);
    turnRight();
    delay(750);
  }
  turnRight();
  drive();
  turnRight();

Το πρόγραμμα που παρέδωσε η ομάδα για το όχημα Β έχει ως εξής:


  //Τώρα ξεκινάν οι οδηγίες μας
  start();
  turnLeft();
  delay(500);
  cm = sonar.ping_cm();
  delay(500);
  turnRight();
  for (int i=1; i<=cm/70; i++) {
    //Εδώ βάζουμε τις εντολές που θέλουμε να επαναλαμβάνονται πολλές φορές
    drive();
    delay(1000);
    turnLeft();
    delay(1000);
    driveMillis(1000);
    delay(1000);
    turnLeft(); 
    delay(1000);
    drive();
    delay(1000);
    turnRight();
    delay(1000);
    driveMillis(1000);
    delay(1000);
    turnRight(); 
  }
  turnRight(); 
  drive();
  turnRight();

Δημιουργία εξωτερικού περιβλήματος για το ένα αποχιονιστικό

Το ένα από τα δυο αποχιονιστικά μας είναι «γυμνό» και φαίνονται λίγο άσχημα τα καλώδια. Μήπως μπορούμε να φτιάξουμε ένα περίβλημα από μακετόχαρτο ώστε να τα καλύψουμε;

Δοκιμάζοντας την προσαρμογή του νέου εξωτερικού περιβλήματος από μακετόχαρτο

Η ομάδα που ανέλαβε αυτή την εργασία προχώρησε στην κατασκευή ενός περιβλήματος για το όχημα Α, ενώ επισημάναμε την ανάγκη να μετακινήσουμε το powerbank σε διαφορετική θέση, ώστε να κατανείμουμε το βάρος του οχήματος καλύτερα.

Βάψιμο αποχιονιστικού

Στο πολύ ωραίο περίβλημα που έχετε δημιουργήσει για το ένα αποχιονιστικό μπορείτε να προσθέσετε χρώματα για να γίνει πιο όμορφο. Αφού πρώτα συμφωνήσουμε στο τι χρώμα θα έχει κάθε επιφάνεια, ξεκινάμε με προσοχή το βάψιμο.

Βάφουμε το όχημα με έντονα χρώματα

Η ομάδα που ανέλαβε το βάψιμο του οχήματος 2 προχώρησε και στην δημιουργία αφίσας για τις κατασκευές μας.

Εκτύπωση ατέρμων κοχλία

Στο ένα αποχιονιστικό χρειαζόμαστε έναν ατέρμων κοχλία για να σπρώχνει το αλάτι. Αρχικά κατεβάστε αυτό το αρχείο στην επιφάνεια εργασίας σας.

Τώρα θα χρειαστεί να ανοίξουμε το πρόγραμμα που χειριζόμαστε τον 3Δ εκτυπωτή.

Ανοίγουμε το Repetier-Host
Ανοίγουμε τον 3Δ εκτυπωτή και κάνουμε σύνδεση στο Tsouska
Προσθέτουμε ένα νέο αντικείμενο
Επιλέγουμε το αρχείο που κατεβάσαμε
Θα το δούμε να εμφανίζεται στην οθόνη

Μετά θα πρέπει να προσθέσουμε το πλαστικό νήμα στην τροφοδοσία. Αν δεν θυμάστε πως γίνεται ζητήστε την βοήθεια του εκπαιδευτικού.

Πριν εκτυπώσουμε θα πρέπει να περιστρέψουμε το αντικείμενο
Το περιστέφουμε 90 μοίρες στον άξονα Χ
Αφού έχουμε τις ρυθμίσεις που φαίνονται στην εικόνα κάνουμε το Sclicing
Μόλις τελειώσει το Slicing κάνουμε print

Όση ώρα διαρκεί η εκτύπωση προσέχουμε μήπως υπάρχει κάποιο σφάλμα ή δυσλειτουργία. Αν αντιληφθούμε ότι κάτι δεν πάει καλά (δεν βγάζει υλικό, έχε ξεκολλήσει το αντικείμενο κλπ) ενημερώνουμε τον εκπαιδευτικό και πατάμε emergency stop.

Εκτύπωση ενός νέου κοχλία και προσθήκη «τσουλήθρας» για τον διασκορπισμό του αλατιού

Τα παιδιά που ανέλαβαν την 3Δ εκτύπωση ήρθαν αντιμέτωπα αρχικά με ένα πρόβλημα λειτουργίας του εκτυπωτή. Ο κινητήρας που γυρνάει το γρανάζι για την μεταφορά του πλαστικού νήματος στην θερμαινόμενη κεφαλή δεν λειτουργούσε. Έκανε συνεχείς μικρές δονήσεις και δεν μπορούσε να φέρει το υλικό για να γίνει η εκτύπωση. Αρχικά ελέγξαμε τα γρανάζια για την ύπαρξη μηχανικού προβλήματος κατά την επαφή τους και είδαμε πως λειτουργούσαν μια χαρά. Αμέσως μετά ελέγξαμε τα καλώδια που κατέληγαν στον βηματικό κινητήρα και εκεί παρατηρήσαμε πως ένα από αυτά είχε κοπεί. Τα παιδιά ανέλαβαν να κάνουν την κόλληση και να ξεκινήσουν την εκτύπωση του κοχλία.

Χειριστήριο εικονικής πραγματικότητας

Το πρόγραμμα που έχουμε βάλει στο χειριστήριο μας στέλνει τα δεδομένα από το γυροσκόπιο στον υπολογιστή μέσω του καλωδίου USB, χρησιμοποιώντας την σειριακή μετάδοση. Το πρόγραμμα μας είναι το εξής:

Στο πρόγραμμα αυτό έχουμε ορίσει ως ταχύτητα της σειριακής μετάδοσης τα 9600 bits ανά δευτερόλεπτο. Μπορούμε να δοκιμάσουμε μια πιο γρήγορη ταχύτητα για να δούμε αν το χειριστήριο έχει καλύτερη απόδοση. Αλλάξτε λοιπόν την ταχύτητα μετάδοση σε 115200 bits ανά δευτερόλεπτο κα φορτώστε το πρόγραμμα στο χειριστήριο.

Τώρα θα πρέπει να κάνουμε αλλαγές και στο πρόγραμμα του υπολογιστή στην Processing. Το πρόγραμμα μας είναι:

/* Το πρόγραμμα που τρέχει στον υπολογιστή μας και περιστρέφει ένα 3Δ αντικείμενο
*  χρησιμοποιώντας τις τιμές περιστροφής που παίρνει από το χειριστήριο μας
*/

import processing.serial.*;  //Εισάγουμε την βιβλιοθήκη για την σιεριακή επικοινωνία με τον υπολογιστή
Serial myPort;               //Δηλώνουμε το αντικείμενο για την σειριακή θύρα επικοινωνίας

String data;  //Μεταβλητή η οποία θα έχει τα δεδομένα που έρχονται από την σειριακή θύρα
float dX;     //Μεταβλητή η οποία θα έχει την περιστροφή γύρω από τον άξονα Χ του χειριστηρίου όπως έρχεται στα δεδομένα
float dY;     //Μεταβλητή η οποία θα έχει την περιστροφή γύρω από τον άξονα Υ του χειριστηρίου όπως έρχεται στα δεδομένα
float dZ;     //Μεταβλητή η οποία θα έχει την περιστροφή γύρω από τον άξονα Ζ του χειριστηρίου όπως έρχεται στα δεδομένα
float mX;     //Μεταβλητή για την περιστροφή σε μοίρες γύρω από τον άξονα Χ στο 3Δ μοντέλο μας
float mY;     //Μεταβλητή για την περιστροφή σε μοίρες γύρω από τον άξονα Υ στο 3Δ μοντέλο μας
float mZ;     //Μεταβλητή για την περιστροφή σε μοίρες γύρω από τον άξονα Ζ στο 3Δ μοντέλο μας
PShape s;     //Το 3Δ σχήμα που θα προσθέσω


void setup() {
  size(800,600,P3D);                         //Ορίζω το μέγεθος σε 800Χ600
  s = loadShape("drone_costum.obj");         //Φορτώνω το 3Δ σχήμα
  s.scale(20);                               //Ορίζω το μέγεθος του σχήματος ώστε να φαίνεται καλά στην οθόνη
  String portName = Serial.list()[0];        //Επιλέγω την πρώτη θύρα από τις διαθέσιμες σειριακές
  myPort = new Serial(this, portName, 9600); //Συνδέομαι στην σειριακή θύρα για να πάρω τα δεδομένα από το Arduino 
  
  mX = 0;  //Ορίζω αρχικά τις περιστροφές στο 3Δ αντικείμενο στις 0 μοίρες
  mY = 0;  //Ορίζω αρχικά τις περιστροφές στο 3Δ αντικείμενο στις 0 μοίρες
  mZ = 0;  //Ορίζω αρχικά τις περιστροφές στο 3Δ αντικείμενο στις 0 μοίρες
}

void draw() {
  background(5,40,230);                                 //Ορίζω το χρώμα του φόντου σε μπλε
  if ( myPort.available() > 0) {                        //Αν υπάρχουν διαθέσιμα δεδομένα στην σειριακή θύρα,
    data = myPort.readStringUntil('\n');                //Τα αποθηκεύω στην μεταβλητή data
    if (data != null) {                                 //Αν τα δεδομένα που αποθήκευσα δεν είναι μηδενικά,
      int posSTART = data.indexOf("START");             //Κρατάω την θέση του δείκτη START
      int posY = data.indexOf("Y");                     //Κρατάω την θέση του δείκτη Y 
      int posZ = data.indexOf("Z");                     //Κρατάω την θέση του δείκτη Z 
      int posEND = data.indexOf("END");                 //Κρατάω την θέση του δείκτη END 
      if (posSTART > -1) {                              //Αν οι δείκτες υπάρχουν μέσα στα δεδομένα,
        dX = float(data.substring(posSTART+6,posY));    //Αποσπάω την τιμή περιστροφής X από τα δεδομένα
        dY = float(data.substring(posY+1,posZ));        //Αποσπάω την τιμή περιστροφής Υ από τα δεδομένα
        dZ = float(data.substring(posZ+1,posEND));      //Αποσπάω την τιμή περιστροφής Ζ από τα δεδομένα
        
        //Τώρα ήρθε η ώρα να υπολογίσω την περιστροφή του 3Δ αντικειμένου από τις τιμές dX,dY,dZ
        mX = 180-dX;
        mY = 180-dZ;
        mZ = dY;
      }
    }
  }
  
  translate(width/2,height/2); //Πηγαίνω στην μέση της οθόνης
  rotateX(radians(mX));        //Περιστρέφω τον καμβά στον άξονα Χ 
  rotateY(radians(mY));        //Περιστρέφω τον καμβά στον άξονα Y
  rotateZ(radians(mZ));        //Περιστρέφω τον καμβά στον άξονα Z 
  shape(s);                    //Τοποθετώ το 3Δ σχήμα                     
}
  • Αλλάξτε και εδώ την ταχύτητα της σειριακής επικοινωνίας από 9600 σε 115300 bits ανά δευτερόλεπτο.
  • Κατεβάστε μια εικόνα που θέλετε να βάλετε στο φόντο και αποθηκεύστε την στον φάκελο data με το όνομα sky.jpg.
  • Πριν από το setup προσθέστε την εντολή: PImage sky;
  • Μέσα στο setup προσθέστε την εντολή: sky = loadImage(«sky.jpg»);
  • Αλλάξτε το μέγεθος του καμβά στις διαστάσεις που έχει η εικόνα που κατεβάσατε, πειράζοντας την εντολή: size(960,540,P3D);
  • Μέσα στη συνάρτηση draw αλλάξτε την εντολη΄background ώστε αντί για χρώμα να βάζει τώρα την εικόνα που κατεβάσαμε: background(sky);
  • Δοκιμάστε το πρόγραμμα σας!

Αφήστε μια απάντηση

Μετάβαση σε γραμμή εργαλείων