@@ -314,7 +314,7 @@ public string HardwareInterface {
314314 get { return "hardware_interface::PositionJointInterface" ; }
315315 }
316316
317- ControllerStateEnum _state ;
317+ ControllerStateEnum _state = ControllerStateEnum . Uninitialized ;
318318 /// <summary>
319319 /// Returns controller state of Stopped, Initialize, or Running
320320 /// </summary>
@@ -395,32 +395,50 @@ public ControllerStateMessage ControllerStateMessage {
395395 /// </summary>
396396 public void LoadController ( ) {
397397 Debug . Log ( "INFO: ZOArmController::Load" ) ;
398+ if ( ControllerState != ControllerStateEnum . Uninitialized && ControllerState != ControllerStateEnum . Terminated ) {
399+ Debug . LogError ( "ERROR: Cannot load arm controller in current state: " + ControllerState . ToString ( ) ) ;
400+ return ;
401+ }
398402 Initialize ( ) ; // BUGBUG: we should separate initialized into load -> start calls
399403 ControllerState = ControllerStateEnum . Initialized ;
404+ _actionServer . OnGoalReceived += OnActionGoalReceived ;
405+ _actionServer . OnCancelReceived += OnActionCancelReceived ;
406+
400407 }
401408
402409 /// <summary>
403410 /// Implements ROS Controller Unload
404411 /// </summary>
405412 public void UnloadController ( ) {
406413 Debug . Log ( "INFO: ZOArmController::Unload" ) ;
414+ if ( ControllerState == ControllerStateEnum . Uninitialized || ControllerState == ControllerStateEnum . Terminated ) {
415+ Debug . LogError ( "ERROR: Cannot unload arm controller in current state: " + ControllerState . ToString ( ) ) ;
416+ return ;
417+ }
418+
407419 Terminate ( ) ;
408420 ControllerState = ControllerStateEnum . Terminated ;
421+ _actionServer . OnGoalReceived -= OnActionGoalReceived ;
422+ _actionServer . OnCancelReceived -= OnActionCancelReceived ;
409423 }
410424
411425 public void StartController ( ) {
412426 Debug . Log ( "INFO: ZOArmController::Start" ) ;
427+ if ( ControllerState != ControllerStateEnum . Initialized && ControllerState != ControllerStateEnum . Stopped ) {
428+ Debug . LogError ( "ERROR: Cannot start arm controller in current state: " + ControllerState . ToString ( ) ) ;
429+ return ;
430+ }
413431 ControllerState = ControllerStateEnum . Running ;
414- _actionServer . OnGoalReceived += OnActionGoalReceived ;
415- _actionServer . OnCancelReceived += OnActionCancelReceived ;
416-
417432 }
418433
419434 public void StopController ( ) {
420435 Debug . Log ( "INFO: ZOArmController::Stop" ) ;
436+ if ( ControllerState != ControllerStateEnum . Running ) {
437+ Debug . LogError ( "ERROR: Cannot stop arm controller in current state: " + ControllerState . ToString ( ) ) ;
438+ return ;
439+ }
440+
421441 ControllerState = ControllerStateEnum . Stopped ;
422- _actionServer . OnGoalReceived -= OnActionGoalReceived ;
423- _actionServer . OnCancelReceived -= OnActionCancelReceived ;
424442 }
425443
426444 #endregion // ZOROSControllerInterface
@@ -448,7 +466,7 @@ private void Initialize() {
448466 // advertise joint state
449467 ROSBridgeConnection . Advertise ( ControllerManager . Name + "/arm_controller/state" , JointTrajectoryControllerStateMessage . Type ) ;
450468
451-
469+
452470
453471 }
454472
@@ -490,43 +508,56 @@ public Task OnControlMessageReceived(ZOROSBridgeConnection rosBridgeConnection,
490508
491509
492510 /// <summary>
493- /// This is a FollowJointTrajectoryActionMessage action responder. Usually used by MoveIt.
511+ /// FollowJointTrajectoryActionMessage action goal responder. Usually used by MoveIt.
494512 /// </summary>
495513 /// <param name="actionServer"></param>
496514 /// <param name="goalMessage"></param>
497515 /// <returns></returns>
498516 Task OnActionGoalReceived ( ZOROSActionServer < FollowJointTrajectoryActionMessage , FollowJointTrajectoryActionGoal > actionServer , FollowJointTrajectoryActionGoal goalMessage ) {
499517
500- Debug . Log ( "INFO: ZOArmController::OnGoalReceived" ) ;
501-
502- // automatically acccept new goal
503- // TODO: perhaps more complex logic? are there conditions where we will not accept a new goal?
504- actionServer . AcceptNewGoal ( goalMessage ) ;
505-
506- Debug . Log ( $ "INFO: Goad id: { goalMessage . goal_id . id } : with number of points: { goalMessage . goal . trajectory . points . Length } ") ;
507-
508- _currentGoalTime = 0 ;
518+ Debug . Log ( "INFO: ZOArmController::OnActionGoalReceived" ) ;
519+ if ( ControllerState == ControllerStateEnum . Terminated || ControllerState == ControllerStateEnum . Uninitialized ) {
520+ Debug . LogError ( "INFO: ZOArmController::OnActionGoalReceived invalid controller state: " + ControllerState . ToString ( ) ) ;
521+ actionServer . SetRejected ( "Controller not initialized" ) ;
522+ } else {
523+ if ( ControllerState != ControllerStateEnum . Running ) {
524+ StartController ( ) ;
525+ }
526+ actionServer . AcceptNewGoal ( goalMessage ) ;
527+ Debug . Log ( $ "INFO: Accepted Goal id: { goalMessage . goal_id . id } : with number of points: { goalMessage . goal . trajectory . points . Length } ") ;
528+ _currentGoalTime = 0 ;
529+ }
509530
510531 return Task . CompletedTask ;
511532 }
512533
534+ /// <summary>
535+ /// FollowJointTrajectoryActionMessage action cancel responder. Usually used by MoveIt.
536+ /// </summary>
537+ /// <param name="actionServer"></param>
538+ /// <param name="goalID"></param>
539+ /// <returns></returns>
513540 Task OnActionCancelReceived ( ZOROSActionServer < FollowJointTrajectoryActionMessage , FollowJointTrajectoryActionGoal > actionServer , GoalIDMessage goalID ) {
514541
515542 Debug . Log ( "INFO: ZOArmController::OnCancelReceived" ) ;
543+
544+ if ( ControllerState == ControllerStateEnum . Running ) {
545+ // Stop Controller
546+ StopController ( ) ;
547+ }
548+
516549 // confirm cancellation to the action server
517550 actionServer . SetCanceled ( ) ;
518551
519552 return Task . CompletedTask ;
520-
521-
522553 }
523554
524555 #endregion
525556
526557
527558 #region ZOSerializationInterface
528559
529- public string Type {
560+ public override string Type {
530561 get => "controller.arm_controller" ;
531562 }
532563
0 commit comments