I would like to create something like this :
I have a module that does something like 'circuit switching' for a stream of messages. That is, it has a single inport and multiple outports. Once a message arrives at the inport, an outport is selected based on some logic (logic is not important in the context of the question). It is checked whether, there is any ongoing message transfer on the outport (for the first message, there won't be any). If there is no transfer, message is sent to that outport, otherwise, it is kept in queue for that particular outport. I need to decide data structure for this communication. Please advice
My idea is to have a map of outports and corresponding queues.
queue<message> m_incoming_queue;
typedef map<outport*,m_incoming_queue> transaction_map
if this is a good solution, i want to know how do I create a queue at the runtime? as in, I dont know in advance how many outports will there be, I create outports based on requirement.
Maybe something like:
// At beginning
typedef queue<message> MessageQueue
typedef map<outport*, MessageQueue> transaction_map
transaction_map tm() // Create the transaction map
// On receipt of each message
// (Some logic that determines outport* op and message m)
if(tm.count(*op) == 0)
{
// There are no queues yet, create one and insert it
tm.insert(transaction_map::value_type(*op, MessageQueue()))
}
// There is already a queue created, so add to it
tm[*op].push(m)
Related
I have a C++ ROS question.
I have an assignment which requires me to get information from a number of topics generated by another program. basically. this other program makes a bunch a topics that publishes some basic data, called Pose, from the turtle simulator ros tutorials. the problem is, that I'm not sure how to get all the information I need from all the different topic sources. I know I need to subscribe to a topic to get its info, and i already know how to get all the topic names and open the subscriptions to them. what I am unclear about is whether or not i have to pass in a unique callback function into each new topic I subscribe to. or if there is a way to make one generic callback function that can be passed into all of the subscriptions.
this is my code for this so far
void getTTurtles(char tType, vector < TurtlePose > Tarray) {
int i;
string tname;
stringstream topicName;
//TurtlePose TPose;
ros::master::V_TopicInfo alltopics;
//get all topic names
ros::master::getTopics(alltopics);
for (int i = 0; i < alltopics.size(); i++) {
topicName.clear();
topicName.str("");
tname = getTurtlename(alltopics[i]);
if (tname[0] == 'T') {
Tarray[i].topicname = alltopics[i].name;
Tarray[i].name = tname;
topicName << "/" << TPose[i].name << "/pose";
ros::Subscriber sub_tur = n.subscribe < turtlesim::Pose > (tname, 1, poseCallback);
}
}
return false;
};
as you can see, i have a function that get all the topic names for me. this allows me to grab only the ones whose names start with T (the purpose of the program is to get my own turtle to collect all of his created T-Turtles while avoiding his created Xturtles, so this function it meant to give me a list of the Tturtles and their locations.). I grab name of the topic names of the turtles and from that can grab the actual turtles name as well. but there is a third element i need to extract. the turtlesim::pose information that is being transmitted by all the Tturtle topics. so i use the topic name(T1,T2,T3, etc) to make a subscription to that topic and pass it a callback function, but i'm not sure how to properly write the callback function to appropriately allocate the pose information into the proper location. for example. how to make sure that when the callback function is called as a result of /T1/pose publishing, to make sure that the information it has transmitted end up in Tarray[0].pose instead of Tarray[1] to [2], while also having /T3/pose go into Tarray[2].pose. so on and so forth.
the solution must be scalable, since the number of T-turtle topics being made can be and probably will be changed.
is their a way to write the subscription or the callback function so that you pass in a specific container at the time of creation to be used whenever that specific subscription get information from its subscribed topic?
thanks in advance for the help?
If Your Input Data Is The Same U Can Use AnyNumber Of Subscribers With One CallBack and When Declaring Subscriber U can Pass Any Number Arguments To It So U can Separate Data That's Incoming To Your Node Inside Your Callback (by pushing it out To separate global vectors etc.)
I am new to Veins and trying to implement a mechanism to detect if the WSM packet was received before. I am using the "psid" as the main variable to identify the packet - is it correct?
Will this type of code work? :
bool MyVeinsApp::msgReceivedBefore(int psid){
/*
This function will be used to determine if the message was received before
and should be discarded or processed further
*/
if(msg_log.find(psid) == msg_log.end()){
return false
}
else {
return true;
}
}
Here msg.log is a C++ data structure storing WSMs based on psid.
The psid only is an identifier for the service you are using (see WaveShortMessage.msg) and therefore not unique among messages of the same service. To distinguish between messages you need a unique message identifier.
A simple approach would be to use the id which every module in OMNeT++ gets:
msg->getId()
UPDATE: Please note that this id also is unique among all messages with the same content (see comment down below).
I started to play around with caf and using it to represent a graph.
Since this graph is unidirected I can create the actors that I need and link them accordingly, but now I want to find a specific actor identified by it's name.
class node_actor : public event_based_actor{
std::string m_name;
...
};
int main(){
auto entry_actor = spawn<node_actor>();
// node_actor will spawn other actors with names
// like this: node_actor will spawn node1
// node1 will spwan node2
// node2 will spwan node3 and so on
// now I want to send a message to node2
scoped_actor self;
self->send(n2, 42});
...
}
What would be the best way to find n2?
Can this be handled by a group, broadcasting a message? E.g like this:
{
auto g = group::get("local", "Node events");
auto entry_actor = spawn_in_group<node_actor>(g);
// change all nodes to call spawn_in_group
scoped_actor self;
self->send(g, name, 42})
}
If so wouldn't that be much overhead, because all nodes must be checked if they match the message?
Or are there other ways that I did not find in the docs yet?
I think the group is a good idea because it also works distributed. You can have a better scalability by announcing each spawned actor to the group instead of broadcasting the messages.
Each actor that needs a name <-> actor mapping would then subscribe to the group (before you actually spawn your nodes). Whenever you spawn a new node, you send its name along with its handle to the group and each listener adds this mapping to its local state (or ignores the message if it is only interested in a few selected names).
In case you have a lot of actors that need the name mapping and you don't want to replicate the mapping many times, you could also use a single actor instead of a group that stores a map and can be queried by others whenever they need to resolve a name.
Your third option is to use the actor registry, but this will only work locally and only if you can use atom names. If this matches your use case, then you can register new actors via detail::singletons::get_actor_registry()->put_named(key, value); and retrieve them via detail::singletons::get_actor_registry()->get_named(key);. I usually don't recommend features from the detail namespace, but this particular feature will make its way to the public API in 0.15. By the way, you can create an atom_value dynamically, but you are of course limited to 10 characters and are only allowed to use alphanumeric characters.
Hope that helps.
i'm studying this source base. Basically this is an Anim server client for Symbian 3rd edition for the purpose of grabbing input events without consuming them in a reliable way.
If you spot this line of the server, here it is basically setting the RProperty value (apparently to an increasing counter); it seems no actual processing of the input is done.
inside this client line, the client is supposed to be receiving the notification data, but it only calls Attach.
my understanding is that Attach is only required to be called once, but is not clear in the client what event is triggered every time the server sets the RProperty
How (and where) is the client supposed to access the RProperty value?
After Attaching the client will somewhere Subscribe to the property where it passes a TRequestStatus reference. The server will signal the request status property via the kernel when the asynchronous event has happened (in your case the property was changed). If your example source code is implemented in the right way, you will find an active object (AO; CActive derived class) hanging around and the iStatus of this AO will be passed to the RProperty API. In this case the RunL function of the AO will be called when the property has been changed.
It is essential in Symbian to understand the active object framework and quite few people do it actually. Unfortunately I did not find a really good description online (they are explained quite well in Symbian OS Internals book) but this page at least gives you a quick example.
Example
In the ConstructL of your CMyActive subclass of CActive:
CKeyEventsClient* iClient;
RProperty iProperty;
// ...
void CMyActive::ConstructL()
{
RProcess myProcess;
TSecureId propertyCategory = myProcess.SecureId();
// avoid interference with other properties by defining the category
// as a secure ID of your process (perhaps it's the only allowed value)
TUint propertyKey = 1; // whatever you want
iClient = CKeyEventsClient::NewL(propertyCategory, propertyKey, ...);
iClient->OpenNotificationPropertyL(&iProperty);
// ...
CActiveScheduler::Add(this);
iProperty.Subscribe(iStatus);
SetActive();
}
Your RunL will be called when the property has been changed:
void CMyActive::RunL()
{
if (iStatus.Int() != KErrCancel) User::LeaveIfError(iStatus.Int());
// forward the error to RunError
// "To ensure that the subscriber does not miss updates, it should
// re-issue a subscription request before retrieving the current value
// and acting on it." (from docs)
iProperty.Subscribe(iStatus);
TInt value; // this type is passed to RProperty::Define() in the client
TInt err = iProperty.Get(value);
if (err != KErrNotFound) User::LeaveIfError(err);
SetActive();
}
This is more of a general design query I had. I have implemented a publish / subscribe pattern by maintaining a list of subscribers. When an event to publish occurs, I loop through the subscribers and push the event to each one, of them in turn.
My problem occurs when due to that publication, somewhere in the depth of the software, another component or event the described component decide to unsubscribe themselves. By doing so, they invalidate my iterator and cause crashes.
What is the best way to solve this? I have been thinking of wrapping the whole publication loop into a try catch block, but that means some subscribers miss the particular subscription upon which someone unsubscribed, and seems a bit over the top. Then I tried feeding it back, e.g. I turned the void publish call into a bool publish call that returns true when the subscriber wants to be deleted, which works for that case, but not if another subscriber unsubscribes. Then I am thinking to "cache" unsubscription requests somewhere and release them when the loop is done, but that seems a bit overkill. Then I am thinking of storing the iterator as a class member, so that I can manipulate the iterator from outside, but that gets messy (say you unsubscribe subscriber 1, iterator is pointed at 2, and the container is a vector - then the iterator would have to be decremented). I think I might prefer one of the latter two solutions, but both seem not ideal.
Is this a common problem? Is there a more elegant solution?
You could either disallow subscription operations during publication, or you could use an appropriate data structure to hold your subscription list, or both.
Assuming that you keep your subscribers in a std::list, you could run your loop thus:
for(iterator_type it = subs.begin(); it != subs.end(); ) {
iterator_type next = it;
++next;
it->notifier();
it = next;
}
That way, if the current item is removed, you still have a valid iterator in next. Of course, you still can't allow arbitrary removal (what if next is removed?) during publication.
To allow arbitrary removal, mark an item as invalid and defer its list removal until it is safe to do so:
... publication loop ...
dontRemoveItems = true;
for(iterator_type it = subs.begin(); it != subs.end(); ++it) {
if(it->valid)
it->notifier();
}
std::erase(std::remove_if(...,, IsNotValid),...);
dontRemoveItems = false;
elsewhere,
... removal code:
if(dontRemoveItems) item->valid = false;
else subs.erase(item);