Tuesday, May 29, 2012
But before I go off and start adding more features, I do want to put out some top-notch documentation and a complimentary bottomside firmware so that using an Arduino with Ethernet support (either Arduino Ethernet or an Arduino with a shield), you can have an operational ROV as quickly as possible!
Thanks for stopping by and expect more information (and posts) on ROV-suite soon!
P.S. I'm pretty tired tonight so this is kind of a brief post that doesn't go into too many details. You can expect more technical details later. Also... Happy 20th post!!!!!
Wednesday, May 16, 2012
The iOS developer made that ROVotics logo and he also came up with the color scheme for our team, so I used them for the Android (and Windows/OSX/Linux) application. I got that compass backdrop and outer ring from the QFlightInstruments project. I made my own ROV image for the center of the compass. On the right hand side of the application, there is an "About Us" button that switches the UI's state to the "about" QML state, which has instructions, a team photo, website URL and a scrollable text field that loads text from a plain text file to display. Underneath the "About Us" button are some lights that change based on values sent from Catalina. The communication light turns orange when ROVotics establishes communication with Catalina (and turns back to the current grey when the communication is lost). The relay indicators are going to have real labels ("Lights" instead of "Relay0") when this application ships. On the right, there is the mission timer which is updated by Catalina and turns orange when the time is up. Underneath the mission timer is a "Vector Decoder" (creative name, huh?) that takes the motor values sent from Catalina and adds them up as vector values to show how the ROV will respond to the joystick input. It's really handy for debugging incorrect motor code! That little white bar between the compass and the vector decoder is the vertical thrust value indicator. It simply shifts up and down depending on the applied vertical thrust. Finally, on the far right is the depth indicator. Catalina sends ROVotics the maximum depth of the pool as well as the ROV's current depth. ROVotivs takes that value and calculates the depth of the ROV as a percentage of the maximum depth. The orange bar then slides up and down to the correct percentage value, which gives the user a graphical representation of the depth.
The entire UI is scalable (although there is a minimum screen resolution), so it should work on everything from phones to tablets to laptops with varying screen resolutions. Let me tell you... Making a UI that scales across that wide variety of screens with this many elements is a pain. It's simple to do (just a little math), but it's still a pain to have to set all of the x, y, width, and height values for each widget added.
Overall, I've really enjoyed working with QML so far, so I do plan on writing more UI's with it. As a bonus over normal QWidgets, QML forces me to have better form with programming because it makes it harder to store variable values in the UI. I'm taking what I've learned from this and applying it to Monterey to make the code top notch.
Speaking of Monterey, it's coming along nicely so far! I still have to add joystick support (with optional bilinear reading). I'm going to avoid mapping buttons and hats right now because in my experience, it's easier just to reach over and tap a keyboard shortcut. However, if people ask for certain joystick mappings, I'll add them. I am still planning on hitting my June target date!
Finally, I found out about this really awesome Qt application called cppcheck which is a very useful opensource C++ source code analyzer. It catches those mistakes that the compiler won't catch (like not assigning a default value to a variable). I've already gone through much of my code with it and have used it to help me spot errors.
Thanks for stopping by!
Thursday, May 3, 2012
For instance, it was too customizable. There were too many options! The customization code was messy (my fault) and cumbersome. It just wasn't worth the gain when it was just as easy to change one line on the bottomside Arduino code to get the same net effect. Not only that, but it scared off new users. Between its messy UI and plethora of options and tabs and QLineEdits, new users were put off.
Because of my lessons learned on Monterey 1.0 and Catalina (my team's topside code), I have decided to make Monterey 2.0 less customizable, but easier to use (don't worry! The application will still be useful and feature-filled!), I think that this will make it less daunting for new users. Also, by cleaning up my source code (after learning more about composition), I have made it easier for people to edit the source themselves if all else fails.
My goal is to provide, for free, the best available ROV controller for inspection-class (micro, mini and general class) ROVs* and I will do what it takes to accomplish that goal. In doing so, I hope that hobbyists not interested or knowledgable in programming, but who are quite gifted when it comes to mechanical and electrical design, will be able to build more advanced and creative ROVs.
Thanks for stopping by!
*I will still keep this hobbyist oriented, though.
P.S. While working on my QML tic tac toe game, I came up with the idea of rewriting Monterey's GUI in QML to help give it a uniform look and feel across all OSes. I'm still thinking about doing that, but that would be a later branch. I want to hit my June release date, so I'm past the point of major designs shifts like that for the 2.0 release. I also have a few other QML applications to make before then.
Wednesday, May 2, 2012
Most of the tutorials that I found for doing this left out parts of the code, which frustrated me greatly because then I could not figure out how and why they did things the way that they did. To help avoid that issue, I'll post an archive of my source here so that no questions are left unanswered!
For an alternate tutorial, check here.
Step 1: Setting up the base of the application
I created a normal "Qt GUI" project using the SDK's wizard. That created the *.pro, main.cpp, mainwindow.h and mainwindow.cpp files for me. I then added a Qt Resource File (QRC) for holding the QML file (something that has to be done in order for QML to work on Android). Then, I added a new, standalone QML file to the project. These files will be the base for the application.
Step 2: Setting up the base of the UI
In the mainwindow.ui file, I added a QDeclarativeView that I would use to display the QML file. In the mainwindow.cpp code (in the constructor), I added "this->setCentralWidget(ui->declarativeView);" right after the UI setup code is run. This makes my QDeclarativeView fill up my entire UI and expand with it.
Step 3: Making the backend
This is a pretty simple step. Start by adding a new class that inherits QObject (important!!!) to your project (I called mine "Logic"). For my Logic class, I wanted it to have a private bool that I could set and return the value of. For the set and return functions, you can either use public slots or "Q_INVOKABLE". I used slots because I was already familiar with them and because it would make more sense to use slots in case I wanted to tie more classes in with my "Logic" class.
Step 4: Linking the backend to the frontend
This is the part that took me longer than it should have.... First off, in mainwindow.cpp, declare two pointers: a QDeclarativeEngine (*engine) and a QDeclarativeContext (*cntx). Set them to "ui->declarativeView->engine()" and "engine->rootContext()". Next, to complete the linkage, use "cntx->setContextProperty("Logic", new Logic);". Finally, use "ui->declarativeView->setSource(QUrl source);" to set the source of your QDeclarativeView to your QML file (located in your QRC).
When calling "cntx->setContextProperty("Logic", new Logic);", the first argument is the string that you're going to use to call the functions in your QML file while the second argument is a object of class type Logic (in this case).
Step 5: Calling your functions in QML
Once steps 1-4 have been completed, step 5 is as simple as "Logic.toggledNow()" in my case. In "foo" terms, it would be "Foo.someFunction()" if you used cntx->setContextProperty("Foo", new myClass); earlier.
I hope this tutorial has helped you out and thanks for stopping by!
Tuesday, May 1, 2012
I like to make sure that my code is well backed up. Also, since I am the head programmer of my robotics team, I like to keep track of the changes that my teammates make to their code no matter where I am. Awhile ago, I downloaded the Android application called Terminal IDE just for fun. I never actually tried it out until a day ago. To my surprise, when I typed in "git" the help text came up. A few minutes later, after becoming root ("su"), I had made a directory on my sdcard and was proceeding to download my team's private repo over ssh from Sourceforge! I was pretty happy about that!
For those of you who want a full featured git client (and editor with nano and vim), check out Terminal IDE. I mean, hey, it's free!
So what are you waiting for?
P.S. It works best with the Hacker's Keyboard download from Google Play because that exposes the tab, ctrl, esc and arrow keys.