From: Cameron J. M. <cjm...@cn...> - 2005-10-24 19:11:49
|
Hi, I'd like to be able to look at the colour of the ground under my robot, for example to have a sensor that could do classic "line following" (you can do it with Lego...). The idea is to use this with a model having a bitmap, which has obstacle_return (at least) set to 0, so the robot can drive over it.=20 I can fake this using the simulation getpose function, and having the control software keep track of the bitmap, but it's not the right way to do it. Is there already a good way to do this? --=20 +----------------------------------------------------------------- | PGP http://www.cns.bu.edu/~cjmorlan/public-key.pgp | Cameron Morland ---- Cameron@Morland.ca | | Thought is not a management function. | --John Ralston Saul +----------------------------------------------------------------- |
From: Reed H. <re...@ac...> - 2005-10-24 19:57:26
|
Cameron J. Morland wrote: > Hi, > > I'd like to be able to look at the colour of the ground under my > robot, for example to have a sensor that could do classic "line > following" (you can do it with Lego...). > > The idea is to use this with a model having a bitmap, which has > obstacle_return (at least) set to 0, so the robot can drive over it. > > I can fake this using the simulation getpose function, and having the > control software keep track of the bitmap, but it's not the right way > to do it. > > Is there already a good way to do this? > Assuming you're talking about stage-- Making a new model in stage is not terribly difficult, if you know what to implement: * You need to add your new type to typetable.c * You need to implement an "init" function (this is what goes in the type table) which is the start of everything else. * The init function sets some function pointers: one to load data from the config file, one called when the first client "subscribes" (startup function), one when the last client unsubscribes (shutdown). Typically the startup function sets the function pointer for an "update" function called each simulation loop. * You can save information in "properties" attached to the model. If you add an interface for your new model to the player plugin, then that can get & set properties on the model. * You need to modify the model's "figure" (maybe have no figure) to determine how it is displayed in the gui. * You can set function pointers as callbacks to be called when a property value is changed. Most models use such callbacks to modify the figure. * The load function queries for entries in the world file; here you'd load your bitmap I think. You can use GDK functions if you need them; stage also provides some GDK/GTK wrappers and general utilities in a sort of module called RTK. I have a patch to libstage that lets you dynamically add entries into the type table (instead of modifying it and recompiling stage) if you want that (actually it maintains a seperate typetable); I also have some example model code if you want that too. You can always just base your new model off an existing one. Reed |
From: Brad K. <bkr...@et...> - 2005-11-02 20:37:07
|
Hello all, I was wondering if anyone is using the MultiClient in the C++ libraries. It's pretty much the last major chunk from the old api that I haven't gotten around to moving over. If people are using it, I'm more than happy to port it over. If not though, I may end up removing it from the headers. The way I understand things, it looks like we could almost do the same thing w/ the following code (roughly). list<PlayerClient*> multi_client; PlayerClient pc1("localhost"); PlayerClient pc2("anotherhost"); multi_client.push_back(&pc1); multi_client.push_back(&pc2); std::for_each(multi_client.begin(), multi_client.end(), std::mem_fun(&PlayerClient::Read)); Any input is welcome. Best regards, -bk |
From: Brian G. <br...@ge...> - 2005-11-05 18:44:16
|
On Nov 2, 2005, at 12:37 PM, Brad Kratochvil wrote: > > I was wondering if anyone is using the MultiClient in the C++ > libraries. It's pretty much the last major chunk from the old api > that I haven't gotten around to moving over. If people are using > it, I'm more than happy to port it over. If not though, I may end > up removing it from the headers. The way I understand things, it > looks like we could almost do the same thing w/ the following code > (roughly). > > list<PlayerClient*> multi_client; > > PlayerClient pc1("localhost"); > PlayerClient pc2("anotherhost"); > > multi_client.push_back(&pc1); > multi_client.push_back(&pc2); > > std::for_each(multi_client.begin(), > multi_client.end(), > std::mem_fun(&PlayerClient::Read)); Well, it depends how PlayerClient::Read() is implemented. In the original lib, that call was blocking, so iterating through each client like that could introduce extra latency by waiting for data on one connection while data was already available on another connection. The benefit of using the PlayerMultiClient is that it called poll() on all the clients' sockets to determine which ones had data ready, then called PlayerClient::Read() on just those clients. So with one PlayerMultiClient::Read() you get all available data without blocking. brian. |
From: Brad K. <bkr...@et...> - 2005-11-07 09:26:07
|
Brian Gerkey wrote: > Well, it depends how PlayerClient::Read() is implemented. In the > original lib, that call was blocking, so iterating through each client > like that could introduce extra latency by waiting for data on one > connection while data was already available on another connection. > The benefit of using the PlayerMultiClient is that it called poll() on > all the clients' sockets to determine which ones had data ready, then > called PlayerClient::Read() on just those clients. So with one > PlayerMultiClient::Read() you get all available data without blocking. Ok. That makes more sense. So the way I see it is that we could either add a ReadIfWaiting() command to PlayerClient so that people could use a list and something like the for_each code, or add a PlayerMultiClient (that would basically inherit from a list and use the for_each code). Which would everyone prefer? I'm leaning more toward not having an extra class because it's less to support in the future. Also, it could always be implemented later if needed. The code difference would be roughly: (without MultiClient) list<PlayerClient*> multi_client; PlayerClient pc1("localhost"); PlayerClient pc2("anotherhost"); multi_client.push_back(&pc1); multi_client.push_back(&pc2); std::for_each(multi_client.begin(), multi_client.end(), std::mem_fun(&PlayerClient::ReadIfWaiting)); (with MultiClient) PlayerMultiClient multi_client; PlayerClient pc1("localhost"); PlayerClient pc2("anotherhost"); multi_client.push_back(&pc1); multi_client.push_back(&pc2); multi_client.Read(); |
From: Geoffrey B. <g....@au...> - 2005-11-07 19:10:40
|
I like the idea of supporting a ReadIfWaiting() method of some kind in the standard PlayerClient. It may be useful even when you only have one client, and it's tidier than doing a peek and read. Geoff Brad Kratochvil wrote: > Ok. That makes more sense. So the way I see it is that we could either > add a ReadIfWaiting() command to PlayerClient so that people could use a > list and something like the for_each code, or add a PlayerMultiClient > (that would basically inherit from a list and use the for_each code). > > Which would everyone prefer? I'm leaning more toward not having an > extra class because it's less to support in the future. Also, it could > always be implemented later if needed. > > The code difference would be roughly: > > (without MultiClient) > > list<PlayerClient*> multi_client; > > PlayerClient pc1("localhost"); > PlayerClient pc2("anotherhost"); > > multi_client.push_back(&pc1); > multi_client.push_back(&pc2); > > std::for_each(multi_client.begin(), > multi_client.end(), > std::mem_fun(&PlayerClient::ReadIfWaiting)); > > (with MultiClient) > > PlayerMultiClient multi_client; > > PlayerClient pc1("localhost"); > PlayerClient pc2("anotherhost"); > > multi_client.push_back(&pc1); > multi_client.push_back(&pc2); > > multi_client.Read(); -- Robotics research group, University of Auckland http://www.ece.auckland.ac.nz/~gbig005/ |
From: Brian G. <br...@ge...> - 2005-11-11 18:45:35
|
On Nov 7, 2005, at 1:26 AM, Brad Kratochvil wrote: > > Ok. That makes more sense. So the way I see it is that we could > either > add a ReadIfWaiting() command to PlayerClient so that people could > use a > list and something like the for_each code, or add a PlayerMultiClient > (that would basically inherit from a list and use the for_each code). > > Which would everyone prefer? I'm leaning more toward not having an > extra class because it's less to support in the future. Also, it > could > always be implemented later if needed. Adding the ReadIfWaiting call sounds good to me. brian. |