The only notable exception is that carmen_map_point_t
points are in map grid cells, and should be multiplied by the map resolution (or converted using carmen_map_to_world
to get distances in metres.
The navigator CPU usage can be reduced by changing the number of lasers used \ (navigator_num_lasers
), increasing the replanning frequency (navigator_replan_frequency
) or, for static worlds with very accurate maps and very good localization, dynamic obstacle avoidance can be turned off using \ (navigator_update_map
). This last change is only recommended in carefully controlled environments.
Localize CPU usage can be reduced by making sure people tracking is off (localize_people_tracking
) and reducing the number of particles (localize_robot_particles
).
robot_collision_avoidance
and robot_allow_rear_motion
.
If robot_allow_rear_motion
is off, then the robot will not move backwards.
If you do not have backwards pointing sensors, such as a laser or sonar sensors, then the robot will not move backwards while collision avoidance is turned on. If you do have backwards pointing sensors, are they enabled? If no rear sensor data shows up in robotgraph, then the robot will not move backwards while collision avoidance is on.
If you turn robot_allow_rear_motion
on, and robot_collision_avoidance
off, then the robot will always move backwards if you ask it to. But, there is no guarantee you won't hit anything. We do { not} in any way endorse ever turning off collision avoidance. You { will} hit things.
You can allow a running simulator to ``see'' a second simulator using void
carmen_simulator_connect_robots(char *other_central). For example, start a CARMEN simulation (central, param, simulator, localize, navigator, navigator). Start a second CARMEN simulation on a different port, such as 1382. You can do this by starting central using
% central -p1382
CENTRALHOST
environment variable set to machine:1382
. Make sure that you start both simulations using the same map.In a third program, you need to connect the two simulations. For example, a program like this would do the trick to tell the first simulator about the second:
#include <carmen/carmen.h> int main(int argc, char *argv[]) { carmen_ipc_initialize(argc, argv); carmen_param_check_version(argv[0]); carmen_simulator_connect_robots("localhost:1382"); return 0; }
Most people would want both simulators to see each other, in which case you would probably want a short program like this:
#include <carmen/carmen.h> int main(int argc, char *argv[]) { Connect to the first IPC context, assumed to be running on localhost carmen_ipc_initialize(argc, argv); carmen_param_check_version(argv[0]); Tell the first simulator about the second carmen_simulator_connect_robots("localhost:1382"); Connect to the second IPC context, assumed to be running on localhost:1382 IPC_connectModule(argv[0], "localhost:1382"); Tell the second simulator about the first. carmen_simulator_connect_robots("localhost"); return 0; }
Position the first robot (using the first navigator_panel
). Position the second robot (using the second navigator_panel
) so that it is a little bit in front of where you put the first robot (which of course you can't see in the second navigator_panel
) and pointing back at the first robot. If you start two instances of robotgraph
, you should see the other robot in each robotgraph. As you drive the robots around, they should interfere with each other and see each other, just as if they were physically there.
The next thing is to understand multiple IPC contexts, reading the IPC manual.
When you subscribe to (most) IPC messages, you set up a handler (and maybe message pointer) on a context-specific basis (although you only get one handler and message allocation per context).
So, if you wanted to navigation status messages from two simulations, you could use the following:
void connect_to_two_simulations(char *simulation1, char *simulation2, IPC_CONTEXT_PTR *context1, IPC_CONTEXT_PTR *context2) { *context1 = IPC_connectModule(module_name, simulation1); carmen_navigator_subscribe_status(NULL, handler1, CARMEN_SUBSCRIBE_NOW); *context2 = IPC_connectModule(module_name, simulation2); carmen_navigator_subscribe_status(NULL, handler2, CARMEN_SUBSCRIBE_NOW); IPC_setContext(*context1); carmen_navigator_set_goal_place("lab door"); carmen_navigator_go(); while (1) { IPC_setContext(*context1); sleep_ipc(1); IPC_setContext(*context2); sleep_ipc(1); } }
What this does is establish a connection with a simulation running on the CENTRALHOST
described by simulation1, and a simulation running on CENTRALHOST
described by simulation2. (The simulations presumably were connected earlier.) The function subscribes to navigator status messages from each simulation, using different handlers for each message. You could certainly handle messages from both simulations using the same function, using the IPC_CONTEXT_PTR
IPC_getContext(); function inside the handler to tell which simulation generated the callback.
After the callbacks are established, the function goes back to the IPC context of the first simulation, sets a goal and starts the robot moving. After that, the function indefinitely just handles messages.