While loop problems

Discussion in 'C' started by brucelee8162, Aug 17, 2007.

Thread Status:
Not open for further replies.
  1. brucelee8162

    brucelee8162 Banned

    Joined:
    Aug 17, 2007
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    Hi there. I'm really hoping someone can help me with this strange problem. I've asked elsewhere but got no answer. The problem is this:

    cr8_set_speed(speed,0);
    while((self->dist-startdist)<distance)
    {
    printf("%f\n",self->dist);
    }
    cr8_set_speed(0,0);

    I'm programming a iRobot Create and the code above makes the robot move forward a certain distance and then it stops. The while loop exits when the printf statement is there, but as soon as I take it away, the while loop never finishes! Whats going on? I'm thinking its some sort of weird compiler error. Any ideas? I know this while loop condition is correct because it works when the printf statement is there.
     
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Just have self->dist into separate variable and let us know the values of each of the following
    self->dist, startdist and the distance
     
  3. DaWei

    DaWei New Member

    Joined:
    Dec 6, 2006
    Messages:
    835
    Likes Received:
    5
    Trophy Points:
    0
    Occupation:
    Semi-retired EE
    Location:
    Texan now in Central NY
    Home Page:
    http://www.daweidesigns.com
    Unless self->dist-startdist or distance is a volatile variable, being changed independently, you are doing nothing to alter the while condition. If it is a volatile variable, you need to specify that so that the compiler doesn't optimize away the read.
     
  4. brucelee8162

    brucelee8162 Banned

    Joined:
    Aug 17, 2007
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    Hi thanks for your help everyone, I added the volatile word in front of all my struct variables, which are updated by a separate thread every 15ms. The drive_straight() function is working now, and so is the turn_right() function. But for some reason the turn_left() and reverse functions, which are basically copies of the other two are still not working! Any ideas? Here are the functions:
    Code:
    reverse():
    
    startdist = self->dist;
        cr8_set_speed(-speed,0);
        while((startdist-self->dist)<distance)
        {printf("%f\n",(startdist-self->dist));
        }
        cr8_set_speed(0,0);
    
    turn_left():
    
    int16_t endAngle = self->angle - angle;
      int16_t tempangle = 0;
      if(endAngle <= 0)
      {
        endAngle = endAngle + 360;
      }
    
        cr8_set_speed(0, turnspeed);
    
        if(self->angle < endAngle)
        {
          while(self->angle < endAngle)
          { 
          }
        }
        while(self->angle > endAngle)
        {
        }
        cr8_set_speed(0,0);
     
    Last edited by a moderator: Aug 17, 2007
  5. DaWei

    DaWei New Member

    Joined:
    Dec 6, 2006
    Messages:
    835
    Likes Received:
    5
    Trophy Points:
    0
    Occupation:
    Semi-retired EE
    Location:
    Texan now in Central NY
    Home Page:
    http://www.daweidesigns.com
    What language is this? It certainly isn't standard C.

    At any rate, you have a printf statement in the reverse function, what is it telling you?

    And please note that Shabbir has kindly provided code tags for you. It's rude to ask for free help if you can't spare the time to read the "Before you make a query" thread, in return.
     
  6. brucelee8162

    brucelee8162 Banned

    Joined:
    Aug 17, 2007
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    Hi. I can't find the "before you make a query" thread and I don't know what code tags are so, sorry. The code I posted is standard C, the function you see there are ones that I have written. The printf function is telling me the distance the robot has travelled. The dist variable is static and the self->dist is the robots distance travelled total. The strange thing is that the printf outputs "0.000000" when it should be incrementing. I've tried this in the forward() function and this does indeed increment. Any ideas?
     
  7. DaWei

    DaWei New Member

    Joined:
    Dec 6, 2006
    Messages:
    835
    Likes Received:
    5
    Trophy Points:
    0
    Occupation:
    Semi-retired EE
    Location:
    Texan now in Central NY
    Home Page:
    http://www.daweidesigns.com
    This is not standard C notation for a function:
    The only use of a ':' in C is as a label identifier. A function (such as reverse ()) supposedly is) has to have the entire function blocked. Without braces, only the first line would constitute the body of the function. The snippet shown will not, in fact, compile without error in a C compiler.

    It is impossible to judge the validity of your logic without knowing about the language you are using.

    If you look at the very top right corner of this page, you will see 5 links. The 3rd one is the "before" link.
     
  8. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    The link is here and the it can also be found in the top right corner of every page of the forum.
     
  9. brucelee8162

    brucelee8162 Banned

    Joined:
    Aug 17, 2007
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    Hi. I have read the before you make a query thread. Sorry that I confused you before, the "reverse():" notation was my own just to indicate that below was PART of my reverse function. So yes, it is standard C. I can post both of my forward and reverse functions if you want. Here they are:

    Code:
    //Moves robot at specified speed for user specified distance
    void drive_straight(float distance)
    {
      float startdist = 0;
      if(distance != 0)
      {
        startdist = self->dist;
        cr8_set_speed(speed,0);
        while((self->dist-startdist)<distance)
        {printf("%f\n",(startdist-self->dist));
        }
        cr8_set_speed(0,0);
      }
      else
      {
        //user control, move forward at set speed until user stops
        if(self->stop == 0)
          cr8_set_speed(speed,0);
      }
    }
    
    //Moves robot at specified speed for user specified distance
    void reverse(float distance)
    {
      float startdist = 0;
      if(distance != 0)
      {
        startdist = self->dist;
        cr8_set_speed(-speed,0);
        while((startdist-self->dist)<distance)
        {printf("%f\n",(startdist-self->dist));
        }
        cr8_set_speed(0,0);
      }
      else
      {
        //user control, move forward at set speed until user stops
        if(self->stop == 0)
          cr8_set_speed(-speed,0);
      }
    }
    
    Ok. There you go. As you can see the functions are virtually the same apart from the speed argument. The first if statement in each function with get executed as I am passing drive_straight(0.1) and reverse(0.1) to them. The else part is for user control, so do not worry about that. Any ideas guys?
     
  10. brucelee8162

    brucelee8162 Banned

    Joined:
    Aug 17, 2007
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    anyone? please, don't hate me cos I didn't read the before you post thread :(
     
  11. DaWei

    DaWei New Member

    Joined:
    Dec 6, 2006
    Messages:
    835
    Likes Received:
    5
    Trophy Points:
    0
    Occupation:
    Semi-retired EE
    Location:
    Texan now in Central NY
    Home Page:
    http://www.daweidesigns.com
    Okay, you have the printf function. It is telling you that startdist-self->dist is zero. You don't have to like that, but you have to deal with it. Actually, you are causing it. You make the assignment startdist = self->dist. They are now equal, whatever they are. When you subtract them you will get zero. Right?
     
  12. brucelee8162

    brucelee8162 Banned

    Joined:
    Aug 17, 2007
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    that is correct. but that assignment is not made within the while loop, its outside it. And this obviously isnt whats causing it cos I have the same bit of code for going forwards and that works. Any other ideas?
     
  13. DaWei

    DaWei New Member

    Joined:
    Dec 6, 2006
    Messages:
    835
    Likes Received:
    5
    Trophy Points:
    0
    Occupation:
    Semi-retired EE
    Location:
    Texan now in Central NY
    Home Page:
    http://www.daweidesigns.com
    It IS what's causing it. It's setting it up initially. You are doing NOTHING in the while loop to change the condition.

    It is possible that something should be happening outside this code that changes one of those variables. We can't know that, can we? It's YOUR code, it's YOUR system, we see only what you choose to show us. If this outside agent that is supposed to make your code work isn't working, FIX IT.
     
  14. brucelee8162

    brucelee8162 Banned

    Joined:
    Aug 17, 2007
    Messages:
    7
    Likes Received:
    0
    Trophy Points:
    0
    I've already said that another thread is responsible for updating the self->dist value, so yes you did know that, and I'm posting this because I'm asking for help because I can't fix it, comprende? Here's the thread code:

    Code:
    volatile int bStop = false;
    
    void * runMe(void * nouse)
    {
       // Do this until we are told to stop
       while (!bStop)
       {
          cr8_delay(15);
          cr8_update();
          pthread_yield();
       }
       
       return NULL;
    }
    
    And yes, the above gets called from the main() function. Don't worry I'll ask elsewhere if you dont know.
     
  15. DaWei

    DaWei New Member

    Joined:
    Dec 6, 2006
    Messages:
    835
    Likes Received:
    5
    Trophy Points:
    0
    Occupation:
    Semi-retired EE
    Location:
    Texan now in Central NY
    Home Page:
    http://www.daweidesigns.com
    You are incorrect. You can tell us that something is happening outside the thread, bet we can't KNOW that something is happening because we aren't at your machine.

    If you go back to the code you've shown previously and replace printf("%f\n",(startdist-self->dist)); with printf("%f\n",(self->dist)); and self->dist doesn't change, then you'll know that something is or is not happening outside that function.

    There is no mention of self->dist in your other thread's code. Possibly cr8_update is supposed to change self->dist. We cannot know that, we are not at your machine and we can't even see code that you don't bother to show us.

    It seems you don't like my attitude, but I'm giving you all the help that I can give remotely, given the paucity of information you supply.

    Thread closed.
     
Thread Status:
Not open for further replies.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice