---
# System prepended metadata

title: Untitled

---

## SmartRobot explorer - Week 14

FOTOOOO

### Requirements

> Build a robot that includes a basicrobot, capable of tracking the boundary of the enviroment on which the robot is located. The robot must be aware of his position in the enviroment and the direction it points to.
    > 1. REQ-BOUNDARY: cause the robot to circumnavigate the enviroment and produce a virtual mapping of the room.

### Requirement analysis
**Preface**
- Assuming we already have the following components/functionalities:
     - **basicrobot**: a component that receive basic commands and consequently activate the motors and emit sonar events.
     -  **smartrobot**: a component that can be viewed as a CoAP resource and embed the core behaviour of the robot. The state of the resource is represented by position and orientation direction of the robot; at every robot movement smartrobot updates the CoAP resource state.
     - **planner**: some utilities function to track the robot position and draw the path done.
     - **coapSupport**: utilities function to read and update the robot resource position.
- Assuming robot starts from position 0,0 (top-left) corner and is oriented towards sud.
- Assuming rectangular room without obstacles placed in borders. 
- *Step* command is a dispatch message, to check the movement we can use CoAP state of the robot resource.

```kotlin
QActor walker context ctxSmartRobot{
["var NumOfRotations = 0
  var Stopped   = false 
  var RobotPos  : String
  var RobotDir  : String
  var PosChanged = false
  val ResultMap =   hashMapOf( 1 to \"-\", 2 to \"-\" )
"]
    State s0 initial{}
    Transition t0 
        whenEvent boundary -> walk // REQ-BOUNDARY

    State walk{
        ["PosChanged  = false "]
        // Read the position of the robot from CoAP
        forward smartrobot -m  step :  step(370)
        delay 500
        // Read the position of the robot and
        // check if the robot is moved updating PosChanged variable.
    }
    Goto walk if "PosChanged" else rotate

    State rotate{
        ["NumOfRotations++"]
        forward smartrobot -m cmd : cmd(l)
        delay 1000
    }
    Goto s0 if "(NumOfRotations==4)" else walk
}
```


### Problem analysis
- Using coapSupport.readPos(resourceName, storeObject) is possible retrive resource (identified by resourceName) position and direction, these information will be stored in storeObject (it must be an HashMap).
- The position of the robot is changed after the execution of step command if the actual position is different by the previous postion.
- Since the step command is a dispatch after this we have to wait a time bigger than step time.
```kotlin
QActor walker context ctxSmartRobot{
["var NumOfRotations = 0
  var Stopped   = false 
  var RobotPos  : String
  var RobotDir  : String
  var PosChanged = false
  val ResultMap = hashMapOf( 1 to \"-\", 2 to \"-\" )
"]
    State s0 initial{
        println("walker ON") 
    }
    Transition t0 
        whenEvent boundary -> walk

    State walk{
        ["PosChanged  = false "]
        delay 300
        [" kotlincode.coapSupport.readPos( \"robot/pos\", ResultMap ) 
           RobotPos = ResultMap.get(1)!!
           RobotDir = ResultMap.get(2)!!
         "]
        forward smartrobot -m  step :  step(370)
        delay 500
        ["		  
          kotlincode.coapSupport.readPos( \"robot/pos\", ResultMap ) 
          PosChanged = ResultMap.get(1)!! != RobotPos
        "]

    }
    Goto walk if "PosChanged" else rotate

    State rotate{
        ["NumOfRotations++"]
        forward smartrobot -m cmd : cmd(l)
        delay 1000
    }
    Goto s0 if "(NumOfRotations==4)" else walk
}
```


### Test Plan
1. To ensure that the robot has run along the boundary of the map, a possible approach consist of verifying from the (CoAP) representation of the robot if every boundary unit has been visited. This approach could be easily extended for future requirement. 
2. To be absolutely sure that the boundary request has been accomplished the robot must be equipped with a camera module.
In order to achive point 1 we have to add a method in 'planner.RoomMap' that check if the boundary is correctly done: 
```java
public boolean isBoundaryDone() {
    int x_size = roomMap.size();
    for (int x = 0; x < x_size; x++) {
        int y_size = roomMap.get(x).size();
        for (int y = 0; y < y_size; y++) {
            Box elem = roomMap.get(x).get(y);
            if (x == 0 || y == 0 || x == x_size - 1 || y == y_size - 1) {
                if (elem.isDirty() || elem.isObstacle()) {
                    return false;
                }
            }
        }
    }
    return true;
}
```

```kotlin
State testInit{
    forward walker -m  boundary :  boundary(_)
    delay 2000
    ["		  
      BoundaryOk = ResultMap.isBoundaryOk()
    "]
}
Goto testPassed if "(BoundaryOk)" else testFailed
    
State testPassed{ print("Boundary done.")}
State testFailed{ print("Boundary failed.")}
```
