রোবট সি সহ সাবস্কিপশন আর্কিটেকচারটি ব্যবহারের সঠিক উপায়


11

সাবসম্পশন আর্কিটেকচার সম্পর্কে আমি ইদানীং প্রচুর পড়ছি এবং লোকেরা অ্যাডভোকেট বলে মনে করার কয়েকটি ভিন্ন উপায় রয়েছে।

উদাহরণস্বরূপ কিছু লোক কোনও টাস্ক নিয়ন্ত্রণ নিতে একটি গ্লোবাল "পতাকা" ভেরিয়েবল ব্যবহার করে। অন্যরা endTimeSlice()সালিসটিকে সত্যই চয়ন করতে দেয় এবং মঞ্জুরি দেয়। এবং আমি মনে করি এটি সঠিক।

আমার কাছে রোবটসি কোডের এই ছোট্ট বিভাগটি রয়েছে যা আমি রোবোট অনুসরণ করে একটি লাইনের জন্য কাজ করছি তবে আমি নিশ্চিত না যে আমি ঠিক এটি করছি কারণ বর্তমানে ট্র্যাক পদ্ধতি সর্বদা অনুসন্ধানের পদ্ধতিটি গ্রহণ করবে। সঠিক প্রবাহটি হ'ল অনুসন্ধানটি লাইনটি সন্ধান করার জন্য একটি সর্পিল পথ ব্যবহার করে রোবটকে লাইনে পৌঁছে দেয়। একবার লাইনটি পাওয়া গেলে ট্র্যাকটি হাতে নেওয়া উচিত।

task evade(){
    if(SensorValue(forwardSonarSensor) > threshold){
            //box the obstruction
    }
}

task find(){
    if(SensorValue(lightSensor) > threshold){
            //spiral the robot
    }
}

task track(){

    if(SensorValue(lightSensor) < threshold){
            //go straight
    }else{
                //execute turns to follow the line
    }
}

task main(){
    while(true){
        StartTask(evade,9);
        StartTask(track,8);
        StartTask(find,7);
        wait1Msec(250);
    }
}

আমি এটিকে সংক্ষিপ্ত রাখতে প্রকৃত কোডের চেয়ে এখানে কিছু মন্তব্য ব্যবহার করেছি। আমার কি যদি বিবৃতিগুলি শর্ত হিসাবে যথেষ্ট ভাল না হয় কারণ যখন রোবটটি লাইন বন্ধ থাকে, তখন এটি track()গ্রহণ করে। এটি ট্র্যাকের মধ্যে অন্য বিবৃতি কারণে? যদি তাই হয়, track()প্রোগ্রামের শুরুতে ঘা থেকে নেওয়ার পরে যখন লাইনটি হারাতে থাকে তখন কীভাবে ঘুরিয়ে সঞ্চালন করবেন?


1
আপনি যে নম্বরটি দেন StartTask, সেগুলি কি কাজের অগ্রাধিকার? 9 কি সর্বোচ্চ অগ্রাধিকার পাবে? findসেক্ষেত্রে এর চেয়ে বেশি অগ্রাধিকার থাকা উচিত নয় track? আসলে শর্ত findelseঅবস্থা trackএকই। সুতরাং, একটি মানুষ হিসাবে, সেন্সর মান যদি প্রান্তিকের চেয়ে বড় হয়, আপনি কি করবেন? সর্পিল যেতে বা লাইন সামঞ্জস্য করতে চালু?
শাহবাজ

আমি জানি সাবস্ক্রিপশন আর্কিটেকচার কী, এবং আমি নিশ্চিত যে আপনার রোবোটগুলিতে নিম্ন স্তরের গণ্য কাজের জন্য বিভিন্ন হার্ডওয়ার মডিউল থাকা উচিত। এবং কোডটি কেবলমাত্র শর্তসাপেক্ষে শোনার পরিবর্তে সংকেতটি শোষণ করে নেওয়া উচিত। সুতরাং আপনি কি অন্য কোনও হার্ডওয়ারের সিগন্যালটি পাস করবেন না? এখন আমার সমস্যাটি হ'ল আমার একটি দুটি আরডুইনো রয়েছে এবং আমি চাইছি আরডুইনো এ আরডুইনো বি থেকে একটি সংকেত গ্রহণ করতে বা আটকাতে চাই। কীভাবে এটি করা হয় তার কোনও ধারণা আছে? যেহেতু আমি আরডুইনো এ এরডিনো বিতে একটি সংকেত প্রেরণ করতে পারি তবে আমি কীভাবে সিগ সাবমিট করতে বা আটকাতে পারি সে সম্পর্কে নিশ্চিত নই
এম্বিয়েন্ট সোডা

উত্তর:


7

Subsumption আর্কিটেকচার সঙ্গে, আপনি সাবধানে এমনভাবে আপনার আচরণে ডিজাইন উচিত যে আপনি যদি বরাদ্দ কাজের Tঅগ্রাধিকার n, তারপর Tহওয়া উচিত যদি উচ্চ অগ্রাধিকার দিয়ে সমস্ত কর্ম চেয়ে কি রোবট কি করা উচিত nউপেক্ষা করা হয়।

আসুন আপনার উদাহরণের কার্যগুলি অর্ডার করুন, তারপরে এটি কার্যকর করার কোনও উপায় বের করুন। আপনার কাজগুলি হয় evade, findএবং track

সাধারণভাবে আপনি রোবটটি একটি লাইন ট্র্যাক করতে চান। তবে এটি যদি লাইনটি সনাক্ত করতে না পারে তবে এটি সন্ধানের চেষ্টা করা উচিত। সর্বোপরি, এটির বাধা এড়ানো উচিত ade এটি আমাদের নিম্নলিখিত আদেশ দেয়:

  • সর্বোচ্চ অগ্রাধিকার: evade
  • তারপর: find
  • তারপর: track

কারণটির findতুলনায় উচ্চতর অগ্রাধিকার trackহ'ল, যেমন আমি উপরে উল্লেখ করেছি, আপনি trackকেবল তখনই প্রয়োজন evadeএবং findঅপ্রয়োজনীয়। যদি আপনি findনীচে রাখেন তবে এর trackঅর্থ আপনি লাইনে না থাকলেও কোনও বাধা না থাকলে আপনি ট্র্যাকিং শুরু করেন।

এখন আসুন আপনার বাস্তবায়নটি দেখুন:

task find(){
    if(SensorValue(lightSensor) > threshold){
            //spiral the robot
    }
}

task track(){

    if(SensorValue(lightSensor) < threshold){
            //go straight
    }else{
                //execute turns to follow the line
    }
}

মনে রাখবেন যে আমরা findএকটি উচ্চ অগ্রাধিকার দিয়েছি । সুতরাং, যদি রোবটটি অনুধাবন করতে না lightSensorপারে তবে লাইনটি সন্ধান করার চেষ্টা করে এটি সর্পিল হয়ে যাবে। এটি হয়ে গেলে, trackলাথি মেরে As আপনি দেখতে পাচ্ছেন, elseশর্তটি trackকখনই ঘটে না।

এটি কাজ করার সময়, রোবটটি খুব বিশ্রীভাবে চলত। আপনার রোবটের বর্তমান বিল্ডটি দেওয়াতে বাস্তবে এটি করার মতো অনেক কিছুই নেই।


যদিও আমি ইতিমধ্যে আপনার প্রশ্নের উত্তর দিয়েছি, তবে এখানে আপনার লাইন ট্র্যাকিংয়ের একটি সাধারণ উন্নতি রয়েছে:

একটি হালকা সেন্সরের পরিবর্তে দুটি ব্যবহার করুন; ls_leftএবং ls_right। (কমপক্ষে) দুটি সেন্সর ব্যবহার করে আপনি বুঝতে পারবেন যে আপনি পুরোপুরি ট্র্যাকের বাইরে রয়েছেন বা ট্র্যাকের বাইরে চলে যাচ্ছেন। দ্বিতীয় ক্ষেত্রে, আপনি সহজেই সঠিক দিকের দিকে ফিরে যেতে পারেন এবং ট্র্যাকটিতে ফিরে আসতে পারেন।

আপনার findকাজ সমান:

task find(){
    if (SensorValue(ls_left) > threshold
        && Sensorvalue(ls_right) > threshold){
            //spiral the robot
    }
}

এটি হ'ল, আপনি সর্পিলতার দিকে যান তবেই যদি আপনি কিছু বুঝতে পারেন না

আপনার trackকাজটি এখন আরও দক্ষ হয়:

task track(){

    if (SensorValue(ls_left) < threshold
        && SensorValue(ls_right) < threshold){
            //go straight
    } else if (SensorValue(ls_left) < threshold
        && SensorValue(ls_right) > threshold){
            //turn left
    } else if (SensorValue(ls_left) > threshold
        && SensorValue(ls_right) < threshold){
            //turn right
    } else {
            // shouldn't happen, but go on spiral anyway
    }
}

স্পষ্টতই, হালকা সেন্সরগুলির একটি ম্যাট্রিক্সের সাহায্যে আপনি আরও ভালভাবে বিচার করতে পারবেন যে আপনি কীভাবে খারাপভাবে ট্র্যাকের বাইরে চলে যাচ্ছেন (অর্থাত্ কোন কোণ দিয়ে) এবং কীভাবে ট্র্যাকটিতে ফিরে যাবেন (যেমন কোন কৌণিক গতির সাথে) তা আরও ভালভাবে সিদ্ধান্ত নিতে পারেন।


4

সংক্ষিপ্ত উত্তর; না আপনাকে কিছুটা আলাদাভাবে করা দরকার।

দীর্ঘ অপূর্ণ উত্তর; আমি আপনাকে রোবটসির জন্য উপযুক্ত কিছু স্যুইডো কোড দেব যা এটি আপনাকে আরও ভাল পথে চালিত করে। প্রথমত, টাস্কগুলি ব্যবহার করবেন না - এটি রোবটসি কাজের জন্য নয়। এগুলি কাজ করার জন্য তৈরি হতে পারে, সম্ভবত নাও হতে পারে (এবং চেষ্টা করার জন্য আপনার বেশ কয়েকটি পরিবর্তন দরকার)।

// global variables
int distance;
int light;

main() {
   while (true) {
   distance = read_distance;
   light = read_light;
   if (task1_wantsToRun())
     task1_run();
   if (task2_wantsToRun())
     task2_run();   
   }
}

এখানে বেশ কয়েকটি জিনিস রয়েছে; অগ্রাধিকার অপ্রাসঙ্গিক হয়ে যায়। অগ্রাধিকার সহ রোবটসিতে কাজগুলি যেমন মনে হয় ঠিক তত সুন্দর, তারা আমার অভিজ্ঞতায় সাবস্ক্রিপশন বাস্তবায়নের জন্য ভাল পছন্দ নয়। এর মতো কারণে, অগ্রাধিকার সর্বদা সম্মানিত হয় না, কার্যগুলিতে বাধা দেওয়া যায় না (কখনও কখনও) সুতরাং যখন কোনও উচ্চ অগ্রাধিকারের ঘটনাটি ঘটে তখন এটি আপনার প্রত্যাশা মতো প্রতিক্রিয়া করে না, রোবটসি সম্প্রতি সম্প্রতি পুনরায় প্রবেশকারী হয়ে ওঠে, সুতরাং সেন্সর অ্যাক্সেস করার মতো জিনিসগুলি 1 টিরও বেশি টাস্ক থেকে ঝুঁকিপূর্ণ (আই 2 সি টাইমিং ইস্যু) হতে পারে এবং কিছু ক্ষেত্রে এটি (স্বয়ংক্রিয়ভাবে সেন্সর পোলড) হয় না।

জিনিসগুলি কাজ করতে করতে আপনি উপরের লুপটিতে আপনার নিজের অগ্রাধিকার বাস্তবায়ন যুক্ত করতে পারেন তবে এটি শুরু করার জন্য সত্যই প্রয়োজন হয় না।

আপনার মন্তব্য "// বক্স বাধা" একটি ব্যালিস্টিক আচরণ বর্ণনা করে। এগুলি মাল্টি-টাস্কিং ব্যবহার করে প্রয়োগ করা কিছুটা জটিল। আমি যে সাধারণ লুপটি ব্যবহার করেছি এটি এটিকে অনেক সহজ এবং প্রারম্ভিক / শেখার জন্য আরও ভাল করে তোলে।

আমি আপনাকে অন্য যে জিনিসটি রেখে যাচ্ছি, তা হ'ল পরিচ্ছন্নতা এবং অনেক কিছুর জন্য উপযুক্ত হওয়ার পরেও, traditionতিহ্যগতভাবে আরও ভালভাবে কী করা হয় তা কার্যকর করার কোনও ভাল উপায় নয়। প্রকৃতপক্ষে 'এ্যাডে' অংশটি গ্রাহকের পক্ষে ভাল প্রার্থী হতে পারে তবে সত্যই আপনার অন্য কাজটিকে 'GoOnAboutYourBusiness' বলা উচিত। আমি এটি বলছি কারণ আপনি সম্ভবত অনুসন্ধান থেকে সাবস্ক্রিপশন অনুসরণ করে পরিবর্তন করতে চান না। Traditionalতিহ্যবাহী প্রোগ্রামিং লুপগুলি সহ তাদের পরিচালনা করুন। একটি একক সেন্সর সহ, - শেষ লুপের চেয়ে হালকা সংবেদকটি আরও গাer় বা হালকা হয়? যদি এটি গাer় হয়ে যায় (কৃষ্ণরেখাকে ধরে নিচ্ছে) একই দিকে ঘুরতে থাকুন, যদি এটি হালকা হয়ে যায় অন্যভাবে, যদি একই থাকে তবে সোজা হয়ে যান। আপনার সম্ভবত কিছু পিআইডি যুক্ত করতে হবে এবং মসৃণ হওয়ার জন্য কেবল বাম এবং ডানদিকে ঘোরার পরিবর্তে একটি স্টিয়ারিং বক্র ব্যবহার করতে হবে।

এবং হ্যাঁ, একাধিক সেন্সর সহায়তা করে। http://www.mindsensors.com/ - হ্যাঁ, আমি বর্তমানে সিনেমাতে এটি (11/10/2012)

আপডেট: আসল কোড

আমি এটি কিছুক্ষণের মধ্যে চেষ্টা করে দেখব, তবে এটি উপরে রচনাগুলি সংকলন এবং চিত্রিত করে:

#pragma config(Sensor, S1,     S_LIGHT,        sensorLightActive)
#pragma config(Sensor, S2,     S_DISTANCE,     sensorSONAR)
#pragma config(Motor,  motorB,          LEFT,          tmotorNXT, PIDControl, encoder)
#pragma config(Motor,  motorC,          RIGHT,         tmotorNXT, PIDControl, encoder)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

int distance_value, light_value;

bool evade_wantsToRun()
{
    return distance_value < 30;
}

void evade_task()
{
    // full stop
    motor[LEFT] = 0;        
    // evade the object ballistically (ie in full control)  
    // turn left, drive
    nSyncedTurnRatio = 0;
    motor[LEFT] = -20;
    Sleep(500);
    nSyncedTurnRatio = 100;
    Sleep(1000);
    // turn right, drive
    nSyncedTurnRatio = 0;
    motor[LEFT] = 20;
    Sleep(500);
    nSyncedTurnRatio = 100;
    Sleep(1000);
    // turn right, drive
    nSyncedTurnRatio = 0;
    motor[LEFT] = 20;
    Sleep(500);
    nSyncedTurnRatio = 100;
    Sleep(1000);
    // turn left, resume
    nSyncedTurnRatio = 0;
    motor[LEFT] = 20;
    Sleep(500);
    motor[LEFT] = 0;
}

///////////////////////////////

void TurnBySteer(int d)
{
    // normalize -100 100 to 0 200
    nSyncedTurnRatio = d + 100; 
}
///////////////////////////////

typedef enum programPhase { starting, searching, following, finished };
programPhase phase = starting;

// these 'tasks' are called from a loop, thus do not need to loop themselves

void initialize()
{
    nSyncedTurnRatio = 50;
    nSyncedMotors = synchBC;
    motor[LEFT] = 30;       // start a spiral drive
    phase = searching;
}

void search()
{
    if (light_value < 24)
    {
        nSyncedTurnRatio = 100;
        phase = following;
    }
}

int lastLight = -1;
int currentSteer = 0;
void follow()
{
    // if it is solid white we have lost the line and must stop
    // if lightSensors detects dark, we are on line
    // if it got lighter, we are going more off line
    // if it got darker we are headed in a good direction, slow down turn in anticipation
    // +++PID will be even smoother
    if (light_value > 64)
    {
        motor[LEFT] = 0;
        phase = finished;
        return;
    }
    if (light_value < 24)
        currentSteer = 0;
    else if (light_value > lastLight)
        currentSteer += sgn(currentSteer) * 1;
    else    // implied (light_value < lastLight)
        currentSteer -= sgn(currentSteer) * 1;      

    TurnBySteer(currentSteer);
}

bool regularProcessing_wantsToRun()
{
    return phase != finished;
}

void regularProcessing_task()
{
    switch (phase)
    {
    case starting:
        initialize();
        break;
    case searching:
        search();
        break;
    case following:
        follow();
    }
}

task main()
{
    // subsumption tasks in priority oder
    while (true)
    {
        // read sensors once per loop
        distance_value = SensorValue[S_DISTANCE];
        light_value = SensorValue[S_LIGHT];
        if (evade_wantsToRun())
            evade_task();
        if (regularProcessing_wantsToRun())
            regularProcessing_task();
        else
            StopAllTasks();
        EndTimeSlice();     // give others a chance, but make it as short as possible
    }
}

আমি একমত যে একটি সাধারণ লুপ দিয়ে এই সমস্যাটি আরও সহজে সমাধান করা যায়। আমি বুঝতে পারছি না কেন কেউ এটিকে হ্রাস করবে।
শাহবাজ

আমি একটি সহজ লুপ দিয়ে সমাধান করা সহজ যে ধারণাটি ছেড়ে যেতে চাই না, বরং এই ধারণাটি যে কার্যগুলির মধ্যে একটি হিসাবে একটি সরল লুপ ব্যবহার করার জন্য এটি সাবমোশনটির সঠিক ব্যবহার। যার যার ডাউনগ্রেড হয়েছে তাতে মোড পয়েন্ট রয়েছে এবং সাবমোশনটির কোনও বোঝাপড়া নেই। আপনি দেখতে পাবেন না যে কোনও লেগো এনএক্সটি (রোবোটসির সাহায্যে বোঝানো) -এ প্রচুর লোক গ্রহণ করছেন না, সুতরাং কোডটি আটকানোর জন্য সহজেই উপলব্ধ হওয়ার আশা করবেন না।
স্পাইকড 3

হ্যাঁ, আমি ভাবছিলাম কেন ওপি সাবমিশনের মতো সাধারণ কোনও কাজের জন্য টাস্ক ব্যবহার করছে।
রকেটম্যাগনেট

কারণ এটি রোবটসির সাথে খুব খুব খুব সাধারণ একটি প্রাথমিক ভুল - সব কিছুর জন্য কাজগুলি ব্যবহার করে দেখতে। আমি চাই তারা এটিকে উন্নত একমাত্র অঞ্চলে নিয়ে যাবে।
স্পাইকড 3
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.