tag:blogger.com,1999:blog-26300662024-03-07T03:57:53.336-05:00Adventures of RoyMy adventures in programming.Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.comBlogger116125tag:blogger.com,1999:blog-2630066.post-42123621419956804842015-01-01T18:18:00.003-05:002015-01-01T18:18:50.639-05:00Projects!<div dir="ltr" style="text-align: left;" trbidi="on">
2015 is here already. The older I get, the faster time flies by. I like to reflect on the projects I've done in the past year whenever a new year comes along. 2014 was a busy one.<br />
<br />
First off, my largest project was completed: I finished my Masters degree. That was a major achievement for me and freed up a lot of time. It was a lot of work, but for those that are on the edge, I definitely recommend doing it. With the way the job market is, it's nice to have a little more credentials if I should ever need to find another job.<br />
<br />
I got heavily into RC aircraft in 2014. I went from having a somewhat functioning quadcopter to a fully functioning quadcopter, a mini-quad and 2 RC airplanes. I learned a lot about electronics and radio frequencies throughout the year because of this hobby and will definitely be continuing it into 2015.<br />
<br />
I toyed a lot with my Corvette last year, but ended up trading it in for a Jeep. I've always loved Jeeps and have another project that should arrive in June that requires 4 doors. Jeeps are awesome to tinker with and I've already started with mine. I also wanted to get back into webdesign, so another project I started is <a href="http://www.jeepparking.com/">http://www.jeepparking.com</a>. I'll be posting my development efforts for that at <a href="http://jeepparking.blogspot.com/">http://jeepparking.blogspot.com</a>. I've always wanted to make an image hosting site that focused on vehicles, so what better vehicle than the almighty Jeep.<br />
<br />
2015 should be interesting. Besides having my first kid on the way, I plan on continuing toying with my quads and working on JeepParking. As much as I've wanted to get back into my game development, I simply haven't had the time. Growing up seems to be a big game of priorities and figuring out what gets done when. I'm sure 2015 is going to hold it's own set of lessons for me to learn.</div>
Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com1tag:blogger.com,1999:blog-2630066.post-71328352658177350512014-02-16T20:36:00.000-05:002014-02-16T20:37:11.841-05:00Restart<div dir="ltr" style="text-align: left;" trbidi="on">
For the last few weeks I've been thinking a lot about AstroMiner. I really want to get back into it but a few things hindered me.<br />
<br />
1) AstroMiner was written using XNA. XNA is no longer being supported by Microsoft so any continued development seems like a waste. It was neat at first in that I could play it on my Xbox and my PC but there are other libraries that could help support that.<br />
<br />
2) Multiplayer support. My biggest regret with AstroMiner is not building in multiplayer support from the beginning. Adding it in was a massive rewrite and was a huge, huge hassle.<br />
<br />
3) Time. I started my Masters program and just didn't have time to develop for fun anymore.<br />
<br />
Time is something I'm always going to have issues with. My masters program finishes this summer and I should have a lot more free time once that's done. As for multiplayer and XNA, there's only 1 other option for that: a rewrite. So I've decided to do just that. I'm going to leave C#/XNA and instead switch to C++/SDL. I might give Unity a shot just to see how far it's come but I think I'm going to end up with the same conclusion.<br />
<br />
So nothing to report today.. just set up my environment. I've going to be using CodeBlocks as an IDE since it's free. I debated Visual Studio Express but I think it'd be interesting to try a new IDE. I've also got some great ideas on how to re-architecture so I can be a lot more flexible in the future. C++/SDL should also give me some nice speed increases.<br />
<br />
Hopefully I'll have a better update in the next week. Fortunately for once I have plenty of art and sound before I start the project.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzb5Cwzj3TmbXCG-8go8HO8VfCHQn-4fM0lFQBRaYDPbipjIBdI0h4nrxCDd9mr1Py0-ZCIpdu-wLYXt5b5DpBn1BUbvUqQVj6iWRD84vPxjsNPrN59U5zL8m0hXS_ufTMYw9rzw/s1600/amcpp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzb5Cwzj3TmbXCG-8go8HO8VfCHQn-4fM0lFQBRaYDPbipjIBdI0h4nrxCDd9mr1Py0-ZCIpdu-wLYXt5b5DpBn1BUbvUqQVj6iWRD84vPxjsNPrN59U5zL8m0hXS_ufTMYw9rzw/s1600/amcpp.png" height="216" width="400" /></a></div>
<br />
Until next time..</div>
Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-76384746366141998532013-12-16T01:29:00.000-05:002013-12-16T01:32:30.596-05:00Corvette HUD Horizontal Flip and Display Screens<div dir="ltr" style="text-align: left;" trbidi="on">
Made some good progress today on the HUD. I've added the capability to have multiple screens using individual class files. This means I can have a screen for the track, a screen for the daily drive, a screen for GPS, a screen for music.. and so on. Since I don't want them instantiated more than one time, each screen is a static class. I know that I'm the only one programming this thing so I'm essentially saving myself from myself when I do that. All the screens also inherit from a screen base class that sets some initial parameters.<br />
<br />
I also added the ability to horizontally flip the entire display. This is necessary because once the HUD is installed, it is going to reflect off a mirror onto the windshield. That mirror is going to flip it, so I need to make sure it's reversed before it gets to the mirror. That was an interesting task in itself. I'm not sure that my approach was the best one, but I started by making a Flow Dependency Matrix for the graphics class for the display itself (which was created by Adafruit). <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-rnRLXgOD6aY/Uq6ZQ7txg1I/AAAAAAAAAu8/Un58ZN7JSKo/s1600/IMG_20131216_000918%5B1%5D.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="300" src="http://2.bp.blogspot.com/-rnRLXgOD6aY/Uq6ZQ7txg1I/AAAAAAAAAu8/Un58ZN7JSKo/s400/IMG_20131216_000918%5B1%5D.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Please excuse the bad handwriting.</td></tr>
</tbody></table>
<br />
I needed to combine that with the ST7335 class that inherits the graphics class. The circles in blue are the ST7335 class and the methods it overrides. Once I had that mapped out, I was able to more accurately see who is calling what. This is important because when I use drawCircle(), I am passing in an X and Y coordinate. I need to flip the X coordinate but also make sure that I am not re-flipping it down the line. A good example of this is the fillRoundRect() method. fillRoundRect() draws a rectangle with beveled edges. So one might think that you should flip the X in there, right? Well it really calls the fillRect() method and the fillCircleHelper() method. That means that the X will be re-flipped in fillRect() and throw everything off. By mapping everything in the FDM I was able to trace all the methods and find out who calls what. After taking my time and carefully placing all the flips in their right methods, I can now horizontally flip the screen using a single line of code:<br />
<br />
tft.setHorizontalFlip(<b><span style="color: blue;">true</span></b>, SCREEN_WIDTH);<br />
<br />
<i>tft </i>is the class that draws directly to the screen. <i>setHorizontalFlip() </i>is the method that sets a private <i>boolean </i>variable to whatever is passed in (which in this case is <b><span style="color: blue;">true</span></b>). <i>SCREEN_WIDTH </i>is, well, the display width of the screen. This is what allows me to flip the X. The formula to flip the screen is pretty simple:<br />
<br />
if (shouldHorizontalFlip)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>x = horizontalFlipAmount - x;<br />
<div>
<br /></div>
<i>horizontalFlipAmount </i>is the private variable that is set to <i>SCREEN_WIDTH</i>. Pretty straight forward when inserted into the right spots.<br />
<br />
So I'm at the point where I can build some screens. I have a few concerns about the display right now. When I rented a Camaro with a HUD a few weeks ago, I noticed that you can clearly see the edges of the display. It looked like a screen reflected onto the windshield whereas with my car, there are no edges (because it's not an actual screen, it's more like your old alarm clock display). I want to avoid that if at all possible. The other concern I have is the refresh rate. Similar issue to the Camaro in that you could almost see the lines scanning along the display. That kind of issue will be hard to work on because I need to physically install the HUD in the car. Installing the HUD in the car requires me to take out the entire dashpad which is a long process in it self. I have to do that anyway so I can sniff the serial line so I need to plan a few days where I don't need to use my car so I can take it all apart and play around. An idea I had for a possible fix is to use an OLED screen. I found <a href="http://www.adafruit.com/products/1431">this 1.5" screen</a> on ADAfruit that might work but it's too small. I really need something that's at least 2" due to the width of the display area. I'll have to look around and see if I can find a larger one.<br />
<br />
So that's where I am right now. I'm going to spend the week creating a tachometer display and throw some fake data in there so I can see it animate. Hopefully I can get a good video together showing everything off :]<br />
<br />
Until next time..</div>
Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-923614804751154562013-12-14T17:20:00.002-05:002013-12-14T17:21:19.796-05:00Custom Corvette HUD<div dir="ltr" style="text-align: left;" trbidi="on">
Long story short, I'm creating a new custom heads up display HUD for my car. The car already comes with a HUD but I wanted something more modern looking and I think this project will be a great challenge for me.<br />
<br />
I honestly really love this new project. I love the hardware aspect. I love the software aspect. I love the framework I've built. I think it's going to be seriously awesome when finished. I'm even adding bluetooth support to the HUD so I can adjust options and update the software from my phone. I also have micro-sd card support so I can store images on there and use them as boot up screens. All in all it's going to be awesome and I can't wait to road-test it. <br />
<br />
So let's start with where I am. Last week I got a used GM HUD and took it apart. After examining the whole thing I've come to realize that there is only 1 piece that I really need to replace and that is the circuit board for the display (that's the picture in the post you see above). The entire rest of the unit can stay exactly as-is. Once I knew that, it was time to get to work. I started with the software part. I wanted to get something started before I tried to mount my HUD into the GM HUD. This is my little setup.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm4.staticflickr.com/3809/11349989024_261856c5fa_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://farm4.staticflickr.com/3809/11349989024_261856c5fa_b.jpg" width="240" /></a></div>
<br />
<br />
I'm using an Arduino to control the screen. I only have 32KB of space to work with. I can upgrade to a 256KB unit in the future but I want to see if I can make the core fit in 32KB first. What you can't see in this picture is the micro-sd port on the other side. The red box you see on the screen is actually the usable HUD area. It looks tiny, right? That was one of the most surprising things about the GM HUD. The actual HUD screen is very tiny.<br />
<br />
Once I had that running well enough, I wanted to see if I could get it mounted in the GM HUD. Time to fabricate :]<br />
<br />
Remember that the piece I wanted to replace is the green one in the post above this. I started by taking it all apart so I can re-use some pieces.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm6.staticflickr.com/5501/11372980795_87bff8861f_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://farm6.staticflickr.com/5501/11372980795_87bff8861f_b.jpg" width="320" /></a></div>
<br />
<br />
Next came the shape cutting. It's not perfect but it'll do for now. For the final piece I'll have this 3d-printed.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm3.staticflickr.com/2856/11373104703_d910d560f2_c.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://farm3.staticflickr.com/2856/11373104703_d910d560f2_c.jpg" width="320" /></a></div>
<br />
<br />
Once I got that fixed up, mounting the screen was easy. You can see the micro-sd card in the 2nd picture.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm3.staticflickr.com/2863/11373015684_e7c838389e_c.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://farm3.staticflickr.com/2863/11373015684_e7c838389e_c.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm6.staticflickr.com/5537/11373086403_a5631de8fd_c.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://farm6.staticflickr.com/5537/11373086403_a5631de8fd_c.jpg" width="320" /></a></div>
<br />
<br />
Once that was done, we connect everything.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm8.staticflickr.com/7345/11372985684_003e8c3140_c.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://farm8.staticflickr.com/7345/11372985684_003e8c3140_c.jpg" width="320" /></a></div>
<br />
<br />
.... and voila!<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://farm6.staticflickr.com/5549/11373077413_4e087a3ef8_b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://farm6.staticflickr.com/5549/11373077413_4e087a3ef8_b.jpg" width="320" /></a></div>
<br />
<br />
This will definitely be tweaked before the final version but at least I can now test and play with everything while it's sitting inside an actual HUD unit. The picture is surprisingly clear through all that glass.<br />
<br />
Next step is going to be continuing the software development aspect. Flipping the image left->right will be a pretty simple task. From there I'll start to actually build screens. I'm also going to need to take my dash apart at some point so I can sniff the serial line that feeds into the HUD. I'm crossing my fingers and hoping that it's something I can use to read/request data from the computer. If not I am going to have to run a line down to the ODB II port. If anyone happens to know any software people inside GM that might've worked on the HUD, feel free to send me their contact info :]</div>
Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-91120536535286836032013-10-01T01:37:00.000-04:002013-10-01T01:49:07.510-04:00Quadcopter Flight Controller + Closure on NBF Jeopardy<div dir="ltr" style="text-align: left;" trbidi="on">
Let's start with NBF Jeopardy. First, a video of the semi-final product.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/Qmy-NOp4k7E?feature=player_embedded' frameborder='0'></iframe></div>
<br />
After I created the video, I wanted some status LEDs so I wired them up to the top of the box. Unfortunately I didn't get any great pictures of it, but imagine 3 very bright and large LEDs on top of the black box and you'll get the gist. I'm happy to say that the game went without a hitch. Arduino and game functioned flawlessly and everyone was happy. I did learn a lesson at the end. After I added the LEDs, I modified the code to turn the LEDs on when a contestant won. I uploaded it to the Arduino and ran the test, only to find that nothing worked. The buttons weren't working at all and the game was detecting button presses before they were pressed. I took everything apart, checked wiring, checked button functionality, checked the 'mechanical' press and everything looked like it was right. What the hell could it be? I combed through the code and nothing was changed.. at all. Or so I thought. It turns out that the last time I edited the code, I was toying around and instead of detecting a high position on a switch, I switched it to detecting a low position. Yup. I apparently saved this without reverting it back to the correct status. Yup. 3 hours I spent looking for a hardware problem when at the end of the day, it was a simple HIGH to LOW. It was a good reminder that I should always a) backup my working code and b) if I make a change for toying around, revert before I save.<br />
<br />
So that happened and it wasn't fun, but I got it all sorted out and everything was great. Onto my next project.<br />
<br />
I posted before about my quadcopter. It's a ton of fun to fly around and see how high I can get without crashing. I was using a OpenPilot CC3D flight controller because it's Open Source and fun to tinker with. I also love the ground control software (GCS) and how easy it was to get everything set up. There's a wizard that walks you through every single step from setting up your bird to setting up your controller. Can't beat that. Unfortunately, a few days ago I was flying in some high winds. I'm not sure what happened, but out of nowhere my quad flipped a few times and slammed hard into the ground. It was sad and I should've gotten pictures, but I ended up with 2 broken quad arms, all props were done for and the worst part: a broken cc3d. At first I thought all was well, but then I noticed that channel 1 was no longer receiving input and the cc3d was not able to engage the speed controllers. I tested every component of the quad separately and they all functioned fine. It really was the cc3d.<br />
<br />
So my next step was to research flight controllers. I found several great ones. ArduPilot stood out as my possible next purchase. MultiWii looked awesome as well. Then I remembered the main reason I got into this: I wanted to eventually make my own flight controller. I have an Arduino. I have sensors. Why not try?<br />
<br />
So I got to tinkering. I started by ordering a BMP085 Pressure Sensor (for detecting altitude changes). I also ordered a L3GD20 3-axis Gyro to pair with an accelerometer and detect the angle of the quad. I have the accelerometer and a GPS already, along with an Arduino Uno, Micro, Mega 2560 and who knows what other Arduino. <br />
<br />
So while I waited for the sensors I ordered to come in, I started reading about how I can get input from the receiver. This was much simpler than I thought. First off I tried using pulseIn(). This seemed like the most obvious approach until I realized that pulseIn halts the code until it either a) times out or b) receives input. This is not acceptable for a craft that needs to stay in the air. I then read about interrupts and found the pinChangeInt library. This allowed me to use several pins on the Arduino as inputs from my receiver. There are several approaches to measuring the signal, but the simplest one was getting the time in micro() from when the interrupt was HIGH and subtracting the time from when the interrupt goes LOW. The difference is what I can convert to throttle, stick and switch position. Once I got that squared away, it was time to convert all the stick inputs to something that can control 4 motors.<br />
<br />
<b>I'd like to start off all of this with a disclaimer.</b> I am not an electrical or aeronautical engineer. I just love writing software. There are probably better approaches to what I'm doing, but this is a great lesson for me and I'm going to plow forward and tweak as I go along.<br />
<br />
So for starters, everything has to run on throttle input. One of the issues I found was that the transmitter wasn't exact. With the sticks not doing anything, I would get a variance of -40 to 40 for the input value. I helped solve this by implementing an averaging filter. I also only update the values to the ESC if the average changes by 6. I found this to greatly reduce the "noise" I was getting. Once I got that squared away, it was time to calculate the throttle. Throttle is the foundation of every single future calculation.<br />
<br />
<pre><span class="type" style="color: #ff6633;"> float</span> throttleToUse<span class="operator" style="color: #663300; font-weight: bold;"> = (</span><span class="int" style="color: #999900;">1000</span><span class="operator" style="color: #663300; font-weight: bold;"> *</span> throttlePercent<span class="operator" style="color: #663300; font-weight: bold;">) *</span> THROTTLE_RATE<span class="operator" style="color: #663300; font-weight: bold;">;</span></pre>
<div>
<br /></div>
<div>
Need to use floats because we need some precision. throttlePercent is based off of stick input and THROTTLE_RATE is a constant that can be set to adjust how powerful the stick really is. A rate of 1 is 1:1. .8 smooths things out a little bit and generally the lower you go the less responsive the quad becomes. It's the equivalent of twisting the throttle on a 50cc scooter and a 1000cc superbike. </div>
<div>
<br /></div>
<div>
So now that we have the throttle we want to use, we can adjust the other calculations.</div>
<div>
<br /></div>
<div>
<div>
<pre><span class="type" style="color: #ff6633;"> float</span> rollAmount<span class="operator" style="color: #663300; font-weight: bold;"> = (</span>throttleToUse<span class="operator" style="color: #663300; font-weight: bold;"> *</span> rollPercent<span class="operator" style="color: #663300; font-weight: bold;">) *</span> ROLL_RATE<span class="operator" style="color: #663300; font-weight: bold;">;</span><span class="type" style="color: #ff6633;">
float</span> pitchAmount<span class="operator" style="color: #663300; font-weight: bold;"> = ((</span>throttleToUse<span class="operator" style="color: #663300; font-weight: bold;"> -</span> rollAmount<span class="operator" style="color: #663300; font-weight: bold;">) *</span> pitchPercent<span class="operator" style="color: #663300; font-weight: bold;">) *</span> PITCH_RATE<span class="operator" style="color: #663300; font-weight: bold;">;</span><span class="type" style="color: #ff6633;">
float</span> yawAmount<span class="operator" style="color: #663300; font-weight: bold;"> = ((</span>throttleToUse<span class="operator" style="color: #663300; font-weight: bold;"> -</span> rollAmount<span class="operator" style="color: #663300; font-weight: bold;"> -</span> pitchAmount<span class="operator" style="color: #663300; font-weight: bold;">) *</span> yawPercent<span class="operator" style="color: #663300; font-weight: bold;">) *</span> YAW_RATE<span class="operator" style="color: #663300; font-weight: bold;">;</span></pre>
<pre><span class="operator" style="color: #663300; font-weight: bold;">
</span></pre>
</div>
</div>
<div>
<b>I am not sure if these are right just yet. </b>So far they work in my serial window and the numbers look good. I haven't done a flight test yet to confirm though.</div>
<div>
<br /></div>
<div>
Now that we have that under control, we need to convert these values into something the speed controllers can use. First off, we need to make sure the motors are set up correctly. I'm using the same motor setup that the CC3D uses which is:</div>
<div>
<br /></div>
<div>
Motor 1 = Front Left</div>
<div>
Motor 2 = Front Right</div>
<div>
Motor 3 = Rear Right</div>
<div>
Motor 4 = Rear Left</div>
<div>
<br /></div>
<div>
The motors are defined in a clockwise pattern from the front left. Knowing that, we can use the following to set the motor outputs:</div>
<div>
<br /></div>
<div>
<div>
<pre> motorValues<span class="operator" style="color: #663300; font-weight: bold;">[</span><span class="int" style="color: #999900;">1</span><span class="operator" style="color: #663300; font-weight: bold;">] =</span><span class="int" style="color: #999900;"> 1000</span><span class="operator" style="color: #663300; font-weight: bold;">+(</span>throttleToUse<span class="operator" style="color: #663300; font-weight: bold;"> +</span> rollAmount<span class="operator" style="color: #663300; font-weight: bold;"> -</span> pitchAmount<span class="operator" style="color: #663300; font-weight: bold;"> +</span> yawAmount<span class="operator" style="color: #663300; font-weight: bold;">);</span><span class="comment" style="color: #999999; font-style: italic;"> // cw, front left
</span> motorValues<span class="operator" style="color: #663300; font-weight: bold;">[</span><span class="int" style="color: #999900;">2</span><span class="operator" style="color: #663300; font-weight: bold;">] =</span><span class="int" style="color: #999900;"> 1000</span><span class="operator" style="color: #663300; font-weight: bold;">+(</span>throttleToUse<span class="operator" style="color: #663300; font-weight: bold;"> -</span> rollAmount<span class="operator" style="color: #663300; font-weight: bold;"> -</span> pitchAmount<span class="operator" style="color: #663300; font-weight: bold;"> -</span> yawAmount<span class="operator" style="color: #663300; font-weight: bold;">);</span><span class="comment" style="color: #999999; font-style: italic;"> // ccw, front right
</span> motorValues<span class="operator" style="color: #663300; font-weight: bold;">[</span><span class="int" style="color: #999900;">3</span><span class="operator" style="color: #663300; font-weight: bold;">] =</span><span class="int" style="color: #999900;"> 1000</span><span class="operator" style="color: #663300; font-weight: bold;">+(</span>throttleToUse<span class="operator" style="color: #663300; font-weight: bold;"> -</span> rollAmount<span class="operator" style="color: #663300; font-weight: bold;"> +</span> pitchAmount<span class="operator" style="color: #663300; font-weight: bold;"> +</span> yawAmount<span class="operator" style="color: #663300; font-weight: bold;">);</span><span class="comment" style="color: #999999; font-style: italic;"> // cw, rear right
</span> motorValues<span class="operator" style="color: #663300; font-weight: bold;">[</span><span class="int" style="color: #999900;">4</span><span class="operator" style="color: #663300; font-weight: bold;">] =</span><span class="int" style="color: #999900;"> 1000</span><span class="operator" style="color: #663300; font-weight: bold;">+(</span>throttleToUse<span class="operator" style="color: #663300; font-weight: bold;"> +</span> rollAmount<span class="operator" style="color: #663300; font-weight: bold;"> +</span> pitchAmount<span class="operator" style="color: #663300; font-weight: bold;"> -</span> yawAmount<span class="operator" style="color: #663300; font-weight: bold;">);</span><span class="comment" style="color: #999999; font-style: italic;"> // ccw, rear left</span></pre>
<pre><span class="comment" style="color: #999999; font-style: italic;">
</span></pre>
</div>
</div>
<div>
1000 is the speed controller off position. With the throttle being all the way down, nothing is going to happen. As the throttle increases, the rate of roll, pitch and yaw can be adjusted.</div>
<div>
<br /></div>
<div>
Now that I had this setup (and tested in the serial output), I wanted to add altitude hold. By now my sensors had come in and I have both the gyro and barometer connected through i2c. The Arduino libraries make reading these inputs very, very easy.</div>
<div>
<br /></div>
<div>
For barometer, we just run <i>bmp.readAltitude();</i> to get altitude. I have a mix on my transmitter to allow a 3 position switch on channel 6. Position 0 is normal flight. Position 1 is altitude hold and position 2 is position hold (using GPS). To hold the altitude, I get the current altitude as soon as that switch is put on position 1. Each time I run through the loop, I get the current altitude and find the difference. I then use that difference to calculate whether I need more or less throttle (to go up or down).</div>
<div>
<br /></div>
<div>
So right now, all libraries and my code are 13,634 bytes. This leaves me 18,622 bytes left to finalize everything. I still need to implement position hold and Attitude mode which I'm thinking is going to take me up to ~20,000 bytes. I will do my best to do some optimization at that point and see how low I can get the codesize to be. One of the things I don't like right now is that it's all purely functional. There's no OOP present at all (besides the obvious stuff). This was fine for a prototype, but I want to clean this up for future use.</div>
<div>
<br /></div>
<div>
So with everything running and looking ok in serial mode, I wanted to do a power-on test. I plugged everything in and drew power from the speed controllers. Everything turned on. Then I plugged the speed controller power into the arduino. Things beeped and the Arduino indicated it was ready. I gave my tx a little throttle and the speed controllers burst to life. 5% max. I then adjusted the pitch, roll and yaw and I could hear the motors adjusting accordingly. I killed the power afterwards and considered it a successful first power-on test.</div>
<div>
<br /></div>
<div>
So what's next?</div>
<div>
<br /></div>
<div>
First, I need to fabricate a case for everything. I have a spare proto-shield that I will set up so I can attach the sensors and GPS onto. I'll then attach that onto my UNO and put together some pins for the ESCs (speed controllers) to attach to.</div>
<div>
<br /></div>
<div>
Once that's set up, I'll mount it to my code and have a first flight. I'll start my having it strapped down just to be safe.</div>
<div>
<br /></div>
<div>
After first flight, I'll continue to refine the code more.</div>
<div>
<br /></div>
<div>
Here is a picture of my current setup:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWFz4e9kH3aVa22bPX2hdnNSLlVKEOOSyT_wo9NblLQrP2tM0e2Apvj7KwTnsx6mr_LuxJFu3wYOwkTHPIEsuPH7YmgbIUfetMLh_o_ry3mYhuvHJy3V1v5k8bojfLbXMG7Ayvug/s1600/dx1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWFz4e9kH3aVa22bPX2hdnNSLlVKEOOSyT_wo9NblLQrP2tM0e2Apvj7KwTnsx6mr_LuxJFu3wYOwkTHPIEsuPH7YmgbIUfetMLh_o_ry3mYhuvHJy3V1v5k8bojfLbXMG7Ayvug/s320/dx1.jpg" width="320" /></a></div>
<div>
<br /></div>
<div>
I'm calling this flight controller <i>dx</i>. dx had a successful first power-on test. Within the next couple of weeks, I hope to be able to report that it also had a successful first flight. Until then.. ~</div>
</div>
Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-22525530964035545912013-09-05T00:55:00.003-04:002013-09-05T00:55:30.737-04:00Arduino Jeopardy Part 2<div dir="ltr" style="text-align: left;" trbidi="on">
More progress on my Arduino Jeopardy rig. This is more cosmetic than anything, but I got all the buttons wired up and I'm off the temporary board. I was hoping to host the main control board inside of an Altoids tin, but there are just too many wires so I'm going to pick up a project box from Radio Shack. I also cut up some tupperware we had laying around. I'll be using them as bases for the buttons themselves.<br />
<br />
Nothing programmatically to report. Just cosmetic stuff. I'm hoping to get everything completely done by Friday night. We'll see.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/xpfFKNr6lfQ?feature=player_embedded' frameborder='0'></iframe></div>
<br /></div>
Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-15419145026960549882013-09-03T02:41:00.004-04:002013-09-03T02:41:31.541-04:00Arduino Jeopardy<div dir="ltr" style="text-align: left;" trbidi="on">
My work is having a little offsite and one of the events they want to do is a Jeopardy style game. I thought this'd be a good opportunity to dust off the Arduino and make some fun buzzers. Initially it seems like a pretty simplistic task. You have 4 buttons. 1 button is for the host. This person starts the game and starts each round. The other 3 buttons are for the contestants. Putting it together was straight forward. 4 buttons each feed into their own digital pin. We also have LEDs for each contestant that light up when they're the winners.<br />
<br />
So we haven't done anything complicated yet. I got this part up and running in about 10 minutes. The next part is really the only time it gets complicated. I'll tell you about my very simple solution that I wrote just to get it done and then I'll tell you about my more complicated solution that I'm going to attempt.<br />
<br />
The issue is knowing who buzzed in first. Two people can press the button at the same time with a millisecond of difference in between. My <b>simple approach</b> is to have a random button checked first using a random number. This random number is between 1 and 3. If the number 2 is selected, the system checks buttons 2,3,1 (in that order) to see if they're HIGH. If nothing, we repeat the loop with a new number. The random number generator is seeded with one of the analog inputs which produces static noise when it's not being used, so it's randomish. This works but it still gives an advantage. In the example above, the random number selected is 2. If contestant 3 presses in a millisecond before contestant 2, contestant 2 will still win because it is checked first.<br />
<br />
So I thought of a more <b>complicated approach </b>that I will attempt if I have some time. I need to research interrupts in Arduino and see what it supports. I am using an Arduino 2560 and I believe it has 6 interrupts, so my thought is that I can put each button on an interrupt. In theory this seems like a much simpler approach because we no longer need the random number generator. Just attach each button to an interrupt and when the button is pressed, trigger a method that tells the main game code that "Button X was pressed." If we're in a round, that person wins. If not, move on. In execution, I think this might be a little more complicated but that's mainly because I haven't done any interrupt work with Arduino yet.<br />
<br />
So that's my latest Arduino work. I had to take apart my old Jeeputer that I built to use the Mega 2560 for this project. I'm not sure if I posted about that at all. I'll have to go through and dig up some old notes and videos, but in a nutshell I used the computer to detect the pitch and lean of my jeep so I could make a better decision about how hard I wanted to push up a hill. I also had purchased several relays so I could control certain parts of my jeep with the jeeputer, but I never got around to adding them and I ended up selling the rig. The nice thing about Arduino is it's very easy to quickly prototype something. In the case of the Jeopardy game, I'm not going to bother putting it on an Arduino Pro because it'll be a once and done thing. Here's a quick video showing the wiring and how it all works. I'll make another post later this week when I have the final buttons/lights set up.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/eYOH90FaE58?feature=player_embedded' frameborder='0'></iframe></div>
<br /></div>
Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com1tag:blogger.com,1999:blog-2630066.post-35013212255385419102013-08-23T00:51:00.002-04:002013-08-23T00:52:14.454-04:00Adventures of Flying<div dir="ltr" style="text-align: left;" trbidi="on">
It's been a few months since the last update. After my last post, I ended up moving to Texas for a new job. 5 months after that I started my Masters in Software Engineering. Unfortunately I didn't realize just how much time it would take out of my day. During the summer my course load was a little light, so I decided to pick back up a hobby I had started a few years ago. It is still in line with what I was doing with the robotics, only this one takes place in the air.<br />
<br />
A while back I had an idea to build a drone quadcopter. I knew that jumping into quadcopters and jumping into drones would be a lot of work, so I thought I would start with the simple robotics part. For this new take, I've jumped into the quadcopter part.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/tWngKU0.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="http://i.imgur.com/tWngKU0.jpg" width="320" /></a></div>
<br />
Here is my current quad. It sits on an HJ plastic frame. It takes quite a beating and keeps on ticking. The only time I've broken the frame is when the quad fell from about 60 feet in the air due to a spinner flying off.<br />
<br />
I am currently running 4 9x4.7 props. 4 <a href="http://www.hobbyking.com/hobbyking/store/uh_viewItem.asp?idProduct=39435">NTM Prop Drive Series 28-26A 1200kv / 250w Motors</a> drive the machine. They are attached to 4 <a href="http://www.hobbyking.com/hobbyking/store/uh_viewItem.asp?idProduct=40685">Hobby King 30A ESC 3A UBEC</a> which will soon be flashed to the SimonK firmware. All this is powered by a <a href="http://www.hobbyking.com/hobbyking/store/uh_viewItem.asp?idProduct=14975">Turnigy 2200mAh 3S 25C Lipo Pack</a>.<br />
<br />
This bird flies really well. I've attached a GoPro to the front and it throws the balance off a little (I end up having to shift the battery around to try and make it easier to handle). I had started building my own Flight Controller using an Arduino Mega 2560 when I found the <a href="http://www.openpilot.org/">OpenPilot</a> project. They already had a stable flight controller that is Open Source and comes with Ground Control Software. After getting my hands on one and getting it set up, I realized that re-inventing the wheel just wasn't worth it in this case. I've been studying their code for both the hardware and GCS and plan on working with that instead of rolling my own.<br />
<br />
So far, most of my flights have consisted of me just learning how to control the quad. I have a smaller one that is meant for indoors that I learned on. Fortunately crashing that one is a lot easier to deal with since it was only $40. My plan with this one is to get it stable enough that I can plant some FPV gear on it and fly around. Once I'm used to that, I will start working on the automation part. I have found that I am also pretty late to the game on that, as OpenPilot also has a Revo project which apparently does all this. Nonetheless, it will be fun to implement that and see what I can do with it. I have an idea for my Masters Thesis and Project that involves this quad and another plane in the sky, but I'll leave that for another post. For now, I'll show off some pictures my brother took while he was in town.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://i.imgur.com/EgKbxBu.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="213" src="http://i.imgur.com/EgKbxBu.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Me Flying</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://i.imgur.com/vwDfhIL.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="213" src="http://i.imgur.com/vwDfhIL.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">My Brother Starting to Fly</td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/cQm49dZ.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="http://i.imgur.com/cQm49dZ.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/Q7pk9yj.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="http://i.imgur.com/Q7pk9yj.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/9kKWJjj.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://i.imgur.com/9kKWJjj.jpg" width="213" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Until next time ~</div>
<a href="http://www.blogger.com/"></a><span id="goog_708738572"></span><span id="goog_708738573"></span><br /></div>
Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-77861391388606809512012-02-16T22:38:00.000-05:002012-02-16T22:38:07.478-05:00Where have I been?<div dir="ltr" style="text-align: left;" trbidi="on">Still programming away, of course. I needed a small break though. It's really easy to get burnt out when you're programming 9-5 for work, then come home and program some more. Every once in a while I step back and take some time off to give my brain a break. It also lets me get a feel for what I really want to work on next.<br />
<br />
Since our last post, I created a GPS receiver using some parts from Sparkfun. It was pretty simple to put together and get working. I'd like to continue working on it and turn it into something I can mount on my motorcycle for when I go on trips. <br />
<br />
I also made an all new enclosure for Tankbot. I ordered an Arduino Pro Mini and soldered everything into a permanent enclosure so he can live on forever (or until the plastic rots away).<br />
<br />
Going forward, I think I'd like to split my time between working on AstroMiner and continuing with the Arduino stuff. I rarely talk about my personal life on here, but one thing that I should mention (since it effects my programming time) is that I've taken a new job back out in Texas. This means that I'll be leaving the awesome Kennedy Space Center and moving back out there. That'll happen over the span of the next month, so my development time will be severely limited while I'm in the middle of that. Once I'm done, though, I plan to start right back up where I left off.<br />
<br />
So that's all I have for you now. Until next time ~</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-80807510164107957492012-01-31T00:23:00.002-05:002012-01-31T00:28:14.636-05:00New Chassis Setup and Power Source for Tankbot<div dir="ltr" style="text-align: left;" trbidi="on">One thing I didn't like about the last chassis was how tall it was. There really wasn't much reason for that and I wanted to see if I could lower the Ping sensor. I also didn't like how far back the Ping sensor was, so I also wanted to move it forward. Lastly, I wanted most of the weight of the bot in the center of the tank instead of forward. This was because I wanted to switch power to NiMH battery and I wanted it to be in the center of the bot.<br />
<br />
So, I present to you, Chassis #2:<br />
<br />
<iframe class="imgur-album" width="100%" height="550" frameborder="0" src="http://imgur.com/a/hVMDk/embed"></iframe><br />
</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-42384430367207811302012-01-30T00:03:00.000-05:002012-01-30T00:03:55.835-05:00Tankbot Stage 4<div dir="ltr" style="text-align: left;" trbidi="on"><div class="separator" style="clear: both; text-align: center;"><a href="http://i.imgur.com/zRA1j.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://i.imgur.com/zRA1j.jpg" width="191" /></a></div><br />
Tankie now has a servo on top that rotates the head around. That way I don't have to move the entire thing whenever I want to detect objects. If the bot decides that there isn't ample space to turn where it is, it'll back up ~1 foot and try again. It'll do this indefinitely until it can turn. I should probably add a reverse ping sensor, but that's a bit overkill for this little dude.<br />
<br />
Next on the list is to move the reset button to the top of the bot instead of buried between all the wires. I also want to figure out a better power setup. Right now the Arduino and Ping run on a 9v while the motors and servo are a 4 AAs. This works fine, but whenever the 9v drops below 7v the Arduino's 5v out drops voltage and throws the ping off. I'd like to see if I can fit some kind of battery from an RC car on here and powering them both from it.<br />
<br />
I'm really happy with how this bot performs. These tracks are awesome and the platform is real easy to work with (although a bit tight). In my normal trend, the next "learning" step is transitioning from the Arduino Mega to a smaller Arduino Pro. That'll cut back on a lot of weight and it's something that I'll need to know how to do for future creations.</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-37230057030279796342012-01-29T06:20:00.002-05:002012-01-29T06:31:05.828-05:00Tankbot Stage 3 (with video)<div dir="ltr" style="text-align: left;" trbidi="on">I continued work on the tankbot this week. I wasn't happy with the chassis at all and was thinking of ways I could redo it. I started looking online for examples when I found a premade chassis from the same company that makes the treads. It was only 8 bucks, so I ordered it. I was also having lots of electrical issues. The motors draw lots of power at stall (2A) and this was stressing the Arduino and wasting battery >:[ I found a replacement set that were a real easy replacement (plug and play pretty much), so I ordered them as well.<br />
<br />
Once it all came in, I reluctantly took the old bot apart and got to work. It took me until 5am to get it done, but here she is:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://i.imgur.com/k1sIU.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="http://i.imgur.com/k1sIU.jpg" width="191" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Hey :]</td></tr>
</tbody></table><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://i.imgur.com/0qlNt.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="191" src="http://i.imgur.com/0qlNt.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Side shot.</td></tr>
</tbody></table><div class="separator" style="clear: both; text-align: center;"><a href="http://i.imgur.com/H3Usz.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://i.imgur.com/H3Usz.jpg" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://i.imgur.com/nvIhG.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://i.imgur.com/nvIhG.jpg" width="320" /></a></div><br />
Ok, so lots to talk about. Let's start with the last picture (the one with the two circular looking things). The bot needs to be able to avoid running into things and what you're seeing there is what I use to detect objects. That is the <a href="http://www.parallax.com/Store/Sensors/ObjectDetection/tabid/176/CategoryID/51/List/0/SortField/0/Level/a/ProductID/92/Default.aspx">Parallax Ping))) Ultrasonic Distance Sensor</a>. I got it a long time ago when I was playing with the Parallax Propellor. It was very easy to get running with the Arduino (even easier than with the Propellor), so I've been using it. A couple of weeks ago, I noticed that it would only detect up to 5 1/2 inches away. This thing should have a range of ~9ft, so that didn't make sense. I assumed that I'd just broke it somehow and since I've had it for so long, I'll just make sure that it's always at the very front of the bot. The other night while I was toying with making a plastic front cover, I realized that when there was foam in between the Tx and Rx, it worked like it should. I think that I'm getting some kind of interference between the two. This was a nice and simple fix and it is now back to detecting its normal range.<br />
<br />
My eventual plan is to mount it on a servo, so I can rotate the servo around instead of the whole bot.<br />
<br />
Now let's go to the picture above it. This is the closeup of the side view. You can see my <a href="http://www.sparkfun.com/products/321">Tamiya Tank Treads</a>, dual gearbox and universal plate set (all from Tamiya). I did replace the motors that came with the gearbox with the <a href="http://www.pololu.com/catalog/product/604">Solarbotics RM3</a>. These motors use less power at stall and don't put nearly as much of a strain on the system. This means longer run times :] <br />
<br />
I also added a spring on the middle of the bot. It can get bumpy, so hopefully the spring can take some of the bumps instead of the whole top. You also can't see it in that shot, but I made some plastic spacers for the front of the bot out of <a href="https://www.inventables.com/technologies/hand-moldable-plastic">hand moldable plastic</a>. They provide a full stop and also give the front somewhere to rest. The rear rests directly on top of the gearbox. The base has lots of holes in it, so the motors can still breath through it all.<br />
<br />
That's it for the major parts lists. The Arduino does all of the grunt work. When the robot first gets power, it won't start moving until you press the start button. You then have 3 seconds to get out of the way before it goes. Since it just avoids obstacles and nothing else, there's nothing real fancy to it right now. I did order a GPS chip last week (for a separate project) that I'm going to toy around with using this bot before I put it in it's own project. It'd be neat if I sent the bot waypoints and it went there without hitting anything.<br />
<br />
Anyway, it's 0620 and I need to sleep. Last but not least, here's a video of the bot in action. My dogs are not a big fan of it, so you'll have to excuse their barking.<br />
<br />
Until next time ~<br />
<br />
<a href="http://www.youtube.com/watch?v=JNOn3MLzw2g">http://www.youtube.com/watch?v=JNOn3MLzw2g</a> <br />
<br />
<div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/JNOn3MLzw2g?feature=player_embedded' frameborder='0'></iframe></div><br />
</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com2tag:blogger.com,1999:blog-2630066.post-85222705481357939402012-01-23T01:11:00.000-05:002012-01-23T01:11:56.595-05:00Tankbot Stage 2<div dir="ltr" style="text-align: left;" trbidi="on"><div class="separator" style="clear: both; text-align: center;"><a href="http://i.imgur.com/Ie6qN.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://i.imgur.com/Ie6qN.jpg" width="191" /></a></div><br />
I need to switch the motor gearing to high torque instead of high speed. Also, notice the plastic sides that I made :] Besides the motors being underpowered currently due to the wrong gearing, he works well. My rangefinder is having some issues where it won't detect anything further than 6 inches. I don't feel like spending money on a new one right now and that's enough distance for me to stop the robot in time, so it'll do for now.<br />
<br />
I've found that the best way to mold the plastic while it's warm is to use your hands for the basic shape. Then when it gets to ~100 degrees or so, start using scissors to get what you really want. That's how I was able to make some cleaner edges. I still want to experiment with having a mold and pressing the plastic into it, but that's for the next monster.<br />
<br />
So after I switch the gearing (which means taking the whole robot apart, then taking the whole motor apart, redoing the gearing and putting everything back together), I'm going to order an onboard compass and integrate that. After that, GPS.<br />
<br />
This is fun.</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-52548717404764650402012-01-19T01:29:00.000-05:002012-01-19T01:29:14.288-05:00Tankbot Prototype<div dir="ltr" style="text-align: left;" trbidi="on"><div class="separator" style="clear: both; text-align: left;">So I think this year is going to be more of a hardware year for me. I had a lot of fun with software and I'm still working on AstroMiner (made some good multiplayer updates this week), but this hardware stuff is really fun as well.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">I've been slowly learning different things with the Arduino. Ping sensor. Controlling servos. Controlling motors. Building an opamp. My big end goal is to make some kind of UAV, but I need to take baby steps to get there too.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">I posted about my little robot last week. He's neat, but he doesn't have much traction and that box is super heavy. It's also put together with an Erector set. I wanted to see if I could go to the next stage with him. First thing I did was order tank treads and a dual motor gearbox. That allows me to control each side independently, much like I do with the current bot. Motors are a lot faster than servos though.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Next step was to build a better base. I saw this awesome <a href="https://www.inventables.com/technologies/hand-moldable-plastic">moldable plastic</a> on Inventables and ordered that. I've been toying around with it tonight. You basically heat this stuff up to 140 degrees in water. When you take it out, you can mold it almost instantly. You can continue to mold it until it cools down to ~70 degrees. As it cools off, it gets harder and harder. If you don't like what you've molded, simply reheat and start over.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">The down side is that if it gets too hot, the stuff will remelt. When it comes to prototyping, though, it's pretty hard to beat. That is, unless you have some cardboard.</div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://i.imgur.com/l3eME.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://i.imgur.com/l3eME.jpg" width="191" /></a></div><br />
<div>So that's the basic shape that I'm thinking (minus the obvious lean). The Arduino and motor drivers will fit inside of the bot itself and the batteries can sit up front or along the back. I can throw a little ping sensor on the top with a servo that rotates around.</div><div><br />
</div><div>I'm going to start off with a generic object avoider like the last bot. Once that's done, I'm going to hook him up to a <a href="http://www.hobbyking.com/hobbyking/store/uh_viewItem.asp?idProduct=8992">remote control</a> and make it so I can control him with that. After that, who knows. GPS waypoints?</div><div><br />
</div><div>So that's what I'm working on for the next couple weeks. Next step is to finalize the actual body of the little dude and then make it using the plastic. Once I have a design I like, I'll reinforce it with aluminum or something and go forward from there.</div><div><br />
</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://i.imgur.com/69FOq.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="191" src="http://i.imgur.com/69FOq.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Family Photo :]</td></tr>
</tbody></table><div>Until next time ~</div></div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-69801080411375341512012-01-10T22:09:00.001-05:002012-01-10T22:11:38.912-05:00Arduino + Electret Microphone<div dir="ltr" style="text-align: left;" trbidi="on">Last week, I ordered a whole bunch of <a href="http://www.sparkfun.com/products/8635">Electret microphones from Sparkfun</a>. I thought I could add some cool noise sensors around the rover I've been building. They come in and I start researching how to use them when I realize that I've made quite the mistake. These little microphones are way too weak for the Arduino to read anything from. What I should have purchased was <a href="http://www.sparkfun.com/products/9964">this breakout board</a> since it has a 100x opamp that amplifies the signal for the Arduino. The damage was done though and I wanted to see if there was anything I could do to make these things work.<br />
<br />
After much research online and toying around, I found <a href="http://www.reconnsworld.com/forum/read.php?9,10">this circuit</a> and tried it to see if it would work.<br />
<br />
Here it is on the breadboard:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSjCJEjznZzakIQy2gAtrt7Q3jjlrIaGRvy8Y6SV_BDlC_4EkbshoFJRIhS3T9NXv_Aq2hPsOD4dAHD4vnAjb0ar1zdscOVSC9OWjOEPj_2UStPsrKAsSBQ-9A3zCm6dmUFsJoag/s1600/IMAG0992.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSjCJEjznZzakIQy2gAtrt7Q3jjlrIaGRvy8Y6SV_BDlC_4EkbshoFJRIhS3T9NXv_Aq2hPsOD4dAHD4vnAjb0ar1zdscOVSC9OWjOEPj_2UStPsrKAsSBQ-9A3zCm6dmUFsJoag/s320/IMAG0992.jpg" width="320" /></a></div><br />
When I first set it up, it didn't work and I couldn't figure out why. I then realized that I just didn't have power going to the board. Nice and simple mistake. After fixing that, it seemed to return some value of 850. Trying a different microphone gave me a different start value. I set up my program so that it would get the ambient noise average before it started so I didn't have to worry about setting a value for each microphone. After I got that setup, I simply check if the sound is higher than the ambient noise and flash an LED if it is. That all seemed to work, so I went ahead and created a more portable version of it for my little rover.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwytXEHzVHe9rX-vNvbkBI34lSJ6LMc9mPiPrPtzU_vhlq1gbC2UCL7Nf-XH4L7JcJvnORGHFAEAHghV7GiH8RFHRK6SXdhdhm9AQccpMqSR6JMHd-UQVaVRxwt_7neEHyIMSyLA/s1600/IMAG0997.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwytXEHzVHe9rX-vNvbkBI34lSJ6LMc9mPiPrPtzU_vhlq1gbC2UCL7Nf-XH4L7JcJvnORGHFAEAHghV7GiH8RFHRK6SXdhdhm9AQccpMqSR6JMHd-UQVaVRxwt_7neEHyIMSyLA/s320/IMAG0997.jpg" width="191" /></a></div><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGYl_6V06lh3NV9LxD5N9_mvHu2CsNkGYFOF6pRrINMBt7t_mR0QTJYrVPxYXmp1fRNvfhc7PNOe9vn5dqZMdpDJ_CfYV1S5VzjZZblN1cusLEmBbK6CYnhjiAWsx3j5EHoq6Ccw/s1600/IMAG0998.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGYl_6V06lh3NV9LxD5N9_mvHu2CsNkGYFOF6pRrINMBt7t_mR0QTJYrVPxYXmp1fRNvfhc7PNOe9vn5dqZMdpDJ_CfYV1S5VzjZZblN1cusLEmBbK6CYnhjiAWsx3j5EHoq6Ccw/s320/IMAG0998.jpg" width="191" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The 3 pins are Signal, +5v, Ground.</td></tr>
</tbody></table><br />
Once that was done (and tested to make sure it still worked (it did)), it was Dremel time.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-TephGF3YKFhSt44HG4bQ3KvuZM879hJusEfhC5luYX-aCN-Re2nv7syUMD-hi1hzHaR5gE1oNhFgaxxuMD456wS9SRTMGXaMYmF5-8sum-iefQ1oK6EXJz3yHVOF41oOTcVkBA/s1600/IMAG1000.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-TephGF3YKFhSt44HG4bQ3KvuZM879hJusEfhC5luYX-aCN-Re2nv7syUMD-hi1hzHaR5gE1oNhFgaxxuMD456wS9SRTMGXaMYmF5-8sum-iefQ1oK6EXJz3yHVOF41oOTcVkBA/s320/IMAG1000.jpg" width="191" /></a></div><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqZfWWwb8M_cyi978azzMb3CB90e2mgnoMHW6Q8mD6RRs6trgZMe0I5KU0aMh-fQwtp8j32miAnsepWvFZm9MVIOqyVk7aLhS_K_ke2GwI-9bHTIKxU41r0VBCaUFV-CmvhKLnmQ/s1600/IMAG1001.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqZfWWwb8M_cyi978azzMb3CB90e2mgnoMHW6Q8mD6RRs6trgZMe0I5KU0aMh-fQwtp8j32miAnsepWvFZm9MVIOqyVk7aLhS_K_ke2GwI-9bHTIKxU41r0VBCaUFV-CmvhKLnmQ/s320/IMAG1001.jpg" width="191" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Now you can see why I added 3 pins :]</td></tr>
</tbody></table><br />
All tested and working well. Here's a little video that shows it in action.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/ZHyVWfwPMOs?feature=player_embedded' frameborder='0'></iframe></div><br />
<a href="http://www.youtube.com/watch?v=ZHyVWfwPMOs">http://www.youtube.com/watch?v=ZHyVWfwPMOs</a> <br />
<br />
I still don't think it's quite right. It should have a much larger range than it does, but this will do for now. I can toy with this until I find a better circuit to use or just order the breakout board that Sparkfun sells.</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com3tag:blogger.com,1999:blog-2630066.post-69908056393708323182012-01-10T11:16:00.001-05:002012-01-10T11:17:43.210-05:00Converting NUnit to MSTest<div dir="ltr" style="text-align: left;" trbidi="on">At my normal job, I was recently put in charge of converting our NUnit tests to MSTest. After much researching online and reading lots of posts, here is the method that seemed to work for me. <br />
<ol style="text-align: left;"><li>Remove dll references to NUnit.Core & NUnit.Framework.</li>
<li>Add a reference to Microsoft.VisualStudio.TestTools.UnitTesting.</li>
<li>In the code, find and replace:</li>
<ol><li>using NUnit.Framework; → using Microsoft.VisualStudio.TestTools.UnitTesting;</li>
<li>[TestFixture] → [TestClass]</li>
<li>[Test] → [TestMethod]</li>
<li>[SetUp] → [TestInitialize]</li>
<li>[TearDown] → [TestCleanup]</li>
<li>[TestFixtureSetUp] → [ClassInitialize]</li>
<li>[TestFixtureTearDown] → [ClassCleanup]</li>
<li>(TestFixtureAttribute) → (TestClassAttribute)</li>
<li>(TestFixtureSetUpAttribute) → (TestInitializeAttribute)</li>
<li>(TestFixtureTearDownAttribute) → (TestCleanupAttribute)</li>
<li>(TestAttribute) → (TestMethodAttribute)</li>
</ol><li>Update all of the Assert calls.</li>
<li>The 'hidden' part. In your project file, locate <PropertyGroup> (not the one specifying debug|release settings), and add the following to it under <ProjectGuid>…</ProjectGuid>:</li>
<ol><li><ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids></li>
<li>Do not change the GUID. Visual Studio uses that exact GUID set to identify all Unit Test projects.</li>
</ol><li>In Visual Studio, go to the "Test View" and confirm that your tests are listed.</li>
<li>If needed, change setup()→ public static void setup(TestContext context)</li>
<li>If needed, change teardown()→ public static void teardown()</li>
</ol><div style="text-align: left;">I'm posting this here for historical purposes. UnitTests can come in handy for all kinds of development and Visual Studio's built in testing makes it extremely easy to do. I know I'm guilty of not having many unit tests for my game, but as code becomes more and more mature, unit testing can make sure that we're not doing something we shouldn't. It's also a good way to make sure the build you're about to release to your players isn't going to destroy something vital, like Saved Games or existing map data.</div></div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-9091463310820157752012-01-07T01:58:00.001-05:002012-01-07T01:59:24.593-05:00Another Robot Dealie<div dir="ltr" style="text-align: left;" trbidi="on"><div class="separator" style="clear: both; text-align: center;"><a href="http://i.imgur.com/B2LVW.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://i.imgur.com/B2LVW.jpg" width="191" /></a></div><br />
I'm having too much fun with Arduino.<br />
<br />
This little dude is pretty simplistic. 2 continuous rotation servos in the back control the rear wheels independently. Another standard servo rotates the Ping sensor on top to check for collisions. If an object is found in front, he'll look around for another way out. If there's no way out, he'll back up and check again. I also added a bright white LED up front for fun.<br />
<br />
I built it using one of those Radio Shack project enclosures and a bunch of Erector Set parts. I'll get some video of him driving around soon.<br />
<br />
The catbot would've been fun, but I had a hard time finding an electric water gun that didn't leak. I didn't want to risk burning out my Arduino, so I moved onto the next project. I'll probably use this as a base for my projects for a while. I also ordered some tank tracks and a dual-motor gearbox, so the next robot should be a bit quicker than this little guy :]</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-29834150334864396862012-01-02T02:11:00.000-05:002012-01-02T02:11:27.891-05:00Arduino Catbot<div dir="ltr" style="text-align: left;" trbidi="on"><div class="separator" style="clear: both; text-align: center;"><a href="http://i.imgur.com/aL4jP.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://i.imgur.com/aL4jP.jpg" width="191" /></a></div><br />
We have 3 cats and 3 dogs in our house. Whenever I go to bed, I can hear the little monsters walking around on the counter. This drives me crazy and I wanted to find a solution. What better way to keep cats off the counter than an Arduino?<br />
<br />
First off, I know you can buy something to easily solve this problem. That's not nearly as fun though.<br />
<br />
To start, I picked up the <a href="http://www.parallax.com/Store/Sensors/ObjectDetection/tabid/176/CategoryID/51/List/0/SortField/0/Level/a/ProductID/92/Default.aspx">Parallax Ping Sensor</a>. This thing sends out a sonar wave to detect any object in front of it. It then returns back a measurement that I can convert into inches. I mounted that on top of a 180 degree servo that I spin around. To save power, I only trigger it all when my <a href="http://www.parallax.com/Store/Sensors/ObjectDetection/tabid/176/CategoryID/51/List/0/SortField/0/Level/a/ProductID/793/Default.aspx">motion detector</a> is set off. Since these things will sit on top of the counter, they should only trigger when a cat jumps up.<br />
<br />
The plan is to shoot a water gun at the intruder (cat) until it is gone. I'll be mounting the water gun on top of the servo and ping sensor, so it will always be pointed in the direction of the intruder.<br />
<br />
Once the final design is complete, I'll build 3 or 4 of these things and leave them around the counters. That should teach them not to jump up there. Long term plan is to network them and have them signal eachother so they can work in unison. I think I can keep this simple and use some kind of IR signal. Once that's all working, maybe I can even put one on wheels and have it patrol the kitchen.<br />
<br />
So much to do, so little time.</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-16907172747052556112011-12-14T23:27:00.001-05:002011-12-16T13:26:00.027-05:00A Different Type of Development<div dir="ltr" style="text-align: left;" trbidi="on"><div class="separator" style="clear: both; text-align: center;"><a href="http://i.imgur.com/hPT6d.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="http://i.imgur.com/hPT6d.jpg" width="400" /></a></div><br />
Decided to switch up my development type a little bit. I picked up an Arduino today from Radio Shack and got back into some robotics stuff. I had previously used the Parallax Propeller and had a lot of fun, but recently I had read a lot about the Arduino and it looked really interesting. Radio Shack had a nice setup for ~$80 which I picked up.<br />
<br />
So far I really like it. I was able to get a little robot that I had frankensteined before up and running in it in a few hours. You can see it there in the background. I'm using an <a href="https://docs.google.com/viewer?a=v&q=cache:YwcZPy9WXEIJ:www.ti.com/lit/ds/symlink/sn754410.pdf+&hl=en&gl=us&pid=bl&srcid=ADGEESgz2QfNw9iMGX4c5iIzz2L9_CxZCp53qNAJTBiRjKXSyB2DOWeMKXKk8YtnTYBolAhEmVPtHnXWHnQOu3KUIvyxqbJkJGNF8J3FTA5uS8NK_kwNG_8xhnK1k_wmaHA9XMLrVVwD&sig=AHIEtbSctEmGs5_ThLUopHK5fKO_8bzNhA">H-Bridge (SN75441)</a> to control the rear motor and turning motor. I also have a Parallax Servo up front that moves an <a href="http://www.parallax.com/Store/Sensors/ObjectDetection/tabid/176/CategoryID/51/List/0/SortField/0/Level/a/ProductID/92/Default.aspx">Ultrasonic Distance Sensor</a> around to find the closest object. The little dude will just drive around and find the closest thing. Then drive up to it and stay there.<br />
<br />
It just wants to hug things :]<br />
<br />
This isn't very AstroMiner related, but it is an area I'm interested in. I have a lot of other projects that I don't post much about. I also have a project for my website, <a href="http://www.pwned.com/">http://www.pwned.com</a>, that I need to start and finish soon.<br />
<br />
On the AstroMiner front, I'm fairly certain that I fixed the bug where blocks were changing their drawing locations. For some reason I was pulling in a new block object every single time I added a block to the world. Once I fixed that and only pulled a new block object if the current block is null, the bug seemed to go away. I'll continue to test it to confirm. Next on the list is player inventory and a faster way to save/load worlds.<br />
<br />
I probably won't do as much dev work starting next week due to the holidays. I'll be back full swing come the new year though.</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com1tag:blogger.com,1999:blog-2630066.post-53950950706549623042011-12-11T23:57:00.002-05:002011-12-16T13:27:50.373-05:00Development Screenshot<div dir="ltr" style="text-align: left;" trbidi="on">Just thought I'd show you what 95% of my dev time looks look.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixYlM_QcJsMgwap0UUWUlF5MNkFg849x1xhP3yHH42FFDATVqXuIJO_d2XGxvuPGpftKicxOk8T4dAj-touKWvO6joLkR-wafM_ONYBTSQ891pP_pUwthMr_KXTMxH-745_CM4iw/s1600/dev.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixYlM_QcJsMgwap0UUWUlF5MNkFg849x1xhP3yHH42FFDATVqXuIJO_d2XGxvuPGpftKicxOk8T4dAj-touKWvO6joLkR-wafM_ONYBTSQ891pP_pUwthMr_KXTMxH-745_CM4iw/s400/dev.png" width="400" /></a></div><br />
I'm currently trying to fix a bug where some blocks are getting their positions crossed and drawing themselves in the wrong locations. This was introduced during the multiplayer addition. I'm not sure if it's on the client or the server where the block is being corrupted.<br />
<br />
You can see the server running in the background there as well. It's not as pretty to look at.</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-24037589621094196162011-12-11T02:44:00.000-05:002011-12-16T13:24:28.989-05:00Tonight's Multiplayer Progress<div dir="ltr" style="text-align: left;" trbidi="on">Block deletion/addition has been fixed and is now working. I've removed almost all of the client-side detection for this. The client tells the server that it is eating and that's it. The server tracks how much health the block has and decides when the block is considered 'destroyed'. When it is, the server sends the client a message saying "destroy this block" and the client does it. The server now also tells the client when to add floating items (the little boxes you see when you eat a block). The client's job is to tell the server that the player's bounding box has intersected with the floater and that the player wants to take it.<br />
<br />
When it comes to multiple players, it's going to come down to whose call makes it to the server first.<br />
<br />
So anyway, lots of rambling there. That's what I worked on all night. Next on the list is player inventory. That should all be managed by the server as well. Once that's done, I'm going to start saving the player's position on the map so when they exit, they come back to the right spot. Then I'm going to start saving the map itself. Fun stuff.<br />
<br />
I miss the whole creative side of this game. I miss adding a structure and functionality to it and seeing how it interacts. I miss toying with the AI, or even just coming up with new AI ideas. I know this part has to be done and when it gets done it'll be well worth it, but I sure do miss all the other parts.</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-52427326999481059622011-12-10T03:26:00.000-05:002011-12-16T13:24:28.990-05:00Multiplayer Updates and Protobuf Usage<div dir="ltr" style="text-align: left;" trbidi="on">Today I started the "no-going-back" multiplayer conversion for AstroMiner. While I do have many backups and I could theoretically go back to day one, I am considering this the point of no return.<br />
<br />
As I mentioned before, a lot of code has to be changed to allow multiplayer support. I could hack it in and make it so it's not nearly as much effort, but that runs the risk of future hassles whenever I add new features. There would be redundant code running on both client and server that wouldn't need to be run. How do I know which results to trust? Server or client? What if my client disagrees with someone else's? These are all questions that I asked myself when I decided to make this conversion. If you want more detail, read my blog post from a few days ago that describes my model for multiplayer.<br />
<br />
So today I started removing code from the client. When the game launches, the server is also launched silently in the background. The client no longer saves or loads maps. That's all handled by the server now. When you start a new map, you actually send a command to the server telling it "load this map" or "start a new map with this seed". The server then does its business and sends another packet back telling you it's done. At that point, the client says "give me all the updates around my position". This was the tricky part.<br />
<br />
Gathering the updates wasn't hard. Building a container class for them to be transported wasn't hard. What was hard is figuring out a solid way to transport them without taking so much space. I toyed around with several serializers. XMLSerializer was slow and took up a lot of space. BinaryFormatter was fast, but it can't handle Vector2's. I tried some custom libraries, such as the <a href="http://www.sharpserializer.com/">Sharp Serializer</a>. This is an awesome little library and would've worked, except it was giving me issues with Vector2's as well. Vector2 is an XNA format and I can't modify it, so I needed something that would let me define my own custom serialization types. Google's Protobuf came to the rescue. More specifically, <a href="https://plus.google.com/116555933118280731127/posts">Marc Gravell</a>'s <a href="http://marcgravell.blogspot.com/2011/05/protobuf-net-v2-beta.html">Mono Implementation</a>. This not only lets me define custom types, it is extremely fast when it serializes and extremely compact. For the sake of internet searches, I'm going to post my code to serialize an XNA Vector2:<br />
<br />
First, you want to declare a <b>RuntimeTypeModel:</b><br />
<br />
<pre style="background-attachment: initial; background-clip: initial; background-color: #f0f0f0; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: rgb(204, 204, 204); border-bottom-style: dashed; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: dashed; border-top-width: 1px; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow-x: auto; overflow-y: auto; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 99%;"><code style="word-wrap: normal;"> <b style="color: black;">private static</b> <span class="Apple-style-span" style="color: #6aa84f;"><b>RuntimeTypeModel</b> </span>serialize;
</code></pre><br />
Then in your initializer, you need to instantiate this model with all of your custom classes. Mine looks like this:<br />
<br />
<pre style="background-attachment: initial; background-clip: initial; background-color: #f0f0f0; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: rgb(204, 204, 204); border-bottom-style: dashed; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: dashed; border-top-width: 1px; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow-x: auto; overflow-y: auto; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 99%;"><code style="word-wrap: normal;"> <b><span class="Apple-style-span" style="color: #3d85c6;">public</span> </b>netManager()
{
serialize = <b><span class="Apple-style-span" style="color: #6aa84f;">RuntimeTypeModel</span></b>.Create();
serialize.Add(<b><span class="Apple-style-span" style="color: #3d85c6;">typeof</span></b>(<b><span class="Apple-style-span" style="color: #6aa84f;">Vector2</span></b>), <b><span class="Apple-style-span" style="color: #3d85c6;">false</span></b>).Add(<span class="Apple-style-span" style="color: #cc0000;">"X"</span>, <span class="Apple-style-span" style="color: #cc0000;">"Y"</span>);
serialize.Add(<b><span class="Apple-style-span" style="color: #3d85c6;">typeof</span></b>(<b><span class="Apple-style-span" style="color: #6aa84f;">chunkUpdate</span></b>), <b><span class="Apple-style-span" style="color: #3d85c6;">true</span></b>);
serialize.Add(<b><span class="Apple-style-span" style="color: #3d85c6;">typeof</span></b>(<b><span class="Apple-style-span" style="color: #6aa84f;">change</span></b>), <b><span class="Apple-style-span" style="color: #3d85c6;">true</span></b>);
serialize.Add(<b><span class="Apple-style-span" style="color: #3d85c6;">typeof</span></b>(<b><span class="Apple-style-span" style="color: #6aa84f;">block</span></b>), <b><span class="Apple-style-span" style="color: #3d85c6;">true</span></b>);
serialize.Add(<b><span class="Apple-style-span" style="color: #3d85c6;">typeof</span></b>(<b><span class="Apple-style-span" style="color: #6aa84f;">Rectangle</span></b>), <b><span class="Apple-style-span" style="color: #3d85c6;">true</span></b>);
</code></pre><br />
By the way, I did all the coloring by hand. You're welcome.<br />
<br />
Ok so to explain that, I'm creating a model so Protobuf knows how to serialize my object. For Vector2's, I'm telling it I only need the .X and .Y values. For all my custom classes (chunkUpdate, change, block), I'm telling it to figure it out on its own. It's also reading XNA's Rectangle on its own. I'm willing to bet it can read Vector2 on its own, but I haven't tested it.<br />
<br />
Anyway, once that's all fancy and done, I simple serialize like so:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxgpUNJM33pzAmeLZJY6RqH0JovX_5F6kAtQYwUyH7gEsI7KM0DNSnR_T-o_fgKXYpIIDtmY-fFjBmcJYPLrtLdf_InSlIF2uPJ7mKIyZBnTCygVRZZgNOVucPzEs1cgXXabNN6g/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> serialize.Serialize(fullPacketStream, cu);
</code></pre><br />
fullPacketStream is a MemoryStream and cu is my chunkUpdate object that I'm serializing. I turn then fullPacketStream into a byte array and send it off on its journey to the client. When the packet is received, I deserialize like so:<br />
<br />
<pre style="background-attachment: initial; background-clip: initial; background-color: #f0f0f0; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: rgb(204, 204, 204); border-bottom-style: dashed; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: dashed; border-top-width: 1px; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow-x: auto; overflow-y: auto; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> serialize.Deserialize(chunkUpdateMemoryStream, chunkUpdateInput, </code><code style="word-wrap: normal;"><b><span class="Apple-style-span" style="color: #3d85c6;">typeof</span></b></code><code style="word-wrap: normal;">(<b><span class="Apple-style-span" style="color: #6aa84f;">chunkUpdate</span></b>));
</code></pre><br />
I now have an intact chunkUpdate class that contains all of the updates for a given chunk of data.<br />
<br />
I spent most of the evening learning about protobuf and getting this to work. I think that by tomorrow night, I should be at the point where I can create a new map or load an existing one. The map will be able to save itself to desk when the server is done with it and the player will be able to travel all throughout the asteroid field and have data being streamed to them on demand. (I just jumped from first person to third)<br />
<br />
Anyway, no screenshots to show because it's all just code :[ I will hopefully have something tomorrow though when I get the full streaming set up.<br />
<br />
Until then ~</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com1tag:blogger.com,1999:blog-2630066.post-60112254175355690362011-12-08T22:43:00.001-05:002011-12-16T13:24:28.990-05:00Successful Multiplayer Test<div dir="ltr" style="text-align: left;" trbidi="on">Just wanted to report that I've had a successful early multiplayer test. I logged into the server with my local machine. I then used tethering through my phone to have my other computer logged into my server through my remote IP. Lastly, a friend of mine logged in from his computer.<br />
<br />
Lag was very minimal (I actually didn't notice any, but I'm local). We flew around. He deleted 2 blocks and I saw it on my screen. Overall, a successful test :]<br />
<br />
One thing I haven't addressed is world syncing. He came into a world that was different than mine. When the player comes onto a server, they'll need to be updated with all the changes/structures before they can start playing.<br />
<br />
I'm currently on the 2nd milestone. I've decided that generating the world is going to be left on the client side. I think it would be too much work for the server to constantly generate asteroid locations around every single player connected. Instead, I have several hashing techniques in mind so I can make sure that all the player worlds are similar.<br />
<br />
Adding/deleting blocks has been completed. I have the packet builder complete and I've been utilizing it. I've decided that the floatingItems can stay on the client side.<br />
<br />
Next thing I have on the list is to sync up the worlds between players. After that, syncing up player inventory and passing in more player information. You currently can see a player standing on a block and the block being slowly eaten, but you can't tell the player is drilling. You can't see the thrust that the player is using. All that needs to be sent to the server.<br />
<br />
After all that, I'm going to actually add bullets before the next milestone. That will leave adding structures as the only player interaction left.<br />
<br />
Anyway, I'm progressing well :] This is actually more fun than I thought it would be, heh.<br />
<br />
Until next time ~</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-854858967280999422011-12-06T23:57:00.007-05:002011-12-16T13:24:28.990-05:00Multiplayer Milestones and A Summary of the Past Year<div dir="ltr" style="text-align: left;" trbidi="on">I started coding today by jumping straight into multiplayer. I added support for structures, multiple players, AI and the environment when I realized I'm doing this all wrong. I need to stop and rebuild from the ground up.<br />
<br />
So I've come up with a plan.<br />
<br />
I have my base server. It currently compiles fine, but most of the sections where I'm checking for player collision are commented out because they currently only support 1 player. I need to add multiple player support for those, but that's for later. For now, I have my base server with all of the AstroMiner objects and classes built in and compiling.<br />
<br />
Next on the list is the world. Generating asteroids, for starters. This will be done on the fly, like it currently is, and the player should be able to fly around in an infinite world, like they can currently do. This also means I will be adding support for multiplayer player movement, light support (which I'm going to calculate client side) and some other things.<br />
<br />
Once that milestone is passed, I will move onto adding/deleting blocks. This will force me to build out a changesManager that can dynamically update from any source and report what changes it has so I can build an efficient packet to send. We obviously don't want to send all the changes all the time. We only want to send updates. These kinds of updates are important, so they will require some validation on the client end telling the server that they received the update. This will also require me to sync up the player's inventory (and now that I think about it, the floating items manager (the little blocks that drop when you eat a block) will have to be working here).<br />
<br />
At that point, I should be able to have multiple players log into the same server, delete and change blocks and have them see eachother's updates. That will be a major milestone because I will have collision detection for multiple players done, an efficient packet packing algorithm and a streaming server-side world that can save itself to the file system.<br />
<br />
Next on the list is environment. This will be game night/day sequence, gravity for any objects that register for it and water. This one will be easy because it's pretty much already done, but nonetheless it's on the list to be reviewed and updated.<br />
<br />
After that, structures. I believe this will be one of the hardest to implement and that's why I've saved it for the very end. Lots of objects check to see if the player is near them to activate. I can do a foreach() on every logged-in player and check, but that seems horribly inefficient. In order for this milestone to be complete, the player should be able craft an object (this will be validated client and server-side), place and remove it from the world. The structures should all run their normal update() routines.<br />
<br />
The next, and definitely hardest out of the bunch, will be the AI manager. 90% of the AI manager will have no problems and will be a seamless transition. 10% will be very complicated. That last 10% is enemy movement and player collision detection. There could be hundreds of enemies in the world and all of them need to check for player collision. They also need to detect if they're near a player and if they are, go towards that player. A foreach loop would also work here, but again - very inefficient.<br />
<br />
So that's my multiplayer roadmap. My goal is to have this done by the end of the month. That's my goal because I'm going home to see my brother before he ships off to the Navy and I'd like to play multiplayer with him there before he goes. I have a feeling that once I get started and figure out the fundamentals of how this server should be laid out, the rest is going to fly by quickly.<br />
<br />
I still don't have a 100% solid idea of how I want the client to interpret the data. I have an idea of how I want to efficiently build packets and how each player will have their own custom packet. Sending it is already done. How the client will interpret that packet and use it to update the world, though, is still a little foggy.<br />
<br />
So anyway, that's my plan. I feel like this is a whole new chapter in my game development saga. <br />
<div class="separator" style="clear: both; text-align: left;"></div><br />
- The First Chapter was just getting started. Learning about Unity, 3d and the different engines/languages I can use.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-9MSIvBENnLIB46ZBYJLvYMUHZjxiJUBHtrDBuJ32FcX6Jg8yrGhfQQngbhMqESR7XBNvl-u5xMcE7oq7ZVhGyBTFuPgm4WEAOkco-HxTGjO_Vx68dhP4V1ohc0GTc-PqPE1jiA/s1600/R22.70818.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-9MSIvBENnLIB46ZBYJLvYMUHZjxiJUBHtrDBuJ32FcX6Jg8yrGhfQQngbhMqESR7XBNvl-u5xMcE7oq7ZVhGyBTFuPgm4WEAOkco-HxTGjO_Vx68dhP4V1ohc0GTc-PqPE1jiA/s200/R22.70818.png" width="200" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtkK01Z1FNiS2YhswTzca9o0bY5p2B-4Wr3o8gSXLfD6wzfnr7-CpN_GZV3M_-lzMXOlTDG4IKfYOSV5P-GD5P8XZQcxRi_dVkArmk9LsjNlAc7NkG3himI7t2pEjyTXjMWFMTMw/s1600/ss.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtkK01Z1FNiS2YhswTzca9o0bY5p2B-4Wr3o8gSXLfD6wzfnr7-CpN_GZV3M_-lzMXOlTDG4IKfYOSV5P-GD5P8XZQcxRi_dVkArmk9LsjNlAc7NkG3himI7t2pEjyTXjMWFMTMw/s200/ss.png" width="200" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm6-yxbniepK4QWLgy_tjfUP1Oy12nODoHd9TUWAFaweDSwj5ogJcR6YKoW-27sAmOTUAfRx421F6aMcAT0OZOCZLnBhBjeBUbNcg4JAGG-UDihsopgwQRileqyU3vtipIM0yO9w/s1600/R27.06614.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm6-yxbniepK4QWLgy_tjfUP1Oy12nODoHd9TUWAFaweDSwj5ogJcR6YKoW-27sAmOTUAfRx421F6aMcAT0OZOCZLnBhBjeBUbNcg4JAGG-UDihsopgwQRileqyU3vtipIM0yO9w/s200/R27.06614.png" width="200" /></a></div><br />
- The Second Chapter was my Minecraft clone. I learned about algorithms, heavy 3d triangle strips and efficient ways of rendering millions of cubes, player input and writing very efficient code. Object pools and utilizing floats efficiently. Using the Garbage Collector as little as possible.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZzepuO8UCM5e7mbG-dzkEgha1OudgP_g7FyTjPQGqeNAMtZzZGAr1UX3U4J-VoI-trzOylNT4XWoVBf98siYbb31cQ5LB_G8EwzFeQ-rAv7EE3ZoImh2BXLc_B8_2oJjZpcfiFg/s1600/xna3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZzepuO8UCM5e7mbG-dzkEgha1OudgP_g7FyTjPQGqeNAMtZzZGAr1UX3U4J-VoI-trzOylNT4XWoVBf98siYbb31cQ5LB_G8EwzFeQ-rAv7EE3ZoImh2BXLc_B8_2oJjZpcfiFg/s200/xna3.png" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxzhGriXp0ynj2ZkL1_MbhDWNvR4q4vCe-d4S_kY0tQkoCDuP4Hhwbecqidg5PffiB9d0eRBJd78PnsbPLdFVgamJirjtM5S2CjXjyIEMNy_wu_mB0kffLgCTzLyFTdbDA_PrsYw/s1600/01a-7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxzhGriXp0ynj2ZkL1_MbhDWNvR4q4vCe-d4S_kY0tQkoCDuP4Hhwbecqidg5PffiB9d0eRBJd78PnsbPLdFVgamJirjtM5S2CjXjyIEMNy_wu_mB0kffLgCTzLyFTdbDA_PrsYw/s200/01a-7.png" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-RRaZ2WcOsuJ5hGd9Xt6xhes5D0790tFnj6s0OS_FpMGmJeI5uI2s1Th0DS-E44OygtHP4gs2JVnydTK4H9zBOPrc1YbbtedtG2mzM4sg53fVr0Zh2r1Qz9GRZHVMrgu3xccaYw/s1600/2011-04-29_02-21-01-AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-RRaZ2WcOsuJ5hGd9Xt6xhes5D0790tFnj6s0OS_FpMGmJeI5uI2s1Th0DS-E44OygtHP4gs2JVnydTK4H9zBOPrc1YbbtedtG2mzM4sg53fVr0Zh2r1Qz9GRZHVMrgu3xccaYw/s200/2011-04-29_02-21-01-AM.png" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTbpeKYHTx4Ul9w8Grbh7s7SmIFJCQAZwmoyTIKd-cKEx9scFP_oeR4faUILBzLQKJAd2-4_CCQustY1jvFEkKhyphenhyphenjB9CfpmG46LwYg4MRc3IrCwyTwxzSfofIDJzu2M__8i7DBbQ/s1600/2011-05-06_09-12-35-PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTbpeKYHTx4Ul9w8Grbh7s7SmIFJCQAZwmoyTIKd-cKEx9scFP_oeR4faUILBzLQKJAd2-4_CCQustY1jvFEkKhyphenhyphenjB9CfpmG46LwYg4MRc3IrCwyTwxzSfofIDJzu2M__8i7DBbQ/s200/2011-05-06_09-12-35-PM.png" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5IOz8dp7I25IQWAYFQBVoBa0ilu_-VoD30OmE7nkg8S7_L2_rdPfVLhg1-Qm1vQYSBIJkYcqZWnHVO_QU-TW9aRZzXXuJgEOhNpBaCV5lbvsBsY6o45Q0u5Ru2IKVKa3k5CzZCg/s1600/2011-07-17_11-44-09-AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5IOz8dp7I25IQWAYFQBVoBa0ilu_-VoD30OmE7nkg8S7_L2_rdPfVLhg1-Qm1vQYSBIJkYcqZWnHVO_QU-TW9aRZzXXuJgEOhNpBaCV5lbvsBsY6o45Q0u5Ru2IKVKa3k5CzZCg/s200/2011-07-17_11-44-09-AM.png" width="200" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjZ9SP0D-RBudct0MMNwiMPNhALv2_geKoUKyedudKsNMGE_g-Oj9b21myAutVrgu8rHd8nMUNz0MjUer4la5V9rYz1oTa-RTaOO1s-IRm9lyNjRxz8Ghl1LbpuMK7HaYXYe-jVg/s1600/2011-05-09_12-53-02-AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjZ9SP0D-RBudct0MMNwiMPNhALv2_geKoUKyedudKsNMGE_g-Oj9b21myAutVrgu8rHd8nMUNz0MjUer4la5V9rYz1oTa-RTaOO1s-IRm9lyNjRxz8Ghl1LbpuMK7HaYXYe-jVg/s200/2011-05-09_12-53-02-AM.png" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrNB4SeQfbr6dUoWHAiEzx9NCwQS1WT06MLZCLA6dPxC8ul3Lr-BzosUMUVdCLcTAvvqaF-g8c936sX3Ymb1-e-MYi1ShlyyjDOCEUKIXFwQodPbOXAV4zvlTU6quin1GWWKutEA/s1600/2011-05-19_11-45-00-PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrNB4SeQfbr6dUoWHAiEzx9NCwQS1WT06MLZCLA6dPxC8ul3Lr-BzosUMUVdCLcTAvvqaF-g8c936sX3Ymb1-e-MYi1ShlyyjDOCEUKIXFwQodPbOXAV4zvlTU6quin1GWWKutEA/s200/2011-05-19_11-45-00-PM.png" width="200" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div>- The Third Chapter was the beginnings of AstroMiner. Creating a seamless 2d world. Adding/deleting blocks. Spritesheets.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTod_hLmTmsobNTpNhU2OzCkdpV3dgKB7A2kTGXuN-5m5iOpt0k3L6QL3jrbOsIkeS5vWAzTnWQ27Xc6Dd8Mh_jghcDjzc_JUt4HZ47Qz864GrU6fGfqiPEgiK_xxNKuIFKFrcHw/s1600/oldAstro.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="162" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTod_hLmTmsobNTpNhU2OzCkdpV3dgKB7A2kTGXuN-5m5iOpt0k3L6QL3jrbOsIkeS5vWAzTnWQ27Xc6Dd8Mh_jghcDjzc_JUt4HZ47Qz864GrU6fGfqiPEgiK_xxNKuIFKFrcHw/s200/oldAstro.png" width="200" /></a></div><div><br />
</div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi53j2CtmyAw7uKVeKf1JQdTaGPcptUOiGQywbCucmOwAAM8cqtaFzwXB6AfhyphenhyphenDJoSvmhwale4sAEXvWgtF6ze9dDk8Gauvq3q_xFKNykT4zraw9iAD0efCFCWBms32Rty9lWQ4bg/s1600/2011-08-13_12-20-53-AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi53j2CtmyAw7uKVeKf1JQdTaGPcptUOiGQywbCucmOwAAM8cqtaFzwXB6AfhyphenhyphenDJoSvmhwale4sAEXvWgtF6ze9dDk8Gauvq3q_xFKNykT4zraw9iAD0efCFCWBms32Rty9lWQ4bg/s200/2011-08-13_12-20-53-AM.png" width="200" /></a></div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaCDMy5tQNCfZ-gqrQ7bb-BrJWc5TY8yh4hvaB2LS8_QCG_IcEDNJ-HdRzvHu_sJYqvWT1HtRbPtZmZRlfOYqNs0tt04NvmKAHBBwkex9OrO15yWjNzbpU4j4uBrbfP1pcRFR_Lg/s1600/2011-08-14_08-53-25-PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaCDMy5tQNCfZ-gqrQ7bb-BrJWc5TY8yh4hvaB2LS8_QCG_IcEDNJ-HdRzvHu_sJYqvWT1HtRbPtZmZRlfOYqNs0tt04NvmKAHBBwkex9OrO15yWjNzbpU4j4uBrbfP1pcRFR_Lg/s200/2011-08-14_08-53-25-PM.png" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoxPGZwBt3yoAeaNSTwHqnelD0ua6ofdc90EXsK19AC9kUDxHJWyAB50Ig6xRnSGuxjqDJc25CjG7pNp_XzLXO1i9Sjo_2o7OHgLdvXUKZkmGI3L-55ZQTafyRWtqtbADCJsUWUg/s1600/2011-08-30_12-31-03-AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoxPGZwBt3yoAeaNSTwHqnelD0ua6ofdc90EXsK19AC9kUDxHJWyAB50Ig6xRnSGuxjqDJc25CjG7pNp_XzLXO1i9Sjo_2o7OHgLdvXUKZkmGI3L-55ZQTafyRWtqtbADCJsUWUg/s200/2011-08-30_12-31-03-AM.png" width="200" /></a></div><br />
- Fourth Chapter would be AI. Implementing an effective, "thinking" enemy that can react to the player. Making that enemy spawn in ways that make sense.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtdLBJtBZDaBwQBk61sqy6kzz3ckTRgLuyrDfcZmpRFHCfkAoZaGHOt9FFXkSVB_Oxj9YXFujqj9LNa0X5vu2sM0YlKItnnODrmLxVeNCvrXX37CU-FSh-NCjmdYi-5IolVz-HWg/s1600/2011-09-29_07-54-35-AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtdLBJtBZDaBwQBk61sqy6kzz3ckTRgLuyrDfcZmpRFHCfkAoZaGHOt9FFXkSVB_Oxj9YXFujqj9LNa0X5vu2sM0YlKItnnODrmLxVeNCvrXX37CU-FSh-NCjmdYi-5IolVz-HWg/s320/2011-09-29_07-54-35-AM.png" width="320" /></a></div><br />
- Fifth Chapter would be crafting and structures. Creating graphics that make sense. Creating structures that take time to do their job. Creating structures that pay attention to their surroundings and react accordingly. Turrets that shoot enemy, doors that open and close and tractor beams that raise and lower the player.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3Scv72rxpBfI6k3kPRcyDR5a7FslBRi6K4_rWM-Npo0rQ5wyCRi5ZJwozemYAVa5GOSXXgmSIeYnfBNbko0ljAWYXsjytYEpN4Wp4kpNjsOWm2UwmSbdyrGsKfbSlm2ILMV6IEA/s1600/2011-11-08_11-58-18-PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3Scv72rxpBfI6k3kPRcyDR5a7FslBRi6K4_rWM-Npo0rQ5wyCRi5ZJwozemYAVa5GOSXXgmSIeYnfBNbko0ljAWYXsjytYEpN4Wp4kpNjsOWm2UwmSbdyrGsKfbSlm2ILMV6IEA/s200/2011-11-08_11-58-18-PM.png" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbsRIX1KMo6y6iSfpFkrDRJRjdPn0nDmrDEqLm5WPUtV0xFNfoFtOgj1ckRXwpc8yBhl-ogI35cKYbOXUBBWqIg92tNtmMD8h_Ksm3xk_pItBzGEb11_U0ABYzNCu528h7Jt-Izw/s1600/2011-10-20_09-48-31-PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbsRIX1KMo6y6iSfpFkrDRJRjdPn0nDmrDEqLm5WPUtV0xFNfoFtOgj1ckRXwpc8yBhl-ogI35cKYbOXUBBWqIg92tNtmMD8h_Ksm3xk_pItBzGEb11_U0ABYzNCu528h7Jt-Izw/s200/2011-10-20_09-48-31-PM.png" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHDi6rnjKfxrGr0dJZng0utDZ-w77yisUOWiT7SqOfB5lO9J3VUg9s7tGE10JBd2gHBZPI_zdiXrfGx2-HBVnXCYwUq1e2u1a2AI3de8USFKnvh3g0I5PgdL9ZWtndXM0EIXT2Gg/s1600/bucket.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHDi6rnjKfxrGr0dJZng0utDZ-w77yisUOWiT7SqOfB5lO9J3VUg9s7tGE10JBd2gHBZPI_zdiXrfGx2-HBVnXCYwUq1e2u1a2AI3de8USFKnvh3g0I5PgdL9ZWtndXM0EIXT2Gg/s200/bucket.png" width="115" /></a></div><br />
- The most recent chapter, the Sixth, was all about fluids. Creating an efficient fluid engine that let me have vast amounts of liquids and let them all update and react with the world around them without taking up tons of resources.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipzrYhwif1c1zO3oLQU5Vst5YnCHE-CLJZgBD8ycwcdhS0zcQzfJBabgsnowg9ceRZyIGl9q_N6BB8w6y_w8s0YJvwTTtxmtu5EPRUvTFJDDJACcb8a44gb5cMnEdo76wVWJSBkg/s1600/2011-10-25_09-04-52-PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipzrYhwif1c1zO3oLQU5Vst5YnCHE-CLJZgBD8ycwcdhS0zcQzfJBabgsnowg9ceRZyIGl9q_N6BB8w6y_w8s0YJvwTTtxmtu5EPRUvTFJDDJACcb8a44gb5cMnEdo76wVWJSBkg/s200/2011-10-25_09-04-52-PM.png" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvPbcB4GfF_x-oRZYXBnMsSh57r830TdUcRg2T4g4p3TUjasOcKUx8ULdMhI-Sqjjko3YOIBfmukBqhEIsSzS-rKybHnGuGHMslTFlVG6npN44NAE77waARkjFmtj_IQkWbC4o8Q/s1600/2011-11-15_11-29-33-PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvPbcB4GfF_x-oRZYXBnMsSh57r830TdUcRg2T4g4p3TUjasOcKUx8ULdMhI-Sqjjko3YOIBfmukBqhEIsSzS-rKybHnGuGHMslTFlVG6npN44NAE77waARkjFmtj_IQkWbC4o8Q/s200/2011-11-15_11-29-33-PM.png" width="200" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeIzTlAcM7q1uVtLsBOTvVEh27AJIY2iBcp8wZqpzzPV7QoMLwUWk-Y5DNypez57lDz7E_mjJThrXgvB8IxOhx4eWUGJrG7M8VvMCNcsTs_go2wo4yiFLQXQ4e3EM5IPoMwHR2RQ/s1600/2011-11-14_07-54-39-AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeIzTlAcM7q1uVtLsBOTvVEh27AJIY2iBcp8wZqpzzPV7QoMLwUWk-Y5DNypez57lDz7E_mjJThrXgvB8IxOhx4eWUGJrG7M8VvMCNcsTs_go2wo4yiFLQXQ4e3EM5IPoMwHR2RQ/s200/2011-11-14_07-54-39-AM.png" width="200" /></a></div><br />
And now we're on the Seventh Chapter, multiplayer. I've barely started this chapter and I've already learned a lot. This might be one of the most challenging ones yet, mainly because I have so much of the fundamentals already done and there's so much that now needs to be changed. I feel like I will definitely learn a lot though. The nice thing is, at the end of the day, that's the point of this entire adventure. To Learn.<br />
<br />
So until next time my friends. ~<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-9MSIvBENnLIB46ZBYJLvYMUHZjxiJUBHtrDBuJ32FcX6Jg8yrGhfQQngbhMqESR7XBNvl-u5xMcE7oq7ZVhGyBTFuPgm4WEAOkco-HxTGjO_Vx68dhP4V1ohc0GTc-PqPE1jiA/s1600/R22.70818.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-9MSIvBENnLIB46ZBYJLvYMUHZjxiJUBHtrDBuJ32FcX6Jg8yrGhfQQngbhMqESR7XBNvl-u5xMcE7oq7ZVhGyBTFuPgm4WEAOkco-HxTGjO_Vx68dhP4V1ohc0GTc-PqPE1jiA/s320/R22.70818.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Learning 3d</td></tr>
</tbody></table><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm6-yxbniepK4QWLgy_tjfUP1Oy12nODoHd9TUWAFaweDSwj5ogJcR6YKoW-27sAmOTUAfRx421F6aMcAT0OZOCZLnBhBjeBUbNcg4JAGG-UDihsopgwQRileqyU3vtipIM0yO9w/s1600/R27.06614.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm6-yxbniepK4QWLgy_tjfUP1Oy12nODoHd9TUWAFaweDSwj5ogJcR6YKoW-27sAmOTUAfRx421F6aMcAT0OZOCZLnBhBjeBUbNcg4JAGG-UDihsopgwQRileqyU3vtipIM0yO9w/s320/R27.06614.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">First AstroMiner concept</td></tr>
</tbody></table><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi53j2CtmyAw7uKVeKf1JQdTaGPcptUOiGQywbCucmOwAAM8cqtaFzwXB6AfhyphenhyphenDJoSvmhwale4sAEXvWgtF6ze9dDk8Gauvq3q_xFKNykT4zraw9iAD0efCFCWBms32Rty9lWQ4bg/s1600/2011-08-13_12-20-53-AM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi53j2CtmyAw7uKVeKf1JQdTaGPcptUOiGQywbCucmOwAAM8cqtaFzwXB6AfhyphenhyphenDJoSvmhwale4sAEXvWgtF6ze9dDk8Gauvq3q_xFKNykT4zraw9iAD0efCFCWBms32Rty9lWQ4bg/s320/2011-08-13_12-20-53-AM.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">First AstroMiner Build</td></tr>
</tbody></table><div class="separator" style="clear: both; text-align: center;"><br />
</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR07MBhOYArYEYLzZqK_0z99JEP2T-nwt6emU5kSHxZjRl9GxsXlmKNBS2oAmc-1U5Nk_PbTwbY_FQoYwrlqjQ8dWlVJRCMz0ejtSUpSplhxiVss1pWs72wydUudxRyMZEyf6nOw/s1600/tg.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR07MBhOYArYEYLzZqK_0z99JEP2T-nwt6emU5kSHxZjRl9GxsXlmKNBS2oAmc-1U5Nk_PbTwbY_FQoYwrlqjQ8dWlVJRCMz0ejtSUpSplhxiVss1pWs72wydUudxRyMZEyf6nOw/s320/tg.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Latest Screenshot</td></tr>
</tbody></table><br />
</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0tag:blogger.com,1999:blog-2630066.post-69573161215028807622011-12-05T23:06:00.002-05:002011-12-16T13:24:28.990-05:00Lesson Learned<div dir="ltr" style="text-align: left;" trbidi="on">For my next game, the very first thing I will do will be multiplayer support.<br />
<br />
The concept is simple. When you launch in single player, the game is going to launch a local server and your client will connect to it. You will be the only player on that server until you reach the multiplayer stage. Then it will open up for others.<br />
<br />
When you want to connect to another server, your client will simply point itself towards that server.<br />
<br />
It sounds very simple and it would be, if I had worked like that from the beginning. At this point of the game, I have so much code working with eachother that separating it is giving me a lot of issues.<br />
<br />
I'll get it done - no doubt. I just wish I would've thought of this from the beginning :]</div>Royhttp://www.blogger.com/profile/15644780099733181444noreply@blogger.com0