Tuesday, December 21, 2010

Hand-Drawn Value Stream Map

Sometimes I get ideas where I can't really let go of them, until they're realized. These ideas tend to be stupid, useless, or impractical, or any combination of the three. I probably would do better to just let these things go, but to this point I've only been able to just implement the idea and move on (case in point).

Here's another stupid idea I couldn't let go of: making computer-drawn value stream maps look hand-drawn. It was a concatenation of circumstances that made me implement this; namely, I saw a post on a Visio blog on making shapes look hand drawn.

So I wrote a VBA macro in Visio that takes an eVSM map and makes it look hand drawn. I implemented this and moved on, like I feel I should. But recently, I saw a post somewhere linking to a whiteboard font based on the t.v. show House, and decided I couldn't live without seeing how it my "hand-drawn" maps would look with a "hand-drawn" font to go with it.

Here's a regular eVSM map:













And here is one of my "incredible" hand-drawn maps, rendered like on a whiteboard (minus any smudges one might expect):












I guess my point for sharing this was just to, 1, show off a really stupid little trick I somehow couldn't live without, and 2, to say that sometimes you have to just give up and give in to that part of your brain that thinks "wouldn't it be cool if...". Who knows, it may come in handy some day (and I mean the experience of working through that problem).

Thursday, December 9, 2010

Winter Sim Presentation (2010)

I saw some cool presentations at Winter Sim this year. One vendor presentation that stood out for me was from forio.com, which lets you upload simulation models and run them in the cloud. Very cool.

I also gave a presentation with Swee Leong from NIST:

Monday, November 8, 2010

Bitwise Comparison

Say you want to have a routine in QUEST SCL that may have to do some things and not others, or vice versa. One way you can specify what sections of code to do is have a series of "flag" that tells the routine what to do and not do. Each flag controls one aspect of the code.

One place I can use this kind of control is in a routine for writing debugging messages to a text file, and optionally to the screen. So for one of these routines, I'd probably want a flag saying whether or not to write to the screen, and another to specify if it's an error message (in which case write to the screen and ignore the other flag), and maybe two more for telling the routine when I'm entering a routine and exiting a routine (to keep track of the call stack, so to speak).

So in this case, I'd need to have four flags I'm setting to true or false every time I call this writing routine. And, if I want to add another flag, I have to change all the calls I've made to this routine to match up with the new flag, since SCL doesn't give you the ability to add optional arguments.


So, rather than deal with this issue of having a flag variable for each option I want to add in a routine, I can instead take advantage of the nature of binary numbers in the computer. Before I continue, keep in mind that I didn't major in computer science or computer anything, so my explanation will probably sound hokey and not quite right.

A computer deals with numbers using binary, where we have a set of numerals that can have a value of zero or one. Each numeral you add on adds a power of two (rather than 10 like in our base-10 system). So, for instance, 1 in binary comes out to 2 to the power of 0, or 1. 10 in binary comes out to 0 to the power of 0 (0) plus 2 to the power of 1 (2) = 2. 100 comes out to 0^0 + 0^1 + 2 ^2 = 4. 1010 comes out to 0^0 + 1^1 + 0^2 + 2^3 = 10

Hopefully, if I did that right, you'll see a pattern where each digit we add onto the left adds another power of 2. 1 = 1, 10 =2 , 100=4, 1000=8, 10000=16, and so on. By seeing this pattern, we can also see that we could use a binary integer to store a series of yes/no flags using 1 for yes and 0 for no (or whatever you want). For instance, 2 + 8 in base 10 equals 10 + 1000 in binary or 1010.

The practical upshot of all this so far is, we can now create a series of flags, each unique flag being a power of two value (1,2,4,8,16,32, and so on), and we can store all the flag values we want to activate by adding the ones we're using together.

So, to define our constants for our message logger:
WriteToScreen 1
ErrorMsg 2
EnteringRoutine 4
ExitingRoutine 8

If we want to write that we're entering a routine we'd just pass in WriteToScreen + EnteringRoutine, which would calculate to 9 in base-10, and our routine could then know which flags to activate based on that number 9.

Now, to break that 9 back up into its parts, we need to go backwards and turn a decimal number back into binary 1's and 0's. Following is a routine that'll do that for us. I'm not sure it's the most efficient, but it seems to work. It works by reading left to right in the powers of two (starting at power 8 - you could increase it if you have more flags to handle). So it starts and sees if 2^8 (256) is less than the num we're trying to break apart. If it is, we turn that flag to true, and subtract 256 from the number until we get down to the last power. In this routine we pass in the flag we want to check against, and return true if the bit we're looking at is true.

Hopefully I didn't bungle the explanation too much, but I really just wanted to have this routine up for future reference, and hopefully it gets you thinking of ways it can help you write more concise or powerful code in SCL.

routine bitwise_or( num : Integer ; against : Integer ) : Integer
Var
i : Integer
pow : Integer
sum : Integer
result : Integer
Begin
sum = num
for i = 8 to 0 by -1 do
pow = 2 ^ i
if( sum >= pow ) then
sum = sum - pow
if( pow == against ) then
result = true
break
endif
endif
endfor
return result
End

Monday, October 25, 2010

GetTickCount

Tonight I was trying to debug some slow SCL code, and wanted to pinpoint exactly which routines were taking the longest to execute. QUEST has a systime() routine that returns the number of seconds since midnight. However, I wanted more accuracy, so I needed to use the GetTickCount routine provided by the Windows API.

I can call this routine using C_EXEC in SCL, and the final routine comes out like this:

routine get_tick_count() : Integer
Const
THE_DLL 'kernel32.dll'
THE_CMD 'GetTickCount'
Var
func_return : Integer
Begin
func_return = c_exec( THE_DLL + ":" + THE_CMD )
return func_return
End

Now, I can get a bit more visibility into what's taking my logics so long to run (though be sure to disable any calls to this routine once you're ready to just run the model)

Friday, October 15, 2010

Select a Part

The other day I was working on a project where I wanted some stats on a part in a model that don't show up in the Trace Entity window. So, I went to write a macro that would let me select a part and show the information I needed. I then realized that I didn't have a routine available that would let me easily select a part, so I went about writing one. Now, it's available for download here, because it was a pain to write and now you don't have to write it too.

Thursday, September 9, 2010

eVSM and QUEST User Groups

If you read back to past posts on this blog, you'll see I do a bit of work with eVSM. Up until now, there hasn't been any organized group of eVSM users that I know of, but that's now changed. An eVSM user has started a LinkedIn group geared toward discussing eVSM, as well as how to do various things in eVSM. You have to be a LinkedIn member to join, and then you have to search for the eVSM user group. Honestly, it would be nice if we could get enough eVSM users on board to build an eVSM Stack Exhange site.

I'm hoping this community gets enough power users and casual users to build and sustain some decent conversation. Luckily, the QUEST group I set up seems to have a great core of power QUEST users (including past & current Deneb/DELMIA employees) who are able to give advice and tips on how to tackle specific problems in QUEST.

Hopefully we can say the same for the eVSM group, soon.

Wednesday, August 18, 2010

eVSM to QUEST Beta Version Now Available

Any QUEST users interested in trying our (CCAT's) eVSM to QUEST converter may now do so, if they'd like to participate in beta testing (meaning we're not sure how well it works yet on lots of different computers). So if you'd like to try it out, email me at jfournier@ccat.us and let me know.

This requires you at least have access to QUEST and Visio (you'll have to get a trial version of eVSM)

Also, more information here.

Friday, June 18, 2010

IE Stack Exchange Site

I recently advocated anyone reading this blog check out OR-Exchange. Basically, the case is/was that if OR-Exchange didn't get to a certain amount of web traffic it would be shut down, as the people behind it (Stack Exchange) have a new model where they want to create nice, high volume question and answer sites on any topic people are willing to discuss.

I've been thinking about it, and it's my opinion that OR-Exchange may be a bit too niche to be able to attract enough users to keep alive.

So I am proposing we create a Stack Exchange site on Industrial Engineering/Continuous Improvement/Systems Analysis, whatever you want to call it.

If you're interested in seeing this site come to fruition, visit:


and follow the site, and if we can get enough followers and example questions, we can move on and get a centralized, modern community started for discussing anything IE/OR/CI.

Tuesday, June 1, 2010

Number Rounding in SCL

I recently found the need to do some simple number rounding in SCL, and was able to dig these two routines out using my SCL Subroutine Indexer though the index was from a previous computer I used, and hadn't copied over to my current machine. Thankfully, Google Desktop was able to find a backup copy I had made who knows when. So, to prevent me from losing these simple functions forever, here they are.

Nothing fancy; I round a number down by converting it to an integer string, then reading it back to a number using VAL. I guess SCL will truncate a number at the decimal point when converting to an integer string (%g), rather than do any real rounding. So to round up I just round down and add one. Like I said, nothing fancy, and apparently nothing worth searching for 20 minutes over. Anyways, these would be good to keep compiled all the time.

routine round_down_to_int( num_value : Real ) : Integer
Var

int_string : String
result : Integer

Begin

result = 1
int_string = str( '%g' , num_value )
result = VAL( int_string )
return result

End
routine round_up_to_int( num_value : Real ) : Integer
Var

result : Integer
rounded_down : Integer

Begin

return round_down_to_int( num_value ) + 1

End

Thursday, April 22, 2010

eVSM, CMSD, and ProModel

So here's a video showing the new ProModel translator I wrote for CMSD. It also shows a little bit of the CMSD Viewer program I've been working on. Best watched in HD so you can read the text and follow along...

Core Manufacturing Simulation Data

I'm not sure if I've mentioned this yet, but I'm pretty sure I haven't. A little over 3 years ago I attended Winter Sim 2006 in Monterey, CA (nice place by the way) and got introduced to the Core Manufacturing Simulation Data (CMSD) specification from NIST. This spec was supposed to act as a neutral data format for holding manufacturing simulation.

I watched its progress over the years, hoping at some point to be able to apply some of my past work translating Value Stream Maps into QUEST models to be generically available to any simulation package.

Cut to March of 2009, and it seemed like the spec was getting pretty close to being a standard. NIST had the spec in to SISO for review and eventual vote, and my boss saw a presentation by Swee Leong from NIST, and was impressed enough by it to allow me to start working on a CMSD translator for Value Stream Mapping.

So I got started right away, first stepping back and looking at what this translator should be. I should mention that the CMSD format is technically set to be a UML standard, but along with that will come an XML schema. So anyways, long story short, I hadn't done much work with parsing XML files, and had some experience kludging together solutions to build XML files, and didn't like the idea of implementing a parser/writer for each translator I might write.

So I decided to build a centralized CMSD XML parser/generator, utilizing Microsoft's built-in DOM libraries to do the actual file I/O from/to XML files, and I would write the code to translate XML elements into instances of CMSD classes. So I built that central tool as a COM/ActiveX class, using VB6 (I know, could I possibly use something older?). So to read a CMSD file I just have to create a new CMSD object and tell it to read the file, and I get all the CMSD data in a nice, easy to program against object model. And, I only have to write and maintain one XML I/O code base, which makes me happy.

So I called this class the CMSD API (very original, I know) and started writing translators. To cut my teeth on the standard, I started off just building something to build a QUEST model from a CMSD API object, just using a simple XML file that NIST had provided to me to demonstrate the XML format. That one translator has turned into about a dozen different translators, some proofs of concept, and some potentially useful tools.

So here, after six paragraphs, is where I get to my point. We're reaching the stage where these translators are ready for some public consumption. They're hopefully useful enough that people can use them, though because the CMSD standard isn't really set in stone yet, I'll refrain from calling them CMSD-based tools; rather they're just tools that utilize a custom XML format.

Okay, so seven paragraphs in, and my point is that I'm looking for simulation users interested in trying this software out. I can't guarantee I can take everyone, and ideally you should be a user of more than one of the following tools:
1. DELMIA QUEST
2. eVSM
3. ProModel
4. Arena
5. Excel
6. Simio
7. FlexSim

Now, if you only use one of the above-listed simulation packages, that's okay. I've also been working on a standalone CMSD editor, that hopefully in the future can take the place of a simulation package builder interface (and just use the simulation package as a solver). Also, if you're good at programming in VBA and would like to be able to build your own translators with my CMSD API, let me know, as I'd like to get feedback on the quality of the methods in the API.

So if you're interested in joining a beta test, contact me. In the meantime you can see the documentation for these tools grow as I write it (thank you, Google Docs):
Documentation

Thursday, April 15, 2010

OR Exchange

I've been a member at StackOverflow since it launched to the public. For those who don't know what it is, it's basically a question and answer site built the way a question-answer site should be built; namely, every page deals with questions, and answers (rather than traditional forum type sites, which are more for threaded discussion, but get question-answer sits shoehorned in). They've built a fantastic community, which means you can go on there and ask a programming question and get an answer in a pretty respectable amount of time.

About 6 months ago they launched StackExchange, which was a service that let people set up their own question-answer sites, with the same look and feel as StackOverflow, but you were responsible for getting your community in order. Apparently a lot of the sites that were created never really got going very well, and that's led the StackExchange people to change the rules a bit. From now on, if you want to start a StackExchange site, you have to put together a proposal convincing them why they should build it, and then you have to rally enough users to initialize the site with questions and answers, and hopefully get enough momentum going that they can launch your site and you end up with a community where you can get answers to your niche questions.

The point of this post, then, is to talk about OR-Exchange. OR-Exchange is a StackExchange site built for answering Operations Research problems, which involves a lot of math programming, but simulation is definitely a part of that. Unfortunately, the StackExchange people don't seem to think there's enough participation in the site, so it's got 3 months left before it's shut down (we'll call it early July is the termination date).

So I encourage you, if you're a simulation user (and why wouldn't you be if you're reading this, unless you're my mom (who doesn't read this, by the way)) to visit OR-Exchange.com and join the community, and maybe ask some general purpose simulation questions (if you know the answer, you're allowed to answer your own questions, too).

Wednesday, March 31, 2010

Interpreting BCL Error Codes

From time to time I'll have to write an SCL macro that executes some BCL statements. It's usually pretty straightforward, just issue the command using the BCL() function in an SCL macro, and it'll return a numeric error code, including 0 for a normal return.

Sometimes though, especially when working with user-provided data, these commands can fail (often due to invalid characters or some such thing). When a BCL command fails, the BCL() function returns a non-zero number and an error message gets printed to the screen for the user to see.

However, a lot of the SCL macros I write are run pretty much autonomously, so anything printed to the screen gets lost to me. That's why I usually have a function for logging messages to a text file, for analysis after the fact, to see why some macro failed.

So, getting to my point, finally, when I am using the BCL statement, I like to have my own routine (named exec_bcl_cmd or something) that wraps all this stuff together: executing the BCL statement, evaluating any error code return, and logging that to a text file. I've created an example SCL file that shows most of this, just a procedure named exec_bcl_cmd, that executes a bcl statement string, then converts the bcl return code integer into a more descriptive error message (pulled from the bclerr.inc file).

You can download it here.

Wednesday, March 24, 2010

Name Change

If anyone even reads this to notice, I've changed the name of this blog from just DELMIA QUEST to DELMIA QUEST and Manufacturing Simulation. I did this because, for the last year or so, I've been dedicating a lot less time to QUEST than I previously did, and a lot more time on using Value Stream Mapping for building simulation models, as well as some other production design/analysis tools.

I'm going to continue focusing a lot of content ("a lot" is used loosely here meaning there's not much content to this blog anyway) on QUEST, but I also want to be able to talk a bit more about the other stuff I do, and a lot of that applies in some way to QUEST, ultimately.

How to Populate a Value Stream Map with Simulation Data

So if you look back in the archives of this blog you might see I've done some work taking data from Value Stream Maps (VSM's) and using it to build QUEST models semi-automatically. With pretty much any simulation package, a user is presented with an interface that exposes pretty much every option imaginable. With VSM, a user only tacks on the data they have available. Some people get overwhelmed by too many dialog options at once. In essence, when you're building a VSM with the intent of using it for simulation, you're only sticking in the data you have, and ignoring all the other options you don't have information for, with a much simplified interface (the VSM software).

It's also important to note that there are two different world views for manufacturing simulation packages, really, that I've seen: resource-based, and process-based. In a resource-based world view, you see all your machines on a virtual floor with some labor objects, maybe. Parts or whatever you call them enter at a source and jump around machines and modeling elements corresponding to, for the most part, physical objects. A process-based view is different, in that you basically get a flow chart where each block usually represents a process or a decision or something. The part item arrives at a source, again, but now moves between processes in sequence through the flow chart. A process can require different resources, so that parts end up getting blocked like in real life. Essentially both world views contain the same information and provide the same outputs, but just go about getting the outputs in different ways.

I'll tell you right now that a VSM pretty much takes on a process-based world view, except that people usually name their process boxes after the resource where the process is done. So there's sort of an implicit definition there, saying that we're doing a process, and that this process requires a resource based on the name of the process.

You may or may not know about QUEST's world view, so I'll go over that quickly: it's a resource-based view, with a construct called a "process" that holds attributes on the process, like what labor resources it requires and what the cycle time is and all that. There is also a "part class" construct that holds some attributes, including the sequence of processes the part needs to be "completed". A machine in QUEST can be told what processes it's able to perform, so that when a part arrives at it, it decides what process to do on that part, and we can then route the part on to its next process (whatever machine that may be at).

So a few years ago a client presented us with a VSM they had created that detailed the process flow for a line they wanted to simulate. It contained some cycle times, but it was, otherwise, pretty much just a process sequence.

So I had to figure out, how can I take this information in an eVSM file (which has an automatic export to Excel) and turn it into a QUEST model. It was pretty easy to just do a one-to-one build of processes in QUEST; one process for each process block in the VSM. But the missing component of data, then, was how to tie a process to one or more machines in a QUEST model?

To tie a VSM process to a QUEST machine resource, I simply had to add a tag onto a process with the ID of the machine to attach it to (a many processes to one machine relationship). So the actual SCL code to do this consisted of reading through the Workstation column in the Excel file, and for each unique value in that column, just build a machine with that name. Then read through every process (row) and create a process in QUEST with that name. Then, look at the Workstation column for that process row, and assign the process to that machine (the Workstation value can actually be a comma-delimited list to specify that multiple machines can handle the process).

The next challenge was process sequencing. I could have assumed that the Excel output from eVSM was in order of the process sequence, but that'd be pretty limiting to a simulation user. eVSM requires that you provide a tag shape to each process shape, and the tag value must be unique for each process. So, I required that the sequence be encoded through just specifying a process' next operation in the sequence (using that next operations' tag text) as a process attribute. Then, the SCL to build the QUEST model just has to set the process sequence for a part class to the sequence of operations in that Excel file. This way of creating the sequence also allowed me to look at each individual process, and find whatever processes were feeding into it. So if I found two or more processes that both output to a single process, that single process must be an assembly operation, and require a part from each of them before running the process.

That brings me to my next, and final data requirement: the part type. Like I said, QUEST likes to have a part class for each unique part type in a system (there are exceptions of course, but I won't get into them). Each part type (in the type of model we're building here) should then have a sequence of operations for the purpose of routing and process execution. So to specify the part type for a process, I just required there be a Product attribute on each process, and the SCL chunks through the data and identifies the sequence of operations and assembly points and all that automatically.

But, to close out, we really need three pieces of information to successfully build a (however basic) QUEST model: what are our part types, what are their process sequences, and where do those processes get done. And a VSM is perfectly adequate at providing that information. I meant to be a lot more succinct in my explanation of how the conversion works, but I'm not sure it's possible. I'll give it a shot again some other time.

Thursday, February 18, 2010

Winter Sim Presentation

This past December, I was fortunate enough to be able to present some of the work I've been doing with extracting data from Value Stream Maps and turning it into simulation data. I started off using QUEST as the simulation tool for the data, and last March (2009) I got the green light to start working on implementing the Core Manufacturing Simulation Data (CMSD) format. The CMSD is meant to be a generic simulation data interchange format, sort of like STEP is for CAD.

So, here's the presentation I made at Winter Sim. If you want to talk about it, you can contact me here.

Wednesday, January 20, 2010

Labor shirt colors

This is a stupid, however somewhat useful SCL macro. Sometimes I end up with a model with lots of laborers who all have the same color shirt. Call me crazy, but I think the model presents a little better if the labors don't all look the same.

So here it is, a stupid SCL macro you can use to change all your labors' shirt colors (note it won't let the color be the same as his pants or skin color (at least with the default laborer I'm using))

So here it is


SCL Examples

I recently received an email from a student using QUEST who was looking for examples of SCL.

I told him to first look at the default QUEST logics at QUESTlib\Sysdef\Logics, to see how QUEST uses SCL.

But I can't think of any good examples of how to write SCL macros. So I found an old macro I wrote that dumps all the process assignments for each laborer in a model to a tab-delimited text file. I figured it would be a good example of how to use SCL to get information out of a model, and shows some examples of different SCL syntax.

You can download it here, hopefully; I put it on Google Docs as just a file, so you should be able to go download it there.