Bodgers – Texts & Emails

This week we looked at sending texts and emails from our python scripts.

To send text messages you will need to set up an account on Twilio which is a platform that allows coders to make and receive phone calls, send and receive text messages from their programmes. You then install the Twilio python library which will allow us to send texts from our script using code like this.


# Download the helper library from https://www.twilio.com/docs/python/install
from twilio.rest import Client

# Your Account Sid and Auth Token from twilio.com/console
# DANGER! This is insecure. See http://twil.io/secure
account_sid = 'your account_sid'
auth_token = 'your auth_token'
client = Client(account_sid, auth_token)

message = client.messages \
                .create(
                     body="Hello Bodgers",
                     from_='+440123456789',
                     to='+353123456789'
                 )

print(message.sid)

To send an email we use smtplib which is an email library that’s built into python and which works well with Gmail. We need to change our Gmail setting to allow insecure apps and then we can use the code below to send our message.


import smtplib

server = smtplib.SMTP('smtp.gmail.com', 485)
server.starttls()
server.login("my.email@email.com", "myPassword")

msg = "Hello World"
server.sendmail("my.email@email.com", "some.email@email.com", msg)
server.quit()

See you all on Saturday

Declan, Dave and Alaidh

Creators: Autonomous Agents!

This week in Creators we did a very fun project – we learned how to simulate creatures with a kind of basic artificial intelligence and their own hopes, dreams and aspirations!  We made an app where a bunch of creatures desired to spell the word “Creators” and were also scared of the mouse.

Click on the image below to play with our completed animation.

creature-steering

All the code is on the creators github as usual! Pretty cool eh?  How did we get it working?

The evolution of Consciousness
At the start we chatted about an interesting channel on youtube called Kurzgesagt which contains short videos on all sorts of interesting topics.  A recent video I watched discussed the notion of consciousness and how it might have evolved and it inspired the project.  Though a lot is speculation about this topic, the video made a reasonable argument that consciousness evolved as a survival tool to allow simple creatures to seek energy (food) and flee from creatures that wanted to eat them.  Watch the video, it’s very good!

Though we aren’t quite at the stage where we are ready to code up conscious beings – it was interesting to think about how we might add needs and desires to a character, so that’s what we looked at!

Reynold’s Steering Behaviours for Autonomous Characters
Having decided that we wanted some creatures that moved to the beat of their own drum, we next needed to figure out how to implement it.  There are LOTS of pretty complicated strategies for simulating intelligence, but we looked at a brilliant research paper published in 1999 by a playstation programmer called Craig Reynolds called Steering Behaviours for Autonomous characters – read the full paper here.  In this paper, Reynolds describes a simple but fantastic way to model “autonomous” characters using forces.

steering2

An “Autonomous” character is one that controls or powers itself – i.e. there is no remote control here! There is a lot in Reynolds paper but the basic idea is to think of some “behaviours” that a creature might exhibit – these could be:

  • Flee: perhaps the creature might want to escape from someone?
  • Seek: perhaps the creature might want to get somewhere really quickly?
  • Arrive: perhaps a creature might want to get somewhere and stay there (i.e. slow down to “arrive” there.
  • Be close to other creatures: perhaps a creature might want to be close to creatures like them
  • etc – basically anything you can think of nearly!

In Reynold’s paper, creatures generally have a limited vision, and can have more than one behaviour happening at once – i.e. I really want to get food, but want to avoid the predator in the way.

The simple but powerful that Reynolds came up with is the idea of using forces to describe these behaviours and letting newton sort it out.  To model a Reynolds behaviour, you:

  1. Determine your DESIRED velocity for this behaviour – this is a force describing how badly you want to escape the predator, or pursue the target, or avoid the obstacle, etc
  2. You STEERING force vector is worked out as:

steering = desired – velocity

With this simple looking formula, and behaviour rules you combine, you can create some great behaviours that can seem to have realistic looking intelligence behind them.

The Code
Because Reynolds uses force, we had an object which could be a good starting point developed way back in Week 8 – our fun with forces model was a perfect starting point since we already had a “Mover” object that had an applyForce function to allow you to add a force to it.

seek-fleeOur movers “seek” home and “flee” the mouse

All we needed to do was to add some “personality” to our Mover so that it decided itself where it wanted to move to.  These are called “behaviours” in Reynolds brilliant paper.  We decided that our first Mover would have a “timid, homebird” personality and it would have two desires: to get home (some location that is dear to it!), and to stay away from the mouse.  We decided that when it is “afraid” of the mouse we should add something visual to let us know it was afraid – we coloured it red.

The first and easiest code to add was the code to make the Mover want to go home:

 goHome(){
    // i want to go home
    let desired = p5.Vector.sub(this.home, this.position);
    desired = desired.limit(this.maxSpeed);
    let steering = p5.Vector.sub(desired, this.velocity);
    this.applyForce(steering);
}
This is a good example of the process – first we create a Vector that describes where we want to go (home – location), next we limit it to the maximum speed of the Mover.  Next we use the magic formula of Steering = Desired – Velocity to find what the steering force should be.  (This looked okay for us, but in Reynold’s paper he recommended a maximum steering force so it doesn’t steer too quickly – good idea but we didn’t bother with it!).  We called this “goHome” but Reynolds calls this the “Seek” behaviour.
 flee(){
     // i am scared of the mouse
     let mousePosition = createVector(mouseX, mouseY);
     let desired = p5.Vector.sub(this.position, mousePosition);
     let dist = desired.mag();
     if(dist < 100){
         desired = desired.limit(this.maxSpeed);
         let steering = p5.Vector.sub(desired, this.velocity);
         this.applyForce(steering.mult(10));
         this.isAfraid=true;
     } else {
         this.isAfraid = false;
     }
}
The next steering behaviour was fear of the mouse.  We added this as per the above “flee” method.  We imagined that our little creatures can see the mouse when it’s 100 pixels away, and if it is, then it’s afraid and a very strong “flee” force is present.  In the show method we decided to show the fear by turning it red (we should have drawn e.g. a scared face or something).
Finally, we add a function which calls the behaviours in turn:
applyBehaviours(){
    this.flee();
    this.goHome();
}
In each draw loop instance, we call the applyBehaviours, just like we call the “move” method and the “show” one.
That’s it!  That’s all it took to give our creatures the desired behaviours!
Drawing a message:
The code to draw a message came from a hidden feature of the font class in p5 – the ability to get points from text with textToPoints.  This allowed us to get a bunch of points to set as home which spelled a message.   Depending on your computer, it could run a little slow so you might want to just add every 2nd points (takes a while to paint on my phone, but looks quite good on my laptop!).
function preload(){
    font = loadFont("fonts/AvenirNextLTW01-Medium.ttf");
}

function setup() {
    createCanvas(innerWidth, innerHeight);
    textFont(font);
    points = font.textToPoints("Creators", 100, height/2, 300);
    
    for(let i=0; i< points.length; i++){
        let startPosition=createVector(points[i].x, points[i].y);
        movers.push(new Mover(random(10,30), startPosition));
    }
}

Explorers Week 7 – Truchet Tiles

Hello everyone

Nice big room last week as we had Advancers and Explorers in the one room. As I said on Saturday, we will continue to combine the both groups for the next two weeks.

We are starting Stop/Start Animation this coming week and if you could bring some or all of the following it would be helpful.

PDF notes of the session can be found here CDA-S7-Week_07-TruchetTiles.pdf

 

See you next week,

Martha

Julie, Ruaidhrí and Eoin McG

Hackers – code for our first prototype remote-controlled robot

Here is a video of the first tests of our remote-controlled robot with 2-wheel drive.

The control for this is based on the calculations we described in an earlier post: https://coderdojoathenry.org/2019/02/24/hackers-how-to-control-a-robots-wheel-motors-based-on-joystick-movements/

Here is the code:

// Code by Luke Madden, CoderDojo Athenry, with some comments added by Michael.
// This code controls a robot with 2-wheel drive, based on movements of a joystick.

// These are the motor H bridge control pins
#define in1 8
#define in2 9
#define in3 10
#define in4 11

// These hold values read from channels of the LemonRX receiver
int ch1;
int ch2; // not currently used
int ch3;

// These are the min and max values we read on each channel when we move the joystick
int joymin = 950;
int joymax = 1950;

// X and Y are joystick values in range -1 to +1
float X;
float Y;

// M1 and M2 are values for Motors 1 and 2, in range -1 to +1
int M1;
int M2; 

void setup() {
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);

  Serial.begin(9600);
}

void loop() {

  // read pulse width values from each channel of lemonRX
  ch1 = pulseIn(5, HIGH, 25000);
  ch2 = pulseIn(6, HIGH, 25000);
  ch3 = pulseIn(7, HIGH, 25000);

  // Convert them to floats in range -1 to 1: map uses int, so set it to int in range -1000 to 1000 and then divide by 1000.0
  X = map(ch1, joymin, joymax, -1000, 1000)/1000.0;
  Y = map(ch3, joymin, joymax, -1000, 1000)/-1000.0;

  // This is the fomula for how much power to send to each motor
  // Motor values should be in range -255 to 255, not -1 to 1, so multiply by 255
  M1 = (X + Y) * 255;
  M2 = (X - Y) * 255;

  // Our fomula can end up with values greater than 255, so constrain them to this range
  M1 = constrain(M1, -255, 255);
  M2 = constrain(M2, -255, 255);

  // Call our function to actually drive the motors
  drive(M1,M2);

  // print out for debugging
  Serial.print("Channels: C1=\t"); // Print the value of
  Serial.print(ch1);        // each channel
  Serial.print("\t M1=\t");
  Serial.print(M1);
  Serial.print("\t M2=\t");
  Serial.print(M2);
  Serial.print("\t C3:\t");
  Serial.println(ch3);

  // this delay seems to help reading joystick
  delay(300);
}

void drive(int M1, int M2) {
  // drive both motors at speeds M1, M2 in range -255, 255
  if (M1 > 0) {
    analogWrite(in1, M1);
    analogWrite(in2, 0);
  }
  else {
    analogWrite(in1, 0);
    analogWrite(in2, -M1);
  }

  if (M2 > 0) {
    analogWrite(in3, M2);
    analogWrite(in4, 0);
  }
  else {
    analogWrite(in3, 0);
    analogWrite(in4, -M2);
  }
}

Creators: Shootah Part 6 – Enemy Shooting Back

alien

This week we did our last iteration on Shootah and added a Bomb to be dropped by the enemy to try to hit the player.

Bomb Class

We copied the existing Bullet class and called it Bomb instead. The main changes we had to make were:

  1. Changing the speed to a negative number so that it moved down instead of moving up (as the Bullet does)
  2. Changed the check for the top of the screen to one for the bottom of the screen instead (to account for the fact it moves down)
  3. Changed the check in its hit() function so that the Bomb doesn’t interact with the Enemy when it’s dropped, but will be marked as inactive it if hits anything else.
  4. Changed the colour of the bomb to red

Manages Bombs

It happened that the code we had already written to manage bullets was already perfect for managing bombs as well.

We used Visual Studio Code’s built-in capability to automatically rename symbols to:

  1. Rename the bullets array to projectiles
  2. Rename the manageBullets() function to manageProjectiles()

This was enough to have bombs move, draw and be removed when it becomes inactive.

Dropping Bombs

We added a new function to Ememy called shoot(). In that function we generated a random number from one to two hundred. We then dropped a bomb every time that number was less than five (we tuned this small number to get a good rate of bomb drops). This meant that the enemy dropped a bomb at random intervals, to make it impossible for the player to anticipate.

Download

The files for this week can be found on our GitHub repository.

Bodgers – GPS

 

This week we looked at GPS which stands for Global Positioning System. The idea behind GPS is based on time and the position of  a network of  satellites. The satellites have very accurate clocks and the satellite locations are known with great precision.

Each GPS satellite continuously transmits a radio signal containing the current time and data about its position. The time delay between when the satellite transmits a signal and the receiver receives it is proportional to the distance from the satellite to the receiver. A GPS receiver monitors multiple satellites and uses their locations and the time it takes for the signals to reach it to determine its location . At a minimum, four satellites must be in view of the receiver for it to get a location fix.

We used the Adafruit Ultimate GPS Breakout connected to an Arduino as our GPS receiver. It’s very easy to set up, all we did was install the Adafruit GPS library on our Arduino and this gave us a load of programmes to chose from. We used the parsing sketch which gave us Longitude, Latitude and our location in degrees which we used with google maps to show our location.

See you all again on the 23/Mar/19

Declan, Dave and Alaidh

 

Bodgers – Pi Camera & OpenCV

This week in the Bodgers group we looked at the Pi Camera Module which is a high quality image sensor add-on board for the Raspberry Pi. You can capture images  from the command line with:

 raspistill -o cam.jpg 

This will take a jpeg picture called cam which will be saved in your home folder.

You can take a picture from your Python script with:


from time import sleep
from picamera import PiCamera

camera = PiCamera()
camera.resolution = (1024, 768)
camera.start_preview()
# Camera warm-up time
sleep(2)
camera.capture('foo.jpg')

This will save a picture called foo in the folder you ran your script from.

OpenCV (Open source computer vision) is a library of programming functions mainly aimed at real-time computer vision. We tried a couple of scripts out, one from the Hackers group, thanks Kevin, that detects colours and another one that detects shapes, we will be looking at this much more in the next few sessions but next Saturday we will look at using an Arduino and a Raspberry Pi together.

See you all then.

Declan, Dave and Alaidh

Week 5, Explorers – Pen Commands

Hello Everyone,

A special welcome to all our new members that came to us this week, I hope you enjoyed yourself and hope to see you back again soon.

Thank you all for coming again this week. This week we looked at pen commands, we have not done this before in the Explorers group so it was new for everyone.

pencommand

We also created some variables which we set as sliders which again is something we had not done before with this group.

 

sliders

 

 

 

 

 

 

 

 

 

Here are the full Pdf version of my notes from this weeks session. CDA-S8 Week 5-Pen Command.pdf

Martha

Creators: Shootah Part 5 – Edges

spaceship.png

This week we extended our colliders so that we could used them to prevent the player going off the edges of the screen. We used it to show how software design needs to evolve.

Colliders

Our colliders were designed to be connected to an object with three things:

  1. A property  containing the x-coordinate of its location
  2. A property y containing the y-coordinate of its location
  3. A function hit() which was called if the attached collider touched another collider

Something to Connect To

We had colliders already attached to our:

  1. Enemy
  2. Bullets

but we didn’t have anything to attach to that could represent the side of the screen.

We created a new class called Static() with nothing more than the x, y  and hit() that we needed so that we could connect a collider to it (stored in one more property – collider).

Screen Edges

We created a pair of these colliders positioned at the right and left-hand side of the screen. We made sure to add them to our list in check_colliders(). Nothing much happened. Why? Well, first, the Player didn’t have a collider, so we added one, liberally copying code from Enemy, which a minor change to the description argument.

Now we could see the contact occurring between the edge and the player, though nothing was stopping it moving yet.

Unintended Consequences

As  often happens with code, this change had unexpected consequences; bullets were not firing properly any more. Why? Because the player now had a collider and the bullets were becoming inactive immediately because they were hitting that. The fix was to modify the Bullet’s hit() function to ignore hitting a collider with the description “player”.

Stopping the Player Moving

We now knew our player was hitting an edge, but another problem became apparent: we didn’t know which edge!

To properly stop the player and stop it moving too far, we really needed to know which side of the player the collider we’d hit was, but that information wasn’t available to us with the current design.

A couple of quick changes were necessary:

  1. In Collider.touching(), instead of just passing the descriptors to the objects hit() functions, we changed it to pass the Collider itself.
  2. In all the hit() functions, we had to made a small adjustment to account for the fact that we were now getting a Collider and not just a string.

With the extra information from the collider, were were able to determine how far the player should be allowed to move to and prevent it going further by setting the x value appropriately.

Download

The files for this week can be found on our GitHub repository.