I don't see an advantage to localizing using the walls. My general opinion is that algorithms that use absolute coordinates or references tend to be fragile. Try to sense and react to your goals instead.
If you find yourself getting tired of changing hard-coded values and want to add configuration files, I recommend LUA or Squirrel. Both are compact, easy to integrate, and provide a full scripting language for your configuration files. I much prefer it to XML or INI.
Move your control loop to another thread and add a thread for high-level control. You will probably combine a state-machine and a set of behaviours for each state
The reason to use a bigger framework like ROS or ROCK or MOOS or YARP is if they provide functionality you need. If you start with do-it-yourself you can always add in the bigger framework when you need it.
(In case you are curious, I wrote the realtime control and programmers API for this: barrett.com/products-arm.htm and directed the 15 person software development team for this: walk-man.eu )
There are lots of optimizations that can be done but this structure should work and will be easy to learn. As you have time to learn more you can do more sophisticated things to optimize the timing between threads and the data usage.
This basic structure should work for you. You will need to use std::thread and std::mutex (to protect the buffers when you are modifying them). The sensor threads will be regulated by blocking reads. The actuator threads will delay with 'usleep(10000);' and then check for data in the buffer; writing the latest datapoint and emptying the buffer. The control thread will use the data from the sensor buffers, calculate the action, modify the actuator buffers, and then sleep
The reason to use circular buffers instead of just single memory locations is that it makes life easier when you want to add filtering or other dataprocessing. Initially you can have the size of the buffers be 2 or 16; something small; and then increase the size if you want to do a 20 point moving average or something like that.
Your control loop, each time through, reads the latest sensor data (don't modify the buffer, just read the latest one), does your control calculation, and then writes the actuator command to the actuator buffer.
Each actuator thread also gets a circular buffer, and periodically checks to see if there is anything new. if there is, it writes the data to the actuator.
Each sensor thread does a blocking read on it's data, and when data is received, that data is put into a global circular buffer. (One buffer for each sensor).
You'll notice that each read() or write() to your sensors and actuators in normally blocking. ie the program will stop until the read or write is finished. There are two approaches to working with this. 1) configure the io operation to be non blocking and set up a loop with polling, checking each time through the loop to see if the read is ready. 2) Let the operating system do all the work for you. Leave the read and writes as blocking and put them in separate threads.
You can mix C and C++ object files in the linking phase no problem (or wrap .h files and code with extern "C" ). You will find that it's easier to use the native linux API's (C) for some of the driver stuff.
In your case, if something fails there are not that many BAD things that can happen. The worst possibility is that the ESC's get stuck at full power and you burn up a motor. Since you have water cooling, this is unlikely.
Distributed computation has the disadvantages of multi-process, plus you have to deal with unreliable communications between computers. The advantage is that it's easy to add another computer.
Multi-process computation is harder because you have to manually (or using scripts or management processes) make sure that all the components are started, and started in the correct sequence. What you gain is that if one component crashes, only the process it lives in crashes and other parts of your system can continue.
Single process computation is nice because the compiler and OS take care of finding all the components (object files and .so files), making sure everything is ok, and starting everything up in the way you want. The disadvantage of single process is that if one component fails, then all components fail.
C & C++ are different languages. I know the syntax looks the same but the idioms are a bit different. Most IPC api's are C and most documentation about IPC uses C so you might be missing good information if you are looking to C++.