I am new to ROS and trying to understand this powerful tool. I am confused between the spin and rate.sleep functions. Could anyone help me with the difference between these two functions and when to use each one?
ros::spin() and ros::spinOnce() are responsible to handle communication events, e.g. arriving messages. If you are subscribing to messages, services, or actions, you must call spin to process the events.
While ros::spinOnce() handles the events and returns immediately, ros::spin() blocks until ROS invokes a shutdown. So, ros::spinOnce() gives you more control if needed. More on that matter here: Callbacks and Spinning.
rate.sleep() on the other hand is merely a thread sleep with a duration defined by a frequency. Here is an example
ros::Rate rate(24.);
while(ros::ok())
{
rate.sleep();
}
This loop will be executed 24 times a second or less, depends what you do inside the loop. A ros::Rate object keeps track of how much time since the last rate.sleep() was executed and sleep for the correct amount of time to hit the 24 Hz mark. See ros::Rate::sleep() API.
The equivalent way in the time domain is ros::Duration::sleep()
ros::Duration duration(1./24.);
while(ros::ok())
{
duration.sleep();
}
Which one you use is just a matter of convenience.
Related
Imagine, we have a sut as a publisher which publishes values continuously and never finishes. On change of some input (ex: we change some mocked #Published property which our sut depends on), it emits an event.
We're collecting these events in results array and then checking if there is an exact expected number of events, not less and not more.
The problem is - how to check there are no more events after what we expect to be emitted? Without wait method we don't know when it's time to check the results array.
wait will work but it feels for me like a crutch for Combine. Because the good unit tests should be fast (see F.I.R.S.T principles of unit testing). And these waits looks more like anti-pattern.
I also couldn't find an Apple's recommendation on this.
You need a test scheduler, which is basically a virtual time scheduler that will let you control when the time-based events will be published. So for example you can fire all the events at once.
Combine does not have build-in a test scheduler, but you can use an open source test scheduler called Entwine
Lets say you have a complex Lua application, and there is some base function that different parts of your code call repeatedly. It's a stateless function with little to no side effects, and fairly simple.
How does the virtual machine handle this? Does it queue up all the calls, and let them run one by one, waiting for the function to to return before calling it again? Or does it do some trickery to avoid this sort of situation? What if the function had some big side effects, like print()?
Lua is single threaded so every function call must return before the next one is called. If a function is blocked then so is the VM. The only way around that is coroutines or Lua lanes or C threads.
I'm implementing a control node for a device with four wheels. So far I have the following nodes:
TALKER:
--Publishes messages for movement of vehicle
LISTENER:
--Listens to messages for movement of vehicle and controls vehicle directly
The communication between these two works and my only problem is what to do if either one shuts down in order to prevent uncontrolled movement of the vehicle. ros::isShuttingDown() call in the LISTENER so it detects when it's about to be killed.
However, if the TALKER is shut down the LISTENER keeps moving the vehicle according to the last message received from TALKER. First I tried to use ros::isShuttingDown() in TALKER as well in order to send a final "stop" message to LISTENER, but it seems that once the node is shutting down, no communication is possible.
Therefore I'm looking for a way to check inside LISTENER if the node TALKER is still alive (or if new messages are still being received).
Anyone an idea on how to see if a node (in this case TALKER) is still alive? Or is there an easy method for detecting how long it has been since the last ROS message was received?
Take a look at the bond package. I believe it does exactly what you need.
Found another interesting and already built-in way with including "ros/network.h":
// master.h:
....
/**
* \brief Retreives the currently-known list of nodes from the master
*/
ROSCPP_DECL bool getNodes(V_string& nodes);
....
However, I didnt figure out how to use it from within another cpp file...
Despite my best efforts, I am unable to produce the kind of synchronization effects I would like to in ActionScript. The issue is that I need to make several external calls to get various pieces of outside information in response to a user request, and the way items will be laid out on the page is dependent on what each of these external calls returns. So, I don't care that all of these calls return asynchronously. However, is there any way to force some amount of synchronization on ActionScript, so that at least calling the method for doing the final layout and placement of items on the page is dependent on all of my calls finishing?
If I understand the question right, event listeners are probably your best bet. Most loader classes throw an Event.COMPLETE message when they finish doing everything behind the scenes. If you wrote those external calls, it would be easy to dispatch a complete event at the end.
So when you make all these external calls, have a function that listens to when those calls complete. This function would keep track of how many calls have been made, and when there's none left to run, continue building your layout.
Rough Sketch to explain below:
var numProcesses:int = 0;
slowthing.addEventListener(Event.COMPLETE,waitForSlowest);
numProcesses++;
slowthing.load();
quickThing.addEventListener(Event.COMPLETE,waitForSlowest);
numProcesses++;
quickthing.load();
function waitForSlowest(e:Event)
{
numProcesses--;
if(numProcesses == 0)
finalizeLayout();
}
I am creating an action script library.I am calling some APIs which parses some xml and gets me the result. It dispatches an Event.COMPLETE when the parsing is done. I want to monitor whether this event is dispatched in some while loop like "while(eventnotdispatched)"
is it possible? I know the other way would be to addeventlistener. But please let me know if the other thing is possible.
Thanks
NO, it is not possible. Actionscript is single threaded. Thus while you are waiting in your while loop, that is the only thread running, and the process you are waiting for can never complete. This is why everything is done with events, so that's what you should use. If you need to update your display periodically while you are waiting for something to complete...again, use events. Create a Timer object which generates a TIMER event every so often, and use that to make your updates.
EDIT: Davr is right, you would not be able to use the while loop like this. You would need a timer.
Yes, it is possible to poll for it. BUT you will still need to create an event listener. It will work something like this:
private var loadCompleted = false;
private var timer:Timer= new Timer(1);
private function onInitCompleted(event:Event):void
{
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.start();
}
private function loadCompleteEventHandler(event:Event):void
{
loadCompleted = true;
...
}
private function timerHandler()
{
if(!loadCompleted)
{
... // stop the timer or something.
timer.stop();
}
}
Please note, this is VERY BAD code. I would NEVER use it in production because Actionscript is a event driven language. There should be absolutely NO REASON for you to need to do this. Whatever you are trying to do could be accomplished using another method much simpler. Tell me what you are trying to accomplish with this and I will present a better solution.
Sorry for yelling, it's late and I am sleepy.
Doing that means forcing a synchronous model of execution on the underlying asynchronous model (that works with callbacks).
What are you trying to achieve exactly, and why not use a callback?
I agree with the statements about it probably being a bad idea and a while loop will certainly not work this way in ActionScript. However, there may be legitimate reasons for doing what you are attempting to do. Only you can prevent bad code. Instead of judging, I'll just get to an answer for your question.
First I'm going to make an assumption, that what you really want to do is monitor a property and for some reason the API for this object does not dispatch an event when this property changes. I'm making this assumption because if you have the event available, I assume you would just use the event.
So... you have an object weirdXmlObj with a property loaded that defaults to false but goes to true when the XML is loaded.
In this case with slight modifications the code posted by CookieOfFortune would in fact work. You wouldn't need the loadCompleteEventHandler function (which was never attached anyway) and in the timer handler you would simply check if( weirdXmlObj.loaded ) and then branch however you wanted to.
Ah but there may be a simpler way, depending on what you are doing.
If you have a display object handy. (i.e. something that makes sense, not just some random object.) You can attach your code to the stage's EnterFrame event instead of using a timer.
myDisplayObject.stage.addEventListner(Event.ENTER_FRAME,frameEnterHandler);
A couple of things to be aware of:
You don't really even need to go to the stage level, all display objects support the EnterFrame event, but it's a nice place to attach the event listener.
You really should keep whatever the function calls to a minimum. In particular the actual frameEnterHandler function should do nothing more than do the if( weirdXmlObj.loaded ) check.
You are attempting to circumvent event-driven programming, which is not a good idea. This is often the case when someone approaches from an older model and does not yet have a good frame of reference to appreciate the elegance of event-driven programming.
Events are your friends. They work very well. Your loadCompleteHandler is all that is required. Want to do something else in response? Add the call in that handler:
private function loadCompletedHandler(event:Event):void
{
waitingObject.fileWasLoadedSoGoDoThatThing();
}
There is no need to make it any more complicated than that. No need for a semaphore or a loop to check the semaphore. Unnecessary environmental semaphores can break the encapsulation that could shield you from unwanted side effects.