LCOV - code coverage report
Current view: top level - src/Kinematics - RobotController.cpp (source / functions) Hit Total Coverage
Test: HLR Lines: 1 124 0.8 %
Date: 2018-01-16 18:35:13 Functions: 2 21 9.5 %

          Line data    Source code
       1             : #include "RobotController.hpp"
       2             : 
       3             : #include "HLR/ObjectMoveStart.h"
       4             : #include "InterpolatingAnglePlanner.hpp"
       5             : 
       6             : namespace HLR
       7             : {
       8             : namespace Kinematics
       9             : {
      10           0 : RobotController::RobotController(RobotDriverHandler& driver) : driver(driver)
      11             : {
      12           0 :     this->events.push(Event::move_to_ready);
      13           0 :     this->worker = std::thread(&RobotController::event_handler, this);
      14           0 : }
      15             : 
      16           0 : RobotController::~RobotController()
      17             : {
      18           0 :     this->events.push(Event::terminate);
      19           0 :     this->worker.join();
      20           0 : }
      21             : 
      22           0 : RobotControllerState RobotController::get_state() const
      23             : {
      24           0 :     std::lock_guard<std::mutex> l(this->state_m);
      25           0 :     return this->state;
      26             : }
      27             : 
      28           0 : void RobotController::pick_up_cup(std::uint32_t id)
      29             : {
      30           0 :     std::lock_guard<std::mutex> l(this->state_m);
      31           0 :     if (this->state != RobotControllerState::idle)
      32             :     {
      33           0 :         throw std::logic_error("Robot is not currently idle.");
      34             :     }
      35             : 
      36             :     {
      37           0 :         std::lock_guard<std::mutex> l(this->objects_m);
      38           0 :         const auto it = this->objects.find(id);
      39           0 :         if (it == this->objects.end())
      40             :         {
      41             :             throw std::invalid_argument(
      42           0 :                 "No object found with the specified id.");
      43             :         }
      44             : 
      45           0 :         if (!it->second.is_cup)
      46             :         {
      47             :             throw std::invalid_argument(
      48           0 :                 "Specifed object exists but is not a cup.");
      49             :         }
      50           0 :         this->cup_position = it->second.position;
      51             :     }
      52             : 
      53           0 :     this->events.push(Event::pick_up_cup);
      54           0 : }
      55             : 
      56           0 : void RobotController::move_stop()
      57             : {
      58           0 :     std::lock_guard<std::mutex> l(this->state_m);
      59           0 :     switch (this->state)
      60             :     {
      61           0 :         case RobotControllerState::moving_to_cup:
      62           0 :             this->events.push(Event::move_stop);
      63           0 :             break;
      64           0 :         default:
      65           0 :             throw std::logic_error("Robot is is not currently moving.");
      66             :     }
      67           0 : }
      68             : 
      69           0 : void RobotController::move_continue()
      70             : {
      71           0 :     std::lock_guard<std::mutex> l(this->state_m);
      72           0 :     switch (this->state)
      73             :     {
      74           0 :         case RobotControllerState::stopped:
      75           0 :             this->events.push(Event::move_continue);
      76           0 :             break;
      77           0 :         default:
      78           0 :             throw std::logic_error("Robot is is not currently stopped.");
      79             :     }
      80           0 : }
      81             : 
      82           0 : void RobotController::move_cancel()
      83             : {
      84           0 :     std::lock_guard<std::mutex> l(this->state_m);
      85           0 :     switch (this->state)
      86             :     {
      87           0 :         case RobotControllerState::moving_to_cup:
      88             :         case RobotControllerState::stopped:
      89           0 :             this->events.push(Event::move_cancel);
      90           0 :             break;
      91           0 :         default:
      92             :             throw std::logic_error(
      93           0 :                 "Robot is is not currently stopped or moving.");
      94             :     }
      95           0 : }
      96             : 
      97           0 : void RobotController::remove_object(const EnvironmentObject& obj)
      98             : {
      99           0 :     std::lock_guard<std::mutex> l(this->objects_m);
     100           0 :     const auto it = this->objects.find(obj.id);
     101           0 :     if (it != this->objects.end())
     102             :     {
     103           0 :         this->objects.erase(it);
     104             :     }
     105           0 : }
     106             : 
     107           0 : void RobotController::add_object(EnvironmentObject&& obj)
     108             : {
     109           0 :     std::lock_guard<std::mutex> l(this->objects_m);
     110           0 :     auto it = this->objects.find(obj.id);
     111           0 :     if (it != this->objects.end())
     112             :     {
     113           0 :         auto id = obj.id;
     114           0 :         this->objects.insert(std::make_pair(id, std::move(obj)));
     115             :     }
     116             :     else
     117             :     {
     118           0 :         this->objects[obj.id] = obj;
     119             :     }
     120           0 : }
     121             : 
     122           0 : void RobotController::set_error_callback(
     123             :     const std::function<void(ArmError)>& cb)
     124             : {
     125           0 :     this->error_callback = cb;
     126           0 : }
     127             : 
     128           0 : void RobotController::move_to_position(const Matrix<double, 3, 1>& pos,
     129             :                                        const Planner& planner,
     130             :                                        double speed)
     131             : {
     132           0 :     auto path_opt = planner.get_path(this->driver.get_arm_state(), pos);
     133             : 
     134           0 :     if (!path_opt.has_value() && this->error_callback)
     135             :     {
     136           0 :         this->error_callback(ArmError::no_path_found);
     137           0 :         return;
     138             :     }
     139             : 
     140             :     try
     141             :     {
     142           0 :         this->driver.move(path_opt.value(), speed);
     143             :     }
     144           0 :     catch (const std::runtime_error& e)
     145             :     {
     146           0 :         if (this->error_callback)
     147             :         {
     148           0 :             this->error_callback(ArmError::driver_error);
     149             :         }
     150             :     }
     151             : }
     152             : 
     153           0 : void RobotController::event_handler()
     154             : {
     155           0 :     bool term = false;
     156           0 :     while (!term)
     157             :     {
     158           0 :         auto ev = this->events.pop();
     159           0 :         switch (ev)
     160             :         {
     161           0 :             case Event::move_to_ready:
     162           0 :                 this->move_to_ready_handler();
     163           0 :                 break;
     164           0 :             case Event::pick_up_cup:
     165           0 :                 this->pick_up_cup_handler();
     166           0 :                 break;
     167           0 :             case Event::move_stop:
     168           0 :                 this->move_stop_handler();
     169           0 :                 break;
     170           0 :             case Event::move_continue:
     171           0 :                 this->move_continue_handler();
     172           0 :                 break;
     173           0 :             case Event::move_cancel:
     174           0 :                 this->move_cancel_handler();
     175           0 :                 break;
     176           0 :             case Event::arm_move_complete:
     177           0 :                 this->arm_move_complete_handler();
     178           0 :                 break;
     179           0 :             case Event::terminate:
     180           0 :                 term = true;
     181           0 :                 break;
     182             :         }
     183             :     }
     184           0 : }
     185             : 
     186           0 : void RobotController::move_to_ready_handler()
     187             : {
     188           0 :     const InterpolatingAnglePlanner planner(this->angle_step_size);
     189           0 :     const double speed = 20;
     190           0 :     this->move_to_position(this->ready_pos, planner, speed);
     191           0 : }
     192             : 
     193           0 : void RobotController::pick_up_cup_handler()
     194             : {
     195           0 :     const InterpolatingAnglePlanner planner(this->angle_step_size);
     196             : 
     197             :     auto path_opt =
     198           0 :         planner.get_path(this->driver.get_arm_state(), cup_position);
     199             : 
     200           0 :     if (!path_opt.has_value() && this->error_callback)
     201             :     {
     202           0 :         this->error_callback(ArmError::no_path_found);
     203           0 :         return;
     204             :     }
     205             : 
     206             :     try
     207             :     {
     208           0 :         this->driver.move(path_opt.value(), 50);
     209             :     }
     210           0 :     catch (const std::runtime_error& e)
     211             :     {
     212           0 :         if (this->error_callback)
     213             :         {
     214           0 :             this->error_callback(ArmError::driver_error);
     215             :         }
     216             :     }
     217             : }
     218             : 
     219           0 : void RobotController::arm_move_complete_handler() {}
     220             : 
     221           0 : void RobotController::move_stop_handler() {}
     222             : 
     223           0 : void RobotController::move_continue_handler() {}
     224             : 
     225           0 : void RobotController::move_cancel_handler() {}
     226             : 
     227             : } // namespace Kinematics
     228           3 : } // namespace HLR

Generated by: LCOV version 1.12