2010-05-10 17 views
6

मैं एक रोबोट पर काम कर रहा हूं जो वेबकैम का उपयोग करके गति का पता लगाने में सक्षम है। मैं इसे सी #सी # में निश्चित समय के लिए कोड का एक टुकड़ा चला रहा है?

रोबोट बहुत तेज़ी से चलता है, इसलिए मैं इसकी गति को कम करने के लिए इसे कम समय अंतराल पर चालू/बंद करना चाहता हूं।

उदाहरण के लिए, यह इंजन शुरू करेगा, फिर 0.5 सेकंड प्रतीक्षा करें और इसे बंद कर दें, यह चक्र हर 2 सेकंड दोहराता है। इस तरह, इसकी गति बहुत तेज़ नहीं होगी। मैं इसे एक ही फ़ंक्शन में शामिल करना चाहता हूं जिसे मूव()

मुझे यह नहीं पता कि यह कैसे करना है, विशेष रूप से क्योंकि मेरा गति पहचान कोड दूसरे बार 20 गुना चलता है। बाधा की स्थिति के आधार पर, मुझे Move() फ़ंक्शन को अक्षम करने और अन्य फ़ंक्शंस को सक्रिय करने की आवश्यकता हो सकती है जो रोबोट को अन्य दिशाओं में ले जाने दें।

किसी भी विचार/सुझाव जहां मुझे शुरू करना है?

बहुत बहुत धन्यवाद!

उत्तर

0

आप उपयोग करने का प्रयास कर सकते हैं -

Thread.Sleep(500); 

कोड का यह टुकड़ा 500 मिलीसेकंड के लिए सोने के लिए वर्तमान में चल रहे धागा डाल देंगे।

0

काम पर निलंबन जोड़ने का एक तरीका कॉल के बीच में नींद जोड़ना है। आप कॉल के बीच में नींद डाल सकते हैं। नींद डालना इस तरह है: System.Threading.Thread.Sleep(5000); 5000 5000 मिलीसेकंड के लिए है।

5

सबसे पहले, हमें यह निर्धारित करने की आवश्यकता है कि आपका प्रोग्राम कैसे बहता है।

क्या यह एक आदेश निष्पादित करता है, प्रतीक्षा करें, फिर अगला आदेश निष्पादित करें? या यह एक साथ आदेश निष्पादित करता है? (उदाहरण के लिए, कुछ और ले जाएं)

मुझे लगता है कि आप चाहते हैं कि आप कुछ जटिल थ्रेडिंग के बजाय अनुक्रम में कमांड निष्पादित करना चाहते हैं, जो आपकी मोटर प्रणाली का समर्थन नहीं कर सकता है।

आदेश में अपने रोबोट धीरे-धीरे ले जाने के लिए प्राप्त करने के लिए, मैं एक चाल() विधि है कि एक पैरामीटर, समय की राशि आप इसे आगे बढ़ खर्च करना चाहते हैं, इस तरह लेता बनाने का सुझाव देते हैं:

public void Move(int numberOfSeconds) 
{ 
    while (numberOfSeconds > 0) 
    { 

     myRobot.MotorOn(); 
     Thread.Sleep(2000); 
     myRobot.MotorOff(); 
     Thread.Sleep(500); 

     numberOfSeconds -= 2; 
    } 
} 

यह सटीक नहीं है, लेकिन यह करने का एक तरीका है।

यदि आप फिर ले जाएं (10) उदाहरण के लिए, आपका रोबोट 10 सेकंड तक चलेगा, और हर सेकेंड के लिए प्रत्येक 2 सेकंड रोक देगा।

अपने कार्यक्रम प्रवाह सवाल के बारे में, आप निर्देशों की एक सूची के रूप में यह के बारे में सोच सकते हैं:

चाल आगे बंद वस्तु घुमाने के लिए जांच वस्तु को उद्देश्य के लिए चाल आगे रोकें

आदि

तो आपके मुख्य कार्यक्रम नियंत्रण पाश में, मानते हुए कि कॉल तुल्यकालिक हैं (यानी।अपने कार्यक्रम बंद हो जाता है, जबकि यह ऊपर ले जाएँ विधि में की तरह एक कमांड को क्रियान्वित किया जाता है,), तो आप बस अगर बयान (या एक स्विच)

public void Main() 
{ 

    // What calculations should the robot do? 
    If (someCalculations == someValue) 
    { 
    // Rotate the robot to face the object 
    robot.RotateRight(10); 
    } 
    else if (someOtherCalculation == someValue) 
    { 
    // We are on course, so move forward 
    Move(10); 
    } 
} 

कि मदद कर सकता है आप आरंभ करने का एक समूह हो सकता था।

यदि आपका रोबोट असीमित है, यानी, रोबोट चीजें कर रहा है (जैसे कि आप लगातार गति सेंसर से प्रतिक्रिया प्राप्त करते हैं) कोड चल रहा है, तो आपको अपने प्रोग्राम को अलग-अलग ढांचा बनाना होगा। Move() विधि अभी भी काम कर सकती है, लेकिन आपका प्रोग्राम प्रवाह थोड़ा अलग होना चाहिए। आप राज्य का ट्रैक रखने के लिए एक चर का उपयोग कर सकते हैं:

public enum RobotStates 
{ 
    Searching, 
    Waiting, 
    Hunting, 
    Busy, 
} 

फिर अपने मुख्य पाश में, आप राज्य की जांच कर सकते हैं:

if (myRobotState != RobotStates.Busy) 
{ 
    // Do something 
} 

राज्य जब अपने कार्यों को पूरा करने को बदलने के लिए याद रखें।

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

+0

+1। –

0

ऐसा लगता है कि आप मुख्य थ्रेड को समय-समय पर कार्य निष्पादित करना चाहते हैं। यदि आपके रोबोट में .NET-Framework स्थापित है, तो आप थ्रेडिंग लाइब्रेरी का उपयोग कर सकते हैं।

while(condition) 
{ 
    //Wait a number ms (2000 ms = 2 secons) 
    Thread.Sleep(2000); 
    //Do something here, e.g. move 

    Thread.Sleep(500); 
    //... 
} 

लेकिन आपका एक बहुत ही कठिन सवाल है। क्या आप कृपया निर्दिष्ट कर सकते हैं कि किस प्रकार के ऑपरेटिंग सिस्टम या/और पर्यावरण (पुस्तकालय, framworks, ...) आपके रोबोट है?

0

जहां तक ​​एक गति का पता लगाने और बाधा का पता लगाना है, आपका कोड जटिल थ्रेडिंग का उपयोग करना चाहिए। आपके लिए मोटर गति की समस्या ने आपने अलग थ्रेड में Move() कॉल करने का प्रयास किया है।

और लूप के लिए आप प्रत्येक MotorOff() कॉल के बाद थ्रेड स्लीप (2 * 1000) का उपयोग कर सकते हैं।

सम्मान।

+0

:) मुझे समझने में आसान 2 * 1000 bcoz पसंद है। 2 सेकंड = 2 * 1000 .. –

1

मैं आपको सलाह देता हूं कि आप Microsoft Robotics Studio? पर कभी भी इसका इस्तेमाल न करें, लेकिन वे वास्तव में इस तरह के मुद्दे को संबोधित कर सकते हैं। और शायद दूसरों को आप अभी तक सामना नहीं किया है।

एक और विकल्प XNA's timing mechanisms. का उपयोग करके ऐप लिखना है केवल स्क्रीन पर प्रतिपादन करने के बजाय, आप अपने रोबोट को प्रतिपादित करेंगे।

+1

मैं 90% निश्चित रोबोटिक्स स्टूडियो * करता हूं * इस समस्या को हल करता हूं। समय और समांतर प्रसंस्करण वे हैं जो लाइब्रेरी के बारे में है। +1 bazillions। – Randolpho

2

थ्रेड। नींद() शायद आप नहीं चाहते हैं क्योंकि यदि आपका हार्डवेयर सक्षम है, तो आप अपने सेंसर को चलते समय चलाना चाहते हैं। मेरे लिए दिमाग में आने वाला पहला समाधान टाइमर का उपयोग करना है। इस तरह आप आवश्यकता होने पर अपने आंदोलन को संसाधित और संभाल सकते हैं।

(अब के लिए इस कोड का परीक्षण किया है, लेकिन यह भर में विचार हो जाता है)

System.Timers.Timer Timer = new Timer(); 
bool Moving; 

void init() 
{ 
    Timer.AutoReset = false; 
    Timer.Elapsed += OnMoveTimerEvent; 
    Moving = false; 
} 

void MainLoop() 
{ 
    //stuff 

    if(should move) 
    { 
    timer.start(); 
    } 

    if(should stop moving) 
    { 
    timer.stop(); 
    } 
} 


void OnMoveTimerEvent(object source, ElapsedEventArgs e)   
{ 
    if (!Moving) 
    { 
    //start motor 
    Timer.Interval = 500; 
    Moving = true; 
    Timer.Start(); 
    } 
    else 
    { 
    //stop motor 
    Moving = true; 
    Timer.Interval = 2000; 
    Timer.Start(); 
    } 
} 
+0

यदि कार्यक्रम में एक से अधिक धागे हैं, थ्रेड। सो केवल उस विशेष धागे को रोक देगा, और अन्य धागे इनपुट या जो कुछ भी संसाधित करने के लिए स्वतंत्र हैं। –

3

आप एक बहुत ही आम समस्या है, जो एक प्रक्रिया को नियंत्रित करने के लिए कैसे जब अपने प्रवर्तक केवल चालू और बंद राज्यों है का सामना करना पड़ा है। आपके द्वारा प्रस्तावित समाधान एक सामान्य समाधान है, जो मोटर को चालू/बंद करके 'कर्तव्य चक्र' सेट करना है। ज्यादातर मामलों में, आप मोटर नियंत्रक खरीद सकते हैं जो आपके लिए यह करेंगे, ताकि आपको विवरणों के बारे में चिंता न करें। आम तौर पर आप पल्सिंग को उच्च आवृत्ति के रूप में चाहते हैं, ताकि गति में कम अवलोकन 'स्टटर' हो।

यदि यह एक शैक्षिक परियोजना है, तो आप Motor Controllers पर सिद्धांत में रूचि रख सकते हैं। आप Control Theory (विशेष रूप से, पीआईडी ​​नियंत्रण) के बारे में भी पढ़ना चाहेंगे, क्योंकि आप अपनी इच्छित गति को बनाए रखने के लिए स्वचालित रूप से मोटर को नियंत्रित करने के लिए अन्य प्रतिक्रिया का उपयोग कर सकते हैं (क्या आपके पास अपनी गति को समझने का कोई तरीका है?)। व्यापक उत्तर के लिए