P diddy has arrived

My friend and I recently got psyched about the new Makerarm, which is a simple, 3-axis arm. We decided to make our own, and here’s what it looks like so far:

V1.1 Final Render.jpg

2016-01-07 13.41.09.jpg

It’s comprised of mostly 3D printed parts and uses stepper motors for its actuators. David, my friend, is programming this one, so I’m pretty hands off on that. When he gets it up and running (right now it can move, but it can’t do anything interesting) I’ll post a video.

Designed in Solidworks, rendered in Keyshot 5, printed on makerbots at the UMD startup shell.

Final note: he came up with the name

My Delta Robot’s Inverse Kinematics

I basically made Arthur, my delta robot, so that I could play with the fascinatingly complex inverse kinematics equations required to get a delta robot running. In the same way that kinematic equations predict the result of a system, an inverse kinematic equation determines the system based on a desired result. In this case, the desired result is always a coordinate in 3D space, and the system is our delta robot with its lever arms at 3 different angles. The inverse kinematic equation takes in the coordinates and gives us the angles of the arms to reach those coordinates.

Delta Robot aka Arthur moves from Noah Todd on Vimeo.

If you’re interested in understanding how this works, let’s dive in!

Screenshot 2016-01-29 02.47.43

I separated the movement of the delta robot into 3 functions. The first, setLevers() is a simple function that sets the levers (the yellow pieces) to given angles. I’m going to skip over this because it is robot specific and basic.

void setLevers(float f, float l, float r){ //f is front, l is left, r is right
 if (f > 150 || l > 150 || r > 150 || f < 15 || l < 15 || r < 15){
 Serial.println("inputs are out of range for lever arms");
 return; // this checks for invalid inputs
 }
 // TODO: create another indicator that the inputs are invalid
 int fcor = 275; int rcor = 350; int lcor = 375; //fcor = front correction
 long upperLimit = 800; // upper limit ~= 800 = 125 degrees to straight down (((1900)))
 long lowerLimit = 2300;// lower limit ~= 2300 = 35 degrees to straight down (((925 )))
 myservofront.writeMicroseconds((f - 35)*(upperLimit - lowerLimit)/(125-35) + fcor + lowerLimit); // tell servo to go to position in variable 'pos' 
 myservoright.writeMicroseconds((r - 35)*(upperLimit - lowerLimit)/(125-35) + rcor + lowerLimit);
 myservoleft.writeMicroseconds((l - 35)*(upperLimit - lowerLimit)/(125-35) + lcor + lowerLimit);
}

The second function, leverCalc(), is mathematically intense, and this is where the angles of the levers are determined. It takes the coordinates of the desired position (x, y, z) and returns an angle for the lever.

The function starts by defining the lengths of the different linkages (P0,P1,P2,P3, as shown in the picture above) along with some variables.

I did the mathematical calculation for this by simplifying the structure into a 2D system for each arm of the delta. To do this, I also had to account for the lateral movement of the linkage of each arm. To adjust the length of P2 when it is projected onto my 2D plane, I created a new variable mP2 or modified P2. I set this equal to the project length by using pythagorean’s theorem (line 3).

Next, I eliminated P0 and P3 by subtracting and adding them respectively to y. Keep in mind that my 2D plane is the y,z plane, not the x,y plane. Using the new y, I found the hypotenuse (h) of y and z, which is also the length of the third side in the triangle created by segments P1 and mP2.

Finally, I used the law of cosines to find the angle between the hypotenuse and P1. I added that to the arccos of z over the hypotenuse to get theta in radians. At the end, I converted theta to degrees.

float leverCalc(float x, float y, float z){
 float p0 = 75, p1 = 150, p2 = 315, p3 = 50, mp2, h, theta; // refer to picture < picture of linkages > for explanations of names. all units in mm
 mp2 = sqrt( pow(p2,2) - pow(x,2) ); // adjusts the linkage length to compensate for the tilt of the linkages
 y = y + p3 - p0; // p0 is the distance from the base of the lever arm to the center of the lever arms
 // p3 is the distance from the center of the tooltip to the bottom ends of the linkages
 // This whole adjustment makes y (the change in y) the y distance from the base of the levers to the ends of the linkages
 h = sqrt( pow(y,2) + pow(z,2) ); // calculates h. Refer to < picture of linkages >
 theta = atan( y / z ) + acos( ( pow(h,2) + pow(p1,2) - pow(mp2,2) ) / (2*h*p1) );
 theta = theta / PI * 180; // adjust theta to match setLever() parameters
 return theta;
 }

The final function, moveTo, just calls the leverCalc function 3 times and adjusts the coordinates for each lever. Then, it does a quick check to make sure the values are in range. Finally, it sets the levers to the desired coordinates.

void moveTo(float x, float y, float z){
 float front, right, left, p2 = 315; // these are the variables for the lever angles
 front = leverCalc(x, y, z); //calculates lever angle for the front lever
 float ry = -y*sin(PI/6) + x*cos(PI/6); // adjust x, y, and z values for the left lever
 float rx = -y*cos(PI/6) - x*sin(PI/6);
 right = leverCalc(rx, ry, z); //calculates lever angle for the left lever
 float ly = -y*sin(PI/6) - x*cos(PI/6); // adjust x, y, and z values for the right lever
 float lx = y*cos(PI/6) - x*sin(PI/6);
 left = leverCalc(lx, ly, z); //calculates lever angle for the right lever
 // Throws error and prevents movement if the input is out of bounds of the mechanism
 if ( atan(x/p2) > PI/6 || atan(rx/p2) > PI/6 || atan(lx/p2) > PI/6 ){
 Serial.println("out of bounds");
 return;
 }
 setLevers(front, left, right); // sets levers to desired angles
 cx = x; cy = y; cz = z;
 }

The moveTo() function is rather basic, and I made a lineTo function (which is flaunted in the above video) that is much smoother. More on that in a later blog post.

 

Developing the Delta robot

At the end of the spring semester, I stumbled across delta robots, and I immediately fell in love. Many manufacturing lines require extremely fast pick-and-place machines to pack boxes, reorient products, and most importantly, stack pancakes. For a long time, companies used slower robots for this task, but in 1987, Demaurex brought the new delta robot to the manufacturing industry, speeding up manufacturing lines across the globe.

The delta robot is so fast because it displaces all the weight of its motors to the non-moving top of the robot. This lets its tooltip be extremely light. The parallel linkages connecting the little arms to the tooltip keep the tooltip parallel to the ground.

Fanuc’s Various Delta Robots

My journey to making one of my own started when I discovered UMD’s new Makerbot printing lab, which offered incredibly cheap parts. Before this, I was paying around ten times as much for the same part. This let me design most of my parts for the robot and print them cheaply.

I started off by designing an elbow for the delta robot, but after I printed it, I discovered that the makerbot replicators were not up to the task of making acceptable moving parts. I went and bought ball joints and threaded rods for the linkages and went on to design what I call the lever arms.

Delta Robot Arm Versions

Progression of my lever arm design

My first iteration, which is on the left, was disgusting. I designed it quickly in solidworks and sent it over to the makerspace. I got it back, and I was pretty disappointed with the part. All the holes were too small and the moving parts didn’t spin within each other. Furthermore, my design was pretty ugly.

The second iteration was miles ahead of the first. I gave the piece some aesthetic appeal, I gave all the holes and moving parts larger tolerances, and I brought the total material used down drastically. I also reduced the number of pieces by three. However, the mounts for the servo and axle were mediocre and flimsy, and the portion of the lever arm where the ball joints were mounted wasn’t up to my standards.

The third iteration was excellent. I bought some swivel hubs from ServoCity, got all the dimensions just right, and made the whole piece smaller, while keeping the lever arm the same length.

After I knew that I had the lever arm just right, I ordered two more. I also went ahead and designed the base of the Delta robot along with its tooltip.

Screenshot 2015-07-21 17.15.42

I made the base a three-part assembly so that I could add new features and change the mounting stand without having to print a whole new base. I angled the lever arm mounts to change the range of freedom of the lever arms, which I believe will give the tooltip a large range of motion. If it doesn’t, it at least looks nice.

Screenshot 2015-07-21 17.16.07

The tooltip is the bare minimum right now, but it has mounting holes that allow me to add two different pieces to it. In the future, I hope to eventually make a three-axis tooltip attachment (Fanuc’s six-axis Delta Robot)

Delta Robot CAD Image

At the time of this article’s publication, I have ordered / have all the parts in the above picture (besides the exact 80/20 extrusions) and I hope to have all the pieces by this Friday!

Have a good day everybody!

A little update

A few days ago, I noticed that I haven’t written on this blog for six months, which is quite unfortunate. Let me update you on what I’ve been up to.

I got a job! I’m interning at Active Signal Technologies, which is a little company south of Baltimore. Right now, we are gearing up to produce noise immune stethoscopes, which are stethoscopes that medics can use in medical evacuations on helicopters or vehicles. I’m helping out by designing, modeling, and making different parts, jigs, and drawings (I’m using solidworks). The jigs below are used to hold piezoelectric magnets to their mounts while they are glued together in an oven. I just sent out the approved drawings, and I should be getting them soon 🙂Screenshot 2015-07-09 12.03.07 Screenshot 2015-07-09 12.00.27

I was inspired at the end of the semester by the ABB Flexpicker, and now I’m embarking on my own adventure to make a delta robot. The first time that I saw it, I fell in love with the insectoid nature of it along with its extreme efficiency. Determined to make one to play with, I got a little bit of money together, and I’ll be 3D printing most of the parts. I’m currently on design iteration 3, and I’m waiting for the parts to print at the University of Maryland Makerspace. Here’s my current iteration of the arm.

Delta Robot Arm (iteration 3)

Delta Robot Arm (iteration 3)

If you’re familiar with delta robots, you’re probably thinking “heh, this guy’s an idiot. He doesn’t have ball bearings!” I do, they’re just not in the current CAD assembly.

Finally, I just got a suggestion for another Mecanum wheel mount (thanks Sean Forrester from FTC Team 5916!), and I’ll throw that into the Shapeways marketplace in the near future. This one lets you attach Mecanum wheels to .77″ profiles, which are popular in the Servo City extrusion lineup. Here’s a sneak peak:

Mecanum adapter for .77

Mecanum adapter for .77″ Profile (WIP)

I’m doing this in inventor not because I like it, but because I’m just modifying a previous model. I prefer Solidworks to Inventor, although Inventor does have some perks.

Anyways, I’m having fun and loving life! Have a great day everybody!

Just Started Submitting ideas to Quirky!

As a college student, I really don’t have the time or resources to build a bunch of random projects… but that doesn’t mean that I can’t waste away a day designing things in CAD! I discovered Quirky around six months ago, and I’ve been meaning to submit ideas to it, but I never got around to it. So yesterday, bored as hell, I decided to finally open Autodesk Inventor and design some products.

My first idea for quirky is simple and sweet. I came up with it in a meeting where the audience was told to make an invention for ramen noodles (it was a interest meeting for Quest if you’re familiar with UMD). I suggested a solution for determining when the ramen was too hot to eat. I talked about having a small indicator material that turns a certain color when the soup is cool enough to eat. My group ran with the idea and made a colorful presentation. After the presentation with the ukelele, I was interested in pursuing the idea, so my mind ran wild for a few minutes, and I imagined a few different utensils and dishes with incorporated temperature-sensitive materials. I found some temperature-sensitive, color-changing glass on inventables, and I finalized some concept designs in my head. I came up with a few utensils and dishes that had small color-changing glass rods inserted into them for determining when food was too hot to eat. Then, two months later (yesterday), I designed the product to submit it to Quirky.

Link to my product page

Right now, the product is undergoing community evaluations. The community needs to vote it up so that it can be evaluated in an expert review. If you want to help me out, you can go to my product page and give it a thumbs up!

Top shot spoon and info Temp bits demo 2

Right now, the product is undergoing community evaluations. The community needs to vote it up so that it can be evaluated in an expert review. If you want to help me out, you can go to my product page and give it a thumbs up!

New Mecanum Wheel Adapters!

Recently, I’ve gotten quite a few people interested in the VEX mecanum wheel adapters, and many people have also bought the 3D prints from shapeways or the stl files from me. I’m pretty happy about it all 🙂 Anyways, it inspired me to make some new adapters to make them more appealing to everyone. I, of course, decided to reduce the total plastic used to reduce the cost, and I’ve had some great results. With my new adapters, which are in beta right now, I have reduced the cost by 43% down to $39.90 for a full set. I have also added an option to not buy the back clamps, which is only $29.90 (57% reduction in cost from version 1). I’ve also made my parts look super fancy.

I’m still determined to reduce the cost further without sacrificing the structural stability.

Another fun thing that I’ve started doing is making another adapter for the matrix system. This was a request from a team in South Africa called the Creepy Crawlers. I don’t see this part selling much, but the adapter was harder to design, so it was more fun to make. Here’s the part so far:

After I finish these models, I’m going to redesign all the NXT motor and sensor adapters. I’m also going to make them free to the public 🙂

The Oasis Chassis

Oasis 1.0

The Oasis chassis is something that I designed over summer break while I was grieving the loss of FTC (It’s so sad to not have FTC…) Every year we spent too little time designing the chassis, and we would always have some annoying problem with it during the season. With ring it up, we sadly discovered that our omni wheels couldn’t hurdle an object on the playing field. Similarly, before we put mecanum wheels on Sheila, she had a terrible two-wheel drive that would often skid around. So even though I’m not participating in FTC anymore, I decided to go ahead and make a chassis that I liked while I was waiting for college to start.

Screenshot 2014-08-16 12.28.01

My first version just focused on the drivetrain. I wanted a flexible drivetrain that could be easily modified (I designed this before the game release). I used sprockets and chains along with plates with multiple holes for the axles. This way, I could switch around the sprockets for different speeds and I could raise or lower the wheels to get over higher objects.

2014-06-21 09.44.56 copy

After designing the Oasis, I laser-cut pieces of HDF for test plates on the side. I also used my VEX Mecanum Wheel adapters on the Mecanum wheels. I then tested the chassis and developed my mecanum drive and superdrive tasks on it. I’ll talk about these in a later article, or you can just look at them on github.

After making sure that the drivetrain worked well, I designed a second version of the Oasis that incorporated more mounting points and a stronger frame.

As a finishing touch, I added a six-bar lift to demonstrate how easily I could attach more components to the chassis. The 80/20 extrusions on the sides can also be replaced with tetrix c-channels. I never made this version.

VEX Mecanum Wheel Adapters

Now that the new FTC season is heating up, I’m going to do a little advertising for my VEX Mecanum wheel adapters. I developed these guys a few months ago, but I haven’t publicized them much. These pieces make it possible for teams to attach VEX mecanum wheels to tetrix pieces easily and sturdily.

I designed the pieces in 123D design a while ago, and I finalized the design a few months ago. They’ve been on my Oasis chassis (which I haven’t posted about yet) for a long time. They’ve been doing really well, and there hasn’t been a single problem with them. They’ve also been on Shapeways for a long time, and I actually just got my first customer today. You can buy them here

These adapters attach to the wheels using bolts. I usually attach three, but I’m pretty sure that people can get away with just a single bolt. The inserts on the pieces fit very snuggly into the gaps on the wheels, and there is absolutely no wiggle room between the wheels and the adapters. I’ve printed 12 of these pieces on 3 different printers, and all of them fit well. The tetrix axle hubs attach to one of the plates, and the hubs can be secured by 1 to 4 bolts.

Butterfly Knife Model

Hey there, this is my first post since I started college at University of Maryland at College Park. I’m having a good time, and recently, I found a bunch of people that like 3D modeling! (finally) We have started to do weekly modeling/rendering challenges, and this week we are designing knives. I decided to make a balisong, which is the only knife that I actually like. Anyways, I modeled the knife in Inventor 2015 and rendered it with the built-in engine. Enjoy! (oh, and if you have any suggestions or critiques, I would love to hear them)

My Gyro Task for FTC

The gyro is easily one of the most useful sensors in FTC, but it is also really really hard to use, and it has many unexplained nuances. My team has always wanted to use a gyro sensor, but doing that is apparently much harder than just pulling a sensor value every few milliseconds.

My Program on Github

After reading a few example programs and uploading one to our NXT, I found that even the developers at HiTechnic haven’t been able to make the gyros work well. I download Xander’s drivers and sample code, and when I used it, I noticed that the rotation steadily increased, which made the rotation calculations almost useless for anything but quick turns.

I decided to do some experimenting and get to the bottom of this gyro sensor. I was determined to make a task that gave me an accurate representation of my robot’s heading. This would allow my team to have a robot capable of precise turns and outlandish driving functions (including our superdrive task, which I’ll talk about soon).

To start, I made a function that outputted raw values like the base gyro reading, updated gyro readings, the calculated heading, and time elapsed. I learned that the gyro uses a Euler sum to calculate the heading of the robot. Essentially, the gyro readings are a representation of its turning velocity in degrees per second. The gyro sensor also outputs a value around 607 (but not always 607) when held still. When it rotates, that value moves up and down, so the difference between the current reading and the resting reading is what we actually want. Therefore, the theoretical algorithm for finding the heading is:

<Heading> += (<currentReading> – <restReading>) * <timeElapsedSinceLastReading>

When I made a simple program that did this, I noticed a problem that was also present in Xander’s example program: the heading continuously increased. I ran the program a few times, and I noticed a few things. One was that the rest reading kept changing. The other was that when the NXT was in a resting position, gyro readings altered between 607 and 608. I inferred that the rest reading must not be 607 but rather a number between 607 and 608. To compensate for this, instead of using the original initialization routine, I made my own. Mine made an initial value, float initial, and made it a mean value of 100 resting gyro readings. This fixed my problem with the gyro reading.

Making the first rotation reading task was fairly simple. Like I stated above, getting the heading of the robot just involves finding the Euler sum of the gyro readings.

<Heading> += (<currentReading> – <restReading>) * <timeElapsed>

So to do this, I just made the time elapsed always equal to 10 milliseconds and entered in all the other variables, getting the below code, which is placed in a while loop.

rotation += (SensorValue[S4] - initial)*.01;
wait1Msec(10);

This worked when tested in the gyro testing program. However, I doubt the ability for this to work when there are other tasks that take up lots of processing space (actually I know that this won’t work from other people’s experiences). When other tasks work simultaneously with the gyro task, the gyro drastically underestimated its heading. This happens because it was using wait1Msec() instead of using timers. Essentially, instead of waiting 10 milliseconds, it waits 10 milliseconds, then it waits for other tasks to run, and then it runs. So the <timeElapsed> value is not an accurate depiction of the actual time elapsed.

To get the most accurate reading for time elapsed, I rewrote the program to use the time1[] timer, which is a timer that returns readings in milliseconds. Unfortunately, this also times out at around 32.8 seconds. To compensate for this, I just reset the timer every thirty seconds. The timer times out because the NXT’s timer can’t count past 32,767.

The final program is below! This task is also used in our superdrive task (which I’ll talk about later, although it is already on github)

 // Finds average base gyro reading
 for(int i = 0; i < 100; i++){ //sums up first hundred gyro readings
   initial += SensorValue[S4];
   wait10Msec(1);
 }
 initial = initial / 100; //divides by 100 to find the average reading
task heading(){
  ClearTimer(T1); //sets timer to 0
  while(true){
    int currentReading = SensorValue[S4] - initial; //gets the new sensor reading
    rotation += (currentReading) * (time1[T1] - lastTime) * .001; // modifies the header
    lastTime = time1[T1]; //sets the last time for the next reading
    if (time1[T1]>30000){ //this resets the timer after 30 seconds
      ClearTimer(T1);
      lastTime = 0;
    }
    wait10Msec(1); //lets other tasks run
  }
}