Adding external logging to Ogre3D

The Ogre3D framework provides logging code to write messages to a file or to stderr. The only way capture ogre log messages for external use is to add an ogre log listener. Unfortunately the code in ::Ogre::Root will always create a file based log object for the log messages. You can suppress file output after the log file is created but there’s no clean way to control the default behavior. You could also replace the default logging object with another but it seems wasteful to allocate dead code.

I’ve created an alternative that allows your own custom logging object to become the recipient of log messages. It minimally changes the Ogre3D library and injects no other dependencies.

Step 1: ::Ogre::LogManager

In ::Ogre::Root.init() if a log manager singleton doesn’t exist then it creates one. If the log manager already exists before init() is called then this is skipped. If you create a log manager externally then you avoid the default log object creation.

In ::Ogre::LogManager the only option for setting the logging object used is a method that creates a standard ::Ogre::Log object. To allow injecting your own logging object I added a method to ::Ogre::LogManager that allows injecting an externally created Log object.

Code (add new method):

void LogManager::addDefaultLog( ::Ogre::Log* p )
{
OGRE_LOCK_AUTO_MUTEX
mDefaultLog = p;
mLogs.insert( LogList::value_type( p->getName(), p ) );
}

Step 2: ::Ogre::Log

The current ::Ogre::Log object is used as a base class for my own custom log object. I override the LogMessage() method and the stream() method so my replacement code will intercept all logging. If you log messages via the stream object it calls LogMessage() so this is sufficient. To make this work correctly those two methods in the ::Ogre::Log class must be marked as virtual. This allows my custom object to override their behavior. In your own custom log object you can do whatever you like with the message strings received.

Declaration changes (add virtual keyword):

virtual void logMessage( const String& message, LogMessageLevel lml = LML_NORMAL, bool maskDebug = false );
virtual Stream stream(LogMessageLevel lml = LML_NORMAL, bool maskDebug = false);

Step 3: Installing your custom log object:

// must be called before ::Ogre::Root.init()
::Ogre::LogManager* mLogManager = new ::Ogre::LogManager();
MyLog* pLog = new MyLog( "DefaultLog" );
mLogManager->addDefaultLog( pLog );


Step 4
: Your new custom log object (declarations):

class MyLog
: public ::Ogre::Log
{
protected:
::Ogre::String mLogName;

public:
MyLog( const char* name );

/** Log a message. Replaces logging in Ogre
*/
void logMessage( const ::Ogre::String& message, ::Ogre::LogMessageLevel lml = ::Ogre::LML_NORMAL, bool maskDebug = false );

/** Get a stream object targeting this log. */
::Ogre::Log::Stream stream( ::Ogre::LogMessageLevel lml = ::Ogre::LML_NORMAL, bool maskDebug = false );
};

Your new custom log object (code):

MyLog::MyLog( const char* name )
: ::Ogre::Log( name, false, false )
{
}

void MyLog::logMessage( const ::Ogre::String& message, ::Ogre::LogMessageLevel lml, bool maskDebug )
{
OGRE_LOCK_AUTO_MUTEX
if ( ( mLogLevel + lml ) >= OGRE_LOG_THRESHOLD )
{
for ( mtLogListener::iterator i = mListeners.begin(); i != mListeners.end(); ++i )
( *i )->messageLogged( message, lml, maskDebug, mLogName );

// also route to debug stream
if ( mDebugOut && !maskDebug )
::std::cerr << message << ::std::endl;

// do whatever you like with the logged strings here
// in my case I send them to the Qt debugging object so all the messages are in one place
qDebug() << message.c_str();
}
}

// pass back a stream based on this object so streamed messages are written using logMessage()
::Ogre::Log::Stream MyLog::stream( ::Ogre::LogMessageLevel lml, bool maskDebug )
{
return Stream( this, lml, maskDebug );
}


recompile and you're good.

Jay Sprenkle

Posted in C++, Ogre, Qt | Tagged , , , | Leave a comment

My cool Christmas gift

A friend of mine gave me a lovely gift

Telegraph morse code key + sounder

It needs some restoration. I’ll be looking into electrolytic rust removal and perhaps chrome plating it. I like the warmer look of brass though. Wonder if I can electroplate something that’s a warmer color onto it?

Thanks Monte!

Posted in Uncategorized | Leave a comment

Controlling dynamic object creation in Qt QML

One of the issues I’ve run across while creating a user interface is dynamically creating objects. I’d like to create a dialog box, tooltip, popup, etc., show it, then dispose of it. I don’t want to create them at startup since a lot of them may never be used at all. It would be a waste of time and memory.

One of the issues is that if you open dialog in one part of the code gaining visibility to the object reference is another part of the code is very difficult.

One solution I’ve found is this. Find an object that is visible to every part of the code that controls the dialog box. In my case the dialog is opened and closed in signal handlers. There’s a parent object for the open and close handlers.  I created a custom property in the parent object:

property var dlg

When you create the dialog object assign it to the property:

parent.dlg = component.createObject(paretnt, {});

When you need to close the dialog simply destroy it:

parent.dlg.destroy();

Easy once you figure it out.

 

Posted in GUI, javascript, Qt, Scoping, Tutorial | Tagged , , , | Leave a comment

Remote development on the BeagleBone Black

The beagle bone doesn’t come with either NFS or Samba installed. I want to be able to share the file system to do remote compilation for it. I tried for several hours to get NFS running but couldn’t make headway with it. Since I’ve used Samba a lot I went with it instead.

Connect to the beaglebone via SSH

You’ll have to update your packages list before you can install anything:

opkg update

Then install samba:

opkg install samba

I’m going to try these instructions and see if I can get it to work

Posted in Beaglebone, Embedded Computing | Tagged | Leave a comment

ScyTek G20-c

Trying out the remote locking unit I purchased. I wanted to test this thing out and be sure I understood how it works before installing it in the car. I went through all the wall warts in the junk box. Found two 12 volt dc units. They produced 19 and 16 volts with no load. Yuk. A 9 volt wall wart actually produces 12 volts unloaded (the locking unit doesn’t present much of a load). So far so good!

I don’t have a siren/buzzer and you really need one to program the unit. You listen for beeps to confirm your selections. Got to work out something for that. Dawn says I should hook it up to my robot ;)

Posted in Toyota restoration | Tagged , , , | Leave a comment

Qt 5.1 and Netbeans 7.3.1 IDE

I saw a post that rated 13 debuggers for C++. Interesting to note that netbeans rated very highly. I actually didn’t find it all that great. It took nearly a week to get it to work at all. It’s not able to catch asserts or segment faults, and doesn’t have very good variable display while paused. There’s no memory dump and no option to change the formatting of displayed values.

Enough kvetching! I got Qt 5.1 working for the first time today. I’ve been running Netbeans 6.91 for quite some time. I tried using previous upgrades but the basic functionality of C++ did not work at all. With 7.3.1 I submitted a bug for a null pointer exception that kept me from compiling. Igor saved the day and fixed it for me. You rock! The latest release actually compiles! Here’s how I got it working:

  1. Create a virtual machine (or get some hardware).
  2. Install windows XP. It works just fine and for a development environment I want light and fast. A VM typically induces a 5% overhead.
  3. Since I used VirtualBox I installed the “virtual box guest addons”. This lets you interoperate with the host operating system. If you don’t like XP Virtual box lets you run the virtualized program windows directly on your bare metal desktop.
  4. install Qt5 from the executable downloaded from Qt. I used: qt-windows-opensource-5.1.0-mingw48_opengl-x86-offline.exe
  5. Install JRE 7 from the executable: jre-7u21-windows-i586.exe. You need this for NetBeans
  6. Install msys (to get the make utility and *nix command line) (Executable: mingw-get-inst-20120426.exe  Choose “basic system” and “developer toolkit” options only)
  7. Set the path to msys in the environment variables  (C:\MinGW\msys\1.0\bin)
  8. Set the path to Qt dll’s in the environment variables (C:\Qt\Qt5.1.0\5.1.0\mingw48_32\bin). You will need these at run time for Qt apps.
  9. Install netbeans from executable: netbeans-7.3.1-cpp-windows.exe
  10. Select “Tools”->”Options” and set the tool chain up. Set the base directory to C:\Qt\Qt5.1.0\5.1.0\mingw48_32\bin. It should fill in most of the executable paths for you. The QMake and Make programs have to be set up separately. QMake is in the Qt binary directory. Make is located in the directory C:\MinGW\msys\1.0\bin. Any old make will NOT work. You have to use this one. The fragmentation of the features of make is pretty bad. I didn’t setup CMake at all and see little use for it.
  11. The Netbeans environment sets up a special interface for Qt compile options. This has been changed for the new version of Qt so you’ll need to do a little bit of trickery to get Qt programs to compile. Open the project properties, go to the Qt tab, and scroll to the last entry in the list. It’s called “custom definitions.” For Qt projects set a special compile option here. This option allows you to enter free form options to pass to QMake. Widgets are now part of the “Widget” category not the “GUI” category. Netbeans has no option for this so add “QT+=widgets” in the project properties. Note that it’s all lower case.

Good luck with your projects!

 

Posted in C++, GUI, Netbeans, Qt | Leave a comment

Beaglebone black

I finally got to plug in the Beaglebone Black board I picked up at Maker Faire. They make a nice powerful single board computer.

I initially tried to power it from the micro usb port. It started booting but as soon as it started to draw much power it shut off. I rewired a 2.1mm barrel connector to a 5 volt wall wart that I had and powered it that was instead.

The unit has a very sophisticated web based interface that lets you control it, edit files, run experiments etc. It’s much easier than when I first did embedded programming.

On my system (linux) I had to add a network route to get to the web page the beagle bone serves:

route add -net 192.168.7.0 netmask 255.255.255.0 eth0

Posted in Embedded Computing | Tagged , | Leave a comment

MySql: timestamp column defaults

I’m starting to see why people don’t like MySql.

If you define a column in a table with no default value:

 CREATE TABLE foo ( bar TIMESTAMP, bletch INT );

You’d expect it to have no default value. If you did this:

 INSERT INTO foo(bletch) VALUES(1);

You’d expect to get a row with a NULL inserted for bar. You don’t. It puts in the current time stamp. To get what you expect you explicitly have to specify the column is nullable:

 CREATE TABLE foo ( bar TIMESTAMP NULL, bletch INT );

If you create a column with a default value of ‘CURRENT_TIMESTAMP’:

 CREATE TABLE foo
 (
 Created   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
 bletch INT
 );

You’d expect the same insert to give you the time of the insert. It doesn’t. You get the time and date of the table’s creation. You have to add ‘ ON UPDATE CURRENT_TIMESTAMP’ to the end to get it to do the expected thing.

It does quite a number of things in a non standard way and not in a good way.

 

Posted in MySQL, rant | Tagged , | Leave a comment

Giving up on Mythbuntu on the EB1033

I’m giving up. These were the show stoppers for me:

  •  DRM DVD’s will not play
  • Every time I turn on the system it forces me to hook up a keyboard and mouse and re-enter the default language etc.
  • The system keeps popping up a dialog wanting me to update my system. For a dedicated system not on the internet that’s bogus.

 

Posted in MythTV | Tagged , | Leave a comment

Installing MythTV on the ASUS EB1033

The Asus EB1033 is a good choice for a silent MythTV front end system. I’ll explain how to set it up and hopefully entertain you along the way.

If you’re not familiar with MythTV it allows splitting the functionality of a PVR/DVR across multiple machines. You can build a “Back End” system to record shows and “Front End” systems that allow you to “consume content”. I put my larger machine, with the noisy fans and hard disks, in the equipment room. In the home theater I want something quiet and small. I chose the Asus for this application.

Here’s the hardware I purchased:

* ASUS EB1033
* StreamZap remote control
* 4 GB of RAM (overkill. 2GB will probably work fine)
* An SSD drive that’s at least 16GB
* Rosewill external USB DVD player
* A TV with an HDMI connection. The Asus does not provide hardware output for sound you’ll need to use the television for audio.
* An HDMI cable
* A network cable to connect to your network (if you have a wifi router you don’t need this)

You’ll need these things to complete the install but will not need afterward. (borrow them from another system)

* usb keyboard
* usb mouse
* regular vga monitor

Optional:

* Android phone or tablet as an extra remote

I would not recommend using the Asus for a back end if you’re using an SSD drive. At this time mechanical hard disks are much cheaper per gigabyte. You’ll want to put as much disk space on your back end unit as you can afford. You can easily purchase enough space to store hundreds of hours of programs.

I had an existing, but very old, version of MythTV that had a combined front and back end. If I put a new front end into the mix it would not be able to communicate with the old back end because the communications protocol they use had been changed. I had to update my back end system as well.

For the installation I chose MythBuntu. Why did I chose this one? Let the saga begin!

I have in the past rolled my own system. It generally took several days to build one like this. First you install Linux. Then you tweak the video drivers settings file because it can’t figure out your video hardware. Then you have to install drivers for the infrared receiver so you can have a remote control. Then you install mysql and fight with permissions issues. Then you install mythtv and spend a day figuring out how to get your channel lineup loaded. etc. It’s not fun unless you’re a masochist. If you are a masochist I can recommend a dominatrix making you build a mythtv system from scratch. It will be endless hours of fun.

About a year after my first build I had to rebuild the system after a hardware crash. I updated the software and got it all working again without issue. Later that year daylight savings time rolled around and I started getting the wrong shows recorded. It was starting all recordings an hour off. The system time was correct and the time zone setting was correct. I hadn’t changed anything because the system had been working fine. It had to be a software bug.

A bit of research using google revealed the problem. The Qt library had a bug in its handling of time zone adjustments during daylight savings time. The MythTV coders knew about the bug. Their response was, instead of fixing the Qt library, they added a special offset to get the correct time. They added a bug to correct a bug. Two bugs that cancel each other out instead of zero bugs. Sigh.

When I rebuilt the system I downloaded the newest version of the Qt library. This version had the time zone handling correction. The old version of MythTV didn’t take that into account. So their ‘fix’ ensured that it recorded an hour off now. A perfect example of why software repositories are not a good thing. What you tested is never what the users end up running. I guess if you’re not supporting it you don’t really care though.

I couldn’t just adjust the clock by an hour because the cron task that automatically adjusts the clock to the atomic clock in colorado would set it back to the correct time. So, at this point, it was either adjust all the recording schedules to record the show that comes on just before the one you really want, or set the time zone wrong. I set the time zone wrong until daylight savings time ended again.

A year later an open source group started producing a disk image with everything pre-installed. That eliminated some of the work but still left the tweaking stage. I used them the next time I had to rebuild my system. This was a nice improvement.

Then I fell prey to the evil of duh ta duh “BAD ADVICE.” I had an annoying problem getting it to load my list of cable stations correctly. I was told “you can probably fix that if you upgrade to the new version.” It seemed simple enough since I already knew the settings I needed. Unfortunately the guys who packaged MythTV also fell prey to the evils of software repositories. They updated to the latest distribution of Linux when the created the package with the new version of MythTV. The new version of Linux decided that my hardware was duh ta duh “DEPRECATED.” This is technical talk for “You’ve got old crap that’s not interesting any longer. We don’t care that it works. Go out and buy some new stuff that’s cool grampa.”

So there I am with a perfectly good system that’s perfectly useless. I can’t reinstall the old software since I don’t have a copy of it and you can’t download it any longer. I can’t install the new version since my computer is now an antique (It’s more than a year old). I searched around and found a different packaged version of MythTV.

The MythDora distribution packaged up MythTV using a Linux that would run on my antique. It was even easier to install than what I had been using. It was able to reliably detect what kind of video hardware I had and automatically install a working driver. Wow. Kudos to you guys!

This long and winding tale finally comes to an end here. Dial forward to today. In my search for the new software my first action is to visit MythDora’s site. The note on the front page indicates they’re not going to keep up the project. Dang. That’s disappointing. A bit of further searching finds MythBuntu and it’s off to the download button.

* The EB1033 has an Intel Atom processor so you’ll need the 64 bit version of MythBuntu for it. I used the 11.10 version for both the front end and back end.
* Download the ISO file and use your favorite CD burning software to make a bootable disk from it.
* For the back end if you’re using old junk hardware you may need the 32 bit version.
* Unpack your new Asus.
* Marvel at how small the unit is. We’re in the future now baby.
* Take out the screws and pop off the top. It’s slightly tricksy. If you can’t figure it out there are some good youtube videos.
* Put in the RAM
* Put the mounting bracket on the SSD drive. Plug it into the connector inside the unit and use the provided screws to secure it.
* Re-assemble the Asus
* Plug in the video monitor, usb keyboard, and mouse. You won’t need to connect the TV yet.
* Plug in the usb dvd drive.
* Connect the power supply.
* Plug in the dongle provided in the StreamZap remote control package.
* Turn the unit on. Press the button on the dvd drive to open the door. Put in your MythBuntu disk.

The installation for this distribution is very good. It will lead you through the installation using simple step by step menus.

Installation notes:

* You CANNOT perform the installation using the TV output. You must use a monitor during the installation. It won’t be needed in regular use so just borrow one for the process.

* There’s an option for downloading updates during the process. Do NOT use this option. It drastically increases the time to complete the installation.

* The install will offer the option of using an android device to control the backend. You can scan a QR code to install the app or just select it from your app store of choice. It’s free but not very pretty.

* If your wifi router has a password you’ll need to enter it early during the installation. The installer will automatically set up the networking for the installation and use this password. You will not have to configure it again later.

* The StreamZap remote is one of the explicitly supported remote controls. During the install process you can select an option to install a remote control. Scroll through the list of supported remote controls and select “StreamZap.”

* Once your installation is complete remove the CD and reboot the Asus. Since the Asus does not provide hardware output for sound you’ll need to use the television for audio. The mythtv back end setup (in the system menu of the desktop) allows you to choose the audio drivers to use. In the list you’ll find a driver with “nvidia” and “hdmi” in the description. This is the correct choice.

* You probably do not need a pin to connect to the backend system. Leave it as “0000″

* You SHOULD enable the option to automatically fill listings in the mythtv back end setup (in the system menu of the desktop). This will fetch the new program listings. I purchased a years worth of service to get the tv listings from Schedules Direct. They aren’t expensive, they’re reliable, and they don’t send me spam wanting me to join a multi-level marketing scheme.

* If you want to be able to use a web browser to control your back end go to the plugins setup and enable “MythWeb”. Once your install is complete you can connect to the backend and perform many functions through a web interface. The plugins setup can be accessed by exiting from the mythtv front end. Then use the mouse to select the mythbuntu control panel.

* There is a music player plugin but I cannot recommend it. It easily has the worst user interface design I’ve ever seen.

After you’ve configured the system to connect to the back end you can remove the keyboard, mouse, and monitor. Connect the TV using the HDMI cable. Put the remote control dongle somewhere visible from where you use the remote control.

Good luck with your new DVR!  I’ll add some links to the hardware if you’re interested in purchasing it shortly

Posted in MythTV | Tagged , , | 3 Comments