ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Does this if/else statement make sense?

asked 2016-10-06 16:04:56 -0600

215 gravatar image

I am currently struggling with an simple if else statement that will not work as I want it to.

I am currently having issues entering the else state of this piece of code, and have no idea why this is the case.

This is the if/else statement.

  if(global_state == false)
  {
    //do nothing
  }
  else 
  { 
    digitalWrite(en_pin,HIGH);
    delay(1);

    unsigned int steps_to_speed;  // Steps required to achieve the the speed desired
    unsigned int acceleration_step_limit; // If desired speed is not achieved, will this variable contain step_limit to when to stop accelerating.

    if (motor_steps < 0)
    {
      profile.dir = CCW;
      motor_steps = -motor_steps;
      digitalWrite(dir_pin,LOW);
    }
    else
    {
      profile.dir = CW;
      digitalWrite(dir_pin,HIGH);
    }

    delay(1);

  // If moving only 1 step.
    if (motor_steps == 1)
    {
    // Move one step
      profile.accel_count = -1;
    // in DECEL state.
      profile.run_state = DECEL;
    // Just a short delay so main() can act on 'running'.
      profile.first_step_delay = 1000;
      OCR1A = 10;
    // Run Timer/Counter 1 with prescaler = 8.
      TCCR1B |= ((0 << CS12) | (1 << CS11) | (0 << CS10));
    }  
    else if (motor_steps != 0)
    {
    // Set max speed limit, by calc min_delay to use in timer.
    // min_delay = (alpha / tt)/ w
      profile.min_time_delay = A_T_x100 / motor_speed;

    // Set accelration by calc the first (c0) step delay .
    // first_step_delay = 1/tt * sqrt(2*alpha/accel)
    // first_step_delay = ( tfreq*0.676/100 )*100 * sqrt( (2*alpha*10000000000) / (accel*100) )/10000
      profile.first_step_delay = (T1_FREQ_148 * sqrt(A_SQ / motor_accel)) / 100;

    // Find out after how many steps does the speed hit the max speed limit.
    // steps_to_speed = speed^2 / (2*alpha*accel)
      steps_to_speed = (long)motor_speed * motor_speed / (long)(((long)A_x20000 * motor_accel) / 100);
    // If we hit max speed limit before 0,5 step it will round to 0.
    // But in practice we need to move atleast 1 step to get any speed at all.
      if (steps_to_speed == 0) 
      {
        steps_to_speed = 1;
      }

      // Find out after how many steps we must start deceleration.
      // n1 = (n1+n2)decel / (accel + decel)
      acceleration_step_limit = ((long)motor_steps * motor_decel) / (motor_accel + motor_decel);
      // We must accelrate at least 1 step before we can start deceleration.
      if (acceleration_step_limit == 0) 
      {
        acceleration_step_limit = 1;
      }

      // Use the limit we hit first to calc decel.
      if (acceleration_step_limit <= steps_to_speed) 
      {
        //profile.decel_length = steps_to_speed - motor_steps;
        profile.decel_length = -(motor_steps-acceleration_step_limit); //---
      }
      else 
      {
        //profile.decel_length = -((long)steps_to_speed * acceleration_step_limit) / motor_decel;acceleration_step_limit
        profile.decel_length = -((long)steps_to_speed * motor_accel) / motor_decel; //--
      }
      // We must decelrate at least 1 step to stop.
      if (profile.decel_length == 0) 
      {
        profile.decel_length = -1;
      }

      // Find step to start decleration.
      //int steps_in_run = motor_steps - steps_to_speed-profile.decel_length;

      profile.decel_start = motor_steps + profile.decel_length;
    //profile.decel_start = motor_steps - steps_to_speed-steps_in_run;

    // If the maximum speed is so low that we dont need to go via accelration state.
      if (profile.first_step_delay <= profile.min_time_delay)
      { 
        profile.first_step_delay = profile.min_time_delay;
        profile.run_state = RUN;
      }
      else
      {
        profile.run_state = ACCEL;
      }

    // Reset counter.
      profile.accel_count = 0;
      OCR1A = 10;
    // Set Timer/Counter to divide clock by 8
      TCCR1B |= ((0 << CS12) | (1 << CS11) | (0 << CS10));

    }

      while(1)
      {
        cli();
        status_step_count.data = profile.moved_steps;
        sei();
        chatter.publish( &status_step_count);
        nh.spinOnce();    
        delay(1);
      }

  }

The code should enter the else state when global_state becomes true, but even thoug it becomes true will the code never enter the else statement, the global state becomes true when node writes to the subscriber attached to the nodehandler.

std_msgs::Int16 ...
(more)
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

answered 2016-10-07 02:07:10 -0600

KenYN gravatar image

Your code is basically

if (!global_state)
{
}
else
{
    // Whatever
}

while (true)
{
    ros::spin();
}

So, basically your code never exits the bottom loop, so can never get back up to the top!

edit flag offensive delete link more

Comments

The while is actually inside the else

alienmon gravatar image alienmon  ( 2016-10-07 03:42:00 -0600 )edit
1

answered 2016-10-07 06:04:27 -0600

Airuno2L gravatar image

updated 2016-10-07 06:47:13 -0600

My first guess would be that since spinOnce is in the else statement, and the else statement is never getting called, your node is just starting, checking the state of global_state once, then closing (i.e. the callback never has a chance to get called). There should be an outer while loop that contains your if and else statements, then spinOnce.

One more note, global variables can usually be avoided by writing your code as a class, then global_state can be a member variable, the callback can be a member function, and the while loop containing spinOnce can be in the class's constructor. A few tips on that can be found here.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-10-06 16:04:56 -0600

Seen: 653 times

Last updated: Oct 07 '16