रोबोट सी के साथ सदस्यता वास्तुकला का उपयोग करने का सही तरीका


11

मैं हाल ही में सबस्क्रिप्शन आर्किटेक्चर के बारे में बहुत कुछ पढ़ रहा हूं और कुछ अलग तरीके हैं जिनसे लोग वकालत करते हैं।

उदाहरण के लिए, कुछ लोग कार्य को नियंत्रण में रखने के लिए एक वैश्विक "ध्वज" चर का उपयोग करते हैं। अन्य लोग इसका उपयोग करते हैं endTimeSlice()और आर्बिटर को वास्तव में चुनने की अनुमति देते हैं। और मुझे लगता है कि यह सही है।

मेरे पास RobotC कोड का यह छोटा सा खंड है जो मैं रोबोट के बाद एक लाइन के लिए काम कर रहा हूं, लेकिन मुझे यकीन नहीं है कि मैं इसे सही कर रहा हूं क्योंकि वर्तमान में ट्रैक विधि हमेशा खोज विधि पर ले जाएगी। सही प्रवाह यह होना चाहिए कि रेखा को खोजने के लिए सर्पिल पथ का उपयोग करके लाइन को रोबोट को निर्देशित करना चाहिए। एक बार लाइन मिल जाने के बाद ट्रैक को संभाल लेना चाहिए।

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? वास्तव में, की स्थिति findऔर elseस्थिति trackसमान हैं। इसलिए, एक मानव के रूप में, यदि सेंसर का मूल्य थ्रेशोल्ड से बड़ा है, तो आप क्या करेंगे? सर्पिल पर जाएं या लाइन को समायोजित करने के लिए मुड़ें?
शहबाज

मुझे पता है कि सबस्क्रिप्शन आर्किटेक्चर क्या है, और मुझे यकीन है कि आपके रोबोट के पास कम स्तर के कम्प्यूटेशनल कार्यों की जिम्मेदारी लेने वाले अलग-अलग हार्डवेयर मॉड्यूल होने चाहिए। और यह कि कोड को केवल सशर्त स्थिति के लिए सुनने के बजाय संकेत को अवशोषित करना चाहिए। तो क्या आपको हार्डवेयर के दूसरे टुकड़े में सिग्नल पास नहीं करना चाहिए? अब मेरी समस्या यह है कि मेरे पास एक दो Arduinos हैं और मैं चाहता हूं कि Arduino A, Arduino B के सिग्नल को कम या बाधित कर दे। किसी को भी यह कैसे किया जाता है किसी भी विचार है? जैसा कि मैं Arduino B को सिग्नल भेजने के लिए Arduino A को वायर कर सकता हूं, लेकिन मैं अनिश्चित हूं कि sig को कैसे कम या बाधित किया जाए
Ambient Soda

जवाबों:


7

सबस्क्रिप्शन आर्किटेक्चर के साथ, आपको अपने व्यवहारों को इस तरह से सावधानीपूर्वक डिज़ाइन करना चाहिए कि यदि आप कार्य को Tप्राथमिकता देते हैं n, तो यह Tहोना चाहिए कि रोबोट को क्या करना चाहिए यदि उच्च प्राथमिकता वाले सभी कार्यों nको अनदेखा कर दिया जाए।

आइए अपने उदाहरण कार्यों को क्रमबद्ध करें, फिर इसे लागू करने का एक तरीका निकालें। आपके कार्य हैं evade, findऔर track

सामान्य तौर पर आप चाहेंगे कि रोबोट एक लाइन को ट्रैक करे। हालाँकि, यदि यह रेखा का पता नहीं लगा सकता है, तो इसे खोजने की कोशिश करनी चाहिए। इन सबसे ऊपर, इसे बाधाओं से बचना चाहिए। यह हमें निम्नलिखित आदेश देता है:

  • सर्वोच्च प्राथमिकता: 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बज उठती। आप देख सकते हैं, 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 से अधिक कार्य जोखिम भरा (I2C समय समस्याएँ) हो सकते हैं, और कुछ मामलों में यह (स्वचालित रूप से प्रदूषित सेंसर) नहीं है।

आप उपरोक्त लूप में अपनी प्राथमिकता के कार्यान्वयन को जोड़ सकते हैं क्योंकि आप काम कर रहे हैं, लेकिन यह वास्तव में शुरू करने के लिए आवश्यक नहीं है।

आपकी टिप्पणी "// बॉक्स बाधा" एक बैलिस्टिक व्यवहार का वर्णन करती है। मल्टी टास्किंग का उपयोग करके इसे लागू करना थोड़ा मुश्किल है। मैंने जो सरल लूप का उपयोग किया है वह इसे बहुत आसान बनाता है, और शुरुआत / सीखने के लिए बेहतर है।

दूसरी चीज जो मैं आपको छोड़ दूंगा, वह यह है कि साफ-सुथरी होने के साथ-साथ बहुत सारी चीजों के लिए उचित है, जो परंपरागत रूप से बेहतर है, उसे लागू करने का एक अच्छा तरीका नहीं है। वास्तव में Indeed ईवडे ’का हिस्सा निर्वाह के लिए एक अच्छा उम्मीदवार हो सकता है, लेकिन ईमानदारी से आपके अन्य कार्य को out GoOnAboutYourBusiness’ कहा जाना चाहिए। मैं यह कहता हूं क्योंकि आप शायद खोज से लेकर सबमिशन तक को बदलना नहीं चाहते हैं। पारंपरिक प्रोग्रामिंग छोरों के साथ उन लोगों को संभालें। एक एकल सेंसर के साथ, - प्रकाश संवेदक गहरा या हल्का होता है, जबकि यह अंतिम लूप था? अगर यह गहरा हो गया (काली रेखा मानकर) उसी दिशा को मोड़ते रहें, अगर यह हल्का हो जाए तो दूसरा रास्ता बंद हो जाता है, यदि यह समान रहता है, तो सीधे जाएं। आपको शायद कुछ पीआईडी ​​जोड़ने की जरूरत है और केवल चिकनी होने के लिए बाएं और दाएं मुड़ने के बजाय स्टीयरिंग कर्व का उपयोग करें।

और हाँ, कई सेंसर मदद करते हैं। 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
    }
}

मैं सहमत हूं कि यह समस्या एक सरल लूप के साथ अधिक आसानी से हल हो गई है। मुझे समझ नहीं आ रहा है कि कोई इसे क्यों कम करेगा।
शहबाज़

मैं इस धारणा को नहीं छोड़ना चाहता हूं कि एक साधारण लूप के साथ हल करना आसान है, बल्कि यह धारणा है कि यह एक साधारण लूप का उपयोग कार्यों में से एक के रूप में उपयोग करने का सही उपयोग है। जिस किसी ने भी इसे डाउनग्रेड किया है, उसके पास आधुनिक बिंदु हैं, और निर्वाह की समझ नहीं है। आप यह नहीं पाएंगे कि लेगो एनएक्सटी (रोबोटसी का उपयोग करके निहित) पर बहुत से लोग ऐसा नहीं कर रहे हैं, इसलिए कोड को पेस्ट किए जाने के लिए आसानी से उपलब्ध होने की उम्मीद नहीं है।
Spiked3

हां, मैं सोच रहा था कि क्यों ओपी सरल के रूप में कुछ के लिए कार्यों का उपयोग कर रहा था।
Rocketmagnet

क्योंकि यह रोबोटसी के साथ एक बहुत ही बहुत सामान्य शुरुआत की गलती है - कोशिश करना और हर चीज के लिए कार्यों का उपयोग करना। काश वे इसे एक उन्नत क्षेत्र में ले जाते।
स्पाइकड 3
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.