First: create a catkin workspace and put this repo in the
src/
directory.
Remark: ROS1.noetic (1.15.9), Python 3.8.5 (64), Ubuntu 20 (.04.2 LTS).
Notice: if a
ERROR: cannot launch node of type [{file}]
occurs, you may need tochmod +x
the mentioned file.
This ROS project presents 2 packages (hanoying_back
, hanoying_front
).
The setup as-is was intended for the game "Towers of Hanoi", but should be adaptable (see there)
This version relies on a simulator (CoppeliaSim) but can be adapted to work with a real setup (see here)
To run the setup:
- you must have a ROS master running at all time (
roscore
) and source your/opt/ros/${version}/setup.bash
from every terminal - start CoppeliaSim and ensure both ROSInterface and RemoteApi plugins are loaded successfully, start the simulation coppeliasim_scene.ttt
- add the Python binding of the RemoteApi
sim.py
to$PYTHONPATH
(it should be in${CoppeliaSim root dir}/programming/remoteApiBindings/python
) - (make sure to have the
remoteApi.so
in the same folder assim.py
, if it's not, copy it over from the/remoteApiBindings/lib/lib
) - build your catkin_workspace and source everything you can to save you sanity, or just:
*
cd ~/catkin_ws
*catkin_make
*source devel/setup.bash
- start the nodes from the
hanoying_back
package first (or useroslaunch hanoying_back back.launch
) - then start the nodes from the
hanoying_front
package (or useroslaunch hanoying_front front.launch
)
Note: it should behave fine even if
hanoying_back
's nodes are started after, or restarted at anytime, but CoppeliaSim has to be started with the simulation running.
Refer to this file for more and see that file for a "healthy" system.
The parameters, topics, services and action servers are all provided by the hanoying_back
package, or CoppeliaSim. So the associated types (msg, srv and action) are also part of hanoying_back
.
List was getting pretty long, so I moved it to another file.
The behavior of the robot should be implemented in the decision_system
node (for now, it just finds a solution from the current state and intend to do the first move).
Because this relies directly on the simulator, a few changes will need to be made before using on a real (physical) setup;
The sim_to_raw
node have for objective to fake the simulation's capture as raw input to the hanoying_back
(this hack was made to go around recompiling the ROSInterface to account for new message types). This is the node to replace with a 'real' one that would publish to /game/raw
, as well as updating the GameRaw.msg
with whatever the sensors being used deliver.
Example:
sensor_msgs/Image cam1
sensor_msgs/Image cam2
double weights[]
Another point will be to update the game_state/process.py
which must process a raw GameRaw
message into a usable GameState
message. The later will be passed around to your process.py
, solver.py
and rules.py
.
Finally, the control of the robot needs to be adapted in the game_move/do_move.py
. The third part of the GameMove.action
file (feedback) may be adapted as needed.
Example:
[..]
---
[..]
---
float32 percent
geometry_msgs/Transform wrist_tf
float32 eta
The setup should allow to implement some other games. To do exactly that, the following must be updated accordingly;
In the hanoying_back
package:
msg/GameRaw.msg
must be able to carry every sensory input you need to evaluate game statemsg/GameState.msg
must be able to reflect any state of the gameaction/GameMove.action
must be able to reflect any move in the game 1- if the previous points require adding custom messages, update
CMakeLists.txt
to include them src/game_state/process.py
must be able to provide game state as aGameState
from aGameRaw
src/game_move/do_move.py
must enable to execute any givenGameMove
2src/game_solve/solver.py
must be able to solve the game from anyGameState
, resulting in a (potentially empty)GameMoveGoal[]
3src/game_solve/rules.py
should be able to validate a move (results inbool
) and list every possible moves from aGameState
(results inGameMoveGoal[]
)
In the hanoying_front
package:
src/ctrl/ctrl.py
(see comments in file, mainly used for debugging RN...)src/gui/gui.py
sub to/game/state
,/decisys/*
and whatever else you want, make yourself at home
Footnotes
-
In the
.action
file, only needs to be updated the goal (first part) and feedback (last part) as needed;reason
should carry custom flags to interpret why a move failed; only the bits 1 (move not valid) and 8 (aborted/preempted) are reserved. ↩ -
This part of the node is only expected to do the move, regardless of validity regarding game rules (only failing when the move is not possible), moves passed to the function in
do_move.py
are valid (except it the parameter/game/move/skip_move_validation
is set); the implementation of the validity check should be ingame_solve/rules.py
. ↩ -
GameMoveGoal
correspond to the first part ofGameMove.action
, see this list for more details list of the added ROS types. ↩