Level: Medium project
GitHub Repository: Privated
Grade: B+ (8.875 out of 10)
What is "Robot chess"?
At some point the AI overlords will take over and enslave all of humanity, but until that point comes we must help them so that they treat us nice when doomsday comes. The first step towards that goal consists in taking the fun of the game of chess away, by having a robot play it by itself.
Thus, this project consisted in developing all the middleware that allows for easy manipulation of chess pieces in a chessboard using a UR3 robot arm with a robotiq 2F-85 gripper.
Project structure:
This project was carried under subject 240AR060 (Introduction to ROS) of the Master of Science in Automatic control and Robotics, @ UPC. In the subject's website (https://sir.upc.edu/projects/rostutorials/final_work/index.html) we were provided some sample code as well as a proposed separation in different packages based off of functionality:
- chesslab_setup
- Aruco reading
- Collision checking
- IK
- RViz connection
- chesslab_sensing
- chesslab_actions
- Moving to a safe position (ensure no collisions) above the aruco.
- Moving linearly in cartesian space towards the chess piece (from the safe configuration).
- Opening/closing the gripper (closing if picking up, opening if dropping).
- Moving linearly back to safe position above chess piece.
- Moving to the place cell (if pickup was just performed) or going to the home configuration (if action was just finished).
- chesslab_planning
This package was provided in its completion (nothing was added to it), as it provides some essencial feaatures for the project:
Reads the arucos embedded on the chessboard as well as on top of each chess piece in order to triangulate its pose and publish it on the /tf topic.
By simulating the scenario in a physical engine (Kautham), it could compute what collisions were present in any configuration of the robot.
Given a desired pose for the end effector of the UR3, it computed the inverse kinematics and provided different possible configurations to achieve that pose.
It served as a connection to RViz, as updating the poses of the arucos would update their location in RViz and in the Kautham physics engine.
This package reads the poses that have been published under the /tf topic, and separates those that belong to the chess pieces. Afterwards, it queries chesslab_setup to update the poses on RViz, as well as in Kautham. chesslab_planning is also queried in order to update the position of the pieces in its cell representation.
This package queries the person managing the computer whether they want to perform a certain action (such as "b2b4":moving the piece in b2 to b4) or let a chess engine decide for them.
Afterwards, the action is sent to chesslab_planning, which returns a sequence of actions to perform (in case the instruction is correct) or asks for another instruction if the previously given one is not doable.
In case we have a valid set of instructions to follow, this package analyses them and makes the robot follow through each of them. Usually these instructions can be segmented into 5 different steps:
This package contains a virtual chessboard with the positions that each chess piece is in, as well as their aruco markers. An order is given to the package, expressed in two cells (such as "b2b4"). The code inside said package processes the order, starting by obtaining what chess is being moved where (pawn B2 -> pawn B4), and then processing whether the move is allowed based off of the current chessboard configuration.
This correctness check is performed via restriction checking. As an example, verifying whether the movement of a black pawn is properly performed requires the following code:
case 'p': // Black pawn //Can't move backwards or sideways if(row_d-row_o>=0) return -1; //Can't move more than 2 spaces if(row_d-row_o<-2) return -1; //Can't move more than 1 sideways if(abs(col_d-col_o)>1) return -1; // Advancing 2 spaces ->possible in origin if(row_d-row_o==-2){ //Possible in origin if(row_o != 6) return -1; //Possible without obstacles if(name_map[row_o-1][col_o]!='0' || name_map[row_o-2][col_o]!='0') return -1; //Possible without lateral movements if(col_o-col_d != 0) return -1; movetype=1; //We are just moving break; } //Move to kill if(col_o-col_d != 0){ //Possible if someone there/passing if(pos2Cell(row_d,col_d)!=passing && piece_d =='0') return -1; // We are killing if(pos2Cell(row_d,col_d)==passing) movetype =3; //Kill passing else if(piece_d !='0') movetype =2; //Normal kill kill = true; break; } //Advancing 1 space ->destination must be empty if(row_d-row_o==-1){ if(piece_d !='0') return -1; movetype=1; break; } ROS_ERROR_STREAM("Situation that was not accounted for encountered! Aborting..."); return -1;
After the move is verified valid, a global check is performed to verify that the king from the team that is moving is not in a check position. Afterwards, knowing that the goal is valid, and knowing what type of movement is being performed, the Fast Forward planner is called, which returns the movement actions that are later passed to the chesslab_actions package.
Demonstrations:
Simulation:
Real robot: