Hello Guest it is October 20, 2020, 01:48:30 AM

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - j1sys

Pages: « 1 2
11
James -

My PERSONAL goal is to move away from MFC and use .NET in my plugins. Time critical code (40hz / 10 hz Update) MAY be left in C++ unmanaged but that code should not be doing MFC IMHO. The techniques to get it working at all can still be used by anybody for any purpose. I believe that the $199 VS2008 C++ Standard would include MFC support for those that needed it. We still are going to be constantly fighting the older version MFC vs either the newer version MFC or vs .NET. I'd rather fight the battle all the way and go for .NET.

I am also looking into the redistribution rights and restrictions to see what I could give someone with an Express version to use for MFC. Again for .NET they would already have it. So for simple plugins, if I can make it work and document it, .NET may be the answer.

It will be a moving target with several different solutions based on the needs of the individual. So the fun has just begun.

-Ed

12
Art, Brian, Poppabear -

I am doing all this with VS Pro 2008, and VS Pro 2003. But I'm targeting, when done, to provide all the pieces that will allow ANYBODY to use the free VS2008 student editiion.

Art/Brian (poppabear wouldn't understand ;^)) - In all of your initial programming I'm sure you didn't ever plan on opening up and allowing plugins. Again thanks for doing it. I will try to provide more help, info, tutorials, templates, functions to the community to support its work and leave you guys to work on the big picture. IMHO classes, especially inherited ones, are not the best choice of how to communicate between master and plugin. Think about COM, Interop and all the Marshaling Options built into the new languages to allow communication with OLD DLLs. They are all based on STRUCTs not CLASSes. In this case we are trying to do the reverse. I understand it will be a VERY big undertaking for you to upgrade your code. I support many legacy customers going back to Manx Aztec C and VC6 for DOS. Just like you like to/need to add a new data field to support a new feature, CWnd needed to be improved. As soon as it added one bool it changed the offset to YOUR classes part of the buffer. That is one of the beauties of inheritence. You can always use a pointer to access the lower classes in the hierarchy. It may be possible to use ALL the headers and libraries from VS2003 plugged into VS2008 but I don't think it is worth the risk or effort. If I remember the code paradigm for C++ it really just passes a pointer to the class data structure as a first hidden parameter but otherwise follows the _CDECL calling format. I should be able to wrap any needed functions in custom static classes and expose an easy to use interface for plugin writers. My worst problems might be exposing the CString text. They may have changed its layout also and it will require some poking around to find the public or hidden pointer that will get me to the raw data.

My plan is to make a struct that has byte arrays of fill space to skip over the areas I can't/won't do on each pass. The following example code snippet is the cheater struct I used to test my theories with TCPModBusData:

struct TrajectoryControlTCPModCon
{
   char   fill1[2762596l];

   TCPModCon   TCPModBusData;
};

TrajectoryControl                 *M3MainPlanner;                  // original CLASS pointer
TrajectoryControlTCPModCon *M3MainPlannerTCPModCon; // duplicate STRUCT pointer

#define   REGTYPE_INPUT_REGISTERS   0x00
#define   REGTYPE_INPUT_HOLDING   0x01
#define   REGTYPE_INPUT_COILS   0x02
#define   REGTYPE_INPUT_DISCRETE   0x03
#define   REGTYPE_OUTPUT_HOLDING   0x04
#define   REGTYPE_OUTPUT_COILS   0x05

.....

extern "C" __declspec(dllexport) bool   InitControl(void *m3Engine, void *m3Setup, void *m3MainPlanner, void *m3View)
{
   AFX_MANAGE_STATE(AfxGetStaticModuleState());

   M3MainPlanner = (TrajectoryControl *) m3MainPlanner;
   M3MainPlannerTCPModCon = (TrajectoryControlTCPModCon *) m3MainPlanner;

   return true;
}

//---------------------------------------------------------------------
//
//   Config() - Legacy Config Interface
//
//---------------------------------------------------------------------

extern "C" __declspec(dllexport) void   Config()
{
   AFX_MANAGE_STATE(AfxGetStaticModuleState());

    CString   txt;

    txt = "";

    TCPModCon   *tcpModCon1 = &M3MainPlanner->TCPModBusData;                      //just to compare ASM listings
    TCPModCon   *tcpModCon2 = &M3MainPlannerTCPModCon->TCPModBusData;     //---------------------------------------

     for (int i = 0; i < 65; i++)
    {
       TCPModCfg *tmc = &M3MainPlannerTCPModCon->TCPModBusData.cgf;

       if (tmc->Enabled)
       {
          CString   valTxt;
          int regType = tmc->Input;

          txt += "Cgf[";
          valTxt.Format("%02d", i);
          txt += valTxt;
          txt += "]: ";

          switch (regType)
          {
          case REGTYPE_INPUT_REGISTERS:
             valTxt = "Input - InputRegisters";
             break;
          case REGTYPE_INPUT_HOLDING:
             valTxt = "Input - HoldingRegisters";
             break;
          case REGTYPE_INPUT_COILS:
             valTxt = "Input - Coils";
             break;
          case REGTYPE_INPUT_DISCRETE:
             valTxt = "Input - DiscreteInputs";
             break;
          case REGTYPE_OUTPUT_HOLDING:
             valTxt = "Output - HoldingRegisters";
             break;
          case REGTYPE_OUTPUT_COILS:
             valTxt = "Output - Coils";
          }

          txt += valTxt;
          txt += "\n";

          switch (regType)
          {
          case REGTYPE_INPUT_COILS:
          case REGTYPE_INPUT_DISCRETE:
          case REGTYPE_OUTPUT_COILS:
             {
                int byteCnt = 8;
                int bitCnt = 8;

                for (int j = 0; j < tmc->nReg; j++)
                         {
                             if (tmc->Data[j]) txt += "1";
                             else txt += "0";

                             if (--bitCnt == 0)
                      {
                         if (--byteCnt == 0) { txt += "\n"; byteCnt = 8; }
                         else txt += " ";
                        
                         bitCnt = 8;
                      }
                   }

                     if (byteCnt < 8 ) txt += "\n";
             }
             break;
            

          case REGTYPE_INPUT_REGISTERS:
          case REGTYPE_INPUT_HOLDING:
          case REGTYPE_OUTPUT_HOLDING:
             {
                int wordCnt = 8;

                for (int j = 0; j < tmc->nReg; j++)
                         {
                             valTxt.Format("%04x", tmc->Data[j]);
                      txt += "0x";
                             txt += valTxt;

                             if (--wordCnt == 0) { txt += "\n"; wordCnt = 8; }
                             else txt += " ";
                   }

                     if (wordCnt < 8 ) txt += "\n";
             }
             break;
          }
       }
    }

   MessageBox(NULL, txt, "PluginCPP", 0);
}

On a side note. I've empiracally tried many different combinations to get the minimal acceptable functions and declarations to make a plugin. Is there any chance of publishing some of the "Load Plugin" code so I can try to get it down to bare bones?

-Ed

13
Hello All -

I am 99.99% confident I have found the "Why" on why development can't be done on VS2005/VS2008.

I am 97% confident I can "fix" the problem and will soon be releasing ".h" files and instructions for others to use.

The problem IS that Mach is passing you four VERY important pointers. (Thank you Art/Brian). The problem is that several of these are pointers to CLASSes not STRUCTs.

To track down the problem I turned on "Assembly Code Listing" in both 2003 and 2008 and compared the generated code line by line. (Yes I'm that crazy). I immediately found that most of the offsets on MainPlanner (TrajectoryControl *) are WAY off. The reason is that TrajectoryControl inherits CWnd and CWnd changed in the MFC libraries between versions. There may be other inheritance differences that add to the problem.

To test my theory I cast the pointer to a hand crafted struct pointer to allow acces to the TCPModBusData struct down near the end of the data area. Using the struct I was then able to access and display the cgf array in a simple MessageBox in myConfig. I use this same technique in VS2003 to have a look at the raw data inside Mach for debugging a stand-alone MODBUS TCP Simulation Server I am working on for release to the Mach community. I now have two versions of the data dumping plugin. One compiled in VS2003 and one, with minor changes, compiled in VS2008.

I am in the process of analyzing TrajectoryControl.h line by line with the intent of creating a STRUCT that can be used in place of the CLASS. This should allow greater portability across different version of the compiler. I am INITIALLY only targeting the Data areas. After completion I will then target the public functions. I don't know if anyone is, or IMHO even should, or can be calling functions in the class currently in VS2003.

This is not just a tease. I am making rapid progress daily and wanted to "leak" to the community that we may have a clean solution soon.

My ultimate goal will be to then wrap ALL interfaces with Mach in a both a managed C++ class and a C# class to allow using .NET. Using .NET may be optimistic but I believe I can do it. If I can't do it directly then I will wrap it all in COM and interact that way.

-Ed

Edward D. Bryson
Joshua 1 Systems Inc.
Knoxville TN USA

14
Thanx for the quick reply. Based on your message I revisted 'Profile' and found the subscreen and checkbox that allowed me to control it. Sorry for the stupid question.

If anybody else didn't find it: Click 'Profile' in the Forum Toolbar, Click 'Look and Layout Preferences' under 'Modify Profile', then 'Uncheck' the box for 'Show most recent posts at the top.'

-Ed

15
Hi -

I'm new to this forum and am reading through some of the old posts to get answers (lots of 'em) to my questions. This will help me not ask the same question again sometime.

Anyway on several other forums it either through default or by profile shows the 'original' post first followed by all answers in ascending order. For 'historical' browsing I find this much easier to read. First the question then all the answers.

Is there anyway to set that as an option on this forum? I've read through the 'Help' and searched for 'descending' and 'ascending' to no avail.

Again, I'm talking about within a topic. I like 'new' topics or answered topics coming out on top of the topic list and know how to click on 'last' to reverse it.

Thanx,

-Ed

16
I have Mach 2 6.11N and Mach 3 2.0.040 installed on my laptop to test some g-code I'm trying to write.

My goal is to have a dynamic step and repeat that can be given the size of a piece of wood, left, right, top, bottom borders, cutter size, # of rows, # of columns, vertical divider size, and horizontal divider size and it will then route a set of niches with little ridges between each one.

I've worked on this for two or three days and have been frustrated in many ways. I have tried using G92 / G92.1 combo to set the lower left corner of each niche. I've switched to G52 to try and get around the two problems I'm running into.

My technique may not be the best method but it is my first attempt at parameterized g-code. For visual testing I've not yet added any spindle on/off or Z axis movement.

To make each niche I first pass around the outside of the niche, then inset a little and zig-zag up from the bottom to remove the rest of the inside.

The problem with Mach 2 is:

It completely ignores the O2100 subroutine and/or resets or destroys the #501 and #502 parameters. So it both displays and executes the toolpath with just the first pass around each niche. So it won't work for me.

The problem with Mach 3 is:

It displays the toolpath properly (including the zig zag cuts to clean the interior of each niche) but when it goes to run the program it 'screws' up the display by only displaying the excuted toolpath for each niche on top of the lower left niche. Based on switching the x/y/z display to "Machine Coords" it appears that it will actually route correctly since the x/y go up correctly for each niche. It also doesn't, IMHO, report the workpiece movement extremes correctly.

So what stupid thing am I doing? What stupid assumption am I making? Or have I found two idiosyncrasies of the two versions?

Any help would be appreciated.

Thanx,

Ed Bryson

Script Follows:

% GCodeGenericGameBoard - route pockets in flat surface for tiles
%

% design parameters used:

#101=3.      ( board width )
#102=3.      ( board height )
#103=.5      ( left border )
#104=.5      ( right border )
#105=.25   ( top border )
#106=.25   ( bottom border )
#107=.05   ( horizontal divider )
#108=.05   ( vertical divider )
#109=.1      ( depth of pockets )

#111=4      ( rows )
#112=4      ( columns )

#201=.1875   ( cutter size )
#202=.050   ( cutter depth of cut per pass )
#203=6.      ( feed rate )

% calculated parameters:

#301=[[#101-#103-#104-[[#111-1]*#107]]/#111]   ( pocket width )
#302=[[#102-#105-#106-[[#112-1]*#108]]/#112]   ( pocket height )

#311=0
#312=0

% main progam - move to start and iterate rows
%
f#203
#311=[#103]
#312=[#106]
m98 p1000 l#111
g52 x0 y0
g90
g0 x0 y0
m30

; o1000 - do a row
;
o1000
m98 p1100 l#112
#311=[#103]
#312=[#312+#302+#108]
m99

% o1100 - do a single box within a row
%
o1100
g52 x#311 y#312 z0
g90
g0 x0 y0
m98 p2000
g90
g0 x0 y0
#311=[#311+#301+#107]
m99

% o2000 - do a layer of routing for a box
%
o2000
#401=[#201/2]         ( half the cutter size )
#411=[#301-#401]      ( width of path based on cutter size )
#412=[#302-#401]      ( height of path based on cutter size )
g91
g0 x#401 y#401
g1 y#412
g1 x#411
g1 y[0-#412]
g1 x[0-#411]
#501=[[#411]-.02]      ( left/right pass size )
#502=[[#201]-.02]      ( y move each pass )
#503=[FIX[[[#302-.02]/#502]]-1]   ( left/right pass count )
g1 x.01 y.01
m98 p2100 l#503
m99

% o2100 - do a left/right pass to route the area withing a box
%
o2100
g91
g1 y#502      ( move to next pass )
g1 x#501      ( do a pass )
#501=[0-#501]      ( setup for reverse )
m99

% end of file!!

Pages: « 1 2