Makeblock-official / PythonForMegaPi

python for MegaPi with Raspberry Pi
http://openlab.makeblock.com
49 stars 26 forks source link

Include routine to access case COMMON_COMMONCMD. #22

Open clplaneguy opened 5 years ago

clplaneguy commented 5 years ago

My project is to use the MegaPi board to balance the "Balancing Robot" while a Raspberry Pi 3B+ is left available for other tasks. The balancing code is already on the board in the firmware. The firmware has a feature to change the "megapi_mode" in case "COMMON_COMMONCMD". However, there is no corresponding method in Python_for_MegaPi to access this case. Please include in Python_for _MegaPi a Python routine that will allow exicution of the arduino c++ code. A user's program would have something like . . .

bot.MegaPi_Mode(megapi_mode);

to access the firmware code . . .

case COMMON_COMMONCMD:                                               //    60            
      {
        uint8_t subcmd = port;
        uint8_t cmd_data = readBuffer(7);
        if(SET_MEGAPI_MODE == subcmd)                 //    #define SET_MEGAPI_MODE      0x12

        {
          Stop();
          if((cmd_data == BLUETOOTH_MODE) ||                             //    0        
             (cmd_data == AUTOMATIC_OBSTACLE_AVOIDANCE_MODE) ||          //    1         
             (cmd_data == BALANCED_MODE) ||                              //    2
             (cmd_data == IR_REMOTE_MODE) ||                             //    3          
             (cmd_data == LINE_FOLLOW_MODE))                             //    4          
          {
            megapi_mode = cmd_data;
            if(EEPROM.read(MEGAPI_MODE_CONFIGURE) != megapi_mode)   //  != buffer[7]
            {
              EEPROM.write(MEGAPI_MODE_CONFIGURE, megapi_mode);     //   = buffer[7]
            }
          }
          else
          {
            megapi_mode = BLUETOOTH_MODE;
            if(EEPROM.read(MEGAPI_MODE_CONFIGURE) != megapi_mode)
            {
              EEPROM.write(MEGAPI_MODE_CONFIGURE, megapi_mode);
            }
          }
        }
      }
      break;

Python_for_MegaPi would have something like . . .

#def COMMON_COMMONCMD (self,slot,speed):    subcmd=0x12, megapi_mode=?
def .MegaPi_Mode (self, megapi_mode):
        deviceId = 60;
#  uint8_t port = readBuffer(6);
#          Number count               1     2    3     4     5         6           7            8                     9               
#          Butter Position            0     1    2     3     4         5           6            7                     8
#          Defination/Output         ff    55   len   idx  action   device       port         slot                 data_a
#                                                                               subcmd      cmd_data                     
#                                                                                         megapi_mode                                                        
self.__writePackage(   bytearray( [0xff, 0x55, 0x07, 0x00,  0x02,  deviceId,     0x12,     megapi_mode     ]    +   self.short2bytes(speed) )   )
#          Buffer
clplaneguy commented 5 years ago

@allaincedric allaincedric has respnoded that

@clplaneguy Python_for_MegaPi is a set of .py file, you can write your own, edit the file installed on your machine copy it to change it or create new class from existing api. At the end if you know the bytes you need to send you can just add a function to the api creating a new class from the existing one.

from megapi import *

class YourMegaPi(MegaPi):

  def __init__(self):
      MegaPi.__init__(self)

  def MegaPi_Mode(self, megapi_mode,speed):
          deviceId = 60;
          self.__writePackage(bytearray([0xff, 0x55, 0x07, 0x00,  0x02,  deviceId, 0x12, megapi_mode]+self.short2bytes(speed)))

if __name__ == '__main__':

  bot=YourMegaPi()
  bot.start()
  bot.MegaPi_Mode(2,100);
  bot.close();

allaincedric uses Python 3! I am firmly embedded in Python 2! His code may work for him, but it does not work for me. This code does not execute, never exits and does not produce an error message. I have added print statements to at least locate where execution halts.

from megapi import *

class YourMegaPi(MegaPi):

        def __init__(self):
                MegaPi.__init__(self)

        def MegaPi_Mode(self, megapi_mode,speed):
                deviceId = 60;
                self.__writePackage(bytearray([0xff, 0x55, 0x07, 0x00,  0x02,  deviceId, 0x12, megapi_mode]+self.short2bytes(speed)))

if __name__ == '__main__':

        print("Program started");
        bot=YourMegaPi()
        print("bot=YourMegaPi()");
        bot.start()
        print("bot.start()");
        bot.MegaPi_Mode(2,100);
        print("bot.MegaPi_Mode(2,100);");
        bot.close();
        print("All done");

His line "bot.MegaPi_Mode(2,100); is what stops execution. I have been experimenting with and adding code in an attempt to find a working combination without success. I have studied and learned most of the firmware. I think. I have studied and learned most of PythonForMegaPi. I think. Now, I am studying and learning Python2 which seems to be my week point!

import sys
print("sys.platform is: " + sys.platform);

from megapi import *

print("\r\nThis program is a test of the Raspberry's attempt to run the MegaPi's firmware to balance the robot");
print("\r\n2/4/2019");

class YourMegaPi(MegaPi):
        def __init__(self):
                MegaPi.__init__(self)

        def MegaPi_ModeA(self, megapi_mode,speed):    #    Routine Alfa
                print("\r\nInside 'MegaPi_A'")                      
                deviceId = 60;                                       
                speed = 0;                                           
                bot.encoderMotorRun(3,100);           
                sleep(1);                                 
                bot.encoderMotorRun(3,  0);          
                #bot.__writePackage(bytearray( [0xff, 0x55, 0x07, 0x00,  0x02,  deviceId,     0x12,     megapi_mode     ] +   self.short2bytes(speed) )   )
                print("\r\nExiting 'MegaPi_A'")               

        #def MegaPi_ModeB(self, megapi_modeA):          #    Routine Beta                 
        def MegaPi_ModeB(self):          #    Routine Beta                 
                print("\r\nInside 'MegPi_ModeB'")                  
                deviceId = 60;        #    COMMON_COMMONCMD                     
                deviceId = 62;        #    ENCODER_PID_MOTION   encoderMotor                      
                speed = 0;
                slot = 3;
                bot.encoderMotorRun(3,100);           
                sleep(1);                             
                bot.encoderMotorRun(3,  0);               
                print("\r\nMotors Run")                  
                bot.__writePackage(bytearray( [0xff, 0x55, 0x07, 0x00,  0x02,  deviceId,     0x02,     3     ] +   bot.short2bytes(speed) )   );
                #self.__writePackage(bytearray( [0xff, 0x55, 0x07, 0x00,  0x02,  deviceId,     0x02,     3     ] +   self.short2bytes(speed) )   );
                print("\r\nExiting 'MegaPi_ModeB'")     

        def MotorTest(self):                              # MotorTest                                        
                print("\r\nInside 'MotorTest'")                  
                bot.encoderMotorRun(3,100);
                sleep(1);
                bot.encoderMotorRun(3,  0);
                sleep(1);

#def COMMON_COMMONCMD (self,slot,speed):    subcmd=0x12, megapi_mode=?
#def MegaPi_Mode (megapi_mode):                                    
#    deviceId = 60;                                                      
##   uint8_t port = readBuffer(6);                                    
#                        Number count              1     2    3     4     5         6           7            8                      9           
#                        Buffer Position           0     1    2     3     4         5           6            7                      8
#                        Definition/Output        ff    55   len   idx  action   device       port         slot                  data_a
#                                                                                            subcmd       cmd_data                     
#                                                                                                       megapi_mode                               
#               self.__writePackage(bytearray( [0xff, 0x55, 0x07, 0x00,  0x02,  deviceId,     0x12,     megapi_mode     ] +   self.short2bytes(speed) )   )
                #bot.encoderMotorRun(3,100);
                #sleep(1);                                    
                #bot.encoderMotorRun(3,  0);
                #bot.__writePackage(bytearray( [0xff, 0x55, 0x07, 0x00,  0x02,  deviceId,     0x12,     megapi_mode     ] +   self.short2bytes(speed) )   )
                print("\r\nExiting 'MotorTest'")

if __name__ == '__main__':

        print("\r\nInside 'Main program'")                  
        bot=YourMegaPi()
#       bot=MegaPi()
        bot.start()
        megapi_modeb = 2;
        speed = 0;
        #bot.encoderMotorRun(3,100);
        #sleep(1);
        #bot.encoderMotorRun(3,  0);
        #sleep(1);
        bot.MotorTest();
        bot.MotorTest();
        print("After MotorTest");
        bot.MegaPi_ModeB();
        print("MegaPi_ModeB");
        bot.__writePackage(bytearray([0xff,0x55,0x07,0x00,0x02,62,0x02,slot]+self.short2bytes(100)));
        sleep(1);
        bot.__writePackage(bytearray([0xff,0x55,0x07,0x00,0x02,62,0x02,slot]+self.short2bytes(  0)));

        #bot.MegaPi_ModeA(2,100);    #    For routine Alfa
        #bot.MegaPi_ModeB(2);        #    For routine Beta
        #bot.__writePackage(bytearray( [0xff, 0x55, 0x07, 0x00,  0x02,  deviceId,     0x12,     megapi_mode     ] +   self.short2bytes(speed) )   )
        #bot.__writePackage(bytearray([0xff,0x55,0x07,0x00,0x02,60,0x12,megapi_mode]+self.short2bytes(speed)))
        self.__writePackage(bytearray([0xff,0x55,0x07,0x00,0x02,deviceId,0x02,slot]+self.short2bytes(speed)))

        bot.close();
        sys.exit("Execution complete")

#bot = MegaPi()
#bot.start('/dev/ttyAMA0')
#bot.start()

#MegaPi_Mode(2);

#def COMMON_COMMONCMD (self,slot,speed):    subcmd=0x12, megapi_mode=?
#def MegaPi_Mode (megapi_mode):
#    deviceId = 60;
#  uint8_t port = readBuffer(6);
#          Number count               1     2    3     4     5         6           7            8                     9           
#          Buffer Position            0     1    2     3     4         5           6            7                     8
#          Definition/Output         ff    55   len   idx  action   device       port         slot                 data_a
#                                                                               subcmd       cmd_data                     
#                                                                                           megapi_mode                               
#self.__writePackage(   bytearray( [0xff, 0x55, 0x07, 0x00,  0x02,  deviceId,     0x12,     megapi_mode     ] +   self.short2bytes(speed) )   )
#    bot.device._writePackge (   bytearray( [0xff, 0x55, 0x07, 0x00,  0x02,  deviceId,     0x12,     megapi_mode     ] +   self.short2bytes(speed) )   )
#          Buffer

#from megapi import *
#
#class YourMegaPi(MegaPi):
#       def MegaPi_Mode(self, megapi_mode,speed):
#               deviceId = 60;
#               self.__writePackage(bytearray([0xff, 0x55, 0x07, 0x00,  0x02,  deviceId, 0x12, megapi_mode]+self.short2bytes(speed)))
#
#if __name__ == '__main__':
#
#       bot=YourMegaPi()
#       bot.start()
#       bot.MegaPi_Mode(2,100);
#       bot.close();

Whatever the correct code is, it is beyond my me.

Can any one help?

clplaneguy commented 5 years ago

@allaincedric I have been working on my project and having trouble. So, I have fallen back one step to something just a little easier. Instead of trying to manually control COMMON_COMMONCMD, I have switched to encoderMotorRun. This allows me to get more immediate feedback. Python2 does not have nearly enough error detection/correction/notification for me, so I have copy/pasted PythonForMegaPi into my program and then added more print statements.

I have had to learn about inheritance, arrays and strings.

The end result is that while the underscore "_" character is used in an imported module with intent and function, outside of a module, sometimes underscore is a valid character and sometimes not. Specifically, the command _writepackage, if inside my program stops execution. So, I have to change it to writepackage2. Now I can manually control the encoder motor in python. I would suggest that this Python2 problem be fixed. However, it may already have been fixed in Python3.

I have not studied the debugger yet.

So, I have a successful conclusion to this easy step. Now I un-focus and find that Makeblock has an IR remote and sensor. I have it on order and will see if that can give me the wireless control I am looking for.

I want this thread to have a successful conclusion. Hopefully that can earn me some credit for when I get stuck again.

THANK YOU for helping me to get started on this process.

clplaneguy commented 5 years ago

I have discovered that the underscore character is special in external models and gets into the subject of Mangling. I have rewritten all of my code to be inserted into the original PythonForMegaPi module.

   def writePackage2(self,pack):
       self.device.writePackage(pack)

    def MegaPiMode(self, megapi_mode):
           deviceId = 60
           speed = 0
           self.__writePackage(bytearray([0xff, 0x55, 0x07, 0x00,  0x02,  deviceId, 0x12, megapi_mode]+self.short2bytes(speed)))

I would make this a Pull request. However, it seems that I do not have authority to do that.

MrHezhisheng commented 5 years ago

hello ,@clplaneguy ! Can you describe the problem simply and directly?

clplaneguy commented 5 years ago

Access to the MegaPi board can be through USB or a wireless app, which I do not have. Programable wireless access through onboard Serial2.4G or Bluetooth is not available. However, serial(2) goes to the Raspberry Pi which is another way to get wireless access to the board and megapi_mode. However megapi_mode must be accessible through PythonForMegaPi.