Chức năng khen thưởng cho q học trên robot


7

Tôi có robot điều khiển vi sai 2 bánh mà tôi sử dụng pid để điều khiển mức thấp để theo dõi. Tôi đã triển khai q learning sử dụng các mẫu cho 16 lần lặp sau đó sử dụng chúng để quyết định vị trí tốt nhất trên đường để xe hơi rẽ vào đó. Điều này cho phép PID thiết lập và làm mượt nhanh chóng. Câu hỏi của tôi là làm thế nào tôi có thể thiết lập chức năng phần thưởng để cải thiện hiệu suất, tức là cho phép học q tìm ra thứ tốt nhất

Biên tập

Những gì nó cố gắng học là cái này, nó có 16 đầu vào chứa các vị trí dòng cho 15 lần lặp cuối cùng và lần lặp này. Vị trí đường nằm giữa -11-1nghĩa là chỉ còn lại hầu hết cảm biến nhìn thấy đường và 0 có nghĩa là đường nằm ở giữa. Tôi muốn nó học một vị trí đường mà khi nó phải đối mặt với đầu vào này một lần nữa, nó sẽ đặt vị trí đường đó giống như tâm của nó và lấy đường cong theo vị trí đường đó. Ví dụ lỗi là vị trí bắt buộc - vị trí đường vì vậy giả sử tôi có 16 0là đầu vào sau đó tôi tính toán yêu cầu là 0.4. Vì vậy, sau đó chiếc xe sẽ tự tập trung tại 0.4tôi hy vọng điều này sẽ giúp :)

Bạn hỏi mã nguồn của tôi, tôi đăng nó dưới đây

void MainController::Control(void){

    float linePosition = sensors->ReadSensors();

    if(linePosition == -2.0f){       
      lost_line->FindLine(lastPos[1] - lastPos[0]);
    } 
    else{
        line_follower->Follow(linePosition);
        lastPos.push_back(linePosition);
        lastPos.erase(lastPos.begin());   
    }
}

Đọc cảm biến của tôi trả về một giá trị giữa -1.0f1.0f. 1.0fcó nghĩa là cảm biến bên ngoài ở bên phải chỉ là dòng. Tôi có 8 cảm biến.

void LineFollower::Follow(float LinePosition){

    float requiredPos = Qpredictor.Process(LinePosition,CurrentSpeed);
    float error = requiredPos - LinePosition;

    float ErrorDer = error -LastError;

    float diffSpeed = (KpTerm * error + (KdTerm * ErrorDer));

    float RightMotorSpeed = CurrentSpeed - diffSpeed;
    float LeftMotorSpeed = CurrentSpeed + diffSpeed;

    LastError = error;

    driver->Drive(LeftMotorSpeed,RightMotorSpeed);
}

Đây là logic cho giá trị cho QPredictor (tôi gọi phần học tập là thế này). Và cuối cùng là QPredictor

float Memory[MemorySize][DataVectorLength] =
{
  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
  {0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3},
  {0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6},
  {0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8},

  {0.000, 0.012, 0.050, 0.113, 0.200, 0.312, 0.450, 0.613, 0.800, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.012, 0.050, 0.113, 0.200, 0.312, 0.450, 0.613, 0.800, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.012, 0.050, 0.113, 0.200, 0.312, 0.450, 0.613, 0.800, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.012, 0.050, 0.113, 0.200, 0.312, 0.450, 0.613, 0.800, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.012, 0.050, 0.113, 0.200, 0.312, 0.450, 0.613, 0.800, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.012, 0.050, 0.113, 0.200, 0.312, 0.450, 0.613, 0.800, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.012, 0.050, 0.113, 0.200, 0.312, 0.450, 0.613, 0.800, 1.000},

  {0.000, 0.025, 0.100, 0.225, 0.400, 0.625, 0.900, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},

  {0.000, 0.050, 0.200, 0.450, 0.800, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},


  {0.000, 0.100, 0.400, 0.900, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.100, 0.400, 0.900, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.100, 0.400, 0.900, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.100, 0.400, 0.900, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.400, 0.900, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.400, 0.900, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.400, 0.900, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.400, 0.900, 1.000, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.400, 0.900, 1.000, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.400, 0.900, 1.000, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.400, 0.900, 1.000, 1.000},
  {0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.100, 0.400, 0.900, 1.000}
};


QPredictor::QPredictor(){
    for(int i=0;i<MemorySize;i++){
        output[i]=0.0f;
        input[i]=0.0f;
    }

    state = 0;
    PrevState = 0;
}

float QPredictor::Process(float linePosition,float currentBaseSpeed){
    for(int i=1;i<DataVectorLength;i++){
        input[i] = input[i-1];
    }

    input[0] = m_abs(linePosition);

    int MinIndex = 0;
    float Distance = 10000.0f;

    float sum = 0.0f;

    for(int i=0;i<MemorySize;i++){
        sum = 0.0f;
        for(int j=0;j<DataVectorLength;j++){
            sum +=m_abs(input[j] - Memory[i][j]);
        }

        if(sum <= Distance){
            MinIndex = i;
            Distance = sum;     
       }
    }

    sum = 0.0f;
    for(int i=0;i<DataVectorLength;i++){
        sum += input[i];
    }

    float eta = 0.95f;

    output[MinIndex] = eta * output[MinIndex] + (1 - eta) * sum;

    return -m_sgn(linePosition) * output[MinIndex];
}


float QPredictor::rewardFunction(float *inputData,float currentBaseSpeed){
    float sum = 0.0f;

    for(int i=0;i<DataVectorLength;i++){
        sum += inputData[i];
    }

    sum /= DataVectorLength;

    return sum;
}

Bây giờ tôi chỉ có Lỗi trung bình và hiện không sử dụng việc học vì nó không hoàn thành nếu không có chức năng khen thưởng. Làm cách nào tôi có thể điều chỉnh nó theo kích thước của Robot của tôi?


1
Tôi nghĩ rằng câu hỏi của bạn cần một số cải tiến trước khi nó có thể được trả lời. Ví dụ, bạn đang cố gắng học gì? Các thông số PID? Mục tiêu của bạn cho hành vi hệ thống cuối cùng là gì?
Jakob


Mảng bộ nhớ lưu trữ trải nghiệm quá khứ của robot, không phải tương lai. Phần thưởng tiêu cực phải được đưa ra nếu tất cả các yếu tố mảng là màu trắng. Đối với các đường cong đơn giản, điều này sẽ làm việc.
Manuel Rodriguez

Vâng, điều đó có ý nghĩa nhưng nếu tôi không mất dòng thì làm sao tôi có thể tăng hoặc giảm phần thưởng hay hình phạt
Ege Keyvan

+1 cho lần thử; Bạn có thể sử dụng một webcam đơn giản để xác nhận; Sử dụng kiểm tra đơn giản để xác định mức độ gần gũi của robot với trung tâm của dòng. Sau đó, sử dụng phần đó và thêm phần thưởng (như +1 cho biết "tiếp tục đi trên làn đường" mỗi giây) và hình phạt (nếu một trong các bánh xe vượt qua vạch; -50 cho mỗi giây).
Prasad Raghavendra

Câu trả lời:


0

Điều khiển PID thích ứng dựa trên thuật toán mã hóa thủ công cho dòng tiếp theo được sửa đổi bằng cách học tăng cường. Ý tưởng là, trong chức năng PID, một tham số không xác định (ví dụ: khoảng cách từ đường có thể được chấp nhận là độ lệch) và tham số này sẽ được tính khi đang bay khi lái robot. Phần thưởng được đưa ra bằng tay bởi một nhà điều hành Clicker đào tạo hoặc có thể được xác định trong một vòng lặp. Robot đang lái một chiếc dù, thời gian được đo. Robot điều khiển các bưu kiện một lần nữa và mục tiêu là giảm thời gian.


Tôi đã nhìn thấy nó nhưng tôi có bản đồ kohonen và q học rằng tôi sử dụng kohonen để phân cụm vectơ đầu vào và sử dụng q học để quyết định đầu ra tôi có thể điều chỉnh hệ thống này với tôi không?
Ege Keyvan

Chắc chắn, bản đồ tự tổ chức có thể được sử dụng làm bộ nhớ kết hợp (Q-KOHON, Claude F. Touzet).
Manuel Rodriguez

Bạn có đề nghị theo đầu vào hệ thống nên thay đổi các tham số?
Ege Keyvan

@EgeKeyvan: vui lòng đăng soucecode của bạn hoặc ảnh chụp màn hình GUI NXT-G
Manuel Rodriguez

Tôi đã đăng nó ngay bây giờ
Ege Keyvan 17/8/2016

0

Tôi nghĩ rằng Q-learning là một sự quá mức cho một vấn đề theo dõi đơn giản như vậy. Tôi thực sự khuyên bạn nên sử dụng một phương pháp đơn giản hơn, cụ thể là bộ điều khiển theo dõi theo đuổi thuần túy. Dưới đây là một số liên kết mà bạn có thể đọc về phương pháp. Trang của Matlab về chủ đề này khá gọn gàng.

Bộ điều khiển theo đuổi thuần túy của Matlab

Thực hiện thuật toán theo dõi đường dẫn thuần túy

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.