Thursday, July 28, 2016

Robo4j and upcoming Neo4j connector, and why neo4j is the first

   Recently robo4j.io project got couple of new modules. One of them is the 1st database module.  It's the connector with Neo4j database. None of those modules is currently available on github due to lack of time and ongoing development process. 
 But here are few fact about  the new robo4j-neo4j module. Example of the robot data visualization is on the picture above. 

  Explanation: 
1. The Green points represent the limits of the space where the robot is currently located. 
2. The Blue point is the Start Robot location which is inside the defined space.  
3. The Yellow points represent the Robot movements, more precisely, the command which have been processed by the robot. 

each colored point has its assignment and relation to another one. On the images there are visible three relations: 
1. DIST represents the relation between the limit point. Limit points are created by the sonic sensor.
2. START represents the relation between limit point and refers the starting location of the robot
3. COMMAND refers to the type of command then has neeb processed inside the robot space (inside Green area)

   As all around the robot can be scanned by sensors the Neo4j database will play the significant role in next step decision making. Let's see in of the next post how finding the shortest path performs.
Stay tuned!


Wednesday, July 13, 2016

Robo4j updatelog: 201607132242 - from command to Consumers and Producers

  

  Robo4j framework has received new major update of the core logic and architecture. The small first taste has been already mention in previous blog post as simple sketch. The sketch has pictured the relation between RoboUnits and RobotAgents. In simplified written words the RoboUnit contains the number of agents. Those agents are interacting between each other and providing the result of the RoboUnit according to its assignment.  
  Let's focused little bit on RoboAgents. RoboAgents behaviour can be simplified as the relation between Producers and Consumers. 
  The Producers are basically providing result of the external inputs to the Consumers. External Producers inputs can be defined by Sensors or the result of the external computation/process. 
  On the other-hand Consumers are applying desired logic on such inputs. Consumers are allowed to use bounded resources, which are provided to the RoboUnit. 

   Current Robo4j framework release contains 1st simple example of RoboUnit implementation by implementing Robo Front-Hand. The front-hand unit is located in the front part of the robot and it's able to carry small things. 
  The Robo Front-hand consists from one engine and one touch sensor. This is enough to employ Producer Consumer scenario where the sensors provides appropriate data to the consumer which is represented by the engine. 
@RoboUnit(value = FrontHandUnit.UNIT_NAME,
        system = FrontHandUnit.SYSTEM_NAME,
        producer= FrontHandUnit.PRODUCER_NAME,
        consumer= FrontHandUnit.CONSUMER_NAME)
public class FrontHandUnit extends DefaultUnit implements LegoUnit {
    /* all connected pars  */
    private static final int CONNECTED_ELEMENTS = 2;
    private static final int DEFAULT_SPEED = 300;
    private static final int AGENT_POSITION = 0;
    static final String UNIT_NAME = "frontHandUnit";
    static final String SYSTEM_NAME = "legoBrick1";
    static final String PRODUCER_NAME = "frontHandSensor";
    static final String CONSUMER_NAME = "frontHand";


    ... 
    @Override
    public LegoUnit init(...

            this.agents.add(createAgent(
                    "frontHandAgent",
                    new FrontHandTouchProducer(exchanger, sensorCache.entrySet()
                            .stream()
                            .filter(sensorEntry -> sensorEntry.getValue()
                              .getPart().equals(LegoEnginePartEnum.HAND))
                            .map(Map.Entry::getValue)
                            .map(legoSensor -> 
                               createTouchSensor(legoBrickRemote, 
                                 legoSensor.getPort()))
                            .reduce(null, (e1, e2) > e2)),

                    new FrontHandEngineConsumer(exchanger,  engineCache.entrySet()
                            .stream()
                            .filter(entry -> entry.getValue()
                               .getPart().equals(LegoEnginePartEnum.HAND))
                            .map(Map.Entry::getValue)
                            .map(legoEngine -> 
                                createEngine(legoBrickRemote, 
                                  legoEngine.getPort(), DEFAULT_SPEED))
                            .reduce(null, (e1, e2) > e2))));
    ...
    @SuppressWarnings(value = "unchecked")
    @Override
    public boolean process(RoboUnitCommand command){

        if(!active.get()){
            return false;
        }

        ProcessAgent processAgent = (ProcessAgent) agents.get(AGENT_POSITION);
        return processAgent.process(command, (cm) -> {
            final FrontHandCommandEnum commandEnum = (FrontHandCommandEnum)cm;
            return logic.get(commandEnum).apply(processAgent);
        }).getStatus().equals(AgentStatusEnum.ACTIVE);

    }
    ...
    @SuppressWarnings(value = "unchecked")
    @Override
    protected Map<RoboUnitCommand, Function<ProcessAgent, AgentStatus > > initLogic(){
        final Map<RoboUnitCommand, Function<ProcessAgent, AgentStatus > > result = new HashMap< >();
        result.put(FrontHandCommandEnum.COMMAND, (ProcessAgent agent) -> {
            agent.setActive(true);
            agent.getExecutor().execute((Runnable) agent.getProducer());
            final Future<Boolean> engineActive = 
                  agent.getExecutor()
                    .submit((Callable<Boolean>) agent.getConsumer());
            try {
                agent.setActive(engineActive.get());
            } catch (InterruptedException | ConcurrentModificationException 
                  | ExecutionException e) {
                      throw new 
                        FrontHandException("SOMETHING ERROR CYCLE COMMAND= ", e);
            }
            return new AgentStatus<String>(AgentStatusEnum.ACTIVE);
        });

        result.put(FrontHandCommandEnum.EXIT, (ProcessAgent agent) -> {
            FrontHandEngineConsumer consumer = (FrontHandEngineConsumer) 
             agent.getConsumer();
            FrontHandTouchProducer producer = (FrontHandTouchProducer) 
              agent.getProducer();
            try {
                consumer.getMotorHandPortA().close();
                producer.getTouchSensor().close();
            } catch (RemoteException e) {
                throw new FrontHandException("RUN ERROR PROCESS: ", e);
            }
            agent.getExecutor().shutdown();
            agent.setActive(false);
            active.set(false);
            return new AgentStatus<String>(AgentStatusEnum.OFFLINE);
        });
        return Collections.unmodifiableMap(result);
    }
    ...

  Following code has shown that RoboUnit consist from two agents one Producer and one Consumer. Producer is represented by TouchSensor and Consumer by Engine. The RoboUnit does accept two commands from outside as the input -> COMMAND and EXIT. 

 The following RoboUnit implementation allows Robo4j-Brick-Client to accept following POST request
{ 
  "commands" : [
    {"name" : "hand",
     "target" : "hand_unit",
     "value" : "command"}
  ]
}

And this is not all we can add additional properties to the command as following example 
{ 
  "commands" : [
    {"name" : "hand",
     "target" : "hand_unit",
     "value" : "command"},
     {"name" : "move",
     "target" : "platform",
     "value" : "20",
     "speed" : "400"
     }
  ]
}
...but more in the upcoming posts... 
Stay tuned!!!