Photos of Ireland of the 50s go on display in Dublin
French photographer Henri Cartier-Bresson was known as ‘the eye of the century’ and captured the last images of Gandhi before his death.
However, pigs being slaughtered, family outings to the races, and upturned currachs were also the focus of his lens during his time in the Ireland of the 1950s and 1960s.
Opening an exhibition of his work, and that of US photographers Dorothea Lange and Robert Cresswell in the National Museum (Collins Barracks) tonight President Michael D Higgins said Cartier-Bresson was ‘a humanist photographer’, who ‘pioneered the genre of street photography’.
“I understand the majority of the Irish images on display have never been shown in Ireland or indeed elsewhere,” said Mr Higgins.
“So we are fortunate in seeing these images of a period often neglected by Irish historiography, one in which the professional, agricultural producers, and institutional forces took on a particular class formation which would last into the modern period,” Mr Higgins added.
The exhibition, curated by Fidelma Mullane, comprises 50 images by Cartier-Bresson, about 30 of which have never been exhibited anywhere in the world before.
Ms Mullane spent many months working with the Henri Cartier-Bresson Foundation in Paris to select the black and white images from some 4,000 in contact sheets.
The exhibition also comprises work by US photographers Dorothea Lange and Robert Cresswell. Lange, who is best known for her images of Depression Era America, was sent by Life magazine to document rural Co Clare.
Cresswell, an anthropologist based in Paris, lived in Kinvara, Co Galway while undertaking research.
Cresswell’s subsequent work was entitled Une Commuunauté Rurale de l’Irlande, and is now considered a seminal study of rural life.
Cartier-Bresson undertook several trips to Ireland, the first being in 1952, and the second a decade later. His images captured a society still dominated by the Catholic Church, but on the cusp of change.
Mr Higgins noted the photographers visited Ireland at a time when land would only support “one landholder....one dowry”, and emigration for most was the norm.
The President quoted the late critic and writer John Berger in emphasising the essential role of the arts in the “opening of pathways to different and better futures”.
Mr Higgins also highlighted the value of public spaces, including galleries and libraries.
“If we put the arts at the very edge of our society, place them out of the reach of the majority of our citizens, we do ourselves a great disservice,” Mr Higgins noted.
Ireland in Focus runs at the National Museum of Ireland, Collins Barracks, Dublin until April 2020.
READ MORE
Joseph O’Connor, Vickie Phelan and Andrea Corr among big winners at book awards


MORTAL KOMBAT A film review by<EMAIL_ADDRESS>Copyright 1995<EMAIL_ADDRESS>Rating: one and a half stars
After seeing the trailers for this movie, I thought to myself that this would finally be a decent video game-to-movie translation. (note I said decent, not great).  The characters are lacking any depth, and they all think they're George Carlin. The action is a bit weak, but the movie is still a lot better than STREETFIGHTER. My advice is to wait for it to hit video if you must see it. My only wish is that if they do make a sequel (as is hinted at the end of the movie) that they hire new writers, and pack a bit more action into it.
<EMAIL_ADDRESS>The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Timothy E. Whitsitt
Democrat
Self employed lawyer. The name of my law practice is Whitsitt Law Office, LLC in Carbondale, CO
BS in Political Science and Economics, 1970, Purdue University JD and MPP, 1974, University of Michigan
81621
I was the Pitkin County representative to the Bar Association Board of Governors for approximately 6 years in the early 2000's. At about the same time I was a member of Governor Ritter's Domestic Violence Taskforce. I served as president of my local Carbondale Rotary Club in 2006. I have been a member of the Board of Directors of the Aspen/Pitkin County Employee Housing, Inc. organization for 30 years. It is a private nonprofit entity which constructs and manages rent restricted housing in the Aspen and Roarking Fork Valley. We've built then owned and operated a 32 unit multifamily rental housing development in Aspen for that entire period of time. We are now in the process of building a new 30 unit rent controlled development in Carbondale with tax credit financing. I was in the late 1990's on of the principal organizers and initial President of the Roaring Fork Valley affiliate of Habitat for Humanity.
Statewide and nationally, I have had fairly limited experience. I have been an active participant in local (town and county) political campaigns for over 20 years. I have contributed to various Democratic candidates for statewide or federal office in the election cycles since 2015, including Andrew Romanoff (2020), Joseph Biden (2020), Diane Mitsch Bush (2020), Beth McCann (Denver DA) 2018, 2020. Hilary Clinton 2016
Aspen/Pitkin County Employee Housing, Inc. Board Carbondale Rotary Club
I think that redistricting is one of the most important and overlooked functions of our government, which has a huge influence on governmental operations and individual representation over a ten year period. The importance of this process in actually implementing the 'one person, one vote' rule cannot be overstated.
I feel that I am generally a consensus builder and would certainly utilize those skills in the work of the commission. I feel that I have a very good geographic base and a pretty fair understanding of the state of Colorado and most, if not all, of its local watersheds and communities of interest. I think that this knowledge will be of great assistance in the commission's work. I have also spent a fair amount of time in several different periods looking at the re-establishment of county boundaries, specifically the boundary between Pitkin and Eagle Counties which unfortunately does not follow logical geographic and physical boundaries, but is instead a straight line, resulting in fairly large disasociation of a portion of the voting populace from the seat of county government.
male


The TRANScription FACtor database is a manually curated set of motifs managed by the company BIOBASE. The most up-to-date version of the TRANSFAC database has to be licensed but older versions are available free for non-commercial users.
Most MEME Suite programs do not support the TRANSFAC 'matrix.dat' motif file directly but there is a script for converting it into MEME format motifs.
For MEME SUITE purposes, the essential portions of the TRANSFAC matrix format are:
The P0 row labels the columns with the letters of the sequence alphabet. The numbered rows (01...nn) contain counts for each letter in the sequence alphabet for that position in the motif. These counts should give the number of times each letter appears in known examples of the motif at the given position. The counts in each numbered row should add up to the same total count. The last column in each count row gives the consensus letter for that position in the motif, and is ignored by MEME SUITE programs.
Here is an example of a TRANSFAC format motif file containing two motifs suitable for MEME SUITE programs:
ID any_old_name_for_motif_1 BF species_name_for_motif_1 P0 A C G T 01 1 2 2 0 S 02 2 1 2 0 R 03 3 0 1 1 A 04 0 5 0 0 C 05 5 0 0 0 A 06 0 0 4 1 G 07 0 1 4 0 G 08 0 0 0 5 T 09 0 0 5 0 G 10 0 1 2 2 K 11 0 2 0 3 Y 12 1 0 3 1 G XX // ID any_old_name_for_motif_2 BF species_name_for_motif_2 P0 A C G T 01 2 1 2 0 R 02 1 2 2 0 S 03 0 5 0 0 C 04 3 0 1 1 A 05 0 0 4 1 G 06 5 0 0 0 A 07 0 1 4 0 G 08 0 0 5 0 G 09 0 0 0 5 T 10 0 2 0 3 Y 11 0 1 2 2 K 12 1 0 3 1 G XX //
The TRANSFAC matrix format can be converted to MEME format with the transfac2meme script.


We Got Planets
Home
Product
Contact
WARNING!!!!!!!
If your planet is inhabited by intelligent life contact your WGP representative right away!!!!!
Fill out the form below.
Full Name:
Galactic Number:
Planet:
Sigma 5
Plides 12IO
Gestyria
Please give us as much detail as possible to make your planet chose to your liking.
Submit


kaggle competition
Predicting Molecular Properties
Go to kaggle competition
Overview
- Goal:
Predict interaction between atoms (scalar coupling constant) in molecules
- Data:
130775 3D-structures of organic molecules
- Methods:
Graph convolutional neural network (SchNet)
- Result:
Top 8% place in kaggle competition (my first kaggle medal)
Notebooks
kaggle competition
Histopathologic Cancer Detection
Go to kaggle competition
Overview
- Background:
This project was done in collaboration with my college Marcel as our course
project for the seminar 'Advanced Data Challenge'.
- Goal:
Predict, if medical images show cancerous or healthy tissue
- Data:
50000 histopathologic images
- Methods:
Convolutional neural network (DenseNet)
- Result:
96% accuracy (balanced classes)
Notebooks
ResNet and DenseNet
Building conv-net architectures from scratch
Overview
- Background:
Course project for the computer vision seminar taught by Roland Kwitt at the University of Salzburg
- Goal:
Classify images with hundred different classes: various animals, every-day objects, etc.
- Data:
50000 tiny images of the CIFAR-100 benchmark dataset (example images shown above)
- Methods:
Convolutional neural networks: ResNet and DenseNet
- Result:
Learned, how these neural network architectures work by building them from scratch
Go to git-hub repo


All trajectory data submitted to BIGNASim needs to be accompanied by its metadata. It can be easily generated through the web site forms, following the standard deposition procedure. However, a more authomatic way to produce such information is also made available though the use of metadata files. They are CSV files composed by:
The list of accepted tags are the following:
| datasetName | Acronim for a dataset which groups one or several trajectory files. Format: alphanumeric chain of 4>length>7 |
| datasetDescription | Short title or description for the dataset |
| publDateSys | Method to define the dataset publication date. Options are "release": submitted data will be made public immediately after validation, "hold": data will be on-hold until [publDate] is reached |
| publDate | Date on which submitted data will be release given [publDateSys]="hold". Format: yyy/mm/dd |
| pubSys | Method to define how the dataset reference publication is given. Options are "document": the dataset is referenced by uploaded files. "reference": the dataset is referenced by a public study. [pubTitle], [pubAuth], [pubJourn], [pubYear], [pubVol] and [pubDOI] require to be specified |
| pubTitle | Title of the dataset reference publication. Mantadory if [pubSys]="reference" |
| pubAuth | List of authors (comma separated) if the dataset reference publication. Mantadory if [pubSys]="reference" |
| pubJourn | Journal where the dataset reference publication is published. Mantadory if [pubSys]="reference" |
| pubYear | Year of the dataset reference publication year. Mantadory if [pubSys]="reference" |
| pubVol | Volume of the Journal where the dataset reference publication is published. Mantadory if [pubSys]="reference" |
| pubDOI | DOI identifier for the the dataset reference publication. Mantadory if [pubSys]="reference" |
| trajFormat | Format of the trajectory file uploaded. Options are "traj_crd": AMBER CRD, "traj_dcd": CHARMM/NAMD DCD, "traj_cdf": AMBER NetCDF, "traj_gro": AMBER BINPOS, "traj_xtc": Gromacs XTC. |
| topFormat | Format of the topology file uploaded. Options are "top_pdb": PDB, "top_prmtop": AMBER PRMTOP, "top_psf": NAMD PSF, "top_top": GROMACS TOPi, "top_itp": GROMACS ITP, "top_rtp": GROMACS RTP |
| PDB | Protein Data Bank identifier for the reference experimental structure of the trajectory |
| NDB | Nucleic Data Bank identifier for the reference experimental structure of the trajectory |
| ligandNames | Comma separated list of ligands included in the trajectory |
| additionalSolvent | Comma separated list of additional solvent molecules of the trajectory |
| counterions | Comma separated list of counterions molecules and their concentrations |
| trajLength | Total trajectory length in nanoseconds. If the trajectory is splitted into multiple files, the sum of them. |
| frames | Number of frames |
| frameStep | Time step taken between frames in nanoseconds |
| trajTemperature | Trajectory temperature in kelvin degrees |
| comments | Any comment valuable for the submission that may help to the correct classification of the data |
| rmsd | all-heavy atoms mass weighted RMSD (%) |
| rmsd_bp | all-heavy atoms mass weighted RMSD per base pair (%/bp) |
| Rgyr | Radius of gyration (%/bp) |
| lostWC | Percentage of lost Watson and Crick bonds |
| lostContacts | Percentage of lost 3D contacts |
| fraying | Presence of fraying. Options are "yes", "no" |
| avgTwist | Global average Twist (degrees) |
| avgRoll | Global average Roll (degrees) |
| minorGrooveSize | Minor groove dimensions . Format: width x depth |
| majorGrooveSize | Major groove dimensions . Format: width x depth |
| grooveSizeMethod | Method use to compute the groove dimensions |


Global NL Database
Console
Add New Location
Add New Student
Add New Job
View Job Map
User
Logout
Add New Job to Database
Location
Choose a location
Student
Choose a student
Position Title
Date
Add Job
Back
© 2017 Global NL


When you ssh to a remote server, your ssh client records the hostname, IP address and public key of the remote server in a flat file called “known_hosts“. The next time you start a ssh session, the ssh client compares the server information with the one saved in the “known_hosts” file. If they differ, an error message is displayed.
If an attacker has access to your home directory, he will have access to the file which may contains hundreds of hosts on which you also have an access.
OpenSSH introduced a countermeasure against this attack since the version 4.0. The ssh client is able to store the host information in a hash format.
The hostname is not readable anymore. To achieve this result, a new configuration directive has been added in version 4.0 and above: “HashKnownHosts [Yes|No]“.
Note that this feature is not enabled by default. Some Linux (or other UNIX flavors) enable it by default. Check your configuration. If you switch the hashing feature on, do not forget to hash your existing known_hosts file:
$ ssh-keygen -H -f $HOME/.ssh/known_hosts
By looking into the OpenSSH client source code (more precisely in “hostfile.c“), I found how hostnames are hashed. Here is an example:
|1|U8gOHG/S5rH9uRH3cXgdUNF13F4=|cNimv6148Swl6QcwqBOjgRnHnKs=
“|1|” is the HASH_MAGIC.
The first part between the separators “|” is the salt encoded in Base64. When a new host is added, the salt is generated randomly.
The second one is the hostname HMAC (“Hash-based Message Authentication Code“) generated via SHA1 using the decoded salt and then encoded in Base64.
Once the hashing performed, it’s not possible to decode it. Like UNIX passwords, the only way to find back a hostname is to apply the same hash function and compare the results.


You must click the button to see me
The button changes colors on hover
Dev Tools Tricks
- Dev Tools Can Have a Dark Mode Too!

- Inspect Page Elements
- Test CSS
- Find Out Where Code Needs to Be Changed
- Simulate User Actions to Test CSS
- Move the dev tools around
- See more organized console.logs with console.table


Alien Resurrection Director: Jean-Pierre Jeunet Starring: Sigourney Weaver, Winona Ryder, Ron Perlman, Michael Wincott, Brad Dourif Rated: R
If you compared the basics of Aliens (the second installment of the series) with Resurrection (the fourth) you would assume they were identical. Ellen Ripley (Weaver) leads a group of gritty, mega-gun toting renegades through the bowels of a ship, looking to destroy the queen alien, in an effort to save themselves and mankind. Unfortunatley for the gang there is an evil guy lurking about who's real intention is to save the alien species, even if it means destroying the humans on board.  Eh. Not so much. Despite the core of similarities to previous Alien films, Resurrection has enough slam-bang action, enough surprises (and plenty of goo) that in my estimation, it is the best of the sequels thus far.
What's different about Resurrection is that Ripley has had a complete personality makeover. Her only similarity to the former Ripley is that she looks astonishingly like Sigourney Weaver. The fourth installment takes place approximately 200 years after she died in Alien 3. But those sneaky scientists managed to find a strand of her DNA in some blood from the prison compound and, combined with Alien DNA, create a new, more powerful and more dynamic Ripley clone. One fascinating element about Resurrection is that since Ripley (still the series' heroine) is part Alien, she has some compassion for them. She has natural instincts that tell her where they are lurking, ditching the computer tracers from all the earlier films. ("It's right behind you man! Get out of there man!") There are some psychosexual elements that I won't presume to ruin for you. Let's just say there's a lot of goo involved. Pretty funky stuff.
Another thing that Alien Resurrection offers that the first three hardly attempted were major digital effects, which make up most of the Aliens you see in this film. Here's a tip; whenever you see an Alien in a close-up, it is a slime-splashed animatronic, its really there. If you see an Alien running or swimming or climbing, it's digital. I tell you this because you may not be able to tell, they are done astonishinly well.
For true Alien fans, Resurrection re-hashes some of the old tricks (not everyone is what you think they are). There is a classic flamethrower which gets quite a bit of use in one scene. Acid blood plays a big part in this one too. But not everything is old hat. There are a few new Alien surprises in this one, which, if you can get past the Grand Canyon sized plot holes, are pretty creepy and cool.
This is indeed the most violent, gory and gooey Alien film to date. (No, it ain't Flubber.) But Jeunet manages to make the grotesque somehow fitting and almost appealing in this fourth installment. Very seldom did I get the feeling that there was a disembowelment for no reason. Everything seems to have its place here. It kept me on the edge of my seat, it made me laugh (appropriately, of course) and it made me glad that this was such a strong rebound from the last sequel. What's more, who knows how long they can continue this series now? After Alien 3, we were pretty dang sure it was over. But ever since they cloned those sheeps in England, these Hollywood people have a whole new arena to play with.
3 out of 4 stars Copyright (C) 1997 Nick Amado
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


The background attribute was used to specify the URL of an image to be set as the background for a td attribute.


Welcome
This website documents the usage of the Gemma REST API. Here you can find example script usage of the API, as well as graphical interface for each endpoint, with description of its parameters and the endpoint URL.
The documentation of the underlying java code can be found here. See the links section in the footer of this page for other relevant links.
Use of this webpage and Gemma web services, including the REST API, is subject to these terms and conditions. Please read these in full before continuing to use this webpage or any other part of the Gemma system.
Updates
Update 2.3.4
November 6th, 2018November 6th [2.3.4] Bug fixes in the dataset search endpoint.
November 5th [2.3.3] Added filtering parameters to dataset search.
October 25th [2.3.2] Changed behavior of the dataset search endpoint to more closely match the Gemma web interface.
October 2nd [2.3.1] Added group information to the User value object.
September 27th [2.3.0] Breaking change in Taxa: Abbreviation property has been removed and is therefore no longer an accepted identifier.
Update 2.2.6
June 7th, 2018Code maintenance, bug fixes. Geeq scores stable and made public.
June 7th [2.2.6] Added: User authentication endpoint.
May 2nd [2.2.5] Fixed: Cleaned up and optimized platforms/elements endpoint, removed redundant information (recursive properties nesting).
April 12th [2.2.3] Fixed: Array arguments not handling non-string properties properly, e.g. ncbiIds of genes.
April 9th [2.2.1] Fixed: Filter argument not working when the filtered field was a primitive type. This most significantly allows filtering by geeq boolean and double properties.
Update 2.2.0
February 8th, 2018Breaking change in the 'Dataset differential analysis' endpoint:
- No longer using qValueThreshold parameter
- Response format changed, now using DifferentialExpressionAnalysisValueObject instead of DifferentialExpressionValueObject
[Experimental] Added Geeq (Gene Expression Experiment Quality) scores to the dataset value objects
Update 2.1.1
December 5th, 2017Added the 'Dataset SVD Information' Endpoint.
Update 2.1.0 (Public stable release)
November 28th, 2017Breaking change in all endpoints that use the ExpressionExperimentValueObject in the response (mainly Datasets, Dataset search, Platforms datasets). The structure of the value object has changed - removed unused properties (moved to ExpressionExperimentDetailsValueObject, which not used in the API)
Breaking changes in 'Dataset genes expression levels' endpoint:
- Added 'consolidate' parameter
- Structure of the ExperimentExpressionLevelsValueObject , that is used in the response, has changed.
Added Basic Authentication.
Fixed: The 'Short Name' identifier for datasets not allowing hyphens.
Versions prior to this release were considered experimental (beta - minor version not bumped on breaking changes).
Update 2.0.5
November 28th, 2017Fixed: gene coexpression endpoint not working.
Fixed: Multiple ontology term URIs not being parsed properly in search endpoints.
Fixed: Problems when some parameters contained unescaped forward slashes
Fixed: Taxon array arguments not working if the first identifier was not found.
Fixed: NPEs on various occasions.
Update 2.0.4
October 30th, 2017Breaking change: Use FactorValueBasicValueObject in 'Dataset samples' endpoint.
Added 'Datasets genes expression levels' endpoint.
Added 'Datasets pca component expression levels' endpoint.
Added 'Datasets differential expression levels' endpoint.
Improved unrecognized identifier error message.
Update 2.0.3
October 18th, 2017Breaking change: Removed 'specific x' endpoints - replaced with 'all x' endpoints using array arguments.
Breaking change: Add array arguments to 'Platform elements' and 'Genes' endpoints.
Breaking change: Change 'Dataset search' endpoint URI to use 'datasets' instead of 'experiments'
Fixed: limit 0 causing 0 results instead of not limiting the response size in some endpoints.
Update 2.0.2
October 18th, 2017Breaking change: Add array arguments, add listed datasets endpoint.
Added NCBI ID as a possible Taxon identifier.
Added optional tree parameter to the 'Taxon phenotypes' endpoint.
Added 'Taxon phenotypes candidate genes' endpoint.
Update 2.0.1
September 22nd, 2017Fixed: Various NPEs and small problems.
Update 2.0-Beta
August 16th, 2017Public beta release.
Code samples
Examples of the API usage in scripts.
{{ rExample }}
R package
For the R language, it is best to use the gemma.R package . Please follow the link for documentation on how to use it. The above code example is connecting directly to the API without the use of the package.
{{ pythonExample }}
API Endpoints
Below is a list of all API endpoints, with a GUI for test calls.
Click on the endpoint category to expand it, and then on each endpoint name to see its interface and parameters.
To display information about any parameter, click the button next to the parameter field.
Response format
The default format of the response is JSON. Some endpoints return text files or tar.gz archives - Your browser or pop up blockers might prevent these files from being downloaded, make sure you allow pop ups on this webpage.
For successful api calls, the reply will have a root element data
containing all
retrieved information wrapped in endpoint-specific objects, and if there was an error, the
response will have an
apiVersion
element and error
element, that will contain
code
, message
and errors
sub-elements.
The errors
sub-element may contain details about the exception that occured.
Should you receive a 500 class error
(any error code starting with the number 5)
indicating a server problem, we kindly ask you to
contact us and provide the api call url you used when you received the
error, and the response.
To display endpoint-specific information about the response, click the button under the 'response' subtitle.
Authentication
The REST API accepts HTTP Basic Authentication. A base64 encoded string containing your password and username is sent in the request headers with each api call over a secure https protocol.
Endpoints that require authorized access are marked with icon
If no credentials are provided, anonymous access is granted for all GET methods (Any data retrieval). Anonymous access may cause some of the endpoints to filter out results that require authorized access (E.g. experiments and platforms that are marked as unusable or private).
If you provide credentials that are invalid, all calls will return a '401 - Unauthorized' error, even if they allow anonymous access.
Using this website, some browsers might prompt you for credentials again, if this form contains invalid ones.
Make sure to test your credentials before bulk queries, e.g. by calling the root endpoint.
 Most endpoints also have a taxon-specific counterpart in the 'Taxon endpoints'.
Taxon endpoints
Endpoints accessing data for specific taxa. E.g: Taxon-specific genes or datasets
Other endpoints
Annotations, search, etc.


For Unit 5, the class was introduced to 3D printing and Scanning.
The class was tasked with scanning ourselves and adding the resulting mesh to another figure in Meshmixer.
We were able to put our heads on top of whatever we chose.
I decided to put my head on a pedastool.
Next, we had to come up with a small item that could not be made subtractively, and finaly we were given the task of
making an item that could be of some sort of use. we could do this with a partner if we so desired.
This the item I made in Meshmixer. As you can see, I put the scan of my head on top of a pedastool.


Represents reasons why a text document is saved.
Automatic after a delay.
When the editor lost focus.
Manually triggered, e.g. by the user pressing save, by starting debugging, or by an API call.
Generated using TypeDoc
Represents reasons why a text document is saved.


21th century is the era of freedom,where everyone can express own feelings by everything they want.Artists are not limited by law or taboo,so today there a lots of styles that make every artist unique.
21th century is the era of freedom,where everyone can express own feelings by everything they want.Artists are not limited by law or taboo,so today there a lots of styles that make every artist unique.


From 123 to 012
Today marked the start of a new stage in my life. I started the winter session of Web Development Immersive at General Assembly in San Francisco. I recently left my job at a music start-up to take part in this program and at the end of 3 month journey my goal is to become a junior developer.
The first day involved some basic introductions into Ruby and the command line. After a few hours of instruction we were pushed into the wild to attempt our first lab. The lab involved 3 exercises and one really had me scratching my head. Interesting side note is that one of my instructors told me this was a problem in his intro to CS course. Below is screenshot of the lab exercise:
As I worked through this project my main issue was getting the asterix "frame" on the top and bottom to be proportionate to the longest word in the string. At first I tried just typing "puts '************'", but that was easily broken when I typed in a word longer or shorter than the length of the words in the entered string. Then I decided that I should use the length of the longest word as a base to build on.
I found the longest word by using these lines of code:
puts "Please enter a phrase to be framed"
phrase = gets.chomp
puts "I am going to frame this"
max_word = phrase.split.max { |a, b| a.length <=> b.length }
frame_top_bottom = (max_word.length + 4)
frame_top_bottom.times {print "*"}
The key here was the + 4 that I got after drawing out the problem (sorry for my poor drawing skills):
It was there that I realized I would need 2 spaces on each side no matter what length the word is in order to create the frame above. While the problem is an elementary one, the lesson is one that I will apply throughout my new career. Drawing out a problem is a great way to visualize what is going on and allows your brain to see it in a new way.
Thanks for sticking with me through my first blog post and I hope to see you back here as I continue on this journey.
Cheers,
Spencer


Heading 4: Check that headings properly describe sections
This heading is labelled by this text
This heading is labelled by its aria label
description
This heading is aria-labbelled by a div
below are two empty headings
below are two hidden headings
Text
Text


Controls:
Drag mouse to rotate.
Drag mouse with ctrl down to pan.
Drag mouse with shift down to zoom.


--- layout: page title: About header-img: "img/about-bg.png" ---
From Houston, TX and work in tech as the business leader for several large dev teams. Figured it was time I learned to write a little code.


|
||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
| Interface Summary | |
|---|---|
| CreateGrammar | Interface that defines the methods that are required to create the Grammar (load from a file or a interactive creation). |
| Derivation | The inteface declares the methods that define the responsabilities of a Derivation object. |
| Element | The inteface that defines a common ancestor to NonTerminal, Terminal and Production objects. |
| Function | Interface that defines the methods that are required to create a function to be associated to the Derivation's nodes and applied over the Grammar symbols The interface encapsulates (hides) from the Grammar the several kind of functions to be implemented. |
| Grammar | The inteface declares the methods that define the responsabilities of a general Grammar. |
| NonTerminal | The inteface declares the methods that define the responsabilities of a NonTerminal object. |
| ParseDerivation | |
| Production | The inteface declares the methods that define the responsabilities of a Production object. |
| StochasticContextFreeGrammar | The inteface declares the methods that define the responsabilities of a Stochastic Context Free Grammar (SCFG). |
| Terminal | The inteface declares the methods that define the responsabilities of a Terminal object. |
| Class Summary | |
|---|---|
| CreateGrammarImpl | Class that offers a concrete implementation of the interface CreateGrammar. |
| DerivationAux_InternalImpl | |
| DerivationComparator | |
| DerivationImpl | |
| ElementImpl | Class that offers a concrete implementation of the interface Element. |
| FunctionImpl | Class that offers a concrete implementation of the interface Function. |
| GrammarImpl | Class that offers a concrete implementation of the interface Grammar. |
| NonTerminalImpl | Class that offers a concrete implementation of the interface NonTerminal. |
| ParseDerivationImpl | |
| ProductionImpl | Class that offers a concrete implementation of the interface Production. |
| StochasticContextFreeGrammarImpl | |
| TerminalImpl | Class that offers a concrete implementation of the interface Terminal. |
| Test0_internalImpl | |
| Test1_internalImpl | |
| Test3_internalImpl | |
| Test4_internalImpl | |
| Test5_internalImpl | |
| Test6_internalImpl | |
| Test7_internalImpl | |
| Test8_internalImpl | |
| Test9_internalImpl |
| Exception Summary | |
|---|---|
| GrammarExceptionImpl | Class that implements a custom Exception in order to handle the exceptions that can appear processing the Grammar. |
| GrammarMaxDepthExceptionImpl | Class that implements a custom Exception in order to handle the exceptions that can appear derivating a Production in the Grammar with a restriction of Max depth.. |
|
||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |


6.3. Roots of Complex Numbers#
If \(z=re^{i\theta}\) and \(n\) is a positive integer,
or
Using this theorem, instead of taking the \(n^{\text{th}}\) power of a complex number, we can simply multiply the argument by \(n\).
Example:
Find \(z^{10}=\left(\dfrac{1}{2}+\dfrac{1}{2}i\right)^{10}\).
If \(w = 2\,e^{i\pi/6}\), find \(w^{-1}\).
Solution:
Firstly, we need to write down \(z\) in \(e^{i\theta}\) form. It can be seen that
\[\begin{align*} r=|z|=\sqrt{\frac{1}{4}+\frac{1}{4}}=\frac{\sqrt{2}}{{2}}=\frac{1}{\sqrt{2}}\quad \text{and}\quad \begin{cases} \cos(\theta)=\dfrac{1/2}{\sqrt{2}/2}=\dfrac{\sqrt{2}}{2},\\ \sin(\theta)=\dfrac{1/2}{\sqrt{2}/2}=\dfrac{\sqrt{2}}{2}. \end{cases} \end{align*}\]As the the principal argument \(\theta \in (- \pi , \pi]\), \(\theta=\frac{\pi}{4}\).
Therefore,
\[\begin{align*} z^{10}&=\left(\dfrac{1}{2}+\dfrac{1}{2}i\right)^{10}=\left(\frac{1}{\sqrt{2}}e^{\frac{\pi}{4}i} \right)^{10} =\left(\frac{1}{\sqrt{2}}\right)^{10} \left(\cos\left(10\frac{\pi}{4}\right) +i\sin\left(10\frac{\pi}{4}\right)\right) \\ & =\left(\frac{1}{(2)^{5}}\right) \left(\cos\left(\frac{5\pi}{2}\right) +i\sin\left(\frac{5\pi}{2}\right)\right) =\left(\frac{1}{32}\right) \left(\cos\left(\frac{\pi}{2}\right) +i\sin\left(\frac{\pi}{2}\right)\right) \\ & =\left(\frac{1}{32}\right) \left(0 +i\right)=\frac{i}{32}. \end{align*}\]Note that \(\dfrac{5\pi}{2}=2\pi+\dfrac{\pi}{2}\) and \(\begin{cases}\cos(5\pi/2)=\cos(\pi/2),\\ \sin(5\pi/2)=\sin(\pi/2).\end{cases}\).
- \[\begin{align*} w^{-1}&=\left(2\,e^{i\pi/6}\right)^{-1}=2^{-1}\,e^{-i\pi/6} \\ & =\frac{1}{2}\,e^{-i\pi/6}=\frac{1}{2}\left(\cos\left(-\frac{\pi}{6}\right) +i\sin\left(-\frac{\pi}{6}\right)\right) \\ & =\frac{1}{2}\left(\frac{\sqrt{3}}{2} -\frac{1}{2}\,i\right)=\frac{1}{4}\left(\sqrt{3} -i\right) =\frac{\sqrt{3}}{4}-\frac{1}{4}{}i. \end{align*}\]
For two complex numbers \(z_1 = r_1 e^{i\theta_1}\) and \(z_2 = r_2 e^{i\theta_2}\) in polar form, we have
Note that for a real number \(c\in \mathbb{R}\),
\(c^{0}=1\),
\(c^{1/n}=\sqrt[n]{c}\) for \(n=1,2,3,\ldots\),
If \(c\neq 0\), \(c^{-n}=\dfrac{1}{c^n}\) for \(n=1,2,3,\ldots\).
Example: Express \((1-i)^6(\sqrt{3}+i)^3\) in the form \(a+bi\).
Solution: Let \(z=1-i=\sqrt{2}e^{-\pi i/4}\) and \(w=\sqrt{3}+i=2e^{i\pi /6}\). We want to compute \(z^6w^3\).
Complex number \(z\) is called \textbf{an \(n^{th}\) root of \(q\)} if \(z^n=q\) for some \(n\in\mathbb{N}\).
Example:
\(25\) has two square roots, \(5\) and \(-5\), and these are the two solutions to \(z^2=25\).
\(-1\) has no real square roots, but it has two complex square roots, \(i\) and \(-i\). These are the two (complex) solutions to \(z^2=-1\).
\(-4\) has two square roots, \(2i\) and \(-2i\), and these are the two solutions to \(z^2=25\).
For a nonzero complex number \(q\), \(z^n=q\) has exactly \(n\) different complex \(n^{th}\) roots.
It follows from Moivre’s theorem that, for a complex number \(z = a+b\,i\) with polar form \(z=|z|\left(\cos(\theta) +i\sin(\theta)\right)\), there are precisely \(n\) different complex numbers. Let \(w_0,~w_1,\ldots,~w_{n-1}\) be \(n^{\text{th}}\) roots of \(z\).
In particular, let \(w = r e^{i\,\alpha}=r\left(\cos(\alpha)+i\sin(\alpha)\right)\) be one of these \(n^{\text{th}}\) roots of \(z\). In other words,
It follows from the last equality that \(\textcolor{blue}{r^n}=\textcolor{green}{|z|}\) and \(\begin{cases} \textcolor{blue}{\cos(n\alpha)}=\textcolor{green}{\cos(\theta)},\\ \textcolor{blue}{\sin(n\alpha)}=\textcolor{green}{\sin(\theta)}. \end{cases}\) This means \(\alpha=\theta+2k\pi\), for \(k\) an integer. Therefore,
and the \(n^{\text{th}}\) root of \(z\) are of the form
Assume that \(q\) is a nonzero complex number and \(n\) is a positive integer. Then, all \(n\) distinct \(z\) roots such that \(z^n = q\) can be find as follows,
where \(r=|q|\) and \(w_k\) with \(k=0,1,2,\ldots,n-1\) are \(n\) distinct \(n^{\text{th}}\) roots.
Observe that each of the \(n^{\text{th}}\) roots of has modulus \(|w_k|=r^{1/n}\). Therefore, all the \(n^{\text{th}}\) roots of lie on the circle of radius \(r^{1/n}\) in the complex plane.
Example: Find the six sixth roots of \(-8\) and graph these roots in the complex plane.
Solution: First of all, we need to write down \(-8\) in \(e^{i\theta}\) form. It can be seen that
As the the principal argument \(\theta \in (- \pi , \pi]\), \(\theta=\pi.\).
Therefore, \(-8=8e^{i\pi} \). Since the argument is not unique, we can replace, \(\pi\) with \(\pi+2\pi k\) for \(k=0,1,2,\ldots,5\). We can find the roots using
\(k\) |
\(0\) |
\(1\) |
\(2\) |
\(3\) |
\(4\) |
\(5\) |
|---|---|---|---|---|---|---|
\(\theta\) |
\(\dfrac{\pi+2\pi(0)}{6}=\dfrac{\pi}{6}\) |
\(\dfrac{\pi+2\pi(1)}{6}=\dfrac{\pi}{2}\) |
\(\dfrac{\pi+2\pi(2)}{6}=\dfrac{5\pi}{6}\) |
\(\dfrac{\pi+2\pi(3)}{6}=\dfrac{7\pi}{6}\) |
\(\dfrac{\pi+2\pi(4)}{6}=\dfrac{3\pi}{2}\) |
\(\dfrac{\pi+2\pi(5)}{6}=\dfrac{11\pi}{6}\) |
Therefore,
Refrences
Kuttler, Kenneth. “A First Course in Linear Algebra (Lyryx).” (2018).
Nicholson, W. Keith. “Linear Algebra with Applications (Lyryx).” (2018).
Stewart, James, Daniel K. Clegg, and Saleem Watson. Calculus: early transcendentals. Cengage Learning, 2020.


the water disinfector has detected 20 liters of water and its has calculate to take 30 minutes to distiliate>/b> the 20 liter of water ......please be patient the process will be done soon ..... corona virus is real please keep disinfecting your water its another way to keep being safe


Cycle for Science
Two nutty scientists are biking from SF to NY and teaching a little physics along the way.
0 miles
0 states
traveled
3,812 miles
15 states
to go
About
Kickstarter
Blog


| # | Monday | Tuesday | Wednesday | Thursday | Friday |
|---|---|---|---|---|---|
| 1 | Ethics | Geography | Chemistry | Music | Sociology |
| 2 | Sociology | History | Arts | Mathematics | |
| 3 | Music | Computer science | Biology | English | |
| 4 | Arts | Physical Education | German | Physics | |
| 5 | Physical Education | Ethics | English | History | |
| 6 | Biology | Philosophy | German | Geography | / |


This BRAND NEW ALL-INCLUSIVE family resort now offers vacation homes and cabin rentals on the North shore of Blackduck Lake. The resort offers some of the most amazing sunsets on the lake year round. There are small 1 bedroom cabins all the way to a 6 bedroom cabin that sleeps up to 22 people. Going up north to spend a week at the lake is a big part of Minnesota tradition, and a stay at White Birch Resort is the perfect way to experience that.
The Months of May and June Kids stay free
The White Birch Resort experience is for those individuals who seek and appreciate a well-deserved taste of luxury resorts while on vacation. With a relaxed approach to luxury for groups of all ages and sizes, guests are excited and guaranteed to enjoy 2600 acres of four season's recreational adventure to explore, accompanied with endless and unmatched resort amenities minus the crowds. As many guests comment, "we feel as though we are in our own private custom lake home with beautiful refined style and decor."
The resort has more than 30 ALL-INCLUSIVE on resort experiences and activities for guests to enjoy. Guests can take advantage of all forms of lake recreation, such as, fishing kayaking, canoeing, boating and swimming in the summer to ice fishing, snowmobiling, snowshoeing and cross-country skiing in the winter. Even though WBR has ample amounts of on resort entertainment, rest assured, the area also features countless access to over 90 local attraction and activities, such as golf courses, State Parks, biking, skiing, snow tubing, site seeing, shopping and much more, if you so choose to explore off the resort. White Birch Resort is supported by and as close as, five miles to surrounding tourist communities of Blackduck, Bemidji, Upper Red Lake, Park Rapids, Grand Rapids and Walker. Sometimes guests even choose White Birch Resort as their home base because accommodations and amenities are so great!
"We had a amazing family vacation at White Birch Resort. The "reunion house #2" we stayed in was beautiful and plenty big enough to accommodate our family of 13 with room to spare. The kids enjoyed the inflatables, pool and of course our hot tub on the porch...which the adults also really enjoyed. It was a great week!! The weather cooperated even if the fish did not. Just a good reason to try it again another year. Monty and Sandy were great hosts and filled our every wish (oops! Almost...no drink blender). All said...we had a GREAT time!! Dora & Ray L."
"I just returned from a stay at White Birch and I had a great time. The resort is family oriented and our two children, ages 8 and 10, really enjoyed themselves. We fished, played in the sand, swam, played horseshoes, explored Blackduck and some of the local attractions and made lots and lots of S'Mores! Monte and Sandy were always available to answer any questions and make suggestions on fishing spots and good restaurants." Jason P.


ABOUT
HOBBIES
FAVORITE WEBSITE
The following are my hobbies:
I Enjoy Codding
I love Eating
swimming
The following are my favorite websites:
YOUTUBE
KHAN ACADEMY
SLADER


Neuroplasticity
Research Neuroplasticity
Discuss how understanding the principles of neuroplasticity benefits people
Neuroplasticity describes the way the nervous system but particularly the brain can adapt, learn and recover from injury. As it pertains to leaning, neuroplasticity describes how experiences reorganise and build neural pathways in the brain. Just understanding the principles of neuroplasticity can be beneficial in many aspects of a persons life by allowing you to engage with the learning process in a more meaningful way, building and strengthening neural pathways ways that improve your knowledge, skills and relationships.
Discuss how you might engage with the principles of neuroplasticity for your own benefit
One of the more important ways you can improve your neuroplasticity is by cultivating a growth mindset. The way you approach the learning process effects the way you learn and a growth mindset enhances growth and strengthening of neural pathways. Simply understanding that the brain remains adaptable past childhood and recontextualizing challenging material not as proof of inadequacy, but instead opportunities for growth can have a positive effect on your ability to overcome learning challenges.
What are some of the ways to increase your neuroplasticity?

- Repetition of material: Strengthen and link exiting neural pathways.
- Specificity: Focusing on the right material for best effect.
- Intensity: Higher intensity of learning allows for increased growth.
- Salience: The training has to be meaningful for best effect.
- Transference: Change in function as a result of a training experience can lead to learning other similar skills.
Link to a resource that you found particularly useful or engaging.
10 Principles of NeuroplasticityResearch Growth Mindset
Discuss what it is and why it is relevant
Growth mindset is trust in the idea that you can learn and adapt overtime. That struggling with a problem isn’t proof of inadequacy, but the process of improving your mind. A growth mindset helps prime your brain to better engage with challenges of the classroom, where a fixed mindset can lock down when it encounters a blocker.
In this exploration, did anything surprise you? Change for you?
I was already familiar with the concepts surrounding neuroplasticity but the idea of a growth mindset alone is a powerful tool, especially considering the difficulty of the challenges we will expect to face during Bootcamp.
How will you integrate growth mindset into your learning journey?
I will incorporate it into my reflections at the end of exercises, making sure that I approached the challenge with a growth mindset in every facet.
Link to a resource that you found particularly useful or engaging.
LearnStorm Growth Mindset: The Truth About Your BrainBlend with your learning plan and strategies - Reflect and discuss how these understandings may shape or influence your learning plan and strategy.
On gaining a greater understanding of neuroplasticity and the concept of a growth mindset, I can see opportunities to better apply myself to the material by approaching the concepts in a more structured way and making sure I have understood the key pillars before moving forward. By doing so I can benefit from increased transference of experience. I can also make sure to repeat material in areas that I am having trouble with, therefore growing and strengthening the neural pathways associated with the concepts. Finally and most importantly, making sure to constantly review my process to make sure that I am approaching challenges with a growth mindset.


Paws Pantry
Donate unwanted pet items to help local shelters and pets in need!
Need Help?
Do you run a shelter or a community not for profit that takes care of local animals?
Let us help!Donate unwanted pet items to help local shelters and pets in need!
Do you run a shelter or a community not for profit that takes care of local animals?
Let us help!


Algorithms for Walking, Running, Swimming, Flying, and Manipulation
© Russ Tedrake, 2023
Last modified .
How to cite these notes, use annotations, and give feedback.
Note: These are working notes used for a course being taught at MIT. They will be updated throughout the Spring 2023 semester. Lecture videos are available on YouTube.
| Previous Chapter | Table of contents | Next Chapter |
The equations of motion for a standard robot can be derived using the method of Lagrange. Using $T$ as the total kinetic energy of the system, and $U$ as the total potential energy of the system, $L = T-U$, and $\tau_i$ as the element of the generalized force vector corresponding to $q_i$, the Lagrangian dynamic equations are: \begin{equation} \frac{d}{dt}\pd{L}{\dot{q}_i} - \pd{L}{q_i} = \tau_i.\end{equation} You can think of them as a generalization of Newton's equations. For a particle, we have $T=\frac{1}{2}m \dot{x}^2,$ so $\frac{d}{dt}\pd{L}{\dot{x}} = m\ddot{x},$ and $\pd{L}{x} = -\pd{U}{x} = f$ amounting to $f=ma$. But the Lagrangian derivation works in generalized coordinate systems and for constrained motion.
Consider the simple double pendulum with torque actuation at both
joints and all of the mass concentrated in two points (for simplicity).
Using $\bq = [\theta_1,\theta_2]^T$, and ${\bf p}_1,{\bf p}_2$ to denote
the locations of $m_1,m_2$, respectively, the kinematics of this system
are:
\begin{eqnarray*}
{\bf p}_1 =& l_1\begin{bmatrix} s_1 \\ - c_1 \end{bmatrix}, &{\bf p}_2 =
{\bf p}_1 + l_2\begin{bmatrix} s_{1+2} \\ - c_{1+2} \end{bmatrix} \\
\dot{{\bf p}}_1 =& l_1 \dot{q}_1\begin{bmatrix} c_1 \\ s_1 \end{bmatrix},
&\dot{{\bf p}}_2 = \dot{{\bf p}}_1 + l_2 (\dot{q}_1+\dot{q}_2) \begin{bmatrix} c_{1+2} \\ s_{1+2} \end{bmatrix}
\end{eqnarray*}
Note that $s_1$ is shorthand for $\sin(q_1)$, $c_{1+2}$ is shorthand for
$\cos(q_1+q_2)$, etc. From this we can write the kinetic and potential
energy:
\begin{align*}
T =& \frac{1}{2} m_1 \dot{\bf p}_1^T \dot{\bf p}_1 + \frac{1}{2} m_2
\dot{\bf p}_2^T \dot{\bf p}_2 \\
=& \frac{1}{2}(m_1 + m_2) l_1^2 \dot{q}_1^2 + \frac{1}{2} m_2 l_2^2 (\dot{q}_1 + \dot{q}_2)^2 + m_2 l_1 l_2 \dot{q}_1 (\dot{q}_1 + \dot{q}_2) c_2 \\
U =& m_1 g y_1 + m_2 g y_2 = -(m_1+m_2) g l_1 c_1 - m_2 g l_2 c_{1+2}
\end{align*}
Taking the partial derivatives
\begin{align*}
\pd{T}{q_1} &= 0, \\
\pd{U}{q_1} & = (m_1 + m_2)gl_1s_1 + m_2 g l_2 s_{1+2}, \\
\pd{T}{q_2} &= - m_2 l_1 l_2 \dot{q}_1(\dot{q}_1 + \dot{q}_2)s_2, \\
\pd{U}{q_2} &= m_2 g l_2 s_{1+2}, \\
\pd{T}{\dot{q}_1} &= (m_1 + m_2) l_1^2 \dot{q}_1 + m_2 l_2^2 (\dot{q}_1 + \dot{q}_2) + m_2 l_1 l_2 (2 \dot{q}_1 + \dot{q}_2) c_2, \\
\pd{T}{\dot{q}_2} &= m_2 l_2^2 (\dot{q}_1 + \dot{q}_2) + m_2 l_1 l_2 \dot{q}_1 c_2, \\
\frac{d}{dt}\pd{T}{\dot{q}_1} &= (m_1+m_2)l_1^2 \ddot{q}_1 + m_2 l_2^2(\ddot{q}_1 + \ddot{q}_2) + m_2 l_1 l_2 (2 \ddot{q}_1 + \ddot{q}_2) c_2 - m_2 l_1 l_2 (2 \dot{q}_1 + \dot{q}_2) \dot{q}_2 s_2, \\
\frac{d}{dt}\pd{T}{\dot{q}_2} &= m_2 l_2^2 (\ddot{q}_1 + \ddot{q}_2) + m_2 l_1 l_2 \ddot{q}_1 c_2 - m_2 l_1 l_2 \dot{q}_1 \dot{q}_2 s_2,
\end{align*}
and plugging them into the Lagrangian, reveals the equations of motion:
\begin{align*}
(m_1 + m_2) l_1^2 \ddot{q}_1& + m_2 l_2^2 (\ddot{q}_1 + \ddot{q}_2) + m_2 l_1 l_2 (2 \ddot{q}_1 + \ddot{q}_2) c_2 \\
&- m_2 l_1 l_2 (2 \dot{q}_1 + \dot{q}_2) \dot{q}_2 s_2 + (m_1 + m_2) l_1 g s_1 + m_2 g l_2 s_{1+2} = \tau_1 \\
m_2 l_2^2 (\ddot{q}_1 + \ddot{q}_2)& + m_2 l_1 l_2 \ddot{q}_1 c_2 + m_2 l_1 l_2
\dot{q}_1^2 s_2 + m_2 g l_2 s_{1+2} = \tau_2
\end{align*}
As we saw in chapter 1, numerically integrating (and animating) these
equations in
If you are not comfortable with these equations, then any good book
chapter on rigid body mechanics can bring you up to speed.
I've also included a few more details about the connections between these equations and the variational principles of mechanics in the notes below, to the extent they may prove useful in our quest to write better optimizations for mechanical systems.
If you crank through the Lagrangian dynamics for a few simple robotic
manipulators, you will begin to see a pattern emerge - the resulting
equations of motion all have a characteristic form. For example, the
kinetic energy of your robot can always be written in the form:
\begin{equation} T = \frac{1}{2} \dot{\bq}^T \bM(\bq)
\dot{\bq},\end{equation} where $\bM$ is the state-dependent inertia matrix
(aka mass matrix). This observation affords some insight into general
manipulator dynamics - for example we know that ${\bf M}$ is always
positive definite, and symmetric
Continuing our abstractions, we find that the equations of motion of a general robotic manipulator (without kinematic loops) take the form \begin{equation}{\bf M}(\bq)\ddot{\bq} + \bC(\bq,\dot{\bq})\dot{\bq} = \btau_g(\bq) + {\bf B}\bu, \label{eq:manip} \end{equation} where $\bq$ is the joint position vector, ${\bf M}$ is the inertia matrix, $\bC$ captures Coriolis forces, and $\btau_g$ is the gravity vector. The matrix $\bB$ maps control inputs $\bu$ into generalized forces. Note that we pair $\bM\ddot\bq + \bC\dot\bq$ together on the left side because these terms together represent the force of inertia; the contribution from kinetic energy to the Lagrangian: $$\frac{d}{dt}\pd{T}{\dot{\bq}}^T - \pd{T}{\bq}^T = \bM(\bq) \ddot{\bq} + \bC(\bq,\dot\bq)\dot\bq.$$ Whenever I write Eq. (\ref{eq:manip}), I see $ma = f$.
The manipulator equations are very general, but they do define some
important characteristics. For example, $\ddot{\bq}$ is (state-dependent)
linearly related to the control input, $\bu$. This observation justifies
the control-affine form of the dynamics assumed throughout the notes. There
are many other important properties that might prove useful. For instance,
we know that the $i$ element of $\bC\dot{\bq}$ is given by
Note that we have chosen to use the notation of second-order systems
(with $\dot{\bq}$ and $\ddot{\bq}$ appearing in the equations) throughout
this book. Although I believe it provides more clarity, there is an
important limitation to this notation: it is impossible to describe 3D
rotations in "minimal coordinates" using this notation without introducing
kinematic singularities (like the famous "gimbal lock"). For instance, a
common singularity-free choice for representing a 3D rotation is the unit
quaternion, described by 4 real values (plus a norm constraint). However
we can still represent the rotational velocity without singularities using
just 3 real values. This means that the length of our velocity vector is
no longer the same as the length of our position vector. For this reason,
you will see that most of the software in
The equations of motions for our machines get complicated quickly.
Fortunately, for robots with a tree-link kinematic structure, there are
very efficient and natural recursive algorithms for generating these
equations of motion. For a detailed reference on these methods, see
If our robot has closed-kinematic chains, for instance those that arise from a four-bar linkage, then we need a little more. The Lagrangian machinery above assumes "minimal coordinates"; if our state vector $\bq$ contains all of the links in the kinematic chain, then we do not have a minimal parameterization -- each kinematic loop adds (at least) one constraint so should remove (at least) one degree of freedom. Although some constraints can be solved away, the more general solution is to use the Lagrangian to derive the dynamics of the unconstrained system (a kinematic tree without the closed-loop constraints), then add additional generalized forces that ensure that the constraint is always satisfied.
Consider the constraint equation \begin{equation}\bh(\bq) = 0.\end{equation} For example, in the case of the kinematic closed-chain, this can be the kinematic constraint that the location of one end of the chain is equal to the location of the other end of the chain. In the following derivation, we'll be using the time derivatives of this constraint: \begin{gather}\dot\bh = \bH\bv = 0,\\ \ddot\bh = \bH \dot\bv + \dot\bH \bv = 0, \label{eq:ddoth} \end{gather} where $\bH(\bq) = \pd{\bh}{\bq}{\bf N}(\bq)$ is the "Jacobian with respect to $\bv$". Note that $\dot{\bH}\bv$ is best calculated directly (rather than trying to solve for $\dot{\bH}$ as an object by itself).
The equations of motion can be written \begin{equation}\bM({\bq})\dot{\bv} + \bC(\bq,\bv)\bv = \btau_g(\bq) + \bB\bu + \bH^T(\bq) \blambda,\label{eq:constrained_manip}\end{equation} where ${\blambda}$ is the constraint force. Let's use the shorthand \begin{equation} \bM({\bq})\dot{\bv} = \btau(\bq,\dot{\bq},\bu) + \bH^T(\bq) \blambda. \label{eq:manip_short} \end{equation} In an optimization-based formulation (for instance, to implement this constraint in a trajectory optimization), we can simply make $\blambda$ a decision variable, and use equations (\ref{eq:ddoth}) and (\ref{eq:manip_short}) as constraints.
In other cases, it can be desirable to solve explicitly for $\blambda$. Inserting the dynamics (\ref{eq:manip_short}) into (\ref{eq:ddoth}) yields \begin{equation}\blambda =- (\bH \bM^{-1} \bH^T)^+ (\bH \bM^{-1} \btau + \dot\bH\bv).\label{eq:lambda_from_h}\end{equation} In many cases, this matrix will be full rank (for instance, in the case of multiple independent four-bar linkages) and the traditional inverse could have been used. When the matrix drops rank (multiple solutions), then the pseudo-inverse will select the solution with the smallest constraint forces in the least-squares sense.
To combat numerical "constraint drift", one might like to add a restoring force in the event that the constraint is not satisfied to numerical precision. To accomplish this, rather than solving for $\ddot\bh = 0$ as above, we can instead solve for \begin{equation}\ddot\bh = \bH\dot\bv + \dot\bH\bv = -2\alpha \dot\bh - \alpha^2 \bh,\end{equation} where $\alpha>0$ is a stiffness parameter. This is known as Baumgarte's stabilization technique, implemented here with a single parameter to provide a critically-damped response. Carrying this through yields \begin{equation} \blambda =- (\bH \bM^{-1} \bH^T)^+ (\bH \bM^{-1} \btau + \dot{\bH}\bv + 2\alpha \bH\bv + \alpha^2 \bh). \end{equation}
There is an important optimization-based derivation/interpretation of
these equations, which we will build on below, using Gauss's
Principle of Least Constraint. This principle says that we can
derive the constrained dynamics as : \begin{align} \min_\dot{\bv} \quad
& \frac{1}{2} (\dot{\bv} - \dot{\bv}_{uc})^T \bM (\dot{\bv} -
\dot{\bv}_{uc}), \label{eq:least_constraint} \\ \subjto \quad &
\ddot{\bh}(\bq,\bv,\dot\bv) = 0 = \bH \dot{\bv} + \dot\bH \bv,
\nonumber \end{align} where $\dot{\bv}_{uc} = \bM^{-1}\tau$ is the
"unconstrained acceleration"
Consider the constraint equation \begin{equation}\bh_v(\bq,\bv) = 0,\end{equation} where $\pd{\bh_v}{\bv} \ne 0.$ These are less common, but arise when, for instance, a joint is driven through a prescribed motion. Again, we will use the derivatives, \begin{equation} \dot\bh_v = \pd{\bh_v}{\bq} {\bf N}(\bq)\bv + \pd{\bh_v}{\bv}\dot{\bv} = 0,\label{eq:hvdot} \end{equation} and, the manipulator equations given by \begin{equation}\bM\dot{\bv} = \btau + \pd{\bh_v}{\bv}^T \blambda.\end{equation} These constraints can be added directly to an optimization with $\blambda$ as a decision variable. Alternatively, we can solve for $\blambda$ explicitly yielding \begin{equation}\blambda = - \left( \pd{\bh_v}{\bv} \bM^{-1} \pd{\bh_v}{\bv} \right)^+ \left[ \pd{\bh_v}{\bv} \bM^{-1} \btau + \pd{\bh_v}{\bq} {\bf N}(\bq) \bv \right].\end{equation}
Again, to combat constraint drift, we can ask instead for $\dot\bh_v = -\alpha \bh_v$, which yields \begin{equation}\blambda = - \left( \pd{\bh_v}{\bv} \bM^{-1} \pd{\bh_v}{\bv} \right)^+ \left[ \pd{\bh_v}{\bv} \bM^{-1} \btau + \pd{\bh_v}{\bq} {\bf N}(\bq) \bv + \alpha \bh_v \right].\end{equation}
Consider the simple, but important, case of "locking" a joint (making a particular joint act as if it is welded in the current configuration). One could write this as a bilateral velocity constraint $${\bf h}_v(\bq,\bv) = v_i = 0.$$ Since $\pd{{\bf h}_v}{\bv} = {\bf e}_i,$ (the vector with $1$ in the $i$th element and zero everywhere else, equation (\ref{eq:hvdot}) reduces to $\dot{v}_i = 0$, and $\pd{\bh_v}{\bv}^T \blambda$ impacts the equation for $\dot{v}_i$ and \emph{only} the equation for $\dot{v}_i$. The resulting equations can be obtained by simply removing the terms associated with $v_i$ from the manipulator dynamics (and setting $\dot{v}_i = 0$).
For hybrid models of contact, it can be useful to work with a description of the dynamics in the floating-base coordinates and solve for the contact forces which enforce the constraints in each mode. We'll define a mode by a list of pairs of contact geometries that are in contact, and even define whether each contact is in sticking contact (with zero relative tangential velocity) or sliding contact. We can ask our geometry engine to return the contact points on the bodies, ${}^A{\bf p}^{C_a}$ and ${}^B{\bf p}^{C_b},$ where $C_a$ is the contact point (or closest point to contact) in body $A$ and $C_b$ is the contact point (or closest point to contact) in body $B$. More generally, we will refer to $C_a$ and $C_b$ as contact frames with their origins at these points, their $z$-axis pointing out along the contact normal, and their $x-y$-axes chosen as an orthonormal basis orthogonal to the normal.
For each sticking contact, we have a bilateral position constraint of the form $${\bf h}_{A,B}(\bq) = {}^W{\bf p}^{C_a}_{C_a} - {}^W{\bf p}^{C_b}_{C_a} = 0.$$ We can assemble all of these constraints into a single bilateral constraint vector ${\bf h}(\bq) = 0,$ and use almost precisely the recipe above. Note that applying Baumgarte stabilization here would only stabilize in the normal direction, by definition the vector between the two points, which is consistent with having (only) a zero-velocity constraint in the tangential direction. For sliding contacts, we have just the scalar constraint, $${\bf h}_{A,B}(\bq) = {}^W{\bf p}^{C_a}_{C_{a;z}} - {}^W{\bf p}^{C_b}_{C_{a;z}} = 0,$$ which says that the distance is zero in the normal direction, plus a constraint the imposes maximum dissipation $${\bf \lambda}^{C_a}_{C_{a;x,y}} = -\mu {\bf \lambda}^{C_a}_{C_{a;z}}\frac{{}^W{\bf \text{v}}^{C_a}_{C_{a;x,y}}}{|{}^W{\bf \text{v}}^{C_a}_{C_{a;x,y}}|},$$ that can be accommodated when we solve for $\lambda$.
The dynamics of multibody systems that make and break contact are closely related to the dynamics of constrained systems, but tend to be much more complex. In the simplest form, you can think of non-penetration as an inequality constraint: the signed distance between collision bodies must be non-negative. But, as we have seen in the chapters on walking, the transitions when these constraints become active correspond to collisions, and for systems with momentum they require some care. We'll also see that frictional contact adds its own challenges.
There are three main approaches used to modeling contact with "rigid" body systems: 1) rigid contact approximated with stiff compliant contact, 2) hybrid models with collision event detection, impulsive reset maps, and continuous (constrained) dynamics between collision events, and 3) rigid contact approximated with time-averaged forces (impulses) in a time-stepping scheme. Each modeling approach has advantages/disadvantages for different applications.
Before we begin, there is a bit of notation that we will use throughout. Let $\phi(\bq)$ indicate the relative (signed) distance between two rigid bodies. For rigid contact, we would like to enforce the unilateral constraint: \begin{equation} \phi(\bq) \geq 0. \end{equation} We'll use ${\bf n} = \pd{\phi}{\bq}$ to denote the "contact normal", as well as ${\bf t}_1$ and ${\bf t}_2$ as a basis for the tangents at the contact (orthonormal vectors in the Cartesian space, projected into joint space), all represented as row vectors in joint coordinates.
We will also find it useful to assemble the contact normal and tangent vectors into a single matrix, $\bJ$, that we'll call the contact Jacobian: $$\bJ(\bq) = \begin{bmatrix} {\bf n}\\ {\bf t}_1\\ {\bf t}_2 \end{bmatrix}.$$ As written, $\bJ\bv$ gives the relative velocity of the closest points in the contact coordinates; it can be also be extended with three more rows to output a full spatial velocity (e.g. when modeling torsional friction). The generalized force produced by the contact is given by $\bJ^T \lambda$, where $\lambda = [f_n, f_{t1}, f_{t2}]^T:$ \begin{equation} \bM(\bq) \dot{\bv} + \bC(\bq,\bv)\bv = \btau_g(\bq) + \bB \bu + \bJ^T(\bq)\lambda. \end{equation}
Most compliant contact models are conceptually straight-forward: we
will implement contact forces using a stiff spring (and
damper
Coulomb friction is described by two parameters -- $\mu_{static}$ and $\mu_{dynamic}$ -- which are the coefficients of static and dynamic friction. When the contact tangential velocity (given by ${\bf t}\bv$) is zero, then friction will produce whatever force is necessary to resist motion, up to the threshold $\mu_{static} f_n.$ But once this threshold is exceeding, we have slip (non-zero contact tangential velocity); during slip friction will produce a constant drag force $|f_t| = \mu_{dynamic} f_n$ in the direction opposing the motion. This behaviour is not a simple function of the current state, but we can approximate it with a continuous function as pictured below.
With these two laws, we can recover the contact forces as relatively simple functions of the current state. However, the devil is in the details. There are a few features of this approach that can make it numerically unstable. If you've ever been working in a robotics simulator and watched your robot take a step only to explode out of the ground and go flying through the air, you know what I mean.
In order to tightly approximate the (nearly) rigid contact that most
robots make with the world, the stiffness of the contact "springs" must be
quite high. For instance, I might want my 180kg humanoid robot model to
penetrate into the ground no more than 1mm during steady-state standing.
The challenge with adding stiff springs to our model is that this results
in stiff
differential equations (it is not a coincidence that the word
stiff is the common term for this in both springs and ODEs). As a
result, the best implementations of compliant contact for simulation make
use of special-purpose numerical integration recipes (e.g.
But there is another serious numerical challenge with the basic implementation of this model. Computing the signed-distance function, $\phi(\bq)$, when it is non-negative is straightforward, but robustly computing the "penetration depth" once two bodies are in collision is not. Consider the case of use $\bphi(\bq)$ to represent the maximum penetration depth of, say, two boxes that are contacting each other. With compliant contact, we must have some penetration to produce any contact force. But the direction of the normal vector, ${\bf n} = \pd{\bphi}{\bq},$ can easily change discontinuously as the point of maximal penetration moves, as I've tried to illustrate here:
If you really think about this example, it actually reveals even more of the foibles of trying to even define the contact points and normals consistently. It seems reasonable to define the point on body B as the point of maximal penetration into body A, but notice that as I've drawn it, that isn't actually unique! The corresponding point on body A should probably be the point on the surface with the minimal distance from the max penetration point (other tempting choices would likely cause the distance to be discontinuous at the onset of penetration). But this whole strategy is asymmetric; why shouldn't I have picked the vector going with maximal penetration into body B? My point is simply that these cases exist, and that even our best software implementations get pretty unsatisfying when you look into the details. And in practice, it's a lot to expect the collision engine to give consistent and smooth contact points out in every situation.
Some of the advantages of this approach include (1) the fact that it is easy to implement, at least for simple geometries, (2) by virtue of being a continuous-time model it can be simulated with error-controlled integrators, and (3) the tightness of the approximation of "rigid" contact can be controlled through relatively intuitive parameters. However, the numerical challenges of dealing with penetration are very real, and they motivate our other two approaches that attempt to more strictly enforce the non-penetration constraints.
The collision event is described by the zero-crossings (from positive to negative) of $\phi$. Let us start by assuming frictionless collisions, allowing us to write \begin{equation}\bM\dot{\bv} = \btau + \lambda {\bf n}^T,\end{equation} where ${\bf n}$ is the "contact normal" we defined above and $\lambda \ge 0$ is now a (scalar) impulsive force that is well-defined when integrated over the time of the collision (denoted $t_c^-$ to $t_c^+$). Integrate both sides of the equation over that (instantaneous) interval: \begin{align*}\int_{t_c^-}^{t_c^+} dt\left[\bM \dot{\bv} \right] = \int_{t_c^-}^{t_c^+} dt \left[ \btau + \lambda {\bf n}^T \right] \end{align*} Since $\bM$, $\btau$, and ${\bf n}$ are constants over this interval, we are left with $$\bM{\bv}^+ - \bM{\bv}^- = {\bf n}^T \int_{t_c^-}^{t_c^+} \lambda dt,$$ where $\bv^+$ is short-hand for $\bv(t_c^+)$. Multiplying both sides by ${\bf n} \bM^{-1}$, we have $$ {\bf n} \bv^+ - {\bf n}\bv^- = {\bf n} \bM^{-1} {\bf n}^T \int_{t_c^-}^{t_c^+} \lambda dt.$$ After the collision, we have $\dot\phi^+ = -e \dot\phi^-$, with $0 \le e \le 1$ denoting the coefficient of restitution, yielding: $$ {\bf n} \bv^+ - {\bf n}\bv^- = -(1+e){\bf n}\bv^-,$$ and therefore $$\int_{t_c^-}^{t_c^+} \lambda dt = - (1+e)\left[ {\bf n} \bM^{-1} {\bf n}^T \right]^\# {\bf n} \bv^-.$$ I've used the notation $A^\#$ here to denote the pseudoinverse of $A$ (I would normally write $A^+,$ but have changed it for this section to avoid confusion). Substituting this back in above results in \begin{equation}\bv^+ = \left[ \bI - (1+e)\bM^{-1} {\bf n}^T \left[{\bf n} \bM^{-1} {\bf n}^T \right]^\# {\bf n} \right] \bv^-.\end{equation}
We can add friction at the contact. Rigid bodies will almost always
experience contact at only a point, so we typically ignore torsional
friction
Imagine a ball (a hollow-sphere) in the plane with mass $m$, radius $r$. The configuration is given by $q = \begin{bmatrix} x, z, \theta \end{bmatrix}^T.$ The equations of motion are $$\bM(\bq)\ddot\bq = \begin{bmatrix} m & 0 & 0 \\ 0 & m & 0 \\ 0 & 0 & \frac{2}{3}mr^2 \end{bmatrix} \ddot\bq = \begin{bmatrix} 0 \\ -g \\ 0 \end{bmatrix} + \begin{bmatrix} 0 & 1 \\ 1 & 0 \\ 0 & r \end{bmatrix} \begin{bmatrix} \lambda_z \\ \lambda_x \end{bmatrix} = \tau_g + \bJ^T {\bf \lambda},$$ where ${\bf \lambda}$ are the contact forces (which are zero except during the impulsive collision). Given a coefficient of restitution $e$ and a collision with a horizontal ground, the post-impact velocities are: $$ \dot{\bq}^+ = \begin{bmatrix} \frac{3}{5} & 0 & -\frac{2}{5} r \\ 0 & - e & 0 \\ -\frac{3}{5r} & 0 & \frac{2}{5}\end{bmatrix}\dot{\bq}^-.$$
We can put the bilateral constraint equations and the impulsive collision equations together to implement a hybrid model for unilateral constraints of the form. Let us generalize \begin{equation}\bphi(\bq) \ge 0,\end{equation} to be the vector of all pairwise (signed) distance functions between rigid bodies; this vector describes all possible contacts. At every moment, some subset of the contacts are active, and can be treated as a bilateral constraint ($\bphi_i=0$). The guards of the hybrid model are when an inactive constraint becomes active ($\bphi_i>0 \rightarrow \bphi_i=0$), or when an active constraint becomes inactive ($\blambda_i>0 \rightarrow \blambda_i=0$ and $\dot\phi_i > 0$). Note that collision events will (almost always) only result in new active constraints when $e=0$, e.g. we have pure inelastic collisions, because elastic collisions will rarely permit sustained contact.
If the contact involves Coulomb friction, then the transitions between sticking and sliding can be modeled as additional hybrid guards.
So far we have seen two different approaches to enforcing the inequality constraints of contact, $\phi(\bq) \ge 0$ and the friction cone. First we introduced compliant contact which effectively enforces non-penetration with a stiff spring. Then we discussed event detection as a means to switch between different models which treat the active constraints as equality constraints. But, perhaps surprisingly, one of the most popular and scalable approaches is something different: it involves formulating a mathematical program that can solve the inequality constraints directly on each time step of the simulation. These algorithms may be more expensive to compute on each time step, but they allow for stable simulations with potentially much larger and more consistent time steps.
What class of mathematical program due we need to simulate contact?
The discrete nature of contact suggests that we might need some form of
combinatorial optimization. Indeed, the most common transcription is to
a Linear Complementarity Problem (LCP)
Rather than dive into the full transcription, which has many terms and can be relatively difficult to parse, let me start with two very simple examples.
Consider our favorite simple mass being actuated by a horizontal force (with the double integrator dynamics), but this time we will add a wall that will prevent the cart position from taking negative values: our non-penetration constraint is $q \ge 0$. Physically, this constraint is implemented by a normal (horizontal) force, $f$, yielding the equations of motion: $$m\ddot{q} = u + f.$$
$f$ is defined as the force required to enforce the non-penetration constraint; certainly the following are true: $f \ge 0$ and $q \cdot f = 0$. $q \cdot f = 0$ is the "complementarity constraint", and you can read it here as "either q is zero or force is zero" (or both); it is our "no force at a distance" constraint, and it is clearly non-convex. It turns out that satisfying these constraints, plus $q \ge 0$, is sufficient to fully define $f$.
To define the LCP, we first discretize time, by approximating \begin{gather*}q[n+1] = q[n] + h v[n+1], \\ v[n+1] = v[n] + \frac{h}{m}(u[n] + f[n]).\end{gather*} This is almost the standard Euler approximation, but note the use of $v[n+1]$ in the right-hand side of the first equation -- this is actually a semi-implicit Euler approximation, and this choice is essential in the derivation.
Given $h, q[n], v[n],$ and $u[n]$, we can solve for $f[n]$ and $q[n+1]$ simultaneously, by solving the following LCP: \begin{gather*} q[n+1] = \left[ q[n] + h v[n] + \frac{h^2}{m} u[n] \right] + \frac{h^2}{m} f[n] \\ q[n+1] \ge 0, \quad f[n] \ge 0, \quad q[n+1]\cdot f[n] = 0. \end{gather*} Take a moment and convince yourself that this fits into the LCP prescription given above.
Note: Please don't confuse this visualization with the more common
visualization of the solution space for an LCP (in two or more
dimensions) in terms of "complementary cones"
Perhaps it's also helpful to plot the solution, $q[n+1], f[n]$ as a function of $q[n], v[n]$. I've done it here for $m=1, h=0.1, u[n]=0$:
In the (time-stepping, "impulse-velocity") LCP formulation, we write the contact problem in it's combinatorial form. In the simple example above, the complementarity constraints force any solution to lie on either the positive x-axis ($f[n] \ge 0$) or the positive y-axis ($q[n+1] \ge 0$). The equality constraint is simply a line that will intersect with this constraint manifold at the solution. But in this frictionless case, it is important to realize that these are simply the optimality conditions of a convex optimization problem: the discrete-time version of Gauss's principle that we used above. Using $\bv'$ as shorthand for $\bv[n+1]$, and replacing $\ddot{\bq} = \frac{\bv' - \bv}{h}$ in Eq \eqref{eq:least_constraint} and scaling the objective by $h^2$ we have: \begin{align*} \min_{\bv'} \quad & \frac{1}{2} \left(\bv' - \bv - h\bM^{-1}\btau\right)^T \bM \left(\bv' - \bv - h\bM^{-1}\btau\right) \\ \subjto \quad & \frac{1}{h}\phi(\bq') = \frac{1}{h} \phi(\bq + h\bv') \approx \frac{1}{h}\phi(\bq) + {\bf n}\bv' \ge 0. \end{align*} The objective is even cleaner/more intuitive if we denote the next step velocity that would have occurred before the contact impulse is applied as $\bv^- = \bv + h\bM^{-1}\btau$: \begin{align*} \min_{\bv'} \quad & \frac{1}{2} \left(\bv' - \bv^-\right)^T \bM \left(\bv' - \bv^-\right) \\ \subjto \quad & \frac{1}{h}\phi(\bq') \ge 0. \end{align*} The LCP for the frictionless contact dynamics is precisely the optimality conditions of this convex (because $\bM \succeq 0$) quadratic program, and once again the contact impulse, ${\bf f} \ge 0$, plays the role of the Lagrange multiplier (with units $N\cdot s$).
So why do we talk so much about LCPs instead of QPs? Well LCPs can also represent a wider class of problems, which is what we arrive at with the standard transcription of Coulomb friction. In the limit of infinite friction, then we could add an additional constraint that the tangential velocity at each contact point was equal to zero (but these equation may not always have a feasible solution). Once we admit limits on the magnitude of the friction forces, the non-convexity of the disjunctive form rear's it's ugly head.
We can use LCP to find a feasible solution with Coulomb friction, but it requires some gymnastics with slack variables to make it work. For this case in particular, I believe a very simple example is best. Let's take our brick and remove the wall and the wheels (so we now have friction with the ground).
The dynamics are the same as our previous example, $$m\ddot{q} = u
+ f,$$ but this time I'm using $f$ for the friction force which is
inside the friction cone if $\dot{q} = 0$ and on the boundary of the
friction cone if $\dot{q} \ne 0;$ this is known as the principle of
maximum dissipation
Now, to write the friction constraints as an LCP, we must introduce some slack variables. First, we'll break the force into a positive component and a negative component: $f[n] = f^+ - f^-.$ And we will introduce one more variable $v_{abs}$ which will be non-zero if the velocity is non-zero (in either direction). Now we can write the LCP: \begin{align*} \find_{v_{abs}, f^+, f^-} \quad \subjto && \\ 0 \le v_{abs} + v[n+1] \quad &\perp& f^+ \ge 0, \\ 0 \le v_{abs} - v[n+1] \quad &\perp& f^- \ge 0, \\ 0 \le \mu mg - f^+ - f^- \quad &\perp& v_{abs} \ge 0,\end{align*} where each instance of $v[n+1]$ we write out with $$v[n+1] = v[n] + \frac{h}{m}(u + f^+ - f^-).$$ It's enough to make your head spin! But if you work it out, all of the constraints we want are there. For example, for $v[n+1] > 0$, then we must have $f^+=0$, $v_{abs} = v[n+1]$, and $f^- = \mu mg$. When $v[n+1] = 0$, we can have $v_{abs} = 0$, $f^+ - f^- \le \mu mg$, and those forces must add up to make $v[n+1] = 0$.
We can put it all together and write an LCP with both normal forces
and friction forces, related by Coulomb friction (using a polyhedral
approximation of the friction cone in 3d)
In
But be careful! Although the primal solution was convex, and the
dual problems are always convex, the objective here can be positive
semi-definite. This isn't a mistake --
When the tangential velocity is zero, this constraint is tight; for sliding contact the relaxation effectively causes the contact to "hydroplane" up out of contact, because $\phi(\bq') \ge h\mu {\bf d}_i\bv'.$ It seems like a quite reasonable approximation to me, especially for small $h$!
Let's continue on and write the dual program. To make the notation a little better, the us stack the Jacobian vectors into $\bJ_\beta$, such that the $i$th row is ${\bf n} + \mu{\bf d_i}$, so that we have $$\pd{L}{\bv'}^T = \bM(\bv' - \bv) - h\btau - \bJ_\beta^T \beta = 0.$$ Substituting this back into the Lagrangian give us the dual program: $$\min_{\beta \ge 0} \frac{1}{2} \beta^T \bJ_\beta \bM^{-1} \bJ_\beta^T \beta + \frac{1}{h}\phi(\bq) \sum_i \beta_i.$$
One final note: I've written just one contact point here to simplify
the notation, but of course we repeat the constraint(s) for each contact
point;
According to
How should we interpret this? If you expand the linear terms, you will see that this is almost exactly the dual form we get from the position equality constraints formulation, including the Baumgarte stabilization. It's interesting to think about the implications of this formulation -- like the Anitescu relaxation, it is possible to get some "force at a distance" because we have not in any way expressed that $\lambda = 0$ when $\phi(\bq) > 0.$ In Anitescu, it happened in a velocity-dependent boundary layer; here it could happen if you are "coming in hot" -- moving towards contact with enough relative velocity that the stabilization terms want to slow you down.
In dual form, it is natural to consider the full conic description of the friction cone: $$\mathcal{FC}(\bq) = \left\{{\bf \lambda} = [f_n, f_{t1}, f_{t2}]^T \middle| f_n \ge 0, \sqrt{f^2_{t1}+f^2_{t2}} \le \mu f_n \right\}.$$ The resulting dual optimization is has a quadratic objective and second-order cone constraints (SOCP).
There are a number of other important relaxations that happen in
MuJoCo. To address the positive indefiniteness in the objective,
The contact solver that we use in Drake further extends and improves upon this line of work...
What equations do we get if we simulate the simple cart colliding with a wall example that we used above?
Following
What remains is to compute $f[n]$, and here is where things get
interesting. Motivated by the idea of "softening the Gauss principle"
(e.g. the principle of least constraint
Coming soon... Box-on-plane example. Multi-contact.
Also a single point force cannot capture effects like torsional friction, and performs badly in some very simple cases (imaging a box sitting on a table). As a result, many of the most effective algorithms for contact restrict themselves to very limited/simplified geometry. For instance, one can place "point contacts" (zero-radius spheres) in the four corners of a robot's foot; in this case adding forces at exactly those four points as they penetrate some other body/mesh can give more consistent contact force locations/directions. A surprising number of simulators, especially for legged robots, do this.
In practice, most collision detection algorithms will return a list of "collision point pairs" given the list of bodies (with one point pair per pair of bodies in collision, or more if they are using the aforementioned "multi-contact" heuristics), and our contact force model simply attaches springs between these pairs. Given a point-pair, $p_A$ and $p_B$, both in world coordinates, ...
Hydroelastic model in drake
The field of analytic mechanics (or variational mechanics), has given us a number of different and potentially powerful interpretations of these equations. While our principle of virtual work was very much rooted in mechanical work, these variational principles have proven to be much more general. In the context of these notes, the variational principles also provide some deep connections between mechanics and optimization. So let's consider some of the equations above, but through the more general lens of variational mechanics.
Most of us are comfortable with the idea that a body is in equilibrium if the sum of all forces acting on that body (including gravity) is zero: $$\sum_i {\bf f}_i = 0.$$ It turns out that there are some limitations in working with forces directly: forces require us to (arbitrarily) define a coordinate system, and to achieve force balance we might need to consider all of the forces in the system, including internal forces like the forces at the joints that hold our robots together.
So it turns out to be better to think not about forces directly, but to think instead about the work, $w$, done by those forces. Work is force times distance. It's a scalar quantity, and it is invariant to the choice of coordinate system. Even for a system that is in equilibrium, we can reason about the virtual work that would occur if we were to make an infinitesimal change to the configuration of the system. Even better, since we know that the internal forces do no work, we can ignore them completely and only consider the virtual work that occurs due to a variation in the configuration variables. A multibody system in equilibrium must have zero virtual work: $$\delta w = \sum_i {\bf \tau}_i^T \delta \bq = 0.$$ Notice that these forces are the generalized forces (they have the same dimension as $\bq$). We can map between a Cartesian force and the generalized force using a kinematic Jacobian: ${\bf \tau}_i = {\bf J}_i^T(\bq){\bf f}_i.$ In particular, forces due to gravity, or any forces described by a "potential energy" function, are can be written as $${\bf \tau}_{g} = -\pd{U_{g}(\bq)}{\bq}^T.$$
If all of the generalized forces can be derived from such a potential function, then we can go even further. For a system to be in equilibrium, we must have that varations in the potential energy function must be zero, $\delta U(\bq) = 0.$ This follows simply from $\delta U = \pd{U}{\bq} \delta \bq$ and the principle of virtual work. Moreover, for the system to be in a stable equilibrium, $\bq$ must not only be a stationary point of the potential, but a minimum of the potential. This is our first important connection in this section between mechanics and optimization.
What about bodies in motion? d'Alembert's principle states that we can reduce dynamics problems to statics problems by simply including a "force of inertia", which is the familiar mass times acceleration for simple particles. In order to have $\delta w = \sum_i {\bf \tau}_i^T \delta \bq = 0,$ for all $\delta \bq$, we must have $\sum_i {\bf \tau}_i = 0,$ so for multibody systems we know that the force of inertia must be: $${\bf \tau}_{inertia} = -{\bf M}(\bq)\ddot{\bq} - {\bf C}(\bq,\dot\bq)\dot{\bq}.$$ But where did that term come from? Is it the result of nature "optimizing" some scalar function?
A natural candidate would be the kinetic energy: $T(\bq, \dot\bq) = \frac{1}{2} \dot\bq^T {\bf M}(\bq) \dot\bq.$ What would it mean to take a variation of the kinetic energy, $\delta T?$ So far we've only had variations with respect to $\delta \bq$, but the kinetic energy depends on both $\bq$ and $\dot\bq$. We cannot vary these variables independently, but how are they related?
The solution is to take a variation not at a single point, but along a trajectory, where the relationship between $\delta \bq$ and $\delta \dot\bq$ is well defined. If we consider $$A(\bq(t)) = \int_{t_0}^{t_1} T(\bq,\dot\bq)dt,$$ then a variation of $A$ (using the calculus of variations) w.r.t. any trajectory $\bq(t)$, will take the form: $$\delta A = A(\bq(t) + \delta \bq(t)) - A(\bq(t) = \int_{t_0}^{t_1} T(\bq + \delta \bq(t), \dot\bq + \delta \dot\bq(t))dt - \int_{t_0}^{t_1} T(\bq(t), \dot\bq(t))dt,$$ where $\delta \bq(t)$ is defined to be an arbitrary (small) differentiable function in the space of $\bq$ that is zero at $t_0$ and $t_1.$
We can expand the term in the first integral: $$T\left(\bq(t)+\bq(t),\, \dot\bq(t) + \delta \dot\bq(t)\right) = T\left(\bq(t),\,\dot\bq(t)\right) + \pd{T}{\bq(t)}\delta \bq(t) + \pd{T}{\dot\bq(t)}\delta \dot\bq(t).$$ Substituting this back in and simplifying leaves: $$\delta A = \int_{t_0}^{t_1} \left[\pd{T}{\bq(t)}\delta {\bf q}(t) + \pd{T}{\dot\bq(t)}\delta \dot{\bf q}(t)\right]dt.$$ Now use integration by parts on the second term: $$\int_{t_0}^{t_1} \pd{T}{\dot\bq(t)}\delta \dot{\bf q}(t)dt = \left[\pd{T}{\dot\bq(t)} \delta {\bf q}(t) \right]_{t_0}^{t_1} - \int_{t_0}^{t_1} \frac{d}{dt} \pd{T}{\dot\bq(t)} \delta {\bf q}(t) dt,$$ and observe that the first term in the right-hand side is zero since $\delta {\bf q}(t_0) = \delta {\bf q}(t_1) = 0$. This leaves $$\delta A = \int_{t_0}^{t_1} \left[\pd{T}{\bq} - \frac{d}{dt}\pd{T}{\dot\bq}\right]\delta {\bf q}(t) dt.$$ If our goal is to analyze the stationary points of this variation, then this quantity must integrate to zero for any ${\bf q}(t)$, so we must have $$\pd{T}{\bq} - \frac{d}{dt}\pd{T}{\dot\bq} = 0.$$
The result is that we find that the natural generalization of $-\pd{U(\bq)}{\bq}^T$ for stationary points of variations of quantities that also depend on velocity is $$\tau_{inertia} = -\pd{T}{\bq}^T + \frac{d}{dt}\pd{T}{\dot{\bq}}^T.$$ This is exactly (the negation of) our familiar $\bM(\bq) \ddot{\bq} + \bC(\bq,\dot\bq)\dot\bq.$
The integral quantity $A$ that we used in the last section is commonly called the "action" of the system. More generally, the action is defined as $$A = \int_{t_0}^{t_1} L(\bq,\dot{\bq})dt,$$ where $L(\bq,\dot\bq)$ is an appropriate "Lagrangian" for the system. The Lagrangian has units of energy, but it is not uniquely defined. Any function which generates the correct equations of motion, in agreement with physical laws, can be taken as a Lagrangian. For our mechanical systems, the familiar form of the Lagrangian is what we presented above: $L = T - U$ (kinetic energy minus potential energy). Since the terms involving $U(\bq)$ do not depend directly on $\dot\bq$, they only contribute the $\pd{U}{\bq}^T$ terms that we expect, and taking $\delta A = 0$ for this Lagrangian is a way to generate the entire equations of motion in one go. For our purposes, where we care about conservative forces but also control inputs (as generalized forces $\bB \bu$), the principle of virtual work tells us that we will have $\delta A + \int_{t_0}^{t_1} \bu^T \bB^T \delta \bq(t) dt = 0.$
The viewpoint of variational mechanics is that it is this scalar
quantity $L(\bq,\dot\bq)$ that should be the central object of study (as
opposed to coordinate dependent forces), and this has proven to
generalize beautifully.
The principle of least action -- really the principle of stationary action -- is the most compact form of the classical laws of physics. This simple rule (it can be written in a single line) summarizes everything! Not only the principles of classical mechanics, but electromagnetism, general relativity, quantum mechanics, everything known about chemistry -- right down to the ultimate known constituents of matter, elementary particles.
In some cases, it might be preferable to use the Hamiltonian formulation of the dynamics, with state variables $\bq$ and $\bp$ (instead of $\dot{\bq}$), where $\bp = \pd{L}{\dot{\bq}}^T = \bM \dot\bq$ results in the dynamics: \begin{align*}\bM(\bq) \dot{\bq} =& \bp \\ \dot{\bp} =& {\bf c}_H(\bq,\bp) + \tau_g(\bq) + \bB\bu, \qquad \text{where}\quad {\bf c}_H(\bq,\bp) = \frac{1}{2} \left(\pd{ \left[ \dot{\bq}^T \bM(\bq) \dot{\bq}\right]}{\bq}\right)^T.\end{align*} Recall that the Hamiltonian is $H({\bf p}, \bq) = {\bf p}^T\dot\bq - L(\bq,\dot\bq)$; these equations of motion are the familiar $\dot\bq = \pd{H}{\bf p}^T, \dot{\bf p} = -\pd{H}{\bq}^T.$
Suppose you have a block A of width 1, block B of width 1, interacting on a friction-less surface. The state of a single block in our system is $\vec{x} = \begin{bmatrix}q_x \\ \dot{q}_x \end{bmatrix}$, which represents the horizontal position (where the position point is located at the geometric center of the block) and horizontal velocity of the associated block. We have as our initial condition $\vec{x}^{(A)}_0 = \begin{bmatrix} -2 \\ 3 \end{bmatrix}$ and $\vec{x}^{(B)}_0 = \begin{bmatrix} 0 \\ 0 \end{bmatrix}$. In other words, at time step $0$ block A is moving towards a stationary block B located at the origin.
| Previous Chapter | Table of contents | Next Chapter |