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 -1
và 1
có -1
nghĩ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 0
là đầ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.4
tô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.0f
và 1.0f
. 1.0f
có 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?