Canal Moon Bridge, The Netherlands

Posted about 1 month back at omg blog!! lol!!



Canal Moon Bridge, The Netherlands

Back to Basics: Polymorphism and Ruby

Posted about 1 month back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Polymorphism - the provision of a single interface to entities of different types

Polymorphism is one of the fundamental features of object oriented programming, but what exactly does it mean? At its core, in Ruby, it means being able to send the same message to different objects and get different results. Let's look at a few different ways to achieve this.

Inheritance

One way we can achieve polymorphism is through inheritance. Let's use the template method to create a simple file parser.

First let's create a GenericParser class that has a parse method. Since this is a template the only thing this method will do is raise an exception:

class GenericParser
  def parse
    raise NotImplementedError, 'You must implement the parse method'
  end
end

Now we need to make a JsonParser class that inherits from GenericParser:

class JsonParser < GenericParser
  def parse
    puts 'An instance of the JsonParser class received the parse message'
  end
end

Let's create an XmlParser to inherit from the GenericParser as well:

class XmlParser < GenericParser
  def parse
    puts 'An instance of the XmlParser class received the parse message'
  end
end

Now let's run a script and take a look at how it behaves:

puts 'Using the XmlParser'
parser = XmlParser.new
parser.parse

puts 'Using the JsonParser'
parser = JsonParser.new
parser.parse

The resulting output looks like this:

Using the XmlParser
An instance of the XmlParser class received the parse message

Using the JsonParser
An instance of the JsonParser class received the parse message

Notice how the code behaves differently depending on which child class receives the parse method. Both the XML and JSON parsers modify GenericParser's behavior, which raises an exception.

Duck Typing

In statically typed languages, runtime polymorphism is more difficult to achieve. Fortunately, with Ruby we can use duck typing.

We'll use our XML and JSON parsers again for this example, minus the inheritance:

class XmlParser
  def parse
    puts 'An instance of the XmlParser class received the parse message'
  end
end

class JsonParser
  def parse
    puts 'An instance of the JsonParser class received the parse message'
  end
end

Now we'll build a generic parser that sends the parse message to a parser that it receives as an argument:

class GenericParser
  def parse(parser)
    parser.parse
  end
end

Now we have a nice example of duck typing at work. Notice how the parse method accepts a variable called parser. The only thing required for this to work is the parser object has to respond to the parse message and luckily both of our parsers do that!

Let's put together a script to see it in action:

parser = GenericParser.new
puts 'Using the XmlParser'
parser.parse(XmlParser.new)

puts 'Using the JsonParser'
parser.parse(JsonParser.new)

This script will result in the following output:

Using the XmlParser
An instance of the XmlParser class received the parse message

Using the JsonParser
An instance of the JsonParser class received the parse message

Notice that the method behaves differently depending on the object that receives it's message. This is polymorphism!

Decorator Pattern

We can also achieve polymorphism through the use of design patterns. Let's look at an example using the decorator pattern:

class Parser
  def parse
    puts 'The Parser class received the parse method'
  end
end

We need to change our XmlParser to include a constructor that accepts a parser as an argument. The parse method will need to be modified to send the parse message to the parser it receives when constructed:

class XmlParser
  def initialize(parser)
    @parser = parser
  end

  def parse
    @parser.parse
    puts 'An instance of the XmlParser class received the parse message'
  end
end

We'll make the same change to our JsonParser:

class JsonParser
  def initialize(parser)
    @parser = parser
  end

  def parse
    puts 'An instance of the JsonParser class received the parse message'
    @parser.parse
  end
end

We'll use the decorators to create our normal XML and JSON parsers, but in the last example, we'll do something a little different: use both decorators to achieve runtime polymorphism:

puts 'Using the XmlParser'
parser = Parser.new
XmlParser.new(parser).parse

puts 'Using the JsonParser'
JsonParser.new(parser).parse

puts 'Using both Parsers!'
JsonParser.new(XmlParser.new(parser)).parse

This script will give us the following output:

Using the XmlParser
The Parser class received the parse method
An instance of the XmlParser class received the parse message

Using the JsonParser
An instance of the JsonParser class received the parse message
The Parser class received the parse method

Using both Parsers!
An instance of the JsonParser class received the parse message
The Parser class received the parse method
An instance of the XmlParser class received the parse message

Notice how we're able to change the results of sending the parse message based on the output.

A Simple Before and After

Now we will look at an intentionally simple example of how taking advantage of polymorphism can simplify our code. Let's say we had the following classes:

class Parser
  def parse(type)
    puts 'The Parser class received the parse method'

    if type == :xml
      puts 'An instance of the XmlParser class received the parse message'
    elsif type == :json
      puts 'An instance of the JsonParser class received the parse message'
    end
  end
end

We can simplify our Parser class by removing the branch logic thanks to simple duck typing. In this particular example we also get the benefit of separating concerns. Now we have our specific parsing logic encapsulated within their own classes:

class Parser
  def parse(parser)
    puts 'The Parser class received the parse method'
    parser.parse
  end
end

class XmlParser
  def parse
    puts 'An instance of the XmlParser class received the parse message'
  end
end

class JsonParser
  def parse
    puts 'An instance of the JsonParser class received the parse message'
  end
end

This example demonstrates that we were able to simplify our class using polymorphism. We were also able to satisfy the Single Responsibility Principle.

In the initial version of the code the Parser class determined which parser to use and then initiated the parsing by instantiating and sending the parse message to the object. In the latter version this class only sends the parse method to kick off the process.

Polymorphism is one of the foundational elements of object oriented programming, but can also be confusing to get a grasp on. Taking the time to understand it and why it's important is a big step towards writing more maintainable and extensible code.

What's next?

If you found this useful, you might also enjoy:

Writing Table, Leeds, England

Posted about 1 month back at omg blog!! lol!!



Writing Table, Leeds, England

A Closer Look at Color Lightness

Posted about 1 month back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

As much as we strive to control every detail of what we build, we are sometimes left with little choice but to leave some design decisions to algorithms. The challenges associated with these decisions become a lot more significant when human perception comes into play. One common example: programmatically choosing a foreground color based on a given background color.

It may sound trivial at first, but having a closer look reveals that there is a bit more to it under the surface. A quick Google search will give some hints, but it will probably end up in more confusion, not least due to the inaccurate use of terms related to the topic.

So, let’s get this straight.

A bit of terminology

Before crunching any numbers, let's define some key concepts relating to colors in the context of screens:

  • Brightness: In a broad sense, brightness is the attribute of an object emitting or reflecting light. More specifically, it's the arithmetic mean of the three components in the RGB—red, green, blue— color model or the third component in the HSB—hue, saturation, brightness—model.
  • Radiance: The total amount of light that goes through a particular area.
  • Weighted: We do not perceive all wavelengths the same; for instance, we tend to perceived green to be lighter than blue or red. A weighted attribute is an attribute that takes that into consideration by giving more weight to green, and less to red and blue.
  • Luminance: Weighted radiance.
  • Gamma correction: The process of coding and decoding luminance with the aim of optimizing the output for human vision.
  • Luma: Used primarily in video, luma is the weighted sum of gamma-corrected RGB values.
  • Lightness: A subjective measure of brightness, relative to the brightness of a white point.
  • Normalization: The process of expressing lightness as a ratio corresponding to the absolute lightness value of the color to that of pure white.

In short, brightness is an absolute measure of light emitted or reflected from an object, while lightness is a subjective measure of perceived light.

How to Determine Lightness

There are several ways to approximate the lightness of a color, with varying degrees of precision. Some are weighted—they take into consideration how we perceive colors—and some are not. For simplicity's sake, we will refer to the value of lightness as L throughout this section. Pure red (255,0,0) will be used as an example.

Non-weighted Methods

These formulae do not take into consideration the perceived lightness of the primary and secondary colors. In other words you'd find out similar results for hues that are primarily red and ones that are primarily green.

Using HSB Brightness

The brightness component of the HSB model corresponds to the value of the largest RGB component:

brightness

Ex: Pure red would have an HSB value of 255 (1.0 normalized) since both other components are null.

Using HSL Lightness

The lightness component of the HSL—hue, saturation, lightness—model corresponds to the arithmetic mean of the largest and smallest RGB components:

lightness

Ex: Pure red would have an HSL lightness of 127.5 (0.5 normalized).

Using Intensity

Intensity is the average of the three components in the RGB space. It could be calculated using an arithmetic mean

arithmetic

…or a geometric one:

geometric

Ex: Pure red would have an arithmetic intensity of 85 (0.33 normalized), and a geometric intensity of 0.

Using Euclidean Distance in 3D RGB space

Considering a three-dimensional, cube-shaped RGB space, lightness would correspond to the Euclidean distance between the color point and the space origin (black):

euclidean

Ex: Pure red would have a euclidean lightness of 255 (0.57 normalized).

Weighted Methods

Weighted formulae take into consideration the perceived lightness of the three primaries, by giving each a coefficient corresponding to how light or dark the human eye perceives it. In video, weighted lightness is commonly referred to as luma.

W3C Method (Working Draft)

w3c

Ex: Pure red would have a W3C lightness of 76 (0.299 normalized).

sRGB Luma (Rec. 709)

709-luma

Ex: Pure red would have a lightness of 54.2 (0.21 normalized).

Using Weighted Euclidean Distance in 3D RGB Space

This method is not official, but it has been reported that it produces better results than the above two:

3d-distance

Ex: Pure red would have a lightness of 125.1 (0.49 normalized).

Tests

In order to determine which of these methods is more reliable, we need to test them with different colors and lightness thresholds, then aggregate the results.

  • Each color will have a subjective, expected outcome (dark or light).
  • If the test result matches the expected outcome, it will be assigned a value of 1. Otherwise it is 0.
  • The higher the score of a method/threshold combination, the more reliable it is.

The tests will be manually run using this online tool made specifically for the purpose.

Results & Conclusion

<figure> Results <figcaption> Plotting the accuracy of the different method/threshold combinations </figcaption> </figure>

Looking at the test results and the chart above, we can make few observations:

  • Weighted methods yield better results than non-weighted methods.
  • In general, the higher the threshold, the more accurate the results.
  • Purples, magentas, and greens yield the most inconsistent results across the different methods.
  • HSB brightness with a .5 threshold yielded the least accurate results.
  • Weighted Euclidean distance (.7) and sRGB luma (.6) performed best within this test.

While there is no method that will be accurate 100% of the time for all the colors in the gamut, using sRGB luma to approximate the perceived color lightness will get decent results for the most common use cases. Otherwise, adjusting the threshold (using the tool mentioned above) or even the per-color coefficients might help improving the outcome.

Here are some example implementations that you can already start using in your own projects.

Junior Dev Ops Award winning company, prestigious country location, near Reading/High Wycombe

Posted about 1 month back at Ruby on Rails, London - The Blog by Dynamic50

Great opportunity for an engineer/developer or design minded technical administrator to work with an award winning and high profile bespoke Ruby on Rails application. Supporting, customising and developing the deployment toolset for the cloud based web apps in a SaaS environment.

Prestigious countryside town location, Oxfordshire near Reading/High Wycombe

Working in small team on award winning web application.

Opportunity to really contribute in an award winning small company.

- Using and developing infrastructure management and application deployment tools for automation and continuous integration of systems and applications.

- Learning Ruby and Shell scripting as well as using script based tools such as Capistrano and Puppet.

- MYSQL management and programming.

- OS and application builds and updates.

- Capacity planning and application deployment

Send your resume to contactus@dynamic50.com or give us a call on 02032862879

Linking up Manchester's data

Posted about 1 month back at RicRoberts :

My helpful screenshot

We’ve recently started work on an new open data initiative called the Greater Manchester Data Synchronisation Programme, (or GMDSP for short). As the name suggests, we’ll be working with authorities in the Manchester area including Manchester City Council, Salford City Council and Trafford Metropolitan Borough Council, who will all publish some similar data sets as Linked Open Data at the same time - that’s the synchronisation bit.

To make this happen we’ll be helping some local code fellows (recruited specifically for this project to work alongside council staff) to convert and publish a selection of datasets to rdf. With our guidance, they’ll model the data and upload it to our PublishMyData platform. In future phases of the project, we plan to build on the work of the code fellows to produce tools and workflows to make the whole process more repeatable.

This project is a collaboration between the Connected Digital Economy Catapult, Future Cities Catapult and Future Everything - the latter we worked with on Nesta’s digital social innovation project over the last year.

As part of their annual festival in Manchester at the end of the month, FutureEverything are organising a hack event (with a £3500 prize fund) focused around the first release of the data. There’s a pre-event at this month’s OpenDataManchester, for propsective participants to meet some of the stakeholders and get advance notification of judging categories.

It’s always great to be involved with others who are also passionate about public sector linked open data. And it’s especially exciting to be working on this Manchester-based project, because it’s where our technical team lay their hats after all.

Episode #447 – March 11th, 2014

Posted about 1 month back at Ruby5

Google's Summer of Code, Test-Driven Rails Part 2, putting the Can in CanCan, building your first Ruby gem, and a Ruby Heroes reminder.

Listen to this episode on Ruby5

Sponsored by Top Ruby Jobs

If you're looking for a top Ruby job or for top Ruby talent, then you should check out Top Ruby Jobs. Top Ruby Jobs is a website dedicated to the best jobs available in the Ruby community.
This episode is sponsored by Top Ruby Jobs

Google Summer of Code: Rails

Rails has been accepted into the Google Summer of Code 2014. The rules state that you have to be at least 18 years old to participate before April 21st, 2014, that you have to be a full or part-time student, and that you have to be passionate about improving Rails. If you’re accepted, you’ll actually be paid $5500 over the course of 3 months to complete your proposed project to improve Rails.
Google Summer of Code: Rails

Test-Driven Rails Part 2

We recently announced part 1 of a blog series by Karol Galanciak called Test-Driven Rails. Part 2 is a continuation of that, describing a popular use case for writing tests: implementing a user registration system. The focus is on writing acceptance tests using Capybara, or in other words making sure the feature works from the user’s perspective. This post is a great illustration of making decisions in your application with test-driven and behavior-driven development.
Test-Driven Rails Part 2

Putting the Can in CanCan

When you need an authorization solution for a Rails app, you might think of CanCan by Ryan Bates. Since Ryan has been taking a break recently, Bryan Rite from MojoLingo forked the gem into a new one called CanCanCan. The gem doesn’t change the CanCan namespace at all so it’s a drop-in replacement except for the Gemfile change. Version 1.7.0 was released recently with strong_parameters support, multiple abilities with associations, and a bunch of overdue bug fixes.
Putting the Can in CanCan

Building Your First Ruby Gem

Building your first Ruby gem may seem like a daunting task, but it's actually not so bad. Matt Huggins has written a step-by-step guide to building your first Ruby gem. There’s even a video tutorial and source code for his examples. If you’re interested in learning how to write a gem, this is the blog post for you.
Building Your First Ruby Gem

Another Ruby Heroes Reminder

Ruby Heroes are being awarded at Rails Conf, which is taking place April 22nd through the 25th. So, now is the time to nominate your unsung heroes who are busy producing educational content, developing plugins and gems, contributing to open-source projects, or putting on events to help developers learn and grow.
Another Ruby Heroes Reminder

Thank You for Listening to Ruby5

Ruby5 is released Tuesday and Friday mornings. To stay informed about and active with this podcast, we encourage you to do one of the following:

Thank You for Listening to Ruby5

Phusion Passenger 4.0.38 released

Posted about 1 month back at Phusion Corporate Blog

Phusion Passenger is a fast and robust web server and application server for Ruby, Python, Node.js and Meteor. Passenger takes a lot of complexity out of deploying web apps, and adds powerful enterprise-grade features that are useful in production. High-profile companies such as Apple, New York Times, AirBnB, Juniper, American Express, etc are already using it, as well as over 350.000 websites.

Phusion Passenger is under constant maintenance and development. Version 4.0.38 is a bugfix release.

Phusion Passenger also has an Enterprise version which comes with a wide array of additional features. By buying Phusion Passenger Enterprise you will directly sponsor the development of the open source version.

Recent changes

  • Fixed a symlink-related security vulnerability.

    Urgency: low
    Scope: local exploit
    Summary: writing files to arbitrary directory by hijacking temp directories
    Affected versions: 4.0.37
    Fixed versions: 4.0.38
    CVE-2014-1832

    Description: This issue is related to CVE-2014-1831 (the security issue as mentioned in the 4.0.37 release notes). The previous fix was incomplete, and still has a (albeit smaller) small attack time window in between two filesystem checks. This attack window is now gone.
  • Added support for the new Ruby 2.1.0 out-of-band garbage collector. This can much improve garbage collection performance, and drastically reduce request times.
  • Passenger Standalone is now compatible with IPv6.
  • Fixed some compilation problems on Solaris. See issue #1047.
  • passenger-install-apache2-module and passenger-install-nginx-module now automatically run in `–auto` mode if stdin is not a TTY. Fixes issue #1030.
  • Fixed an issue with non-bundled Meteor apps not correctly running in production mode.
  • The `PassengerPreStart` option is now compatible with IPv6 server sockets.
  • When running Python WSGI apps, `wsgi.run_once` is now set to False. This should improve the performance of certain apps and frameworks.
  • When handling HTTP requests with chunked transfer encoding, the ‘Transfer-Encoding’ header is no longer passed to the application. This is because the web server already buffers and dechunks the request body.
  • Fixed a possible hang in Phusion Passenger for Nginx when Nginx is instructed to reload or reopen log files. Thanks to Feng Gu, pull request #97.
  • The preferred Nginx version has been upgraded to 1.4.6.
  • Fixed a problem with running passenger-install-apache2-module and passenger-install-nginx-module on JRuby. They were not able to accept any terminal input after displaying the programming language menu.

Installing or upgrading to 4.0.38

OS X OS X Debian Debian Ubuntu Ubuntu
Heroku Heroku Ruby gem Ruby gem Tarball Tarball

Final

Fork us on Github!

Phusion Passenger’s core is open source. Please fork or watch us on Github. :)

<iframe src="http://ghbtns.com/github-btn.html?user=phusion&amp;repo=passenger&amp;type=watch&amp;size=large&amp;count=true" allowtransparency="true" frameborder="0" scrolling="0" width="170" height="30"></iframe><iframe src="http://ghbtns.com/github-btn.html?user=phusion&amp;repo=passenger&amp;type=fork&amp;size=large&amp;count=true" allowtransparency="true" frameborder="0" scrolling="0" width="170" height="30"></iframe><iframe src="http://ghbtns.com/github-btn.html?user=phusion&amp;type=follow&amp;size=large&amp;count=true" allowtransparency="true" frameborder="0" scrolling="0" width="190" height="30"></iframe>

If you would like to stay up to date with Phusion news, please fill in your name and email address below and sign up for our newsletter. We won’t spam you, we promise.



Getting Started with Sass, Bourbon, and Neat with Yeoman

Posted about 1 month back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Yeoman is a toolchain for front-end development utilizing Grunt and Bower to scaffold, develop, and build webapps.

There are official generators maintained by the Yeoman team such as generator-angular for AngularJS and generator-backbone for Backbone.js.

Yeoman also supplies framework specific generators for Backbone and Angular like yo backbone:model Foo. With Yeoman, you can spend more time writing code and less time configuring out of the box.

In this post, we will create a basic Yeoman project, install Sass (without Compass) using Grunt, and set up Bourbon and Neat using Bower.

Creating a Yeoman Webapp project

Start by installing Yeoman.

npm install -g yo

Next, install a Yeoman generator. For this example, I'll be using the Yeoman Webapp Generator:

npm install -g generator-webapp

Create a folder for your project (in this case: yeoman-example), change directory to the folder, then run yo webapp:

$ mkdir yeoman-example
$ cd yeoman-example
$ yo webapp

When prompted, make sure "Sass with Compass" and "Bootstrap" are deselected. We will be adding Sass ourselves using the official grunt-contrib-sass plugin.

The setup should look similar to this:

yo-webapp setup screen

Installing grunt-contrib-sass

Make sure you have Sass installed. You can find out by running sass -v and if it outputs a version number.

$ gem install sass
$ sass -v
Sass 3.2.14 (Media Mark)

Next, install grunt-contrib-sass using the command:

npm install grunt-contrib-sass --save-dev

In the project's app folder, create a new folder called sass. This is where we will put our sass files. Move main.css to app/sass and change the extension to .scss:

$ mkdir app/sass
$ mv app/styles/main.css app/sass/main.scss

Installing Bourbon and Neat using Bower

Install Bourbon and Neat using bower install --save:

bower install --save bourbon
bower install --save neat

This downloads and saves the Bourbon and Neat repositories in the app/bower_components directory.

In main.scss, import bourbon and neat:

// In `app/sass/main.scss`
@import 'bourbon';
@import 'neat';

// Other imports and styles go here

Configuring Sass with Grunt

Next, we'll need to configure our Gruntfile for compiling .scss files. Open Gruntfile.js and update grunt.initConfig to configure what files to compile with Sass.

We will also add an options hash with Bourbon and Neat's stylesheets to the Sass loadPath. By adding these to the loadPath, Sass will see Bourbon and Neat's stylesheets in bower_components/..when we use @import 'bourbon'; and @import 'neat';:

grunt.initConfig({
  // ...
  sass: {
    dist: {
      files: [{
        expand: true,
        cwd: '<%= yeoman.app %>/sass',
        src: ['*.scss'],
        dest: '<%= yeoman.app %>/styles',
        ext: '.css'
      }],

      options: {
        loadPath: [
          '<%= yeoman.app %>/bower_components/bourbon/app/assets/stylesheets',
          '<%= yeoman.app %>/bower_components/neat/app/assets/stylesheets'
        ]
      }
    }
  },
  // ...

We also want the sass task to execute when we run grunt build. You can achieve this by adding sass to the build task:

grunt.registerTask('build', [
 'clean:dist',
 'useminPrepare',
 'sass',
 // ...
]);

Setting up Auto Compile

When you run grunt serve, Grunt will start a server, watch files, and run tasks based on what files are changed.

In Gruntfile.js, update the watch.styles hash in grunt.initConfig to compile .scss files whenever they are changed:

grunt.initConfig({
  // ...
  watch: {
    styles: {
      files: ['<%= yeoman.app %>/sass/{,*/}*.scss'],
      tasks: ['sass', 'newer:copy:styles', 'autoprefixer']
    }
    // ...
  },
  // ...
}

Wrapping up

Your project is now ready to go with Sass, Bourbon, and Neat!

Understanding how to add and configure Sass with Yeoman allows you to use different generators without worrying if they come with the right options for Sass.

Hawk's Snowy Perch

Posted about 1 month back at Mike Clark

Hawk's Snowy Perch

Spectacularly beautiful morning with fresh snow, and this red-tailed hawk was enjoying the powder.

Powder Day

Posted about 1 month back at Mike Clark

Powder Day

Spectacularly beautiful morning with fresh snow, and this red-tailed hawk was enjoying the powder.

Episode #446 - March 7th, 2014

Posted about 1 month back at Ruby5

Running your own CI with Drone and Docker, building web-based RubyMotion apps with Under OS, funding for the Hello Ruby book, rubygems.org operating costs, Rails 4 assets on Heroku, and turning your text on its head with flippit all in this episode of the Ruby5.

Listen to this episode on Ruby5

This episode is sponsored by New Relic

New Relic is _the_ all-in-one web performance analytics product. It lets you manage and monitor web application performance, from the browser down to the line of code. With Real User Monitoring, New Relic users can see browser response times by geographical location of the user, or by browser type.
This episode is sponsored by New Relic

Drone & Docker

Hate Jenkins but want to run your own CI server? This blog post from Jean-Philippe Boily will walk you through setting one up with Drone and Docker!
Drone & Docker

Under OS

Building html based applications for iOS has never been easier thanks to this new platform built on top of RubyMotion.
Under OS

Hello Ruby Book Funded

The Hello Ruby book project was successfully funded on February 22.
Hello Ruby Book Funded

RubyGems.org Costs

Ever wonder how much it costs to run rubygems.org?
RubyGems.org Costs

Rails 4 Assets on Heroku

This article contains information needed to run the asset pipeline in Rails version 4 and above on Heroku.
Rails 4 Assets on Heroku

Flippit

Tired of all your text being rightside-up? The flippit service and gem from Rocketeer Jonathan Jackson makes it easier than ever to turn your world upside down!
Flippit

Printing Ralph

Posted about 1 month back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

I have a 3D printer. It's a lot of work, but is also a lot of fun. It's fun because turning 3D models into actual, tangible objects is just cool. It's work, because it requires a lot of tinkering to get it right. You need to churn out a lot of small objects to make sure the printer is calibrated correcly. The object should be simple enough that you can measure how much you need to tweak for the next print.

I figured early on in my printing career that I'd print something that people would like to have, even if the print quality wasn't perfect. And what's a better thing to print, both in terms of calibration and in terms of being neat to have, than Ralph, thoughtbot's lovable mascot.

A few of the Ralphs I've printed

I've made quite a few so far.

Thing is, Ralph started as an image, not a 3D model. But if we have a few pieces of software (and a 3D printer, of course), we can turn an image like Ralph into solid chunk of plastic.

I used an Open Source vector drawing program called Inkscape to modify a vector image of Ralph that our designers made. But because I didn't want the eyes and brainwaves to fall over, I needed a backing to hold it all together. Once I modified the vector drawing to close up all the gaps, I had all the pieces ready to make the jump into 3D.

The Third Dimension

Taking the front and back vector images and turning them into a 3D object required another program, OpenSCAD. This is an Open Source 3D modeler that builds objects via code, rather than clicking, pushing, and pulling graphically. I imported the vectors and extruded them on top of one another and ended up with the object you can see above. This is an STL file. There are a number of other ways to do this, like using OpenJSCAD or TinkerCad, or directly via Inkscape.

STL files are the standard format for printable 3D models. GitHub can display them and even perform diffs on them, which is really useful if you ever need it. There are also a number of sites like Thingiverse that contain multitudes of objects ready for the printing. Some even come with OpenSCAD source so you can easily modify them to suit your needs.

Here's what Ralph looks like on GitHub's STL viewer:

<script src="https://embed.github.com/view/3d/jyurek/3d/master/Objects/Ralph/ralph-with-backing.stl"></script>

Cutting it up

Once you have a 3D model in STL format, you need to turn it into instructions for the printer to follow. We give it to a program called a slicer, which compiles the 3D model to printer machine code. The program turns the 3D model into horizontal slices that the printer can use to build the object up, layer by layer. I use a program called Slic3r, which is also Open Source and fairly easy to use. These Ralphs were to be printed two at a time, so I scaled down the model and arranged two on the print surface.

Ralphs getting ready to be sliced

All the physical calculations happen during slicing: how fast the nozzle moves, how it gets to every single spot on the layer, how much plastic to put there, what pattern it's going to use to fill everything in, how thick each layer will be, and so on.

The neat thing about this is that, because it just did all these calculations, it knows how much plastic it needs to build the model. These two Ralphs need 4.7 meters of filament (for a total of 31.2 cubic centimeters of PLA plastic).

This is where the vast majority of software tweaking comes in to play, as these variables can make a print look awesome or terrible. Fortunately I've just recalibrated my printer, so I was pretty optimistic that these would look good. Here are a few pictures of some older Ralph prints I made (on the left of each) compared to a print from this batch (on the right):

The difference between an OK print and a pretty good print

And the end result is a plastic Ralph (or 10) that can sit on your desk and cheer you on while you're furiously coding away. 3D printing is still young, but it's a really fun hobby to get into, especially if you're the kind of person who loves to tinker.

Liftoff 1.0

Posted about 1 month back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Way back in January of 2013, we released Liftoff to help developers quickly configure Xcode projects. We used it heavily internally, but felt like it was only solving part of the problem. So we've improved it, and are proud to announce Liftoff 1.0.

Distribution

Earlier versions of Liftoff were distributed as a Ruby gem, but that added some weird overhead to the tool, since it isn't used for Ruby development. For this reason, Liftoff 1.0 is now distributed through Homebrew. We're adding it to our thoughtbot/formulae tap, and all future updates will be done there.

The RubyGems version will stay up, but is deprecated. If you install the Homebrew version, you should make sure to uninstall the RubyGems version to avoid confusion/potential conflicts.

liftoffrc

The next thing that we were able to improve was the way you configure Liftoff itself. Originally, we used command line flags to enable specific configurations (there was no way to selectively disable configurations). This worked fine for us because we never touched these flags. But it made Liftoff extremely rigid and clumsy for people who wanted to configure their projects differently.

I had opened an issue after an internal conversation about possibly using a config file instead of command line options, and after an awesome contribution from @mokagio, we had a viable solution for configuring projects quickly and easily, without increasing overhead for users out of the box.

The liftoffrc file is written in YAML, and works with a 3 stage fallback system on a per-key basis. The lookup order is:

  1. Local (./.liftoffrc)
  2. User (~/.liftoffrc)
  3. Default (<liftoff installation location>/defaults/liftoffrc)

If a key isn't defined at one level, it will fall back to the next level. So you can safely override individual keys without changing the default behavior, or build your own set of defaults at the User level and override those options at the Local level.

Take a look at the default liftoffrc to see what keys are available for customization.

Project Creation

The largest change in Liftoff 1.0 is that you can now use it to create new projects from scratch, as opposed to only being able to use it for configuring existing projects. Now, when you run liftoff in a directory that doesn't contain a project, you'll get a prompt asking you for the project name, the company name, your name, and the prefix. These values will be used to create a directory structure, populate template files, and configure the new project. You can see what the default directory/group structure will look like in the default liftoffrc.

This becomes especially powerful when you consider that since the keys used to generate the new project are defined in liftoffrc, they are easily overridden for your specific needs. You can even pre-define some defaults for the options collected at the command line to speed up the data entry. For example, I'm setting author inside ~/.liftoffrc so that I don't have to enter my name any time I want to create a new project. I'm also setting company: thoughtbot inside ~/Code/thoughtbot/.liftoffrc and company: Gordon Fontenot inside ~/Code/personal/.liftoffrc. Now, projects I create have sensible defaults based on where I'm creating them.

Additionally, you can completely redefine the project structure based on your personal preference, or your employer's requirements. Again, referring to the default liftoffrc, you can see that the directory structure is a simple dictionary. And since the directory structure is mimicked in the group structure (including linking groups to their directory counterparts, which Xcode doesn't do by default), the group structure will match.

We're also creating .gitkeep files in each directory on disk, which is critical, because Xcode is all-too-happy to delete a directory off disk once it sees that there aren't any files left in it. That's a sure-fire way to end up with merge-conflicts in your pbxproj file.

Wrapping up

So that's Liftoff 1.0. We've put a lot of work into this release, and it's been a really great addition to our toolbelt so far. If you have ideas on how to make it even better, [open an issue][liftoff-issues], or even better: submit a pull request. If you're ready to check it out for yourself, install it via Homebrew:

brew tap thoughtbot/formulae
brew install liftoff

What's next?

Arduino Sensor Network

Posted about 1 month back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Previously, we looked at creating a Low Power Custom Arduino Sensor Board for use in a sensor network. Now, let's look at writing the software for our sensor network using that custom board. We will revisit the bathroom occupancy sensor as an example.

Low Power Using Interrupts

Last time we looked at optimizing power by sleeping the Arduino and waking it only when a door's state changed. To do this, we used the pin change interrupt on pins 2 and 3. Unfortunately, we can only monitor change on those pins when the processor is in idle mode which doesn't offer us max power savings. It would be nice to put the processor into its highest power savings mode: deep sleep. In deep sleep, those pins can still use interrupts but instead of interrupting on change, it would interrupt on a single state of HIGH or LOW. To use this type of interrupt we would have to remove the interrupt after it fires and then add it back to trigger on the opposite state every time the processor was woken. This is doable but there is a simpler solution.

The Watchdog Timer (WDT) is a timer that runs on microcontrollers as a safety feature. Its purpose is to notify the processor if a fault or exception occurs. Say for instance, that you have code in the main execution loop that you know takes no more than 100ms to execute. You could set the WDT to interrupt just over 100ms. Then at the end of every execution loop reset the WDT. Now if the WDT interrupt is ever reached, you know that the WDT timed out meaning the code took longer than expected to execute. You can then handle the failure accordingly in the interrupt callback.

We are going to use the WDT a little differently than its intended use. If we set the WDT to interrupt every second, then we can put the processor into deep sleep and it will wake up in second intervals. Every time it wakes up, we can check the doors and transmit their state if it has changed. This may not be ideal for optimal power savings but it doesn't cost much more power and it allows us to have a more general application for sensing and reporting anything. Our Arduino will wakeup every second, check some sensors, and then report their state if they changed. Using this model, we can have the sensor board be more than just a bathroom door detector. It could be placed around the office and report temperature, humidity, brightness, motion, etc.

Let's create a new Arduino project and setup the WDT.

// Import the interrupt library
#include <avr/interrupt.h>

volatile int __watch_dog_timer_flag = 1;

// Define WDT interrupt callback
ISR(WDT_vect)
{
  __watch_dog_timer_flag = 1;
}

void setup()
{
  // Disable processor reset on WDT time-out
  MCUSR &= ~(1<<WDRF);

  // Tell WDT we're going to change its prescaler
  WDTCSR |= (1<<WDCE);

  // Set prescaler to 1 second
  WDTCSR = 1 << WDP1 | 1 << WDP2;

  // Turn on the WDT
  WDTCSR |= (1 << WDIE);
}

void loop()
{
  if (__watch_dog_timer_flag == 1) {
    __watch_dog_timer_flag = 0;
    
    // do things here ...
  }
}

First, we create a flag variable that we use to know which interrupt was fired. We use the volatile keyword to let the compiler know that this variable might change at any time. This is important for variables being modified within interrupt callbacks and the main execution loop. Next, we define the interrupt callback using the ISR, Interrupt Service Routine, function. We tell the ISR which interrupt callback we're defining, WDT_vect is for the Watchdog Timer Interrupt Vector. The only thing we need to do Inside the interrupt callback is set the flag.

Next, we setup the WDT using some register bit manipulation. The MCUSR register is the processor's status register and allows us to reset the processor when the WDT times out. We don't want this to happen so we use the bitwise & operator to set the WDRF, Watchdog Reset Flag, bit to 0. Then, we configure the WDT Control Register, WDTCSR. Setting the WDCE bit tells the processor that we are going to change the timer prescaler. Then, we set the timer prescaler with the WDP1 and WDP2 bits so the WDT will time-out around 1 second. Now, we can enable the WDT by setting the WDIE bit. You can find out more about these registers in the datasheet. Finally, in the execution loop, we check to see if the flag is set, meaning the WDT has triggered. If it has triggered, we reset the flag and execute the application specific code.

Revisiting the bathroom occupancy detector, the sensor board in charge of monitoring the downstairs bathrooms has to sense the input from 2 reed switches on the doors. We will use pins D2 and D3 for the reed switches. We also want to activate the internal pull-up resistor which adds a resistor to power inside the chip. This gives our door pins a default state if the door is not closed.

byte leftDoorStatus = 0;
byte rightDoorStatus = 0;

void setup()
{
  // WDT init ...

  pinMode(2, INPUT);
  digitalWrite(2, HIGH);
  
  pinMode(3, INPUT);
  digitalWrite(3, HIGH);
}

void loop()
{
  if (__watch_dog_timer_flag == 1) {
    __watch_dog_timer_flag = 0;
    
    byte left = digitalRead(2);
  
    if (leftDoorStatus != left) {
      leftDoorStatus = left;
    }

    byte right = digitalRead(3);
    
    if (rightDoorStatus != right) {
      rightDoorStatus = right;
    }
  }
}

Here, we added two global status variables. Then, we set the pins 2 and 3 as INPUT and turn on their internal pull-up resistors using digitalWrite(x, HIGH);. In the loop function, we check and compare the doors' status with the global status. If the status has changed we set the global variable. Now, we can use the nRF24 board to communicate these changes to the hub.

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

// ...

void setup()
{
  // ...

  Mirf.csnPin = 10;
  Mirf.cePin = 9;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"bath1");
  Mirf.payload = 32;
  Mirf.config();
}

Make sure to include the proper libraries. We can download the Mirf library and place it into our Arduino libraries folder. Setup the Mirf by setting the csnPin and cePin, which are on pins 10 and 9 respectively, telling it to use the hardware SPI, setting the address as bath1, and the payload as 32 bytes. Now in the execution loop we can transmit the data when a status has changed.

const String rightDoorID = "E1MLhY2yhH";
const String leftDoorID = "bEOr5qhMHY";

void loop()
{
  if (__watch_dog_timer_flag == 1) {
    __watch_dog_timer_flag = 0;
    
    byte left = digitalRead(2);
  
    if (leftDoorStatus != left) {
      leftDoorStatus = left;
      sendDataWithIDAndStatus(leftDoorID, leftDoorStatus);
    }

    byte right = digitalRead(3);
    
    if (rightDoorStatus != right) {
      rightDoorStatus = right;
      sendDataWithIDAndStatus(rightDoorID, rightDoorStatus);
    }
  }
}

void sendDataWithIDAndStatus(String id, byte status)
{
  byte doorStatus[12];
  id.getBytes(doorStatus, 11);
  doorStatus[11] = status;

  Mirf.setTADDR((byte *)"tbhub");
  Mirf.send(doorStatus);
  while(Mirf.isSending()) ;
  Mirf.powerDown();

  free(doorStatus);
}

First, we add two IDs for our door sensors. These IDs correspond to their respective ID in the cloud storage service we are using to store the data (more on this later). When the status has changed we call sendDataWithIDAndStatus(id, status) which combines the ID and status of the door into a byte array and uses Mirf to transmit the array to the hub, tbhub. We wait for transmission to finish and then tell the Mirf board to sleep.

The last thing we have to do is sleep the processor after the application code has executed.

#include <avr/power.h>
#include <avr/sleep.h>

void loop()
{
  if (__watch_dog_timer_flag == 1) {
    __watch_dog_timer_flag = 0;
    
    // Application code ...

    enterSleepMode();
  }
}

void enterSleepMode()
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();

  sleep_disable();
  power_all_enable();
}

Call enterSleepMode() after our application code in the main loop. This function sets and enables the sleep mode then tells the processor to enter sleep mode with sleep_mode(). When the processor wakes up from the interrupt, code execution begins where it left off, disabling sleep and turning on power for all peripherals.

A Library to Simplify

We have provided an Arduino library that we can use to make this much simpler. Add the thoughtbot directory into the Arduino libraries directory and restart the Arduino software.

The library provides the TBClient class and a wrapper file TBWrapper.

The TBClient class abstracts the communication to the hub. Initialize a client class by calling TBClient client((byte *)"cname", 32);. This will initialize the Mirf software. The first parameter is the name of the client device. This name will be used to receive transmissions meant just for this board. It's very important that this name be 5 characters long or else the wireless library won't work. The second parameter is the size of the transmission payload in bytes. The max is 32 bytes which we set above even though we might not use all that. TBClient also provides a sendData(byte *address, byte *data) function for transmitting. It takes in the 5 character address of the device to transmit to and the byte array of data to transmit.

TBWrapper is a file that wraps the standard Arduino setup() and loop() functions to setup the WDT and put the processor in deep sleep. If we wanted custom sleep and interrupt logic other than what we did above, we could remove this file. Keeping this file will simplify the code so that we can concern ourselves only with our application. With TBWrapper, use clientSetup() and clientLoop() instead of setup() and loop() respectively. Inside clientSetup(), we can setup any pins or modules we need for our sensing application. clientLoop() will be executed about every second when the processor comes out of sleep. In here, we should check our sensors and transmit their data if any have changed.

To use this library, create a new file with the Arduino software. In the menu, under Sketch select Import Library... and pick thoughtbot. Also import the Mirf and SPI libraries. The final code after refactoring the above code to use the libraries will look like this:

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include <MirfSpiDriver.h>

#include <TBClient.h>
#include <TBWrapper.h>

const String rightDoorID = "E1MLhY2yhH";
const String leftDoorID = "bEOr5qhMHY";

TBClient client((byte *) "bath1", 32);

byte leftDoorStatus = 0;
byte rightDoorStatus = 0;

void clientSetup()
{
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);
  
  pinMode(3, INPUT);
  digitalWrite(3, HIGH);
}

void clientLoop()
{
  byte left = digitalRead(2);
  
  if (leftDoorStatus != left) {
    leftDoorStatus = left;
    sendDataWithIDAndStatus(leftDoorID, leftDoorStatus);
  }

  byte right = digitalRead(3);
  
  if (rightDoorStatus != right) {
    rightDoorStatus = right;
    sendDataWithIDAndStatus(rightDoorID, rightDoorStatus);
  }
}

void sendDataWithIDAndStatus(String id, byte status)
{
  byte doorStatus[12];
  id.getBytes(doorStatus, 11);
  doorStatus[11] = status;
  client.sendData((byte *)"tbhub", (byte *)doorStatus);
  free(doorStatus);
}

The Hub

The hub, our Arduino Yún, also has an nRF24 board attached and is receiving the transmissions. It will post the sensor data to an internet service so we can access that data from anywhere. We decided to use Parse as the internet service because of its ease to use and large data capacity for the free tier.

Let's look at how we can receive data from our sensor board and post it to the cloud.

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include <MirfSpiDriver.h>

#include <Bridge.h>
#include <Process.h>

void setup()
{
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  
  Mirf.setRADDR((byte *) "tbhub");
  Mirf.payload = 32;
  
  Mirf.config();
  
  Bridge.begin();
}

Here, we are setting up the Mirf library by giving it the name of our device, tbhub, and the payload size, 32 bytes. The Bridge.begin(); call is setting up the Arduino to be able to talk to the on-board Linux computer. Now we can monitor for received data in the loop() function.

void loop()
{
  if (Mirf.dataReady()) {
    byte data[32];
    Mirf.getData((byte *) &data);
    String id = String((char *)data);
    sendData(id, data[11]);
  }
}

When we receive data, we extract the sensor ID from the first bytes of the string and send it along with the status byte to the Parse API.

void sendData(String id, byte value)
{
  Process curl;
  curl.begin("curl");
  curl.addParameter("-k");
  curl.addParameter("-X");
  curl.addParameter("POST");
  curl.addParameter("-H");
  curl.addParameter("X-Parse-Application-Id:YOUR-APPLICATION-ID");
  curl.addParameter("-H");
  curl.addParameter("X-Parse-REST-API-Key:YOUR-PARSE-API-KEY");
  curl.addParameter("-H");
  curl.addParameter("Content-Type:application/json");
  curl.addParameter("-d");
  
  String data = "{\"sensor\":{\"__type\":\"Pointer\",\"className\":\"Sensor\",\"objectId\":\"";
  data += id;
  data += "\"},\"value\":";
  data += value;
  data += "}";
  
  curl.addParameter(data);
  curl.addParameter("https://api.parse.com/1/classes/SensorValue");
  curl.run();
}

Process is a class available on the Arduino Yún that sends a command to the Linux computer for execution. Unfortunately, the string parameter in the addParameter(String) method, must not contain any spaces, leaving the code to look messy and repetitive. We are using curl to POST the new sensor status to a Parse object called SensorValue. The string identifiers for each door on the sensor board correspond to a Sensor object on Parse. Above, we are creating a new SensorValue object in Parse that points to the appropriate Sensor object.

This code and the code for the client can be found in the GitHub repository.

Conclusion

Now we have the code to make our sensor board run, and with that we can start sensing and reporting anything we can imagine. The hardware and software is all open source, so make a sensor network at your office or home and report back to us with your awesome creations!