thunderbots-at-home / athomesoftware

Thunderbots@Home software repository
0 stars 0 forks source link

Fix base controller, not moving with joystick #82

Closed UltronDestroyer closed 10 years ago

UltronDestroyer commented 10 years ago

More twiddlefudging to do. Namely, the Arduino code is the same as whats on github, and the base controller is subscribed to port ttyACM0 (the arduino port) and is supposedly sending commands yet nothing is moving. (The motor is powered)

UltronDestroyer commented 10 years ago

It works on my laptop but not on the mainframe. Sigh. Here we go

UltronDestroyer commented 10 years ago

Probably something to do with the serial ports it's communicating with

UltronDestroyer commented 10 years ago

Here's the error:

device_file: /dev/ttyACM0 [ INFO] [1393989468.983502854]: reading serial comm buffer [ INFO] [1393989469.083800155]: received message: [ INFO] [1393989469.184250818]: received message: st2681,0,0.0,0.0,0.0,0.0,0.0,0.0 [ INFO] [1393989469.284649761]: received message: 32734,0,0.0,0.0,0.0,0.0,0.0,0.0 terminate called after throwing an instance of 'std::runtime_error' what(): Time is out of dual 32-bit range Aborted (core dumped)

UltronDestroyer commented 10 years ago

Able to replicate the error: run the base controller node for a long time and then terminate it. The buffer of the arduino will be full. Next time the arduino is run, the buffer will overflow when you try to write to it and thus crash. Relaunching it clears the buffer after the crash, however the cmd_vel still isn't sent properly.

Working on that now

UltronDestroyer commented 10 years ago
while ( !(base_controller::g_request_shutdown) ) {
            std::string readValue;
            readValue = base_controller::async_serial->readStringUntil("\n");

            if (readValue != "") {
                ROS_INFO( "received message: %s", readValue.c_str() );
                odom_manager.UpdateOdometry(parser.parse( readValue.c_str() ));
                odom_pub.publish( odom_manager.GetCurrentOdom() );
                broadcaster.sendTransform( odom_manager.GetCurrentTransform() );
            }

            ros::spinOnce();
            usleep( 100000 ); 
        }
UltronDestroyer commented 10 years ago

I can only assume that when running the node through the terminal it doesn't process interrupts? Will have to confirm later

UltronDestroyer commented 10 years ago

By that I mean it is only processing this on a single thread

michaelmoritsugu commented 10 years ago

Hmm?

So, it's supposed to process interrupts for signals with code 9. I'm not sure if it covers any others.

I'm glad you've found a way to replicate this. I agree with you that the buffer is filling up but I'm not sure what the best way to clear it would be.

UltronDestroyer commented 10 years ago

Fixed it. Instead of calling ros::ok() I called node.ok(). Base can now be controlled from any computer with the ps3 controller. Also, the nav stack works with cmd_vel just testing the odometry now

michaelmoritsugu commented 10 years ago

you'll have to explain this to me

jbalanko commented 10 years ago

Me too

On Tuesday, March 4, 2014, Michael Moritsugu notifications@github.com wrote:

you'll have to explain this to me

Reply to this email directly or view it on GitHubhttps://github.com/thunderbots/athomesoftware/issues/82#issuecomment-36712441 .

Sent from my Nintendo Game Boy Color

michaelmoritsugu commented 10 years ago

Just to respond to your comment

" I can only assume that when running the node through the terminal it doesn't process interrupts? Will have to confirm later "

The node has the global lock in place to process interrupts. Last I saw ros doesn't have a way to add signal handling to a node. This makes it hard to release resources when ctrl+c is used to send USRINT to the process that is running the node. The horrible workaround solution was to create a global lock and register my own version of a signal handler.

If my memory is correct following the execution of my defined signal handler control is handed back to ros which performs it's own shutdown stuff.

Apparently there's a ticket for this but I don't remember if they marked it as not an issue. It's definitely something that'd be important to have in ros.

Also, from what I saw this morning we should be using rosnode kill (or something similar, I can look this up when I'm not at work).

UltronDestroyer commented 10 years ago

Another solution would've been to instantiate your sig handler on a new thread and in the loop call ros::MultiThreadedSpinner::spin(), which processes other threads every time it hits spin().

For the kill, I added a couple days ago a two button kill-switch with the PS3 controller (Press the small left and right top buttons kills all nodes on the system). This method uses "rosnode kill -a" sent to the roscore.

On Wed, Mar 5, 2014 at 10:37 AM, Michael Moritsugu <notifications@github.com

wrote:

Just to respond to your comment

" I can only assume that when running the node through the terminal it doesn't process interrupts? Will have to confirm later "

The node has the global lock in place to process interrupts. Last I saw ros doesn't have a way to add signal handling to a node. This makes it hard to release resources when ctrl+c is used to send USRINT to the process that is running the node. The horrible workaround solution was to create a global lock and register my own version of a signal handler.

If my memory is correct following the execution of my defined signal handler control is handed back to ros which performs it's own shutdown stuff.

Apparently there's a ticket for this but I don't remember if they marked it as not an issue. It's definitely something that'd be important to have in ros.

Also, from what I saw this morning we should be using rosnode kill (or something similar, I can look this up when I'm not at work).

Reply to this email directly or view it on GitHubhttps://github.com/thunderbots/athomesoftware/issues/82#issuecomment-36776901 .

michaelmoritsugu commented 10 years ago

Whoa, a single thread for a signal handler? Maybe I'm just allergic to threads but the perspective I've used so far is to consider them when there is an overwhelming need for them.

That second approach makes sense to me in theory but how does it get around needing to share the reference to the AsyncManager? Or am I being silly and is shared state implied?

Glad you're using rosndoe kill -a for the kill switch. I need to review whether or not that provides a way for me to release resources on shutdown.